From 5f594ad191cba1b8b4dac2d0488da7428c703384 Mon Sep 17 00:00:00 2001
From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
Date: Thu, 14 Sep 2023 18:01:22 -0400
Subject: [PATCH] docs: add language switcher
---
README.rst | 11 +++
docs/source/_static/css/crowdin-furo.css | 79 ++++++++++++++++++
docs/source/_static/js/crowdin.js | 44 ++++++++++
docs/source/_static/js/crowdin_web_widget.js | 88 ++++++++++++++++++++
docs/source/conf.py | 9 +-
5 files changed, 228 insertions(+), 3 deletions(-)
create mode 100644 docs/source/_static/css/crowdin-furo.css
create mode 100644 docs/source/_static/js/crowdin.js
create mode 100644 docs/source/_static/js/crowdin_web_widget.js
diff --git a/README.rst b/README.rst
index 91f23c6b..7f99dce1 100644
--- a/README.rst
+++ b/README.rst
@@ -2,6 +2,17 @@ Overview
========
LizardByte has the full documentation hosted on `Read the Docs `__.
+This documentation is being localized on `Crowdin `__.
+
+.. image:: https://badges.awesome-crowdin.com/translation-15178612-614257.png
+ :target: https://crowdin.com/project/lizardbyte-docs
+
+.. admonition:: Community!
+
+ Accurate translations depend on contributions from amazing community members, like you! If you would like to
+ contribute to the localization of this documentation, please visit our
+ `Crowdin project `__ or use the widget at the bottom of each page.
+
About
-----
`LizardByte `__ is developing self hosted cloud game streaming solutions.
diff --git a/docs/source/_static/css/crowdin-furo.css b/docs/source/_static/css/crowdin-furo.css
new file mode 100644
index 00000000..6694771d
--- /dev/null
+++ b/docs/source/_static/css/crowdin-furo.css
@@ -0,0 +1,79 @@
+#crowdin-language-picker .cr-picker-button,
+#crowdin-language-picker .cr-picker-submenu {
+ border: 1px solid currentColor;
+
+ /* Set the default theme to light */
+ background-color: white;
+ color: var(--color-code-foreground);
+
+ /* If in dark theme, apply these styles */
+ @media (prefers-color-scheme: dark) {
+ body:not([data-theme="light"]) & {
+ background-color: var(--color-code-background);
+ color: var(--color-code-foreground);
+ border-color: var(--color-foreground-border);
+ }
+ }
+
+ /* If explicitly set to dark theme, apply these styles */
+ & body[data-theme="dark"] & {
+ background-color: var(--color-code-background);
+ color: var(--color-code-foreground);
+ border-color: var(--color-foreground-border);
+ }
+}
+
+#crowdin-language-picker .cr-picker-submenu > a {
+ /* Set the default theme to light */
+ color: var(--color-code-foreground);
+
+ /* If in dark theme, apply these styles */
+ @media (prefers-color-scheme: dark) {
+ body:not([data-theme="light"]) & {
+ color: var(--color-code-foreground);
+ }
+ }
+
+ /* If explicitly set to dark theme, apply these styles */
+ & body[data-theme="dark"] & {
+ color: var(--color-code-foreground);
+ }
+}
+
+#crowdin-language-picker .cr-picker-submenu > a.cr-selected {
+ /* Set the default theme to light */
+ color: #aaaaaa !important;
+
+ /* If in dark theme, apply these styles */
+ @media (prefers-color-scheme: dark) {
+ body:not([data-theme="light"]) & {
+ color: #7e838a !important;
+ }
+ }
+
+ /* If explicitly set to dark theme, apply these styles */
+ & body[data-theme="dark"] & {
+ color: #7e838a !important;
+ }
+}
+
+#crowdjet-container,
+#crowdjet-iframe {
+ /* add border */
+ border-radius: 4px;
+ border-width: 1px;
+ border-style: solid;
+ border-color: var(--color-foreground-border);
+
+ /* If in dark theme, apply these styles */
+ @media (prefers-color-scheme: dark) {
+ body:not([data-theme="light"]) & {
+ border-color: var(--color-foreground-border);
+ }
+ }
+
+ /* If explicitly set to dark theme, apply these styles */
+ & body[data-theme="dark"] & {
+ border-color: var(--color-foreground-border);
+ }
+}
diff --git a/docs/source/_static/js/crowdin.js b/docs/source/_static/js/crowdin.js
new file mode 100644
index 00000000..54ed388f
--- /dev/null
+++ b/docs/source/_static/js/crowdin.js
@@ -0,0 +1,44 @@
+// this script requires jquery to be loaded on the source page, like so...
+//
+
+// use Jquery to load other javascript
+$.getScript('https://proxy-translator.app.crowdin.net/assets/proxy-translator.js', function() {
+ window.proxyTranslator.init({
+ baseUrl: "https://docs.lizardbyte.dev",
+ appUrl: "https://proxy-translator.app.crowdin.net",
+ valuesParams: "U2FsdGVkX19eQczbrFgaLYbrEBP8is5CVpC2YSnXxH/sRjWqaBtQOsLZJbSRMepcn3D2sofzZxALb2pvT3MLmM+WG5EpWSF7CzzYsAOJ+k/FpMUJ1PZ1FQmmlKCIWyD7",
+ distributionBaseUrl: "https://distributions.crowdin.net",
+ filePath: "/docs.lizardbyte.dev.json",
+ distribution: "fb3b3d5c18de9bc717d96b91bw4",
+ languagesData: {
+ "en":{"code":"en","name":"English","twoLettersCode":"en"},
+ "it":{"code":"it","name":"Italian","twoLettersCode":"it"},
+ "es-ES":{"code":"es-ES","name":"Spanish","twoLettersCode":"es"},
+ },
+ defaultLanguage: "en",
+ defaultLanguageTitle: "English",
+ languageDetectType: "default",
+ poweredBy: false,
+ position: "bottom-left",
+ submenuPosition: "top-left",
+ })
+
+ // container
+ let container = document.getElementById('crowdin-language-picker')
+ container.classList.remove('cr-position-bottom-left')
+
+ // change styling of language selector button
+ let button = document.getElementsByClassName('cr-picker-button')[0]
+
+ // container auto width based on content
+ container.style.width = button.offsetWidth + 10 + 'px'
+ container.style.position = 'relative'
+ container.style.left = '10px'
+ container.style.bottom = '10px'
+
+ // get rst versions
+ let sidebar = document.getElementsByClassName('sidebar-sticky')[0]
+
+ // move button to related pages
+ sidebar.appendChild(container)
+})
diff --git a/docs/source/_static/js/crowdin_web_widget.js b/docs/source/_static/js/crowdin_web_widget.js
new file mode 100644
index 00000000..751999d5
--- /dev/null
+++ b/docs/source/_static/js/crowdin_web_widget.js
@@ -0,0 +1,88 @@
+// this script requires jquery to be loaded on the source page, like so...
+//
+
+// use Jquery to load other javascript
+$.getScript('https://crowdin.com/js/crowdjet/crowdjet.js', function() {
+ // crowdin web widget: https://crowdin.com/project/lizardbyte/tools/web-widget
+ // get body
+ let body = document.getElementsByTagName('body')[0]
+
+ // create container (popup)
+ let container = document.createElement('div')
+ container.id = 'crowdjet-container'
+ container.dataset.projectId = '614257'
+ container.style.bottom = '90px'
+ container.style.left = '5px'
+ body.appendChild(container)
+
+ // get sidebar
+ let sidebar = document.getElementsByClassName('sidebar-sticky')[0]
+
+ // create expand container (button)
+ let expandContainer = document.createElement('div')
+ expandContainer.id = 'crowdjet-expand-container'
+ expandContainer.style.position = 'relative'
+ expandContainer.style.bottom = '-25px'
+ expandContainer.style.left = '160px'
+
+ // hide expand container temporarily
+ expandContainer.style.display = 'none'
+
+ sleep(2000).then(() => {
+ expandContainer.style.position = 'relative'
+ })
+
+ sidebar.appendChild(expandContainer)
+
+ sleep(2000).then(() => {
+ // get html of crowdjet-expand-iframe
+ let iframe = document.getElementById('crowdjet-expand-iframe');
+ let iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
+ let htmlTag = iframeDoc.getElementsByTagName('html')[0];
+
+ // get html of crowdjet-iframe
+ let iframe2 = document.getElementById('crowdjet-iframe');
+ let iframeDoc2 = iframe2.contentDocument || iframe2.contentWindow.document;
+ let htmlTag2 = iframeDoc2.getElementsByTagName('html')[0];
+
+ updateIframeStyles(htmlTag);
+ updateIframe2Styles(htmlTag2);
+
+ // show expand container
+ expandContainer.style.display = 'block'
+
+ // Set up mutation observer to watch for changes in the data-theme attribute
+ const observer = new MutationObserver((mutationsList, observer) => {
+ for(let mutation of mutationsList) {
+ if (mutation.attributeName === 'data-theme') {
+ updateIframeStyles(htmlTag);
+ updateIframe2Styles(htmlTag2);
+ }
+ }
+ });
+
+ observer.observe(document.body, { attributes: true, attributeFilter: ['data-theme'] });
+ })
+
+ function updateIframeStyles(htmlTag) {
+ let element = document.querySelector('.sidebar-sticky');
+ let colorValue;
+
+ if (element) {
+ colorValue = getComputedStyle(element).getPropertyValue('--color-sidebar-background').trim();
+ }
+
+ htmlTag.style.backgroundColor = colorValue;
+ }
+
+ function updateIframe2Styles(htmlTag) {
+ let element = document.querySelector('.content');
+ let colorValue;
+
+ if (element) {
+ colorValue = getComputedStyle(element).getPropertyValue('--color-background-primary').trim();
+ }
+
+ htmlTag.style.backgroundColor = colorValue;
+ }
+})
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 1f18e592..b0ec59cf 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -69,12 +69,15 @@
# These paths are either relative to html_static_path
# or fully qualified paths (eg. https://...)
-# html_css_files = [
-# 'css/custom.css',
-# ]
+html_css_files = [
+ 'css/crowdin-furo.css',
+]
html_js_files = [
'https://app.lizardbyte.dev/node_modules/jquery/dist/jquery.min.js', # jquery, required for ajax request
'https://app.lizardbyte.dev/js/ranking_sorter.js', # ranking sorter, required to sort projects
+ 'https://app.lizardbyte.dev/js/sleep.js', # sleep, used to delay repositioning of crowdin elements
+ 'js/crowdin.js', # crowdin language selector
+ 'js/crowdin_web_widget.js', # crowdin translation widget
'js/projects.js', # load projects with readthedocs documentation
]