diff --git a/.github/ci-generateTranslations.js b/.github/ci-generateTranslations.js new file mode 100644 index 0000000..54fb452 --- /dev/null +++ b/.github/ci-generateTranslations.js @@ -0,0 +1,168 @@ +var https = require("https"); +const jsdom = require("jsdom"); +const { JSDOM } = jsdom; +const axios = require("axios").default; +const fs = require("fs"); + +const dom = new JSDOM(``, { + url: "https://obs.ninja", + contentType: "text/html", + includeNodeLocations: true, + storageQuota: 10000000, + pretendToBeVisual: true, +}); + +global.document = new JSDOM(``, { + url: "https://obs.ninja", + contentType: "text/html", + includeNodeLocations: true, + storageQuota: 10000000, + pretendToBeVisual: false, +}).window.document; + +function downloadTranslation(filename, trans = {}) { + // downloads the current translation to a file + console.log("Downloading translation: " + filename); + const textDoc = JSON.stringify(trans, null, 2); + + fs.writeFile(`translations/${filename}.json`, textDoc, function (err) { + if (err) { + return console.log(err); + } + }); + + return trans; +} + +async function updateTranslation(filename) { + // updates the website with a specific translation + let data = await axios({ + method: "get", + url: `https://raw.githubusercontent.com/steveseguin/obsninja/master/translations/${filename}.json?${( + Math.random() * 100 + ).toString()}`, + }) + .then(function (response) { + return response.data; + }) + .catch(function (error) { + console.log(error); + }); + + const oldTransItems = data["innerHTML"]; + + // const allItems1 = document.querySelectorAll('[data-translate]'); + + allItems.forEach((ele) => { + const key = ele.dataset.translate; //.replace(/[\W]+/g, "-").toLowerCase(); + if (key in oldTransItems) { + ele.innerHTML = oldTransItems[key]; + } + }); + + const oldTransTitles = data["titles"]; + //const allTitles1 = document.querySelectorAll('[title]'); + allTitles.forEach((ele) => { + const key = ele.dataset.key; + //const key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); + if (key in oldTransTitles) { + ele.title = oldTransTitles[key]; + } + }); + + const oldTransPlaceholders = data.placeholders; + //const allPlaceholders1 = document.querySelectorAll('[placeholder]'); + allPlaceholders.forEach((ele) => { + const key = ele.dataset.key; + //const key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); + if (key in oldTransPlaceholders) { + ele.placeholder = oldTransPlaceholders[key]; + } + }); + + return [true, data]; +} + +const updateList = [ + "cs", + "de", + "en", + "es", + "fr", + "it", + "ja", + "nl", + "pig", + "pt", + "ru", + "tr", + "blank", +]; // list of languages to update. Update this if you add a new language. + +const allItems = document.querySelectorAll("[data-translate]"); +const defaultTrans = {}; +allItems.forEach((ele) => { + const key = ele.dataset.translate; //.replace(/[\W]+/g, "-").toLowerCase(); + defaultTrans[key] = ele.innerHTML; +}); + +const defaultTransTitles = {}; +const allTitles = document.querySelectorAll("[title]"); +allTitles.forEach((ele) => { + const key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); + ele.dataset.key = key; + defaultTransTitles[key] = ele.title; +}); + +const defaultTransPlaceholders = {}; +const allPlaceholders = document.querySelectorAll("[placeholder]"); +allPlaceholders.forEach((ele) => { + const key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); + ele.dataset.key = key; + defaultTransPlaceholders[key] = ele.placeholder; +}); + +const combinedTrans = {}; +combinedTrans.titles = defaultTransTitles; +combinedTrans.innerHTML = defaultTrans; +combinedTrans.placeholders = defaultTransPlaceholders; + +var counter = 0; +for (var i = 0; i < updateList.length; i++) { + const lang = updateList[i]; + + var translation = updateTranslation(lang); // we don't need to worry about DATA. + updateTranslation(lang) + .then(function (translation) { + const newTrans = translation[1]["innerHTML"]; + //const allItems = document.querySelectorAll('[data-translate]'); + allItems.forEach((ele) => { + const key = ele.dataset.translate; //.replace(/[\W]+/g, "-").toLowerCase(); + newTrans[key] = ele.innerHTML; + }); + + const newTransTitles = translation[1]["titles"]; + //const allTitles = document.querySelectorAll('[title]'); + allTitles.forEach((ele) => { + const key = ele.dataset.key; + newTransTitles[key] = ele.title; + }); + + const newPlaceholders = translation[1]["placeholders"]; + // const allPlaceholders = document.querySelectorAll('[placeholder]'); + allPlaceholders.forEach((ele) => { + const key = ele.dataset.key; + newPlaceholders[key] = ele.placeholder; + }); + + // //// DOWNLOAD UPDATED TRANSLATION + const outputTrans = {}; + outputTrans["titles"] = newTransTitles; + outputTrans["innerHTML"] = newTrans; + outputTrans["placeholders"] = newPlaceholders; + downloadTranslation(lang, outputTrans); + }) + .catch(function (error) { + console.log(error); + }); +} diff --git a/.github/workflows/update_translations.yml b/.github/workflows/update_translations.yml new file mode 100644 index 0000000..370ebb1 --- /dev/null +++ b/.github/workflows/update_translations.yml @@ -0,0 +1,39 @@ +# This is a basic workflow to help you get started with Actions + +name: Update translations + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + paths: + - 'index.html' + - 'main.js' + branches: + - master + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '14' + - run: npm install jsdom && npm install axios + - run: node .github/ci-generateTranslations.js + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + commit-message: Generated updated translations + branch: generated_translations + title: "[OBSNinja Bot] Updated translations" + labels: i18n diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ccb2c80 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +package-lock.json \ No newline at end of file diff --git a/main.css b/main.css index 3a74985..0c271a5 100644 --- a/main.css +++ b/main.css @@ -753,6 +753,11 @@ body { margin: 20px; padding: 10px 50px; } +.gowebcam:enabled { + background-color: #3C3; + color: black; + font-weight: bold; +} .mainmenuclass { display: inherit; diff --git a/main.js b/main.js index 155ad38..ea4f9ec 100644 --- a/main.js +++ b/main.js @@ -7651,9 +7651,6 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel if (gowebcam) { gowebcam.disabled = false; gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#3C3"; - gowebcam.style.color = "black"; - gowebcam.style.fontWeight = "bold"; gowebcam.innerHTML = "START"; miniTranslate(gowebcam, "start"); } @@ -7845,9 +7842,6 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel if (gowebcam) { gowebcam.disabled = false; gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#3C3"; - gowebcam.style.color = "black"; - gowebcam.style.fontWeight = "bold"; gowebcam.innerHTML = "START"; miniTranslate(gowebcam, "start"); } @@ -8111,9 +8105,6 @@ async function grabAudio(eleName = "previewWebcam", selector = "#audioSource", t if (gowebcam) { gowebcam.disabled = false; gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#3C3"; - gowebcam.style.color = "black"; - gowebcam.style.fontWeight = "bold"; gowebcam.innerHTML = "START"; miniTranslate(gowebcam, "start"); } @@ -9867,9 +9858,6 @@ function setupWebcamSelection(stream = null) { if (gowebcam) { gowebcam.disabled = false; gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#3C3"; - gowebcam.style.color = "black"; - gowebcam.style.fontWeight = "bold"; gowebcam.innerHTML = "START"; miniTranslate(gowebcam, "start"); } @@ -10068,9 +10056,6 @@ function previewWebcam() { gowebcam.style.display = ""; gowebcam.disabled = false; gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#3C3"; - gowebcam.style.color = "black"; - gowebcam.style.fontWeight = "bold"; gowebcam.innerHTML = "START"; miniTranslate(gowebcam, "start"); }