Merge remote-tracking branch 'upstream/upcoming' into upcoming
This commit is contained in:
commit
870e4947a1
21 changed files with 705 additions and 111 deletions
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
// App info
|
// App info
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
|
|
||||||
|
"date.format": "${d} ${m}, ${y}",
|
||||||
|
|
||||||
// Dialogs
|
// Dialogs
|
||||||
"dialog.cancel": "Ακύρωση",
|
"dialog.cancel": "Ακύρωση",
|
||||||
"dialog.ok": "ΟΚ",
|
"dialog.ok": "ΟΚ",
|
||||||
|
@ -9,8 +12,8 @@
|
||||||
"notification.updatingLibrarySongs": "Ενημέρωση βιβλιοθήκης τραγουδιών...",
|
"notification.updatingLibrarySongs": "Ενημέρωση βιβλιοθήκης τραγουδιών...",
|
||||||
"notification.updatingLibraryAlbums": "Ενημέρωση βιβλιοθήκης άλμπουμ...",
|
"notification.updatingLibraryAlbums": "Ενημέρωση βιβλιοθήκης άλμπουμ...",
|
||||||
"notification.updatingLibraryArtists": "Ενημέρωση βιβλιοθήκης καλλιτεχνών...",
|
"notification.updatingLibraryArtists": "Ενημέρωση βιβλιοθήκης καλλιτεχνών...",
|
||||||
|
|
||||||
// Terms
|
// Terms
|
||||||
|
"term.appleInc": "Apple Inc.",
|
||||||
"term.appleMusic": "Apple Music",
|
"term.appleMusic": "Apple Music",
|
||||||
"term.applePodcasts": "Apple Podcasts",
|
"term.applePodcasts": "Apple Podcasts",
|
||||||
"term.itunes": "iTunes",
|
"term.itunes": "iTunes",
|
||||||
|
@ -60,6 +63,7 @@
|
||||||
"term.viewAs": "Προβολή Ως",
|
"term.viewAs": "Προβολή Ως",
|
||||||
"term.viewAs.coverArt": "Εξώφυλλο",
|
"term.viewAs.coverArt": "Εξώφυλλο",
|
||||||
"term.viewAs.list": "Λίστα",
|
"term.viewAs.list": "Λίστα",
|
||||||
|
"term.size": "Μέγεθος",
|
||||||
"term.size.normal": "Κανονικό",
|
"term.size.normal": "Κανονικό",
|
||||||
"term.size.compact": "Συμπαγή",
|
"term.size.compact": "Συμπαγή",
|
||||||
"term.enable": "Ενεργοποίηση",
|
"term.enable": "Ενεργοποίηση",
|
||||||
|
@ -67,17 +71,58 @@
|
||||||
"term.enabled": "Ενεργοποιημένο",
|
"term.enabled": "Ενεργοποιημένο",
|
||||||
"term.disabled": "Απενεργοποιημένο",
|
"term.disabled": "Απενεργοποιημένο",
|
||||||
"term.connect": "Σύνδεση",
|
"term.connect": "Σύνδεση",
|
||||||
|
"term.connecting": "Γίνεται Σύνδεση",
|
||||||
|
"term.disconnect": "Αποσύνδεση",
|
||||||
|
"term.authed": "Επικυρωμένο",
|
||||||
|
"term.confirm": "Σίγουρα;",
|
||||||
|
"term.more": "Περισσότερα",
|
||||||
|
"term.less": "Λιγότερα",
|
||||||
|
"term.showMore": "Εμφάνιση περισσότερων",
|
||||||
|
"term.showLess": "Εμφάνιση λιγότερων",
|
||||||
|
"term.topSongs" : "Κορυφαία Τραγούδια",
|
||||||
|
"term.latestReleases": "Τελευταίες Κυκλοφορίες",
|
||||||
|
"term.time.added": "Προστέθηκε",
|
||||||
|
"term.time.released": "Κυκλοφόρησε",
|
||||||
|
"term.time.updated": "Ενημερώθηκε",
|
||||||
|
"term.fullscreenView": "Πλήρης οθόνη",
|
||||||
|
"term.defaultView": "Κανονική οθόνη",
|
||||||
|
"term.spacializedAudioSetting": "Χωρική Ρύθμιση Ήχου",
|
||||||
|
"term.clearAll": "Εκκαθάριση Όλων",
|
||||||
|
"term.recentStations": "Πρόσφατοι Σταθμοί",
|
||||||
|
"term.language": "Γλώσσα",
|
||||||
|
"term.noLyrics": "Φόρτωση... / Δεν βρέθηκαν στίχοι./ Ορχηστικό.",
|
||||||
|
"term.copyright": "Copyright",
|
||||||
|
"term.rightsReserved": "Όλα τα δικαιώματα διατηρούνται.",
|
||||||
|
"term.sponsor": "Χορήγησε αυτό το έργο",
|
||||||
|
"term.ciderTeam": "Ομάδα Cider",
|
||||||
|
"term.developer": "Προγραμματιστής",
|
||||||
|
"term.socialTeam": "Κοινωνική Ομάδα",
|
||||||
|
"term.contributors": "Συνεισφέροντες",
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
"home.title": "Αρχική",
|
"home.title": "Αρχική",
|
||||||
"home.recentlyPlayed": "Έπαιξαν Πρόσφατα",
|
"home.recentlyPlayed": "Έπαιξαν Πρόσφατα",
|
||||||
"home.recentlyAdded": "Πρόσφατες Προσθήκες",
|
"home.recentlyAdded": "Πρόσφατες Προσθήκες",
|
||||||
"home.artistsFeed": "Ροή των Καλλιτεχνών σου",
|
"home.artistsFeed": "Ροή των Καλλιτεχνών σου",
|
||||||
|
"home.artistsFeed.noArtist": "Ακολούθησε μερικούς καλλιτέχνες πρώτα και οι τελευταίες κυκλοφορίες τους θα εμφανίζονται εδώ",
|
||||||
"home.madeForYou": "Δημιουργήθηκε Για Εσάς",
|
"home.madeForYou": "Δημιουργήθηκε Για Εσάς",
|
||||||
"home.friendsListeningTo": "Οι Φίλοι σου Ακούν",
|
"home.friendsListeningTo": "Οι Φίλοι σου Ακούν",
|
||||||
"home.followedArtists": "Καλλιτέχνες που Ακολουθείτε",
|
"home.followedArtists": "Καλλιτέχνες που Ακολουθείτε",
|
||||||
// Errors
|
// Errors
|
||||||
"error.appleMusicSubRequired": "Το Apple Music απαιτεί μια συνδρομή.",
|
"error.appleMusicSubRequired": "Το Apple Music απαιτεί μια συνδρομή.",
|
||||||
|
"error.connectionError": "Δεν είναι δυνατή η σύνδεση με το Apple Music.",
|
||||||
|
"error.noResults": "Κανένα αποτέλεσμα.",
|
||||||
|
"error.noResults.description": "Δοκιμάστε μια νέα αναζήτηση.",
|
||||||
|
|
||||||
|
//Podcasts
|
||||||
|
"podcast.followOnCider": "Ακολούθηση στο Cider",
|
||||||
|
"podcast.followedOnCider": "Ακολουθείτε στο Cider",
|
||||||
|
"podcast.subscribeOnItunes": "Συνδρομή στο iTunes",
|
||||||
|
"podcast.subscribedOnItunes": "Συνδρομητής στο iTunes",
|
||||||
|
"podcast.itunesStore": "iTunes Store",
|
||||||
|
"podcast.episodes": "Επεισόδια",
|
||||||
|
"podcast.playEpisode": "Αναπαραγωγή Επεισοδίου",
|
||||||
|
"podcast.website": "Ιστότοπος Podcast",
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
"action.addToLibrary": "Προσθήκη στη Βιβλιοθήκη",
|
"action.addToLibrary": "Προσθήκη στη Βιβλιοθήκη",
|
||||||
|
@ -92,6 +137,7 @@
|
||||||
"action.removeFromQueue.success": "Αφαιρέθηκε από την Ουρά",
|
"action.removeFromQueue.success": "Αφαιρέθηκε από την Ουρά",
|
||||||
"action.removeFromQueue.error": "Σφάλμα Αφαίρεσης από την Ουρά",
|
"action.removeFromQueue.error": "Σφάλμα Αφαίρεσης από την Ουρά",
|
||||||
"action.addToPlaylist": "Προσθήκη σε Λίστα",
|
"action.addToPlaylist": "Προσθήκη σε Λίστα",
|
||||||
|
"action.removeFromPlaylist": "Αφαίρεση από Λίστα",
|
||||||
"action.addToFavorites": "Προσθήκη στα Αγαπημένα",
|
"action.addToFavorites": "Προσθήκη στα Αγαπημένα",
|
||||||
"action.follow": "Ακολούθηση",
|
"action.follow": "Ακολούθηση",
|
||||||
"action.follow.success": "Ακολουθήθηκε",
|
"action.follow.success": "Ακολουθήθηκε",
|
||||||
|
@ -112,6 +158,7 @@
|
||||||
"action.dislike": "Δεν μου αρέσει",
|
"action.dislike": "Δεν μου αρέσει",
|
||||||
"action.undoDislike": "Αναίρεση \"Δεν μου αρέσει\"",
|
"action.undoDislike": "Αναίρεση \"Δεν μου αρέσει\"",
|
||||||
"action.showWebRemoteQR": "Εμφάνιση Web Remote QR",
|
"action.showWebRemoteQR": "Εμφάνιση Web Remote QR",
|
||||||
|
|
||||||
// Settings - Audio
|
// Settings - Audio
|
||||||
"settings.header.audio": "Ήχος",
|
"settings.header.audio": "Ήχος",
|
||||||
"settings.header.audio.description": "Προσαρμογή ρυθμίσεων ήχου για το Cider.",
|
"settings.header.audio.description": "Προσαρμογή ρυθμίσεων ήχου για το Cider.",
|
||||||
|
@ -140,9 +187,11 @@
|
||||||
"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": "Υψηλή",
|
||||||
"settings.header.visual.animatedArtworkQuality.extreme": "Πολύ Υψηλή",
|
"settings.header.visual.animatedArtworkQuality.veryHigh": "Πολύ Υψηλή",
|
||||||
|
"settings.header.visual.animatedArtworkQuality.extreme": "Ακραία",
|
||||||
"settings.option.visual.animatedWindowBackground": "Κινούμενο Φόντο Παραθύρου", // Toggle
|
"settings.option.visual.animatedWindowBackground": "Κινούμενο Φόντο Παραθύρου", // Toggle
|
||||||
"settings.option.visual.hardwareAcceleration": "Επιτάχυνση Υλικού", // Dropdown
|
"settings.option.visual.hardwareAcceleration": "Επιτάχυνση Υλικού", // Dropdown
|
||||||
|
"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",
|
||||||
// Refer to term.disabled for the disabled option
|
// Refer to term.disabled for the disabled option
|
||||||
|
@ -168,6 +217,9 @@
|
||||||
"settings.header.connectivity.discordRPC.appleMusic": "Εμφάνιση ως 'Apple Music'",
|
"settings.header.connectivity.discordRPC.appleMusic": "Εμφάνιση ως 'Apple Music'",
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "Εκκαθάριση του Discord Rich Presence στην Παύση", // Toggle
|
"settings.option.connectivity.discordRPC.clearOnPause": "Εκκαθάριση του Discord Rich Presence στην Παύση", // Toggle
|
||||||
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect
|
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect
|
||||||
|
"settings.option.connectivity.lastfmScrobble.delay": "Καθυστέρηση LastFM Scrobble (%)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Ενεργοποίηση LastFM \"Now Playing\"",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Αφαίρεση καλλιτεχνών feature από τον τίτλο του τραγουδιού (LastFM)",
|
||||||
// Refer to term.connect for the connect button
|
// Refer to term.connect for the connect button
|
||||||
|
|
||||||
// Settings - Experimental
|
// Settings - Experimental
|
||||||
|
@ -176,7 +228,32 @@
|
||||||
"settings.option.experimental.compactUI": "Συμπαγής Διεπαφή", // Toggle
|
"settings.option.experimental.compactUI": "Συμπαγής Διεπαφή", // Toggle
|
||||||
// Refer to term.disabled & term.enabled
|
// Refer to term.disabled & term.enabled
|
||||||
|
|
||||||
|
// Spatialization Menu
|
||||||
|
"spatial.spatialProperties" : "Χωρικές Ιδιότητες",
|
||||||
|
"spatial.width" : "Πλάτος",
|
||||||
|
"spatial.height" : "Ύψος",
|
||||||
|
"spatial.depth" : "Βάθος",
|
||||||
|
"spatial.roomMaterials" : "Υλικά Δωματίου",
|
||||||
|
"spatial.roomDimensions" : "Διαστάσεις Δωματίου",
|
||||||
|
"spatial.roomPositions" : "Θέσεις Δωματίου",
|
||||||
|
"spatial.setDimensions" : "Ορισμός Διαστάσεων",
|
||||||
|
"spatial.setPositions" : "Ορισμός Θέσεων",
|
||||||
|
"spatial.up" : "Πάνω",
|
||||||
|
"spatial.front" : "Πρόσοψη",
|
||||||
|
"spatial.left" : "Αριστερά",
|
||||||
|
"spatial.right" : "Δεξιά",
|
||||||
|
"spatial.back" : "Πίσω Όψη",
|
||||||
|
"spatial.down" : "Κάτω",
|
||||||
|
"spatial.listener" : "Ακροατής",
|
||||||
|
"spatial.audioSource" : "Πηγή Ήχου",
|
||||||
|
|
||||||
|
// Settings - Unfinished
|
||||||
|
"settings.header.unfinished": "Ημιτελής",
|
||||||
|
|
||||||
// Web Remote
|
// Web Remote
|
||||||
"remote.web.title": "Cider Remote",
|
"remote.web.title": "Cider Remote",
|
||||||
"remote.web.description": "Σαρώστε τον κωδικό QR για σύζευξη του Cider με το κινητό σας"
|
"remote.web.description": "Σαρώστε τον κωδικό QR για σύζευξη του Cider με το κινητό σας",
|
||||||
|
|
||||||
|
//About
|
||||||
|
"about.thanks": "Μεγάλα ευχαριστώ στην Ομάδα Cider Collective και σε όλους τους συνεισφέροντές μας."
|
||||||
}
|
}
|
|
@ -98,6 +98,8 @@
|
||||||
"term.developer": "Developer",
|
"term.developer": "Developer",
|
||||||
"term.socialTeam": "Social Team",
|
"term.socialTeam": "Social Team",
|
||||||
"term.contributors": "Contributors",
|
"term.contributors": "Contributors",
|
||||||
|
"term.equalizer": "Equalizer",
|
||||||
|
"term.reset": "Reset",
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
"home.title": "Home",
|
"home.title": "Home",
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
"term.search": "Procurar",
|
"term.search": "Procurar",
|
||||||
"term.library": "Biblioteca",
|
"term.library": "Biblioteca",
|
||||||
"term.listenNow": "Ouça Agora",
|
"term.listenNow": "Ouça Agora",
|
||||||
"term.browse": "Pesquisar",
|
"term.browse": "Explorar",
|
||||||
"term.radio": "Radio",
|
"term.radio": "Radio",
|
||||||
"term.recentlyAdded": "Adicionado Recentemente",
|
"term.recentlyAdded": "Adicionado Recentemente",
|
||||||
"term.songs": "Músicas",
|
"term.songs": "Músicas",
|
||||||
|
@ -72,6 +72,8 @@
|
||||||
"term.enabled": "Ativado",
|
"term.enabled": "Ativado",
|
||||||
"term.disabled": "Desativado",
|
"term.disabled": "Desativado",
|
||||||
"term.connect": "Conectar",
|
"term.connect": "Conectar",
|
||||||
|
"term.disconnect": "Desconectar",
|
||||||
|
"term.connecting": "Conectando",
|
||||||
"term.confirm": "Confirmar ?",
|
"term.confirm": "Confirmar ?",
|
||||||
"term.more": "Mais",
|
"term.more": "Mais",
|
||||||
"term.less": "Menos",
|
"term.less": "Menos",
|
||||||
|
@ -86,6 +88,8 @@
|
||||||
"term.defaultView": "Visualização Normal",
|
"term.defaultView": "Visualização Normal",
|
||||||
"term.spacializedAudioSetting": "Definições de Audio Espacial",
|
"term.spacializedAudioSetting": "Definições de Audio Espacial",
|
||||||
"term.clearAll": "Limpar Tudo",
|
"term.clearAll": "Limpar Tudo",
|
||||||
|
"term.language": "Idioma",
|
||||||
|
"term.recentStations": "Estações Recentes",
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
"home.title": "Inicio",
|
"home.title": "Inicio",
|
||||||
|
@ -160,11 +164,15 @@
|
||||||
"settings.header.visual.animatedArtworkQuality.low": "Baixa",
|
"settings.header.visual.animatedArtworkQuality.low": "Baixa",
|
||||||
"settings.header.visual.animatedArtworkQuality.medium": "Media",
|
"settings.header.visual.animatedArtworkQuality.medium": "Media",
|
||||||
"settings.header.visual.animatedArtworkQuality.high": "Alta",
|
"settings.header.visual.animatedArtworkQuality.high": "Alta",
|
||||||
|
"settings.header.visual.animatedArtworkQuality.veryHigh": "Muito Alta",
|
||||||
"settings.header.visual.animatedArtworkQuality.extreme": "Extrema",
|
"settings.header.visual.animatedArtworkQuality.extreme": "Extrema",
|
||||||
"settings.option.visual.animatedWindowBackground": "Fundo de Janela Animado", // Toggle
|
"settings.option.visual.animatedWindowBackground": "Fundo de Janela Animado", // Toggle
|
||||||
"settings.option.visual.hardwareAcceleration": "Acelaração no Hardware", // Dropdown
|
"settings.option.visual.hardwareAcceleration": "Acelaração no Hardware", // Dropdown
|
||||||
|
"settings.option.visual.hardwareAcceleration.description": "Necessário reiniciar a aplicação",
|
||||||
"settings.header.visual.hardwareAcceleration.default": "Normal",
|
"settings.header.visual.hardwareAcceleration.default": "Normal",
|
||||||
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
|
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
|
||||||
|
|
||||||
|
|
||||||
// Refer to term.disabled for the disabled option
|
// Refer to term.disabled for the disabled option
|
||||||
"settings.option.visual.showPersonalInfo": "Mostrar Informaçoes Pessoais", // Toggle
|
"settings.option.visual.showPersonalInfo": "Mostrar Informaçoes Pessoais", // Toggle
|
||||||
// Settings - General (Reserved)
|
// Settings - General (Reserved)
|
||||||
|
@ -186,7 +194,7 @@
|
||||||
// Refer to term.disabled for the disabled option
|
// Refer to term.disabled for the disabled option
|
||||||
"settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'",
|
"settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'",
|
||||||
"settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'",
|
"settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'",
|
||||||
"settings.header.connectivity.discordRPC.clearOnPause": "Apagar Discord Rich Presence quando estiver pausado", // Toggle
|
"settings.option.connectivity.discordRPC.clearOnPause": "Apagar Discord Rich Presence quando estiver pausado", // Toggle
|
||||||
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect
|
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect
|
||||||
"settings.option.connectivity.lastfmScrobble.delay": "Atraso dos Scrobbles do LastFM (%)",
|
"settings.option.connectivity.lastfmScrobble.delay": "Atraso dos Scrobbles do LastFM (%)",
|
||||||
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Ativar LastFM Now Playing",
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Ativar LastFM Now Playing",
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"notification.updatingLibraryAlbums": "正在更新資料庫的專輯...",
|
"notification.updatingLibraryAlbums": "正在更新資料庫的專輯...",
|
||||||
"notification.updatingLibraryArtists": "正在更新資料庫的藝人...",
|
"notification.updatingLibraryArtists": "正在更新資料庫的藝人...",
|
||||||
// Terms
|
// Terms
|
||||||
|
"term.appleInc": "Apple Inc.",
|
||||||
"term.appleMusic": "Apple Music", // Follows brand term
|
"term.appleMusic": "Apple Music", // Follows brand term
|
||||||
"term.applePodcasts": "Apple Podcasts", // Follows brand term
|
"term.applePodcasts": "Apple Podcasts", // Follows brand term
|
||||||
"term.itunes": "iTunes", // Follows brand term
|
"term.itunes": "iTunes", // Follows brand term
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
"term.login": "登入",
|
"term.login": "登入",
|
||||||
"term.about": "關於",
|
"term.about": "關於",
|
||||||
"term.privateSession": "私人模式",
|
"term.privateSession": "私人模式",
|
||||||
"term.queue": "播放清單",
|
"term.queue": "待播清單",
|
||||||
"term.search": "搜尋",
|
"term.search": "搜尋",
|
||||||
"term.library": "資料庫",
|
"term.library": "資料庫",
|
||||||
"term.listenNow": "立即聆聽",
|
"term.listenNow": "立即聆聽",
|
||||||
|
@ -70,6 +71,9 @@
|
||||||
"term.enabled": "已啟用",
|
"term.enabled": "已啟用",
|
||||||
"term.disabled": "已停用",
|
"term.disabled": "已停用",
|
||||||
"term.connect": "連結",
|
"term.connect": "連結",
|
||||||
|
"term.connecting": "連結中",
|
||||||
|
"term.disconnect": "取消連結",
|
||||||
|
"term.authed": "已授權",
|
||||||
"term.confirm": "確認?",
|
"term.confirm": "確認?",
|
||||||
"term.more": "更多",
|
"term.more": "更多",
|
||||||
"term.less": "較少",
|
"term.less": "較少",
|
||||||
|
@ -82,10 +86,18 @@
|
||||||
"term.time.updated": "更新於",
|
"term.time.updated": "更新於",
|
||||||
"term.fullscreenView": "全螢幕檢視",
|
"term.fullscreenView": "全螢幕檢視",
|
||||||
"term.defaultView": "一般檢視",
|
"term.defaultView": "一般檢視",
|
||||||
"term.spacializedAudioSetting": "音频空间化设置",
|
"term.spacializedAudioSetting": "空間音訊設定",
|
||||||
"term.clearAll": "清空",
|
"term.clearAll": "清空",
|
||||||
"term.recentStations": "最近播放的頻道",
|
"term.recentStations": "最近播放的頻道",
|
||||||
"term.language": "語言",
|
"term.language": "語言",
|
||||||
|
"term.noLyrics": "加載中... / 找不到歌詞。/ 純音樂。",
|
||||||
|
"term.copyright": "Copyright",
|
||||||
|
"term.rightsReserved": "保留一切權利。",
|
||||||
|
"term.sponsor": "贊助這個項目",
|
||||||
|
"term.ciderTeam": "Cider 團隊",
|
||||||
|
"term.developer": "開發者",
|
||||||
|
"term.socialTeam": "社交團隊",
|
||||||
|
"term.contributors": "貢獻者",
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
"home.title": "主頁",
|
"home.title": "主頁",
|
||||||
|
@ -98,21 +110,32 @@
|
||||||
"home.followedArtists": "追蹤的藝人",
|
"home.followedArtists": "追蹤的藝人",
|
||||||
// Errors
|
// Errors
|
||||||
"error.appleMusicSubRequired": "需要訂閱Apple Music以使用Cider",
|
"error.appleMusicSubRequired": "需要訂閱Apple Music以使用Cider",
|
||||||
"error.connectionError": "There was a problem connecting to Apple Music.",
|
"error.connectionError": "無法連接到 Apple Music。",
|
||||||
"error.noResults": "No Results.",
|
"error.noResults": "沒有結果",
|
||||||
"error.noResults.description": "Try a new search.",
|
"error.noResults.description": "請嘗試新的搜尋內容。",
|
||||||
|
|
||||||
|
//Podcasts
|
||||||
|
"podcast.followOnCider": "在Cider上追蹤",
|
||||||
|
"podcast.followedOnCider": "已在Cider上追蹤",
|
||||||
|
"podcast.subscribeOnItunes": "在iTunes上訂閱",
|
||||||
|
"podcast.subscribedOnItunes": "已在iTunes上訂閱",
|
||||||
|
"podcast.itunesStore": "iTunes Store",
|
||||||
|
"podcast.episodes": "單集",
|
||||||
|
"podcast.playEpisode": "播放單集",
|
||||||
|
"podcast.website": "Podcast 網頁",
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
"action.addToLibrary": "加入資料庫",
|
"action.addToLibrary": "加入資料庫",
|
||||||
"action.addToLibrary.success": "成功加入資料庫",
|
"action.addToLibrary.success": "成功加入資料庫",
|
||||||
"action.addToLibrary.error": "加入資料庫的過程發生錯誤",
|
"action.addToLibrary.error": "加入資料庫的過程發生錯誤",
|
||||||
"action.removeFromLibrary": "從資料庫刪除",
|
"action.removeFromLibrary": "從資料庫刪除",
|
||||||
"action.removeFromLibrary.success": "已從資料庫刪除",
|
"action.removeFromLibrary.success": "已從資料庫刪除",
|
||||||
"action.addToQueue": "加入播放清單",
|
"action.addToQueue": "加入待播清單",
|
||||||
"action.addToQueue.success": "成功加入播放清單",
|
"action.addToQueue.success": "成功加入待播清單",
|
||||||
"action.addToQueue.error": "加入播放清單的過程發生錯誤",
|
"action.addToQueue.error": "加入待播清單的過程發生錯誤",
|
||||||
"action.removeFromQueue": "從播放清單刪除",
|
"action.removeFromQueue": "從待播清單刪除",
|
||||||
"action.removeFromQueue.success": "已從播放清單刪除",
|
"action.removeFromQueue.success": "已從待播清單刪除",
|
||||||
"action.removeFromQueue.error": "從播放清單刪除的過程中發生錯誤",
|
"action.removeFromQueue.error": "從待播清單刪除的過程中發生錯誤",
|
||||||
"action.addToPlaylist": "加至播放列表",
|
"action.addToPlaylist": "加至播放列表",
|
||||||
"action.removeFromPlaylist": "從播放列表刪除",
|
"action.removeFromPlaylist": "從播放列表刪除",
|
||||||
"action.addToFavorites": "加至收藏",
|
"action.addToFavorites": "加至收藏",
|
||||||
|
@ -194,6 +217,9 @@
|
||||||
"settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'",
|
"settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'",
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", // Toggle
|
"settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", // Toggle
|
||||||
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect
|
"settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect
|
||||||
|
"settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延遲 (%)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 LastFM 正在播放",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (LastFM)",
|
||||||
// Refer to term.connect for the connect button
|
// Refer to term.connect for the connect button
|
||||||
|
|
||||||
// Settings - Experimental
|
// Settings - Experimental
|
||||||
|
@ -202,10 +228,32 @@
|
||||||
"settings.option.experimental.compactUI": "緊凑型 UI", // Toggle
|
"settings.option.experimental.compactUI": "緊凑型 UI", // Toggle
|
||||||
// Refer to term.disabled & term.enabled
|
// Refer to term.disabled & term.enabled
|
||||||
|
|
||||||
|
// Spatialization Menu
|
||||||
|
"spatial.spatialProperties" : "空間音訊屬性",
|
||||||
|
"spatial.width" : "闊度",
|
||||||
|
"spatial.height" : "高度",
|
||||||
|
"spatial.depth" : "深度",
|
||||||
|
"spatial.roomMaterials" : "空間材質",
|
||||||
|
"spatial.roomDimensions" : "空間大小",
|
||||||
|
"spatial.roomPositions" : "空間位置",
|
||||||
|
"spatial.setDimensions" : "大小設定",
|
||||||
|
"spatial.setPositions" : "位置設定",
|
||||||
|
"spatial.up" : "上方",
|
||||||
|
"spatial.front" : "前方",
|
||||||
|
"spatial.left" : "左方",
|
||||||
|
"spatial.right" : "右方",
|
||||||
|
"spatial.back" : "後方",
|
||||||
|
"spatial.down" : "下方",
|
||||||
|
"spatial.listener" : "觀眾",
|
||||||
|
"spatial.audioSource" : "音源",
|
||||||
|
|
||||||
// Settings - Unfinished
|
// Settings - Unfinished
|
||||||
"settings.header.unfinished": "未完成",
|
"settings.header.unfinished": "未完成",
|
||||||
|
|
||||||
// Web Remote
|
// Web Remote
|
||||||
"remote.web.title": "遙距控制 Cider",
|
"remote.web.title": "遙距控制 Cider",
|
||||||
"remote.web.description": "掃描以下的二維碼以控制 Cider",
|
"remote.web.description": "掃描以下的二維碼以控制 Cider",
|
||||||
|
|
||||||
|
//About
|
||||||
|
"about.thanks": "感謝Cider Collective團隊以及所有貢獻者所作出的貢獻。"
|
||||||
}
|
}
|
|
@ -82,7 +82,7 @@
|
||||||
"term.time.updated": "更改于",
|
"term.time.updated": "更改于",
|
||||||
"term.fullscreenView": "全螢幕顯示",
|
"term.fullscreenView": "全螢幕顯示",
|
||||||
"term.defaultView": "預設顯示",
|
"term.defaultView": "預設顯示",
|
||||||
"term.spacializedAudioSetting": "音频空间化设置",
|
"term.spacializedAudioSetting": "音頻空間化設置",
|
||||||
"term.clearAll": "清空",
|
"term.clearAll": "清空",
|
||||||
"term.recentStations": "最近收聽的廣播",
|
"term.recentStations": "最近收聽的廣播",
|
||||||
"term.language": "語言",
|
"term.language": "語言",
|
||||||
|
@ -110,9 +110,9 @@
|
||||||
"action.addToQueue": "加入待播清單",
|
"action.addToQueue": "加入待播清單",
|
||||||
"action.addToQueue.success": "成功加入待播清單",
|
"action.addToQueue.success": "成功加入待播清單",
|
||||||
"action.addToQueue.error": "加入待播清單的過程發生錯誤",
|
"action.addToQueue.error": "加入待播清單的過程發生錯誤",
|
||||||
"action.removeFromQueue": "從代播清單刪除",
|
"action.removeFromQueue": "從待播清單刪除",
|
||||||
"action.removeFromQueue.success": "已從代播清單刪除",
|
"action.removeFromQueue.success": "已從待播清單刪除",
|
||||||
"action.removeFromQueue.error": "從代播清單刪除的過程發生錯誤",
|
"action.removeFromQueue.error": "從待播清單刪除的過程發生錯誤",
|
||||||
"action.addToPlaylist": "加入播放列表",
|
"action.addToPlaylist": "加入播放列表",
|
||||||
"action.removeFromPlaylist": "從播放列表刪除",
|
"action.removeFromPlaylist": "從播放列表刪除",
|
||||||
"action.addToFavorites": "加入我的最愛",
|
"action.addToFavorites": "加入我的最愛",
|
||||||
|
|
|
@ -50,7 +50,7 @@ export class AppEvents {
|
||||||
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
||||||
* Commandline arguments
|
* Commandline arguments
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
switch (store.get("visual.hw_acceleration")) {
|
switch (store.visual.hw_acceleration) {
|
||||||
default:
|
default:
|
||||||
case "default":
|
case "default":
|
||||||
electron.app.commandLine.appendSwitch('enable-accelerated-mjpeg-decode')
|
electron.app.commandLine.appendSwitch('enable-accelerated-mjpeg-decode')
|
||||||
|
@ -75,6 +75,10 @@ export class AppEvents {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.platform === "linux") {
|
||||||
|
electron.app.commandLine.appendSwitch('disable-features', 'MediaSessionService');
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
||||||
* Protocols
|
* Protocols
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
|
@ -5,10 +5,11 @@ import * as electron from 'electron'
|
||||||
export default class PluginHandler {
|
export default class PluginHandler {
|
||||||
private basePluginsPath = path.join(__dirname, '../plugins');
|
private basePluginsPath = path.join(__dirname, '../plugins');
|
||||||
private userPluginsPath = path.join(electron.app.getPath('userData'), 'plugins');
|
private userPluginsPath = path.join(electron.app.getPath('userData'), 'plugins');
|
||||||
private pluginsList: any = {};
|
private readonly pluginsList: any = {};
|
||||||
|
private readonly _store: any;
|
||||||
constructor() {
|
|
||||||
|
|
||||||
|
constructor(config: any) {
|
||||||
|
this._store = config;
|
||||||
this.pluginsList = this.getPlugins();
|
this.pluginsList = this.getPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ export default class PluginHandler {
|
||||||
if (plugins[file] || plugin.name in plugins) {
|
if (plugins[file] || plugin.name in plugins) {
|
||||||
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
|
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
|
||||||
} else {
|
} else {
|
||||||
plugins[file] = new plugin(electron.app);
|
plugins[file] = new plugin(electron.app, this._store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -38,7 +39,7 @@ export default class PluginHandler {
|
||||||
if (plugins[file] || plugin in plugins) {
|
if (plugins[file] || plugin in plugins) {
|
||||||
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
|
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
|
||||||
} else {
|
} else {
|
||||||
plugins[file] = new plugin(electron.app);
|
plugins[file] = new plugin(electron.app, this._store);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as Store from 'electron-store';
|
||||||
import * as electron from "electron";
|
import * as electron from "electron";
|
||||||
|
|
||||||
export class ConfigStore {
|
export class ConfigStore {
|
||||||
public store: Store | undefined;
|
private _store: Store;
|
||||||
|
|
||||||
private defaults: any = {
|
private defaults: any = {
|
||||||
"general": {
|
"general": {
|
||||||
|
@ -49,6 +49,18 @@ export class ConfigStore {
|
||||||
"down": 'acoustic-ceiling-tiles',
|
"down": 'acoustic-ceiling-tiles',
|
||||||
"up": 'acoustic-ceiling-tiles',
|
"up": 'acoustic-ceiling-tiles',
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"equalizer": {
|
||||||
|
'60' : 0,
|
||||||
|
'170': 0 ,
|
||||||
|
'310': 0 ,
|
||||||
|
'600': 0 ,
|
||||||
|
'1000': 0 ,
|
||||||
|
'3000': 0 ,
|
||||||
|
'6000': 0 ,
|
||||||
|
'12000': 0 ,
|
||||||
|
'14000': 0 ,
|
||||||
|
'16000': 0 ,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"visual": {
|
"visual": {
|
||||||
|
@ -84,14 +96,26 @@ export class ConfigStore {
|
||||||
private migrations: any = {}
|
private migrations: any = {}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.store = new Store({
|
this._store = new Store({
|
||||||
name: 'cider-config',
|
name: 'cider-config',
|
||||||
defaults: this.defaults,
|
defaults: this.defaults,
|
||||||
migrations: this.migrations,
|
migrations: this.migrations,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.store.set(this.mergeStore(this.defaults, this.store.store))
|
this._store.set(this.mergeStore(this.defaults, this._store.store))
|
||||||
this.ipcHandler(this.store);
|
this.ipcHandler(this._store);
|
||||||
|
}
|
||||||
|
|
||||||
|
get store() {
|
||||||
|
return this._store.store;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key: string) {
|
||||||
|
return this._store.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: string, value: any) {
|
||||||
|
this._store.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,10 +15,10 @@ import {wsapi} from "./wsapi";
|
||||||
import * as jsonc from "jsonc";
|
import * as jsonc from "jsonc";
|
||||||
|
|
||||||
export class Win {
|
export class Win {
|
||||||
win: any | undefined = null;
|
private win: any | undefined = null;
|
||||||
app: any | undefined = null;
|
private app: any | undefined = null;
|
||||||
store: any | undefined = null;
|
private store: any | undefined = null;
|
||||||
devMode: boolean = !electron.app.isPackaged;
|
private devMode: boolean = !electron.app.isPackaged;
|
||||||
|
|
||||||
constructor(app: electron.App, store: any) {
|
constructor(app: electron.App, store: any) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import PluginHandler from "./base/plugins";
|
||||||
const config = new ConfigStore();
|
const config = new ConfigStore();
|
||||||
const App = new AppEvents(config.store);
|
const App = new AppEvents(config.store);
|
||||||
const Cider = new Win(electron.app, config.store)
|
const Cider = new Win(electron.app, config.store)
|
||||||
const plug = new PluginHandler();
|
const plug = new PluginHandler(config.store);
|
||||||
|
|
||||||
let win: Electron.BrowserWindow;
|
let win: Electron.BrowserWindow;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ electron.app.on('ready', () => {
|
||||||
win = await Cider.createWindow()
|
win = await Cider.createWindow()
|
||||||
App.bwCreated(win);
|
App.bwCreated(win);
|
||||||
/// please dont change this for plugins to get proper and fully initialized Win objects
|
/// please dont change this for plugins to get proper and fully initialized Win objects
|
||||||
plug.callPlugins('onReady', Cider);
|
plug.callPlugins('onReady', win);
|
||||||
win.on("ready-to-show", () => {
|
win.on("ready-to-show", () => {
|
||||||
win.show();
|
win.show();
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ export default class ExamplePlugin {
|
||||||
*/
|
*/
|
||||||
private _win: any;
|
private _win: any;
|
||||||
private _app: any;
|
private _app: any;
|
||||||
|
private _store: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
||||||
|
@ -17,8 +18,9 @@ export default class ExamplePlugin {
|
||||||
/**
|
/**
|
||||||
* Runs on plugin load (Currently run on application start)
|
* Runs on plugin load (Currently run on application start)
|
||||||
*/
|
*/
|
||||||
constructor(app: any) {
|
constructor(app: any, store: any) {
|
||||||
this._app = app;
|
this._app = app;
|
||||||
|
this._store = store;
|
||||||
console.log('Example plugin loaded');
|
console.log('Example plugin loaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
import * as electron from 'electron';
|
|
||||||
import * as DiscordRPC from 'discord-rpc'
|
import * as DiscordRPC from 'discord-rpc'
|
||||||
|
|
||||||
export default class DiscordRPCPlugin {
|
export default class DiscordRPCPlugin {
|
||||||
/**
|
/**
|
||||||
* Private variables for interaction in plugins
|
* Private variables for interaction in plugins
|
||||||
*/
|
*/
|
||||||
private _win: any;
|
private _win: Electron.BrowserWindow | undefined;
|
||||||
private _app: any;
|
private _app: any;
|
||||||
|
private _store: any;
|
||||||
private _discord: any;
|
private _discord: any;
|
||||||
|
|
||||||
private connect(clientId: any) {
|
private connect(clientId: any) {
|
||||||
this._discord = {isConnected: false};
|
this._discord = {isConnected: false};
|
||||||
if (this._win.store.store.general.discord_rpc == 0 || this._discord.isConnected) return;
|
if (this._store.general.discord_rpc == 0 || this._discord.isConnected) return;
|
||||||
|
|
||||||
DiscordRPC.register(clientId) // Apparently needed for ask to join, join, spectate etc.
|
DiscordRPC.register(clientId) // Apparently needed for ask to join, join, spectate etc.
|
||||||
const client = new DiscordRPC.Client({transport: "ipc"});
|
const client = new DiscordRPC.Client({transport: "ipc"});
|
||||||
|
@ -38,7 +40,7 @@ export default class DiscordRPCPlugin {
|
||||||
* Disconnects from Discord RPC
|
* Disconnects from Discord RPC
|
||||||
*/
|
*/
|
||||||
private disconnect() {
|
private disconnect() {
|
||||||
if (this._win.store.store.general.discord_rpc == 0 || !this._discord.isConnected) return;
|
if (this._store.general.discord_rpc == 0 || !this._discord.isConnected) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this._discord.destroy().then(() => {
|
this._discord.destroy().then(() => {
|
||||||
|
@ -55,7 +57,7 @@ export default class DiscordRPCPlugin {
|
||||||
* @param {object} attributes
|
* @param {object} attributes
|
||||||
*/
|
*/
|
||||||
private updateActivity(attributes: any) {
|
private updateActivity(attributes: any) {
|
||||||
if (this._win.store.store.general.discord_rpc == 0) return;
|
if (this._store.general.discord_rpc == 0) return;
|
||||||
|
|
||||||
if (!this._discord.isConnected) {
|
if (!this._discord.isConnected) {
|
||||||
this._discord.clearActivity().catch((e: any) => console.error(`[DiscordRPC][updateActivity] ${e}`));
|
this._discord.clearActivity().catch((e: any) => console.error(`[DiscordRPC][updateActivity] ${e}`));
|
||||||
|
@ -67,7 +69,7 @@ export default class DiscordRPCPlugin {
|
||||||
const listenURL = `https://cider.sh/p?s&id=${attributes.playParams.id}` // cider://play/s/[id] (for song)
|
const listenURL = `https://cider.sh/p?s&id=${attributes.playParams.id}` // cider://play/s/[id] (for song)
|
||||||
//console.log(attributes)
|
//console.log(attributes)
|
||||||
|
|
||||||
interface ActObject {
|
interface ActObject extends DiscordRPC.Presence {
|
||||||
details?: any,
|
details?: any,
|
||||||
state?: any,
|
state?: any,
|
||||||
startTimestamp?: any,
|
startTimestamp?: any,
|
||||||
|
@ -78,7 +80,10 @@ export default class DiscordRPCPlugin {
|
||||||
smallImageText?: any,
|
smallImageText?: any,
|
||||||
instance: true,
|
instance: true,
|
||||||
buttons?: [
|
buttons?: [
|
||||||
{ label: "Listen on Cider", url?: any },
|
{
|
||||||
|
label: string,
|
||||||
|
url: string
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,11 +102,11 @@ export default class DiscordRPCPlugin {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
if (ActivityObject.largeImageKey == "" || ActivityObject.largeImageKey == null) {
|
if (ActivityObject.largeImageKey == "" || ActivityObject.largeImageKey == null) {
|
||||||
ActivityObject.largeImageKey = (this._win.store.store.general.discord_rpc == 1) ? "cider" : "logo"
|
ActivityObject.largeImageKey = (this._store.general.discord_rpc == 1) ? "cider" : "logo"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the pause/play icon and test for clear activity on pause
|
// Remove the pause/play icon and test for clear activity on pause
|
||||||
if (this._win.store.store.general.discordClearActivityOnPause == 1) {
|
if (this._store.general.discordClearActivityOnPause == 1) {
|
||||||
delete ActivityObject.smallImageKey
|
delete ActivityObject.smallImageKey
|
||||||
delete ActivityObject.smallImageText
|
delete ActivityObject.smallImageText
|
||||||
}
|
}
|
||||||
|
@ -128,11 +133,9 @@ export default class DiscordRPCPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Check if its pausing (false) or playing (true)
|
// Check if its pausing (false) or playing (true)
|
||||||
if (!attributes.status) {
|
if (!attributes.status) {
|
||||||
if (this._win.store.store.general.discordClearActivityOnPause == 1) {
|
if (this._store.general.discordClearActivityOnPause == 1) {
|
||||||
this._discord.clearActivity().catch((e: any) => console.error(`[DiscordRPC][clearActivity] ${e}`));
|
this._discord.clearActivity().catch((e: any) => console.error(`[DiscordRPC][clearActivity] ${e}`));
|
||||||
ActivityObject = null
|
ActivityObject = null
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,8 +171,9 @@ export default class DiscordRPCPlugin {
|
||||||
/**
|
/**
|
||||||
* Runs on plugin load (Currently run on application start)
|
* Runs on plugin load (Currently run on application start)
|
||||||
*/
|
*/
|
||||||
constructor(app: any) {
|
constructor(app: any, store: any) {
|
||||||
this._app = app;
|
this._app = app;
|
||||||
|
this._store = store
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,7 +181,7 @@ export default class DiscordRPCPlugin {
|
||||||
*/
|
*/
|
||||||
onReady(win: any): void {
|
onReady(win: any): void {
|
||||||
this._win = win;
|
this._win = win;
|
||||||
this.connect((this._win.store.store.general.discord_rpc == 1) ? '911790844204437504' : '886578863147192350');
|
this.connect((this._store.general.discord_rpc == 1) ? '911790844204437504' : '886578863147192350');
|
||||||
// electron.ipcMain.on("forceUpdateRPC", (event, attributes : object) => {
|
// electron.ipcMain.on("forceUpdateRPC", (event, attributes : object) => {
|
||||||
// this.updateActivity(attributes)
|
// this.updateActivity(attributes)
|
||||||
// });
|
// });
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import * as electron from 'electron';
|
import * as electron from 'electron';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {resolve} from 'path';
|
import {resolve} from 'path';
|
||||||
//@ts-ignore
|
|
||||||
|
|
||||||
export default class LastFMPlugin {
|
export default class LastFMPlugin {
|
||||||
private sessionPath = resolve(electron.app.getPath('userData'), 'session.json');
|
private sessionPath = resolve(electron.app.getPath('userData'), 'session.json');
|
||||||
|
@ -15,6 +14,7 @@ export default class LastFMPlugin {
|
||||||
private _win: any;
|
private _win: any;
|
||||||
private _app: any;
|
private _app: any;
|
||||||
private _lastfm: any;
|
private _lastfm: any;
|
||||||
|
private _store: any;
|
||||||
|
|
||||||
private authenticateFromFile() {
|
private authenticateFromFile() {
|
||||||
let sessionData = require(this.sessionPath)
|
let sessionData = require(this.sessionPath)
|
||||||
|
@ -26,12 +26,12 @@ export default class LastFMPlugin {
|
||||||
|
|
||||||
authenticate() {
|
authenticate() {
|
||||||
try {
|
try {
|
||||||
if (this._win.store.store.lastfm.auth_token) {
|
if (this._store.lastfm.auth_token) {
|
||||||
this._win.store.store.lastfm.enabled = true;
|
this._store.lastfm.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._win.store.store.lastfm.enabled || !this._win.store.store.lastfm.auth_token) {
|
if (!this._store.lastfm.enabled || !this._store.lastfm.auth_token) {
|
||||||
this._win.store.store.lastfm.enabled = false;
|
this._store.lastfm.enabled = false;
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/// dont move this require to top , app wont load
|
/// dont move this require to top , app wont load
|
||||||
|
@ -47,8 +47,8 @@ export default class LastFMPlugin {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err)
|
console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err)
|
||||||
console.log("[LastFM][Auth] Beginning authentication from configuration")
|
console.log("[LastFM][Auth] Beginning authentication from configuration")
|
||||||
console.log("[LastFM][tk]", this._win.store.store.lastfm.auth_token)
|
console.log("[LastFM][tk]", this._store.lastfm.auth_token)
|
||||||
this._lastfm.authenticate(this._win.store.store.lastfm.auth_token, (err: any, session: any) => {
|
this._lastfm.authenticate(this._store.lastfm.auth_token, (err: any, session: any) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ export default class LastFMPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async scrobbleSong(attributes: any) {
|
private async scrobbleSong(attributes: any) {
|
||||||
await new Promise(resolve => setTimeout(resolve, Math.round(attributes.durationInMillis * (this._win.store.store.lastfm.scrobble_after / 100))));
|
await new Promise(resolve => setTimeout(resolve, Math.round(attributes.durationInMillis * (this._store.lastfm.scrobble_after / 100))));
|
||||||
const currentAttributes = attributes;
|
const currentAttributes = attributes;
|
||||||
|
|
||||||
if (!this._lastfm || this._lastfm.cachedAttributes === attributes) {
|
if (!this._lastfm || this._lastfm.cachedAttributes === attributes) {
|
||||||
|
@ -117,7 +117,7 @@ export default class LastFMPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private filterArtistName(artist: any) {
|
private filterArtistName(artist: any) {
|
||||||
if (!this._win.store.store.lastfm.enabledRemoveFeaturingArtists) return artist;
|
if (!this._store.lastfm.enabledRemoveFeaturingArtists) return artist;
|
||||||
|
|
||||||
artist = artist.split(' ');
|
artist = artist.split(' ');
|
||||||
if (artist.includes('&')) {
|
if (artist.includes('&')) {
|
||||||
|
@ -135,7 +135,7 @@ export default class LastFMPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateNowPlayingSong(attributes: any) {
|
private updateNowPlayingSong(attributes: any) {
|
||||||
if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._win.store.store.lastfm.NowPlaying) {
|
if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._store.lastfm.NowPlaying) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +177,9 @@ export default class LastFMPlugin {
|
||||||
/**
|
/**
|
||||||
* Runs on plugin load (Currently run on application start)
|
* Runs on plugin load (Currently run on application start)
|
||||||
*/
|
*/
|
||||||
constructor(app: any) {
|
constructor(app: any, store: any) {
|
||||||
this._app = app;
|
this._app = app;
|
||||||
|
this._store = store
|
||||||
electron.app.on('second-instance', (_e: any, argv: any) => {
|
electron.app.on('second-instance', (_e: any, argv: any) => {
|
||||||
// Checks if first instance is authorized and if second instance has protocol args
|
// Checks if first instance is authorized and if second instance has protocol args
|
||||||
argv.forEach((value: any) => {
|
argv.forEach((value: any) => {
|
||||||
|
@ -187,8 +188,8 @@ export default class LastFMPlugin {
|
||||||
let authURI = String(argv).split('/auth/')[1];
|
let authURI = String(argv).split('/auth/')[1];
|
||||||
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
|
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
|
||||||
const authKey = authURI.split('lastfm?token=')[1];
|
const authKey = authURI.split('lastfm?token=')[1];
|
||||||
this._win.store.store.lastfm.enabled = true;
|
this._store.lastfm.enabled = true;
|
||||||
this._win.store.store.lastfm.auth_token = authKey;
|
this._store.lastfm.auth_token = authKey;
|
||||||
console.log(authKey);
|
console.log(authKey);
|
||||||
this._win.win.webContents.send('LastfmAuthenticated', authKey);
|
this._win.win.webContents.send('LastfmAuthenticated', authKey);
|
||||||
this.authenticate();
|
this.authenticate();
|
||||||
|
@ -203,8 +204,8 @@ export default class LastFMPlugin {
|
||||||
let authURI = String(arg).split('/auth/')[1];
|
let authURI = String(arg).split('/auth/')[1];
|
||||||
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
|
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
|
||||||
const authKey = authURI.split('lastfm?token=')[1];
|
const authKey = authURI.split('lastfm?token=')[1];
|
||||||
this._win.store.store.lastfm.enabled = true;
|
this._store.lastfm.enabled = true;
|
||||||
this._win.store.store.lastfm.auth_token = authKey;
|
this._store.lastfm.auth_token = authKey;
|
||||||
this._win.win.webContents.send('LastfmAuthenticated', authKey);
|
this._win.win.webContents.send('LastfmAuthenticated', authKey);
|
||||||
console.log(authKey);
|
console.log(authKey);
|
||||||
this.authenticate();
|
this.authenticate();
|
||||||
|
|
196
src/main/plugins/mpris.ts
Normal file
196
src/main/plugins/mpris.ts
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import * as Player from 'mpris-service';
|
||||||
|
|
||||||
|
export default class MPRIS {
|
||||||
|
/**
|
||||||
|
* Private variables for interaction in plugins
|
||||||
|
*/
|
||||||
|
private _win: any;
|
||||||
|
private _app: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
||||||
|
*/
|
||||||
|
public name: string = 'MPRIS Service';
|
||||||
|
public description: string = 'Handles MPRIS service calls for Linux systems.';
|
||||||
|
public version: string = '1.0.0';
|
||||||
|
public author: string = 'Core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MPRIS Service
|
||||||
|
*/
|
||||||
|
private mpris: any;
|
||||||
|
private mprisEvents: Object = {
|
||||||
|
"playpause": "pausePlay",
|
||||||
|
"play": "pausePlay",
|
||||||
|
"pause": "pausePlay",
|
||||||
|
"next": "nextTrack",
|
||||||
|
"previous": "previousTrack",
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************************
|
||||||
|
* Private Methods
|
||||||
|
* ****************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a media event
|
||||||
|
* @param type - pausePlay, nextTrack, PreviousTrack
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private runMediaEvent(type: string) {
|
||||||
|
if (this._win) {
|
||||||
|
this._win.webContents.executeJavaScript(`MusicKitInterop.${type}()`).catch(console.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks non-linux systems from running this plugin
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private static linuxOnly(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
|
||||||
|
if (process.platform !== 'linux') {
|
||||||
|
descriptor.value = function () {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to MPRIS Service
|
||||||
|
*/
|
||||||
|
@MPRIS.linuxOnly
|
||||||
|
private connect() {
|
||||||
|
this.mpris = Player({
|
||||||
|
name: 'Cider',
|
||||||
|
identity: 'Cider',
|
||||||
|
supportedUriSchemes: [],
|
||||||
|
supportedMimeTypes: [],
|
||||||
|
supportedInterfaces: ['player']
|
||||||
|
});
|
||||||
|
this.mpris = Object.assign(this.mpris, {
|
||||||
|
canQuit: true,
|
||||||
|
canControl: true,
|
||||||
|
canPause: true,
|
||||||
|
canPlay: true,
|
||||||
|
canGoNext: true,
|
||||||
|
active: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const pos_atr = {durationInMillis: 0};
|
||||||
|
this.mpris.getPosition = function () {
|
||||||
|
const durationInMicro = pos_atr.durationInMillis * 1000;
|
||||||
|
const percentage = parseFloat("0") || 0;
|
||||||
|
return durationInMicro * percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(this.mprisEvents)) {
|
||||||
|
this.mpris.on(key, () => {
|
||||||
|
this.runMediaEvent(value)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update MPRIS Player Attributes
|
||||||
|
*/
|
||||||
|
@MPRIS.linuxOnly
|
||||||
|
private updatePlayer(attributes: any) {
|
||||||
|
|
||||||
|
const MetaData = {
|
||||||
|
'mpris:trackid': this.mpris.objectPath(`track/${attributes.playParams.id.replace(/[.]+/g, "")}`),
|
||||||
|
'mpris:length': attributes.durationInMillis * 1000, // In microseconds
|
||||||
|
'mpris:artUrl': (attributes.artwork.url.replace('/{w}x{h}bb', '/512x512bb')).replace('/2000x2000bb', '/35x35bb'),
|
||||||
|
'xesam:title': `${attributes.name}`,
|
||||||
|
'xesam:album': `${attributes.albumName}`,
|
||||||
|
'xesam:artist': [`${attributes.artistName}`,],
|
||||||
|
'xesam:genre': attributes.genreNames
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.mpris.metadata["mpris:trackid"] === MetaData["mpris:trackid"]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mpris.metadata = MetaData
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update MPRIS Player State
|
||||||
|
* @private
|
||||||
|
* @param attributes
|
||||||
|
*/
|
||||||
|
@MPRIS.linuxOnly
|
||||||
|
private updatePlayerState(attributes: any) {
|
||||||
|
|
||||||
|
let status = 'Stopped';
|
||||||
|
if (attributes.status) {
|
||||||
|
status = 'Playing';
|
||||||
|
} else if (attributes.status === false) {
|
||||||
|
status = 'Paused';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.mpris.playbackStatus === status) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.mpris.playbackStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear state
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private clearState() {
|
||||||
|
this.mpris.metadata = {'mpris:trackid': '/org/mpris/MediaPlayer2/TrackList/NoTrack'}
|
||||||
|
this.mpris.playbackStatus = 'Stopped';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************************
|
||||||
|
* Public Methods
|
||||||
|
* ****************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on plugin load (Currently run on application start)
|
||||||
|
*/
|
||||||
|
constructor(app: any, _store: any) {
|
||||||
|
this._app = app;
|
||||||
|
console.log(`[${this.name}] plugin loaded`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on app ready
|
||||||
|
*/
|
||||||
|
onReady(win: any): void {
|
||||||
|
this._win = win;
|
||||||
|
console.log(`[${this.name}] plugin ready`);
|
||||||
|
this.connect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on app stop
|
||||||
|
*/
|
||||||
|
onBeforeQuit(): void {
|
||||||
|
console.log(`[${this.name}] plugin stopped`);
|
||||||
|
this.clearState()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on playback State Change
|
||||||
|
* @param attributes Music Attributes (attributes.state = current state)
|
||||||
|
*/
|
||||||
|
onPlaybackStateDidChange(attributes: object): void {
|
||||||
|
this.updatePlayerState(attributes)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on song change
|
||||||
|
* @param attributes Music Attributes
|
||||||
|
*/
|
||||||
|
onNowPlayingItemDidChange(attributes: object): void {
|
||||||
|
this.updatePlayer(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ var CiderAudio = {
|
||||||
gainNode : null,
|
gainNode : null,
|
||||||
spatialNode : null,
|
spatialNode : null,
|
||||||
spatialInput: null,
|
spatialInput: null,
|
||||||
|
audioBands : null,
|
||||||
},
|
},
|
||||||
init: function (cb = function () { }) {
|
init: function (cb = function () { }) {
|
||||||
//AudioOutputs.fInit = true;
|
//AudioOutputs.fInit = true;
|
||||||
|
@ -42,6 +43,7 @@ var CiderAudio = {
|
||||||
if (app.cfg.audio.spatial){
|
if (app.cfg.audio.spatial){
|
||||||
CiderAudio.spatialOn()
|
CiderAudio.spatialOn()
|
||||||
}
|
}
|
||||||
|
CiderAudio.equalizer()
|
||||||
},
|
},
|
||||||
normalizerOn: function (){},
|
normalizerOn: function (){},
|
||||||
normalizerOff: function (){
|
normalizerOff: function (){
|
||||||
|
@ -49,7 +51,7 @@ var CiderAudio = {
|
||||||
},
|
},
|
||||||
spatialOn: function (){
|
spatialOn: function (){
|
||||||
try{
|
try{
|
||||||
CiderAudio.audioNodes.gainNode.connect(CiderAudio.context.destination);} catch(e){}
|
CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.context.destination);} catch(e){}
|
||||||
CiderAudio.audioNodes.spatialNode = new ResonanceAudio(CiderAudio.context);
|
CiderAudio.audioNodes.spatialNode = new ResonanceAudio(CiderAudio.context);
|
||||||
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.context.destination);
|
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.context.destination);
|
||||||
let roomDimensions = {
|
let roomDimensions = {
|
||||||
|
@ -90,6 +92,43 @@ var CiderAudio = {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
equalizer: function (){
|
||||||
|
const BANDS = [60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000];
|
||||||
|
CiderAudio.audioNodes.audioBands = {};
|
||||||
|
|
||||||
|
BANDS.forEach((band, i) => {
|
||||||
|
const filter = CiderAudio.context.createBiquadFilter();
|
||||||
|
|
||||||
|
CiderAudio.audioNodes.audioBands[band] = filter;
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
// The first filter, includes all lower frequencies
|
||||||
|
filter.type = "lowshelf";
|
||||||
|
} else if (i === BANDS.length - 1) {
|
||||||
|
// The last filter, includes all higher frequencies
|
||||||
|
filter.type = "highshelf";
|
||||||
|
} else {
|
||||||
|
filter.type = "peaking";
|
||||||
|
}
|
||||||
|
filter.frequency.value = band;
|
||||||
|
filter.gain.value = 0;
|
||||||
|
if (i == 0){
|
||||||
|
if (app.cfg.audio.spatial) {
|
||||||
|
CiderAudio.audioNodes.spatialNode.output.disconnect(CiderAudio.context.destination);
|
||||||
|
CiderAudio.audioNodes.spatialNode.output.connect(filter);
|
||||||
|
} else {
|
||||||
|
CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.context.destination);
|
||||||
|
CiderAudio.audioNodes.gainNode.connect(filter);
|
||||||
|
}
|
||||||
|
} else if (i === BANDS.length - 1) {
|
||||||
|
CiderAudio.audioNodes.audioBands[BANDS[i - 1]].connect(filter);
|
||||||
|
} else {
|
||||||
|
CiderAudio.audioNodes.audioBands[BANDS[i - 1]].connect(filter);
|
||||||
|
filter.connect(CiderAudio.context.destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,8 @@ const app = new Vue({
|
||||||
modals: {
|
modals: {
|
||||||
addToPlaylist: false,
|
addToPlaylist: false,
|
||||||
spatialProperties: false,
|
spatialProperties: false,
|
||||||
qrcode: false
|
qrcode: false,
|
||||||
|
equalizer: false,
|
||||||
},
|
},
|
||||||
socialBadges: {
|
socialBadges: {
|
||||||
badgeMap: {},
|
badgeMap: {},
|
||||||
|
|
|
@ -5701,4 +5701,72 @@ body.no-gpu {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.equalizer-panel {
|
||||||
|
.modal-window {
|
||||||
|
height: 300px;
|
||||||
|
max-height: 300px;
|
||||||
|
width: 400px;
|
||||||
|
max-width: 400px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.info-header {
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visual-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 16px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
width: 50px;
|
||||||
|
height: 100%;
|
||||||
|
background-image: var(--gfx-closeBtn);
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
appearance: none;
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgb(196, 43, 28)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-content{
|
||||||
|
display: block;
|
||||||
|
.input-container{
|
||||||
|
display: inline-grid;
|
||||||
|
width: 35px;
|
||||||
|
justify-items: center;
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
.reset-button{
|
||||||
|
width: 50%;
|
||||||
|
margin-left: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input.eq-slider {
|
||||||
|
-webkit-appearance: slider-vertical;
|
||||||
|
width: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
@import url("less/compact.less");
|
@import url("less/compact.less");
|
||||||
|
|
108
src/renderer/views/components/equalizer.ejs
Normal file
108
src/renderer/views/components/equalizer.ejs
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
<script type="text/x-template" id="eq-view">
|
||||||
|
<div class="modal-fullscreen equalizer-panel">
|
||||||
|
<div class="modal-window" >
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="modal-title">{{$root.getLz('term.equalizer')}}</div>
|
||||||
|
<button class="close-btn" @click="close()"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-content">
|
||||||
|
<!-- BANDS = [60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000]; -->
|
||||||
|
<div class="inputs-container">
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['60']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['60']" @change="changeGain('60')">
|
||||||
|
60
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['170']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['170']" @change="changeGain('170')">
|
||||||
|
170
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['310']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['310']" @change="changeGain('310')">
|
||||||
|
310
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['600']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['600']" @change="changeGain('600')">
|
||||||
|
600
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['1000']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['1000']" @change="changeGain('1000')">
|
||||||
|
1000
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['3000']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['3000']" @change="changeGain('3000')">
|
||||||
|
3000
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['6000']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['6000']" @change="changeGain('6000')">
|
||||||
|
6000
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['12000']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['12000']" @change="changeGain('12000')">
|
||||||
|
12000
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['14000']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['14000']" @change="changeGain('14000')">
|
||||||
|
14000
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
{{app.cfg.audio.equalizer['16000']}}
|
||||||
|
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="app.cfg.audio.equalizer['16000']" @change="changeGain('16000')">
|
||||||
|
16000
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</br>
|
||||||
|
<div class="reset-button md-btn" @click="resetGain()">{{$root.getLz('term.reset')}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Vue.component('eq-view', {
|
||||||
|
template: '#eq-view',
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
app: this.$root,
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: ["src", "url"],
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
app.resetState()
|
||||||
|
},
|
||||||
|
changeGain(i) {
|
||||||
|
CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer[i]
|
||||||
|
},
|
||||||
|
resetGain(){
|
||||||
|
this.app.cfg.audio.equalizer = {
|
||||||
|
'60' : 0,
|
||||||
|
'170': 0 ,
|
||||||
|
'310': 0 ,
|
||||||
|
'600': 0 ,
|
||||||
|
'1000': 0 ,
|
||||||
|
'3000': 0 ,
|
||||||
|
'6000': 0 ,
|
||||||
|
'12000': 0 ,
|
||||||
|
'14000': 0 ,
|
||||||
|
'16000': 0 ,
|
||||||
|
}
|
||||||
|
for (var i in this.app.cfg.audio.equalizer){
|
||||||
|
this.changeGain(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -207,7 +207,7 @@
|
||||||
<sidebar-library-item :name="$root.getLz('home.title')" svg-icon="./assets/feather/home.svg" page="home">
|
<sidebar-library-item :name="$root.getLz('home.title')" svg-icon="./assets/feather/home.svg" page="home">
|
||||||
</sidebar-library-item>
|
</sidebar-library-item>
|
||||||
<div class="app-sidebar-header-text">
|
<div class="app-sidebar-header-text">
|
||||||
Apple Music
|
{{$root.getLz('term.appleMusic')}}
|
||||||
</div>
|
</div>
|
||||||
<sidebar-library-item :name="$root.getLz('term.listenNow')" svg-icon="./assets/feather/play-circle.svg"
|
<sidebar-library-item :name="$root.getLz('term.listenNow')" svg-icon="./assets/feather/play-circle.svg"
|
||||||
page="listen_now"></sidebar-library-item>
|
page="listen_now"></sidebar-library-item>
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
<sidebar-library-item :name="$root.getLz('term.radio')" svg-icon="./assets/feather/radio.svg" page="radio">
|
<sidebar-library-item :name="$root.getLz('term.radio')" svg-icon="./assets/feather/radio.svg" page="radio">
|
||||||
</sidebar-library-item>
|
</sidebar-library-item>
|
||||||
<div class="app-sidebar-header-text">
|
<div class="app-sidebar-header-text">
|
||||||
Library
|
{{$root.getLz('term.library')}}
|
||||||
</div>
|
</div>
|
||||||
<sidebar-library-item :name="$root.getLz('term.recentlyAdded')" svg-icon="./assets/feather/plus-circle.svg"
|
<sidebar-library-item :name="$root.getLz('term.recentlyAdded')" svg-icon="./assets/feather/plus-circle.svg"
|
||||||
page="library-recentlyadded"></sidebar-library-item>
|
page="library-recentlyadded"></sidebar-library-item>
|
||||||
|
@ -264,6 +264,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="usermenu-item" v-if="cfg.advanced.AudioContext"
|
||||||
|
@click="modals.equalizer = true">
|
||||||
|
{{$root.getLz('term.equalizer')}}
|
||||||
|
</button>
|
||||||
<button class="usermenu-item" v-if="cfg.advanced.AudioContext && cfg.audio.spatial"
|
<button class="usermenu-item" v-if="cfg.advanced.AudioContext && cfg.audio.spatial"
|
||||||
@click="modals.spatialProperties = true">
|
@click="modals.spatialProperties = true">
|
||||||
{{$root.getLz('term.spacializedAudioSetting')}}
|
{{$root.getLz('term.spacializedAudioSetting')}}
|
||||||
|
@ -619,6 +623,9 @@
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<spatial-properties v-if="modals.spatialProperties"></spatial-properties>
|
<spatial-properties v-if="modals.spatialProperties"></spatial-properties>
|
||||||
</transition>
|
</transition>
|
||||||
|
<transition name="modal">
|
||||||
|
<eq-view v-if="modals.equalizer"></eq-view>
|
||||||
|
</transition>
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<qrcode-modal v-if="modals.qrcode" :src="webremoteqr" :url="webremoteurl"></qrcode-modal>
|
<qrcode-modal v-if="modals.qrcode" :src="webremoteqr" :url="webremoteurl"></qrcode-modal>
|
||||||
</transition>
|
</transition>
|
||||||
|
@ -730,6 +737,9 @@
|
||||||
<!-- QRCode Modal -->
|
<!-- QRCode Modal -->
|
||||||
<%- include('components/qrcode-modal')
|
<%- include('components/qrcode-modal')
|
||||||
%>
|
%>
|
||||||
|
<!-- Equalizer -->
|
||||||
|
<%- include('components/equalizer')
|
||||||
|
%>
|
||||||
<!-- Add to playlist -->
|
<!-- Add to playlist -->
|
||||||
<%- include('components/add-to-playlist')
|
<%- include('components/add-to-playlist')
|
||||||
%>
|
%>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script type="text/x-template" id="cider-browse">
|
<script type="text/x-template" id="cider-browse">
|
||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
<h1 class="header-text">Browse</h1>
|
<h1 class="header-text">{{$root.getLz("term.browse")}}</h1>
|
||||||
<template v-if="data.relationships && data.relationships.tabs">
|
<template v-if="data.relationships && data.relationships.tabs">
|
||||||
<template v-for="(recom,index) in data.relationships.tabs.data[0].relationships.children.data">
|
<template v-for="(recom,index) in data.relationships.tabs.data[0].relationships.children.data">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue