diff --git a/.circleci/config.yml b/.circleci/config.yml index 62dc1183..2d7b5b75 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,21 +1,26 @@ version: 2.1 -orbs: # adds orbs to your configuration - jira: circleci/jira@1.0.5 # invokes the Jira orb, making its commands accessible -branches: - only: - - main - - develop -jobs: - build: - working_directory: ~/Cider + +executors: + cider-ci: docker: - image: circleci/node:16 - + working_directory: ~/Cider + +orbs: # Add orbs to your configuration + jira: circleci/jira@1.0.5 # invokes the Jira orb, making its commands accessible + +# The jobs for this project +jobs: + prepare-build: + executor: cider-ci steps: - checkout - run: name: Set App Version command: echo "export APP_VERSION=$(grep '"version":.*' package.json | cut -d '"' -f 4 | head -1)" >> $BASH_ENV + # - run: + # name: Rename Repository + # command: sed -i 's/github:ciderapp\/Cider/github:ciderapp\/cider-releases/' package.json - run: name: Update Package Managers command: sudo npm update -g npm yarn @@ -24,7 +29,7 @@ jobs: keys: - yarn-packages-{{ checksum "cider.lock" }} - run: - name: Install Dependencies + name: Install Node Dependencies command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn - save_cache: name: Save Yarn Package Cache @@ -32,50 +37,160 @@ jobs: paths: - ~/.cache/yarn - run: - name: Install system build dependencies - command: | - sudo apt-get update -y - curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null - sudo apt-get install -y dpkg fakeroot wine64 - sudo dpkg --add-architecture i386 - sudo apt-get update -y - sudo apt-get install -y wine32 - sudo apt install -y gh + name: TypeScript Compile + command: yarn build + - persist_to_workspace: + # Must be an absolute path, or relative path from working_directory. This is a directory on the container which is + # taken to be the root directory of the workspace. + root: . + # Must be relative path from root + paths: + - node_modules + - build + - resources + - yarn.lock + - package.json + - winget.json # winget.json is a file that is generated by the winget package manager + - LICENSE + - license.txt + + build-linux: + executor: cider-ci + steps: + - attach_workspace: + at: ~/Cider - run: name: Fix Versioning and Add Channel command: yarn circle:script - - run: - name: TypeScript Compile - command: yarn build - run: name: Generate Builds (Linux) command: yarn electron-builder -l -p never post-steps: - jira/notify + - persist_to_workspace: + root: . + paths: + - dist/*.deb + - dist/*.AppImage + - dist/*.snap + - dist/latest-linux.yml + + build-windows: + executor: cider-ci + steps: + - attach_workspace: + at: ~/Cider + - run: + name: Install Windows System Build Dependencies + command: | + sudo apt-get update -y + sudo apt-get install -y dpkg fakeroot wine64 + sudo dpkg --add-architecture i386 + sudo apt-get update -y + sudo apt-get install -y wine32 + - run: + name: Fix Versioning and Add Channel + command: yarn circle:script - run: name: Generate Builds (Windows) command: yarn electron-builder -w --x64 -p never post-steps: - jira/notify + - persist_to_workspace: + root: . + paths: + - dist/*.exe + - dist/Cider-Setup-*.exe.blockmap + - dist/latest.yml + + build-winget: + executor: cider-ci + steps: + - attach_workspace: + at: ~/Cider + - run: + name: Install Windows System Build Dependencies + command: | + sudo apt-get update -y + sudo apt-get install -y dpkg fakeroot wine64 + sudo dpkg --add-architecture i386 + sudo apt-get update -y + sudo apt-get install -y wine32 + - run: + name: Fix Versioning and Add Channel + command: yarn circle:script - run: name: Generate Builds (Winget) command: yarn electron-builder --win -c winget.json -p never post-steps: - jira/notify + - persist_to_workspace: + root: . + paths: + - dist/*.exe + - dist/Cider-Setup-winget-*.exe.blockmap + + release: + executor: cider-ci + steps: + - attach_workspace: + at: ~/Cider/ + - run: + name: Installing GitHub Command Line Interface + command: | + sudo apt-get update -y + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null + sudo apt-get update -y + sudo apt install -y gh - run: name: Move Build Files command: | - mkdir ~/Cider/dist/artifacts/ - mv ~/Cider/dist/*.exe ~/Cider/dist/artifacts - mv ~/Cider/dist/*.deb ~/Cider/dist/artifacts - mv ~/Cider/dist/*.AppImage ~/Cider/dist/artifacts - mv ~/Cider/dist/*.snap ~/Cider/dist/artifacts - mv ~/Cider/dist/*.yml ~/Cider/dist/artifacts - mv ~/Cider/dist/*.blockmap ~/Cider/dist/artifacts + mkdir ~/Cider/dist/artifacts/ + mv ~/Cider/dist/*.exe ~/Cider/dist/artifacts + mv ~/Cider/dist/*.deb ~/Cider/dist/artifacts + mv ~/Cider/dist/*.AppImage ~/Cider/dist/artifacts + mv ~/Cider/dist/*.snap ~/Cider/dist/artifacts + mv ~/Cider/dist/*.yml ~/Cider/dist/artifacts + mv ~/Cider/dist/*.blockmap ~/Cider/dist/artifacts - store_artifacts: - path: ~/Cider/dist/artifacts + path: ~/Cider/dist/artifacts - run: name: Publish Release command: | - gh release create "v${APP_VERSION}.${CIRCLE_BUILD_NUM}" --title "Cider Version ${APP_VERSION} - Build ${CIRCLE_BUILD_NUM} (${CIRCLE_BRANCH})" --generate-notes -R ciderapp/cider-releases ~/Cider/dist/artifacts/*.deb ~/Cider/dist/artifacts/*.AppImage ~/Cider/dist/artifacts/*.snap ~/Cider/dist/artifacts/*.exe ~/Cider/dist/artifacts/*.yml ~/Cider/dist/artifacts/*.blockmap + gh release create "v${APP_VERSION}.${CIRCLE_BUILD_NUM}" --title "Cider Version ${APP_VERSION} - Build ${CIRCLE_BUILD_NUM} (${CIRCLE_BRANCH})" --generate-notes -R ciderapp/cider-releases ~/Cider/dist/artifacts/*.deb ~/Cider/dist/artifacts/*.AppImage ~/Cider/dist/artifacts/*.snap ~/Cider/dist/artifacts/*.exe ~/Cider/dist/artifacts/*.yml ~/Cider/dist/artifacts/*.blockmap + +# Orchestrate our job run sequence +workflows: + build_and_release: + jobs: + - prepare-build: + filters: + branches: + only: main + - build-windows: + requires: + - prepare-build + filters: + branches: + only: main + - build-linux: + requires: + - prepare-build + filters: + branches: + only: main + - build-winget: + requires: + - prepare-build + filters: + branches: + only: main + - release: + requires: + - build-windows + - build-linux + - build-winget + filters: + branches: + only: main diff --git a/package.json b/package.json index b7347a4f..9c22e95d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "airtunes2": "git+https://github.com/vapormusic/node_airtunes2.git#hap", "castv2-client": "^1.2.0", "chokidar": "^3.5.3", - "discord-rpc": "^4.0.1", + "discord-auto-rpc": "^1.0.16", "dns-js": "git+https://github.com/ciderapp/node-dns-js.git", "ejs": "^3.1.6", "electron-fetch": "^1.7.4", @@ -82,7 +82,7 @@ "electron-builder-notarize-pkg": "^1.2.0", "electron-webpack": "^2.8.2", "musickit-typescript": "^1.2.4", - "typescript": "^4.6.3", + "typescript": "^4.6.4", "vue-devtools": "^5.1.4", "webpack": "~5.72.0" }, @@ -109,9 +109,9 @@ } ], "build": { - "electronVersion": "18.2.0", + "electronVersion": "18.2.1", "electronDownload": { - "version": "18.2.0+wvcus", + "version": "18.2.1+wvcus", "mirror": "https://github.com/castlabs/electron-releases/releases/download/v" }, "appId": "cider", diff --git a/resources/circle.js b/resources/circle.js index dcf1d0ef..80e7c8cf 100644 --- a/resources/circle.js +++ b/resources/circle.js @@ -1,53 +1,46 @@ - - if (!process.env['CIRCLECI']) { - console.log(`[CIRCLECI SCRIPT] CircleCI not found... Aborting script`) - return + console.log(`[CIRCLECI SCRIPT] CircleCI not found... Aborting script`) + return } -let fs = require('fs') +const {readFileSync, writeFile} = require('fs') +const pkg = JSON.parse(readFileSync('package.json').toString()); +let channel = process.env['CIRCLE_BRANCH']; -var data = fs.readFileSync('package.json'); -var package = JSON.parse(data); - - - -let channel; if (process.env['CIRCLE_BRANCH'] === 'lts') { - channel = 'latest' + channel = 'latest' } else if (process.env['CIRCLE_BRANCH'] === 'main') { - channel = 'beta' + channel = 'beta' } else if (process.env['CIRCLE_BRANCH'] === 'develop') { - channel = 'alpha' -} else { - channel = process.env['CIRCLE_BRANCH'] // It won't have auto update support + channel = 'alpha' } - +channel = channel.split('/').join('-') // https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables -var pvers = package.version.split('.') -package.version = `${pvers[0]}.${pvers[1]}.${pvers[2]}-${channel}.${process.env['CIRCLE_BUILD_NUM']}` +const version = pkg.version.split('.'); +pkg.version = `${version[0]}.${version[1]}.${version[2]}-${channel}` // package.build.channel = channel -package.publish = { - "provider": "github", - "repo": "cider-releases", - "owner": "ciderapp", - "vPrefixedTagName": true, - "tag": `v${package.version}`, - "channel": channel, - "releaseType": "release" +pkg.publish = { + "provider": "github", + "repo": "cider-releases", + "owner": "ciderapp", + "vPrefixedTagName": true, + "tag": `v${pkg.version}`, + "channel": channel, + "releaseType": "release" } -let {exec} = require('child_process') -exec('echo $APP_VERSION', {env: {'APP_VERSION': package.version}}, function (error, stdout, stderr) -{ - console.log(stdout, stderr, error); -}); -fs.writeFile('package.json', JSON.stringify(package), err => { - // error checking - if(err) throw err; - console.log(`VERSION CHANGED TO ${package.version}`); +const {exec} = require('child_process') + +exec('echo $APP_VERSION', {env: {'APP_VERSION': pkg.version}}, function (error, stdout, stderr) { + console.log(stdout, stderr, error); +}); + +writeFile('package.json', JSON.stringify(pkg), err => { + // error checking + if (err) throw err; + console.log(`VERSION CHANGED TO ${pkg.version}`); }); diff --git a/src/i18n/README.md b/src/i18n/README.md index 4246957d..3422daa7 100644 --- a/src/i18n/README.md +++ b/src/i18n/README.md @@ -297,5 +297,44 @@ Update 28/04/2022 21:45 UTC * `settings.option.general.resumetabs.description`: Added for `en_US` * `settings.option.general.resumetabs.dynamic`: Added for `en_US` * `settings.option.general.resumetabs.dynamic.description`: Added for `en_US` +* `term.dynamic`: Added for `en_US` + +Update 29/04/2022 00:00 UTC + + * `menubar.options.about`: Added for `en_US` + * `menubar.options.settings`: Added for `en_US` + * `menubar.options.quit`: Added for `en_US` + * `menubar.options.view`: Added for `en_US` + * `menubar.options.reload`: Added for `en_US` + * `menubar.options.forcereload`: Added for `en_US` + * `menubar.options.toggledevtools`: Added for `en_US` + * `menubar.options.window`: Added for `en_US` + * `menubar.options.minimize`: Added for `en_US` + * `menubar.options.toggleprivate`: Added for `en_US` + * `menubar.options.webremote`: Added for `en_US` + * `menubar.options.audio`: Added for `en_US` + * `menubar.options.plugins`: Added for `en_US` + * `menubar.options.control`: Added for `en_US` + * `menubar.options.next`: "Added for `en_US` + * `menubar.options.previous`: Added for `en_US` + * `menubar.options.volumeup`: Added for `en_US` + * `menubar.options.volumedown`: Added for `en_US` + * `menubar.options.browse`: Added for `en_US` + * `menubar.options.artists`: Added for `en_US` + * `menubar.options.search`: Added for `en_US` + * `menubar.options.albums`: Added for `en_US` + * `menubar.options.cast`: Added for `en_US` + * `menubar.options.account`: Added for `en_US` + * `menubar.options.accountsettings`: Added for `en_US` + * `menubar.options.signout`: Added for `en_US` + * `menubar.options.support`: Added for `en_US` + * `menubar.options.discord`: Added for `en_US` + * `menubar.options.github`: Added for `en_US` + * `menubar.options.report`: Added for `en_US` + * `menubar.options.bug`: Added for `en_US` + * `menubar.options.feature`: Added for `en_US` + * `menubar.options.trans`: Added for `en_US` + * `menubar.options.license`: Added for `en_US` + * `menubar.options.conf`: Added for `en_US` diff --git a/src/i18n/el_GR.json b/src/i18n/el_GR.json index eda64396..2c7843c6 100644 --- a/src/i18n/el_GR.json +++ b/src/i18n/el_GR.json @@ -10,6 +10,7 @@ "notification.updatingLibrarySongs": "Ενημέρωση βιβλιοθήκης τραγουδιών...", "notification.updatingLibraryAlbums": "Ενημέρωση βιβλιοθήκης άλμπουμ...", "notification.updatingLibraryArtists": "Ενημέρωση βιβλιοθήκης καλλιτεχνών...", + "term.variables": "Μεταβλητές", "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", "term.applePodcasts": "Apple Podcasts", @@ -20,9 +21,13 @@ "term.accountSettings": "Ρυθμίσεις λογαριασμού", "term.logout": "Αποσύνδεση", "term.login": "Σύνδεση", + "term.cast": "Μετάδοση", "term.about": "Σχετικά με", "term.privateSession": "Ιδιωτική περίοδος λειτουργίας", + "term.disablePrivateSession": "Απενεργ. ιδιωτικής περ. λειτουργίας", "term.queue": "Ουρά", + "term.lyrics": "Στίχοι", + "term.miniplayer": "MiniPlayer", "term.history": "Ιστορικό", "term.search": "Εύρεση", "term.library": "Βιβλιοθήκη", @@ -68,6 +73,7 @@ "term.viewAs": "Προβολή ως", "term.viewAs.coverArt": "Εξώφυλλο", "term.viewAs.list": "Λίστα", + "term.dynamic": "Δυναμικό", "term.size": "Μέγεθος", "term.size.normal": "Κανονικό", "term.size.compact": "Συμπαγή", @@ -89,12 +95,26 @@ "term.time.added": "Προστέθηκε", "term.time.released": "Κυκλοφόρησε", "term.time.updated": "Ενημερώθηκε", + "term.time.days": "μέρες", + "term.time.day": { + "one": "μέρα", + "other": "μέρες" + }, "term.time.hours": "ώρες", - "term.time.hour": "ώρα", + "term.time.hour": { + "one": "ώρα", + "other": "ώρες" + }, "term.time.minutes": "λεπτά", - "term.time.minute": "λεπτό", + "term.time.minute": { + "one": "λεπτό", + "other": "λεπτά" + }, "term.time.seconds": "δευτερόλεπτα", - "term.time.second": "δευτερόλεπτο", + "term.time.second": { + "one": "δευτερόλεπτο", + "other": "δευτερόλεπτα" + }, "term.fullscreenView": "Πλήρης οθόνη", "term.defaultView": "Κανονική οθόνη", "term.audioSettings": "Ρυθμίσεις ήχου", @@ -114,7 +134,8 @@ "term.contributors": "Συνεισφέροντες", "term.equalizer": "Ισοσταθμιστής", "term.reset": "Επαναφορά", - "term.tracks": { + "term.tracks": "τραγούδια", + "term.track": { "one": "τραγούδι", "other": "τραγούδια" }, @@ -145,6 +166,7 @@ "term.noVideos": "Δεν βρέθηκαν βίντεο", "term.plugin": "Πρόσθετα", "term.pluginMenu": "Μενού πρόσθετων", + "term.pluginMenu.none": "Δεν υπάρχουν πρόσθετα", "term.replay": "Replay", "term.uniqueAlbums": "Μοναδικά άλμπουμ", "term.uniqueArtists": "Μοναδικοί καλλιτέχνες", @@ -156,10 +178,12 @@ "term.plays": "Αναπαραγωγές", "term.topGenres": "Κορυφαία είδη", "term.confirmLogout": "Θέλετε σίγουρα να αποσυνδεθείτε;", + "term.creditDesignedBy": "Σχεδιάστηκε από ${authorUsername}", + "term.discNumber": "Δίσκος ${discNumber}", "home.title": "Αρχική", "home.recentlyPlayed": "Έπαιξαν πρόσφατα", "home.recentlyAdded": "Πρόσφατες προσθήκες", - "home.artistsFeed": "Ροή των καλλιτεχνών σου", + "home.artistsFeed": "Ροή των καλλιτεχνών σας", "home.artistsFeed.noArtist": "Ακολούθησε μερικούς καλλιτέχνες πρώτα και οι τελευταίες κυκλοφορίες τους θα εμφανίζονται εδώ", "home.madeForYou": "Δημιουργήθηκε για εσάς", "home.friendsListeningTo": "Οι φίλοι σου ακούν", @@ -176,6 +200,9 @@ "podcast.episodes": "Επεισόδια", "podcast.playEpisode": "Αναπαραγωγή επεισοδίου", "podcast.website": "Ιστότοπος Podcast", + "action.edit": "Επεξεργασία", + "action.done": "Τέλος", + "action.editTracklist": "Επεξεργασία λίστας τραγουδιών", "action.addToLibrary": "Προσθήκη στη βιβλιοθήκη", "action.addToLibrary.success": "Προστέθηκε στη βιβλιοθήκη", "action.addToLibrary.error": "Σφάλμα Προσθήκης στη βιβλιοθήκης", @@ -202,6 +229,8 @@ "action.startRadio": "Έναρξη ραδιοφώνου", "action.goToArtist": "Μετάβαση σε καλλιτέχνη", "action.goToAlbum": "Μετάβαση σε άλμπουμ", + "action.showInPlaylist": "Εμφάνιση στη λίστα αναπαραγωγής", + "action.showInAppleMusic": "Εμφάνιση στο Apple Music", "action.moveToTop": "Μετακίνηση στη κορυφή", "action.share": "Κοινή χρήση", "action.rename": "Μετονομασία", @@ -209,7 +238,7 @@ "action.unlove": "Αναίρεση \"Μου αρέσει\"", "action.dislike": "Δεν μου αρέσει", "action.undoDislike": "Αναίρεση \"Δεν μου αρέσει\"", - "action.showWebRemoteQR": "Εμφάνιση Web Remote QR", + "action.showWebRemoteQR": "Web Remote", "action.playTracksNext": "Αναπαραγωγή ${app.selectedMediaItems.length} τραγουδιών ως επόμενων", "action.playTracksLater": "Αναπαραγωγή ${app.selectedMediaItems.length} τραγουδιών αργότερα", "action.removeTracks": "Αφαίρεση ${self.selectedItems.length} τραγουδιών από την ουρά", @@ -218,13 +247,23 @@ "action.showAlbum": "Εμφάνιση ολόκληρου άλμπουμ", "action.tray.minimize": "Ελαχιστοποίηση στη γωνία γραμμής εργασιών", "action.tray.quit": "Έξοδος", - + "action.tray.show": "Εμφάνιση Cider", "action.update": "Ενημέρωση", "action.install": "Εγκατάσταση", "action.copy": "Αντιγραφή", "action.newpreset": "Νέα προρύθμιση...", "action.deletepreset": "Διαγραφή προρύθμισης", "action.open": "Άνοιγμα", + "action.relaunch.confirm": "Θέλετε να επανεκκινήσετε τον Cider;", + "action.cast.chromecast": "Chromecast", + "action.cast.todevices": "Μετάδοση σε συσκευές", + "action.cast.stop": "Διακοπή μετάδοσης σε όλες τις συσκευές", + "action.cast.airplay": "AirPlay", + "action.cast.airplay.underdevelopment": "Το AirPlay είναι ακόμη υπό ανάπτυξη", + "action.cast.scan": "Σάρωση", + "action.cast.scanning": "Γίνεται σάρωση...", + "action.createNew": "Δημιουργία νέας...", + "action.openArtworkInBrowser": "Άνοιγμα εξώφυλλου στον περιηγητή", "settings.header.general": "Γενικά", "settings.header.general.description": "Προσαρμογή γενικών ρυθμίσεων για το Cider.", "settings.option.general.language": "Γλώσσα", @@ -234,6 +273,10 @@ "settings.option.general.resumebehavior.locally.description": "Το Cider θα συνεχίσει την τελευταία συνεδρία σας αυτής της συσκευής.", "settings.option.general.resumebehavior.history": "Ιστορικό", "settings.option.general.resumebehavior.history.description": "Το Cider θα βάλει στην ουρά το τελευταίο τραγούδι από το συνολικό ιστορικό Apple Music, όλων των συσκευών σας.", + "settings.option.general.resumetabs": "Άνοιγμα καρτέλας στην εκκίνηση", + "settings.option.general.resumetabs.description": "Μπορείτε να επιλέξετε ποια καρτέλα θα εμφανίζεται όταν ανοίγετε τον Cider.", + "settings.option.general.resumetabs.dynamic": "Δυναμικό", + "settings.option.general.resumetabs.dynamic.description": "Ο Cider θα ανοίγει την καρτέλα που χρησιμοποιήσατε τελευταία.", "settings.option.general.language.main": "Γλώσσες", "settings.option.general.language.fun": "Γλώσσες για πλάκα", "settings.option.general.language.unsorted": "Αταξινόμητες", @@ -242,10 +285,34 @@ "settings.option.general.updateCider.branch.description": "Επιλέξτε τον κλάδο στον οποίο θα γίνεται η ενημέρωση του Cider", "settings.option.general.updateCider.branch.main": "Σταθερό", "settings.option.general.updateCider.branch.develop": "Αναπτυξιακό", + "settings.option.general.customizeSidebar": "Προσαρμογή στοιχείων πλευρικής μπάρας", + "settings.option.general.customizeSidebar.customize": "Προσαρμογή", + "settings.option.general.keybindings": "Συνδυασμοί πλήκτρων", + "settings.notyf.general.keybindings.update.success": "Ο συνδιασμός ενημερώθηκε με επιτυχία", + "settings.prompt.general.keybindings.update.success": "Ο συνδιασμός ενημερώθηκε με επιτυχία. Πατήστε ΟΚ για επανεκκίνηση του Cider", + "settings.option.general.keybindings.open": "Άνοιγμα", + "settings.description.search": "Αναζήτηση", + "settings.description.albums": "Άλμπουμ βιβλιοθήκης", + "settings.description.artists": "Καλλιτέχνες βιβλιοθήκης", + "settings.description.browse": "Περιήγηση", + "settings.description.private": "Εναλλαγή ιδιωτικής περιόδου λειτουργίας", + "settings.description.remote": "Web Remote", + "settings.description.audio": "Ρυθμίσεις ήχου", + "settings.description.plugins": "Μενού πρόσθετων", + "settings.description.cast": "Μετάδοση σε συσκευές", + "settings.description.settings": "Ρυθμίσεις", + "settings.description.developer": "Εργαλεία προγραμματιστή", + "settings.notyf.updateCider.update-not-available": "Δεν υπάρχει διαθέσιμη ενημέρωση", + "settings.notyf.updateCider.update-downloaded": "Έγινε λήψη της ενημέρωσης, επανεκκίνησε για εφαρμογή", + "settings.notyf.updateCider.update-error": "Σφάλμα ενημέρωσης του Cider", + "settings.notyf.updateCider.update-timeout": "Λήξη χρόνου ενημέρωσης", "settings.header.audio": "Ήχος", "settings.header.audio.description": "Προσαρμογή ρυθμίσεων ήχου για το Cider.", "settings.option.audio.volumeStep": "Βήματα έντασης", "settings.option.audio.maxVolume": "Μέγιστη ένταση", + "settings.option.audio.changePlaybackRate": "Αλλαγή ταχύτητας αναπαραγωγής", + "settings.option.audio.playbackRate": "Ταχύτητα αναπαραγωγής", + "settings.option.audio.playbackRate.change": "Αλλαγή", "settings.option.audio.quality": "Ποιότητα ήχου", "settings.header.audio.quality.hireslossless": "Lossless υψηλής ανάλυσης", "settings.header.audio.quality.hireslossless.description": "έως και 24-bit/192 kHz", @@ -258,18 +325,34 @@ "settings.option.audio.seamlessTransition": "Αδιάκοπη μετάβαση ήχου", "settings.option.audio.enableAdvancedFunctionality": "Ενεργοποίηση προηγμένης λειτουργικότητας", "settings.option.audio.enableAdvancedFunctionality.description": "Ενεργοποιώντας τη λειτουργικότητα AudioContext θα επιτρέψει σε επεκταμένες δυνατότητες ήχου όπως Κανονικοποίηση Έντασης Ήχου, Ισοσταθμιστές και Οπτικοποιητές, ωστόσο σε κάποια συστήματα μπορεί να προκαλέσει τραύλισμα ήχου.", + "settings.warn.audio.enableAdvancedFunctionality.lowcores": "Η συσκευή σου ίσως να μη μπορέσει να χειρηστεί αυτές τις δυνατότητες. Σίγουρα θέλετε να συνεχίσετε;", "settings.option.audio.audioLab": "Cider Audio Lab", - "settings.option.audio.audioLab.description": "Περιέχει μια ποικιλία από τροποποιήσεις ήχου που έγιναν από την ομάδα προγραμματιστών του Cider", + "settings.option.audio.audioLab.description": "Μια ποικιλία τροποποιήσεων ήχου από την ομάδα προγραμματιστών του Cider.", + "settings.option.audio.audioLab.subheader": "Σχεδιάστηκε από τους προγραμματιστές του Cider", "settings.warn.audioLab.withoutAF": "Το AudioContext (προηγμένη λειτουργικότητα) απαιτείται για την ενεργοποίηση του Cider Audio Laboratory.", - "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Ένταση Analog Warmth", - "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Αλλάζει την ένταση της επεξεργασίας του Analog Warmth Module.", + "settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Αναλογική ζεστασιά", + "settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Προσομοιώνει την αναλογική ζεστασιά του Korg Nutube 6P1", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Ένταση αναλογικής ζεστασιάς", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Αλλάζει την ένταση της επεξεργασίας της αναλογικής ζεστασιάς.", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "Λείο", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "Θερμό", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Ατμόσφαιρα ήχου", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Εφαρμόζει μια διαφορετική ατμόσφαιρα στον ήχο.", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Λειτουργία ατμόσφαιρας ήχου", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Αλλάζει τη λειτουργία ατμόσφαιρας ήχου.", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural1": "Φυσική (Κανονικό)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural2": "Φυσική (Υψηλό)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural3": "Φυσική (Υψηλότερο)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Επεξεργαστής ήχου Cider (CAP)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Βελτιώνει την αντιληπτή ποιότητα ήχου χρησιμοποιώντας αλγορίθμους.", "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "Το CAP δεν είναι συμβατό με τη Χωρικοποίηση Ήχου. Παρακαλούμε απενεργοποιήστε τη Χωρικοποίηση Ήχου για να συνεχίσετε.", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Ένταση CAP", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Αλλάζει την ένταση της επεξεργασίας του ήχου. (Η επιθετική επεξεργασία μπορεί να αποφέρει ανεπιθύμητα αποτελέσματα)", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Κανονική", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Επιθετική", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Κανονικοποίηση Έντασης Ήχου", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Κανονικοποιεί την ένταση για μεμονωμένα κομμάτια για μια πιο ομοιόμορφη εμπειρία ακρόασης.", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Κανονικοποίηση έντασης ήχου", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Κανονικοποιεί την ένταση για μεμονωμένα κομμάτια για μια πιο ομοιόμορφη εμπειρία ακρόασης. (Δεν λειτουργεί σε κομμάτια που ανέβηκαν από χρήστες)", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Διαχειρίζεται από το Audio Lab", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Χωρικοποίηση Ήχου", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Πιο τρισδιάστατος και χωρικοποιημένος ήχος (σημείωση: Αυτό δεν είναι Dolby Atmos)", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Χωρικοποίηση Cider", @@ -281,15 +364,16 @@ "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Η Χωρικοποίηση δεν είναι συμβατή με το CAP. Παρακαλούμε απενεργοποιήστε το CAP για να συνεχίσετε.", "settings.header.visual": "Οπτικά", "settings.header.visual.description": "Προσαρμογή οπτικών ρυθμίσεων για το Cider.", - "settings.option.visual.windowBackgroundStyle": "Στυλ Φόντου Παραθύρου", + "settings.option.visual.windowStyle": "Στυλ παραθύρου", + "settings.option.visual.windowBackgroundStyle": "Στυλ φόντου παραθύρου", "settings.header.visual.windowBackgroundStyle.none": "Κανένα", "settings.header.visual.windowBackgroundStyle.artwork": "Εξώφυλλο", "settings.header.visual.windowBackgroundStyle.image": "Εικόνα", - "settings.option.visual.animatedArtwork": "Κινούμενο Εξώφυλλο", + "settings.option.visual.animatedArtwork": "Κινούμενο εξώφυλλο", "settings.header.visual.animatedArtwork.always": "Πάντα", "settings.header.visual.animatedArtwork.limited": "Περιορισμός σε σελίδες και ειδικές καταχωρήσεις", "settings.header.visual.animatedArtwork.disable": "Απενεργοποιημένο παντού", - "settings.option.visual.animatedArtworkQuality": "Ποιότητα Κινούμενου Εξωφύλλου", + "settings.option.visual.animatedArtworkQuality": "Ποιότητα κινούμενου εξωφύλλου", "settings.header.visual.animatedArtworkQuality.low": "Χαμηλή", "settings.header.visual.animatedArtworkQuality.medium": "Μέτρια", "settings.header.visual.animatedArtworkQuality.high": "Υψηλή", @@ -300,30 +384,52 @@ "settings.option.visual.hardwareAcceleration.description": "Απαιτεί επανεκκίνηση", "settings.header.visual.hardwareAcceleration.default": "Προεπιλογή", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.option.visual.uiscale": "Κλίμακα διεπαφής χρήστη", "settings.header.visual.theme": "Θέμα", "settings.option.visual.theme.github.download": "Εγκατάσταση από σύνδεσμο GitHub", + "settings.option.visual.theme.github.openfolder": "Άνοιγμα φακέλου θεμάτων", "settings.option.visual.theme.github.explore": "Εξερεύνηση θεμάτων GitHub", "settings.header.visual.theme.github.page": "Θέματα από το GitHub", "settings.option.visual.theme.github.install.confirm": "Θέλετε σίγουρα να εγκαταστήσετε το θέμα {{ repo }};", "settings.prompt.visual.theme.github.URL": "Εισάγετε τον σύνδεσμο του θέματος που θέλετε να εγκαταστήσετε", "settings.notyf.visual.theme.install.success": "Το θέμα εγκαταστάθηκε με επιτυχία", "settings.notyf.visual.theme.install.error": "Αποτυχία εγκατάστασης του θέματος", + "settings.header.visual.plugin": "Πρόσθετο", + "settings.option.visual.plugin.github.download": "Εγκατάσταση από σύνδεσμο GitHub", + "settings.option.visual.plugin.github.explore": "Εξερεύνηση πρόσθετων GitHub", + "settings.header.visual.plugin.github.page": "Πρόσθετα από το GitHub", + "settings.option.visual.plugin.github.install.confirm": "Θέλετε σίγουρα να εγκαταστήσετε το πρόσθετο {{ repo }};", + "settings.prompt.visual.plugin.github.URL": "Εισάγετε τον σύνδεσμο του πρόσθετου που θέλετε να εγκαταστήσετε", + "settings.prompt.visual.plugin.github.success": "Το πρόσθετο εγκαταστάθηκε με επιτυχία, πατήστε ΟΚ για επανεκκίνηση του Cider", + "settings.notyf.visual.plugin.install.success": "Το πρόσθετο εγκαταστάθηκε με επιτυχία", + "settings.notyf.visual.plugin.install.error": "Αποτυχία εγκατάστασης του πρόσθετου", "settings.option.visual.theme.default": "Cider", "settings.option.visual.theme.dark": "Σκοτεινό", "settings.option.visual.showPersonalInfo": "Εμφάνιση προσωπικών στοιχείων", + "settings.header.window": "Παράθυρο", + "settings.header.window.description": "Προσαρμογή ρυθμίσεων παραθύρου για το Cider.", + "settings.option.window.openOnStartup": "Άνοιγμα του Cider στην εκκίνηση", + "settings.option.window.openOnStartup.hidden": "Άνοιγμα κρυμμένο", + "settings.option.window.useNativeTitleBar": "Χρήση γραμμής τίτλου του συστήμστος", + "settings.option.window.windowControlStyle": "Στυλ ελέγχου παραθύρου", + "settings.option.window.windowControlStyle.right": "Δεξιά", + "settings.option.window.windowControlStyle.left": "Αριστερά", "settings.header.lyrics": "Στίχοι", "settings.header.lyrics.description": "Προσαρμογή ρυθμίσεων στίχων για το Cider.", - "settings.option.lyrics.enableMusixmatch": "Ενεργοποίηση Στίχων Musixmatch", - "settings.option.lyrics.enableMusixmatchKaraoke": "Ενεργοποίηση Λειτουργίας Καραόκε (Musixmatch μόνο)", - "settings.option.lyrics.musixmatchPreferredLanguage": "Προτιμώμενη Γλώσσα Μετάφρασης Musixmatch", - "settings.option.lyrics.enableYoutubeLyrics": "Ενεργοποίηση Στίχων Youtube για Μουσικά Βίντεο", - "settings.header.connectivity": "Σύνδεση", - "settings.header.connectivity.description": "Προσαρμογή ρυθμίσεων σύνδεσης για το Cider.", + "settings.option.lyrics.enableMusixmatch": "Ενεργοποίηση στίχων Musixmatch", + "settings.option.lyrics.enableMusixmatchKaraoke": "Ενεργοποίηση λειτουργίας καραόκε (Musixmatch μόνο)", + "settings.option.lyrics.musixmatchPreferredLanguage": "Προτιμώμενη γλώσσα μετάφρασης Musixmatch", + "settings.option.lyrics.enableYoutubeLyrics": "Ενεργοποίηση στίχων YouTube για μουσικά βίντεο", + "settings.option.lyrics.enableQQLyrics": "Ενεργοποίηση στίχων QQ", + "settings.header.connectivity": "Συνδεσιμότητα", + "settings.header.connectivity.description": "Προσαρμογή ρυθμίσεων συνδεσιμότητας για το Cider.", + "settings.option.connectivity.playbackNotifications": "Ειδοποιήσεις αναπαραγωγής", "settings.option.connectivity.discordRPC": "Discord Rich Presence", - "settings.option.connectivity.playbackNotifications": "Ειδοποιήσεις Αναπαραγωγής", - "settings.header.connectivity.discordRPC.cider": "Εμφάνιση ως 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Εμφάνιση ως 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Εκκαθάριση του Discord Rich Presence στην Παύση", + "settings.option.connectivity.discordRPC.clientName": "Τίτλος", + "settings.option.connectivity.discordRPC.clearOnPause": "Εκκαθάριση του Discord Rich Presence στην παύση", + "settings.option.connectivity.discordRPC.hideButtons": "Απόκρυψη κουμπιών του Discord Rich Presence", + "settings.option.connectivity.discordRPC.detailsFormat": "Δομή λεπτομεριών", + "settings.option.connectivity.discordRPC.stateFormat": "Δομή κατάστασης", "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", "settings.option.connectivity.lastfmScrobble.delay": "Καθυστέρηση LastFM Scrobble (%)", "settings.option.connectivity.lastfmScrobble.nowPlaying": "Ενεργοποίηση LastFM \"Now Playing\"", @@ -334,32 +440,52 @@ "settings.option.debug.openAppData": "Άνοιγμα του φακέλου Cider", "settings.header.experimental": "Πειραματικές", "settings.header.experimental.description": "Προσαρμογή πειραματικών ρυθμίσεων για το Cider.", - "settings.option.experimental.compactUI": "Συμπαγής Διεπαφή", - "settings.option.experimental.closeButtonBehaviour": "Συμπεριφορά Κουμπιού Εξόδου", - "settings.option.experimental.closeButtonBehaviour.quit": "Έξοδος του Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "Ελαχιστοποίηση στη γραμμή εργασιών", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "Ελαχιστοποίηση στη γωνία γραμμής εργασιών", + "settings.option.experimental.reinstallwidevine": "Επανεγκατάσταση του WidevineCDM", + "settings.option.experimental.reinstallwidevine.confirm": "Θέλετε σίγουρα να επανεγκαταστήσετε το Widevine;", + "settings.option.experimental.unknownPlugin": "Άγνωστες πηγές", + "settings.option.experimental.unknownPlugin.description": "Να επιτρέπεται η εγκατάσταση πρόσθετων από repo εκτός του Cider Plugin Repository", + "settings.option.experimental.compactUI": "Συμπαγής διεπαφή", + "settings.option.window.close_button_hide": "Απόκρυψη εφαρμογής με το πάτημα του κουμπιού κλεισίματος", + "settings.option.experimental.inline_playlists": "Ενσωμάτωση λιστών αναπαραγωγής και άλμπουμ", + "settings.option.advanced.playlistTrackMapping": "Χαρτογράφηση κομματιών λίστών αναπαραγωγής", + "settings.option.advanced.playlistTrackMapping.description": "Ενεργοποιεί τη βαθιά σάρωση των λιστών αναπαραγωγής για να προσδιορίσει ποια κομμάτια βρίσκονται σε ποιες λίστες αναπαραγωγής. Οι χρόνοι δημιουργίας της προσωρινής μνήμης των λιστών αναπαραγωγής μπορεί να αυξηθούν σημαντικά.", + "settings.option.visual.transparent": "Διαφανές πλαίσιο", + "settings.option.visual.transparent.description": "(χρειάζεται υποστήριξη θέματος, απαιτεί επανεκκίνηση)", + "settings.header.advanced": "Για προχωρημένους", + "settings.header.connect": "Συγχρονισμός", + "settings.option.connect.link_account": "Ενεργοποίηση συγχρονισμού με Cider Connect", + "settings.option.connect.link_account.description": "Η σύνδεση του λογαριασμού σας Discord με το Cider Connect σάς επιτρέπει να αποθηκεύετε δεδομένα χρήστη, συμπεριλαμβανομένων των Ρυθμίσεων, των EQ, και άλλα. (Υπό ανάπτυξη)", "spatial.notTurnedOn": "Η Χωρικοποίηση Ήχου είναι απενεργοποιημένη. Για χρήση, παρακαλούμε ενεργοποιήστε την πρώτα.", - "spatial.spatialProperties": "Χωρικές Ιδιότητες", + "spatial.spatialProperties": "Χωρικές ιδιότητες", "spatial.width": "Πλάτος", "spatial.height": "Ύψος", "spatial.depth": "Βάθος", "spatial.gain": "Απολαβή", - "spatial.roomMaterials": "Υλικά Δωματίου", - "spatial.roomDimensions": "Διαστάσεις Δωματίου", - "spatial.roomPositions": "Θέσεις Δωματίου", - "spatial.setDimensions": "Ορισμός Διαστάσεων", - "spatial.setPositions": "Ορισμός Θέσεων", + "spatial.roomMaterials": "Υλικά δωματίου", + "spatial.roomDimensions": "Διαστάσεις δωματίου", + "spatial.roomPositions": "Θέσεις δωματίου", + "spatial.setDimensions": "Ορισμός διαστάσεων", + "spatial.setPositions": "Ορισμός θέσεων", "spatial.up": "Πάνω", "spatial.front": "Πρόσοψη", "spatial.left": "Αριστερά", "spatial.right": "Δεξιά", - "spatial.back": "Πίσω Όψη", + "spatial.back": "Πίσω όψη", "spatial.down": "Κάτω", "spatial.listener": "Ακροατής", - "spatial.audioSource": "Πηγή Ήχου", + "spatial.audioSource": "Πηγή ήχου", "settings.header.unfinished": "Ημιτελής", "remote.web.title": "Cider Remote", "remote.web.description": "Σαρώστε τον κωδικό QR για σύζευξη του Cider με το κινητό σας", + "share.platform.twitter.tweet": "Ακούστε το {{song}} στο Apple Music.\n\n{{url}}\n\n#AppleMusic #Cider", + "share.platform.twitter": "Twitter", + "share.platform.facebook": "Facebook", + "share.platform.reddit": "Reddit", + "share.platform.telegram": "Telegram", + "share.platform.whatsapp": "WhatsApp", + "share.platform.messenger": "Messenger", + "share.platform.email": "Email", + "share.platform.songLink": "Αντιγραφή με song.link", + "share.platform.clipboard": "Αντιγραφή συνδέσμου", "about.thanks": "Μεγάλα ευχαριστώ στην Ομάδα Cider Collective και σε όλους τους συνεισφέροντές μας." -} \ No newline at end of file +} diff --git a/src/i18n/en_OWO.json b/src/i18n/en_OWO.json index 940d93fd..5e03b54d 100644 --- a/src/i18n/en_OWO.json +++ b/src/i18n/en_OWO.json @@ -73,6 +73,7 @@ "term.viewAs": "View As", "term.viewAs.coverArt": "Cuvw Awt", "term.viewAs.list": "Wist", + "term.dynamic": "Dynyamic", "term.size": "Size", "term.size.normal": "Nyowmaw", "term.size.compact": "Compact", @@ -199,6 +200,9 @@ "podcast.episodes": "Episodes", "podcast.playEpisode": "Pway Episode", "podcast.website": "Podcast Website", + "action.edit": "Edit", + "action.done": "Donye", + "action.editTracklist": "Edit Twackwist", "action.addToLibrary": "Add to Wibwawy", "action.addToLibrary.success": "Added to Wibwawy", "action.addToLibrary.error": "Ewwow Adding to Wibwawy", @@ -269,6 +273,10 @@ "settings.option.general.resumebehavior.locally.description": "Cidew wiww wesume youw wast session on this machinye.", "settings.option.general.resumebehavior.history": "Histowy", "settings.option.general.resumebehavior.history.description": "Cidew wiww queue the wast song fwom youw uvwaww Appwe Music histowy, acwoss devices.", + "settings.option.general.resumetabs": "Open Tab on Waunch", + "settings.option.general.resumetabs.description": "You can choose what tab you want to open when you waunch Cidew.", + "settings.option.general.resumetabs.dynamic": "Dynyamic", + "settings.option.general.resumetabs.dynamic.description": "Cidew wiww open the tab that you wast used.", "settings.option.general.language.main": "Wanguages", "settings.option.general.language.fun": "Fun Wanguages", "settings.option.general.language.unsorted": "Unsowted", @@ -280,6 +288,8 @@ "settings.option.general.customizeSidebar": "Customize Sidebaw Items", "settings.option.general.customizeSidebar.customize": "Customize", "settings.option.general.keybindings": "Keybindings", + "settings.notyf.general.keybindings.update.success": "Keybind updated successfuwwy", + "settings.prompt.general.keybindings.update.success": "Keybind updated successfuwwy. Pwess OK to wewaunch Cidew", "settings.option.general.keybindings.open": "Open", "settings.description.search": "Seawch", "settings.description.albums": "Wibwawy Awbums", diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json index 6236b726..9f058996 100644 --- a/src/i18n/en_US.json +++ b/src/i18n/en_US.json @@ -73,6 +73,7 @@ "term.viewAs": "View As", "term.viewAs.coverArt": "Cover Art", "term.viewAs.list": "List", + "term.dynamic": "Dynamic", "term.size": "Size", "term.size.normal": "Normal", "term.size.compact": "Compact", @@ -263,6 +264,42 @@ "action.cast.scanning": "Scanning...", "action.createNew": "Create New...", "action.openArtworkInBrowser": "Open artwork in browser", + "menubar.options.about": "About", + "menubar.options.settings": "Settings", + "menubar.options.quit": "Quit Cider", + "menubar.options.view": "View ", + "menubar.options.reload": "Reload", + "menubar.options.forcereload": "Force Reload", + "menubar.options.toggledevtools": "Toggle Developer Tools", + "menubar.options.window": "Window", + "menubar.options.minimize": "Minimize", + "menubar.options.toggleprivate": "Toggle Private Session", + "menubar.options.webremote": "Web Remote", + "menubar.options.audio": "Audio Settings", + "menubar.options.plugins": "Plu-gins Menu", + "menubar.options.controls": "Controls", + "menubar.options.next": "Next", + "menubar.options.playpause": "Play/Pause", + "menubar.options.previous": "Previous", + "menubar.options.volumeup": "Volume Up", + "menubar.options.volumedown": "Volume Down", + "menubar.options.browse": "Browse", + "menubar.options.artists": "Artists", + "menubar.options.search": "Search", + "menubar.options.albums": "Albums", + "menubar.options.cast": "Cast To Devices", + "menubar.options.account": "Account", + "menubar.options.accountsettings": "Account Settings", + "menubar.options.signout": "Sign Out", + "menubar.options.support": "Support", + "menubar.options.discord": "Discord", + "menubar.options.github": "GitHub Wiki", + "menubar.options.report": "Report a...", + "menubar.options.bug": "Bug", + "menubar.options.feature": "Feature Request", + "menubar.options.trans": "Translation Report/Request", + "menubar.options.license": "View License", + "menubar.options.conf": "Open Configuration File in Editor", "settings.header.general": "General", "settings.header.general.description": "Adjust the general settings for Cider.", "settings.option.general.language": "Language", @@ -329,6 +366,7 @@ "settings.option.audio.audioLab.description": "An assortment of in-house developed audio effects for Cider.", "settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California", "settings.warn.audioLab.withoutAF": "AudioContext (Advanced Functionality) is required to enable Cider Audio Laboratory.", + "settings.warn.enableAdvancedFunctionality": "AudioContext (Advanced Functionality) is required to enable this feature.", "settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Analog Warmth", "settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simulates the analog warmth modelled after the Korg Nutube 6P1", "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity", @@ -391,6 +429,11 @@ "settings.header.visual.theme.github.page": "Themes from GitHub", "settings.option.visual.theme.github.install.confirm": "Are you sure you want to install {{ repo }}?", "settings.prompt.visual.theme.github.URL": "Enter the URL of the theme you want to install", + "settings.prompt.visual.theme.uninstallTheme": "Are you sure you want to uninstall {{ theme }}?", + "settings.option.visual.theme.checkForUpdates": "Check for updates", + "settings.option.visual.theme.manageStyles": "Manage Styles", + "settings.option.visual.theme.uninstall": "Uninstall", + "settings.option.visual.theme.viewInfo": "View Info", "settings.notyf.visual.theme.install.success": "Theme installed successfully", "settings.notyf.visual.theme.install.error": "Theme installation failed", "settings.header.visual.plugin": "Plugin", diff --git a/src/i18n/es_ES.json b/src/i18n/es_ES.json index e10bab53..eb31ea60 100644 --- a/src/i18n/es_ES.json +++ b/src/i18n/es_ES.json @@ -73,6 +73,7 @@ "term.viewAs": "Ver como", "term.viewAs.coverArt": "Portada", "term.viewAs.list": "Lista", + "term.dynamic": "Dinámico", "term.size": "Tamaño", "term.size.normal": "Normal", "term.size.compact": "Compacto", @@ -199,6 +200,9 @@ "podcast.episodes": "Episodios", "podcast.playEpisode": "Reproducir Episodio", "podcast.website": "Sitio web de Podcasts", + "action.edit": "Editar", + "action.done": "Hecho", + "action.editTracklist": "Edit Tracklist", "action.addToLibrary": "Agregar a la Biblioteca", "action.addToLibrary.success": "Agregado a la Biblioteca", "action.addToLibrary.error": "Error al agregar a la Biblioteca", @@ -260,6 +264,42 @@ "action.cast.scanning": "Escaneando...", "action.createNew": "Crear Nuevo...", "action.openArtworkInBrowser": "Abrir Ilustración en el navegador", + "menubar.options.about": "Acerca de", + "menubar.options.settings": "Ajustes", + "menubar.options.quit": "Salir", + "menubar.options.view": "Ver", + "menubar.options.reload": "Recargar", + "menubar.options.forcereload": "Forzar Recarga", + "menubar.options.toggledevtools": "Herramientas de Desarrollo", + "menubar.options.window": "Ventana", + "menubar.options.minimize": "Minimizar", + "menubar.options.toggleprivate": "Cambiar Sesión Privada", + "menubar.options.webremote": "Web Remoto", + "menubar.options.audio": "Configuraciones de Audio", + "menubar.options.plugins": "Menu de Plu-gins", + "menubar.options.controls": "Controles", + "menubar.options.next": "Siguiente", + "menubar.options.playpause": "Reproducir/Pausar", + "menubar.options.previous": "Anterior", + "menubar.options.volumeup": "Subir Volumen", + "menubar.options.volumedown": "Bajar Volumen", + "menubar.options.browse": "Explorar", + "menubar.options.artists": "Artistas", + "menubar.options.search": "Buscar", + "menubar.options.albums": "Álbumes", + "menubar.options.cast": "Transmitir a Dispositivos", + "menubar.options.account": "Cuenta", + "menubar.options.accountsettings": "Ajustes de Cuenta", + "menubar.options.signout": "Cerrar Sesión", + "menubar.options.support": "Soporte", + "menubar.options.discord": "Discord", + "menubar.options.github": "GitHub Wiki", + "menubar.options.report": "Reportar a...", + "menubar.options.bug": "Bug", + "menubar.options.feature": "Solicitud de características", + "menubar.options.trans": "Solicitud de Informe/Traducción", + "menubar.options.license": "Ver licencia", + "menubar.options.conf": "Abrir archivo de configuración en el editor", "settings.header.general": "General", "settings.header.general.description": "Ajuste la configuración general de Cider.", "settings.option.general.language": "Idioma", @@ -269,6 +309,10 @@ "settings.option.general.resumebehavior.locally.description": "Cider reanudará su última sesión en esta PC.", "settings.option.general.resumebehavior.history": "Histórico", "settings.option.general.resumebehavior.history.description": "Cider pondrá en cola la última canción de su historial general de Apple Music, en todos sus dispositivos.", + "settings.option.general.resumetabs" : "Abrir pestaña al iniciar", + "settings.option.general.resumetabs.description" : "Puede elegir qué pestaña desea abrir cuando inicie Cider.", + "settings.option.general.resumetabs.dynamic" : "Dinámico", + "settings.option.general.resumetabs.dynamic.description" : "Cider abrirá la pestaña que utilizó por última vez.", "settings.option.general.language.main": "Idiomas", "settings.option.general.language.fun": "Idiomas Fun (Parodias)", "settings.option.general.language.unsorted": "Sin Clasificar", @@ -280,6 +324,8 @@ "settings.option.general.customizeSidebar": "Personalizar elementos de la barra lateral", "settings.option.general.customizeSidebar.customize": "Personalizar", "settings.option.general.keybindings": "Combinaciones de Teclas", + "settings.notyf.general.keybindings.update.success": "Combinación de teclas actualizada correctamente", + "settings.prompt.general.keybindings.update.success": "La combinación de teclas se actualizó correctamente. Pulsa OK para reiniciar Cider", "settings.option.general.keybindings.open": "Abrir", "settings.description.search": "Buscar", "settings.description.albums": "Álbumes de la biblioteca", @@ -410,6 +456,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Habilitar el modo Karaoke (solo Musixmatch)", "settings.option.lyrics.musixmatchPreferredLanguage": "Idioma preferido de traducción de Musixmatch", "settings.option.lyrics.enableYoutubeLyrics": "Habilitar letras de YouTube para videos musicales", + "settings.option.lyrics.enableQQLyrics": "Habilitar letras de QQ", "settings.header.connectivity": "Conectividad", "settings.header.connectivity.description": "Ajuste la configuración de conectividad para Cider.", "settings.option.connectivity.playbackNotifications": "Notificaciones de Reproducción", @@ -442,7 +489,9 @@ "settings.option.visual.transparent.description": "Marco transparente (necesita compatibilidad con temas, requiere reiniciar)", "settings.header.advanced": "Avanzado", "settings.header.connect": "Conectar", - "spatial.notTurnedOn": "La espacialización de audio está deshabilitada. Para usar, habilítelo primero.", + "settings.option.connect.link_account": "Habilitar sincronización con Cider Connect", + "settings.option.connect.link_account.description": "Vincular su cuenta de Discord con Cider Connect le permite almacenar datos de usuario que incluyen configuraciones, ecualizadores y eventualmente más, una vez que haya terminado. (Trabajo en progreso)", + "spatial.notTurnedOn": "La Espacialización de audio está deshabilitada. Para usar, habilítelo primero.", "spatial.spatialProperties": "Propiedades de Espacialización", "spatial.width": "Ancho", "spatial.height": "Alto", diff --git a/src/i18n/source/en_US.json b/src/i18n/source/en_US.json index 6f0ce8f2..6a9a00fe 100644 --- a/src/i18n/source/en_US.json +++ b/src/i18n/source/en_US.json @@ -264,6 +264,42 @@ "action.cast.scanning": "Scanning...", "action.createNew": "Create New...", "action.openArtworkInBrowser": "Open artwork in browser", + "menubar.options.about": "About", + "menubar.options.settings": "Settings", + "menubar.options.quit": "Quit Cider", + "menubar.options.view": "View ", + "menubar.options.reload": "Reload", + "menubar.options.forcereload": "Force Reload", + "menubar.options.toggledevtools": "Toggle Developer Tools", + "menubar.options.window": "Window", + "menubar.options.minimize": "Minimize", + "menubar.options.toggleprivate": "Toggle Private Session", + "menubar.options.webremote": "Web Remote", + "menubar.options.audio": "Audio Settings", + "menubar.options.plugins": "Plu-gins Menu", + "menubar.options.controls": "Controls", + "menubar.options.next": "Next", + "menubar.options.playpause": "Play/Pause", + "menubar.options.previous": "Previous", + "menubar.options.volumeup": "Volume Up", + "menubar.options.volumedown": "Volume Down", + "menubar.options.browse": "Browse", + "menubar.options.artists": "Artists", + "menubar.options.search": "Search", + "menubar.options.albums": "Albums", + "menubar.options.cast": "Cast To Devices", + "menubar.options.account": "Account", + "menubar.options.accountsettings": "Account Settings", + "menubar.options.signout": "Sign Out", + "menubar.options.support": "Support", + "menubar.options.discord": "Discord", + "menubar.options.github": "GitHub Wiki", + "menubar.options.report": "Report a...", + "menubar.options.bug": "Bug", + "menubar.options.feature": "Feature Request", + "menubar.options.trans": "Translation Report/Request", + "menubar.options.license": "View License", + "menubar.options.conf": "Open Configuration File in Editor", "settings.header.general": "General", "settings.header.general.description": "Adjust the general settings for Cider.", "settings.option.general.language": "Language", @@ -392,6 +428,11 @@ "settings.header.visual.theme.github.page": "Themes from GitHub", "settings.option.visual.theme.github.install.confirm": "Are you sure you want to install {{ repo }}?", "settings.prompt.visual.theme.github.URL": "Enter the URL of the theme you want to install", + "settings.prompt.visual.theme.uninstallTheme": "Are you sure you want to uninstall {{ theme }}?", + "settings.option.visual.theme.checkForUpdates": "Check for updates", + "settings.option.visual.theme.manageStyles": "Manage Styles", + "settings.option.visual.theme.uninstall": "Uninstall", + "settings.option.visual.theme.viewInfo": "View Info", "settings.notyf.visual.theme.install.success": "Theme installed successfully", "settings.notyf.visual.theme.install.error": "Theme installation failed", "settings.header.visual.plugin": "Plugin", diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts index 2556d2d9..0c785691 100644 --- a/src/main/base/browserwindow.ts +++ b/src/main/base/browserwindow.ts @@ -4,7 +4,18 @@ import * as windowStateKeeper from "electron-window-state"; import * as express from "express"; import * as getPort from "get-port"; import {search} from "youtube-search-without-api-key"; -import {existsSync, rmSync, mkdirSync, readdirSync, readFileSync, writeFileSync, statSync} from "fs"; +import { + existsSync, + rmSync, + mkdirSync, + readdirSync, + readFileSync, + writeFileSync, + statSync, + unlinkSync, + rmdirSync, + lstatSync +} from "fs"; import {Stream} from "stream"; import {networkInterfaces} from "os"; import * as mm from 'music-metadata'; @@ -46,6 +57,7 @@ export class BrowserWindow { "pages/library-artists", "pages/browse", "pages/settings", + "pages/installed-themes", "pages/listen_now", "pages/home", "pages/artist-feed", @@ -178,6 +190,10 @@ export class BrowserWindow { page: "settings", component: ``, condition: `page == 'settings'` + }, { + page: "installed-themes", + component: ``, + condition: `page == 'installed-themes'` }, { page: "search", component: ``, @@ -256,8 +272,10 @@ export class BrowserWindow { }, }; + public static watcher: any; + StartWatcher(path: string) { - const watcher = watch(path, { + BrowserWindow.watcher = watch(path, { ignored: /[\/\\]\./, persistent: true }); @@ -267,7 +285,7 @@ export class BrowserWindow { } // Declare the listeners of the watcher - watcher + BrowserWindow.watcher .on('add', function (path: string) { // console.log('File', path, 'has been added'); }) @@ -294,6 +312,10 @@ export class BrowserWindow { }); } + async StopWatcher() { + await BrowserWindow.watcher.close(); + } + /** * Creates the browser window * @generator @@ -313,6 +335,8 @@ export class BrowserWindow { }); this.options.width = windowState.width; this.options.height = windowState.height; + this.options.x = windowState.x; + this.options.y = windowState.y; switch (process.platform) { default: @@ -698,6 +722,50 @@ export class BrowserWindow { }; }) + ipcMain.handle("uninstall-theme", async (event, path) => { + await this.StopWatcher() + const themesDir = utils.getPath("themes") + // validate the path is in the themes directory + try { + if (path.startsWith(themesDir)) { + // get last dir in path, can be either / or \ and may have a trailing slash + const themeName = path.split(/[\\\/]/).pop() + if (themeName == "Themes" || themeName == "themes") { + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + status: 3 + }); + return + } + // if path is directory, delete it + if (lstatSync(path).isDirectory()) { + await rmdirSync(path, {recursive: true}); + } else { + // if path is file, delete it + await unlinkSync(path); + } + // return the path + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + status: 0 + }); + } else { + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + status: 1 + }); + } + } catch (e: any) { + BrowserWindow.win.webContents.send("theme-uninstalled", { + path: path, + message: e.message, + status: 2 + }); + } + + this.StartWatcher(utils.getPath('themes')) + }) + ipcMain.handle("reinstall-widevine-cdm", () => { // remove WidevineCDM from appdata folder const widevineCdmPath = join(app.getPath("userData"), "./WidevineCdm"); @@ -813,7 +881,7 @@ export class BrowserWindow { } else if (statSync(join(utils.getPath("themes"), file)).isDirectory()) { let subFiles = readdirSync(join(utils.getPath("themes"), file)); for (let subFile of subFiles) { - if (subFile.endsWith(".less")) { + if (subFile.endsWith("index.less")) { themes.push(join(file, subFile)); } } @@ -832,15 +900,20 @@ export class BrowserWindow { themePath = themePath.slice(0, -10); } if (existsSync(join(themePath, "theme.json"))) { - let themeJson = JSON.parse(readFileSync(join(themePath, "theme.json"), "utf8")); - themeObjects.push({ - name: themeJson.name || themeName, - description: themeJson.description || themeDescription, - path: themePath, - file: theme, - github_repo: themeJson.github_repo || "", - commit: themeJson.commit || "" - }); + try { + let themeJson = JSON.parse(readFileSync(join(themePath, "theme.json"), "utf8")); + themeObjects.push({ + name: themeJson.name || themeName, + description: themeJson.description || themeDescription, + path: themePath, + file: theme, + github_repo: themeJson.github_repo || "", + commit: themeJson.commit || "", + pack: themeJson.pack || false, + }); + } catch (e) { + console.error(e); + } } else { themeObjects.push({ name: themeName, @@ -848,7 +921,8 @@ export class BrowserWindow { path: themePath, file: theme, github_repo: "", - commit: "" + commit: "", + pack: false }); } } @@ -971,6 +1045,11 @@ export class BrowserWindow { BrowserWindow.win.setResizable(!lock); }); + // Move window + ipcMain.on("windowmove", (_event, x, y) => { + BrowserWindow.win.setBounds({x, y}); + }); + //Fullscreen ipcMain.on('setFullScreen', (_event, flag) => { BrowserWindow.win.setFullScreen(flag) @@ -1215,7 +1294,7 @@ export class BrowserWindow { shell.openPath(app.getPath('userData')); }); - + //#region Cider Connect ipcMain.on('cc-auth', (_event) => { shell.openExternal(String(utils.getStoreValue('cc_authURL'))); @@ -1279,7 +1358,7 @@ export class BrowserWindow { BrowserWindow.win.webContents.executeJavaScript(` window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem)); window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime)); - window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue.items)); + window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue._unplayedQueueItems)); ipcRenderer.send('stopGCast','');`) BrowserWindow.win.destroy(); } diff --git a/src/main/base/store.ts b/src/main/base/store.ts index 5de4dc33..c3bc6373 100644 --- a/src/main/base/store.ts +++ b/src/main/base/store.ts @@ -53,11 +53,11 @@ export class Store { "keybindings": { "search": [ process.platform == "darwin" ? "Command" : "Control", - "S" + "F" ], "albums": [ process.platform == "darwin" ? "Command" : "Control", - "F" + "S" ], "artists": [ process.platform == "darwin" ? "Command" : "Control", @@ -124,6 +124,8 @@ export class Store { "quality": "HIGH", "seamless_audio": true, "normalization": false, + "dBSPL": false, + "dBSPLcalibration": 90, "maikiwiAudio": { "ciderPPE": false, "ciderPPE_value": "MAIKIWI", diff --git a/src/main/plugins/menubar.ts b/src/main/plugins/menubar.ts index b47dcabe..a9d73428 100644 --- a/src/main/plugins/menubar.ts +++ b/src/main/plugins/menubar.ts @@ -3,6 +3,7 @@ import {utils} from "../base/utils"; export default class Thumbar { + /** * Base Plugin Details (Eventually implemented into a GUI in settings) */ @@ -16,36 +17,42 @@ export default class Thumbar { * Menubar Assets * @private */ - private isMac: boolean = process.platform === 'darwin'; + private isMac: boolean = process.platform === 'darwin'; private _menuTemplate: any = [ { label: app.getName(), submenu: [ { - label: 'About', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.about'), click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`) }, {type: 'separator'}, { - label: 'Settings', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.settings'), accelerator: utils.getStoreValue("general.keybindings.settings").join('+'), - click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('settings')`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('settings')`), }, + ...(this.isMac ? [ {type: 'separator'}, {role: 'services'}, {type: 'separator'}, {role: 'hide'}, {role: 'hideOthers'}, {role: 'unhide'}, + ]: [ {type: 'separator'}, - {role: 'quit'} - ] + {role: 'quit', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.quit')}, + ]), + ], }, + + { - label: 'View', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.view'), submenu: [ - {role: 'reload'}, - {role: 'forceReload'}, + {role: 'reload', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.reload')}, + {role: 'forceReload', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.forcereload')}, + ...(this.isMac ? [ {role: 'toggleDevTools'}, {type: 'separator'}, {role: 'resetZoom'}, @@ -53,25 +60,28 @@ export default class Thumbar { {role: 'zoomOut'}, {type: 'separator'}, {role: 'togglefullscreen'}, - ] + + ]: []), + ], }, { - label: 'Window', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.window'), submenu: [ - {role: 'minimize'}, + {role: 'minimize', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.minimize')}, + ...(this.isMac ? [ { label: 'Show', click: () => utils.getWindow().show() }, {role: 'zoom'}, - ...(this.isMac ? [ + {type: 'separator'}, {role: 'front'}, {role: 'close'}, - ] : [ + {role: 'close'}, - ]), + { label: 'Edit', submenu: [ @@ -83,146 +93,148 @@ export default class Thumbar { {role: 'paste'}, ] }, + ] : [] + ), {type: 'separator'}, { - label: 'Toggle Private Session', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.toggleprivate'), accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`) }, {type: 'separator'}, { - label: 'Web Remote', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.webremote'), accelerator: utils.getStoreValue("general.keybindings.webRemote").join('+'), sublabel: 'Opens in external window', click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('remote-pair')`) }, { - label: 'Audio Settings', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.audio'), accelerator: utils.getStoreValue("general.keybindings.audioSettings").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.audioSettings = true`) }, { - label: 'Plug-in Menu', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.plugins'), accelerator: utils.getStoreValue("general.keybindings.pluginMenu").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`) } ] }, { - label: 'Controls', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.controls'), submenu: [ { - label: 'Pause / Play', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.playpause'), accelerator: 'Space', click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`) }, { - label: 'Next', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.next'), accelerator: 'CommandOrControl+Right', click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`) }, { - label: 'Previous', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.previous'), accelerator: 'CommandOrControl+Left', click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`) }, {type: 'separator'}, { - label: 'Volume Up', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.volumeup'), accelerator: 'CommandOrControl+Up', click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`) }, { - label: 'Volume Down', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.volumedown'), accelerator: 'CommandOrControl+Down', click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeDown()`) }, { - label: 'Browse', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.browse'), accelerator: utils.getStoreValue("general.keybindings.browse").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`) }, {type: 'separator'}, { - label: 'Artists', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.artists'), accelerator: utils.getStoreValue("general.keybindings.artists").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-artists')`) }, { - label: 'Search', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.search'), accelerator: utils.getStoreValue("general.keybindings.search").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('search')`) }, {type: 'separator'}, { - label: 'Album', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.albums'), accelerator: utils.getStoreValue("general.keybindings.albums").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`) }, {type: 'separator'}, { - label: 'Cast To Devices', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.cast'), accelerator: utils.getStoreValue("general.keybindings.castToDevices").join('+'), click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`) } ] }, { - label: 'Account', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.account'), submenu: [ { - label: 'Account Settings', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.accountsettings'), click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('apple-account-settings')`) }, { - label: 'Sign Out', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.signout'), click: () => utils.getWindow().webContents.executeJavaScript(`app.unauthorize()`) } ] }, { - label: 'Support', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.support'), role: 'help', submenu: [ { - label: 'Discord', + label: utils.getLocale('Discord', 'menubar.options.discord'), click: () => shell.openExternal("https://discord.gg/AppleMusic").catch(console.error) }, { - label: 'GitHub Wiki', + label: utils.getLocale('GitHub Wiki', 'menubar.options.github'), click: () => shell.openExternal("https://github.com/ciderapp/Cider/wiki/Troubleshooting").catch(console.error) }, {type: 'separator'}, { - label: 'Report a...', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.report'), submenu: [ { - label: 'Bug', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.bug'), click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug%2Ctriage&template=bug_report.yaml&title=%5BBug%5D%3A+").catch(console.error) }, { - label: 'Feature Request', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.feature'), click: () => shell.openExternal("https://github.com/ciderapp/Cider/discussions/new?category=feature-request").catch(console.error) }, { - label: 'Translation Report/Request', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.trans'), click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=%F0%9F%8C%90+Translations&template=translation.yaml&title=%5BTranslation%5D%3A+").catch(console.error) }, ] }, {type: 'separator'}, { - label: 'View License', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.license'), click: () => shell.openExternal("https://github.com/ciderapp/Cider/blob/main/LICENSE").catch(console.error) }, {type: 'separator'}, { - label: 'Toggle Developer Tools', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.toggledevtools'), accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join('+'), click: () => utils.getWindow().webContents.openDevTools() }, { - label: 'Open Configuration File in Editor', + label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.conf'), click: () => utils.getStoreInstance().openInEditor() } ] diff --git a/src/main/plugins/raop.ts b/src/main/plugins/raop.ts index a4d70aba..e99c3de7 100644 --- a/src/main/plugins/raop.ts +++ b/src/main/plugins/raop.ts @@ -181,7 +181,7 @@ export default class RAOP { this.portairplay = ipport; this.device = this.airtunes.add(ipv4, { port: ipport, - volume: 60, + volume: 50, password: sepassword, txt: txt }); diff --git a/src/renderer/assets/feather/heart-fill.svg b/src/renderer/assets/feather/heart-fill.svg index 1f790aad..4daaa2c8 100644 --- a/src/renderer/assets/feather/heart-fill.svg +++ b/src/renderer/assets/feather/heart-fill.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/renderer/assets/feather/heart.svg b/src/renderer/assets/feather/heart.svg index a083b7e2..973edba4 100644 --- a/src/renderer/assets/feather/heart.svg +++ b/src/renderer/assets/feather/heart.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/renderer/less/elements.css b/src/renderer/less/elements.css index 20323ac9..0c54721e 100644 --- a/src/renderer/less/elements.css +++ b/src/renderer/less/elements.css @@ -364,6 +364,21 @@ align-items: center; justify-content: center; } +.cd-mediaitem-list-item .heart-unfilled { + background-image: url("assets/feather/heart.svg"); + height: 12px; + width: 36px; + filter: contrast(0); + background-repeat: no-repeat; +} + +.cd-mediaitem-list-item .heart-filled { + background-image: url("assets/feather/heart-fill.svg"); + height: 12px; + width: 36px; + filter: contrast(0); + background-repeat: no-repeat; +} .cd-mediaitem-list-item .explicit-icon { background-image: url("assets/explicit.svg"); height: 12px; @@ -372,9 +387,7 @@ background-repeat: no-repeat; } .heart-icon { - position: absolute; - filter: contrast(0); - background-repeat: no-repeat; + display: flex } @keyframes load-bar { 10% { diff --git a/src/renderer/less/elements.less b/src/renderer/less/elements.less index b2ee7753..11412567 100644 --- a/src/renderer/less/elements.less +++ b/src/renderer/less/elements.less @@ -359,7 +359,11 @@ align-items: center; border-radius: var(--mediaItemRadius); position: relative; - + &:hover{ + .heart-icon{ + display: none; + } + } .popular { background-image: url(assets/star.svg); background-repeat: no-repeat; @@ -448,6 +452,22 @@ justify-content: center; } + .heart-unfilled { + -webkit-mask-image: url("assets/feather/heart.svg"); + height: 12px; + width: 12px; + background-repeat: no-repeat; + background-color: #999; + } + + .heart-filled { + -webkit-mask-image: url("assets/feather/heart-fill.svg"); + height: 12px; + width: 12px; + background-repeat: no-repeat; + background-color: #999; + } + .explicit-icon { background-image: url("./assets/explicit.svg"); height: 12px; @@ -457,10 +477,9 @@ } .heart-icon { + display: flex; position: absolute; - right:0; - filter: contrast(0); - background-repeat: no-repeat; + left: 20px; } /* CSS.gg diff --git a/src/renderer/less/helpers.less b/src/renderer/less/helpers.less index 245cce92..431947c4 100644 --- a/src/renderer/less/helpers.less +++ b/src/renderer/less/helpers.less @@ -353,7 +353,7 @@ &:hover { &::before { - transition: transform .1s ease-in, opacity .1s ease-in; + transition: transform 0s ease-in, opacity 0s ease-in; opacity : 1; transform : scale(1); } diff --git a/src/renderer/less/pages.less b/src/renderer/less/pages.less index 2e03391e..b98b560a 100644 --- a/src/renderer/less/pages.less +++ b/src/renderer/less/pages.less @@ -488,63 +488,79 @@ /* Album / Playlist Page */ .playlist-page { - --bgColor : transparent; - padding : 0px; + --bgColor : transparent; + padding : 0px; //background: linear-gradient(180deg, var(--bgColor) 32px, var(--bgColor) 18px, transparent 60px, transparent 100%); - top : 0; - padding-top : var(--navigationBarHeight); - display:flex; + top : 0; + padding-top : var(--navigationBarHeight); + display : flex; flex-direction: column; - height: 100%; - overflow: hidden; + height : 100%; + overflow : hidden; + + .cd-mediaitem-list-item { + &:hover { + .heart-icon { + display: flex; + } + } + + .heart-icon { + left: -25px; + } + } .editTracksBtn { position: absolute; - top: 20px; - right: 20px; - z-index: 1; + top : 20px; + right : 20px; + z-index : 1; >span { display: flex; - gap: 8px; + gap : 8px; } } .mediaContainer { transition: width 0.5s ease-in-out, height 0.5s ease-in-out; - width: 260px;height:260px; + width : 260px; + height : 260px; } .playlist-body { - padding : 32px; + padding : 32px; // margin-top: -75px; - overflow-y:overlay; - height:100%; - padding:0px; + overflow-y : overlay; + height : 100%; + padding : 0px; background-color: var(--color1); &.scrollbody { .tabs { - display: flex; + display : flex; flex-flow: column; - height: 100%; + height : 100%; .nav-link { - text-transform:capitalize; + text-transform: capitalize; } .tab-content { - height: 100%; + height : 100%; overflow: hidden; - margin:0px; + margin : 0px; + .tab-pane { - height: 100%; - overflow-y: overlay; - overflow-x:hidden; - padding: var(--contentInnerPadding); + height : 100%; + overflow-y : overlay; + overflow-x : hidden; + padding : var(--contentInnerPadding); + padding-inline : 40px; -webkit-mask-image: linear-gradient(180deg, transparent, white 20px); + .well { - margin:0px; + margin: 0px; } } } @@ -563,7 +579,7 @@ background : rgba(0, 0, 0, 0.25); top : var(--navigationBarHeight); transition : opacity 0.1s var(--appleEase); - display: none; + display : none; } .playlist-display { @@ -649,14 +665,14 @@ } .playlist-desc { - transition: height .2s ease-in-out, opacity .2s ease-in-out; + transition : height .2s ease-in-out, opacity .2s ease-in-out; box-sizing : border-box; font-size : 14px; flex-shrink : unset; margin-right: 5px; max-height : 100px; position : relative; - height : 4vh; + height : 4vh; .content { height : 4vh; @@ -750,11 +766,11 @@ } .playlist-time { - font-size: 0.9em; - margin : 6px; - opacity : 0.7; + font-size : 0.9em; + margin : 6px; + opacity : 0.7; transition: height .2s ease-in-out, opacity .2s ease-in-out; - height: 0.9em; + height : 0.9em; } &.inline-playlist { @@ -802,8 +818,8 @@ .pilldim { .nav-pills { - width: max-content; - margin: 0 auto; + width : max-content; + margin : 0 auto; margin-top: 16px; } } @@ -813,26 +829,24 @@ transition: min-height 0.5s ease-in-out; min-height: 200px; - .playlistInfo { - - } + .playlistInfo {} .mediaContainer { transition: width 0.5s ease-in-out, height 0.5s ease-in-out; - width: 128px!important; - height: 128px!important; + width : 128px !important; + height : 128px !important; } .playlist-time { transition: height .2s ease-in-out, opacity .2s ease-in-out; - height: 0px; - opacity: 0; + height : 0px; + opacity : 0; } .playlist-desc { transition: height .2s ease-in-out, opacity .2s ease-in-out; - height: 0px!important; - opacity: 0; + height : 0px !important; + opacity : 0; } } } @@ -920,7 +934,7 @@ pointer-events : none; .header-content { - z-index : 1; + z-index : 1; // margin-top: -16px; } @@ -1112,9 +1126,56 @@ /* Artist Page End */ -// Settings page -.settings-page { - padding: 0px; + +.installed-themes-page { + + .themeContextMenu { + background: transparent; + color : var(--keyColor); + border : 0px; + } + + .list-group-item { + &.addon { + background: rgb(86 86 86 / 20%); + } + &.applied { + background: var(--keyColor-disabled); + pointer-events: none; + } + } + + .repo-header { + font-size : 16px; + position : sticky; + top : 0; + left : 0; + right : 0; + width : 100%; + height : 50px; + z-index : 1; + background : rgba(36, 36, 36, 0.5); + display : flex; + justify-content: center; + align-items : center; + backdrop-filter: var(--glassFilter); + overflow : hidden; + border-bottom : 1px solid rgb(0 0 0 / 18%); + border-top : 1px solid rgb(135 135 135 / 18%); + } + + .style-editor-container { + height : 100%; + flex : 1; + background: var(--color2); + padding : 0px; + overflow-y: overlay; + + .list-group-item { + border-radius: 0px; + } + } + .stylestack-editor { width: 100%; @@ -1125,17 +1186,34 @@ } .themeLabel { - display:flex; + display : flex; align-items: center; } + .handle { + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .list-group-item { + + &:hover { + cursor: grab; + } + &:active { + cursor: grabbing; + } + } + .removeItem { - border: 0px; - background: transparent; - height: 32px; + border : 0px; + background : transparent; + height : 32px; font-weight: bold; - color: var(--textColor); - cursor: pointer; + color : var(--textColor); + cursor : pointer; } .stylesDropdown { @@ -1145,7 +1223,11 @@ } } } +} +// Settings page +.settings-page { + padding: 0px; .nav { width : 90%; @@ -1163,8 +1245,9 @@ .settings-option-body-webview { height: 100%; - width: 100%; + width : 100%; } + .settings-option-body { margin: 16px; } diff --git a/src/renderer/main/vueapp.js b/src/renderer/main/vueapp.js index 0356313f..8218881d 100644 --- a/src/renderer/main/vueapp.js +++ b/src/renderer/main/vueapp.js @@ -148,6 +148,10 @@ const app = new Vue({ }, tmpHeight: '', tmpWidth: '', + tmpX: '', + tmpY: '', + miniTmpX: '', + miniTmpY: '', tmpVar: [], notification: false, chrome: { @@ -231,6 +235,7 @@ const app = new Vue({ pages: [], }, moreinfodata: [], + notyf: notyf }, watch: { cfg: { @@ -284,6 +289,9 @@ const app = new Vue({ } } }, + formatVolumeTooltip() { + return this.cfg.audio.dBSPL ? (Number(this.cfg.audio.dBSPLcalibration) + (Math.log10(this.mk.volume) * 20)).toFixed(2) + ' dB SPL' : (Math.log10(this.mk.volume) * 20).toFixed(2) + ' dBFS' + }, mainMenuVisibility(val) { if (val) { (this.mk.isAuthorized) ? this.chrome.menuOpened = !this.chrome.menuOpened : false; @@ -593,9 +601,7 @@ const app = new Vue({ }, async init() { let self = this - if (this.cfg.visual.theme != "default.less" && this.cfg.visual.theme != "") { - this.setTheme(this.cfg.visual.theme) - } + if (this.cfg.visual.styles.length != 0) { await this.reloadStyles() } @@ -703,6 +709,7 @@ const app = new Vue({ let lastItem = window.localStorage.getItem("currentTrack") let time = window.localStorage.getItem("currentTime") let queue = window.localStorage.getItem("currentQueue") + app.mk.queue.position = 0; // Reset queue position. if (lastItem != null) { lastItem = JSON.parse(lastItem) let kind = lastItem.attributes.playParams.kind; @@ -722,7 +729,7 @@ const app = new Vue({ if (queue != null) { queue = JSON.parse(queue) if (queue && queue.length > 0) { - let ids = queue.map(e => (e.playParams ? e.playParams.id : (e.attributes.playParams ? e.attributes.playParams.id : ''))) + let ids = queue.map(e => (e.playParams ? e.playParams.id : (e.item.attributes.playParams ? e.item.attributes.playParams.id : ''))) let i = 0; if (ids.length > 0) { for (let id of ids) { @@ -833,6 +840,14 @@ const app = new Vue({ ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes()); }) + this.mk.addEventListener(MusicKit.Events.queueItemsDidChange, ()=>{ + if (self.$refs.queue) { + setTimeout(()=>{ + self.$refs.queue.updateQueue(); + }, 100) + } + }) + this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => { if (self.$refs.queue) { self.$refs.queue.updateQueue(); @@ -1148,8 +1163,10 @@ const app = new Vue({ async function deepScan(parent = "p.playlistsroot") { console.debug(`scanning ${parent}`) - const playlistData = await app.mk.api.v3.music(`/v1/me/library/playlist-folders/${parent}/children/`) - await asyncForEach(playlistData.data.data, async (playlist) => { + // const playlistData = await app.mk.api.v3.music(`/v1/me/library/playlist-folders/${parent}/children/`) + const playlistData = await MusicKitTools.v3Continuous({href: `/v1/me/library/playlist-folders/${parent}/children/`}) + console.log(playlistData) + await asyncForEach(playlistData, async (playlist) => { playlist.parent = parent if ( playlist.type != "library-playlist-folders" && @@ -4107,13 +4124,19 @@ const app = new Vue({ if (flag) { this.tmpWidth = window.innerWidth; this.tmpHeight = window.innerHeight; + this.tmpX = window.screenX; + this.tmpY = window.screenY; ipcRenderer.send('unmaximize'); ipcRenderer.send('windowmin', 250, 250) + if (this.miniTmpX !== '' && this.miniTmpY !== '') ipcRenderer.send('windowmove', this.miniTmpX, this.miniTmpY) ipcRenderer.send('windowresize', 300, 300, false) app.appMode = 'mini'; } else { + this.miniTmpX = window.screenX; + this.miniTmpY = window.screenY; ipcRenderer.send('windowmin', 844, 410) ipcRenderer.send('windowresize', this.tmpWidth, this.tmpHeight, false) + ipcRenderer.send('windowmove', this.tmpX, this.tmpY) ipcRenderer.send('windowontop', false) //this.cfg.visual.miniplayer_top_toggle = true; app.appMode = 'player'; diff --git a/src/renderer/style.css b/src/renderer/style.css index 5683d8c9..3448d228 100644 --- a/src/renderer/style.css +++ b/src/renderer/style.css @@ -12944,6 +12944,7 @@ body[platform='darwin'] #window-controls-container { } body[platform='darwin'] .app-chrome .app-chrome-item > .app-mainmenu { opacity: 0; + width: 52px; pointer-events: none; -webkit-app-region: drag; } diff --git a/src/renderer/style.less b/src/renderer/style.less index 3900c772..b24ce657 100644 --- a/src/renderer/style.less +++ b/src/renderer/style.less @@ -3289,6 +3289,7 @@ body[platform='darwin'] { .app-chrome .app-chrome-item > .app-mainmenu { opacity: 0; + width: 52px; pointer-events: none; -webkit-app-region: drag; } diff --git a/src/renderer/views/app/chrome-bottom.ejs b/src/renderer/views/app/chrome-bottom.ejs index 4e88e841..e27a6e13 100644 --- a/src/renderer/views/app/chrome-bottom.ejs +++ b/src/renderer/views/app/chrome-bottom.ejs @@ -101,7 +101,7 @@ :class="{'active': this.cfg.audio.volume == 0}"> + v-b-tooltip.hover :title="formatVolumeTooltip()">
+ v-b-tooltip.hover :title="formatVolumeTooltip()">
- -
diff --git a/src/renderer/views/components/audio-controls.ejs b/src/renderer/views/components/audio-controls.ejs index 57a174e6..657a01d6 100644 --- a/src/renderer/views/components/audio-controls.ejs +++ b/src/renderer/views/components/audio-controls.ejs @@ -14,7 +14,7 @@
+ step="2" v-model="volume"/>
diff --git a/src/renderer/views/components/fullscreen.ejs b/src/renderer/views/components/fullscreen.ejs index 065863c6..73f194af 100644 --- a/src/renderer/views/components/fullscreen.ejs +++ b/src/renderer/views/components/fullscreen.ejs @@ -82,7 +82,7 @@ + v-b-tooltip.hover :title="$root.formatVolumeTooltip()">
diff --git a/src/renderer/views/components/mediaitem-list-item.ejs b/src/renderer/views/components/mediaitem-list-item.ejs index c77a50f8..abd2909d 100644 --- a/src/renderer/views/components/mediaitem-list-item.ejs +++ b/src/renderer/views/components/mediaitem-list-item.ejs @@ -65,8 +65,9 @@ -
-
+
+ +