commit
706e71a10d
61 changed files with 1703 additions and 650 deletions
10
package.json
10
package.json
|
@ -39,10 +39,10 @@
|
||||||
"@sentry/electron": "^3.0.7",
|
"@sentry/electron": "^3.0.7",
|
||||||
"@sentry/integrations": "^6.19.6",
|
"@sentry/integrations": "^6.19.6",
|
||||||
"adm-zip": "0.4.10",
|
"adm-zip": "0.4.10",
|
||||||
"airtunes2": "git+https://github.com/vapormusic/node_airtunes2.git",
|
"airtunes2": "git+https://github.com/vapormusic/node_airtunes2.git#hap",
|
||||||
"castv2-client": "^1.2.0",
|
"castv2-client": "^1.2.0",
|
||||||
"chokidar": "^3.5.3",
|
"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",
|
"dns-js": "git+https://github.com/ciderapp/node-dns-js.git",
|
||||||
"ejs": "^3.1.6",
|
"ejs": "^3.1.6",
|
||||||
"electron-fetch": "^1.7.4",
|
"electron-fetch": "^1.7.4",
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
"electron-builder-notarize-pkg": "^1.2.0",
|
"electron-builder-notarize-pkg": "^1.2.0",
|
||||||
"electron-webpack": "^2.8.2",
|
"electron-webpack": "^2.8.2",
|
||||||
"musickit-typescript": "^1.2.4",
|
"musickit-typescript": "^1.2.4",
|
||||||
"typescript": "^4.6.3",
|
"typescript": "^4.6.4",
|
||||||
"vue-devtools": "^5.1.4",
|
"vue-devtools": "^5.1.4",
|
||||||
"webpack": "~5.72.0"
|
"webpack": "~5.72.0"
|
||||||
},
|
},
|
||||||
|
@ -109,9 +109,9 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
"electronVersion": "18.1.0",
|
"electronVersion": "18.2.1",
|
||||||
"electronDownload": {
|
"electronDownload": {
|
||||||
"version": "18.1.0+wvcus",
|
"version": "18.2.1+wvcus",
|
||||||
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
|
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
|
||||||
},
|
},
|
||||||
"appId": "cider",
|
"appId": "cider",
|
||||||
|
|
|
@ -297,5 +297,48 @@ Update 28/04/2022 21:45 UTC
|
||||||
* `settings.option.general.resumetabs.description`: Added for `en_US`
|
* `settings.option.general.resumetabs.description`: Added for `en_US`
|
||||||
* `settings.option.general.resumetabs.dynamic`: Added for `en_US`
|
* `settings.option.general.resumetabs.dynamic`: Added for `en_US`
|
||||||
* `settings.option.general.resumetabs.dynamic.description`: 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`
|
||||||
|
|
||||||
|
|
||||||
|
Update 08/05/2022 00:29 UTC
|
||||||
|
|
||||||
|
* `settings.option.visual.theme.github.available`: Added for `en_US`,
|
||||||
|
* `settings.option.visual.theme.github.applied`: Added for `en_US`,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"notification.updatingLibrarySongs": "Ενημέρωση βιβλιοθήκης τραγουδιών...",
|
"notification.updatingLibrarySongs": "Ενημέρωση βιβλιοθήκης τραγουδιών...",
|
||||||
"notification.updatingLibraryAlbums": "Ενημέρωση βιβλιοθήκης άλμπουμ...",
|
"notification.updatingLibraryAlbums": "Ενημέρωση βιβλιοθήκης άλμπουμ...",
|
||||||
"notification.updatingLibraryArtists": "Ενημέρωση βιβλιοθήκης καλλιτεχνών...",
|
"notification.updatingLibraryArtists": "Ενημέρωση βιβλιοθήκης καλλιτεχνών...",
|
||||||
|
"term.variables": "Μεταβλητές",
|
||||||
"term.appleInc": "Apple Inc.",
|
"term.appleInc": "Apple Inc.",
|
||||||
"term.appleMusic": "Apple Music",
|
"term.appleMusic": "Apple Music",
|
||||||
"term.applePodcasts": "Apple Podcasts",
|
"term.applePodcasts": "Apple Podcasts",
|
||||||
|
@ -20,9 +21,13 @@
|
||||||
"term.accountSettings": "Ρυθμίσεις λογαριασμού",
|
"term.accountSettings": "Ρυθμίσεις λογαριασμού",
|
||||||
"term.logout": "Αποσύνδεση",
|
"term.logout": "Αποσύνδεση",
|
||||||
"term.login": "Σύνδεση",
|
"term.login": "Σύνδεση",
|
||||||
|
"term.cast": "Μετάδοση",
|
||||||
"term.about": "Σχετικά με",
|
"term.about": "Σχετικά με",
|
||||||
"term.privateSession": "Ιδιωτική περίοδος λειτουργίας",
|
"term.privateSession": "Ιδιωτική περίοδος λειτουργίας",
|
||||||
|
"term.disablePrivateSession": "Απενεργ. ιδιωτικής περ. λειτουργίας",
|
||||||
"term.queue": "Ουρά",
|
"term.queue": "Ουρά",
|
||||||
|
"term.lyrics": "Στίχοι",
|
||||||
|
"term.miniplayer": "MiniPlayer",
|
||||||
"term.history": "Ιστορικό",
|
"term.history": "Ιστορικό",
|
||||||
"term.search": "Εύρεση",
|
"term.search": "Εύρεση",
|
||||||
"term.library": "Βιβλιοθήκη",
|
"term.library": "Βιβλιοθήκη",
|
||||||
|
@ -68,6 +73,7 @@
|
||||||
"term.viewAs": "Προβολή ως",
|
"term.viewAs": "Προβολή ως",
|
||||||
"term.viewAs.coverArt": "Εξώφυλλο",
|
"term.viewAs.coverArt": "Εξώφυλλο",
|
||||||
"term.viewAs.list": "Λίστα",
|
"term.viewAs.list": "Λίστα",
|
||||||
|
"term.dynamic": "Δυναμικό",
|
||||||
"term.size": "Μέγεθος",
|
"term.size": "Μέγεθος",
|
||||||
"term.size.normal": "Κανονικό",
|
"term.size.normal": "Κανονικό",
|
||||||
"term.size.compact": "Συμπαγή",
|
"term.size.compact": "Συμπαγή",
|
||||||
|
@ -89,12 +95,26 @@
|
||||||
"term.time.added": "Προστέθηκε",
|
"term.time.added": "Προστέθηκε",
|
||||||
"term.time.released": "Κυκλοφόρησε",
|
"term.time.released": "Κυκλοφόρησε",
|
||||||
"term.time.updated": "Ενημερώθηκε",
|
"term.time.updated": "Ενημερώθηκε",
|
||||||
|
"term.time.days": "μέρες",
|
||||||
|
"term.time.day": {
|
||||||
|
"one": "μέρα",
|
||||||
|
"other": "μέρες"
|
||||||
|
},
|
||||||
"term.time.hours": "ώρες",
|
"term.time.hours": "ώρες",
|
||||||
"term.time.hour": "ώρα",
|
"term.time.hour": {
|
||||||
|
"one": "ώρα",
|
||||||
|
"other": "ώρες"
|
||||||
|
},
|
||||||
"term.time.minutes": "λεπτά",
|
"term.time.minutes": "λεπτά",
|
||||||
"term.time.minute": "λεπτό",
|
"term.time.minute": {
|
||||||
|
"one": "λεπτό",
|
||||||
|
"other": "λεπτά"
|
||||||
|
},
|
||||||
"term.time.seconds": "δευτερόλεπτα",
|
"term.time.seconds": "δευτερόλεπτα",
|
||||||
"term.time.second": "δευτερόλεπτο",
|
"term.time.second": {
|
||||||
|
"one": "δευτερόλεπτο",
|
||||||
|
"other": "δευτερόλεπτα"
|
||||||
|
},
|
||||||
"term.fullscreenView": "Πλήρης οθόνη",
|
"term.fullscreenView": "Πλήρης οθόνη",
|
||||||
"term.defaultView": "Κανονική οθόνη",
|
"term.defaultView": "Κανονική οθόνη",
|
||||||
"term.audioSettings": "Ρυθμίσεις ήχου",
|
"term.audioSettings": "Ρυθμίσεις ήχου",
|
||||||
|
@ -114,7 +134,8 @@
|
||||||
"term.contributors": "Συνεισφέροντες",
|
"term.contributors": "Συνεισφέροντες",
|
||||||
"term.equalizer": "Ισοσταθμιστής",
|
"term.equalizer": "Ισοσταθμιστής",
|
||||||
"term.reset": "Επαναφορά",
|
"term.reset": "Επαναφορά",
|
||||||
"term.tracks": {
|
"term.tracks": "τραγούδια",
|
||||||
|
"term.track": {
|
||||||
"one": "τραγούδι",
|
"one": "τραγούδι",
|
||||||
"other": "τραγούδια"
|
"other": "τραγούδια"
|
||||||
},
|
},
|
||||||
|
@ -145,6 +166,7 @@
|
||||||
"term.noVideos": "Δεν βρέθηκαν βίντεο",
|
"term.noVideos": "Δεν βρέθηκαν βίντεο",
|
||||||
"term.plugin": "Πρόσθετα",
|
"term.plugin": "Πρόσθετα",
|
||||||
"term.pluginMenu": "Μενού πρόσθετων",
|
"term.pluginMenu": "Μενού πρόσθετων",
|
||||||
|
"term.pluginMenu.none": "Δεν υπάρχουν πρόσθετα",
|
||||||
"term.replay": "Replay",
|
"term.replay": "Replay",
|
||||||
"term.uniqueAlbums": "Μοναδικά άλμπουμ",
|
"term.uniqueAlbums": "Μοναδικά άλμπουμ",
|
||||||
"term.uniqueArtists": "Μοναδικοί καλλιτέχνες",
|
"term.uniqueArtists": "Μοναδικοί καλλιτέχνες",
|
||||||
|
@ -156,10 +178,12 @@
|
||||||
"term.plays": "Αναπαραγωγές",
|
"term.plays": "Αναπαραγωγές",
|
||||||
"term.topGenres": "Κορυφαία είδη",
|
"term.topGenres": "Κορυφαία είδη",
|
||||||
"term.confirmLogout": "Θέλετε σίγουρα να αποσυνδεθείτε;",
|
"term.confirmLogout": "Θέλετε σίγουρα να αποσυνδεθείτε;",
|
||||||
|
"term.creditDesignedBy": "Σχεδιάστηκε από ${authorUsername}",
|
||||||
|
"term.discNumber": "Δίσκος ${discNumber}",
|
||||||
"home.title": "Αρχική",
|
"home.title": "Αρχική",
|
||||||
"home.recentlyPlayed": "Έπαιξαν πρόσφατα",
|
"home.recentlyPlayed": "Έπαιξαν πρόσφατα",
|
||||||
"home.recentlyAdded": "Πρόσφατες προσθήκες",
|
"home.recentlyAdded": "Πρόσφατες προσθήκες",
|
||||||
"home.artistsFeed": "Ροή των καλλιτεχνών σου",
|
"home.artistsFeed": "Ροή των καλλιτεχνών σας",
|
||||||
"home.artistsFeed.noArtist": "Ακολούθησε μερικούς καλλιτέχνες πρώτα και οι τελευταίες κυκλοφορίες τους θα εμφανίζονται εδώ",
|
"home.artistsFeed.noArtist": "Ακολούθησε μερικούς καλλιτέχνες πρώτα και οι τελευταίες κυκλοφορίες τους θα εμφανίζονται εδώ",
|
||||||
"home.madeForYou": "Δημιουργήθηκε για εσάς",
|
"home.madeForYou": "Δημιουργήθηκε για εσάς",
|
||||||
"home.friendsListeningTo": "Οι φίλοι σου ακούν",
|
"home.friendsListeningTo": "Οι φίλοι σου ακούν",
|
||||||
|
@ -176,6 +200,9 @@
|
||||||
"podcast.episodes": "Επεισόδια",
|
"podcast.episodes": "Επεισόδια",
|
||||||
"podcast.playEpisode": "Αναπαραγωγή επεισοδίου",
|
"podcast.playEpisode": "Αναπαραγωγή επεισοδίου",
|
||||||
"podcast.website": "Ιστότοπος Podcast",
|
"podcast.website": "Ιστότοπος Podcast",
|
||||||
|
"action.edit": "Επεξεργασία",
|
||||||
|
"action.done": "Τέλος",
|
||||||
|
"action.editTracklist": "Επεξεργασία λίστας τραγουδιών",
|
||||||
"action.addToLibrary": "Προσθήκη στη βιβλιοθήκη",
|
"action.addToLibrary": "Προσθήκη στη βιβλιοθήκη",
|
||||||
"action.addToLibrary.success": "Προστέθηκε στη βιβλιοθήκη",
|
"action.addToLibrary.success": "Προστέθηκε στη βιβλιοθήκη",
|
||||||
"action.addToLibrary.error": "Σφάλμα Προσθήκης στη βιβλιοθήκης",
|
"action.addToLibrary.error": "Σφάλμα Προσθήκης στη βιβλιοθήκης",
|
||||||
|
@ -202,6 +229,8 @@
|
||||||
"action.startRadio": "Έναρξη ραδιοφώνου",
|
"action.startRadio": "Έναρξη ραδιοφώνου",
|
||||||
"action.goToArtist": "Μετάβαση σε καλλιτέχνη",
|
"action.goToArtist": "Μετάβαση σε καλλιτέχνη",
|
||||||
"action.goToAlbum": "Μετάβαση σε άλμπουμ",
|
"action.goToAlbum": "Μετάβαση σε άλμπουμ",
|
||||||
|
"action.showInPlaylist": "Εμφάνιση στη λίστα αναπαραγωγής",
|
||||||
|
"action.showInAppleMusic": "Εμφάνιση στο Apple Music",
|
||||||
"action.moveToTop": "Μετακίνηση στη κορυφή",
|
"action.moveToTop": "Μετακίνηση στη κορυφή",
|
||||||
"action.share": "Κοινή χρήση",
|
"action.share": "Κοινή χρήση",
|
||||||
"action.rename": "Μετονομασία",
|
"action.rename": "Μετονομασία",
|
||||||
|
@ -209,7 +238,7 @@
|
||||||
"action.unlove": "Αναίρεση \"Μου αρέσει\"",
|
"action.unlove": "Αναίρεση \"Μου αρέσει\"",
|
||||||
"action.dislike": "Δεν μου αρέσει",
|
"action.dislike": "Δεν μου αρέσει",
|
||||||
"action.undoDislike": "Αναίρεση \"Δεν μου αρέσει\"",
|
"action.undoDislike": "Αναίρεση \"Δεν μου αρέσει\"",
|
||||||
"action.showWebRemoteQR": "Εμφάνιση Web Remote QR",
|
"action.showWebRemoteQR": "Web Remote",
|
||||||
"action.playTracksNext": "Αναπαραγωγή ${app.selectedMediaItems.length} τραγουδιών ως επόμενων",
|
"action.playTracksNext": "Αναπαραγωγή ${app.selectedMediaItems.length} τραγουδιών ως επόμενων",
|
||||||
"action.playTracksLater": "Αναπαραγωγή ${app.selectedMediaItems.length} τραγουδιών αργότερα",
|
"action.playTracksLater": "Αναπαραγωγή ${app.selectedMediaItems.length} τραγουδιών αργότερα",
|
||||||
"action.removeTracks": "Αφαίρεση ${self.selectedItems.length} τραγουδιών από την ουρά",
|
"action.removeTracks": "Αφαίρεση ${self.selectedItems.length} τραγουδιών από την ουρά",
|
||||||
|
@ -218,13 +247,23 @@
|
||||||
"action.showAlbum": "Εμφάνιση ολόκληρου άλμπουμ",
|
"action.showAlbum": "Εμφάνιση ολόκληρου άλμπουμ",
|
||||||
"action.tray.minimize": "Ελαχιστοποίηση στη γωνία γραμμής εργασιών",
|
"action.tray.minimize": "Ελαχιστοποίηση στη γωνία γραμμής εργασιών",
|
||||||
"action.tray.quit": "Έξοδος",
|
"action.tray.quit": "Έξοδος",
|
||||||
|
"action.tray.show": "Εμφάνιση Cider",
|
||||||
"action.update": "Ενημέρωση",
|
"action.update": "Ενημέρωση",
|
||||||
"action.install": "Εγκατάσταση",
|
"action.install": "Εγκατάσταση",
|
||||||
"action.copy": "Αντιγραφή",
|
"action.copy": "Αντιγραφή",
|
||||||
"action.newpreset": "Νέα προρύθμιση...",
|
"action.newpreset": "Νέα προρύθμιση...",
|
||||||
"action.deletepreset": "Διαγραφή προρύθμισης",
|
"action.deletepreset": "Διαγραφή προρύθμισης",
|
||||||
"action.open": "Άνοιγμα",
|
"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": "Γενικά",
|
||||||
"settings.header.general.description": "Προσαρμογή γενικών ρυθμίσεων για το Cider.",
|
"settings.header.general.description": "Προσαρμογή γενικών ρυθμίσεων για το Cider.",
|
||||||
"settings.option.general.language": "Γλώσσα",
|
"settings.option.general.language": "Γλώσσα",
|
||||||
|
@ -234,6 +273,10 @@
|
||||||
"settings.option.general.resumebehavior.locally.description": "Το Cider θα συνεχίσει την τελευταία συνεδρία σας αυτής της συσκευής.",
|
"settings.option.general.resumebehavior.locally.description": "Το Cider θα συνεχίσει την τελευταία συνεδρία σας αυτής της συσκευής.",
|
||||||
"settings.option.general.resumebehavior.history": "Ιστορικό",
|
"settings.option.general.resumebehavior.history": "Ιστορικό",
|
||||||
"settings.option.general.resumebehavior.history.description": "Το Cider θα βάλει στην ουρά το τελευταίο τραγούδι από το συνολικό ιστορικό Apple Music, όλων των συσκευών σας.",
|
"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.main": "Γλώσσες",
|
||||||
"settings.option.general.language.fun": "Γλώσσες για πλάκα",
|
"settings.option.general.language.fun": "Γλώσσες για πλάκα",
|
||||||
"settings.option.general.language.unsorted": "Αταξινόμητες",
|
"settings.option.general.language.unsorted": "Αταξινόμητες",
|
||||||
|
@ -242,10 +285,34 @@
|
||||||
"settings.option.general.updateCider.branch.description": "Επιλέξτε τον κλάδο στον οποίο θα γίνεται η ενημέρωση του Cider",
|
"settings.option.general.updateCider.branch.description": "Επιλέξτε τον κλάδο στον οποίο θα γίνεται η ενημέρωση του Cider",
|
||||||
"settings.option.general.updateCider.branch.main": "Σταθερό",
|
"settings.option.general.updateCider.branch.main": "Σταθερό",
|
||||||
"settings.option.general.updateCider.branch.develop": "Αναπτυξιακό",
|
"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": "Ήχος",
|
||||||
"settings.header.audio.description": "Προσαρμογή ρυθμίσεων ήχου για το Cider.",
|
"settings.header.audio.description": "Προσαρμογή ρυθμίσεων ήχου για το Cider.",
|
||||||
"settings.option.audio.volumeStep": "Βήματα έντασης",
|
"settings.option.audio.volumeStep": "Βήματα έντασης",
|
||||||
"settings.option.audio.maxVolume": "Μέγιστη ένταση",
|
"settings.option.audio.maxVolume": "Μέγιστη ένταση",
|
||||||
|
"settings.option.audio.changePlaybackRate": "Αλλαγή ταχύτητας αναπαραγωγής",
|
||||||
|
"settings.option.audio.playbackRate": "Ταχύτητα αναπαραγωγής",
|
||||||
|
"settings.option.audio.playbackRate.change": "Αλλαγή",
|
||||||
"settings.option.audio.quality": "Ποιότητα ήχου",
|
"settings.option.audio.quality": "Ποιότητα ήχου",
|
||||||
"settings.header.audio.quality.hireslossless": "Lossless υψηλής ανάλυσης",
|
"settings.header.audio.quality.hireslossless": "Lossless υψηλής ανάλυσης",
|
||||||
"settings.header.audio.quality.hireslossless.description": "έως και 24-bit/192 kHz",
|
"settings.header.audio.quality.hireslossless.description": "έως και 24-bit/192 kHz",
|
||||||
|
@ -258,18 +325,34 @@
|
||||||
"settings.option.audio.seamlessTransition": "Αδιάκοπη μετάβαση ήχου",
|
"settings.option.audio.seamlessTransition": "Αδιάκοπη μετάβαση ήχου",
|
||||||
"settings.option.audio.enableAdvancedFunctionality": "Ενεργοποίηση προηγμένης λειτουργικότητας",
|
"settings.option.audio.enableAdvancedFunctionality": "Ενεργοποίηση προηγμένης λειτουργικότητας",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.description": "Ενεργοποιώντας τη λειτουργικότητα AudioContext θα επιτρέψει σε επεκταμένες δυνατότητες ήχου όπως Κανονικοποίηση Έντασης Ήχου, Ισοσταθμιστές και Οπτικοποιητές, ωστόσο σε κάποια συστήματα μπορεί να προκαλέσει τραύλισμα ήχου.",
|
"settings.option.audio.enableAdvancedFunctionality.description": "Ενεργοποιώντας τη λειτουργικότητα AudioContext θα επιτρέψει σε επεκταμένες δυνατότητες ήχου όπως Κανονικοποίηση Έντασης Ήχου, Ισοσταθμιστές και Οπτικοποιητές, ωστόσο σε κάποια συστήματα μπορεί να προκαλέσει τραύλισμα ήχου.",
|
||||||
|
"settings.warn.audio.enableAdvancedFunctionality.lowcores": "Η συσκευή σου ίσως να μη μπορέσει να χειρηστεί αυτές τις δυνατότητες. Σίγουρα θέλετε να συνεχίσετε;",
|
||||||
"settings.option.audio.audioLab": "Cider Audio Lab",
|
"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.warn.audioLab.withoutAF": "Το AudioContext (προηγμένη λειτουργικότητα) απαιτείται για την ενεργοποίηση του Cider Audio Laboratory.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Ένταση Analog Warmth",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Αναλογική ζεστασιά",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Αλλάζει την ένταση της επεξεργασίας του Analog Warmth Module.",
|
"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.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "Το CAP δεν είναι συμβατό με τη Χωρικοποίηση Ήχου. Παρακαλούμε απενεργοποιήστε τη Χωρικοποίηση Ήχου για να συνεχίσετε.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Ένταση CAP",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Ένταση CAP",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Αλλάζει την ένταση της επεξεργασίας του ήχου. (Η επιθετική επεξεργασία μπορεί να αποφέρει ανεπιθύμητα αποτελέσματα)",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Αλλάζει την ένταση της επεξεργασίας του ήχου. (Η επιθετική επεξεργασία μπορεί να αποφέρει ανεπιθύμητα αποτελέσματα)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Κανονική",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Κανονική",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Επιθετική",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Επιθετική",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Κανονικοποίηση Έντασης Ήχου",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Κανονικοποίηση έντασης ήχου",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Κανονικοποιεί την ένταση για μεμονωμένα κομμάτια για μια πιο ομοιόμορφη εμπειρία ακρόασης.",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Κανονικοποιεί την ένταση για μεμονωμένα κομμάτια για μια πιο ομοιόμορφη εμπειρία ακρόασης. (Δεν λειτουργεί σε κομμάτια που ανέβηκαν από χρήστες)",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Διαχειρίζεται από το Audio Lab",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Χωρικοποίηση Ήχου",
|
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Χωρικοποίηση Ήχου",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Πιο τρισδιάστατος και χωρικοποιημένος ήχος (σημείωση: Αυτό δεν είναι Dolby Atmos)",
|
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Πιο τρισδιάστατος και χωρικοποιημένος ήχος (σημείωση: Αυτό δεν είναι Dolby Atmos)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Χωρικοποίηση Cider",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Χωρικοποίηση Cider",
|
||||||
|
@ -281,15 +364,16 @@
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Η Χωρικοποίηση δεν είναι συμβατή με το CAP. Παρακαλούμε απενεργοποιήστε το CAP για να συνεχίσετε.",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Η Χωρικοποίηση δεν είναι συμβατή με το CAP. Παρακαλούμε απενεργοποιήστε το CAP για να συνεχίσετε.",
|
||||||
"settings.header.visual": "Οπτικά",
|
"settings.header.visual": "Οπτικά",
|
||||||
"settings.header.visual.description": "Προσαρμογή οπτικών ρυθμίσεων για το Cider.",
|
"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.none": "Κανένα",
|
||||||
"settings.header.visual.windowBackgroundStyle.artwork": "Εξώφυλλο",
|
"settings.header.visual.windowBackgroundStyle.artwork": "Εξώφυλλο",
|
||||||
"settings.header.visual.windowBackgroundStyle.image": "Εικόνα",
|
"settings.header.visual.windowBackgroundStyle.image": "Εικόνα",
|
||||||
"settings.option.visual.animatedArtwork": "Κινούμενο Εξώφυλλο",
|
"settings.option.visual.animatedArtwork": "Κινούμενο εξώφυλλο",
|
||||||
"settings.header.visual.animatedArtwork.always": "Πάντα",
|
"settings.header.visual.animatedArtwork.always": "Πάντα",
|
||||||
"settings.header.visual.animatedArtwork.limited": "Περιορισμός σε σελίδες και ειδικές καταχωρήσεις",
|
"settings.header.visual.animatedArtwork.limited": "Περιορισμός σε σελίδες και ειδικές καταχωρήσεις",
|
||||||
"settings.header.visual.animatedArtwork.disable": "Απενεργοποιημένο παντού",
|
"settings.header.visual.animatedArtwork.disable": "Απενεργοποιημένο παντού",
|
||||||
"settings.option.visual.animatedArtworkQuality": "Ποιότητα Κινούμενου Εξωφύλλου",
|
"settings.option.visual.animatedArtworkQuality": "Ποιότητα κινούμενου εξωφύλλου",
|
||||||
"settings.header.visual.animatedArtworkQuality.low": "Χαμηλή",
|
"settings.header.visual.animatedArtworkQuality.low": "Χαμηλή",
|
||||||
"settings.header.visual.animatedArtworkQuality.medium": "Μέτρια",
|
"settings.header.visual.animatedArtworkQuality.medium": "Μέτρια",
|
||||||
"settings.header.visual.animatedArtworkQuality.high": "Υψηλή",
|
"settings.header.visual.animatedArtworkQuality.high": "Υψηλή",
|
||||||
|
@ -300,30 +384,52 @@
|
||||||
"settings.option.visual.hardwareAcceleration.description": "Απαιτεί επανεκκίνηση",
|
"settings.option.visual.hardwareAcceleration.description": "Απαιτεί επανεκκίνηση",
|
||||||
"settings.header.visual.hardwareAcceleration.default": "Προεπιλογή",
|
"settings.header.visual.hardwareAcceleration.default": "Προεπιλογή",
|
||||||
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
|
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
|
||||||
|
"settings.option.visual.uiscale": "Κλίμακα διεπαφής χρήστη",
|
||||||
"settings.header.visual.theme": "Θέμα",
|
"settings.header.visual.theme": "Θέμα",
|
||||||
"settings.option.visual.theme.github.download": "Εγκατάσταση από σύνδεσμο GitHub",
|
"settings.option.visual.theme.github.download": "Εγκατάσταση από σύνδεσμο GitHub",
|
||||||
|
"settings.option.visual.theme.github.openfolder": "Άνοιγμα φακέλου θεμάτων",
|
||||||
"settings.option.visual.theme.github.explore": "Εξερεύνηση θεμάτων GitHub",
|
"settings.option.visual.theme.github.explore": "Εξερεύνηση θεμάτων GitHub",
|
||||||
"settings.header.visual.theme.github.page": "Θέματα από το GitHub",
|
"settings.header.visual.theme.github.page": "Θέματα από το GitHub",
|
||||||
"settings.option.visual.theme.github.install.confirm": "Θέλετε σίγουρα να εγκαταστήσετε το θέμα {{ repo }};",
|
"settings.option.visual.theme.github.install.confirm": "Θέλετε σίγουρα να εγκαταστήσετε το θέμα {{ repo }};",
|
||||||
"settings.prompt.visual.theme.github.URL": "Εισάγετε τον σύνδεσμο του θέματος που θέλετε να εγκαταστήσετε",
|
"settings.prompt.visual.theme.github.URL": "Εισάγετε τον σύνδεσμο του θέματος που θέλετε να εγκαταστήσετε",
|
||||||
"settings.notyf.visual.theme.install.success": "Το θέμα εγκαταστάθηκε με επιτυχία",
|
"settings.notyf.visual.theme.install.success": "Το θέμα εγκαταστάθηκε με επιτυχία",
|
||||||
"settings.notyf.visual.theme.install.error": "Αποτυχία εγκατάστασης του θέματος",
|
"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.default": "Cider",
|
||||||
"settings.option.visual.theme.dark": "Σκοτεινό",
|
"settings.option.visual.theme.dark": "Σκοτεινό",
|
||||||
"settings.option.visual.showPersonalInfo": "Εμφάνιση προσωπικών στοιχείων",
|
"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": "Στίχοι",
|
||||||
"settings.header.lyrics.description": "Προσαρμογή ρυθμίσεων στίχων για το Cider.",
|
"settings.header.lyrics.description": "Προσαρμογή ρυθμίσεων στίχων για το Cider.",
|
||||||
"settings.option.lyrics.enableMusixmatch": "Ενεργοποίηση Στίχων Musixmatch",
|
"settings.option.lyrics.enableMusixmatch": "Ενεργοποίηση στίχων Musixmatch",
|
||||||
"settings.option.lyrics.enableMusixmatchKaraoke": "Ενεργοποίηση Λειτουργίας Καραόκε (Musixmatch μόνο)",
|
"settings.option.lyrics.enableMusixmatchKaraoke": "Ενεργοποίηση λειτουργίας καραόκε (Musixmatch μόνο)",
|
||||||
"settings.option.lyrics.musixmatchPreferredLanguage": "Προτιμώμενη Γλώσσα Μετάφρασης Musixmatch",
|
"settings.option.lyrics.musixmatchPreferredLanguage": "Προτιμώμενη γλώσσα μετάφρασης Musixmatch",
|
||||||
"settings.option.lyrics.enableYoutubeLyrics": "Ενεργοποίηση Στίχων Youtube για Μουσικά Βίντεο",
|
"settings.option.lyrics.enableYoutubeLyrics": "Ενεργοποίηση στίχων YouTube για μουσικά βίντεο",
|
||||||
"settings.header.connectivity": "Σύνδεση",
|
"settings.option.lyrics.enableQQLyrics": "Ενεργοποίηση στίχων QQ",
|
||||||
"settings.header.connectivity.description": "Προσαρμογή ρυθμίσεων σύνδεσης για το Cider.",
|
"settings.header.connectivity": "Συνδεσιμότητα",
|
||||||
|
"settings.header.connectivity.description": "Προσαρμογή ρυθμίσεων συνδεσιμότητας για το Cider.",
|
||||||
|
"settings.option.connectivity.playbackNotifications": "Ειδοποιήσεις αναπαραγωγής",
|
||||||
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
|
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
|
||||||
"settings.option.connectivity.playbackNotifications": "Ειδοποιήσεις Αναπαραγωγής",
|
"settings.option.connectivity.discordRPC.clientName": "Τίτλος",
|
||||||
"settings.header.connectivity.discordRPC.cider": "Εμφάνιση ως 'Cider'",
|
"settings.option.connectivity.discordRPC.clearOnPause": "Εκκαθάριση του Discord Rich Presence στην παύση",
|
||||||
"settings.header.connectivity.discordRPC.appleMusic": "Εμφάνιση ως 'Apple Music'",
|
"settings.option.connectivity.discordRPC.hideButtons": "Απόκρυψη κουμπιών του Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "Εκκαθάριση του Discord Rich Presence στην Παύση",
|
"settings.option.connectivity.discordRPC.detailsFormat": "Δομή λεπτομεριών",
|
||||||
|
"settings.option.connectivity.discordRPC.stateFormat": "Δομή κατάστασης",
|
||||||
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling",
|
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling",
|
||||||
"settings.option.connectivity.lastfmScrobble.delay": "Καθυστέρηση LastFM Scrobble (%)",
|
"settings.option.connectivity.lastfmScrobble.delay": "Καθυστέρηση LastFM Scrobble (%)",
|
||||||
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Ενεργοποίηση LastFM \"Now Playing\"",
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Ενεργοποίηση LastFM \"Now Playing\"",
|
||||||
|
@ -334,32 +440,52 @@
|
||||||
"settings.option.debug.openAppData": "Άνοιγμα του φακέλου Cider",
|
"settings.option.debug.openAppData": "Άνοιγμα του φακέλου Cider",
|
||||||
"settings.header.experimental": "Πειραματικές",
|
"settings.header.experimental": "Πειραματικές",
|
||||||
"settings.header.experimental.description": "Προσαρμογή πειραματικών ρυθμίσεων για το Cider.",
|
"settings.header.experimental.description": "Προσαρμογή πειραματικών ρυθμίσεων για το Cider.",
|
||||||
"settings.option.experimental.compactUI": "Συμπαγής Διεπαφή",
|
"settings.option.experimental.reinstallwidevine": "Επανεγκατάσταση του WidevineCDM",
|
||||||
"settings.option.experimental.closeButtonBehaviour": "Συμπεριφορά Κουμπιού Εξόδου",
|
"settings.option.experimental.reinstallwidevine.confirm": "Θέλετε σίγουρα να επανεγκαταστήσετε το Widevine;",
|
||||||
"settings.option.experimental.closeButtonBehaviour.quit": "Έξοδος του Cider",
|
"settings.option.experimental.unknownPlugin": "Άγνωστες πηγές",
|
||||||
"settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "Ελαχιστοποίηση στη γραμμή εργασιών",
|
"settings.option.experimental.unknownPlugin.description": "Να επιτρέπεται η εγκατάσταση πρόσθετων από repo εκτός του Cider Plugin Repository",
|
||||||
"settings.option.experimental.closeButtonBehaviour.minimizeTray": "Ελαχιστοποίηση στη γωνία γραμμής εργασιών",
|
"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.notTurnedOn": "Η Χωρικοποίηση Ήχου είναι απενεργοποιημένη. Για χρήση, παρακαλούμε ενεργοποιήστε την πρώτα.",
|
||||||
"spatial.spatialProperties": "Χωρικές Ιδιότητες",
|
"spatial.spatialProperties": "Χωρικές ιδιότητες",
|
||||||
"spatial.width": "Πλάτος",
|
"spatial.width": "Πλάτος",
|
||||||
"spatial.height": "Ύψος",
|
"spatial.height": "Ύψος",
|
||||||
"spatial.depth": "Βάθος",
|
"spatial.depth": "Βάθος",
|
||||||
"spatial.gain": "Απολαβή",
|
"spatial.gain": "Απολαβή",
|
||||||
"spatial.roomMaterials": "Υλικά Δωματίου",
|
"spatial.roomMaterials": "Υλικά δωματίου",
|
||||||
"spatial.roomDimensions": "Διαστάσεις Δωματίου",
|
"spatial.roomDimensions": "Διαστάσεις δωματίου",
|
||||||
"spatial.roomPositions": "Θέσεις Δωματίου",
|
"spatial.roomPositions": "Θέσεις δωματίου",
|
||||||
"spatial.setDimensions": "Ορισμός Διαστάσεων",
|
"spatial.setDimensions": "Ορισμός διαστάσεων",
|
||||||
"spatial.setPositions": "Ορισμός Θέσεων",
|
"spatial.setPositions": "Ορισμός θέσεων",
|
||||||
"spatial.up": "Πάνω",
|
"spatial.up": "Πάνω",
|
||||||
"spatial.front": "Πρόσοψη",
|
"spatial.front": "Πρόσοψη",
|
||||||
"spatial.left": "Αριστερά",
|
"spatial.left": "Αριστερά",
|
||||||
"spatial.right": "Δεξιά",
|
"spatial.right": "Δεξιά",
|
||||||
"spatial.back": "Πίσω Όψη",
|
"spatial.back": "Πίσω όψη",
|
||||||
"spatial.down": "Κάτω",
|
"spatial.down": "Κάτω",
|
||||||
"spatial.listener": "Ακροατής",
|
"spatial.listener": "Ακροατής",
|
||||||
"spatial.audioSource": "Πηγή Ήχου",
|
"spatial.audioSource": "Πηγή ήχου",
|
||||||
"settings.header.unfinished": "Ημιτελής",
|
"settings.header.unfinished": "Ημιτελής",
|
||||||
"remote.web.title": "Cider Remote",
|
"remote.web.title": "Cider Remote",
|
||||||
"remote.web.description": "Σαρώστε τον κωδικό QR για σύζευξη του Cider με το κινητό σας",
|
"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 και σε όλους τους συνεισφέροντές μας."
|
"about.thanks": "Μεγάλα ευχαριστώ στην Ομάδα Cider Collective και σε όλους τους συνεισφέροντές μας."
|
||||||
}
|
}
|
|
@ -73,6 +73,7 @@
|
||||||
"term.viewAs": "View As",
|
"term.viewAs": "View As",
|
||||||
"term.viewAs.coverArt": "Cuvw Awt",
|
"term.viewAs.coverArt": "Cuvw Awt",
|
||||||
"term.viewAs.list": "Wist",
|
"term.viewAs.list": "Wist",
|
||||||
|
"term.dynamic": "Dynyamic",
|
||||||
"term.size": "Size",
|
"term.size": "Size",
|
||||||
"term.size.normal": "Nyowmaw",
|
"term.size.normal": "Nyowmaw",
|
||||||
"term.size.compact": "Compact",
|
"term.size.compact": "Compact",
|
||||||
|
@ -199,6 +200,9 @@
|
||||||
"podcast.episodes": "Episodes",
|
"podcast.episodes": "Episodes",
|
||||||
"podcast.playEpisode": "Pway Episode",
|
"podcast.playEpisode": "Pway Episode",
|
||||||
"podcast.website": "Podcast Website",
|
"podcast.website": "Podcast Website",
|
||||||
|
"action.edit": "Edit",
|
||||||
|
"action.done": "Donye",
|
||||||
|
"action.editTracklist": "Edit Twackwist",
|
||||||
"action.addToLibrary": "Add to Wibwawy",
|
"action.addToLibrary": "Add to Wibwawy",
|
||||||
"action.addToLibrary.success": "Added to Wibwawy",
|
"action.addToLibrary.success": "Added to Wibwawy",
|
||||||
"action.addToLibrary.error": "Ewwow Adding 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.locally.description": "Cidew wiww wesume youw wast session on this machinye.",
|
||||||
"settings.option.general.resumebehavior.history": "Histowy",
|
"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.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.main": "Wanguages",
|
||||||
"settings.option.general.language.fun": "Fun Wanguages",
|
"settings.option.general.language.fun": "Fun Wanguages",
|
||||||
"settings.option.general.language.unsorted": "Unsowted",
|
"settings.option.general.language.unsorted": "Unsowted",
|
||||||
|
@ -280,6 +288,8 @@
|
||||||
"settings.option.general.customizeSidebar": "Customize Sidebaw Items",
|
"settings.option.general.customizeSidebar": "Customize Sidebaw Items",
|
||||||
"settings.option.general.customizeSidebar.customize": "Customize",
|
"settings.option.general.customizeSidebar.customize": "Customize",
|
||||||
"settings.option.general.keybindings": "Keybindings",
|
"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.option.general.keybindings.open": "Open",
|
||||||
"settings.description.search": "Seawch",
|
"settings.description.search": "Seawch",
|
||||||
"settings.description.albums": "Wibwawy Awbums",
|
"settings.description.albums": "Wibwawy Awbums",
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
"term.viewAs": "View As",
|
"term.viewAs": "View As",
|
||||||
"term.viewAs.coverArt": "Cover Art",
|
"term.viewAs.coverArt": "Cover Art",
|
||||||
"term.viewAs.list": "List",
|
"term.viewAs.list": "List",
|
||||||
|
"term.dynamic": "Dynamic",
|
||||||
"term.size": "Size",
|
"term.size": "Size",
|
||||||
"term.size.normal": "Normal",
|
"term.size.normal": "Normal",
|
||||||
"term.size.compact": "Compact",
|
"term.size.compact": "Compact",
|
||||||
|
@ -263,6 +264,42 @@
|
||||||
"action.cast.scanning": "Scanning...",
|
"action.cast.scanning": "Scanning...",
|
||||||
"action.createNew": "Create New...",
|
"action.createNew": "Create New...",
|
||||||
"action.openArtworkInBrowser": "Open artwork in browser",
|
"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": "General",
|
||||||
"settings.header.general.description": "Adjust the general settings for Cider.",
|
"settings.header.general.description": "Adjust the general settings for Cider.",
|
||||||
"settings.option.general.language": "Language",
|
"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.description": "An assortment of in-house developed audio effects for Cider.",
|
||||||
"settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California",
|
"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.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": "Analog Warmth",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simulates the analog warmth modelled after the Korg Nutube 6P1",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simulates the analog warmth modelled after the Korg Nutube 6P1",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity",
|
||||||
|
@ -391,6 +429,13 @@
|
||||||
"settings.header.visual.theme.github.page": "Themes from GitHub",
|
"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.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.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.option.visual.theme.github.available": "Available",
|
||||||
|
"settings.option.visual.theme.github.applied": "Applied",
|
||||||
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
||||||
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
||||||
"settings.header.visual.plugin": "Plugin",
|
"settings.header.visual.plugin": "Plugin",
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
"term.viewAs": "Ver como",
|
"term.viewAs": "Ver como",
|
||||||
"term.viewAs.coverArt": "Portada",
|
"term.viewAs.coverArt": "Portada",
|
||||||
"term.viewAs.list": "Lista",
|
"term.viewAs.list": "Lista",
|
||||||
|
"term.dynamic": "Dinámico",
|
||||||
"term.size": "Tamaño",
|
"term.size": "Tamaño",
|
||||||
"term.size.normal": "Normal",
|
"term.size.normal": "Normal",
|
||||||
"term.size.compact": "Compacto",
|
"term.size.compact": "Compacto",
|
||||||
|
@ -199,6 +200,9 @@
|
||||||
"podcast.episodes": "Episodios",
|
"podcast.episodes": "Episodios",
|
||||||
"podcast.playEpisode": "Reproducir Episodio",
|
"podcast.playEpisode": "Reproducir Episodio",
|
||||||
"podcast.website": "Sitio web de Podcasts",
|
"podcast.website": "Sitio web de Podcasts",
|
||||||
|
"action.edit": "Editar",
|
||||||
|
"action.done": "Hecho",
|
||||||
|
"action.editTracklist": "Edit Tracklist",
|
||||||
"action.addToLibrary": "Agregar a la Biblioteca",
|
"action.addToLibrary": "Agregar a la Biblioteca",
|
||||||
"action.addToLibrary.success": "Agregado a la Biblioteca",
|
"action.addToLibrary.success": "Agregado a la Biblioteca",
|
||||||
"action.addToLibrary.error": "Error al agregar a la Biblioteca",
|
"action.addToLibrary.error": "Error al agregar a la Biblioteca",
|
||||||
|
@ -260,6 +264,42 @@
|
||||||
"action.cast.scanning": "Escaneando...",
|
"action.cast.scanning": "Escaneando...",
|
||||||
"action.createNew": "Crear Nuevo...",
|
"action.createNew": "Crear Nuevo...",
|
||||||
"action.openArtworkInBrowser": "Abrir Ilustración en el navegador",
|
"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": "General",
|
||||||
"settings.header.general.description": "Ajuste la configuración general de Cider.",
|
"settings.header.general.description": "Ajuste la configuración general de Cider.",
|
||||||
"settings.option.general.language": "Idioma",
|
"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.locally.description": "Cider reanudará su última sesión en esta PC.",
|
||||||
"settings.option.general.resumebehavior.history": "Histórico",
|
"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.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.main": "Idiomas",
|
||||||
"settings.option.general.language.fun": "Idiomas Fun (Parodias)",
|
"settings.option.general.language.fun": "Idiomas Fun (Parodias)",
|
||||||
"settings.option.general.language.unsorted": "Sin Clasificar",
|
"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": "Personalizar elementos de la barra lateral",
|
||||||
"settings.option.general.customizeSidebar.customize": "Personalizar",
|
"settings.option.general.customizeSidebar.customize": "Personalizar",
|
||||||
"settings.option.general.keybindings": "Combinaciones de Teclas",
|
"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.option.general.keybindings.open": "Abrir",
|
||||||
"settings.description.search": "Buscar",
|
"settings.description.search": "Buscar",
|
||||||
"settings.description.albums": "Álbumes de la biblioteca",
|
"settings.description.albums": "Álbumes de la biblioteca",
|
||||||
|
@ -320,6 +366,7 @@
|
||||||
"settings.option.audio.audioLab.description": "Una variedad de efectos de audio desarrollados internamente para Cider.",
|
"settings.option.audio.audioLab.description": "Una variedad de efectos de audio desarrollados internamente para Cider.",
|
||||||
"settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California",
|
"settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California",
|
||||||
"settings.warn.audioLab.withoutAF": "Se requiere AudioContext (funcionalidad avanzada) para habilitar Laboratorio de audio de Cider.",
|
"settings.warn.audioLab.withoutAF": "Se requiere AudioContext (funcionalidad avanzada) para habilitar Laboratorio de audio de Cider.",
|
||||||
|
"settings.warn.enableAdvancedFunctionality": "AudioContext (funcionalidad avanzada) es necesaria para habilitar esta característica.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Calidez analógica",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Calidez analógica",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simula la calidez analógica inspirada en el Korg Nutube 6P1",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simula la calidez analógica inspirada en el Korg Nutube 6P1",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Intensidad de calidez analógica",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Intensidad de calidez analógica",
|
||||||
|
@ -382,6 +429,13 @@
|
||||||
"settings.header.visual.theme.github.page": "Temas de GitHub",
|
"settings.header.visual.theme.github.page": "Temas de GitHub",
|
||||||
"settings.option.visual.theme.github.install.confirm": "¿Está seguro de que desea instalar {{ repo }}?",
|
"settings.option.visual.theme.github.install.confirm": "¿Está seguro de que desea instalar {{ repo }}?",
|
||||||
"settings.prompt.visual.theme.github.URL": "Introduce la URL del tema que quieres instalar",
|
"settings.prompt.visual.theme.github.URL": "Introduce la URL del tema que quieres instalar",
|
||||||
|
"settings.prompt.visual.theme.uninstallTheme": "¿Estas seguro que lo quieres desinstalar {{ theme }}?",
|
||||||
|
"settings.option.visual.theme.checkForUpdates": "Buscar actualizaciones",
|
||||||
|
"settings.option.visual.theme.manageStyles": "Gestionar Estilos",
|
||||||
|
"settings.option.visual.theme.uninstall": "Desinstalar",
|
||||||
|
"settings.option.visual.theme.viewInfo": "Ver Información",
|
||||||
|
"settings.option.visual.theme.github.available": "Disponible",
|
||||||
|
"settings.option.visual.theme.github.applied": "Aplicado",
|
||||||
"settings.notyf.visual.theme.install.success": "Tema Instalado Correctamente",
|
"settings.notyf.visual.theme.install.success": "Tema Instalado Correctamente",
|
||||||
"settings.notyf.visual.theme.install.error": "La Instalación del Tema Falló",
|
"settings.notyf.visual.theme.install.error": "La Instalación del Tema Falló",
|
||||||
"settings.header.visual.plugin": "Plugin",
|
"settings.header.visual.plugin": "Plugin",
|
||||||
|
@ -410,6 +464,7 @@
|
||||||
"settings.option.lyrics.enableMusixmatchKaraoke": "Habilitar el modo Karaoke (solo Musixmatch)",
|
"settings.option.lyrics.enableMusixmatchKaraoke": "Habilitar el modo Karaoke (solo Musixmatch)",
|
||||||
"settings.option.lyrics.musixmatchPreferredLanguage": "Idioma preferido de traducción de 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.enableYoutubeLyrics": "Habilitar letras de YouTube para videos musicales",
|
||||||
|
"settings.option.lyrics.enableQQLyrics": "Habilitar letras de QQ",
|
||||||
"settings.header.connectivity": "Conectividad",
|
"settings.header.connectivity": "Conectividad",
|
||||||
"settings.header.connectivity.description": "Ajuste la configuración de conectividad para Cider.",
|
"settings.header.connectivity.description": "Ajuste la configuración de conectividad para Cider.",
|
||||||
"settings.option.connectivity.playbackNotifications": "Notificaciones de Reproducción",
|
"settings.option.connectivity.playbackNotifications": "Notificaciones de Reproducción",
|
||||||
|
@ -442,7 +497,9 @@
|
||||||
"settings.option.visual.transparent.description": "Marco transparente (necesita compatibilidad con temas, requiere reiniciar)",
|
"settings.option.visual.transparent.description": "Marco transparente (necesita compatibilidad con temas, requiere reiniciar)",
|
||||||
"settings.header.advanced": "Avanzado",
|
"settings.header.advanced": "Avanzado",
|
||||||
"settings.header.connect": "Conectar",
|
"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.spatialProperties": "Propiedades de Espacialización",
|
||||||
"spatial.width": "Ancho",
|
"spatial.width": "Ancho",
|
||||||
"spatial.height": "Alto",
|
"spatial.height": "Alto",
|
||||||
|
|
|
@ -378,6 +378,8 @@
|
||||||
"settings.header.visual.theme.github.page": "Témák a GitHub-ról",
|
"settings.header.visual.theme.github.page": "Témák a GitHub-ról",
|
||||||
"settings.option.visual.theme.github.install.confirm": "Biztosan szeretnéd telepíteni a(z) {{ repo }} témát?",
|
"settings.option.visual.theme.github.install.confirm": "Biztosan szeretnéd telepíteni a(z) {{ repo }} témát?",
|
||||||
"settings.prompt.visual.theme.github.URL": "Add meg a telepítendő téma URL-jét",
|
"settings.prompt.visual.theme.github.URL": "Add meg a telepítendő téma URL-jét",
|
||||||
|
"settings.option.visual.theme.github.available": "Elérhető",
|
||||||
|
"settings.option.visual.theme.github.applied": "Alkalmazva",
|
||||||
"settings.notyf.visual.theme.install.success": "Téma sikeresen telepítve",
|
"settings.notyf.visual.theme.install.success": "Téma sikeresen telepítve",
|
||||||
"settings.notyf.visual.theme.install.error": "Sikertelen volt a téma telepítése",
|
"settings.notyf.visual.theme.install.error": "Sikertelen volt a téma telepítése",
|
||||||
"settings.header.visual.plugin": "Plugin",
|
"settings.header.visual.plugin": "Plugin",
|
||||||
|
@ -406,6 +408,7 @@
|
||||||
"settings.option.lyrics.enableMusixmatchKaraoke": "Karaoke mód bekapcsolása (Csak MusixMatch)",
|
"settings.option.lyrics.enableMusixmatchKaraoke": "Karaoke mód bekapcsolása (Csak MusixMatch)",
|
||||||
"settings.option.lyrics.musixmatchPreferredLanguage": "MusixMatch fordítás nyelve",
|
"settings.option.lyrics.musixmatchPreferredLanguage": "MusixMatch fordítás nyelve",
|
||||||
"settings.option.lyrics.enableYoutubeLyrics": "YouTube dalszövegek engedélyezése a zenei videóknál",
|
"settings.option.lyrics.enableYoutubeLyrics": "YouTube dalszövegek engedélyezése a zenei videóknál",
|
||||||
|
"settings.option.lyrics.enableQQLyrics": "QQLyrics dalszövegek engedélyezése",
|
||||||
"settings.header.connectivity": "Csatlakozások",
|
"settings.header.connectivity": "Csatlakozások",
|
||||||
"settings.header.connectivity.description": "A Cider csatlakozás beállításainak módosítása.",
|
"settings.header.connectivity.description": "A Cider csatlakozás beállításainak módosítása.",
|
||||||
"settings.option.connectivity.playbackNotifications": "Lejátszási értesítések",
|
"settings.option.connectivity.playbackNotifications": "Lejátszási értesítések",
|
||||||
|
|
|
@ -264,6 +264,42 @@
|
||||||
"action.cast.scanning": "Scanning...",
|
"action.cast.scanning": "Scanning...",
|
||||||
"action.createNew": "Create New...",
|
"action.createNew": "Create New...",
|
||||||
"action.openArtworkInBrowser": "Open artwork in browser",
|
"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": "General",
|
||||||
"settings.header.general.description": "Adjust the general settings for Cider.",
|
"settings.header.general.description": "Adjust the general settings for Cider.",
|
||||||
"settings.option.general.language": "Language",
|
"settings.option.general.language": "Language",
|
||||||
|
@ -330,6 +366,7 @@
|
||||||
"settings.option.audio.audioLab.description": "An assortment of in-house developed audio effects for Cider.",
|
"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.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.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": "Analog Warmth",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simulates the analog warmth modelled after the Korg Nutube 6P1",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simulates the analog warmth modelled after the Korg Nutube 6P1",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity",
|
||||||
|
@ -392,6 +429,13 @@
|
||||||
"settings.header.visual.theme.github.page": "Themes from GitHub",
|
"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.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.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.option.visual.theme.github.available": "Available",
|
||||||
|
"settings.option.visual.theme.github.applied": "Applied",
|
||||||
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
||||||
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
||||||
"settings.header.visual.plugin": "Plugin",
|
"settings.header.visual.plugin": "Plugin",
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"term.login": "登录",
|
"term.login": "登录",
|
||||||
"term.about": "关于",
|
"term.about": "关于",
|
||||||
"term.privateSession": "私人聆听",
|
"term.privateSession": "私人聆听",
|
||||||
|
"term.lyrics": "歌词",
|
||||||
"term.queue": "待播清单",
|
"term.queue": "待播清单",
|
||||||
"term.history": "历史记录",
|
"term.history": "历史记录",
|
||||||
"term.miniplayer": "迷你播放器",
|
"term.miniplayer": "迷你播放器",
|
||||||
|
@ -115,7 +116,11 @@
|
||||||
"term.contributors": "贡献者",
|
"term.contributors": "贡献者",
|
||||||
"term.equalizer": "均衡器",
|
"term.equalizer": "均衡器",
|
||||||
"term.reset": "重置",
|
"term.reset": "重置",
|
||||||
"term.tracks": "首歌曲",
|
"term.track": {
|
||||||
|
"one": "首歌曲",
|
||||||
|
"other": "首歌曲"
|
||||||
|
},
|
||||||
|
"term.tracks": "歌曲",
|
||||||
"term.videos": "音乐视频",
|
"term.videos": "音乐视频",
|
||||||
"term.menu": "菜单",
|
"term.menu": "菜单",
|
||||||
"term.check": "检查",
|
"term.check": "检查",
|
||||||
|
@ -161,6 +166,9 @@
|
||||||
"podcast.episodes": "单集",
|
"podcast.episodes": "单集",
|
||||||
"podcast.playEpisode": "播放单集",
|
"podcast.playEpisode": "播放单集",
|
||||||
"podcast.website": "Podcast 网站",
|
"podcast.website": "Podcast 网站",
|
||||||
|
"action.edit": "编辑",
|
||||||
|
"action.done": "完成",
|
||||||
|
"action.editTracklist": "编辑歌曲清单",
|
||||||
"action.addToLibrary": "加入资料库",
|
"action.addToLibrary": "加入资料库",
|
||||||
"action.addToLibrary.success": "成功加入资料库",
|
"action.addToLibrary.success": "成功加入资料库",
|
||||||
"action.addToLibrary.error": "加入资料库的过程发生了错误",
|
"action.addToLibrary.error": "加入资料库的过程发生了错误",
|
||||||
|
@ -187,6 +195,7 @@
|
||||||
"action.startRadio": "开始电台",
|
"action.startRadio": "开始电台",
|
||||||
"action.goToArtist": "前往艺人",
|
"action.goToArtist": "前往艺人",
|
||||||
"action.goToAlbum": "前往专辑",
|
"action.goToAlbum": "前往专辑",
|
||||||
|
"action.showInAppleMusic": "显示于 Apple Music",
|
||||||
"action.moveToTop": "移到顶部",
|
"action.moveToTop": "移到顶部",
|
||||||
"action.share": "分享歌曲",
|
"action.share": "分享歌曲",
|
||||||
"action.rename": "重命名",
|
"action.rename": "重命名",
|
||||||
|
@ -203,11 +212,19 @@
|
||||||
"action.showAlbum": "显示专辑",
|
"action.showAlbum": "显示专辑",
|
||||||
"action.tray.minimize": "最小化",
|
"action.tray.minimize": "最小化",
|
||||||
"action.tray.quit": "退出",
|
"action.tray.quit": "退出",
|
||||||
|
|
||||||
"action.update": "更新",
|
"action.update": "更新",
|
||||||
"action.copy": "复制",
|
"action.copy": "复制",
|
||||||
"action.newpreset": "新建默认...",
|
"action.newpreset": "新建默认...",
|
||||||
"action.deletepreset": "删除默认",
|
"action.deletepreset": "删除默认",
|
||||||
|
"action.open": "打开",
|
||||||
|
"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": "添加...",
|
||||||
"settings.header.general": "通用",
|
"settings.header.general": "通用",
|
||||||
"settings.header.general.description": "调整 Cider 的通用设置",
|
"settings.header.general.description": "调整 Cider 的通用设置",
|
||||||
"settings.option.audio.volumeStep": "音量改变量",
|
"settings.option.audio.volumeStep": "音量改变量",
|
||||||
|
@ -218,6 +235,10 @@
|
||||||
"settings.option.general.resumebehavior.locally.description": "Cider 将还原你在这台电脑上的最后一次操作。",
|
"settings.option.general.resumebehavior.locally.description": "Cider 将还原你在这台电脑上的最后一次操作。",
|
||||||
"settings.option.general.resumebehavior.history": "历史",
|
"settings.option.general.resumebehavior.history": "历史",
|
||||||
"settings.option.general.resumebehavior.history.description": "Cider 将跨设备将你的整个 Apple Music 历史记录中的最后一首歌曲排队入列。",
|
"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": "语言",
|
"settings.option.general.language": "语言",
|
||||||
"settings.option.general.language.main": "语言",
|
"settings.option.general.language.main": "语言",
|
||||||
"settings.option.general.language.fun": "恶搞语言",
|
"settings.option.general.language.fun": "恶搞语言",
|
||||||
|
@ -229,6 +250,8 @@
|
||||||
"settings.option.general.updateCider.branch.develop": "测试(Develop)",
|
"settings.option.general.updateCider.branch.develop": "测试(Develop)",
|
||||||
"settings.option.general.customizeSidebar": "自定义侧边栏的功能",
|
"settings.option.general.customizeSidebar": "自定义侧边栏的功能",
|
||||||
"settings.option.general.customizeSidebar.customize": "自定义",
|
"settings.option.general.customizeSidebar.customize": "自定义",
|
||||||
|
"settings.option.general.keybindings": "快捷操作键",
|
||||||
|
"settings.option.general.keybindings.open": "打开",
|
||||||
"settings.notyf.updateCider.update-not-available": "没有可用的更新",
|
"settings.notyf.updateCider.update-not-available": "没有可用的更新",
|
||||||
"settings.notyf.updateCider.update-downloaded": "更新已成功下载,重启后进行更新",
|
"settings.notyf.updateCider.update-downloaded": "更新已成功下载,重启后进行更新",
|
||||||
"settings.notyf.updateCider.update-error": "更新时,发生错误",
|
"settings.notyf.updateCider.update-error": "更新时,发生错误",
|
||||||
|
@ -250,20 +273,27 @@
|
||||||
"settings.option.audio.audioLab": "Cider 音频实验室",
|
"settings.option.audio.audioLab": "Cider 音频实验室",
|
||||||
"settings.option.audio.audioLab.description": "包含由 Cider 开发团队进行的各种音频优化功能。",
|
"settings.option.audio.audioLab.description": "包含由 Cider 开发团队进行的各种音频优化功能。",
|
||||||
"settings.warn.audioLab.withoutAF": "使用 Cider 音频实验室需要打开进阶音频功能才可使用。" ,
|
"settings.warn.audioLab.withoutAF": "使用 Cider 音频实验室需要打开进阶音频功能才可使用。" ,
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "模拟温暖",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "模拟温暖",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "以 Korg Nutube 6P1 为蓝本的模拟温暖。",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "以 Korg Nutube 6P1 为蓝本的模拟温暖。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "模拟温暖强度",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "模拟温暖强度",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "改变模拟温暖模组处理的强度。",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "改变模拟温暖模组处理的强度。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "温和",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "温和",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "温暖",
|
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "温暖",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 数码增强音频处理™️",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider 音乐气氛实现器™️",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "以最先进的音频置为蓝本,实现不同的音乐气氛。",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider 音乐气氛™️模式",
|
||||||
|
"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 数码增强音频处理™️",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "通过人类的听力心理学模型和 AAC 编码特色的即时算法,强化 256 kbps AAC 音频的感知音频质量。",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "通过人类的听力心理学模型和 AAC 编码特色的即时算法,强化 256 kbps AAC 音频的感知音频质量。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "数码增强音频处理设置",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "数码增强音频处理设置",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "将更改音频处理的激进/振奋程度(增强选项有可能会引起杂讯)。",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "将更改音频处理的激进/振奋程度(增强选项有可能会引起杂讯)。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "标准",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "标准",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "增强",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "增强",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量平衡",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量平衡",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "自动将歌曲播放音量调整到相同水平,享受更舒适的聆听体验。",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "自动将歌曲播放音量调整到相同水平,享受更舒适的聆听体验。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "此功能由音频实验室管理",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "此功能由音频实验室管理",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空间音频",
|
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空间音频",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "将音频进行空间化处理来制造一个更立体的聆听体验(注:此功能不是官方的杜比全景声)。",
|
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "将音频进行空间化处理来制造一个更立体的聆听体验(注:此功能不是官方的杜比全景声)。",
|
||||||
|
@ -274,6 +304,7 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "标准",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "标准",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "发烧友",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "发烧友",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "音频空间无法与 CAP 相容,请关闭 CAP 在进行操作。",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "音频空间无法与 CAP 相容,请关闭 CAP 在进行操作。",
|
||||||
|
"settings.option.visual.uiscale": "UI界面大小",
|
||||||
"settings.header.visual": "外观",
|
"settings.header.visual": "外观",
|
||||||
"settings.header.visual.description": "调整 Cider 的外观",
|
"settings.header.visual.description": "调整 Cider 的外观",
|
||||||
"settings.option.visual.windowBackgroundStyle": "窗口背景样式",
|
"settings.option.visual.windowBackgroundStyle": "窗口背景样式",
|
||||||
|
@ -312,7 +343,7 @@
|
||||||
"settings.notyf.visual.plugin.install.error": "插件安装失败",
|
"settings.notyf.visual.plugin.install.error": "插件安装失败",
|
||||||
"settings.option.visual.theme.default": "默认",
|
"settings.option.visual.theme.default": "默认",
|
||||||
"settings.option.visual.theme.dark": "午夜黑",
|
"settings.option.visual.theme.dark": "午夜黑",
|
||||||
"settings.option.visual.showPersonalInfo": "显示个人资料",
|
"settings.option.visual.showPersonalInfo": "显示个人信息",
|
||||||
"settings.header.window": "窗口",
|
"settings.header.window": "窗口",
|
||||||
"settings.header.window.description": "调整 Cider 的窗口设置",
|
"settings.header.window.description": "调整 Cider 的窗口设置",
|
||||||
"settings.option.window.openOnStartup": "开机时,自动运行 Cider ",
|
"settings.option.window.openOnStartup": "开机时,自动运行 Cider ",
|
||||||
|
@ -327,19 +358,21 @@
|
||||||
"settings.option.lyrics.enableMusixmatchKaraoke": "启用卡拉 OK 模式(仅 Musixmatch)",
|
"settings.option.lyrics.enableMusixmatchKaraoke": "启用卡拉 OK 模式(仅 Musixmatch)",
|
||||||
"settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌词语言偏好",
|
"settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌词语言偏好",
|
||||||
"settings.option.lyrics.enableYoutubeLyrics": "播放 MV 时使用 YouTube 歌词",
|
"settings.option.lyrics.enableYoutubeLyrics": "播放 MV 时使用 YouTube 歌词",
|
||||||
|
"settings.option.lyrics.enableQQLyrics": "启用 QQ 音乐的歌词",
|
||||||
"settings.header.connectivity": "外部连接",
|
"settings.header.connectivity": "外部连接",
|
||||||
"settings.header.connectivity.description": "调整 Cider 与外部应用的交互设置",
|
"settings.header.connectivity.description": "调整 Cider 与外部应用的交互设置",
|
||||||
"settings.option.connectivity.discordRPC": "Discord 动态",
|
"settings.option.connectivity.discordRPC": "Discord 动态",
|
||||||
"settings.option.connectivity.playbackNotifications": "歌曲播放通知",
|
"settings.option.connectivity.playbackNotifications": "歌曲播放通知",
|
||||||
"settings.header.connectivity.discordRPC.cider": "显示正在使用 'Cider'",
|
"settings.option.connectivity.discordRPC.clientName": "应用程序名称",
|
||||||
"settings.header.connectivity.discordRPC.appleMusic": "显示正在使用 'Apple Music'",
|
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "暂停时清除 Discord 动态",
|
"settings.option.connectivity.discordRPC.clearOnPause": "暂停时清除 Discord 动态",
|
||||||
"settings.option.connectivity.discordRPC.hideButtons": "隐藏 Discord 动态上的按钮",
|
"settings.option.connectivity.discordRPC.hideButtons": "隐藏 Discord 动态上的按钮",
|
||||||
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 记录",
|
"settings.option.connectivity.discordRPC.detailsFormat": "详细信息格式",
|
||||||
"settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延迟 (%)",
|
"settings.option.connectivity.discordRPC.stateFormat": "动态格式",
|
||||||
"settings.option.connectivity.lastfmScrobble.nowPlaying": "打开 LastFM 正在播放",
|
"settings.option.connectivity.lastfmScrobble": "Last.FM 音乐记录",
|
||||||
"settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除合作者 (LastFM)",
|
"settings.option.connectivity.lastfmScrobble.delay": "Last.FM 歌曲追踪延迟 (%)",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "不记录单曲循环 (LastFM)",
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "打开 Last.FM 正在聆听",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除合作者 (Last.FM)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.filterLoop": "不记录单曲循环 (Last.FM)",
|
||||||
"settings.header.debug": "Debug",
|
"settings.header.debug": "Debug",
|
||||||
"settings.option.debug.copy_log": "拷贝日志至剪贴板",
|
"settings.option.debug.copy_log": "拷贝日志至剪贴板",
|
||||||
"settings.option.debug.openAppData": "打开 Cider 程序文件夹",
|
"settings.option.debug.openAppData": "打开 Cider 程序文件夹",
|
||||||
|
|
|
@ -151,6 +151,9 @@
|
||||||
"podcast.episodes": "單集",
|
"podcast.episodes": "單集",
|
||||||
"podcast.playEpisode": "播放單集",
|
"podcast.playEpisode": "播放單集",
|
||||||
"podcast.website": "Podcast 網站",
|
"podcast.website": "Podcast 網站",
|
||||||
|
"action.edit": "編輯",
|
||||||
|
"action.done": "完成",
|
||||||
|
"action.editTracklist": "編輯歌曲清單",
|
||||||
"action.addToLibrary": "加入到資料庫",
|
"action.addToLibrary": "加入到資料庫",
|
||||||
"action.addToLibrary.success": "成功加入資料庫",
|
"action.addToLibrary.success": "成功加入資料庫",
|
||||||
"action.addToLibrary.error": "加入資料庫時,發生錯誤",
|
"action.addToLibrary.error": "加入資料庫時,發生錯誤",
|
||||||
|
@ -215,6 +218,10 @@
|
||||||
"settings.option.general.resumebehavior.locally.description": "Cider 將還原你在這台電腦上的最後一次操作。",
|
"settings.option.general.resumebehavior.locally.description": "Cider 將還原你在這台電腦上的最後一次操作。",
|
||||||
"settings.option.general.resumebehavior.history": "歷史",
|
"settings.option.general.resumebehavior.history": "歷史",
|
||||||
"settings.option.general.resumebehavior.history.description": "Cider 將跨裝置將你的整個 Apple Music 歷史記錄中的最後一首歌曲排隊入列。",
|
"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.main": "語言",
|
||||||
"settings.option.general.language.fun": "特殊語言",
|
"settings.option.general.language.fun": "特殊語言",
|
||||||
"settings.option.general.language.unsorted": "未分類",
|
"settings.option.general.language.unsorted": "未分類",
|
||||||
|
@ -345,8 +352,8 @@
|
||||||
"settings.option.connectivity.discordRPC.hideButtons": "隱藏 Discord 動態上的按鈕",
|
"settings.option.connectivity.discordRPC.hideButtons": "隱藏 Discord 動態上的按鈕",
|
||||||
"settings.option.connectivity.discordRPC.detailsFormat": "詳細資訊格式",
|
"settings.option.connectivity.discordRPC.detailsFormat": "詳細資訊格式",
|
||||||
"settings.option.connectivity.discordRPC.stateFormat": "狀態格式",
|
"settings.option.connectivity.discordRPC.stateFormat": "狀態格式",
|
||||||
"settings.option.connectivity.lastfmScrobble": "Last.FM Scrobbling 記錄",
|
"settings.option.connectivity.lastfmScrobble": "Last.FM 音樂記錄",
|
||||||
"settings.option.connectivity.lastfmScrobble.delay": "Last.FM Scrobble 延遲 (%)",
|
"settings.option.connectivity.lastfmScrobble.delay": "Last.FM 歌曲追蹤延遲 (%)",
|
||||||
"settings.option.connectivity.lastfmScrobble.nowPlaying": "開啟 Last.FM 正在聆聽",
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "開啟 Last.FM 正在聆聽",
|
||||||
"settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除客串藝人 (Last.FM)",
|
"settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除客串藝人 (Last.FM)",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "不記錄單曲循環 (Last.FM)",
|
"settings.option.connectivity.lastfmScrobble.filterLoop": "不記錄單曲循環 (Last.FM)",
|
||||||
|
|
|
@ -212,7 +212,6 @@ export class AppEvents {
|
||||||
* Handles the creation of a new instance of the app
|
* Handles the creation of a new instance of the app
|
||||||
*/
|
*/
|
||||||
private InstanceHandler() {
|
private InstanceHandler() {
|
||||||
|
|
||||||
// Detects of an existing instance is running (So if the lock has been achieved, no existing instance has been found)
|
// Detects of an existing instance is running (So if the lock has been achieved, no existing instance has been found)
|
||||||
const gotTheLock = app.requestSingleInstanceLock()
|
const gotTheLock = app.requestSingleInstanceLock()
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,18 @@ import * as windowStateKeeper from "electron-window-state";
|
||||||
import * as express from "express";
|
import * as express from "express";
|
||||||
import * as getPort from "get-port";
|
import * as getPort from "get-port";
|
||||||
import {search} from "youtube-search-without-api-key";
|
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 {Stream} from "stream";
|
||||||
import {networkInterfaces} from "os";
|
import {networkInterfaces} from "os";
|
||||||
import * as mm from 'music-metadata';
|
import * as mm from 'music-metadata';
|
||||||
|
@ -37,6 +48,7 @@ export class BrowserWindow {
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
dev: app.isPackaged,
|
dev: app.isPackaged,
|
||||||
osRelease: os.release(),
|
osRelease: os.release(),
|
||||||
|
updatable: !process.windowsStore || !process.mas,
|
||||||
components: [
|
components: [
|
||||||
"pages/podcasts",
|
"pages/podcasts",
|
||||||
"pages/apple-account-settings",
|
"pages/apple-account-settings",
|
||||||
|
@ -45,6 +57,7 @@ export class BrowserWindow {
|
||||||
"pages/library-artists",
|
"pages/library-artists",
|
||||||
"pages/browse",
|
"pages/browse",
|
||||||
"pages/settings",
|
"pages/settings",
|
||||||
|
"pages/installed-themes",
|
||||||
"pages/listen_now",
|
"pages/listen_now",
|
||||||
"pages/home",
|
"pages/home",
|
||||||
"pages/artist-feed",
|
"pages/artist-feed",
|
||||||
|
@ -95,6 +108,7 @@ export class BrowserWindow {
|
||||||
"components/fullscreen",
|
"components/fullscreen",
|
||||||
"components/miniplayer",
|
"components/miniplayer",
|
||||||
"components/castmenu",
|
"components/castmenu",
|
||||||
|
"components/airplay-modal",
|
||||||
"components/artist-chip",
|
"components/artist-chip",
|
||||||
"components/hello-world",
|
"components/hello-world",
|
||||||
"components/inline-collection-list",
|
"components/inline-collection-list",
|
||||||
|
@ -176,6 +190,10 @@ export class BrowserWindow {
|
||||||
page: "settings",
|
page: "settings",
|
||||||
component: `<cider-settings></cider-settings>`,
|
component: `<cider-settings></cider-settings>`,
|
||||||
condition: `page == 'settings'`
|
condition: `page == 'settings'`
|
||||||
|
}, {
|
||||||
|
page: "installed-themes",
|
||||||
|
component: `<installed-themes></installed-themes>`,
|
||||||
|
condition: `page == 'installed-themes'`
|
||||||
}, {
|
}, {
|
||||||
page: "search",
|
page: "search",
|
||||||
component: `<cider-search :search="search"></cider-search>`,
|
component: `<cider-search :search="search"></cider-search>`,
|
||||||
|
@ -254,8 +272,10 @@ export class BrowserWindow {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static watcher: any;
|
||||||
|
|
||||||
StartWatcher(path: string) {
|
StartWatcher(path: string) {
|
||||||
const watcher = watch(path, {
|
BrowserWindow.watcher = watch(path, {
|
||||||
ignored: /[\/\\]\./,
|
ignored: /[\/\\]\./,
|
||||||
persistent: true
|
persistent: true
|
||||||
});
|
});
|
||||||
|
@ -265,7 +285,7 @@ export class BrowserWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare the listeners of the watcher
|
// Declare the listeners of the watcher
|
||||||
watcher
|
BrowserWindow.watcher
|
||||||
.on('add', function (path: string) {
|
.on('add', function (path: string) {
|
||||||
// console.log('File', path, 'has been added');
|
// console.log('File', path, 'has been added');
|
||||||
})
|
})
|
||||||
|
@ -292,6 +312,10 @@ export class BrowserWindow {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async StopWatcher() {
|
||||||
|
await BrowserWindow.watcher.close();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the browser window
|
* Creates the browser window
|
||||||
* @generator
|
* @generator
|
||||||
|
@ -311,6 +335,8 @@ export class BrowserWindow {
|
||||||
});
|
});
|
||||||
this.options.width = windowState.width;
|
this.options.width = windowState.width;
|
||||||
this.options.height = windowState.height;
|
this.options.height = windowState.height;
|
||||||
|
this.options.x = windowState.x;
|
||||||
|
this.options.y = windowState.y;
|
||||||
|
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
default:
|
default:
|
||||||
|
@ -696,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", () => {
|
ipcMain.handle("reinstall-widevine-cdm", () => {
|
||||||
// remove WidevineCDM from appdata folder
|
// remove WidevineCDM from appdata folder
|
||||||
const widevineCdmPath = join(app.getPath("userData"), "./WidevineCdm");
|
const widevineCdmPath = join(app.getPath("userData"), "./WidevineCdm");
|
||||||
|
@ -811,7 +881,7 @@ export class BrowserWindow {
|
||||||
} else if (statSync(join(utils.getPath("themes"), file)).isDirectory()) {
|
} else if (statSync(join(utils.getPath("themes"), file)).isDirectory()) {
|
||||||
let subFiles = readdirSync(join(utils.getPath("themes"), file));
|
let subFiles = readdirSync(join(utils.getPath("themes"), file));
|
||||||
for (let subFile of subFiles) {
|
for (let subFile of subFiles) {
|
||||||
if (subFile.endsWith(".less")) {
|
if (subFile.endsWith("index.less")) {
|
||||||
themes.push(join(file, subFile));
|
themes.push(join(file, subFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -830,6 +900,7 @@ export class BrowserWindow {
|
||||||
themePath = themePath.slice(0, -10);
|
themePath = themePath.slice(0, -10);
|
||||||
}
|
}
|
||||||
if (existsSync(join(themePath, "theme.json"))) {
|
if (existsSync(join(themePath, "theme.json"))) {
|
||||||
|
try {
|
||||||
let themeJson = JSON.parse(readFileSync(join(themePath, "theme.json"), "utf8"));
|
let themeJson = JSON.parse(readFileSync(join(themePath, "theme.json"), "utf8"));
|
||||||
themeObjects.push({
|
themeObjects.push({
|
||||||
name: themeJson.name || themeName,
|
name: themeJson.name || themeName,
|
||||||
|
@ -837,8 +908,12 @@ export class BrowserWindow {
|
||||||
path: themePath,
|
path: themePath,
|
||||||
file: theme,
|
file: theme,
|
||||||
github_repo: themeJson.github_repo || "",
|
github_repo: themeJson.github_repo || "",
|
||||||
commit: themeJson.commit || ""
|
commit: themeJson.commit || "",
|
||||||
|
pack: themeJson.pack || false,
|
||||||
});
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
themeObjects.push({
|
themeObjects.push({
|
||||||
name: themeName,
|
name: themeName,
|
||||||
|
@ -846,7 +921,8 @@ export class BrowserWindow {
|
||||||
path: themePath,
|
path: themePath,
|
||||||
file: theme,
|
file: theme,
|
||||||
github_repo: "",
|
github_repo: "",
|
||||||
commit: ""
|
commit: "",
|
||||||
|
pack: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -897,6 +973,10 @@ export class BrowserWindow {
|
||||||
event.returnValue = process.platform;
|
event.returnValue = process.platform;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on("get-port", (event) => {
|
||||||
|
event.returnValue = this.clientPort;
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on("is-dev", (event) => {
|
ipcMain.on("is-dev", (event) => {
|
||||||
event.returnValue = this.devMode;
|
event.returnValue = this.devMode;
|
||||||
});
|
});
|
||||||
|
@ -965,6 +1045,11 @@ export class BrowserWindow {
|
||||||
BrowserWindow.win.setResizable(!lock);
|
BrowserWindow.win.setResizable(!lock);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Move window
|
||||||
|
ipcMain.on("windowmove", (_event, x, y) => {
|
||||||
|
BrowserWindow.win.setBounds({x, y});
|
||||||
|
});
|
||||||
|
|
||||||
//Fullscreen
|
//Fullscreen
|
||||||
ipcMain.on('setFullScreen', (_event, flag) => {
|
ipcMain.on('setFullScreen', (_event, flag) => {
|
||||||
BrowserWindow.win.setFullScreen(flag)
|
BrowserWindow.win.setFullScreen(flag)
|
||||||
|
@ -1209,16 +1294,27 @@ export class BrowserWindow {
|
||||||
shell.openPath(app.getPath('userData'));
|
shell.openPath(app.getPath('userData'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//#region Cider Connect
|
||||||
ipcMain.on('cc-auth', (_event) => {
|
ipcMain.on('cc-auth', (_event) => {
|
||||||
shell.openExternal(String(utils.getStoreValue('cc_authURL')));
|
shell.openExternal(String(utils.getStoreValue('cc_authURL')));
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('cc-logout', (_event) => {
|
ipcMain.on('cc-logout', (_event) => { //Make sure to update the default store
|
||||||
utils.setStoreValue('connectUser', {
|
utils.setStoreValue('connectUser', {
|
||||||
auth: null
|
"auth": null,
|
||||||
|
"sync": {
|
||||||
|
themes: false,
|
||||||
|
plugins: false,
|
||||||
|
settings: false,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
utils.getWindow().reload();
|
utils.getWindow().reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on('cc-push', (_event) => {
|
||||||
|
utils.pushStoreToConnect();
|
||||||
|
})
|
||||||
/* *********************************************************************************************
|
/* *********************************************************************************************
|
||||||
* Window Events
|
* Window Events
|
||||||
* **********************************************************************************************/
|
* **********************************************************************************************/
|
||||||
|
@ -1262,7 +1358,7 @@ export class BrowserWindow {
|
||||||
BrowserWindow.win.webContents.executeJavaScript(`
|
BrowserWindow.win.webContents.executeJavaScript(`
|
||||||
window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem));
|
window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem));
|
||||||
window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime));
|
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','');`)
|
ipcRenderer.send('stopGCast','');`)
|
||||||
BrowserWindow.win.destroy();
|
BrowserWindow.win.destroy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ export class Plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getPluginFromMap(plugin: string): any {
|
public static getPluginFromMap(plugin: string): any {
|
||||||
if(Plugins.PluginMap[plugin]) {
|
if (Plugins.PluginMap[plugin]) {
|
||||||
return Plugins.PluginMap[plugin];
|
return Plugins.PluginMap[plugin];
|
||||||
}else{
|
} else {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as ElectronStore from 'electron-store';
|
import * as ElectronStore from 'electron-store';
|
||||||
import * as electron from "electron";
|
import * as electron from "electron";
|
||||||
import {app} from "electron";
|
import {app} from "electron";
|
||||||
|
import fetch from "electron-fetch";
|
||||||
export class Store {
|
export class Store {
|
||||||
static cfg: ElectronStore;
|
static cfg: ElectronStore;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export class Store {
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"close_button_hide": false,
|
"close_button_hide": false,
|
||||||
"discord_rpc": {
|
"discordrpc": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"client": "Cider",
|
"client": "Cider",
|
||||||
"clear_on_pause": true,
|
"clear_on_pause": true,
|
||||||
|
@ -52,11 +52,11 @@ export class Store {
|
||||||
"keybindings": {
|
"keybindings": {
|
||||||
"search": [
|
"search": [
|
||||||
process.platform == "darwin" ? "Command" : "Control",
|
process.platform == "darwin" ? "Command" : "Control",
|
||||||
"S"
|
"F"
|
||||||
],
|
],
|
||||||
"albums": [
|
"albums": [
|
||||||
process.platform == "darwin" ? "Command" : "Control",
|
process.platform == "darwin" ? "Command" : "Control",
|
||||||
"F"
|
"S"
|
||||||
],
|
],
|
||||||
"artists": [
|
"artists": [
|
||||||
process.platform == "darwin" ? "Command" : "Control",
|
process.platform == "darwin" ? "Command" : "Control",
|
||||||
|
@ -123,6 +123,8 @@ export class Store {
|
||||||
"quality": "HIGH",
|
"quality": "HIGH",
|
||||||
"seamless_audio": true,
|
"seamless_audio": true,
|
||||||
"normalization": false,
|
"normalization": false,
|
||||||
|
"dBSPL": false,
|
||||||
|
"dBSPLcalibration": 90,
|
||||||
"maikiwiAudio": {
|
"maikiwiAudio": {
|
||||||
"ciderPPE": false,
|
"ciderPPE": false,
|
||||||
"ciderPPE_value": "MAIKIWI",
|
"ciderPPE_value": "MAIKIWI",
|
||||||
|
@ -212,17 +214,22 @@ export class Store {
|
||||||
},
|
},
|
||||||
"connectUser": {
|
"connectUser": {
|
||||||
"auth": null,
|
"auth": null,
|
||||||
|
"sync": {
|
||||||
|
themes: false,
|
||||||
|
plugins: false,
|
||||||
|
settings: false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
private migrations: any = {
|
private migrations: any = {
|
||||||
'>=1.4.3': (store: ElectronStore) => {
|
'>=1.4.3': (store: ElectronStore) => {
|
||||||
if (typeof store.get('general.discord_rpc') == 'number' || typeof store.get('general.discord_rpc') == 'string') {
|
if (typeof store.get('general.discordrpc') == 'number' || typeof store.get('general.discordrpc') == 'string') {
|
||||||
store.delete('general.discord_rpc');
|
store.delete('general.discordrpc');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
private schema: ElectronStore.Schema<any> = {
|
private schema: ElectronStore.Schema<any> = {
|
||||||
"general.discord_rpc": {
|
"general.discordrpc": {
|
||||||
type: 'object'
|
type: 'object'
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -261,6 +268,7 @@ export class Store {
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IPC Handler
|
* IPC Handler
|
||||||
*/
|
*/
|
||||||
|
@ -282,4 +290,42 @@ export class Store {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static pushToCloud(): void {
|
||||||
|
if (Store.cfg.get('connectUser.auth') === null) return;
|
||||||
|
var syncData = Object();
|
||||||
|
if (Store.cfg.get('connectUser.sync.themes')) {
|
||||||
|
syncData.push({
|
||||||
|
themes: Store.cfg.store.themes
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (Store.cfg.get('connectUser.sync.plugins')) {
|
||||||
|
syncData.push({
|
||||||
|
plugins: Store.cfg.store.plugins
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Store.cfg.get('connectUser.sync.settings')) {
|
||||||
|
syncData.push({
|
||||||
|
general: Store.cfg.get('general'),
|
||||||
|
home: Store.cfg.get('home'),
|
||||||
|
libraryPrefs: Store.cfg.get('libraryPrefs'),
|
||||||
|
advanced: Store.cfg.get('advanced'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let postBody = {
|
||||||
|
id: Store.cfg.get('connectUser.id'),
|
||||||
|
app: electron.app.getName(),
|
||||||
|
version: electron.app.isPackaged ? electron.app.getVersion() : 'dev',
|
||||||
|
syncData: syncData
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('https://connect.cidercollective.dev/api/v1/setttings/set', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(postBody)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ export class utils {
|
||||||
return Store.cfg.store
|
return Store.cfg.store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the store instance
|
* Get the store instance
|
||||||
* @returns {Store}
|
* @returns {Store}
|
||||||
|
@ -97,6 +98,18 @@ export class utils {
|
||||||
Store.cfg.set(key, value)
|
Store.cfg.set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes Store to Connect
|
||||||
|
* @return Function
|
||||||
|
*/
|
||||||
|
static pushStoreToConnect(): Function {
|
||||||
|
return Store.pushToCloud
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the browser window
|
* Gets the browser window
|
||||||
*/
|
*/
|
||||||
|
@ -198,4 +211,6 @@ export class utils {
|
||||||
autoUpdater.logger = log
|
autoUpdater.logger = log
|
||||||
await autoUpdater.checkForUpdatesAndNotify()
|
await autoUpdater.checkForUpdatesAndNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default class ChromecastPlugin {
|
||||||
// private GCstream = new Stream.PassThrough(),
|
// private GCstream = new Stream.PassThrough(),
|
||||||
private connectedHosts: any = {};
|
private connectedHosts: any = {};
|
||||||
private connectedPlayer: any;
|
private connectedPlayer: any;
|
||||||
// private port = false;
|
private ciderPort :any = 9000;
|
||||||
// private server = false;
|
// private server = false;
|
||||||
// private bufcount = 0;
|
// private bufcount = 0;
|
||||||
// private bufcount2 = 0;
|
// private bufcount2 = 0;
|
||||||
|
@ -148,7 +148,7 @@ export default class ChromecastPlugin {
|
||||||
}
|
}
|
||||||
let media = {
|
let media = {
|
||||||
// Here you can plug an URL to any mp4, webm, mp3 or jpg file with the proper contentType.
|
// Here you can plug an URL to any mp4, webm, mp3 or jpg file with the proper contentType.
|
||||||
contentId: 'http://' + this.getIp() + ':9000/audio.wav',
|
contentId: 'http://' + this.getIp() + ':'+ this.ciderPort +'/audio.wav',
|
||||||
contentType: 'audio/wav',
|
contentType: 'audio/wav',
|
||||||
streamType: 'LIVE', // or LIVE
|
streamType: 'LIVE', // or LIVE
|
||||||
|
|
||||||
|
@ -361,4 +361,12 @@ export default class ChromecastPlugin {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRendererReady(): void {
|
||||||
|
this._win.webContents.executeJavaScript(
|
||||||
|
`ipcRenderer.sendSync('get-port')`
|
||||||
|
).then((result: any) => {
|
||||||
|
this.ciderPort = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,40 +1,29 @@
|
||||||
import * as RPC from 'discord-rpc'
|
import {AutoClient} from 'discord-auto-rpc'
|
||||||
import {ipcMain} from "electron";
|
import {ipcMain} from "electron";
|
||||||
import fetch from 'electron-fetch'
|
import fetch from 'electron-fetch'
|
||||||
|
|
||||||
export default class DiscordRPC {
|
export default class DiscordRPC {
|
||||||
|
|
||||||
/**
|
|
||||||
* Private variables for interaction in plugins
|
|
||||||
*/
|
|
||||||
private _utils: any;
|
|
||||||
private _app: any;
|
|
||||||
private _attributes: any;
|
|
||||||
private _connection: boolean = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
||||||
*/
|
*/
|
||||||
public name: string = 'Discord Rich Presence';
|
public name: string = 'Discord Rich Presence';
|
||||||
public description: string = 'Discord RPC plugin for Cider';
|
public description: string = 'Discord RPC plugin for Cider';
|
||||||
public version: string = '1.0.0';
|
public version: string = '1.1.0';
|
||||||
public author: string = 'vapormusic/Core (Cider Collective)';
|
public author: string = 'vapormusic/Core (Cider Collective)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private variables for interaction in plugins
|
||||||
|
*/
|
||||||
|
private _utils: any;
|
||||||
|
private _attributes: any;
|
||||||
|
private ready: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin Initialization
|
* Plugin Initialization
|
||||||
*/
|
*/
|
||||||
private _client: any = null;
|
private _client: any = null;
|
||||||
private _activity: RPC.Presence = {
|
private _activityCache: any = {
|
||||||
details: '',
|
|
||||||
state: '',
|
|
||||||
largeImageKey: '',
|
|
||||||
largeImageText: '',
|
|
||||||
smallImageKey: '',
|
|
||||||
smallImageText: '',
|
|
||||||
instance: false
|
|
||||||
};
|
|
||||||
|
|
||||||
private _activityCache: RPC.Presence = {
|
|
||||||
details: '',
|
details: '',
|
||||||
state: '',
|
state: '',
|
||||||
largeImageKey: '',
|
largeImageKey: '',
|
||||||
|
@ -44,6 +33,73 @@ export default class DiscordRPC {
|
||||||
instance: false
|
instance: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************************
|
||||||
|
* Public Methods
|
||||||
|
* ****************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on plugin load (Currently run on application start)
|
||||||
|
*/
|
||||||
|
constructor(utils: any) {
|
||||||
|
this._utils = utils;
|
||||||
|
console.debug(`[Plugin][${this.name}] Loading Complete.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on app ready
|
||||||
|
*/
|
||||||
|
onReady(_win: any): void {
|
||||||
|
const self = this
|
||||||
|
this.connect();
|
||||||
|
console.debug(`[Plugin][${this.name}] Ready.`);
|
||||||
|
ipcMain.on('updateRPCImage', (_event, imageurl) => {
|
||||||
|
if (!this._utils.getStoreValue("general.privateEnabled")) {
|
||||||
|
fetch('https://api.cider.sh/v1/images', {
|
||||||
|
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({url: imageurl}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'User-Agent': _win.webContents.getUserAgent()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(function (json) {
|
||||||
|
self._attributes["artwork"]["url"] = json.url
|
||||||
|
self.setActivity(self._attributes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on app stop
|
||||||
|
*/
|
||||||
|
onBeforeQuit(): void {
|
||||||
|
console.debug(`[Plugin][${this.name}] Stopped.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on playback State Change
|
||||||
|
* @param attributes Music Attributes (attributes.status = current state)
|
||||||
|
*/
|
||||||
|
onPlaybackStateDidChange(attributes: object): void {
|
||||||
|
this._attributes = attributes
|
||||||
|
this.setActivity(attributes)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on song change
|
||||||
|
* @param attributes Music Attributes
|
||||||
|
*/
|
||||||
|
onNowPlayingItemDidChange(attributes: object): void {
|
||||||
|
this._attributes = attributes
|
||||||
|
this.setActivity(attributes)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
* Private Methods
|
* Private Methods
|
||||||
* ****************************************************************************************/
|
* ****************************************************************************************/
|
||||||
|
@ -53,63 +109,91 @@ export default class DiscordRPC {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private connect() {
|
private connect() {
|
||||||
if (!this._utils.getStoreValue("general.discord_rpc.enabled")) {
|
if (!this._utils.getStoreValue("general.discordrpc.enabled")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const clientId = this._utils.getStoreValue("general.discord_rpc.client") === "Cider" ? '911790844204437504' : '886578863147192350';
|
const clientId = this._utils.getStoreValue("general.discordrpc.client") === "Cider" ? '911790844204437504' : '886578863147192350';
|
||||||
|
|
||||||
// Apparently needed for ask to join, join, spectate etc.
|
|
||||||
RPC.register(clientId)
|
|
||||||
|
|
||||||
// Create the client
|
// Create the client
|
||||||
this._client = new RPC.Client({transport: "ipc"});
|
this._client = new AutoClient({transport: "ipc"});
|
||||||
|
|
||||||
// Runs on Ready
|
// Runs on Ready
|
||||||
this._client.on('ready', () => {
|
this._client.once('ready', () => {
|
||||||
console.info(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${this._client.user.id}.`);
|
console.info(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${this._client.user.id}.`);
|
||||||
|
|
||||||
|
if (this._activityCache && this._activityCache.details && this._activityCache.state) {
|
||||||
|
console.info(`[DiscordRPC][connect] Restoring activity cache.`);
|
||||||
|
this._client.setActivity(this._activityCache)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handles Errors
|
|
||||||
this._client.on('error', (err: any) => {
|
|
||||||
console.error(`[DiscordRPC] ${err}`);
|
|
||||||
this.disconnect()
|
|
||||||
});
|
|
||||||
|
|
||||||
// If Discord is closed, allow reconnecting
|
|
||||||
this._client.transport.once('close', () => {
|
|
||||||
console.info(`[DiscordRPC] Connection closed`);
|
|
||||||
this.disconnect()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Login to Discord
|
// Login to Discord
|
||||||
this._client.login({clientId})
|
this._client.endlessLogin({clientId: clientId})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this._connection = true;
|
this.ready = true
|
||||||
})
|
})
|
||||||
.catch((e: any) => console.error(`[DiscordRPC][connect] ${e}`));
|
.catch((e: any) => console.error(`[DiscordRPC][connect] ${e}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects from Discord RPC
|
* Sets the activity
|
||||||
|
* @param attributes Music Attributes
|
||||||
*/
|
*/
|
||||||
private disconnect() {
|
private setActivity(attributes: any) {
|
||||||
if (!this._client) {
|
if (!this._client) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this._client.destroy().then(() => {
|
// Check if show buttons is (true) or (false)
|
||||||
this._connection = false;
|
let activity: Object = {
|
||||||
console.log('[DiscordRPC][disconnect] Disconnected from discord.')
|
details: this._utils.getStoreValue("general.discordrpc.details_format"),
|
||||||
}).catch((e: any) => console.error(`[DiscordRPC][disconnect] ${e}`));
|
state: this._utils.getStoreValue("general.discordrpc.state_format"),
|
||||||
|
largeImageKey: attributes?.artwork?.url?.replace('{w}', '1024').replace('{h}', '1024'),
|
||||||
|
largeImageText: attributes.albumName,
|
||||||
|
instance: false // Whether the activity is in a game session
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up, allow creating a new connection
|
// Filter the activity
|
||||||
this._client = null;
|
activity = this.filterActivity(activity, attributes)
|
||||||
|
|
||||||
|
if (!this.ready) {
|
||||||
|
this._activityCache = activity
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the activity
|
||||||
|
if (!attributes.status && this._utils.getStoreValue("general.discordrpc.clear_on_pause")) {
|
||||||
|
this._client.clearActivity()
|
||||||
|
} else if (activity && this._activityCache !== activity) {
|
||||||
|
this._client.setActivity(activity)
|
||||||
|
}
|
||||||
|
this._activityCache = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter the Discord activity object
|
* Filter the Discord activity object
|
||||||
*/
|
*/
|
||||||
private static filterActivity(activity: any, attributes: any): Object {
|
private filterActivity(activity: any, attributes: any): Object {
|
||||||
|
|
||||||
|
// Add the buttons if people want them
|
||||||
|
if (!this._utils.getStoreValue("general.discordrpc.hide_buttons")) {
|
||||||
|
activity.buttons = [
|
||||||
|
{label: 'Listen on Cider', url: attributes.url.cider},
|
||||||
|
{label: 'View on Apple Music', url: attributes.url.appleMusic}
|
||||||
|
] //To change attributes.url => preload/cider-preload.js
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the timestamp if its playing
|
||||||
|
if (attributes.status) {
|
||||||
|
activity.startTimestamp = Date.now() - (attributes?.durationInMillis - attributes?.remainingTime)
|
||||||
|
activity.endTimestamp = attributes.endTime
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user wants to keep the activity when paused
|
||||||
|
if (!this._utils.getStoreValue("general.discordrpc.clear_on_pause")) {
|
||||||
|
activity.smallImageKey = attributes.status ? 'play' : 'pause';
|
||||||
|
activity.smallImageText = attributes.status ? 'Playing' : 'Paused';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works with:
|
* Works with:
|
||||||
|
@ -173,138 +257,4 @@ export default class DiscordRPC {
|
||||||
}
|
}
|
||||||
return activity
|
return activity
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the activity
|
|
||||||
* @param {activity} activity
|
|
||||||
*/
|
|
||||||
private setActivity(activity: any) {
|
|
||||||
if (!this._connection || !this._client || !activity) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter the activity
|
|
||||||
activity = DiscordRPC.filterActivity(activity, this._attributes)
|
|
||||||
|
|
||||||
// Set the activity
|
|
||||||
if (!this._attributes.status && this._utils.getStoreValue("general.discord_rpc.clear_on_pause")) {
|
|
||||||
this._client.clearActivity()
|
|
||||||
} else if (this._activity && this._activityCache !== this._activity && this._activity.details) {
|
|
||||||
this._client.setActivity(activity)
|
|
||||||
this._activityCache = this._activity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the activity of the client
|
|
||||||
* @param {object} attributes
|
|
||||||
*/
|
|
||||||
private updateActivity(attributes: any) {
|
|
||||||
if (!this._utils.getStoreValue("general.discord_rpc.enabled") || this._utils.getStoreValue("general.privateEnabled")) {
|
|
||||||
return
|
|
||||||
} else if (!this._client || !this._connection) {
|
|
||||||
this.connect()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if show buttons is (true) or (false)
|
|
||||||
this._activity = {
|
|
||||||
details: this._utils.getStoreValue("general.discord_rpc.details_format"),
|
|
||||||
state: this._utils.getStoreValue("general.discord_rpc.state_format"),
|
|
||||||
largeImageKey: attributes?.artwork?.url?.replace('{w}', '1024').replace('{h}', '1024'),
|
|
||||||
largeImageText: attributes.albumName,
|
|
||||||
instance: false // Whether the activity is in a game session
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the buttons if people want them
|
|
||||||
if (!this._utils.getStoreValue("general.discord_rpc.hide_buttons")) {
|
|
||||||
this._activity.buttons = [
|
|
||||||
{label: 'Listen on Cider', url: attributes.url.cider},
|
|
||||||
{label: 'View on Apple Music', url: attributes.url.appleMusic}
|
|
||||||
] //To change attributes.url => preload/cider-preload.js
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the timestamp if its playing
|
|
||||||
if (attributes.status) {
|
|
||||||
this._activity.startTimestamp = Date.now() - (attributes?.durationInMillis - attributes?.remainingTime)
|
|
||||||
this._activity.endTimestamp = attributes.endTime
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user wants to keep the activity when paused
|
|
||||||
if (!this._utils.getStoreValue("general.discord_rpc.clear_on_pause")) {
|
|
||||||
this._activity.smallImageKey = attributes.status ? 'play' : 'pause';
|
|
||||||
this._activity.smallImageText = attributes.status ? 'Playing' : 'Paused';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setActivity(this._activity)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************************
|
|
||||||
* Public Methods
|
|
||||||
* ****************************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on plugin load (Currently run on application start)
|
|
||||||
*/
|
|
||||||
constructor(utils: { getStore: () => any; getApp: () => any; }) {
|
|
||||||
this._utils = utils;
|
|
||||||
console.debug(`[Plugin][${this.name}] Loading Complete.`);
|
|
||||||
this._app = utils.getApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on app ready
|
|
||||||
*/
|
|
||||||
onReady(_win: any): void {
|
|
||||||
let self = this
|
|
||||||
this.connect();
|
|
||||||
console.debug(`[Plugin][${this.name}] Ready.`);
|
|
||||||
ipcMain.on('updateRPCImage', (_event, imageurl) => {
|
|
||||||
if (!this._utils.getStoreValue("general.privateEnabled")) {
|
|
||||||
fetch('https://api.cider.sh/v1/images', {
|
|
||||||
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({url: imageurl}),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'User-Agent': _win.webContents.getUserAgent()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(function (json) {
|
|
||||||
self._attributes["artwork"]["url"] = json.url
|
|
||||||
self.updateActivity(self._attributes)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on app stop
|
|
||||||
*/
|
|
||||||
onBeforeQuit(): void {
|
|
||||||
if (this._client) {
|
|
||||||
this.disconnect()
|
|
||||||
}
|
|
||||||
console.debug(`[Plugin][${this.name}] Stopped.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on playback State Change
|
|
||||||
* @param attributes Music Attributes (attributes.status = current state)
|
|
||||||
*/
|
|
||||||
onPlaybackStateDidChange(attributes: object): void {
|
|
||||||
this._attributes = attributes
|
|
||||||
this.updateActivity(attributes)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on song change
|
|
||||||
* @param attributes Music Attributes
|
|
||||||
*/
|
|
||||||
onNowPlayingItemDidChange(attributes: object): void {
|
|
||||||
this._attributes = attributes
|
|
||||||
this.updateActivity(attributes)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {utils} from "../base/utils";
|
||||||
|
|
||||||
export default class Thumbar {
|
export default class Thumbar {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
||||||
*/
|
*/
|
||||||
|
@ -22,30 +23,36 @@ export default class Thumbar {
|
||||||
label: app.getName(),
|
label: app.getName(),
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'About',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.about'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Settings',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.settings'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.settings").join('+'),
|
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'},
|
{type: 'separator'},
|
||||||
{role: 'services'},
|
{role: 'services'},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{role: 'hide'},
|
{role: 'hide'},
|
||||||
{role: 'hideOthers'},
|
{role: 'hideOthers'},
|
||||||
{role: 'unhide'},
|
{role: 'unhide'},
|
||||||
|
]: [
|
||||||
{type: 'separator'},
|
{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: [
|
submenu: [
|
||||||
{role: 'reload'},
|
{role: 'reload', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.reload')},
|
||||||
{role: 'forceReload'},
|
{role: 'forceReload', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.forcereload')},
|
||||||
|
...(this.isMac ? [
|
||||||
{role: 'toggleDevTools'},
|
{role: 'toggleDevTools'},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{role: 'resetZoom'},
|
{role: 'resetZoom'},
|
||||||
|
@ -53,24 +60,27 @@ export default class Thumbar {
|
||||||
{role: 'zoomOut'},
|
{role: 'zoomOut'},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{role: 'togglefullscreen'},
|
{role: 'togglefullscreen'},
|
||||||
]
|
|
||||||
|
]: []),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Window',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.window'),
|
||||||
submenu: [
|
submenu: [
|
||||||
{role: 'minimize'},
|
{role: 'minimize', label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.minimize')},
|
||||||
|
...(this.isMac ? [
|
||||||
{
|
{
|
||||||
label: 'Show',
|
label: 'Show',
|
||||||
click: () => utils.getWindow().show()
|
click: () => utils.getWindow().show()
|
||||||
},
|
},
|
||||||
{role: 'zoom'},
|
{role: 'zoom'},
|
||||||
...(this.isMac ? [
|
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{role: 'front'},
|
{role: 'front'},
|
||||||
{role: 'close'},
|
{role: 'close'},
|
||||||
] : [
|
|
||||||
{role: 'close'},
|
{role: 'close'},
|
||||||
]),
|
|
||||||
|
|
||||||
{
|
{
|
||||||
label: 'Edit',
|
label: 'Edit',
|
||||||
|
@ -83,146 +93,148 @@ export default class Thumbar {
|
||||||
{role: 'paste'},
|
{role: 'paste'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
] : []
|
||||||
|
),
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Toggle Private Session',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.toggleprivate'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join('+'),
|
accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Web Remote',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.webremote'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.webRemote").join('+'),
|
accelerator: utils.getStoreValue("general.keybindings.webRemote").join('+'),
|
||||||
sublabel: 'Opens in external window',
|
sublabel: 'Opens in external window',
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('remote-pair')`)
|
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('+'),
|
accelerator: utils.getStoreValue("general.keybindings.audioSettings").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.audioSettings = true`)
|
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('+'),
|
accelerator: utils.getStoreValue("general.keybindings.pluginMenu").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Controls',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.controls'),
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Pause / Play',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.playpause'),
|
||||||
accelerator: 'Space',
|
accelerator: 'Space',
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Next',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.next'),
|
||||||
accelerator: 'CommandOrControl+Right',
|
accelerator: 'CommandOrControl+Right',
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Previous',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.previous'),
|
||||||
accelerator: 'CommandOrControl+Left',
|
accelerator: 'CommandOrControl+Left',
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Volume Up',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.volumeup'),
|
||||||
accelerator: 'CommandOrControl+Up',
|
accelerator: 'CommandOrControl+Up',
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Volume Down',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.volumedown'),
|
||||||
accelerator: 'CommandOrControl+Down',
|
accelerator: 'CommandOrControl+Down',
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeDown()`)
|
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('+'),
|
accelerator: utils.getStoreValue("general.keybindings.browse").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Artists',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.artists'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.artists").join('+'),
|
accelerator: utils.getStoreValue("general.keybindings.artists").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-artists')`)
|
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('+'),
|
accelerator: utils.getStoreValue("general.keybindings.search").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('search')`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('search')`)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Album',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.albums'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.albums").join('+'),
|
accelerator: utils.getStoreValue("general.keybindings.albums").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Cast To Devices',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.cast'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.castToDevices").join('+'),
|
accelerator: utils.getStoreValue("general.keybindings.castToDevices").join('+'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Account',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.account'),
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Account Settings',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.accountsettings'),
|
||||||
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('apple-account-settings')`)
|
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()`)
|
click: () => utils.getWindow().webContents.executeJavaScript(`app.unauthorize()`)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Support',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.support'),
|
||||||
role: 'help',
|
role: 'help',
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Discord',
|
label: utils.getLocale('Discord', 'menubar.options.discord'),
|
||||||
click: () => shell.openExternal("https://discord.gg/AppleMusic").catch(console.error)
|
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)
|
click: () => shell.openExternal("https://github.com/ciderapp/Cider/wiki/Troubleshooting").catch(console.error)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Report a...',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.report'),
|
||||||
submenu: [
|
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)
|
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)
|
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)
|
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'},
|
{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)
|
click: () => shell.openExternal("https://github.com/ciderapp/Cider/blob/main/LICENSE").catch(console.error)
|
||||||
},
|
},
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
{
|
{
|
||||||
label: 'Toggle Developer Tools',
|
label: utils.getLocale(utils.getStoreValue('general.language'), 'menubar.options.toggledevtools'),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join('+'),
|
accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join('+'),
|
||||||
click: () => utils.getWindow().webContents.openDevTools()
|
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()
|
click: () => utils.getStoreInstance().openInEditor()
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -89,9 +89,9 @@ export default class RAOP {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
private ondeviceup(name: any, host: any, port: any, addresses: any, text: any) {
|
private ondeviceup(name: any, host: any, port: any, addresses: any, text: any) {
|
||||||
if (this.castDevices.findIndex((item: any) => item.name === host && item.port === port && item.addresses === addresses) === -1) {
|
if (this.castDevices.findIndex((item: any) => item.name == host.replace(".local","") && item.port == port && item.addresses == addresses) === -1) {
|
||||||
this.castDevices.push({
|
this.castDevices.push({
|
||||||
name: host,
|
name: host.replace(".local",""),
|
||||||
host: addresses ? addresses[0] : '',
|
host: addresses ? addresses[0] : '',
|
||||||
port: port,
|
port: port,
|
||||||
addresses: addresses,
|
addresses: addresses,
|
||||||
|
@ -152,9 +152,23 @@ export default class RAOP {
|
||||||
this._win.webContents.executeJavaScript(`console.log(
|
this._win.webContents.executeJavaScript(`console.log(
|
||||||
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
||||||
)`);
|
)`);
|
||||||
this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt);}
|
this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// const browser2 = this.mdns.createBrowser(this.mdns.tcp('airplay'));
|
||||||
|
// browser2.on('ready', browser2.discover);
|
||||||
|
|
||||||
|
// browser2.on('update', (service: any) => {
|
||||||
|
// if (service.addresses && service.fullname && (service.fullname.includes('_raop._tcp') || service.fullname.includes('_airplay._tcp'))) {
|
||||||
|
// // console.log(service.txt)
|
||||||
|
// this._win.webContents.executeJavaScript(`console.log(
|
||||||
|
// "${service.name} ${service.host}:${service.port} ${service.addresses}"
|
||||||
|
// )`);
|
||||||
|
// this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,7 +181,7 @@ export default class RAOP {
|
||||||
this.portairplay = ipport;
|
this.portairplay = ipport;
|
||||||
this.device = this.airtunes.add(ipv4, {
|
this.device = this.airtunes.add(ipv4, {
|
||||||
port: ipport,
|
port: ipport,
|
||||||
volume: 60,
|
volume: 50,
|
||||||
password: sepassword,
|
password: sepassword,
|
||||||
txt: txt
|
txt: txt
|
||||||
});
|
});
|
||||||
|
@ -178,6 +192,15 @@ export default class RAOP {
|
||||||
this._win.webContents.setAudioMuted(true);
|
this._win.webContents.setAudioMuted(true);
|
||||||
this._win.webContents.executeJavaScript(`CiderAudio.sendAudio()`).catch((err: any) => console.error(err));
|
this._win.webContents.executeJavaScript(`CiderAudio.sendAudio()`).catch((err: any) => console.error(err));
|
||||||
}
|
}
|
||||||
|
if (status == "need_password"){
|
||||||
|
this._win.webContents.executeJavaScript(`app.setAirPlayCodeUI()`)
|
||||||
|
}
|
||||||
|
if (status == "pair_success"){
|
||||||
|
this._win.webContents.executeJavaScript(`app.sendAirPlaySuccess()`)
|
||||||
|
}
|
||||||
|
if (status == "pair_failed"){
|
||||||
|
this._win.webContents.executeJavaScript(`app.sendAirPlayFailed()`)
|
||||||
|
}
|
||||||
if (status == 'stopped') {
|
if (status == 'stopped') {
|
||||||
this.airtunes.stopAll(() => {
|
this.airtunes.stopAll(() => {
|
||||||
console.log('end');
|
console.log('end');
|
||||||
|
@ -210,6 +233,12 @@ export default class RAOP {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
electron.ipcMain.on('setAirPlayPasscode', (event, passcode) => {
|
||||||
|
if (this.device){
|
||||||
|
this.device.setPasscode(passcode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
electron.ipcMain.on('writeWAV', (event, leftbuffer, rightbuffer) => {
|
electron.ipcMain.on('writeWAV', (event, leftbuffer, rightbuffer) => {
|
||||||
if (this.airtunes != null) {
|
if (this.airtunes != null) {
|
||||||
if (this.worker == null) {
|
if (this.worker == null) {
|
||||||
|
|
1
src/renderer/assets/feather/heart-fill.svg
Normal file
1
src/renderer/assets/feather/heart-fill.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
|
After Width: | Height: | Size: 373 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
|
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 364 B |
|
@ -105,7 +105,7 @@ function fallbackinitMusicKit() {
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.init()
|
app.init()
|
||||||
if(app.cfg.visual.window_background_style == "mica" && !app.isDev) {
|
if (app.cfg.visual.window_background_style == "mica" && !app.isDev) {
|
||||||
app.spawnMica()
|
app.spawnMica()
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
@ -134,7 +134,7 @@ document.addEventListener('musickitloaded', function () {
|
||||||
function waitForApp() {
|
function waitForApp() {
|
||||||
if (typeof app.init !== "undefined") {
|
if (typeof app.init !== "undefined") {
|
||||||
app.init()
|
app.init()
|
||||||
if(app.cfg.visual.window_background_style == "mica" && !app.isDev) {
|
if (app.cfg.visual.window_background_style == "mica" && !app.isDev) {
|
||||||
app.spawnMica()
|
app.spawnMica()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,6 +364,21 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: 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 {
|
.cd-mediaitem-list-item .explicit-icon {
|
||||||
background-image: url("assets/explicit.svg");
|
background-image: url("assets/explicit.svg");
|
||||||
height: 12px;
|
height: 12px;
|
||||||
|
@ -371,6 +386,9 @@
|
||||||
filter: contrast(0);
|
filter: contrast(0);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
.heart-icon {
|
||||||
|
display: flex
|
||||||
|
}
|
||||||
@keyframes load-bar {
|
@keyframes load-bar {
|
||||||
10% {
|
10% {
|
||||||
box-shadow: inset 0 -4px 0;
|
box-shadow: inset 0 -4px 0;
|
||||||
|
|
|
@ -359,7 +359,11 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: var(--mediaItemRadius);
|
border-radius: var(--mediaItemRadius);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
&:hover{
|
||||||
|
.heart-icon{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
.popular {
|
.popular {
|
||||||
background-image: url(assets/star.svg);
|
background-image: url(assets/star.svg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -448,6 +452,22 @@
|
||||||
justify-content: center;
|
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 {
|
.explicit-icon {
|
||||||
background-image: url("./assets/explicit.svg");
|
background-image: url("./assets/explicit.svg");
|
||||||
height: 12px;
|
height: 12px;
|
||||||
|
@ -456,6 +476,12 @@
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.heart-icon {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
/* CSS.gg
|
/* CSS.gg
|
||||||
*/
|
*/
|
||||||
@keyframes load-bar {
|
@keyframes load-bar {
|
||||||
|
|
|
@ -70,10 +70,11 @@
|
||||||
|
|
||||||
.spatialproperties-panel {
|
.spatialproperties-panel {
|
||||||
.modal-window {
|
.modal-window {
|
||||||
|
&:not(.airplay-modal){
|
||||||
height : 700px;
|
height : 700px;
|
||||||
max-height: 700px;
|
max-height: 700px;
|
||||||
width : 800px;
|
width : 800px;
|
||||||
max-width : 800px;
|
max-width : 800px;}
|
||||||
overflow : hidden;
|
overflow : hidden;
|
||||||
|
|
||||||
.info-header {
|
.info-header {
|
||||||
|
@ -352,7 +353,7 @@
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
&::before {
|
&::before {
|
||||||
transition: transform .1s ease-in, opacity .1s ease-in;
|
transition: transform 0s ease-in, opacity 0s ease-in;
|
||||||
opacity : 1;
|
opacity : 1;
|
||||||
transform : scale(1);
|
transform : scale(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,58 +493,74 @@
|
||||||
//background: linear-gradient(180deg, var(--bgColor) 32px, var(--bgColor) 18px, transparent 60px, transparent 100%);
|
//background: linear-gradient(180deg, var(--bgColor) 32px, var(--bgColor) 18px, transparent 60px, transparent 100%);
|
||||||
top : 0;
|
top : 0;
|
||||||
padding-top : var(--navigationBarHeight);
|
padding-top : var(--navigationBarHeight);
|
||||||
display:flex;
|
display : flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height : 100%;
|
||||||
overflow: hidden;
|
overflow : hidden;
|
||||||
|
|
||||||
|
.cd-mediaitem-list-item {
|
||||||
|
&:hover {
|
||||||
|
.heart-icon {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart-icon {
|
||||||
|
left: -25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.editTracksBtn {
|
.editTracksBtn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top : 20px;
|
||||||
right: 20px;
|
right : 20px;
|
||||||
z-index: 1;
|
z-index : 1;
|
||||||
|
|
||||||
>span {
|
>span {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap : 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mediaContainer {
|
.mediaContainer {
|
||||||
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
|
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
|
||||||
width: 260px;height:260px;
|
width : 260px;
|
||||||
|
height : 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-body {
|
.playlist-body {
|
||||||
padding : 32px;
|
padding : 32px;
|
||||||
// margin-top: -75px;
|
// margin-top: -75px;
|
||||||
overflow-y:overlay;
|
overflow-y : overlay;
|
||||||
height:100%;
|
height : 100%;
|
||||||
padding:0px;
|
padding : 0px;
|
||||||
background-color: var(--color1);
|
background-color: var(--color1);
|
||||||
|
|
||||||
&.scrollbody {
|
&.scrollbody {
|
||||||
.tabs {
|
.tabs {
|
||||||
display: flex;
|
display : flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
height: 100%;
|
height : 100%;
|
||||||
|
|
||||||
.nav-link {
|
.nav-link {
|
||||||
text-transform:capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
height: 100%;
|
height : 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin:0px;
|
margin : 0px;
|
||||||
|
|
||||||
.tab-pane {
|
.tab-pane {
|
||||||
height: 100%;
|
height : 100%;
|
||||||
overflow-y: overlay;
|
overflow-y : overlay;
|
||||||
overflow-x:hidden;
|
overflow-x : hidden;
|
||||||
padding: var(--contentInnerPadding);
|
padding : var(--contentInnerPadding);
|
||||||
|
padding-inline : 40px;
|
||||||
-webkit-mask-image: linear-gradient(180deg, transparent, white 20px);
|
-webkit-mask-image: linear-gradient(180deg, transparent, white 20px);
|
||||||
|
|
||||||
.well {
|
.well {
|
||||||
margin:0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,7 +579,7 @@
|
||||||
background : rgba(0, 0, 0, 0.25);
|
background : rgba(0, 0, 0, 0.25);
|
||||||
top : var(--navigationBarHeight);
|
top : var(--navigationBarHeight);
|
||||||
transition : opacity 0.1s var(--appleEase);
|
transition : opacity 0.1s var(--appleEase);
|
||||||
display: none;
|
display : none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-display {
|
.playlist-display {
|
||||||
|
@ -649,7 +665,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-desc {
|
.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;
|
box-sizing : border-box;
|
||||||
font-size : 14px;
|
font-size : 14px;
|
||||||
flex-shrink : unset;
|
flex-shrink : unset;
|
||||||
|
@ -750,11 +766,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-time {
|
.playlist-time {
|
||||||
font-size: 0.9em;
|
font-size : 0.9em;
|
||||||
margin : 6px;
|
margin : 6px;
|
||||||
opacity : 0.7;
|
opacity : 0.7;
|
||||||
transition: height .2s ease-in-out, opacity .2s ease-in-out;
|
transition: height .2s ease-in-out, opacity .2s ease-in-out;
|
||||||
height: 0.9em;
|
height : 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.inline-playlist {
|
&.inline-playlist {
|
||||||
|
@ -802,8 +818,8 @@
|
||||||
|
|
||||||
.pilldim {
|
.pilldim {
|
||||||
.nav-pills {
|
.nav-pills {
|
||||||
width: max-content;
|
width : max-content;
|
||||||
margin: 0 auto;
|
margin : 0 auto;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,26 +829,24 @@
|
||||||
transition: min-height 0.5s ease-in-out;
|
transition: min-height 0.5s ease-in-out;
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
|
|
||||||
.playlistInfo {
|
.playlistInfo {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.mediaContainer {
|
.mediaContainer {
|
||||||
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
|
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
|
||||||
width: 128px!important;
|
width : 128px !important;
|
||||||
height: 128px!important;
|
height : 128px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-time {
|
.playlist-time {
|
||||||
transition: height .2s ease-in-out, opacity .2s ease-in-out;
|
transition: height .2s ease-in-out, opacity .2s ease-in-out;
|
||||||
height: 0px;
|
height : 0px;
|
||||||
opacity: 0;
|
opacity : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-desc {
|
.playlist-desc {
|
||||||
transition: height .2s ease-in-out, opacity .2s ease-in-out;
|
transition: height .2s ease-in-out, opacity .2s ease-in-out;
|
||||||
height: 0px!important;
|
height : 0px !important;
|
||||||
opacity: 0;
|
opacity : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1112,9 +1126,56 @@
|
||||||
|
|
||||||
/* Artist Page End */
|
/* Artist Page End */
|
||||||
|
|
||||||
// Settings page
|
|
||||||
.settings-page {
|
.installed-themes-page {
|
||||||
padding: 0px;
|
|
||||||
|
.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 {
|
.stylestack-editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1125,17 +1186,34 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.themeLabel {
|
.themeLabel {
|
||||||
display:flex;
|
display : flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.handle {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item {
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.removeItem {
|
.removeItem {
|
||||||
border: 0px;
|
border : 0px;
|
||||||
background: transparent;
|
background : transparent;
|
||||||
height: 32px;
|
height : 32px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--textColor);
|
color : var(--textColor);
|
||||||
cursor: pointer;
|
cursor : pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stylesDropdown {
|
.stylesDropdown {
|
||||||
|
@ -1145,7 +1223,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings page
|
||||||
|
.settings-page {
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
width : 90%;
|
width : 90%;
|
||||||
|
@ -1163,8 +1245,9 @@
|
||||||
|
|
||||||
.settings-option-body-webview {
|
.settings-option-body-webview {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width : 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-option-body {
|
.settings-option-body {
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ const Events = {
|
||||||
if (event.keyCode === 82 && event.ctrlKey) {
|
if (event.keyCode === 82 && event.ctrlKey) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
bootbox.confirm("Reload Cider?", (res)=>{
|
bootbox.confirm("Reload Cider?", (res)=>{
|
||||||
if(res) {
|
if (res) {
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -251,9 +251,9 @@ function simulateGamepad () {
|
||||||
|
|
||||||
cursorPos[1] -= cursorSpeed
|
cursorPos[1] -= cursorSpeed
|
||||||
// sounds.Hover.play()
|
// sounds.Hover.play()
|
||||||
// if(intTabIndex <= 0) {
|
// if (intTabIndex <= 0) {
|
||||||
// intTabIndex = 0
|
// intTabIndex = 0
|
||||||
// }else{
|
// } else {
|
||||||
// intTabIndex--
|
// intTabIndex--
|
||||||
// }
|
// }
|
||||||
// $(tabbable[intTabIndex]).focus()
|
// $(tabbable[intTabIndex]).focus()
|
||||||
|
@ -263,9 +263,9 @@ function simulateGamepad () {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
cursorPos[1] += cursorSpeed
|
cursorPos[1] += cursorSpeed
|
||||||
// if(intTabIndex < tabbable.length) {
|
// if (intTabIndex < tabbable.length) {
|
||||||
// intTabIndex++
|
// intTabIndex++
|
||||||
// }else{
|
// } else {
|
||||||
// intTabIndex = tabbable.length
|
// intTabIndex = tabbable.length
|
||||||
// }
|
// }
|
||||||
// $(tabbable[intTabIndex]).focus()
|
// $(tabbable[intTabIndex]).focus()
|
||||||
|
|
|
@ -148,6 +148,10 @@ const app = new Vue({
|
||||||
},
|
},
|
||||||
tmpHeight: '',
|
tmpHeight: '',
|
||||||
tmpWidth: '',
|
tmpWidth: '',
|
||||||
|
tmpX: '',
|
||||||
|
tmpY: '',
|
||||||
|
miniTmpX: '',
|
||||||
|
miniTmpY: '',
|
||||||
tmpVar: [],
|
tmpVar: [],
|
||||||
notification: false,
|
notification: false,
|
||||||
chrome: {
|
chrome: {
|
||||||
|
@ -207,6 +211,7 @@ const app = new Vue({
|
||||||
showPlaylist: false,
|
showPlaylist: false,
|
||||||
castMenu: false,
|
castMenu: false,
|
||||||
moreInfo: false,
|
moreInfo: false,
|
||||||
|
airplayPW: false,
|
||||||
},
|
},
|
||||||
socialBadges: {
|
socialBadges: {
|
||||||
badgeMap: {},
|
badgeMap: {},
|
||||||
|
@ -230,6 +235,7 @@ const app = new Vue({
|
||||||
pages: [],
|
pages: [],
|
||||||
},
|
},
|
||||||
moreinfodata: [],
|
moreinfodata: [],
|
||||||
|
notyf: notyf
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
cfg: {
|
cfg: {
|
||||||
|
@ -283,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) {
|
mainMenuVisibility(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
(this.mk.isAuthorized) ? this.chrome.menuOpened = !this.chrome.menuOpened : false;
|
(this.mk.isAuthorized) ? this.chrome.menuOpened = !this.chrome.menuOpened : false;
|
||||||
|
@ -592,9 +601,7 @@ const app = new Vue({
|
||||||
},
|
},
|
||||||
async init() {
|
async init() {
|
||||||
let self = this
|
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) {
|
if (this.cfg.visual.styles.length != 0) {
|
||||||
await this.reloadStyles()
|
await this.reloadStyles()
|
||||||
}
|
}
|
||||||
|
@ -702,6 +709,7 @@ const app = new Vue({
|
||||||
let lastItem = window.localStorage.getItem("currentTrack")
|
let lastItem = window.localStorage.getItem("currentTrack")
|
||||||
let time = window.localStorage.getItem("currentTime")
|
let time = window.localStorage.getItem("currentTime")
|
||||||
let queue = window.localStorage.getItem("currentQueue")
|
let queue = window.localStorage.getItem("currentQueue")
|
||||||
|
app.mk.queue.position = 0; // Reset queue position.
|
||||||
if (lastItem != null) {
|
if (lastItem != null) {
|
||||||
lastItem = JSON.parse(lastItem)
|
lastItem = JSON.parse(lastItem)
|
||||||
let kind = lastItem.attributes.playParams.kind;
|
let kind = lastItem.attributes.playParams.kind;
|
||||||
|
@ -721,7 +729,7 @@ const app = new Vue({
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
queue = JSON.parse(queue)
|
queue = JSON.parse(queue)
|
||||||
if (queue && queue.length > 0) {
|
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;
|
let i = 0;
|
||||||
if (ids.length > 0) {
|
if (ids.length > 0) {
|
||||||
for (let id of ids) {
|
for (let id of ids) {
|
||||||
|
@ -832,6 +840,14 @@ const app = new Vue({
|
||||||
ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes());
|
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) => {
|
this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => {
|
||||||
if (self.$refs.queue) {
|
if (self.$refs.queue) {
|
||||||
self.$refs.queue.updateQueue();
|
self.$refs.queue.updateQueue();
|
||||||
|
@ -1118,11 +1134,13 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async refreshPlaylists(localOnly = false) {
|
async refreshPlaylists(localOnly = false, useCachedPlaylists = true) {
|
||||||
let self = this
|
let self = this
|
||||||
let trackMap = this.cfg.advanced.playlistTrackMapping
|
let trackMap = this.cfg.advanced.playlistTrackMapping
|
||||||
let newListing = []
|
let newListing = []
|
||||||
let trackMapping = {}
|
let trackMapping = {}
|
||||||
|
|
||||||
|
if (useCachedPlaylists) {
|
||||||
const cachedPlaylist = await CiderCache.getCache("library-playlists")
|
const cachedPlaylist = await CiderCache.getCache("library-playlists")
|
||||||
const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks")
|
const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks")
|
||||||
|
|
||||||
|
@ -1141,14 +1159,17 @@ const app = new Vue({
|
||||||
if (localOnly) {
|
if (localOnly) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.library.backgroundNotification.message = "Building playlist cache..."
|
this.library.backgroundNotification.message = "Building playlist cache..."
|
||||||
this.library.backgroundNotification.show = true
|
this.library.backgroundNotification.show = true
|
||||||
|
|
||||||
async function deepScan(parent = "p.playlistsroot") {
|
async function deepScan(parent = "p.playlistsroot") {
|
||||||
console.debug(`scanning ${parent}`)
|
console.debug(`scanning ${parent}`)
|
||||||
const playlistData = await app.mk.api.v3.music(`/v1/me/library/playlist-folders/${parent}/children/`)
|
// 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 MusicKitTools.v3Continuous({href: `/v1/me/library/playlist-folders/${parent}/children/`})
|
||||||
|
console.log(playlistData)
|
||||||
|
await asyncForEach(playlistData, async (playlist) => {
|
||||||
playlist.parent = parent
|
playlist.parent = parent
|
||||||
if (
|
if (
|
||||||
playlist.type != "library-playlist-folders" &&
|
playlist.type != "library-playlist-folders" &&
|
||||||
|
@ -1242,7 +1263,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).then(res => {
|
).then(res => {
|
||||||
self.refreshPlaylists()
|
self.refreshPlaylists(false, false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async editPlaylist(id, name = app.getLz('term.newPlaylist')) {
|
async editPlaylist(id, name = app.getLz('term.newPlaylist')) {
|
||||||
|
@ -1257,7 +1278,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).then(res => {
|
).then(res => {
|
||||||
self.refreshPlaylists()
|
self.refreshPlaylists(false, false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
copyToClipboard(str) {
|
copyToClipboard(str) {
|
||||||
|
@ -1301,7 +1322,7 @@ const app = new Vue({
|
||||||
})
|
})
|
||||||
self.sortPlaylists()
|
self.sortPlaylists()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.refreshPlaylists()
|
app.refreshPlaylists(false, false)
|
||||||
}, 8000)
|
}, 8000)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -1318,6 +1339,9 @@ const app = new Vue({
|
||||||
if (found) {
|
if (found) {
|
||||||
self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1)
|
self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1)
|
||||||
}
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
app.refreshPlaylists(false, false);
|
||||||
|
}, 8000);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1671,11 +1695,11 @@ const app = new Vue({
|
||||||
params["meta[albums:tracks]"] = 'popularity'
|
params["meta[albums:tracks]"] = 'popularity'
|
||||||
params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright"
|
params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright"
|
||||||
}
|
}
|
||||||
if(kind.includes("playlist") || kind.includes("album")){
|
if (kind.includes("playlist") || kind.includes("album")){
|
||||||
app.page = (kind) + "_" + (id);
|
app.page = (kind) + "_" + (id);
|
||||||
window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}`
|
window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}`
|
||||||
app.getTypeFromID((kind), (id), (isLibrary), params);
|
app.getTypeFromID((kind), (id), (isLibrary), params);
|
||||||
}else{
|
} else {
|
||||||
app.page = (kind)
|
app.page = (kind)
|
||||||
window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}`
|
window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}`
|
||||||
}
|
}
|
||||||
|
@ -2563,7 +2587,7 @@ const app = new Vue({
|
||||||
})
|
})
|
||||||
self.sortPlaylists()
|
self.sortPlaylists()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.refreshPlaylists()
|
app.refreshPlaylists(false, false)
|
||||||
}, 13000)
|
}, 13000)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -3830,6 +3854,15 @@ const app = new Vue({
|
||||||
|
|
||||||
// tracks are found in relationship.data
|
// tracks are found in relationship.data
|
||||||
},
|
},
|
||||||
|
setAirPlayCodeUI() {
|
||||||
|
this.modals.airplayPW = true
|
||||||
|
},
|
||||||
|
sendAirPlaySuccess(){
|
||||||
|
notyf.success('Device paired successfully!');
|
||||||
|
},
|
||||||
|
sendAirPlayFailed(){
|
||||||
|
notyf.error('Device paring failed!');
|
||||||
|
},
|
||||||
windowFocus(val) {
|
windowFocus(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
document.querySelectorAll(".animated-artwork-video").forEach(el => {
|
document.querySelectorAll(".animated-artwork-video").forEach(el => {
|
||||||
|
@ -4009,7 +4042,8 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app.mk.nowPlayingItem._container["attributes"] && app.mk.nowPlayingItem._container.name != "station") {
|
const nowPlayingContainer = app.mk.nowPlayingItem._container;
|
||||||
|
if (nowPlayingContainer && nowPlayingContainer["attributes"] && nowPlayingContainer.name != "station") {
|
||||||
menus.normal.items.find(x => x.id == "showInMusic").hidden = false
|
menus.normal.items.find(x => x.id == "showInMusic").hidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4096,13 +4130,19 @@ const app = new Vue({
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.tmpWidth = window.innerWidth;
|
this.tmpWidth = window.innerWidth;
|
||||||
this.tmpHeight = window.innerHeight;
|
this.tmpHeight = window.innerHeight;
|
||||||
|
this.tmpX = window.screenX;
|
||||||
|
this.tmpY = window.screenY;
|
||||||
ipcRenderer.send('unmaximize');
|
ipcRenderer.send('unmaximize');
|
||||||
ipcRenderer.send('windowmin', 250, 250)
|
ipcRenderer.send('windowmin', 250, 250)
|
||||||
|
if (this.miniTmpX !== '' && this.miniTmpY !== '') ipcRenderer.send('windowmove', this.miniTmpX, this.miniTmpY)
|
||||||
ipcRenderer.send('windowresize', 300, 300, false)
|
ipcRenderer.send('windowresize', 300, 300, false)
|
||||||
app.appMode = 'mini';
|
app.appMode = 'mini';
|
||||||
} else {
|
} else {
|
||||||
|
this.miniTmpX = window.screenX;
|
||||||
|
this.miniTmpY = window.screenY;
|
||||||
ipcRenderer.send('windowmin', 844, 410)
|
ipcRenderer.send('windowmin', 844, 410)
|
||||||
ipcRenderer.send('windowresize', this.tmpWidth, this.tmpHeight, false)
|
ipcRenderer.send('windowresize', this.tmpWidth, this.tmpHeight, false)
|
||||||
|
ipcRenderer.send('windowmove', this.tmpX, this.tmpY)
|
||||||
ipcRenderer.send('windowontop', false)
|
ipcRenderer.send('windowontop', false)
|
||||||
//this.cfg.visual.miniplayer_top_toggle = true;
|
//this.cfg.visual.miniplayer_top_toggle = true;
|
||||||
app.appMode = 'player';
|
app.appMode = 'player';
|
||||||
|
|
|
@ -108,11 +108,11 @@ const wsapi = {
|
||||||
app.mk.isPlaying ? app.mk.pause() : app.mk.play()
|
app.mk.isPlaying ? app.mk.pause() : app.mk.play()
|
||||||
},
|
},
|
||||||
toggleRepeat() {
|
toggleRepeat() {
|
||||||
if(MusicKit.getInstance().repeatMode == 0) {
|
if (MusicKit.getInstance().repeatMode == 0) {
|
||||||
MusicKit.getInstance().repeatMode = 1
|
MusicKit.getInstance().repeatMode = 1
|
||||||
}else if(MusicKit.getInstance().repeatMode == 1){
|
} else if (MusicKit.getInstance().repeatMode == 1){
|
||||||
MusicKit.getInstance().repeatMode = 2
|
MusicKit.getInstance().repeatMode = 2
|
||||||
}else{
|
} else {
|
||||||
MusicKit.getInstance().repeatMode = 0
|
MusicKit.getInstance().repeatMode = 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -7936,6 +7936,15 @@ fieldset:disabled .btn {
|
||||||
filter: contrast(0);
|
filter: contrast(0);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
.cd-mediaitem-list-item .playIcon{
|
||||||
|
width: 44px;
|
||||||
|
margin-left: 11px;
|
||||||
|
}
|
||||||
|
.cd-mediaitem-list-item .heart-icon {
|
||||||
|
position: absolute;
|
||||||
|
filter: contrast(0);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
@keyframes load-bar {
|
@keyframes load-bar {
|
||||||
10% {
|
10% {
|
||||||
box-shadow: inset 0 -4px 0;
|
box-shadow: inset 0 -4px 0;
|
||||||
|
@ -12935,6 +12944,7 @@ body[platform='darwin'] #window-controls-container {
|
||||||
}
|
}
|
||||||
body[platform='darwin'] .app-chrome .app-chrome-item > .app-mainmenu {
|
body[platform='darwin'] .app-chrome .app-chrome-item > .app-mainmenu {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
width: 52px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1207,6 +1207,14 @@ body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.cl
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.heart-icon {
|
||||||
|
height: 9px;
|
||||||
|
width: 13px;
|
||||||
|
filter: contrast(0);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
margin-left: 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.lossless-icon {
|
.lossless-icon {
|
||||||
|
@ -3281,6 +3289,7 @@ body[platform='darwin'] {
|
||||||
|
|
||||||
.app-chrome .app-chrome-item > .app-mainmenu {
|
.app-chrome .app-chrome-item > .app-mainmenu {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
width: 52px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,11 +133,11 @@ app.mkapi("artists", false, "412778295", {
|
||||||
var library = []
|
var library = []
|
||||||
var downloaded = null;
|
var downloaded = null;
|
||||||
function downloadChunk () {
|
function downloadChunk () {
|
||||||
if(downloaded == null) {
|
if (downloaded == null) {
|
||||||
app.mk.api.library.songs("", {limit: 100}, {includeResponseMeta: !0}).then((response)=>{
|
app.mk.api.library.songs("", {limit: 100}, {includeResponseMeta: !0}).then((response)=>{
|
||||||
processChunk(response)
|
processChunk(response)
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
downloaded.next("", {limit: 100}, {includeResponseMeta: !0}).then((response)=>{
|
downloaded.next("", {limit: 100}, {includeResponseMeta: !0}).then((response)=>{
|
||||||
processChunk(response)
|
processChunk(response)
|
||||||
})
|
})
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
:class="{'active': this.cfg.audio.volume == 0}"></button>
|
:class="{'active': this.cfg.audio.volume == 0}"></button>
|
||||||
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
|
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
|
||||||
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
|
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
|
||||||
v-b-tooltip.hover :title="`${(Math.log10(mk.volume) * 20).toFixed(2)} dB`">
|
v-b-tooltip.hover :title="formatVolumeTooltip()">
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item generic">
|
<div class="app-chrome-item generic">
|
||||||
<button class="playback-button--small miniplayer"
|
<button class="playback-button--small miniplayer"
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
:class="{'active': this.cfg.audio.volume == 0}"></button>
|
:class="{'active': this.cfg.audio.volume == 0}"></button>
|
||||||
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
|
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
|
||||||
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
|
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
|
||||||
v-b-tooltip.hover :title="`${(Math.log10(mk.volume) * 20).toFixed(2)} dB`">
|
v-b-tooltip.hover :title="formatVolumeTooltip()">
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item generic">
|
<div class="app-chrome-item generic">
|
||||||
<button class="playback-button--small miniplayer"
|
<button class="playback-button--small miniplayer"
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<castmenu v-if="modals.castMenu"></castmenu>
|
<castmenu v-if="modals.castMenu"></castmenu>
|
||||||
</transition>
|
</transition>
|
||||||
|
<transition name="modal">
|
||||||
|
<airplay-modal v-if="modals.airplayPW"></airplay-modal>
|
||||||
|
</transition>
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<plugin-menu v-if="modals.pluginMenu"></plugin-menu>
|
<plugin-menu v-if="modals.pluginMenu"></plugin-menu>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
|
@ -142,13 +142,13 @@
|
||||||
</span>
|
</span>
|
||||||
<span class="usermenu-item-name">{{$root.getLz('action.showWebRemoteQR')}}</span>
|
<span class="usermenu-item-name">{{$root.getLz('action.showWebRemoteQR')}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="usermenu-item" v-if="cfg.advanced.AudioContext" @click="modals.castMenu = true">
|
<button class="usermenu-item" @click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))">
|
||||||
<span class="usermenu-item-icon">
|
<span class="usermenu-item-icon">
|
||||||
<%- include("../svg/cast.svg") %>
|
<%- include("../svg/cast.svg") %>
|
||||||
</span>
|
</span>
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.cast')}}</span>
|
<span class="usermenu-item-name">{{$root.getLz('term.cast')}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="usermenu-item" v-if="cfg.advanced.AudioContext" @click="modals.audioSettings = true">
|
<button class="usermenu-item" @click="cfg.advanced.AudioContext ? modals.audioSettings = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))">
|
||||||
<span class="usermenu-item-icon">
|
<span class="usermenu-item-icon">
|
||||||
<%- include("../svg/headphones.svg") %>
|
<%- include("../svg/headphones.svg") %>
|
||||||
</span>
|
</span>
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
<input type="range" class="" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0"
|
<input type="range" class="" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0"
|
||||||
:max="cfg.audio.maxVolume" v-model="mk.volume" v-if="typeof mk.volume != 'undefined'"
|
:max="cfg.audio.maxVolume" v-model="mk.volume" v-if="typeof mk.volume != 'undefined'"
|
||||||
@change="checkMuteChange()" v-b-tooltip.hover
|
@change="checkMuteChange()" v-b-tooltip.hover
|
||||||
:title="`${(Math.log10(mk.volume) * 20).toFixed(2)} dB`">
|
:title="formatVolumeTooltip()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
42
src/renderer/views/components/airplay-modal.ejs
Normal file
42
src/renderer/views/components/airplay-modal.ejs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<script type="text/x-template" id="airplay-modal">
|
||||||
|
<div class="spatialproperties-panel castmenu modal-fullscreen airplay-modal" @click.self="close()" @contextmenu.self="close()">
|
||||||
|
<div class="modal-window airplay-modal">
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="modal-title">{{'Enter password'}}</div>
|
||||||
|
<button class="close-btn" @click="close()"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-content" style="overflow-y: overlay; padding: 3%">
|
||||||
|
<input type="text" v-model="passcode"/>
|
||||||
|
</div>
|
||||||
|
<div class="md-footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col" >
|
||||||
|
<button style="width:100%" @click="enterPassword()" class="md-btn md-btn-block md-btn-primary">{{'OK'}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
Vue.component('airplay-modal', {
|
||||||
|
template: '#airplay-modal',
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
passcode: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.$root.modals.airplayPW = false
|
||||||
|
},
|
||||||
|
enterPassword() {
|
||||||
|
console.log('Entered passCode: ', this.passcode)
|
||||||
|
ipcRenderer.send("setAirPlayPasscode",this.passcode)
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -29,7 +29,7 @@
|
||||||
template: '#artist-chip',
|
template: '#artist-chip',
|
||||||
async mounted() {
|
async mounted() {
|
||||||
let artistId = this.item.id
|
let artistId = this.item.id
|
||||||
if(typeof this.item.relationships == "object") {
|
if (typeof this.item.relationships == "object") {
|
||||||
artistId = this.item.relationships.catalog.data[0].id
|
artistId = this.item.relationships.catalog.data[0].id
|
||||||
}
|
}
|
||||||
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artistId}`).then(response => {
|
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artistId}`).then(response => {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="md-option-segment md-option-segment_auto percent">
|
<div class="md-option-segment md-option-segment_auto percent">
|
||||||
<input type="number"
|
<input type="number"
|
||||||
style="width: 100%; text-align: center; margin-right: 5px;" min="0"
|
style="width: 100%; text-align: center; margin-right: 5px;" min="0"
|
||||||
step="5" v-model="volume"/>
|
step="2" v-model="volume"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-line">
|
<div class="md-option-line">
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
app.modals.audioSettings = false
|
app.modals.audioSettings = false
|
||||||
},
|
},
|
||||||
openSpatialAudio() {
|
openSpatialAudio() {
|
||||||
if(app.cfg.audio.spatial === true && app.cfg.audio.maikiwiAudio.spatial === false) {
|
if (app.cfg.audio.spatial === true && app.cfg.audio.maikiwiAudio.spatial === false) {
|
||||||
app.modals.spatialProperties = true
|
app.modals.spatialProperties = true
|
||||||
app.modals.audioSettings = false
|
app.modals.audioSettings = false
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<div class="md-option-container" style="margin-top: 12px;margin-bottom: 12px;">
|
<div class="md-option-container" style="margin-top: 12px;margin-bottom: 12px;">
|
||||||
<div class="md-option-line">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{true ? 'Homepods only for now! (NO PASSWORD PLEASE!)' : 'Please add FFmpeg location in Settings -> Advanced'}}
|
{{'EXPERIMENTAL!!! Supports Homepods / Apple TVs / Shairport for now, AirPlay on Samsung/LG/Sony devices will be added later'}}
|
||||||
<!-- {{$root.getLz('action.cast.airplay.underdevelopment')}} -->
|
<!-- {{$root.getLz('action.cast.airplay.underdevelopment')}} -->
|
||||||
<template v-if="true" v-for="(device) in devices.airplay">
|
<template v-if="true" v-for="(device) in devices.airplay">
|
||||||
<div class="md-option-line" style="cursor: pointer" @click="setAirPlayCast(device)">
|
<div class="md-option-line" style="cursor: pointer" @click="setAirPlayCast(device)">
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
<button class="volume-button--small volume" @click="app.muteButtonPressed()" :class="{'active': app.cfg.audio.volume == 0}"></button>
|
<button class="volume-button--small volume" @click="app.muteButtonPressed()" :class="{'active': app.cfg.audio.volume == 0}"></button>
|
||||||
<input type="range" class="slider" @wheel="app.volumeWheel" :step="app.cfg.audio.volumeStep" min="0" :max="app.cfg.audio.maxVolume" v-model="app.mk.volume"
|
<input type="range" class="slider" @wheel="app.volumeWheel" :step="app.cfg.audio.volumeStep" min="0" :max="app.cfg.audio.maxVolume" v-model="app.mk.volume"
|
||||||
v-if="typeof app.mk.volume != 'undefined'" @change="app.checkMuteChange()"
|
v-if="typeof app.mk.volume != 'undefined'" @change="app.checkMuteChange()"
|
||||||
v-b-tooltip.hover :title="`${(Math.log10(app.mk.volume) * 20).toFixed(2)} dB`">
|
v-b-tooltip.hover :title="$root.formatVolumeTooltip()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script type="text/x-template" id="lyrics-view">
|
<script type="text/x-template" id="lyrics-view">
|
||||||
<div ref="lyricsview" class="md-body lyric-body">
|
<div ref="lyricsview" class="md-body lyric-body">
|
||||||
<template v-if="lyrics && lyrics != [] && lyrics.length > 0">
|
<template v-if="lyrics && lyrics != [] && lyrics.length > 0 && !qqInstrumental(lyrics)">
|
||||||
<template v-for="(lyric, index) in lyrics" v-if="lyric && lyric.line && lyric.line != 'lrcInstrumental'">
|
<template v-for="(lyric, index) in lyrics" v-if="lyric && lyric.line && lyric.line != 'lrcInstrumental'">
|
||||||
<h3 class="lyric-line" @click="seekTo(lyric.startTime)" :class="{unsynced : lyric.startTime == 9999999}"
|
<h3 class="lyric-line" @click="seekTo(lyric.startTime)" :class="{unsynced : lyric.startTime == 9999999}"
|
||||||
v-bind:line-index="index.toString()">
|
v-bind:line-index="index.toString()">
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
seekTo(startTime) {
|
seekTo(startTime) {
|
||||||
if(startTime != 9999999) this.app.seekTo(startTime, false);
|
if (startTime != 9999999) this.app.seekTo(startTime, false);
|
||||||
},
|
},
|
||||||
getActiveLyric() {
|
getActiveLyric() {
|
||||||
const delayfix = 0.1
|
const delayfix = 0.1
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
if (app.currentLyricsLine != i) {
|
if (app.currentLyricsLine != i) {
|
||||||
app.currentLyricsLine = i;
|
app.currentLyricsLine = i;
|
||||||
if (((app.lyricon && app.drawer.open) || app.appMode == 'fullscreen') && this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)) {
|
if (((app.lyricon && app.drawer.open) || app.appMode == 'fullscreen') && this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)) {
|
||||||
if(this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`)) {this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).classList.remove("active");}
|
if (this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`)) {this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).classList.remove("active");}
|
||||||
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).classList.add("active")
|
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).classList.add("active")
|
||||||
if (this.checkIfScrollIsStatic) {
|
if (this.checkIfScrollIsStatic) {
|
||||||
let lyricElement = this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)
|
let lyricElement = this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)
|
||||||
|
@ -183,6 +183,14 @@
|
||||||
}
|
}
|
||||||
else return []
|
else return []
|
||||||
},
|
},
|
||||||
|
qqInstrumental(lyrics) {
|
||||||
|
for(lyric of lyrics){
|
||||||
|
if (lyric.line.includes("纯音乐") && lyric.line.includes("欣赏")){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
checkIfScrollIsStatic : setInterval(() => {
|
checkIfScrollIsStatic : setInterval(() => {
|
||||||
try {
|
try {
|
||||||
if (position === this.$refs.lyricsview.scrollTop) {
|
if (position === this.$refs.lyricsview.scrollTop) {
|
||||||
|
|
|
@ -76,9 +76,9 @@
|
||||||
}, event)
|
}, event)
|
||||||
},
|
},
|
||||||
getVideoPriority() {
|
getVideoPriority() {
|
||||||
if(app.cfg.visual.animated_artwork == "always") {
|
if (app.cfg.visual.animated_artwork == "always") {
|
||||||
return true;
|
return true;
|
||||||
}else if (this.videoPriority && app.cfg.visual.animated_artwork == "limited") {
|
} else if (this.videoPriority && app.cfg.visual.animated_artwork == "limited") {
|
||||||
return true
|
return true
|
||||||
} else if (app.cfg.visual.animated_artwork == "disabled") {
|
} else if (app.cfg.visual.animated_artwork == "disabled") {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<button @click="addToLibrary()" v-if="!addedToLibrary && (showIndex == false ||(showIndex == true && showIndexPlaylist != false))">
|
<button @click="addToLibrary()" v-if="!addedToLibrary && (showIndex == false ||(showIndex == true && showIndexPlaylist != false))">
|
||||||
<div class="svg-icon addIcon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/plus.svg)'}"></div>
|
<div class="svg-icon addIcon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/plus.svg)'}"></div>
|
||||||
</button>
|
</button>
|
||||||
<button v-else-if='!(showArtwork == true && (showIndex == false ||(showIndex == true && showIndexPlaylist != false)))' @click="playTrack()" style="width: 44px;margin-left: -5px;">
|
<button v-else-if='!(showArtwork == true && (showIndex == false ||(showIndex == true && showIndexPlaylist != false)))' @click="playTrack()">
|
||||||
<div class="svg-icon playIcon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/play.svg)'}"></div>
|
<div class="svg-icon playIcon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/play.svg)'}"></div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,6 +65,10 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="heart-icon" v-if="!(app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? (app.mk.nowPlayingItem.songId ?? app.mk.nowPlayingItem.id )) == itemId) || (app.mk.nowPlayingItem.id == item.id)))">
|
||||||
|
<!-- <div class="heart-unfilled" v-if="isLoved == false" :style="{'--url': 'url(./assets/feather/heart.svg)'}" /> -->
|
||||||
|
<div class="heart-filled" v-if="isLoved == true" :style="{'--url': 'url(./assets/feather/heart-fill.svg)'}" />
|
||||||
|
</div>
|
||||||
<div class="explicit-icon" v-if="item.attributes && item.attributes.contentRating == 'explicit'"></div>
|
<div class="explicit-icon" v-if="item.attributes && item.attributes.contentRating == 'explicit'"></div>
|
||||||
<template v-if="showMetaData == true" @dblclick="route()">
|
<template v-if="showMetaData == true" @dblclick="route()">
|
||||||
<div class="metainfo">
|
<div class="metainfo">
|
||||||
|
@ -98,7 +102,8 @@
|
||||||
displayDuration: true,
|
displayDuration: true,
|
||||||
addClasses: {},
|
addClasses: {},
|
||||||
itemId: 0,
|
itemId: 0,
|
||||||
isLibrary: false
|
isLibrary: false,
|
||||||
|
isLoved: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -121,6 +126,9 @@
|
||||||
} else {
|
} else {
|
||||||
this.itemId = this.item.id;
|
this.itemId = this.item.id;
|
||||||
}
|
}
|
||||||
|
if (this.item.attributes.playParams) {
|
||||||
|
this.getHeartStatus();
|
||||||
|
}
|
||||||
let duration = this.item.attributes.durationInMillis ?? 0
|
let duration = this.item.attributes.durationInMillis ?? 0
|
||||||
if (duration == 0 || !this.showDuration) {
|
if (duration == 0 || !this.showDuration) {
|
||||||
this.displayDuration = false
|
this.displayDuration = false
|
||||||
|
@ -145,7 +153,7 @@
|
||||||
},
|
},
|
||||||
getClasses() {
|
getClasses() {
|
||||||
this.addClasses = {}
|
this.addClasses = {}
|
||||||
if(typeof this.item.attributes.playParams == "undefined") {
|
if (typeof this.item.attributes.playParams == "undefined") {
|
||||||
this.addClasses["disabled"] = true
|
this.addClasses["disabled"] = true
|
||||||
}
|
}
|
||||||
if (this.classList) {
|
if (this.classList) {
|
||||||
|
@ -178,7 +186,7 @@
|
||||||
} else {
|
} else {
|
||||||
return this.item.attributes.playParams.kind
|
return this.item.attributes.playParams.kind
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
return this.item.type
|
return this.item.type
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -323,6 +331,7 @@
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"disabled": true,
|
"disabled": true,
|
||||||
"action": function () {
|
"action": function () {
|
||||||
|
self.isLoved = true
|
||||||
app.love(self.item)
|
app.love(self.item)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -333,6 +342,7 @@
|
||||||
"name": this.app.getLz('action.unlove'),
|
"name": this.app.getLz('action.unlove'),
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"action": function () {
|
"action": function () {
|
||||||
|
self.isLoved = false
|
||||||
app.unlove(self.item)
|
app.unlove(self.item)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -499,6 +509,19 @@
|
||||||
visibilityChanged: function (isVisible, entry) {
|
visibilityChanged: function (isVisible, entry) {
|
||||||
this.isVisible = isVisible
|
this.isVisible = isVisible
|
||||||
},
|
},
|
||||||
|
async getHeartStatus() {
|
||||||
|
try {
|
||||||
|
await app.getRating(this.item).then(res => {
|
||||||
|
if (res == 1) {
|
||||||
|
this.isLoved = true
|
||||||
|
} else {
|
||||||
|
this.isLoved = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
addToLibrary() {
|
addToLibrary() {
|
||||||
let item = this.item
|
let item = this.item
|
||||||
if (item.attributes.playParams.id) {
|
if (item.attributes.playParams.id) {
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<div class="title text-overflow-elipsis" @click='app.routeView(item)'>
|
<div class="title text-overflow-elipsis" @click='app.routeView(item)'>
|
||||||
{{ item.attributes.name ?? '' }}
|
{{ item.attributes.name ?? '' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="subtitle text-overflow-elipsis item-navigate" v-if="item.attributes.artistName" :style = "{'z-index': ((item.attributes.editorialNotes == null) && item.attributes.artistName) ? '4' : ''}" @click="if(item.attributes.artistName)app.searchAndNavigate(item,'artist')">
|
<div class="subtitle text-overflow-elipsis item-navigate" v-if="item.attributes.artistName" :style = "{'z-index': ((item.attributes.editorialNotes == null) && item.attributes.artistName) ? '4' : ''}" @click="if (item.attributes.artistName)app.searchAndNavigate(item,'artist')">
|
||||||
{{ item.attributes.artistName ?? '' }}
|
{{ item.attributes.artistName ?? '' }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -93,12 +93,12 @@
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.getBadges()
|
await this.getBadges()
|
||||||
if(typeof this.item.attributes.playParams == "object") {
|
if (typeof this.item.attributes.playParams == "object") {
|
||||||
if(this.item.attributes.playParams.kind.includes("radioStation") && (this.item.attributes.playParams.streamingKind == 1 || this.item.attributes.playParams.streamingKind == 2)) {
|
if (this.item.attributes.playParams.kind.includes("radioStation") && (this.item.attributes.playParams.streamingKind == 1 || this.item.attributes.playParams.streamingKind == 2)) {
|
||||||
this.unavailable = true
|
this.unavailable = true
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if(this.item.type == "music-movies" || this.item.type == "tv-episodes") {
|
if (this.item.type == "music-movies" || this.item.type == "tv-episodes") {
|
||||||
this.unavailable = true
|
this.unavailable = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getSubtitle() {
|
getSubtitle() {
|
||||||
if(this.kind == 'card') {
|
if (this.kind == 'card') {
|
||||||
try {
|
try {
|
||||||
if (typeof this.item.attributes.artistNames != "undefined") {
|
if (typeof this.item.attributes.artistNames != "undefined") {
|
||||||
return this.item.attributes.artistNames
|
return this.item.attributes.artistNames
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
}catch(e) {
|
}catch(e) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
if (typeof this.item.attributes.artistName != "undefined") {
|
if (typeof this.item.attributes.artistName != "undefined") {
|
||||||
return this.item.attributes.artistName
|
return this.item.attributes.artistName
|
||||||
} else {
|
} else {
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getSubtitleNavigation() {
|
getSubtitleNavigation() {
|
||||||
if(this.kind == 'card') {
|
if (this.kind == 'card') {
|
||||||
try {
|
try {
|
||||||
if (typeof this.item.attributes.artistNames != "undefined") {
|
if (typeof this.item.attributes.artistNames != "undefined") {
|
||||||
return app.routeView(this.item)
|
return app.routeView(this.item)
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
}catch(e) {
|
}catch(e) {
|
||||||
return app.routeView(this.item)
|
return app.routeView(this.item)
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
if (typeof this.item.attributes.artistName != "undefined") {
|
if (typeof this.item.attributes.artistName != "undefined") {
|
||||||
return app.searchAndNavigate(this.item,'artist')
|
return app.searchAndNavigate(this.item,'artist')
|
||||||
} else {
|
} else {
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
},
|
},
|
||||||
getArtworkUrl(size = -1, includeUrl = false) {
|
getArtworkUrl(size = -1, includeUrl = false) {
|
||||||
let artwork = this.item.attributes.artwork ? this.item.attributes.artwork.url : ''
|
let artwork = this.item.attributes.artwork ? this.item.attributes.artwork.url : ''
|
||||||
if(size != -1) {
|
if (size != -1) {
|
||||||
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', ((size === 900) ? "sr" : "cc"))
|
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', ((size === 900) ? "sr" : "cc"))
|
||||||
}
|
}
|
||||||
switch (this.kind) {
|
switch (this.kind) {
|
||||||
|
@ -232,9 +232,9 @@
|
||||||
artwork = this.item.attributes.editorialArtwork?.subscriptionHero?.url ?? (this.item.attributes.artwork?.url ?? (this.item.relationships?.contents?.data[0]?.attributes?.editorialArtwork?.subscriptionHero?.url ?? ''))
|
artwork = this.item.attributes.editorialArtwork?.subscriptionHero?.url ?? (this.item.attributes.artwork?.url ?? (this.item.relationships?.contents?.data[0]?.attributes?.editorialArtwork?.subscriptionHero?.url ?? ''))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!includeUrl) {
|
if (!includeUrl) {
|
||||||
return artwork
|
return artwork
|
||||||
}else{
|
} else {
|
||||||
return `url("${artwork}")`
|
return `url("${artwork}")`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -442,7 +442,7 @@
|
||||||
if (self.item.relationships.catalog){
|
if (self.item.relationships.catalog){
|
||||||
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
self.app.copyToClipboard(self.item.attributes.url)}
|
self.app.copyToClipboard(self.item.attributes.url)}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -454,7 +454,7 @@
|
||||||
if (self.item.relationships.catalog){
|
if (self.item.relationships.catalog){
|
||||||
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.songLinkShare((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.songLinkShare((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
self.app.songLinkShare(self.item.attributes.url)}
|
self.app.songLinkShare(self.item.attributes.url)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,10 +471,10 @@
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.isInLibrary().then((_) => {
|
await this.isInLibrary().then((_) => {
|
||||||
if(self.addedToLibrary) {
|
if (self.addedToLibrary) {
|
||||||
menus.normal.items.find(x => x.id == 'addToLibrary').hidden = true
|
menus.normal.items.find(x => x.id == 'addToLibrary').hidden = true
|
||||||
menus.normal.items.find(x => x.id == 'removeFromLibrary').hidden = false
|
menus.normal.items.find(x => x.id == 'removeFromLibrary').hidden = false
|
||||||
}else{
|
} else {
|
||||||
menus.normal.items.find(x => x.id == 'addToLibrary').disabled = false
|
menus.normal.items.find(x => x.id == 'addToLibrary').disabled = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -530,7 +530,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(self.app.cfg.home.followedArtists.includes(this.item.id)) {
|
if (self.app.cfg.home.followedArtists.includes(this.item.id)) {
|
||||||
followAction = "unfollow"
|
followAction = "unfollow"
|
||||||
}
|
}
|
||||||
app.showMenuPanel({
|
app.showMenuPanel({
|
||||||
|
|
|
@ -13,12 +13,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="queue-body" v-if="page == 'queue'">
|
<div class="queue-body" v-if="page == 'queue'">
|
||||||
<draggable v-model="queueItems" @start="drag=true" @end="drag=false;move()">
|
<draggable v-model="queueItems" @start="drag=true" @end="drag=false;move()">
|
||||||
<template v-for="(queueItem, position) in queueItems">
|
<template v-for="(queueItem, position) in displayQueueItems">
|
||||||
<div v-if="position <= queuePosition" style="display: none;">{{ position }}</div>
|
|
||||||
<div class="cd-queue-item"
|
<div class="cd-queue-item"
|
||||||
:class="{selected: selectedItems.includes(position)}"
|
:class="{selected: selectedItems.includes(position)}"
|
||||||
@click="select($event, position)"
|
@click="select($event, position)"
|
||||||
@dblclick="playQueueItem(position)" v-else :key="position"
|
@dblclick="playQueueItem(position)" :key="position"
|
||||||
@contextmenu="selected = position;queueContext($event, queueItem.item, position)">
|
@contextmenu="selected = position;queueContext($event, queueItem.item, position)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
|
@ -61,6 +60,13 @@
|
||||||
app: this.$root
|
app: this.$root
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
displayQueueItems() {
|
||||||
|
const displayLimit = 50;
|
||||||
|
const lastDisplayPosition = Math.min(displayLimit + this.queuePosition, this.queueItems.length);
|
||||||
|
return this.queueItems.slice(this.queuePosition, lastDisplayPosition);
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.updateQueue()
|
this.updateQueue()
|
||||||
},
|
},
|
||||||
|
@ -70,8 +76,8 @@
|
||||||
this.history = history.data.data
|
this.history = history.data.data
|
||||||
},
|
},
|
||||||
select(e, position) {
|
select(e, position) {
|
||||||
if(e.ctrlKey || e.shiftKey) {
|
if (e.ctrlKey || e.shiftKey) {
|
||||||
if(this.selectedItems.indexOf(position) == -1) {
|
if (this.selectedItems.indexOf(position) == -1) {
|
||||||
this.selectedItems.push(position)
|
this.selectedItems.push(position)
|
||||||
} else {
|
} else {
|
||||||
this.selectedItems.splice(this.selectedItems.indexOf(position), 1)
|
this.selectedItems.splice(this.selectedItems.indexOf(position), 1)
|
||||||
|
@ -83,7 +89,7 @@
|
||||||
queueContext(event, item, position) {
|
queueContext(event, item, position) {
|
||||||
let self = this
|
let self = this
|
||||||
let useMenu = "single"
|
let useMenu = "single"
|
||||||
if(this.selectedItems.length > 1) {
|
if (this.selectedItems.length > 1) {
|
||||||
useMenu = "multiple"
|
useMenu = "multiple"
|
||||||
}
|
}
|
||||||
let menus = {
|
let menus = {
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
playlistSelect(playlist) {
|
playlistSelect(playlist) {
|
||||||
if(playlist.type != "library-playlist-folders") {
|
if (playlist.type != "library-playlist-folders") {
|
||||||
this.addToPlaylist(playlist.id)
|
this.addToPlaylist(playlist.id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -294,7 +294,7 @@
|
||||||
this.room_materials = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.room_materials))
|
this.room_materials = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.room_materials))
|
||||||
this.audio_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.audio_position))
|
this.audio_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.audio_position))
|
||||||
this.listener_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.listener_position))
|
this.listener_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.listener_position))
|
||||||
if(typeof this.app.mk.nowPlayingItem != "undefined") {
|
if (typeof this.app.mk.nowPlayingItem != "undefined") {
|
||||||
this.setRoom()
|
this.setRoom()
|
||||||
}
|
}
|
||||||
this.ready = true
|
this.ready = true
|
||||||
|
@ -320,7 +320,7 @@
|
||||||
},
|
},
|
||||||
objectContainerStyle() {
|
objectContainerStyle() {
|
||||||
let scale = 1
|
let scale = 1
|
||||||
if(this.room_dimensions.width * this.visualMultiplier > 300) {
|
if (this.room_dimensions.width * this.visualMultiplier > 300) {
|
||||||
scale = 300 / (this.room_dimensions.width * this.visualMultiplier)
|
scale = 300 / (this.room_dimensions.width * this.visualMultiplier)
|
||||||
}
|
}
|
||||||
let style = {
|
let style = {
|
||||||
|
@ -346,7 +346,7 @@
|
||||||
window.CiderAudio.audioNodes.spatialNode.setRoomProperties(this.room_dimensions, this.room_materials);
|
window.CiderAudio.audioNodes.spatialNode.setRoomProperties(this.room_dimensions, this.room_materials);
|
||||||
CiderAudio.audioNodes.spatialInput.setPosition(...this.audio_position)
|
CiderAudio.audioNodes.spatialInput.setPosition(...this.audio_position)
|
||||||
CiderAudio.audioNodes.spatialNode.setListenerPosition(...this.listener_position)
|
CiderAudio.audioNodes.spatialNode.setListenerPosition(...this.listener_position)
|
||||||
if(!this.app.cfg.audio.normalization) {
|
if (!this.app.cfg.audio.normalization) {
|
||||||
window.CiderAudio.audioNodes.gainNode.gain.value = app.cfg.audio.spatial_properties.gain
|
window.CiderAudio.audioNodes.gainNode.gain.value = app.cfg.audio.spatial_properties.gain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(this.app.cfg.home.followedArtists.includes(self.data.id)) {
|
if (this.app.cfg.home.followedArtists.includes(self.data.id)) {
|
||||||
followAction = "unfollow"
|
followAction = "unfollow"
|
||||||
}
|
}
|
||||||
app.showMenuPanel({
|
app.showMenuPanel({
|
||||||
|
|
368
src/renderer/views/pages/installed-themes.ejs
Normal file
368
src/renderer/views/pages/installed-themes.ejs
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
<script type="text/x-template" id="installed-themes">
|
||||||
|
<div class="content-inner github-themes-page installed-themes-page">
|
||||||
|
<div class="gh-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col nopadding">
|
||||||
|
<h1 class="header-text">
|
||||||
|
{{ $root.getLz("settings.option.visual.theme.manageStyles") }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto nopadding flex-center">
|
||||||
|
<button class="md-btn md-btn-small md-btn-block" @click="$root.appRoute('themes-github')">
|
||||||
|
{{$root.getLz('settings.option.visual.theme.github.explore')}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto flex-center">
|
||||||
|
<button class="md-btn md-btn-small md-btn-block" @click="$root.checkForThemeUpdates()">
|
||||||
|
{{ $root.getLz('settings.option.visual.theme.checkForUpdates') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto nopadding flex-center">
|
||||||
|
<button class="md-btn md-btn-small md-btn-block" @click="openThemesFolder()">
|
||||||
|
{{$root.getLz('settings.option.visual.theme.github.openfolder')}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gh-content">
|
||||||
|
<div class="repos-list">
|
||||||
|
<div class="repo-header">
|
||||||
|
<h4>{{$root.getLz('settings.option.visual.theme.github.available')}}</h4>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<template v-for="theme in themes">
|
||||||
|
<li @click="addStyle(theme.file)"
|
||||||
|
@contextmenu="contextMenu($event, theme)"
|
||||||
|
class="list-group-item list-group-item-dark"
|
||||||
|
:class="{'applied': $root.cfg.visual.styles.includes(theme.file)}">
|
||||||
|
|
||||||
|
<b-row>
|
||||||
|
<b-col class="themeLabel">{{theme.name}}</b-col>
|
||||||
|
<template v-if="$root.cfg.visual.styles.includes(theme.file)">
|
||||||
|
<b-col sm="auto" v-if="theme.pack">
|
||||||
|
<button class="themeContextMenu codicon codicon-package"></button>
|
||||||
|
</b-col>
|
||||||
|
<b-col sm="auto">
|
||||||
|
<button class="themeContextMenu codicon codicon-check"></button>
|
||||||
|
</b-col>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<b-col sm="auto" v-if="theme.pack">
|
||||||
|
<button class="themeContextMenu codicon codicon-package"></button>
|
||||||
|
</b-col>
|
||||||
|
<b-col sm="auto">
|
||||||
|
<button @click.stop="contextMenu($event, theme)" class="themeContextMenu codicon codicon-list-unordered"></button>
|
||||||
|
</b-col>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</b-row>
|
||||||
|
</li>
|
||||||
|
<li @click="addStyle(packEntry.file)"
|
||||||
|
@contextmenu="contextMenu($event, theme)"
|
||||||
|
class="list-group-item list-group-item-dark addon"
|
||||||
|
v-for="packEntry in theme.pack"
|
||||||
|
:class="{'applied': $root.cfg.visual.styles.includes(packEntry.file)}"
|
||||||
|
v-if="theme.pack">
|
||||||
|
|
||||||
|
<b-row>
|
||||||
|
<b-col class="themeLabel">{{packEntry.name}}</b-col>
|
||||||
|
<template v-if="$root.cfg.visual.styles.includes(packEntry.file)">
|
||||||
|
<b-col sm="auto">
|
||||||
|
<button class="themeContextMenu codicon codicon-check"></button>
|
||||||
|
</b-col>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<b-col sm="auto">
|
||||||
|
<button class="themeContextMenu codicon codicon-diff-added"></button>
|
||||||
|
</b-col>
|
||||||
|
</template>
|
||||||
|
</b-row>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="style-editor-container">
|
||||||
|
<div class="repo-header">
|
||||||
|
<h4>{{ $root.getLz("settings.option.visual.theme.github.applied") }} </h4>
|
||||||
|
</div>
|
||||||
|
<stylestack-editor ref="stackEditor" v-if="themes.length != 0" :themes="themes"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// do not translate
|
||||||
|
Vue.component('stylestack-editor', {
|
||||||
|
/*html*/
|
||||||
|
template: `
|
||||||
|
<div class="stylestack-editor" >
|
||||||
|
<draggable class="list-group" v-model="$root.cfg.visual.styles" @end="$root.reloadStyles()">
|
||||||
|
<b-list-group-item variant="dark" v-for="theme in $root.cfg.visual.styles" :key="theme">
|
||||||
|
<b-row>
|
||||||
|
<b-col sm="auto">
|
||||||
|
<div class="handle codicon codicon-grabber"></div>
|
||||||
|
</b-col>
|
||||||
|
<b-col class="themeLabel">{{getThemeName(theme)}}</b-col>
|
||||||
|
<b-col sm="auto">
|
||||||
|
<button class="removeItem codicon codicon-close" @click="remove(theme)"></button>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-list-group-item>
|
||||||
|
</draggable>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
props: {
|
||||||
|
themes: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
selected: null,
|
||||||
|
newTheme: null,
|
||||||
|
themeList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log(this.themes)
|
||||||
|
this.themeList = [...this.themes]
|
||||||
|
|
||||||
|
this.themeList.forEach(theme => {
|
||||||
|
if (theme.pack) {
|
||||||
|
theme.pack.forEach(packEntry => {
|
||||||
|
packEntry.file = theme.file.replace('index.less', '') + packEntry.file
|
||||||
|
this.themeList.push(packEntry)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
gitHubExplore() {
|
||||||
|
this.$root.appRoute("themes-github")
|
||||||
|
},
|
||||||
|
getThemeName(filename) {
|
||||||
|
try {
|
||||||
|
return this.themeList.find(theme => theme.file === filename).name;
|
||||||
|
} catch (e) {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
moveUp() {
|
||||||
|
const styles = this.$root.cfg.visual.styles
|
||||||
|
const index = styles.indexOf(this.selected)
|
||||||
|
if (index > 0) {
|
||||||
|
styles.splice(index, 1)
|
||||||
|
styles.splice(index - 1, 0, this.selected)
|
||||||
|
}
|
||||||
|
this.$root.reloadStyles()
|
||||||
|
},
|
||||||
|
moveDown() {
|
||||||
|
const styles = this.$root.cfg.visual.styles
|
||||||
|
const index = styles.indexOf(this.selected)
|
||||||
|
if (index < styles.length - 1) {
|
||||||
|
styles.splice(index, 1)
|
||||||
|
styles.splice(index + 1, 0, this.selected)
|
||||||
|
}
|
||||||
|
this.$root.reloadStyles()
|
||||||
|
},
|
||||||
|
remove(style) {
|
||||||
|
const styles = this.$root.cfg.visual.styles
|
||||||
|
const index = styles.indexOf(style)
|
||||||
|
styles.splice(index, 1)
|
||||||
|
this.$root.reloadStyles()
|
||||||
|
},
|
||||||
|
addStyle(style) {
|
||||||
|
const styles = this.$root.cfg.visual.styles
|
||||||
|
styles.push(style)
|
||||||
|
this.$root.reloadStyles()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Vue.component('installed-themes', {
|
||||||
|
template: "#installed-themes",
|
||||||
|
props: [],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
repos: [],
|
||||||
|
openRepo: {
|
||||||
|
id: -1,
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
html_url: '',
|
||||||
|
stargazers_count: 0,
|
||||||
|
owner: {
|
||||||
|
avatar_url: ''
|
||||||
|
},
|
||||||
|
readme: ""
|
||||||
|
},
|
||||||
|
themesInstalled: [],
|
||||||
|
themes: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getThemesList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getThemesList() {
|
||||||
|
let self = this
|
||||||
|
let themes = ipcRenderer.sendSync("get-themes")
|
||||||
|
themes.unshift({
|
||||||
|
name: "Acrylic Grain",
|
||||||
|
file: "grain.less"
|
||||||
|
})
|
||||||
|
themes.unshift({
|
||||||
|
name: "Sweetener",
|
||||||
|
file: "sweetener.less"
|
||||||
|
})
|
||||||
|
themes.unshift({
|
||||||
|
name: "Reduce Visuals",
|
||||||
|
file: "reduce_visuals.less"
|
||||||
|
})
|
||||||
|
themes.unshift({
|
||||||
|
name: "Inline Drawer",
|
||||||
|
file: "inline_drawer.less"
|
||||||
|
})
|
||||||
|
themes.unshift({
|
||||||
|
name: "Dark",
|
||||||
|
file: "dark.less"
|
||||||
|
})
|
||||||
|
this.themes = themes
|
||||||
|
},
|
||||||
|
contextMenu(event, theme) {
|
||||||
|
let self = this
|
||||||
|
let menu = {
|
||||||
|
items: {
|
||||||
|
"uninstall": {
|
||||||
|
name: app.getLz("settings.option.visual.theme.uninstall"),
|
||||||
|
disabled: true,
|
||||||
|
action: () => {
|
||||||
|
bootbox.confirm(app.stringTemplateParser(app.getLz("settings.prompt.visual.theme.uninstallTheme"), {
|
||||||
|
theme: theme.name ?? theme.file
|
||||||
|
}), (res) => {
|
||||||
|
if (res) {
|
||||||
|
console.debug(theme)
|
||||||
|
ipcRenderer.once("theme-uninstalled", (event, args) => {
|
||||||
|
console.debug(event, args)
|
||||||
|
self.getThemesList()
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke("uninstall-theme", theme.path)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"viewInfo": {
|
||||||
|
name: app.getLz("settings.option.visual.theme.viewInfo"),
|
||||||
|
disabled: true,
|
||||||
|
action: () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (theme.path) {
|
||||||
|
menu.items.uninstall.disabled = false
|
||||||
|
}
|
||||||
|
this.$root.showMenuPanel(menu, event)
|
||||||
|
},
|
||||||
|
openThemesFolder() {
|
||||||
|
ipcRenderer.invoke("open-path", "themes")
|
||||||
|
},
|
||||||
|
getInstalledThemes() {
|
||||||
|
let self = this
|
||||||
|
const themes = ipcRenderer.sendSync("get-themes")
|
||||||
|
// for each theme, get the github_repo property and push it to the themesInstalled array, if not blank
|
||||||
|
themes.forEach(theme => {
|
||||||
|
if (theme.github_repo !== "" && typeof theme.commit != "") {
|
||||||
|
self.themesInstalled.push(theme.github_repo.toLowerCase())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addStyle(filename) {
|
||||||
|
this.$refs.stackEditor.addStyle(filename)
|
||||||
|
},
|
||||||
|
showRepo(repo) {
|
||||||
|
const self = this
|
||||||
|
const readmeUrl = `https://raw.githubusercontent.com/${repo.full_name}/main/README.md`;
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch(readmeUrl, requestOptions)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(result => {
|
||||||
|
self.openRepo = repo
|
||||||
|
self.openRepo.readme = self.convertReadMe(result);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
self.openRepo = repo
|
||||||
|
self.openRepo.readme = `This repository doesn't have a README.md file.`;
|
||||||
|
console.log('error', error)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
convertReadMe(text) {
|
||||||
|
return marked.parse(text)
|
||||||
|
},
|
||||||
|
installThemeRepo(repo) {
|
||||||
|
let self = this
|
||||||
|
let msg = app.stringTemplateParser(app.getLz('settings.option.visual.theme.github.install.confirm'), {
|
||||||
|
repo: repo.full_name
|
||||||
|
});
|
||||||
|
bootbox.confirm(msg, (res) => {
|
||||||
|
if (res) {
|
||||||
|
ipcRenderer.once("theme-installed", (event, arg) => {
|
||||||
|
if (arg.success) {
|
||||||
|
self.themes = ipcRenderer.sendSync("get-themes")
|
||||||
|
self.getInstalledThemes()
|
||||||
|
notyf.success(app.getLz('settings.notyf.visual.theme.install.success'));
|
||||||
|
} else {
|
||||||
|
notyf.error(app.getLz('settings.notyf.visual.theme.install.error'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ipcRenderer.invoke("get-github-theme", repo.html_url)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
installThemeURL() {
|
||||||
|
let self = this
|
||||||
|
bootbox.prompt(app.getLz('settings.prompt.visual.theme.github.URL'), (result) => {
|
||||||
|
if (result) {
|
||||||
|
ipcRenderer.once("theme-installed", (event, arg) => {
|
||||||
|
if (arg.success) {
|
||||||
|
self.themes = ipcRenderer.sendSync("get-themes")
|
||||||
|
notyf.success(app.getLz('settings.notyf.visual.theme.install.success'));
|
||||||
|
} else {
|
||||||
|
notyf.error(app.getLz('settings.notyf.visual.theme.install.error'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ipcRenderer.invoke("get-github-theme", result)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getRepos() {
|
||||||
|
let self = this
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch("https://api.github.com/search/repositories?q=topic:cidermusictheme fork:true", requestOptions)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(result => {
|
||||||
|
let items = JSON.parse(result).items
|
||||||
|
self.repos = items
|
||||||
|
})
|
||||||
|
.catch(error => console.log('error', error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -132,9 +132,9 @@
|
||||||
self.themes = []
|
self.themes = []
|
||||||
notyf.success(app.getLz('settings.notyf.visual.plugin.install.success'));
|
notyf.success(app.getLz('settings.notyf.visual.plugin.install.success'));
|
||||||
bootbox.confirm(app.getLz("settings.prompt.visual.plugin.github.success"), (ok)=>{
|
bootbox.confirm(app.getLz("settings.prompt.visual.plugin.github.success"), (ok)=>{
|
||||||
if(ok) {
|
if (ok) {
|
||||||
ipcRenderer.invoke("relaunchApp")
|
ipcRenderer.invoke("relaunchApp")
|
||||||
}else{
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -154,9 +154,9 @@
|
||||||
if (arg.success) {
|
if (arg.success) {
|
||||||
self.themes = ipcRenderer.sendSync("get-themes")
|
self.themes = ipcRenderer.sendSync("get-themes")
|
||||||
bootbox.confirm(app.getLz("settings.prompt.visual.plugin.github.success"), (ok)=>{
|
bootbox.confirm(app.getLz("settings.prompt.visual.plugin.github.success"), (ok)=>{
|
||||||
if(ok) {
|
if (ok) {
|
||||||
ipcRenderer.invoke("relaunchApp")
|
ipcRenderer.invoke("relaunchApp")
|
||||||
}else{
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -187,7 +187,7 @@
|
||||||
},
|
},
|
||||||
searchPodcasts() {
|
searchPodcasts() {
|
||||||
let self = this
|
let self = this
|
||||||
if(this.search.term == "") {
|
if (this.search.term == "") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.mk.api.v3.podcasts("/v1/catalog/us/search", {term: this.search.term, types: ["podcasts"], limit: 25}).then(response => {
|
app.mk.api.v3.podcasts("/v1/catalog/us/search", {term: this.search.term, types: ["podcasts"], limit: 25}).then(response => {
|
||||||
|
@ -227,7 +227,7 @@
|
||||||
async getNextEpisodes(next, podcastId) {
|
async getNextEpisodes(next, podcastId) {
|
||||||
|
|
||||||
let podcastShow = await app.mk.api.v3.podcasts(next)
|
let podcastShow = await app.mk.api.v3.podcasts(next)
|
||||||
if(podcastId != this.podcastSelected.id) {
|
if (podcastId != this.podcastSelected.id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
podcastShow.data.data.forEach(ep => {
|
podcastShow.data.data.forEach(ep => {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h4>{{ loaded.attributes.listenTimeInMinutes }} {{$root.getLz('term.time.minutes')}}</h4>
|
<h4>{{ convertToHours(loaded.attributes.listenTimeInMinutes) }} {{$root.getLz('term.time.hours')}}</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueAlbumCount }} {{$root.getLz('term.uniqueAlbums')}}</h4>
|
<h4>{{ loaded.attributes.uniqueAlbumCount }} {{$root.getLz('term.uniqueAlbums')}}</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueArtistCount }} {{$root.getLz('term.uniqueArtists')}}</h4>
|
<h4>{{ loaded.attributes.uniqueArtistCount }} {{$root.getLz('term.uniqueArtists')}}</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueSongCount }} {{$root.getLz('term.uniqueSongs')}}</h4>
|
<h4>{{ loaded.attributes.uniqueSongCount }} {{$root.getLz('term.uniqueSongs')}}</h4>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<mediaitem-square :item="artistData.relationships.artist.data[0]"></mediaitem-square>
|
<mediaitem-square :item="artistData.relationships.artist.data[0]"></mediaitem-square>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
{{ artistData.attributes.listenTimeInMinutes }} {{$root.getLz('term.time.minutes', {'count': artistData.attributes.listenTimeInMinutes})}}<br>
|
{{ convertToHours(artistData.attributes.listenTimeInMinutes) }} {{$root.getLz('term.time.hours', {'count': convertToHours(artistData.attributes.listenTimeInMinutes) })}}<br>
|
||||||
{{$root.getLz('term.listenedTo')}} {{ artistData.attributes.playCount }} {{$root.getLz('term.times')}}
|
{{$root.getLz('term.listenedTo')}} {{ artistData.attributes.playCount }} {{$root.getLz('term.times')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
<mediaitem-square :item="albumData.relationships.album.data[0]"></mediaitem-square>
|
<mediaitem-square :item="albumData.relationships.album.data[0]"></mediaitem-square>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
{{ albumData.attributes.listenTimeInMinutes }} {{$root.getLz('term.time.minutes', {'count': albumData.attributes.listenTimeInMinutes})}}<br>
|
{{ convertToHours(albumData.attributes.listenTimeInMinutes) }} {{$root.getLz('term.time.hours', {'count': convertToHours(albumData.attributes.listenTimeInMinutes)})}}<br>
|
||||||
{{ albumData.attributes.playCount }} {{$root.getLz('term.plays')}}
|
{{ albumData.attributes.playCount }} {{$root.getLz('term.plays')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -151,6 +151,9 @@
|
||||||
let playlist = await app.mk.api.v3.music(replayData.relationships.playlist.data[0].href, {extend: "editorialArtwork,editorialVideo"})
|
let playlist = await app.mk.api.v3.music(replayData.relationships.playlist.data[0].href, {extend: "editorialArtwork,editorialVideo"})
|
||||||
replayData.playlist = playlist.data.data[0]
|
replayData.playlist = playlist.data.data[0]
|
||||||
this.loaded = replayData
|
this.loaded = replayData
|
||||||
|
},
|
||||||
|
convertToHours(minutes) {
|
||||||
|
return Math.floor(minutes / 60)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -441,6 +441,30 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext && app.cfg.audio.normalization">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
dB SPL Display
|
||||||
|
<br>
|
||||||
|
<small>(Advanced users only) Display dB SPL instead of dBFS on the volume slider.</small>
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" v-model="app.cfg.audio.dBSPL" switch/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="md-option-line" v-show="app.cfg.audio.dBSPL">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
0 dBFS Calibration
|
||||||
|
<br>
|
||||||
|
<small>Enter the peak Z-weighted dB SPL when Cider is at 0 dBFS.</small>
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="number" v-model="app.cfg.audio.dBSPLcalibration"/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</b-tab>
|
</b-tab>
|
||||||
|
@ -456,20 +480,8 @@
|
||||||
{{$root.getLz('settings.header.visual.theme')}}
|
{{$root.getLz('settings.header.visual.theme')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<button class="md-btn md-btn-block" @click="$root.appRoute('installed-themes')">
|
||||||
<select class="md-select" @change="$root.setTheme($root.cfg.visual.theme)"
|
{{$root.getLz('settings.option.visual.theme.manageStyles')}}
|
||||||
v-model="$root.cfg.visual.theme">
|
|
||||||
<option value="default.less">
|
|
||||||
{{$root.getLz('settings.option.visual.theme.default')}}
|
|
||||||
</option>
|
|
||||||
<option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}
|
|
||||||
</option>
|
|
||||||
<option v-for="theme in themes" :value="theme.file">{{ theme.name }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<button class="md-btn md-btn-small md-btn-block" @click="gitHubExplore()"
|
|
||||||
style="margin-top: 8px">
|
|
||||||
{{$root.getLz('settings.option.visual.theme.github.explore')}}
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1013,18 +1025,18 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="app.cfg.general.discord_rpc.enabled" switch/>
|
<input type="checkbox" v-model="app.cfg.general.discordrpc.enabled" switch/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.general.discord_rpc.enabled != false">
|
<div class="md-option-line" v-show="app.cfg.general.discordrpc.enabled != false">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.clientName')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.clientName')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<select class="md-select" v-model="app.cfg.general.discord_rpc.client">
|
<select class="md-select" v-model="app.cfg.general.discordrpc.client">
|
||||||
<option value="Cider">{{$root.getLz('app.name')}}</option>
|
<option value="Cider">{{$root.getLz('app.name')}}</option>
|
||||||
<option value="AppleMusic">{{$root.getLz('term.appleMusic')}}
|
<option value="AppleMusic">{{$root.getLz('term.appleMusic')}}
|
||||||
</option>
|
</option>
|
||||||
|
@ -1033,29 +1045,29 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.general.discord_rpc.enabled != false">
|
<div class="md-option-line" v-show="app.cfg.general.discordrpc.enabled != false">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.clearOnPause')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.clearOnPause')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="app.cfg.general.discord_rpc.clear_on_pause" switch/>
|
<input type="checkbox" v-model="app.cfg.general.discordrpc.clear_on_pause" switch/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.general.discord_rpc.enabled != false">
|
<div class="md-option-line" v-show="app.cfg.general.discordrpc.enabled != false">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.hideButtons')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.hideButtons')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="app.cfg.general.discord_rpc.hide_buttons" switch/>
|
<input type="checkbox" v-model="app.cfg.general.discordrpc.hide_buttons" switch/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.general.discord_rpc.enabled != false">
|
<div class="md-option-line" v-show="app.cfg.general.discordrpc.enabled != false">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.detailsFormat')}}<br/>
|
{{$root.getLz('settings.option.connectivity.discordRPC.detailsFormat')}}<br/>
|
||||||
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title}, {album},
|
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title}, {album},
|
||||||
|
@ -1063,12 +1075,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<input type="text" v-model="app.cfg.general.discord_rpc.details_format"/>
|
<input type="text" v-model="app.cfg.general.discordrpc.details_format"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.general.discord_rpc.enabled != false">
|
<div class="md-option-line" v-show="app.cfg.general.discordrpc.enabled != false">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.stateFormat')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.stateFormat')}}
|
||||||
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title}, {album},
|
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title}, {album},
|
||||||
|
@ -1076,7 +1088,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<input type="text" v-model="app.cfg.general.discord_rpc.state_format"/>
|
<input type="text" v-model="app.cfg.general.discordrpc.state_format"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1192,19 +1204,6 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line">
|
|
||||||
<!-- Do not translate -->
|
|
||||||
<div class="md-option-segment">
|
|
||||||
Style Editor<br>
|
|
||||||
<small>Mix and match various theme components to get Cider looking exactly how you
|
|
||||||
want.</small>
|
|
||||||
</div>
|
|
||||||
<div class="md-option-segment">
|
|
||||||
<stylestack-editor :themes="themes"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.experimental.unknownPlugin')}}
|
{{$root.getLz('settings.option.experimental.unknownPlugin')}}
|
||||||
|
@ -1412,112 +1411,6 @@
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
|
||||||
// do not translate
|
|
||||||
Vue.component('stylestack-editor', {
|
|
||||||
/*html*/
|
|
||||||
template: `
|
|
||||||
<div class="stylestack-editor">
|
|
||||||
<draggable class="list-group" v-model="$root.cfg.visual.styles" @end="$root.reloadStyles()">
|
|
||||||
<b-list-group-item variant="dark" v-for="theme in $root.cfg.visual.styles" :key="theme">
|
|
||||||
<b-row>
|
|
||||||
<b-col class="themeLabel">{{getThemeName(theme)}}</b-col>
|
|
||||||
<b-col sm="auto">
|
|
||||||
<button class="removeItem codicon codicon-close" @click="remove(theme)"></button>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</b-list-group-item>
|
|
||||||
<b-list-group-item slot="footer" style="-webkit-user-drag: none" variant="dark">
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-dropdown class="stylesDropdown" variant="primary" text="Add Style...">
|
|
||||||
<b-dropdown-item v-for="theme in themeList" @click="addStyle(theme.file)">{{theme.name}}</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
</b-col>
|
|
||||||
<b-col>
|
|
||||||
<b-btn @click="gitHubExplore()">{{$root.getLz('settings.option.visual.theme.github.explore')}}</b-btn>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</b-list-group-item>
|
|
||||||
</draggable>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
props: {
|
|
||||||
themes: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function () {
|
|
||||||
return {
|
|
||||||
selected: null,
|
|
||||||
newTheme: null,
|
|
||||||
themeList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.themeList = [...this.themes]
|
|
||||||
this.themeList.unshift({
|
|
||||||
name: "Acrylic Grain",
|
|
||||||
file: "grain.less"
|
|
||||||
})
|
|
||||||
this.themeList.unshift({
|
|
||||||
name: "Sweetener",
|
|
||||||
file: "sweetener.less"
|
|
||||||
})
|
|
||||||
this.themeList.unshift({
|
|
||||||
name: "Reduce Visuals",
|
|
||||||
file: "reduce_visuals.less"
|
|
||||||
})
|
|
||||||
this.themeList.unshift({
|
|
||||||
name: "Inline Drawer",
|
|
||||||
file: "inline_drawer.less"
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
gitHubExplore() {
|
|
||||||
this.$root.appRoute("themes-github")
|
|
||||||
},
|
|
||||||
getThemeName(filename) {
|
|
||||||
try {
|
|
||||||
return this.themeList.find(theme => theme.file === filename).name;
|
|
||||||
} catch (e) {
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
moveUp() {
|
|
||||||
const styles = this.$root.cfg.visual.styles
|
|
||||||
const index = styles.indexOf(this.selected)
|
|
||||||
if (index > 0) {
|
|
||||||
styles.splice(index, 1)
|
|
||||||
styles.splice(index - 1, 0, this.selected)
|
|
||||||
}
|
|
||||||
this.$root.reloadStyles()
|
|
||||||
},
|
|
||||||
moveDown() {
|
|
||||||
const styles = this.$root.cfg.visual.styles
|
|
||||||
const index = styles.indexOf(this.selected)
|
|
||||||
if (index < styles.length - 1) {
|
|
||||||
styles.splice(index, 1)
|
|
||||||
styles.splice(index + 1, 0, this.selected)
|
|
||||||
}
|
|
||||||
this.$root.reloadStyles()
|
|
||||||
},
|
|
||||||
remove(style) {
|
|
||||||
const styles = this.$root.cfg.visual.styles
|
|
||||||
const index = styles.indexOf(style)
|
|
||||||
styles.splice(index, 1)
|
|
||||||
this.$root.reloadStyles()
|
|
||||||
},
|
|
||||||
addStyle(style) {
|
|
||||||
const styles = this.$root.cfg.visual.styles
|
|
||||||
styles.push(style)
|
|
||||||
this.$root.reloadStyles()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
Vue.component('cider-settings', {
|
Vue.component('cider-settings', {
|
||||||
template: "#cider-settings",
|
template: "#cider-settings",
|
||||||
|
@ -1542,7 +1435,7 @@
|
||||||
this.tabIndex = parseInt(window.location.hash.split("/")[1])
|
this.tabIndex = parseInt(window.location.hash.split("/")[1])
|
||||||
console.debug("tabIndex", this.tabIndex)
|
console.debug("tabIndex", this.tabIndex)
|
||||||
this.canChangeHash = true
|
this.canChangeHash = true
|
||||||
}else{
|
} else {
|
||||||
this.canChangeHash = true
|
this.canChangeHash = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1629,10 +1522,10 @@
|
||||||
app.cfg.general.keybindings.browse = [app.platform == "darwin" ? "Command" : "Control", "B"];
|
app.cfg.general.keybindings.browse = [app.platform == "darwin" ? "Command" : "Control", "B"];
|
||||||
app.cfg.general.keybindings.togglePrivateSession = [app.platform == "darwin" ? "Command" : "Control", "P"];
|
app.cfg.general.keybindings.togglePrivateSession = [app.platform == "darwin" ? "Command" : "Control", "P"];
|
||||||
app.cfg.general.keybindings.webRemote = [app.platform == "darwin" ? "Command" : "Control", "W"];
|
app.cfg.general.keybindings.webRemote = [app.platform == "darwin" ? "Command" : "Control", "W"];
|
||||||
app.cfg.general.keybindings.audioSettings = [app.platform == "darwin" ? "Option" : "Shift", "A"];
|
app.cfg.general.keybindings.audioSettings = [app.platform == "darwin" ? "Option" : "Alt", "A"];
|
||||||
app.cfg.general.keybindings.pluginMenu = [app.platform == "darwin" ? "Option" : "Shift", "P"];
|
app.cfg.general.keybindings.pluginMenu = [app.platform == "darwin" ? "Option" : "Alt", "P"];
|
||||||
app.cfg.general.keybindings.castToDevices = [app.platform == "darwin" ? "Option" : "Shift", "C"];
|
app.cfg.general.keybindings.castToDevices = [app.platform == "darwin" ? "Option" : "Alt", "C"];
|
||||||
app.cfg.general.keybindings.settings = [app.platform == "darwin" ? "Option" : "Shift", "S"];
|
app.cfg.general.keybindings.settings = [app.platform == "darwin" ? "Option" : "Alt", "S"];
|
||||||
app.cfg.general.keybindings.openDeveloperTools = [app.platform == "darwin" ? "Command" : "Control", app.platform == "darwin" ? "Option" : "Shift", "I"];
|
app.cfg.general.keybindings.openDeveloperTools = [app.platform == "darwin" ? "Command" : "Control", app.platform == "darwin" ? "Option" : "Shift", "I"];
|
||||||
notyf.success(app.getLz('settings.notyf.general.keybindings.update.success'));
|
notyf.success(app.getLz('settings.notyf.general.keybindings.update.success'));
|
||||||
bootbox.confirm(app.getLz("settings.prompt.general.keybindings.update.success"), (ok) => {
|
bootbox.confirm(app.getLz("settings.prompt.general.keybindings.update.success"), (ok) => {
|
||||||
|
|
|
@ -5,17 +5,14 @@
|
||||||
<div class="col nopadding">
|
<div class="col nopadding">
|
||||||
<h1 class="header-text">{{$root.getLz('settings.header.visual.theme.github.page')}}</h1>
|
<h1 class="header-text">{{$root.getLz('settings.header.visual.theme.github.page')}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto nopadding flex-center">
|
||||||
<select class="md-select" @change="$root.setTheme($root.cfg.visual.theme)"
|
<button class="md-btn md-btn-small md-btn-block" @click="$root.appRoute('installed-themes')">
|
||||||
v-model="$root.cfg.visual.theme">
|
{{$root.getLz('settings.option.visual.theme.manageStyles')}}
|
||||||
<option value="default.less">{{$root.getLz('settings.option.visual.theme.default')}}</option>
|
</button>
|
||||||
<option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}</option>
|
|
||||||
<option v-for="theme in themes" :value="theme.file">{{ theme.name }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<button class="md-btn md-btn-small md-btn-block" @click="openThemesFolder()">
|
<button class="md-btn md-btn-small md-btn-block" @click="$root.checkForThemeUpdates()">
|
||||||
{{$root.getLz('settings.option.visual.theme.github.openfolder')}}
|
{{ $root.getLz('settings.option.visual.theme.checkForUpdates') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto nopadding flex-center">
|
<div class="col-auto nopadding flex-center">
|
||||||
|
@ -106,7 +103,6 @@
|
||||||
this.themes = ipcRenderer.sendSync("get-themes")
|
this.themes = ipcRenderer.sendSync("get-themes")
|
||||||
this.getRepos();
|
this.getRepos();
|
||||||
this.getInstalledThemes();
|
this.getInstalledThemes();
|
||||||
app.checkForThemeUpdates()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openThemesFolder() {
|
openThemesFolder() {
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
return "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"
|
return "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"
|
||||||
}
|
}
|
||||||
height = parseInt(height * window.devicePixelRatio)
|
height = parseInt(height * window.devicePixelRatio)
|
||||||
if(width) {
|
if (width) {
|
||||||
width = parseInt(width * window.devicePixelRatio)
|
width = parseInt(width * window.devicePixelRatio)
|
||||||
}
|
}
|
||||||
let newurl = `${url.replace('{w}', width ?? height).replace('{h}', height).replace('{f}', "webp").replace('{c}', ((width === 900) ? "sr" : "cc"))}`;
|
let newurl = `${url.replace('{w}', width ?? height).replace('{h}', height).replace('{f}', "webp").replace('{c}', ((width === 900) ? "sr" : "cc"))}`;
|
||||||
|
|
|
@ -86,14 +86,14 @@
|
||||||
|
|
||||||
if (luma > 140) {
|
if (luma > 140) {
|
||||||
return "#aaaaaa"
|
return "#aaaaaa"
|
||||||
}else{
|
} else {
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
getSubtitle() {
|
getSubtitle() {
|
||||||
if(this.kind == 'card') {
|
if (this.kind == 'card') {
|
||||||
try {
|
try {
|
||||||
if (typeof this.item.attributes.artistNames != "undefined") {
|
if (typeof this.item.attributes.artistNames != "undefined") {
|
||||||
return this.item.attributes.artistNames
|
return this.item.attributes.artistNames
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
}catch(e) {
|
}catch(e) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
if (typeof this.item.attributes.artistName != "undefined") {
|
if (typeof this.item.attributes.artistName != "undefined") {
|
||||||
return this.item.attributes.artistName
|
return this.item.attributes.artistName
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getSubtitleNavigation() {
|
getSubtitleNavigation() {
|
||||||
if(this.kind == 'card') {
|
if (this.kind == 'card') {
|
||||||
try {
|
try {
|
||||||
if (typeof this.item.attributes.artistNames != "undefined") {
|
if (typeof this.item.attributes.artistNames != "undefined") {
|
||||||
return app.routeView(this.item)
|
return app.routeView(this.item)
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
}catch(e) {
|
}catch(e) {
|
||||||
return app.routeView(this.item)
|
return app.routeView(this.item)
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
if (typeof this.item.attributes.artistName != "undefined") {
|
if (typeof this.item.attributes.artistName != "undefined") {
|
||||||
return app.searchAndNavigate(this.item,'artist')
|
return app.searchAndNavigate(this.item,'artist')
|
||||||
} else {
|
} else {
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
},
|
},
|
||||||
getArtworkUrl(size = -1, includeUrl = false) {
|
getArtworkUrl(size = -1, includeUrl = false) {
|
||||||
let artwork = this.item.attributes.artwork ? this.item.attributes.artwork.url : ''
|
let artwork = this.item.attributes.artwork ? this.item.attributes.artwork.url : ''
|
||||||
if(size != -1) {
|
if (size != -1) {
|
||||||
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', ((size === 900) ? "sr" : "cc"))
|
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', ((size === 900) ? "sr" : "cc"))
|
||||||
}
|
}
|
||||||
switch (this.kind) {
|
switch (this.kind) {
|
||||||
|
@ -208,9 +208,9 @@
|
||||||
artwork = this.item.attributes.editorialArtwork.subscriptionHero.url
|
artwork = this.item.attributes.editorialArtwork.subscriptionHero.url
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!includeUrl) {
|
if (!includeUrl) {
|
||||||
return artwork
|
return artwork
|
||||||
}else{
|
} else {
|
||||||
return `url("${artwork}")`
|
return `url("${artwork}")`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -423,10 +423,10 @@
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.isInLibrary().then((_) => {
|
await this.isInLibrary().then((_) => {
|
||||||
if(self.addedToLibrary) {
|
if (self.addedToLibrary) {
|
||||||
menus.normal.items.find(x => x.id == 'addToLibrary').hidden = true
|
menus.normal.items.find(x => x.id == 'addToLibrary').hidden = true
|
||||||
menus.normal.items.find(x => x.id == 'removeFromLibrary').hidden = false
|
menus.normal.items.find(x => x.id == 'removeFromLibrary').hidden = false
|
||||||
}else{
|
} else {
|
||||||
menus.normal.items.find(x => x.id == 'addToLibrary').disabled = false
|
menus.normal.items.find(x => x.id == 'addToLibrary').disabled = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"electronVersion": "18.0.4",
|
"electronVersion": "18.2.0",
|
||||||
"electronDownload": {
|
"electronDownload": {
|
||||||
"version": "18.0.4+wvcus",
|
"version": "18.2.0+wvcus",
|
||||||
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
|
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
|
||||||
},
|
},
|
||||||
"appId": "cider",
|
"appId": "cider",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue