Merge remote-tracking branch 'origin/main'
|
@ -1,6 +1,6 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./resources/banner.png" width="80%" height="60%" alt="Banner"><br>
|
<img src="./resources/banner.png" width="80%" height="60%" alt="Banner"><br>
|
||||||
<b>A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance in mind. 🚀</b>
|
<b>A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance & visuals in mind. 🚀</b>
|
||||||
<br><br>
|
<br><br>
|
||||||
<img src="https://img.shields.io/github/stars/ciderapp/Cider?label=Stars" alt="GitHub Stars"/>
|
<img src="https://img.shields.io/github/stars/ciderapp/Cider?label=Stars" alt="GitHub Stars"/>
|
||||||
<img src="https://img.shields.io/github/forks/ciderapp/Cider?label=Forks" alt="GitHub Forks"/>
|
<img src="https://img.shields.io/github/forks/ciderapp/Cider?label=Forks" alt="GitHub Forks"/>
|
||||||
|
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 110 KiB |
|
@ -39,7 +39,7 @@
|
||||||
"appx": {
|
"appx": {
|
||||||
"applicationId": "CiderAlpha",
|
"applicationId": "CiderAlpha",
|
||||||
"publisher": "CN=CiderCollective, OID.2.25.311729368913984317654407730594956997722=1",
|
"publisher": "CN=CiderCollective, OID.2.25.311729368913984317654407730594956997722=1",
|
||||||
"displayName": "Cider (Alpha)",
|
"displayName": "Cider",
|
||||||
"identityName": "CiderCollective.CiderAlpha",
|
"identityName": "CiderCollective.CiderAlpha",
|
||||||
"backgroundColor": "transparent",
|
"backgroundColor": "transparent",
|
||||||
"setBuildNumber": true
|
"setBuildNumber": true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "cider",
|
"name": "cider",
|
||||||
"applicationId": "Cider",
|
"applicationId": "Cider",
|
||||||
"productName": "Cider",
|
"productName": "Cider",
|
||||||
"version": "1.4.7",
|
"version": "1.5.0",
|
||||||
"description": "A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance in mind.",
|
"description": "A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance in mind.",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
"@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#hap",
|
"airtunes2": "git+https://github.com/ciderapp/node_airtunes2",
|
||||||
"castv2-client": "^1.2.0",
|
"castv2-client": "^1.2.0",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"discord-auto-rpc": "^1.0.16",
|
"discord-auto-rpc": "^1.0.16",
|
||||||
|
@ -54,6 +54,7 @@
|
||||||
"electron-window-state": "^5.0.3",
|
"electron-window-state": "^5.0.3",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"get-port": "^5.1.1",
|
"get-port": "^5.1.1",
|
||||||
|
"jimp": "^0.16.1",
|
||||||
"jsonc": "^2.0.0",
|
"jsonc": "^2.0.0",
|
||||||
"lastfmapi": "^0.1.1",
|
"lastfmapi": "^0.1.1",
|
||||||
"mdns-js": "git+https://github.com/ciderapp/node-mdns-js.git",
|
"mdns-js": "git+https://github.com/ciderapp/node-mdns-js.git",
|
||||||
|
@ -110,9 +111,9 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
"electronVersion": "18.3.0",
|
"electronVersion": "19.0.1",
|
||||||
"electronDownload": {
|
"electronDownload": {
|
||||||
"version": "18.3.0+wvcus",
|
"version": "19.0.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",
|
||||||
|
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 6 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 7 KiB |
|
@ -427,3 +427,12 @@ Update 24/05/2022 21:15 UTC
|
||||||
* `settings.option.general.updateCider.branch.main`: Deleted for all language files
|
* `settings.option.general.updateCider.branch.main`: Deleted for all language files
|
||||||
* `settings.option.general.updateCider.branch.develop`: Deleted for all language files
|
* `settings.option.general.updateCider.branch.develop`: Deleted for all language files
|
||||||
* `settings.notyf.updateCider.update-error`: Deleted for all language files
|
* `settings.notyf.updateCider.update-error`: Deleted for all language files
|
||||||
|
|
||||||
|
Update 30/5/2022 05:35 UTC
|
||||||
|
|
||||||
|
* `settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM`: Added to `en_US`
|
||||||
|
* `settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE`: Added to `en_US`
|
||||||
|
* `settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk`: Added to `en_US`
|
||||||
|
* `settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k`: Added to `en_US`
|
||||||
|
* `settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive`: Added to `en_US`
|
||||||
|
* `settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy`: Added to `en_US`
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"date.format": "${d}.${m}.${y}",
|
"date.format": "${d}.${m}.${y}",
|
||||||
"dialog.cancel": "Abbrechen",
|
"dialog.cancel": "Abbrechen",
|
||||||
"dialog.ok": "OK",
|
"dialog.ok": "OK",
|
||||||
"notification.updatingLibrarySongs": "Aktualisiere Songs...",
|
"notification.updatingLibrarySongs": "Aktualisiere Titel...",
|
||||||
"notification.updatingLibraryAlbums": "Aktualisiere Alben...",
|
"notification.updatingLibraryAlbums": "Aktualisiere Alben...",
|
||||||
"notification.updatingLibraryArtists": "Aktualisiere Künstler...",
|
"notification.updatingLibraryArtists": "Aktualisiere Künstler...",
|
||||||
"term.appleInc": "Apple Inc.",
|
"term.appleInc": "Apple Inc.",
|
||||||
|
@ -24,13 +24,13 @@
|
||||||
"term.privateSession": "Private Sitzung",
|
"term.privateSession": "Private Sitzung",
|
||||||
"term.queue": "Warteschlange",
|
"term.queue": "Warteschlange",
|
||||||
"term.history": "Verlauf",
|
"term.history": "Verlauf",
|
||||||
"term.search": "Suche",
|
"term.search": "Suchen",
|
||||||
"term.library": "Mediathek",
|
"term.library": "Mediathek",
|
||||||
"term.listenNow": "Jetzt hören",
|
"term.listenNow": "Jetzt hören",
|
||||||
"term.browse": "Entdecken",
|
"term.browse": "Entdecken",
|
||||||
"term.radio": "Radio",
|
"term.radio": "Radio",
|
||||||
"term.recentlyAdded": "Zuletzt hinzugefügt",
|
"term.recentlyAdded": "Zuletzt hinzugefügt",
|
||||||
"term.songs": "Songs",
|
"term.songs": "Titel",
|
||||||
"term.albums": "Alben",
|
"term.albums": "Alben",
|
||||||
"term.artists": "Künstler",
|
"term.artists": "Künstler",
|
||||||
"term.podcasts": "Podcasts",
|
"term.podcasts": "Podcasts",
|
||||||
|
@ -282,6 +282,44 @@
|
||||||
"settings.option.experimental.compactUI": "Kompaktes UI",
|
"settings.option.experimental.compactUI": "Kompaktes UI",
|
||||||
"settings.option.window.close_button_hide": "Schließtaste soll die App verbergen",
|
"settings.option.window.close_button_hide": "Schließtaste soll die App verbergen",
|
||||||
"settings.option.experimental.inline_playlists": "Inline Playlists und Alben",
|
"settings.option.experimental.inline_playlists": "Inline Playlists und Alben",
|
||||||
|
"settings.header.advanced": "Erweitert",
|
||||||
|
"settings.option.debug.openAppData": "Öffne Cider-Ordner",
|
||||||
|
"settings.option.visual.theme.github.explore": "Durchsuche GitHub Themes",
|
||||||
|
"settings.option.visual.plugin.github.explore": "Durchsuche GitHub Plugins",
|
||||||
|
"settings.option.experimental.reinstallwidevine": "WidevineCDM neu installieren",
|
||||||
|
"settings.option.experimental.reinstallwidevine.confirm": "Möchtest du wirklich Widevine neu installieren?",
|
||||||
|
"settings.option.visual.theme.checkForUpdates": "Nach Updates suchen",
|
||||||
|
"settings.option.visual.theme.manageStyles": "Styles verwalten",
|
||||||
|
"settings.option.window.useNativeTitleBar": "Native Fenster-Titelleiste verwenden",
|
||||||
|
"settings.option.window.windowControlStyle": "Fenstersteuerungs-Stil",
|
||||||
|
"settings.option.window.windowControlStyle.right": "Rechts",
|
||||||
|
"settings.option.experimental.unknownPlugin": "Unbekannte Quellen",
|
||||||
|
"settings.option.experimental.unknownPlugin.description": "Erlaube Installation von Plugins von anderen Quellen als der Cider-Plugin-Quelle",
|
||||||
|
"settings.option.window.windowControlStyle.left": "Links",
|
||||||
|
"settings.option.visual.windowStyle": "Fenster-Style",
|
||||||
|
"settings.option.general.resumebehavior": "Fortsetzungs-Verhalten",
|
||||||
|
"settings.option.general.resumebehavior.description": "Fortsetzungs-Verhalten beeinflusst, wie Cider die Sitzung fortsetzt, wenn man zur App zurückkehrt.",
|
||||||
|
"settings.option.general.resumebehavior.locally": "Lokal",
|
||||||
|
"settings.option.general.resumebehavior.locally.description": "Cider wird die letzte Sitzung auf diesem Rechner fortsetzen.",
|
||||||
|
"settings.option.general.resumebehavior.history": "Verlauf",
|
||||||
|
"settings.option.general.resumebehavior.history.description": "Cider wird den letzten Song aus dem geräteübergreifenden Apple-Music-Verlauf in die Warteschlange stellen.",
|
||||||
|
"settings.option.general.resumetabs" : "Tab beim Start öffnen",
|
||||||
|
"settings.option.general.resumetabs.description" : "Wähle welcher Tab beim Starten von Cider geöffnet werden soll.",
|
||||||
|
"settings.option.general.resumetabs.dynamic" : "Dynamisch",
|
||||||
|
"settings.option.general.resumetabs.dynamic.description" : "Cider wird den zuletzt genutzten Tab öffnen.",
|
||||||
|
"settings.option.general.keybindings": "Tastenkombinationen",
|
||||||
|
"settings.option.general.keybindings.pressCombination": "Drücke eine Kombination aus zwei Tasten um die Tastenkombination zu aktualisieren.",
|
||||||
|
"settings.option.general.keybindings.pressEscape": "Drücke Escape um zurückzukehren.",
|
||||||
|
"settings.notyf.general.keybindings.update.success": "Tastenkombination erfolgreich aktualisiert",
|
||||||
|
"settings.prompt.general.keybindings.update.success": "Tastenkombination erfolgreich aktualisiert. Drücke OK um Cider neuzustarten.",
|
||||||
|
"settings.option.general.keybindings.open": "Öffnen",
|
||||||
|
"settings.option.general.themeUpdateNotification": "Automatisch nach Theme-Updates suchen",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Verwaltet vom Audio Lab",
|
||||||
|
"settings.option.advanced.playlistTrackMapping.description": "Ermöglicht tiefes Scannen von Wiedergabelisten, um festzustellen, welche Titel sich in welchen Wiedergabelisten befinden. Die Erstellungszeiten für den Wiedergabelisten-Cache können sich erheblich verlängern.",
|
||||||
|
"settings.option.visual.transparent": "Transparentes Fenster",
|
||||||
|
"settings.option.visual.transparent.description": "Benötigt Theme Support, Neustart erforderlich",
|
||||||
|
"action.cast.todevices": "An Geräte streamen",
|
||||||
|
"action.cast.stop": "Streamen an alle Geräte beenden",
|
||||||
"spatial.notTurnedOn": "Die Audio-Spatialisierung ist deaktiviert. Um sie zu verwenden, musst du diese zuerst aktivieren.",
|
"spatial.notTurnedOn": "Die Audio-Spatialisierung ist deaktiviert. Um sie zu verwenden, musst du diese zuerst aktivieren.",
|
||||||
"spatial.spatialProperties": "Räumliche Einstellungen",
|
"spatial.spatialProperties": "Räumliche Einstellungen",
|
||||||
"spatial.width": "Breite",
|
"spatial.width": "Breite",
|
||||||
|
@ -299,10 +337,39 @@
|
||||||
"spatial.right": "Rechts",
|
"spatial.right": "Rechts",
|
||||||
"spatial.back": "Hinten",
|
"spatial.back": "Hinten",
|
||||||
"spatial.down": "Unten",
|
"spatial.down": "Unten",
|
||||||
"spatial.listener": "Hörer*in",
|
"spatial.listener": "Hörer",
|
||||||
"spatial.audioSource": "Audioquelle",
|
"spatial.audioSource": "Audioquelle",
|
||||||
"settings.header.unfinished": "Unvollendet",
|
"settings.header.unfinished": "Unvollendet",
|
||||||
|
"settings.option.window.openOnStartup": "Öffne Cider beim Start",
|
||||||
|
"settings.option.window.openOnStartup.hidden": "Öffne Cider minimiert",
|
||||||
|
"term.audioControls": "Lautstärkeregelung",
|
||||||
|
"term.variables": "Variablen",
|
||||||
|
"settings.option.audio.volumeStep": "Lautstärke-Schritt",
|
||||||
|
"settings.option.audio.maxVolume": "Max. Lautstärke",
|
||||||
|
"settings.option.audio.changePlaybackRate": "Wiedergabegeschwindigkeit ändern",
|
||||||
|
"settings.option.audio.playbackRate": "Wiedergabegeschwindigkeit",
|
||||||
|
"settings.option.audio.playbackRate.change": "Ändern",
|
||||||
|
"settings.option.audio.dbspl.display": "dB SPL Anzeige",
|
||||||
|
"settings.option.audio.dbspl.description": "(Nur für erfahrene Benutzer) Zeigt dB SPL anstelle von dBFS am Lautstärkeregler.",
|
||||||
|
"settings.option.audio.dbfs.calibration": "0 dBFS Kalibration",
|
||||||
|
"settings.option.audio.dbfs.description": "Geb den Spitzenwert des Z-gewichteten dB SPL an, wenn Cider auf 0 dBFS steht.",
|
||||||
|
"settings.option.connectivity.discordRPC.hideButtons": "Buttons im Discord Rich Presence ausblenden",
|
||||||
|
"settings.option.connectivity.discordRPC.hideTimestamp": "Zeitstempel im Discord Rich Presence ausblenden",
|
||||||
|
"settings.option.general.showLovedTracksInline": "Zeige geliebte Titel inline",
|
||||||
|
"settings.option.audio.advanced": "Erweiterte Lautstärkeregelung",
|
||||||
"remote.web.title": "Cider Remote",
|
"remote.web.title": "Cider Remote",
|
||||||
"remote.web.description": "Scanne den QR-Code um dein Handy mit dieser Cider-Instanz zu verbinden",
|
"remote.web.description": "Scanne den QR-Code um dein Handy mit dieser Cider-Instanz zu verbinden",
|
||||||
"about.thanks": "Vielen lieben Dank an das Cider Collective Team und an alle Mithelfer."
|
"about.thanks": "Vielen lieben Dank an das Cider Collective Team und an alle Mithelfer.",
|
||||||
|
"term.navigateBack": "Zurück",
|
||||||
|
"term.navigateForward": "Weiter",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Verbessert die wahrgenommene Audioqualität von AAC-kodierten Audiodaten durch die Verwendung eines Echtzeit-Algorithmus, der sowohl psychoakustische Modelle des menschlichen Gehörs als auch AAC-Kodierungsmerkmale nutzt.",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Verwirklicht eine andere musikalische Atmosphäre, die nach dem Stand der Technik von Audio-Setups modelliert ist.",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Ändert die Betriebsart des Atmosphere Realizer-Moduls.",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Vorabgestimmter Spatialisierungseffekt. Deaktiviert die anpassbaren Einstellungen der Audio-Spatialisierung.",
|
||||||
|
"settings.option.audio.audioLab.description": "Eine Auswahl an selbst entwickelten Audioeffekten für Cider.",
|
||||||
|
"action.open": "Öffnen",
|
||||||
|
"settings.option.visual.theme.github.openfolder": "Öffne Themes Ordner",
|
||||||
|
"settings.option.debug.copy_log": "Logs in die Zwischenablage kopieren",
|
||||||
|
"settings.header.visual.theme.github.page": "Themes von GitHub",
|
||||||
|
"settings.header.visual.plugin.github.page": "Plugins von GitHub"
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,8 @@
|
||||||
"term.audioControls": "Vowume Contwows",
|
"term.audioControls": "Vowume Contwows",
|
||||||
"term.clearAll": "Cweaw Aww",
|
"term.clearAll": "Cweaw Aww",
|
||||||
"term.recentStations": "Wecent Stations",
|
"term.recentStations": "Wecent Stations",
|
||||||
|
"term.personalStations": "Pewsonyaw Stations",
|
||||||
|
"term.amLive": "Appwe Music Wive",
|
||||||
"term.language": "Wanguage",
|
"term.language": "Wanguage",
|
||||||
"term.funLanguages": "Fun",
|
"term.funLanguages": "Fun",
|
||||||
"term.noLyrics": "Woading... / Wywics nyot found./ Instwumentaw.",
|
"term.noLyrics": "Woading... / Wywics nyot found./ Instwumentaw.",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "English (US)",
|
"i18n.languageName": "English (US)",
|
||||||
"i18n.languageNameEnglish": "English (US)",
|
"i18n.languageNameEnglish": "English (US)",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@maikirakiwi @kyw504100 @nosh118",
|
"i18n.authors": "@notmaikiwi @kyw504100 @nosh118 @cryptofyre",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${m} ${d}, ${y}",
|
"date.format": "${m} ${d}, ${y}",
|
||||||
"dialog.cancel": "Cancel",
|
"dialog.cancel": "Cancel",
|
||||||
|
@ -212,6 +212,12 @@
|
||||||
"podcast.episodes": "Episodes",
|
"podcast.episodes": "Episodes",
|
||||||
"podcast.playEpisode": "Play Episode",
|
"podcast.playEpisode": "Play Episode",
|
||||||
"podcast.website": "Podcast Website",
|
"podcast.website": "Podcast Website",
|
||||||
|
"action.hideLibrary": "Hide Library",
|
||||||
|
"action.showLibrary": "Show Library",
|
||||||
|
"action.cut": "Cut",
|
||||||
|
"action.paste": "Paste",
|
||||||
|
"action.selectAll": "Select All",
|
||||||
|
"action.delete": "Delete",
|
||||||
"action.edit": "Edit",
|
"action.edit": "Edit",
|
||||||
"action.done": "Done",
|
"action.done": "Done",
|
||||||
"action.editTracklist": "Edit Tracklist",
|
"action.editTracklist": "Edit Tracklist",
|
||||||
|
@ -367,6 +373,7 @@
|
||||||
"settings.header.audio": "Audio",
|
"settings.header.audio": "Audio",
|
||||||
"settings.header.audio.description": "Adjust the audio settings for Cider.",
|
"settings.header.audio.description": "Adjust the audio settings for Cider.",
|
||||||
"settings.option.audio.volumeStep": "Volume Step",
|
"settings.option.audio.volumeStep": "Volume Step",
|
||||||
|
"settings.option.audio.advanced": "Advanced Volume Control",
|
||||||
"settings.option.audio.maxVolume": "Max Volume",
|
"settings.option.audio.maxVolume": "Max Volume",
|
||||||
"settings.option.audio.changePlaybackRate": "Change Playback Rate",
|
"settings.option.audio.changePlaybackRate": "Change Playback Rate",
|
||||||
"settings.option.audio.playbackRate": "Playback Rate",
|
"settings.option.audio.playbackRate": "Playback Rate",
|
||||||
|
@ -406,18 +413,22 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "Moonlight Softcake",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "Moonlight Softcake",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Enhances the perceived audio quality of AAC encoded audio by using a real-time algorithm that takes advantage of both psychoacoustic models of human hearing and AAC encoding characteristics.",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Enhances the perceived audio quality of AAC encoded audio by using a real-time algorithm that takes advantage of both psychoacoustic models of human hearing and AAC encoding characteristics.",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP is not compatible with Spatialization. Please disable Spatialization to continue.",
|
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP is not compatible with Spatialization. Please disable Spatialization to continue.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Strength",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Strength",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Changes the strength of the processing done to the audio. (Aggressive may yield undesirable results)",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Changes the strength of the processing done to the audio. (Aggressive may yield undesirable results)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "Adaptive",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "Legacy",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Aggressive",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Aggressive",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalization",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalization",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizes peak volume for individual tracks to create a more uniform listening experience. (Does not work on user uploaded tracks)",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizes peak volume for individual tracks to create a more uniform listening experience. (Does not work on user uploaded tracks)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Managed by Audio Lab",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Managed by Audio Lab",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Pre-tuned Spatializing Effect, disables the customizable settings of Audio Spatialization. Spatialization must be enabled as a prerequisite.",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Pre-tuned Spatializing Effect, disables the customizable settings of Audio Spatialization.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Spatialization Profile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Spatialization Profile",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Changes the Tuning Profile of the Spatialization.",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Changes the Tuning Profile of the Spatialization.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Standard",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Standard",
|
||||||
|
@ -426,6 +437,8 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffused",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffused",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Expanded Encore",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Spatialization is not compatible with CAP. Please disable CAP to continue.",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Spatialization is not compatible with CAP. Please disable CAP to continue.",
|
||||||
"settings.option.audio.dbspl.display": "dB SPL Display",
|
"settings.option.audio.dbspl.display": "dB SPL Display",
|
||||||
"settings.option.audio.dbspl.description": "(Advanced users only) Display dB SPL instead of dBFS on the volume slider.",
|
"settings.option.audio.dbspl.description": "(Advanced users only) Display dB SPL instead of dBFS on the volume slider.",
|
||||||
|
@ -564,5 +577,44 @@
|
||||||
"share.platform.email": "Email",
|
"share.platform.email": "Email",
|
||||||
"share.platform.songLink": "Copy with song.link",
|
"share.platform.songLink": "Copy with song.link",
|
||||||
"share.platform.clipboard": "Copy Link",
|
"share.platform.clipboard": "Copy Link",
|
||||||
"about.thanks": "Major thanks to the Cider Collective Team and all of our contributors."
|
"about.thanks": "Major thanks to the Cider Collective Team and all of our contributors.",
|
||||||
|
"oobe.yes": "Yes",
|
||||||
|
"oobe.no": "No",
|
||||||
|
"oobe.next": "Next",
|
||||||
|
"oobe.previous": "Previous",
|
||||||
|
"oobe.done": "Done",
|
||||||
|
"oobe.amupsell.title": "Before we start",
|
||||||
|
"oobe.amupsell.text": "Cider requires an active, paid Apple Music subscription\nCider will not work with Apple Music Voice Plan or some promotional trial subscriptions. If you already have a qualified Apple Music subscription click Next to continue.",
|
||||||
|
"oobe.amupsell.subscribeBtn": "Subscribe to Apple Music",
|
||||||
|
"oobe.amupsell.explainBtn": "Explain",
|
||||||
|
"oobe.amupsell.subscribeUrl": "https://apple.co/3MdqJVQ",
|
||||||
|
"oobe.amupsell.amWebUrl": "https://beta.music.apple.com/",
|
||||||
|
"oobe.amupsell.promoExplained": "Some promotional and non US Apple Music trial subscriptions do not have access to the required Apple Music Web Player API's needed for Cider to function. To verify if your active trial will work with Cider go to <a href='{{ amWebUrl }}'>{{ amWebUrl }}</a> log in and try to play some music. If it works, great! You're ready to use Cider, however if it does not consider subscribing to Apple Music here: <a href='{{ subscribeUrl }}'>{{ subscribeUrl }}</a>",
|
||||||
|
"oobe.intro.title": "Welcome to Cider",
|
||||||
|
"oobe.intro.subtitle": "",
|
||||||
|
"oobe.intro.text": "Let's get a few things set up so you can use Cider, how you'd like. You can always change these settings later.",
|
||||||
|
"oobe.general.title": "General",
|
||||||
|
"oobe.general.subtitle": "",
|
||||||
|
"oobe.general.text": "",
|
||||||
|
"oobe.audio.title": "Audio",
|
||||||
|
"oobe.audio.subtitle": "",
|
||||||
|
"oobe.audio.text": "Cider features a custom tuned and designed audio stack that delivers a rich high quality audio experience.\nFeaturing Cider Adrenaline, Atmosphere Realizer, and Spatialized Audio.\nTo enable this functionality \"Advanced Audio Functionality\" must be enabled.\nEnabling Advanced Audio Functionality will give you access to these enhancements in the Cider Audio Labs, found in the app settings.",
|
||||||
|
"oobe.audio.advancedFunctionality": "",
|
||||||
|
"oobe.visual.title": "Visual",
|
||||||
|
"oobe.visual.subtitle": "",
|
||||||
|
"oobe.visual.text": "",
|
||||||
|
"oobe.visual.layout.text": "Cider features two window different layouts.\nMaverick is an iTunes like layout with the player at the top of the window.\nMojave is a new spin created by the Cider Collective.\n\nYou can change the layout any time in the settings.",
|
||||||
|
"oobe.visual.suggestingThemes": "Theming is a great way to personalize your experience. Here are a few we suggest: ",
|
||||||
|
"oobe.visual.suggestingThemes.subtext": "(These themes will be downloaded from GitHub)",
|
||||||
|
"oobe.visual.suggestingThemes.default": "Cider",
|
||||||
|
"oobe.visual.suggestingThemes.default.text": "The classic Cider theme.",
|
||||||
|
"oobe.visual.suggestingThemes.dark": "Dark",
|
||||||
|
"oobe.visual.suggestingThemes.dark.text": "Darkness.",
|
||||||
|
"oobe.visual.suggestingThemes.community1": "Groovy",
|
||||||
|
"oobe.visual.suggestingThemes.community1.text": "A WinUI influenced theme",
|
||||||
|
"oobe.visual.suggestingThemes.community2": "iTheme",
|
||||||
|
"oobe.visual.suggestingThemes.community2.text": "The classic big fruit layout.",
|
||||||
|
"oobe.visual.suggestingThemes.community3": "Dracula",
|
||||||
|
"oobe.visual.suggestingThemes.community3.text": "The iconic Dracula color scheme.",
|
||||||
|
"oobe.amsignin.title": ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "हिन्दी",
|
"i18n.languageName": "हिन्दी",
|
||||||
"i18n.languageNameEnglish": "Hindi",
|
"i18n.languageNameEnglish": "Hindi",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@maikirakiwi @vringster",
|
"i18n.authors": "@notmaikiwi @vringster",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${m} ${d}, ${y}",
|
"date.format": "${m} ${d}, ${y}",
|
||||||
"dialog.cancel": "रोकें",
|
"dialog.cancel": "रोकें",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "日本語",
|
"i18n.languageName": "日本語",
|
||||||
"i18n.languageNameEnglish": "Japanese",
|
"i18n.languageNameEnglish": "Japanese",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@maikirakiwi @tanaka_kakuel",
|
"i18n.authors": "@notmaikiwi @tanaka_kakuel",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${y}年${m}月${d}日",
|
"date.format": "${y}年${m}月${d}日",
|
||||||
"dialog.cancel": "キャンセル",
|
"dialog.cancel": "キャンセル",
|
||||||
|
@ -334,22 +334,31 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "春毫ジャスミンマキアート",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "春毫ジャスミンマキアート",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "北海道のロイヤルミルクティー",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "北海道のロイヤルミルクティー",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "ムーンライトソフトケーキ",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "ムーンライトソフトケーキ",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "黒糖クレームブリュレミルク",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "布団はやわらかいなー",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "音楽をより豊かに、生き生きとさせます",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "人の聴覚心理モデルとAAC符号化の特徴を活用したリアルタイムアルゴリズムにより、AACの認知音質を向上させます。",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAPはSpatializationと互換性がありません",
|
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAPはSpatializationと互換性がありません",
|
||||||
"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.ciderPPEStrength.adaptive": "アダプティブ",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "レガシー",
|
||||||
"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.audioNormalization.disabled": "Audio Labの設定",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "開発チームがチューニングした設定を使用することができます。(オーディオ空間化を有効にする必要があります)",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "開発チームがチューニングした設定を使用することができます。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Spatialization Profile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Spatialization Profile",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "プロファイルをSpatializationに変更します",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "プロファイルをSpatializationに変更します",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "スタンダード",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "スタンダード",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "音場",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "分離感",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "ミニマル",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "拡散",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "アンコール",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "拡張アンコール",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "オーディオ空間化はCAPと互換性がありません",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "オーディオ空間化はCAPと互換性がありません",
|
||||||
"settings.header.visual": "ビジュアル",
|
"settings.header.visual": "ビジュアル",
|
||||||
"settings.header.visual.description": "Ciderのビジュアル設定",
|
"settings.header.visual.description": "Ciderのビジュアル設定",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "English (US)",
|
"i18n.languageName": "English (US)",
|
||||||
"i18n.languageNameEnglish": "English (US)",
|
"i18n.languageNameEnglish": "English (US)",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@maikirakiwi @kyw504100 @nosh118",
|
"i18n.authors": "@notmaikiwi @kyw504100 @nosh118 @cryptofyre",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${m} ${d}, ${y}",
|
"date.format": "${m} ${d}, ${y}",
|
||||||
"dialog.cancel": "Cancel",
|
"dialog.cancel": "Cancel",
|
||||||
|
@ -212,6 +212,12 @@
|
||||||
"podcast.episodes": "Episodes",
|
"podcast.episodes": "Episodes",
|
||||||
"podcast.playEpisode": "Play Episode",
|
"podcast.playEpisode": "Play Episode",
|
||||||
"podcast.website": "Podcast Website",
|
"podcast.website": "Podcast Website",
|
||||||
|
"action.hideLibrary": "Hide Library",
|
||||||
|
"action.showLibrary": "Show Library",
|
||||||
|
"action.cut": "Cut",
|
||||||
|
"action.paste": "Paste",
|
||||||
|
"action.selectAll": "Select All",
|
||||||
|
"action.delete": "Delete",
|
||||||
"action.edit": "Edit",
|
"action.edit": "Edit",
|
||||||
"action.done": "Done",
|
"action.done": "Done",
|
||||||
"action.editTracklist": "Edit Tracklist",
|
"action.editTracklist": "Edit Tracklist",
|
||||||
|
@ -263,6 +269,7 @@
|
||||||
"action.tray.playpause": "Play/Pause",
|
"action.tray.playpause": "Play/Pause",
|
||||||
"action.tray.next": "Next",
|
"action.tray.next": "Next",
|
||||||
"action.tray.previous": "Previous",
|
"action.tray.previous": "Previous",
|
||||||
|
"action.tray.listento": "Listen To:",
|
||||||
"action.update": "Update",
|
"action.update": "Update",
|
||||||
"action.install": "Install",
|
"action.install": "Install",
|
||||||
"action.copy": "Copy",
|
"action.copy": "Copy",
|
||||||
|
@ -366,6 +373,7 @@
|
||||||
"settings.header.audio": "Audio",
|
"settings.header.audio": "Audio",
|
||||||
"settings.header.audio.description": "Adjust the audio settings for Cider.",
|
"settings.header.audio.description": "Adjust the audio settings for Cider.",
|
||||||
"settings.option.audio.volumeStep": "Volume Step",
|
"settings.option.audio.volumeStep": "Volume Step",
|
||||||
|
"settings.option.audio.advanced": "Advanced Volume Control",
|
||||||
"settings.option.audio.maxVolume": "Max Volume",
|
"settings.option.audio.maxVolume": "Max Volume",
|
||||||
"settings.option.audio.changePlaybackRate": "Change Playback Rate",
|
"settings.option.audio.changePlaybackRate": "Change Playback Rate",
|
||||||
"settings.option.audio.playbackRate": "Playback Rate",
|
"settings.option.audio.playbackRate": "Playback Rate",
|
||||||
|
@ -398,20 +406,29 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Realizes a different musical atmosphere modelled after the state of the art audio setups.",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Realizes a different musical atmosphere modelled after the state of the art audio setups.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider Atmosphere Realizer™️ Mode",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider Atmosphere Realizer™️ Mode",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Changes the mode of operation of the Atmosphere Realizer module.",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Changes the mode of operation of the Atmosphere Realizer module.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Natural (Standard)",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Hōjicha Cheese Foam Tea",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Natural (Plus)",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Genmaicha Tapioca Milk Tea",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_1": "Rock Salt Cheese Foam Tea",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_2": "Uji Matcha Milk Tea",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "Moonlight Softcake",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Enhances the perceived audio quality of 256 kbps AAC audio by using a real-time algorithm that takes advantage of both psychoacoustic models of human hearing and AAC encoding characteristics.",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Enhances the perceived audio quality of AAC encoded audio by using a real-time algorithm that takes advantage of both psychoacoustic models of human hearing and AAC encoding characteristics.",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP is not compatible with Spatialization. Please disable Spatialization to continue.",
|
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP is not compatible with Spatialization. Please disable Spatialization to continue.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Strength",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Strength",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Changes the strength of the processing done to the audio. (Aggressive may yield undesirable results)",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Changes the strength of the processing done to the audio. (Aggressive may yield undesirable results)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "Adaptive",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "Legacy",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Aggressive",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Aggressive",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalization",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalization",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizes peak volume for individual tracks to create a more uniform listening experience. (Does not work on user uploaded tracks)",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizes peak volume for individual tracks to create a more uniform listening experience. (Does not work on user uploaded tracks)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Managed by Audio Lab",
|
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Managed by Audio Lab",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Pre-tuned Spatializing Effect, disables the customizable settings of Audio Spatialization. Spatialization must be enabled as a prerequisite.",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Pre-tuned Spatializing Effect, disables the customizable settings of Audio Spatialization.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Spatialization Profile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Spatialization Profile",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Changes the Tuning Profile of the Spatialization.",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Changes the Tuning Profile of the Spatialization.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Standard",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Standard",
|
||||||
|
@ -419,6 +436,9 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Separation",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Separation",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffused",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
|
||||||
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Expanded Encore",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Spatialization is not compatible with CAP. Please disable CAP to continue.",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Spatialization is not compatible with CAP. Please disable CAP to continue.",
|
||||||
"settings.option.audio.dbspl.display": "dB SPL Display",
|
"settings.option.audio.dbspl.display": "dB SPL Display",
|
||||||
"settings.option.audio.dbspl.description": "(Advanced users only) Display dB SPL instead of dBFS on the volume slider.",
|
"settings.option.audio.dbspl.description": "(Advanced users only) Display dB SPL instead of dBFS on the volume slider.",
|
||||||
|
@ -557,5 +577,44 @@
|
||||||
"share.platform.email": "Email",
|
"share.platform.email": "Email",
|
||||||
"share.platform.songLink": "Copy with song.link",
|
"share.platform.songLink": "Copy with song.link",
|
||||||
"share.platform.clipboard": "Copy Link",
|
"share.platform.clipboard": "Copy Link",
|
||||||
"about.thanks": "Major thanks to the Cider Collective Team and all of our contributors."
|
"about.thanks": "Major thanks to the Cider Collective Team and all of our contributors.",
|
||||||
|
"oobe.yes": "Yes",
|
||||||
|
"oobe.no": "No",
|
||||||
|
"oobe.next": "Next",
|
||||||
|
"oobe.previous": "Previous",
|
||||||
|
"oobe.done": "Done",
|
||||||
|
"oobe.amupsell.title": "Before we start",
|
||||||
|
"oobe.amupsell.text": "Cider requires an active, paid Apple Music subscription\nCider will not work with Apple Music Voice Plan or some promotional trial subscriptions. If you already have a qualified Apple Music subscription click Next to continue.",
|
||||||
|
"oobe.amupsell.subscribeBtn": "Subscribe to Apple Music",
|
||||||
|
"oobe.amupsell.explainBtn": "Explain",
|
||||||
|
"oobe.amupsell.subscribeUrl": "https://apple.co/3MdqJVQ",
|
||||||
|
"oobe.amupsell.amWebUrl": "https://beta.music.apple.com/",
|
||||||
|
"oobe.amupsell.promoExplained": "Some promotional and non US Apple Music trial subscriptions do not have access to the required Apple Music Web Player API's needed for Cider to function. To verify if your active trial will work with Cider go to <a href='{{ amWebUrl }}'>{{ amWebUrl }}</a> log in and try to play some music. If it works, great! You're ready to use Cider, however if it does not consider subscribing to Apple Music here: <a href='{{ subscribeUrl }}'>{{ subscribeUrl }}</a>",
|
||||||
|
"oobe.intro.title": "Welcome to Cider",
|
||||||
|
"oobe.intro.subtitle": "",
|
||||||
|
"oobe.intro.text": "Let's get a few things set up so you can use Cider, how you'd like. You can always change these settings later.",
|
||||||
|
"oobe.general.title": "General",
|
||||||
|
"oobe.general.subtitle": "",
|
||||||
|
"oobe.general.text": "",
|
||||||
|
"oobe.audio.title": "Audio",
|
||||||
|
"oobe.audio.subtitle": "",
|
||||||
|
"oobe.audio.text": "Cider features a custom tuned and designed audio stack that delivers a rich high quality audio experience.\nFeaturing Cider Adrenaline, Atmosphere Realizer, and Spatialized Audio.\nTo enable this functionality \"Advanced Audio Functionality\" must be enabled.\nEnabling Advanced Audio Functionality will give you access to these enhancements in the Cider Audio Labs, found in the app settings.",
|
||||||
|
"oobe.audio.advancedFunctionality": "",
|
||||||
|
"oobe.visual.title": "Visual",
|
||||||
|
"oobe.visual.subtitle": "",
|
||||||
|
"oobe.visual.text": "",
|
||||||
|
"oobe.visual.layout.text": "Cider features two window different layouts.\nMaverick is an iTunes like layout with the player at the top of the window.\nMojave is a new spin created by the Cider Collective.\n\nYou can change the layout any time in the settings.",
|
||||||
|
"oobe.visual.suggestingThemes": "Theming is a great way to personalize your experience. Here are a few we suggest: ",
|
||||||
|
"oobe.visual.suggestingThemes.subtext": "(These themes will be downloaded from GitHub)",
|
||||||
|
"oobe.visual.suggestingThemes.default": "Cider",
|
||||||
|
"oobe.visual.suggestingThemes.default.text": "The classic Cider theme.",
|
||||||
|
"oobe.visual.suggestingThemes.dark": "Dark",
|
||||||
|
"oobe.visual.suggestingThemes.dark.text": "Darkness.",
|
||||||
|
"oobe.visual.suggestingThemes.community1": "Groovy",
|
||||||
|
"oobe.visual.suggestingThemes.community1.text": "A WinUI influenced theme",
|
||||||
|
"oobe.visual.suggestingThemes.community2": "iTheme",
|
||||||
|
"oobe.visual.suggestingThemes.community2.text": "The classic big fruit layout.",
|
||||||
|
"oobe.visual.suggestingThemes.community3": "Dracula",
|
||||||
|
"oobe.visual.suggestingThemes.community3.text": "The iconic Dracula color scheme.",
|
||||||
|
"oobe.amsignin.title": ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "简体中文(中国)",
|
"i18n.languageName": "简体中文(中国)",
|
||||||
"i18n.languageNameEnglish": "Simp. Chinese (China)",
|
"i18n.languageNameEnglish": "Simp. Chinese (China)",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@maikirakiwi @BillKerman @jay900604",
|
"i18n.authors": "@notmaikiwi @BillKerman @jay900604",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${y}年${m}月${d}日",
|
"date.format": "${y}年${m}月${d}日",
|
||||||
"dialog.cancel": "取消",
|
"dialog.cancel": "取消",
|
||||||
|
@ -290,7 +290,7 @@
|
||||||
"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.tunedAudioSpatialization": "Cider 空间音频效果",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider 空间音频效果",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "预先调整音频空间效果,关闭空间音讯可自订设置。但必须先打开音频空间才可以做设置。",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "预先调整音频空间效果,关闭空间音讯可自订设置。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 音频空间配置档",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 音频空间配置档",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "变更音频空间的配置档,需重新启动应用程序。",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "变更音频空间的配置档,需重新启动应用程序。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "标准",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "标准",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "繁體中文(香港)",
|
"i18n.languageName": "繁體中文(香港)",
|
||||||
"i18n.languageNameEnglish": "Trad. Chinese (Hong Kong)",
|
"i18n.languageNameEnglish": "Trad. Chinese (Hong Kong)",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@kyw504100 @maikirakiwi @BillKerman @jay900604",
|
"i18n.authors": "@kyw504100 @notmaikiwi @BillKerman @jay900604",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${y} 年 ${m} 月 ${d} 日",
|
"date.format": "${y} 年 ${m} 月 ${d} 日",
|
||||||
"dialog.cancel": "取消",
|
"dialog.cancel": "取消",
|
||||||
|
@ -399,7 +399,7 @@
|
||||||
"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.tunedAudioSpatialization": "Cider 空間音訊效果",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider 空間音訊效果",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "預先調整空間音訊效果,關閉空間音訊可自訂設定。但必須先開啟空間音訊才可以做設定。",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "預先調整空間音訊效果,關閉空間音訊可自訂設定。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 空間音訊配置檔案",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 空間音訊配置檔案",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "變更空間音訊的配置檔案,需要重新啟動應用程式。",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "變更空間音訊的配置檔案,需要重新啟動應用程式。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "繁體中文(臺灣)",
|
"i18n.languageName": "繁體中文(臺灣)",
|
||||||
"i18n.languageNameEnglish": "Trad. Chinese (Taiwan)",
|
"i18n.languageNameEnglish": "Trad. Chinese (Taiwan)",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@maikirakiwi @jay900604 @kyw504100 @BillKerman",
|
"i18n.authors": "@notmaikiwi @jay900604 @kyw504100 @BillKerman",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${y}年${m}月${d}日",
|
"date.format": "${y}年${m}月${d}日",
|
||||||
"dialog.cancel": "取消",
|
"dialog.cancel": "取消",
|
||||||
|
@ -42,12 +42,19 @@
|
||||||
"term.createNewPlaylist": "新增播放列表",
|
"term.createNewPlaylist": "新增播放列表",
|
||||||
"term.createNewPlaylistFolder": "新增播放列表檔案夾",
|
"term.createNewPlaylistFolder": "新增播放列表檔案夾",
|
||||||
"term.deletePlaylist": "你確定要刪除此播放列表嗎?",
|
"term.deletePlaylist": "你確定要刪除此播放列表嗎?",
|
||||||
|
"term.navigateBack": "回上一頁",
|
||||||
|
"term.navigateForward": "到下一頁",
|
||||||
"term.play": "播放",
|
"term.play": "播放",
|
||||||
"term.pause": "暫停",
|
"term.pause": "暫停",
|
||||||
|
"term.stop": "停止",
|
||||||
"term.previous": "上一首",
|
"term.previous": "上一首",
|
||||||
"term.next": "下一首",
|
"term.next": "下一首",
|
||||||
"term.shuffle": "隨機播放",
|
"term.shuffle": "隨機播放",
|
||||||
"term.repeat": "重複播放",
|
"term.repeat": "重複播放",
|
||||||
|
"term.enableShuffle": "開啟隨機播放",
|
||||||
|
"term.disableShuffle": "取消隨機播放",
|
||||||
|
"term.repeat": "開啟單曲循環",
|
||||||
|
"term.enableRepeatOne": "取消單曲循環",
|
||||||
"term.volume": "音量",
|
"term.volume": "音量",
|
||||||
"term.mute": "靜音",
|
"term.mute": "靜音",
|
||||||
"term.unmute": "取消靜音",
|
"term.unmute": "取消靜音",
|
||||||
|
@ -264,10 +271,10 @@
|
||||||
"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.atmosphereRealizer": "Cider 音樂氣氛實現器™️",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider 臨場音效™️",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "以最先進的音訊設定為設計,實現不同的音樂氣氛。",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "以業界頂尖的算法,實現擁有臨場感的音樂體驗。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider 音樂氣氛™️模式",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider 臨場音效™️模式",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "更改氣氛實現器模塊的操作模式。",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "更改臨場音效感的模式。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "自然(標準)",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "自然(標準)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "自然(增強)",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "自然(增強)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 數位增強音訊處理™️",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 數位增強音訊處理™️",
|
||||||
|
@ -280,7 +287,7 @@
|
||||||
"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.tunedAudioSpatialization": "Cider 空間音訊效果",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider 空間音訊效果",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "預先調整空間音訊效果,關閉空間音訊可自訂設定。但必須先開啟空間音訊才可以做設定。",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "預先調整空間音訊效果,關閉空間音訊可自訂設定。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 空間音訊配置檔案",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 空間音訊配置檔案",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "變更空間音訊的配置檔案,需要重新啟動應用程式。",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "變更空間音訊的配置檔案,需要重新啟動應用程式。",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "標準",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "標準",
|
||||||
|
|
|
@ -55,6 +55,9 @@ export class AppEvents {
|
||||||
app.exit()
|
app.exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try limiting JS memory to 350MB.
|
||||||
|
app.commandLine.appendSwitch('js-flags', '--max-old-space-size=350');
|
||||||
|
|
||||||
// Expose GC
|
// Expose GC
|
||||||
app.commandLine.appendSwitch('js-flags', '--expose_gc')
|
app.commandLine.appendSwitch('js-flags', '--expose_gc')
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {join} from "path";
|
import {join} from "path";
|
||||||
import {app, BrowserWindow as bw, ipcMain, ShareMenu, shell} from "electron";
|
import {app, BrowserWindow as bw, ipcMain, ShareMenu, shell, screen} from "electron";
|
||||||
import * as windowStateKeeper from "electron-window-state";
|
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";
|
||||||
|
@ -28,6 +28,7 @@ import * as os from "os";
|
||||||
import wallpaper from "wallpaper";
|
import wallpaper from "wallpaper";
|
||||||
import * as AdmZip from "adm-zip";
|
import * as AdmZip from "adm-zip";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file Creates the BrowserWindow
|
* @file Creates the BrowserWindow
|
||||||
* @author CiderCollective
|
* @author CiderCollective
|
||||||
|
@ -55,6 +56,7 @@ export class BrowserWindow {
|
||||||
"pages/library-songs",
|
"pages/library-songs",
|
||||||
"pages/library-albums",
|
"pages/library-albums",
|
||||||
"pages/library-artists",
|
"pages/library-artists",
|
||||||
|
"pages/library-recentlyadded",
|
||||||
"pages/browse",
|
"pages/browse",
|
||||||
"pages/groupings",
|
"pages/groupings",
|
||||||
"pages/settings",
|
"pages/settings",
|
||||||
|
@ -81,11 +83,11 @@ export class BrowserWindow {
|
||||||
"pages/zoo",
|
"pages/zoo",
|
||||||
"pages/plugin-renderer",
|
"pages/plugin-renderer",
|
||||||
"pages/keybinds",
|
"pages/keybinds",
|
||||||
|
"pages/oobe",
|
||||||
"components/mediaitem-artwork",
|
"components/mediaitem-artwork",
|
||||||
"components/artwork-material",
|
"components/artwork-material",
|
||||||
"components/menu-panel",
|
"components/menu-panel",
|
||||||
"components/sidebar-playlist",
|
"components/sidebar-playlist",
|
||||||
"components/spatial-properties",
|
|
||||||
"components/audio-settings",
|
"components/audio-settings",
|
||||||
"components/plugin-menu",
|
"components/plugin-menu",
|
||||||
"components/audio-controls",
|
"components/audio-controls",
|
||||||
|
@ -118,6 +120,11 @@ export class BrowserWindow {
|
||||||
"components/inline-collection-list",
|
"components/inline-collection-list",
|
||||||
],
|
],
|
||||||
appRoutes: [
|
appRoutes: [
|
||||||
|
{
|
||||||
|
page: "library-recentlyadded",
|
||||||
|
component: `<cider-recentlyadded></cider-recentlyadded>`,
|
||||||
|
condition: "page == 'library-recentlyadded'"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
page: "plugin-renderer",
|
page: "plugin-renderer",
|
||||||
component: `<plugin-renderer></plugin-renderer>`,
|
component: `<plugin-renderer></plugin-renderer>`,
|
||||||
|
@ -738,15 +745,28 @@ export class BrowserWindow {
|
||||||
return json;
|
return json;
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on("get-wallpaper", async (event) => {
|
ipcMain.on("get-wallpaper", async (event, args) => {
|
||||||
const wpPath: string = await wallpaper.get();
|
const wpPath: string = await wallpaper.get();
|
||||||
// get the wallpaper and encode it to base64 then return
|
const Jimp = require("jimp")
|
||||||
const wpBase64: string = await readFileSync(wpPath, 'base64')
|
const img = await Jimp.read(wpPath)
|
||||||
// add the data:image properties
|
const blurAmount = args.blurAmount ?? 256
|
||||||
const wpData: string = `data:image/png;base64,${wpBase64}`
|
if(blurAmount) {
|
||||||
|
img.blur(blurAmount)
|
||||||
|
}
|
||||||
|
const screens = await screen.getAllDisplays()
|
||||||
|
const width = screens.reduce((a, b) => a + b.size.width, 0)
|
||||||
|
const height = screens.reduce((a, b) => a + b.size.height, 0)
|
||||||
|
|
||||||
|
img.cover(width, height, Jimp.HORIZONTAL_ALIGN_LEFT | Jimp.VERTICAL_ALIGN_MIDDLE)
|
||||||
|
const result = await img.getBase64Async(Jimp.MIME_PNG)
|
||||||
|
|
||||||
event.returnValue = {
|
event.returnValue = {
|
||||||
path: wpPath,
|
path: wpPath,
|
||||||
data: wpData
|
data: result,
|
||||||
|
res: {
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1489,4 +1509,3 @@ export class BrowserWindow {
|
||||||
console.log('remote broadcasted')
|
console.log('remote broadcasted')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ export class Store {
|
||||||
"general": {
|
"general": {
|
||||||
"close_button_hide": false,
|
"close_button_hide": false,
|
||||||
"discordrpc": {
|
"discordrpc": {
|
||||||
"enabled": false,
|
"enabled": true,
|
||||||
"client": "Cider",
|
"client": "Cider",
|
||||||
"clear_on_pause": true,
|
"clear_on_pause": true,
|
||||||
"hide_buttons": false,
|
"hide_buttons": false,
|
||||||
|
@ -87,14 +87,17 @@ export class Store {
|
||||||
"W"
|
"W"
|
||||||
],
|
],
|
||||||
"audioSettings": [
|
"audioSettings": [
|
||||||
|
"CommandOrControl",
|
||||||
process.platform == "darwin" ? "Option" : "Shift",
|
process.platform == "darwin" ? "Option" : "Shift",
|
||||||
"A"
|
"A"
|
||||||
],
|
],
|
||||||
"pluginMenu": [
|
"pluginMenu": [
|
||||||
|
"CommandOrControl",
|
||||||
process.platform == "darwin" ? "Option" : "Shift",
|
process.platform == "darwin" ? "Option" : "Shift",
|
||||||
"P"
|
"P"
|
||||||
],
|
],
|
||||||
"castToDevices": [
|
"castToDevices": [
|
||||||
|
"CommandOrControl",
|
||||||
process.platform == "darwin" ? "Option" : "Shift",
|
process.platform == "darwin" ? "Option" : "Shift",
|
||||||
"C"
|
"C"
|
||||||
],
|
],
|
||||||
|
|
67
src/main/base/vcomponents.json
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
[
|
||||||
|
"pages/podcasts",
|
||||||
|
"pages/apple-account-settings",
|
||||||
|
"pages/library-songs",
|
||||||
|
"pages/library-albums",
|
||||||
|
"pages/library-artists",
|
||||||
|
"pages/browse",
|
||||||
|
"pages/groupings",
|
||||||
|
"pages/settings",
|
||||||
|
"pages/installed-themes",
|
||||||
|
"pages/listen_now",
|
||||||
|
"pages/radio",
|
||||||
|
"pages/home",
|
||||||
|
"pages/artist-feed",
|
||||||
|
"pages/cider-playlist",
|
||||||
|
"pages/playlist-inline",
|
||||||
|
"pages/recordLabel",
|
||||||
|
"pages/cider-multiroom",
|
||||||
|
"pages/collection-list",
|
||||||
|
"pages/apple-curator",
|
||||||
|
"pages/artist",
|
||||||
|
"pages/search",
|
||||||
|
"pages/about",
|
||||||
|
"pages/library-videos",
|
||||||
|
"pages/remote-pair",
|
||||||
|
"pages/themes-github",
|
||||||
|
"pages/plugins-github",
|
||||||
|
"pages/replay",
|
||||||
|
"pages/audiolabs",
|
||||||
|
"pages/zoo",
|
||||||
|
"pages/plugin-renderer",
|
||||||
|
"pages/keybinds",
|
||||||
|
"pages/oobe",
|
||||||
|
"components/mediaitem-artwork",
|
||||||
|
"components/artwork-material",
|
||||||
|
"components/menu-panel",
|
||||||
|
"components/sidebar-playlist",
|
||||||
|
"components/audio-settings",
|
||||||
|
"components/plugin-menu",
|
||||||
|
"components/audio-controls",
|
||||||
|
"components/audio-playbackrate",
|
||||||
|
"components/qrcode-modal",
|
||||||
|
"components/moreinfo-modal",
|
||||||
|
"components/equalizer",
|
||||||
|
"components/add-to-playlist",
|
||||||
|
"components/queue",
|
||||||
|
"components/mediaitem-scroller-horizontal",
|
||||||
|
"components/mediaitem-scroller-horizontal-large",
|
||||||
|
"components/mediaitem-scroller-horizontal-sp",
|
||||||
|
"components/mediaitem-scroller-horizontal-mvview",
|
||||||
|
"components/mediaitem-list-item",
|
||||||
|
"components/mediaitem-hrect",
|
||||||
|
"components/mediaitem-square",
|
||||||
|
"components/mediaitem-mvview",
|
||||||
|
"components/listennow-child",
|
||||||
|
"components/mediaitem-mvview-sp",
|
||||||
|
"components/animatedartwork-view",
|
||||||
|
"components/listitem-horizontal",
|
||||||
|
"components/lyrics-view",
|
||||||
|
"components/fullscreen",
|
||||||
|
"components/miniplayer",
|
||||||
|
"components/castmenu",
|
||||||
|
"components/airplay-modal",
|
||||||
|
"components/artist-chip",
|
||||||
|
"components/hello-world",
|
||||||
|
"components/inline-collection-list"
|
||||||
|
]
|
174
src/main/base/vrouting.json
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"page": "plugin-renderer",
|
||||||
|
"component": "<plugin-renderer></plugin-renderer>",
|
||||||
|
"condition": "page == 'plugin-renderer'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "zoo",
|
||||||
|
"component": "<cider-zoo></cider-zoo>",
|
||||||
|
"condition": "page == 'zoo'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "podcasts",
|
||||||
|
"component": "<apple-podcasts></apple-podcasts>",
|
||||||
|
"condition": "page == 'podcasts'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "library-videos",
|
||||||
|
"component": "<cider-library-videos></cider-library-videos>",
|
||||||
|
"condition": "page == 'library-videos'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "apple-account-settings",
|
||||||
|
"component": "<apple-account-settings></apple-account-settings>",
|
||||||
|
"condition": "page == 'apple-account-settings'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "about",
|
||||||
|
"component": "<about-page></about-page>",
|
||||||
|
"condition": "page == 'about'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "cider-artist",
|
||||||
|
"component": "<cider-artist :data=\"artistPage.data\"></cider-artist>",
|
||||||
|
"condition": "page == 'artist-page' && artistPage.data.attributes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "collection-list",
|
||||||
|
"component": "<cider-collection-list :data=\"collectionList.response\" :type=\"collectionList.type\" :title=\"collectionList.title\"></cider-collection-list>",
|
||||||
|
"condition": "page == 'collection-list'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "home",
|
||||||
|
"component": "<cider-home></cider-home>",
|
||||||
|
"condition": "page == 'home'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "artist-feed",
|
||||||
|
"component": "<cider-artist-feed></cider-artist-feed>",
|
||||||
|
"condition": "page == 'artist-feed'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "playlist-inline",
|
||||||
|
"component": "<playlist-inline :data=\"showingPlaylist\"></playlist-inline>",
|
||||||
|
"condition": "modals.showPlaylist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "playlist_",
|
||||||
|
"component": "<cider-playlist :data=\"showingPlaylist\"></cider-playlist>",
|
||||||
|
"condition": "page.includes('playlist_')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "oobe",
|
||||||
|
"component": "<cider-oobe/>",
|
||||||
|
"condition": "page == 'oobe'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "album_",
|
||||||
|
"component": "<cider-playlist :data=\"showingPlaylist\"></cider-playlist>",
|
||||||
|
"condition": "page.includes('album_')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "recordLabel_",
|
||||||
|
"component": "<cider-recordlabel :data=\"showingPlaylist\"></cider-recordlabel>",
|
||||||
|
"condition": "page.includes('recordLabel_')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "multiroom",
|
||||||
|
"component": "<cider-multiroom :data=\"multiroom\"></cider-multiroom>",
|
||||||
|
"condition": "page.includes('multiroom')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "curator_",
|
||||||
|
"component": "<cider-recordlabel :data=\"showingPlaylist\"></cider-recordlabel>",
|
||||||
|
"condition": "page.includes('curator_')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "browsepage",
|
||||||
|
"component": "<cider-browse :data=\"browsepage\"></cider-browse>",
|
||||||
|
"condition": "page == 'browse'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "groupings",
|
||||||
|
"component": "<cider-groupings :data=\"browsepage\"></cider-groupings>",
|
||||||
|
"condition": "page == 'groupings'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "listen_now",
|
||||||
|
"component": "<cider-listen-now :data=\"listennow\"></cider-listen-now>",
|
||||||
|
"condition": "page == 'listen_now'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "radio",
|
||||||
|
"component": "<cider-radio :data=\"radio\"></cider-radio>",
|
||||||
|
"condition": "page == 'radio'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "settings",
|
||||||
|
"component": "<cider-settings></cider-settings>",
|
||||||
|
"condition": "page == 'settings'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "installed-themes",
|
||||||
|
"component": "<installed-themes></installed-themes>",
|
||||||
|
"condition": "page == 'installed-themes'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "search",
|
||||||
|
"component": "<cider-search :search=\"search\"></cider-search>",
|
||||||
|
"condition": "page == 'search'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "library-songs",
|
||||||
|
"component": "<cider-library-songs :data=\"library.songs\"></cider-library-songs>",
|
||||||
|
"condition": "page == 'library-songs'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "library-albums",
|
||||||
|
"component": "<cider-library-albums :data=\"library.songs\"></cider-library-albums>",
|
||||||
|
"condition": "page == 'library-albums'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "library-artists",
|
||||||
|
"component": "<cider-library-artists></cider-library-artists>",
|
||||||
|
"condition": "page == 'library-artists'",
|
||||||
|
"onEnter": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "appleCurator",
|
||||||
|
"component": "<cider-applecurator :data=\"appleCurator\"></cider-applecurator>",
|
||||||
|
"condition": "page.includes('appleCurator')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "themes-github",
|
||||||
|
"component": "<themes-github></themes-github>",
|
||||||
|
"condition": "page == 'themes-github'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "plugins-github",
|
||||||
|
"component": "<plugins-github></plugins-github>",
|
||||||
|
"condition": "page == 'plugins-github'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "remote-pair",
|
||||||
|
"component": "<remote-pair></remote-pair>",
|
||||||
|
"condition": "page == 'remote-pair'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "audiolabs",
|
||||||
|
"component": "<audiolabs-page></audiolabs-page>",
|
||||||
|
"condition": "page == 'audiolabs'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "replay",
|
||||||
|
"component": "<replay-page></replay-page>",
|
||||||
|
"condition": "page == 'replay'"
|
||||||
|
}
|
||||||
|
]
|
1
src/renderer/assets/hamborgar.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
After Width: | Height: | Size: 341 B |
BIN
src/renderer/assets/oobe/ss1.png
Normal file
After Width: | Height: | Size: 168 KiB |
BIN
src/renderer/assets/oobe/ss2.png
Normal file
After Width: | Height: | Size: 164 KiB |
|
@ -158,9 +158,6 @@ const CiderAudio = {
|
||||||
CiderAudio.audioNodes.spatialNode.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
|
CiderAudio.audioNodes.spatialNode.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
spatialOff: function () {
|
|
||||||
CiderAudio.hierarchical_loading();
|
|
||||||
},
|
|
||||||
intelliGainComp_h0_0: function () {
|
intelliGainComp_h0_0: function () {
|
||||||
let filters = []; const precisionHz = 12;
|
let filters = []; const precisionHz = 12;
|
||||||
if (CiderAudio.audioNodes.audioBands !== null) { filters = filters.concat(CiderAudio.audioNodes.audioBands) }
|
if (CiderAudio.audioNodes.audioBands !== null) { filters = filters.concat(CiderAudio.audioNodes.audioBands) }
|
||||||
|
|
|
@ -2,32 +2,31 @@ var notyf = new Notyf();
|
||||||
|
|
||||||
const MusicKitObjects = {
|
const MusicKitObjects = {
|
||||||
LibraryPlaylist: function () {
|
LibraryPlaylist: function () {
|
||||||
this.id = ""
|
this.id = "";
|
||||||
this.type = "library-playlist-folders"
|
this.type = "library-playlist-folders";
|
||||||
this.href = ""
|
this.href = "";
|
||||||
this.attributes = {
|
this.attributes = {
|
||||||
dateAdded: "",
|
dateAdded: "",
|
||||||
name: ""
|
name: "",
|
||||||
}
|
};
|
||||||
this.playlists = []
|
this.playlists = [];
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
// limit an array to a certain number of items
|
// limit an array to a certain number of items
|
||||||
Array.prototype.limit = function (n) {
|
Array.prototype.limit = function (n) {
|
||||||
return this.slice(0, n);
|
return this.slice(0, n);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vue.component('animated-number', {
|
Vue.component("animated-number", {
|
||||||
|
|
||||||
template: "<div style='display: inline-block;'>{{ displayNumber }}</div>",
|
template: "<div style='display: inline-block;'>{{ displayNumber }}</div>",
|
||||||
props: { 'number': { default: 0 } },
|
props: { number: { default: 0 } },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
displayNumber: 0,
|
displayNumber: 0,
|
||||||
interval: false
|
interval: false,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
|
@ -49,111 +48,110 @@ Vue.component('animated-number', {
|
||||||
this.displayNumber = this.displayNumber + change;
|
this.displayNumber = this.displayNumber + change;
|
||||||
}
|
}
|
||||||
}, 20);
|
}, 20);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
Vue.component('sidebar-library-item', {
|
Vue.component("sidebar-library-item", {
|
||||||
template: '#sidebar-library-item',
|
template: "#sidebar-library-item",
|
||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
svgIcon: {
|
svgIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: ''
|
default: "",
|
||||||
},
|
},
|
||||||
cdClick: {
|
cdClick: {
|
||||||
type: Function,
|
type: Function,
|
||||||
required: false
|
required: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
app: app,
|
app: app,
|
||||||
svgIconData: ""
|
svgIconData: "",
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
if (this.svgIcon) {
|
if (this.svgIcon) {
|
||||||
this.svgIconData = await this.app.getSvgIcon(this.svgIcon)
|
this.svgIconData = await this.app.getSvgIcon(this.svgIcon);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {}
|
methods: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
function fallbackinitMusicKit() {
|
function fallbackinitMusicKit() {
|
||||||
const request = new XMLHttpRequest();
|
const request = new XMLHttpRequest();
|
||||||
|
|
||||||
function loadAlternateKey() {
|
function loadAlternateKey() {
|
||||||
let parsedJson = JSON.parse(this.responseText)
|
let parsedJson = JSON.parse(this.responseText);
|
||||||
MusicKit.configure({
|
MusicKit.configure({
|
||||||
developerToken: parsedJson.developerToken,
|
developerToken: parsedJson.developerToken,
|
||||||
app: {
|
app: {
|
||||||
name: 'Apple Music',
|
name: "Apple Music",
|
||||||
build: '1978.4.1',
|
build: "1978.4.1",
|
||||||
version: "1.0"
|
version: "1.0",
|
||||||
},
|
},
|
||||||
sourceType: 24,
|
sourceType: 24,
|
||||||
suppressErrorDialog: true
|
suppressErrorDialog: true,
|
||||||
})
|
});
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.addEventListener("load", loadAlternateKey);
|
request.addEventListener("load", loadAlternateKey);
|
||||||
request.open("GET", "https://raw.githubusercontent.com/lujjjh/LitoMusic/main/token.json");
|
request.open(
|
||||||
|
"GET",
|
||||||
|
"https://raw.githubusercontent.com/lujjjh/LitoMusic/main/token.json"
|
||||||
|
);
|
||||||
request.send();
|
request.send();
|
||||||
}
|
}
|
||||||
|
document.addEventListener("musickitloaded", function () {
|
||||||
document.addEventListener('musickitloaded', function () {
|
console.log("MusicKit loaded");
|
||||||
console.log('MusicKit loaded')
|
|
||||||
// MusicKit global is now defined
|
// MusicKit global is now defined
|
||||||
function initMusicKit() {
|
function initMusicKit() {
|
||||||
let parsedJson = JSON.parse(this.responseText)
|
let parsedJson = JSON.parse(this.responseText);
|
||||||
MusicKit.configure({
|
MusicKit.configure({
|
||||||
developerToken: parsedJson.token,
|
developerToken: parsedJson.token,
|
||||||
app: {
|
app: {
|
||||||
name: 'Apple Music',
|
name: "Apple Music",
|
||||||
build: '1978.4.1',
|
build: "1978.4.1",
|
||||||
version: "1.0"
|
version: "1.0",
|
||||||
},
|
},
|
||||||
sourceType: 24,
|
sourceType: 24,
|
||||||
suppressErrorDialog: true
|
suppressErrorDialog: true,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setTimeout(waitForApp, 250);
|
setTimeout(waitForApp, 250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitForApp()
|
waitForApp();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const request = new XMLHttpRequest();
|
const request = new XMLHttpRequest();
|
||||||
request.timeout = 5000;
|
request.timeout = 5000;
|
||||||
request.addEventListener("load", initMusicKit);
|
request.addEventListener("load", initMusicKit);
|
||||||
request.onreadystatechange = function (aEvt) {
|
request.onreadystatechange = function (aEvt) {
|
||||||
if (request.readyState == 4) {
|
if (request.readyState == 4) {
|
||||||
if (request.status != 200)
|
if (request.status != 200) fallbackinitMusicKit();
|
||||||
fallbackinitMusicKit()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
request.open("GET", "https://api.cider.sh/v1/");
|
request.open("GET", "https://api.cider.sh/v1/");
|
||||||
|
@ -161,17 +159,14 @@ document.addEventListener('musickitloaded', function () {
|
||||||
|
|
||||||
// check for widevine failure and reconfigure the instance.
|
// check for widevine failure and reconfigure the instance.
|
||||||
window.addEventListener("drmUnsupported", function () {
|
window.addEventListener("drmUnsupported", function () {
|
||||||
initMusicKit()
|
initMusicKit();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if ("serviceWorker" in navigator) {
|
||||||
|
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
// Use the window load event to keep the page load performant
|
// Use the window load event to keep the page load performant
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener("load", () => {
|
||||||
navigator.serviceWorker.register('sw.js?v=1');
|
navigator.serviceWorker.register("sw.js?v=1");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,26 +179,29 @@ const getBase64FromUrl = async (url) => {
|
||||||
reader.onloadend = () => {
|
reader.onloadend = () => {
|
||||||
const base64data = reader.result;
|
const base64data = reader.result;
|
||||||
resolve(base64data);
|
resolve(base64data);
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function Clone(obj) {
|
function Clone(obj) {
|
||||||
return JSON.parse(JSON.stringify(obj));
|
return JSON.parse(JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
function uuidv4() {
|
function uuidv4() {
|
||||||
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
|
||||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
(
|
||||||
|
c ^
|
||||||
|
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
|
||||||
|
).toString(16)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function xmlToJson(xml) {
|
function xmlToJson(xml) {
|
||||||
|
|
||||||
// Create the return object
|
// Create the return object
|
||||||
let obj = {};
|
let obj = {};
|
||||||
|
|
||||||
if (xml.nodeType == 1) { // element
|
if (xml.nodeType == 1) {
|
||||||
|
// element
|
||||||
// do attributes
|
// do attributes
|
||||||
if (xml.attributes.length > 0) {
|
if (xml.attributes.length > 0) {
|
||||||
obj["@attributes"] = {};
|
obj["@attributes"] = {};
|
||||||
|
@ -212,7 +210,8 @@ function xmlToJson(xml) {
|
||||||
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
|
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (xml.nodeType == 3) { // text
|
} else if (xml.nodeType == 3) {
|
||||||
|
// text
|
||||||
obj = xml.nodeValue;
|
obj = xml.nodeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,10 +220,10 @@ function xmlToJson(xml) {
|
||||||
for (var i = 0; i < xml.childNodes.length; i++) {
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
||||||
var item = xml.childNodes.item(i);
|
var item = xml.childNodes.item(i);
|
||||||
var nodeName = item.nodeName;
|
var nodeName = item.nodeName;
|
||||||
if (typeof (obj[nodeName]) == "undefined") {
|
if (typeof obj[nodeName] == "undefined") {
|
||||||
obj[nodeName] = xmlToJson(item);
|
obj[nodeName] = xmlToJson(item);
|
||||||
} else {
|
} else {
|
||||||
if (typeof (obj[nodeName].push) == "undefined") {
|
if (typeof obj[nodeName].push == "undefined") {
|
||||||
var old = obj[nodeName];
|
var old = obj[nodeName];
|
||||||
obj[nodeName] = [];
|
obj[nodeName] = [];
|
||||||
obj[nodeName].push(old);
|
obj[nodeName].push(old);
|
||||||
|
@ -235,7 +234,7 @@ function xmlToJson(xml) {
|
||||||
}
|
}
|
||||||
console.log(obj);
|
console.log(obj);
|
||||||
return obj;
|
return obj;
|
||||||
};
|
}
|
||||||
|
|
||||||
async function asyncForEach(array, callback) {
|
async function asyncForEach(array, callback) {
|
||||||
for (let index = 0; index < array.length; index++) {
|
for (let index = 0; index < array.length; index++) {
|
||||||
|
@ -245,30 +244,33 @@ async function asyncForEach(array, callback) {
|
||||||
|
|
||||||
var checkIfScrollIsStatic = setInterval(() => {
|
var checkIfScrollIsStatic = setInterval(() => {
|
||||||
try {
|
try {
|
||||||
if (position === document.getElementsByClassName('lyric-body')[0].scrollTop) {
|
if (
|
||||||
clearInterval(checkIfScrollIsStatic)
|
position === document.getElementsByClassName("lyric-body")[0].scrollTop
|
||||||
|
) {
|
||||||
|
clearInterval(checkIfScrollIsStatic);
|
||||||
// do something
|
// do something
|
||||||
}
|
}
|
||||||
position = document.getElementsByClassName('lyric-body')[0].scrollTop
|
position = document.getElementsByClassName("lyric-body")[0].scrollTop;
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
|
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
// WebGPU Console Notification
|
// WebGPU Console Notification
|
||||||
async function webGPU() {
|
async function webGPU() {
|
||||||
try {
|
try {
|
||||||
const currentGPU = await navigator.gpu.requestAdapter()
|
const currentGPU = await navigator.gpu.requestAdapter();
|
||||||
console.log("WebGPU enabled on", currentGPU.name, "with feature ID", currentGPU.features.size)
|
console.log(
|
||||||
|
"WebGPU enabled on",
|
||||||
|
currentGPU.name,
|
||||||
|
"with feature ID",
|
||||||
|
currentGPU.features.size
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("WebGPU disabled / WebGPU initialization failed")
|
console.log("WebGPU disabled / WebGPU initialization failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isJson(item) {
|
function isJson(item) {
|
||||||
item = typeof item !== "string"
|
item = typeof item !== "string" ? JSON.stringify(item) : item;
|
||||||
? JSON.stringify(item)
|
|
||||||
: item;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
item = JSON.parse(item);
|
item = JSON.parse(item);
|
||||||
|
@ -283,12 +285,62 @@ function isJson(item) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
webGPU().then()
|
webGPU().then();
|
||||||
|
|
||||||
let screenWidth = screen.width;
|
let screenWidth = screen.width;
|
||||||
let screenHeight = screen.height;
|
let screenHeight = screen.height;
|
||||||
|
|
||||||
window.onerror = function (error) {
|
document.addEventListener("DOMContentLoaded", async function () {
|
||||||
console.log(error)
|
// app.oobeInit()
|
||||||
bootbox.alert("Error occurred: " + error)
|
});
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
"contextmenu",
|
||||||
|
function (e) {
|
||||||
|
if (
|
||||||
|
e.target.tagName.toLowerCase() == "textarea" ||
|
||||||
|
(e.target.tagName.toLowerCase() == "input" &&
|
||||||
|
e.target.type != "checkbox" &&
|
||||||
|
e.target.type != "radio" &&
|
||||||
|
e.target.disabled == false)
|
||||||
|
) {
|
||||||
|
e.preventDefault();
|
||||||
|
const menuPanel = {
|
||||||
|
items: {
|
||||||
|
cut: {
|
||||||
|
name: app.getLz("action.cut"),
|
||||||
|
action: function () {
|
||||||
|
document.execCommand("cut");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
copy: {
|
||||||
|
name: app.getLz("action.copy"),
|
||||||
|
action: function () {
|
||||||
|
document.execCommand("copy");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paste: {
|
||||||
|
name: app.getLz("action.paste"),
|
||||||
|
action: function () {
|
||||||
|
document.execCommand("paste");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
name: app.getLz("action.delete"),
|
||||||
|
action: function () {
|
||||||
|
document.execCommand("delete");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
selectAll: {
|
||||||
|
name: app.getLz("action.selectAll"),
|
||||||
|
action: function () {
|
||||||
|
document.execCommand("selectAll");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
app.showMenuPanel(menuPanel, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
20
src/renderer/less/appvars.less
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
@colorMixRate: 1%;
|
||||||
|
@transparencyRate: 50%;
|
||||||
|
|
||||||
|
@keyColor : #fc3c44;
|
||||||
|
@ciderColor: #ff2654;
|
||||||
|
@baseColor: #1e1e1e;
|
||||||
|
@baseColorMix: mix(@baseColor, transparent, @transparencyRate);
|
||||||
|
@sidebarColor: #2e2e2e;
|
||||||
|
@sidebarColorMix: mix(@sidebarColor, transparent, @transparencyRate);
|
||||||
|
@appOpacity: 0.15;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--baseColor: @baseColor;
|
||||||
|
--baseColorMix: @baseColorMix;
|
||||||
|
--sidebarColor: @sidebarColor;
|
||||||
|
--sidebarColorMix: @sidebarColorMix;
|
||||||
|
--ciderColor: @ciderColor;
|
||||||
|
--appOpacity: @appOpacity;
|
||||||
|
--transparencyRate: @transparencyRate;
|
||||||
|
}
|
1
src/renderer/less/bootstrap.less
vendored
|
@ -845,6 +845,7 @@
|
||||||
padding : 0.5rem 1rem;
|
padding : 0.5rem 1rem;
|
||||||
background-color: rgba(0, 0, 0, 0.03);
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
border-top : 1px solid rgba(0, 0, 0, 0.125);
|
border-top : 1px solid rgba(0, 0, 0, 0.125);
|
||||||
|
text-align : center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-footer:last-child {
|
.card-footer:last-child {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "codicon";
|
font-family: "codicon";
|
||||||
font-display: block;
|
font-display: block;
|
||||||
src: url("codicon.ttf") format("truetype");
|
src: url("./codicon.ttf?f06865699f1720ee6ca6e0a4aa084d76") format("truetype");
|
||||||
}
|
}
|
||||||
|
|
||||||
.codicon[class*='codicon-'] {
|
.codicon[class*='codicon-'] {
|
||||||
|
@ -43,6 +43,10 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.codicon-modifier-hidden {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* custom speed & easing for loading icon */
|
/* custom speed & easing for loading icon */
|
||||||
.codicon-loading {
|
.codicon-loading {
|
||||||
animation-duration: 1s !important;
|
animation-duration: 1s !important;
|
||||||
|
@ -551,3 +555,7 @@
|
||||||
.codicon-arrow-circle-left:before { content: "\ebfd" }
|
.codicon-arrow-circle-left:before { content: "\ebfd" }
|
||||||
.codicon-arrow-circle-right:before { content: "\ebfe" }
|
.codicon-arrow-circle-right:before { content: "\ebfe" }
|
||||||
.codicon-arrow-circle-up:before { content: "\ebff" }
|
.codicon-arrow-circle-up:before { content: "\ebff" }
|
||||||
|
.codicon-layout-sidebar-right-off:before { content: "\ec00" }
|
||||||
|
.codicon-layout-panel-off:before { content: "\ec01" }
|
||||||
|
.codicon-layout-sidebar-left-off:before { content: "\ec02" }
|
||||||
|
.codicon-blank:before { content: "\ec03" }
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
@media (max-width: 951px) {
|
@media (max-width: 951px) {
|
||||||
#app-content {
|
#app-content {
|
||||||
zoom: 0.8;
|
// zoom: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,6 @@
|
||||||
// if page width is less than 951px
|
// if page width is less than 951px
|
||||||
@media (max-width: 951px) {
|
@media (max-width: 951px) {
|
||||||
#app-content {
|
#app-content {
|
||||||
zoom: 0.8;
|
// zoom: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,14 +7,90 @@
|
||||||
--chromeHeight2: 90px;
|
--chromeHeight2: 90px;
|
||||||
--chromeHeight : calc(var(--chromeHeight1) + var(--chromeHeight2));
|
--chromeHeight : calc(var(--chromeHeight1) + var(--chromeHeight2));
|
||||||
|
|
||||||
|
.modular-fs .app-drawer .lyric-footer {
|
||||||
|
bottom: var(--chromeHeight2);
|
||||||
|
}
|
||||||
|
|
||||||
.app-chrome {
|
.app-chrome {
|
||||||
|
|
||||||
|
&:not(.chrome-bottom) {
|
||||||
|
.app-chrome--center {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.top-nav-group {
|
||||||
|
background : #1e1e1e99;
|
||||||
|
border : 1px solid lighten(@baseColor, 8);
|
||||||
|
border-radius: 12px;
|
||||||
|
display : flex;
|
||||||
|
height : 32px;
|
||||||
|
|
||||||
|
.app-sidebar-item {
|
||||||
|
background-color: #1e1e1e00;
|
||||||
|
border-radius : 10px !important;
|
||||||
|
border : 0px;
|
||||||
|
min-width : 120px;
|
||||||
|
padding : 6px;
|
||||||
|
justify-content : center;
|
||||||
|
align-items : center;
|
||||||
|
margin : 0px;
|
||||||
|
height : 100%;
|
||||||
|
position : relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
--dist : 1px;
|
||||||
|
content : '';
|
||||||
|
position : absolute;
|
||||||
|
top : var(--dist);
|
||||||
|
left : var(--dist);
|
||||||
|
right : var(--dist);
|
||||||
|
bottom : var(--dist);
|
||||||
|
background-color: #fff;
|
||||||
|
opacity : 0;
|
||||||
|
border-radius : 10px;
|
||||||
|
transform : scale(0.5);
|
||||||
|
transition : transform 0.2s ease-in-out, opacity 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
|
||||||
|
opacity : .1;
|
||||||
|
transform : scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
opacity : .2;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.md-btn-primary {
|
||||||
|
box-shadow : 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8);
|
||||||
|
background-color: lighten(@baseColor, @colorMixRate * 5);
|
||||||
|
z-index : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.app-mainmenu {
|
.app-mainmenu {
|
||||||
width : 30px;
|
width : 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
width: 300px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
height: var(--chromeHeight1);
|
height: var(--chromeHeight1);
|
||||||
|
@ -23,8 +99,9 @@
|
||||||
background : var(--color2);
|
background : var(--color2);
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
height : var(--chromeHeight2);
|
height : var(--chromeHeight2);
|
||||||
box-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25);
|
box-shadow : 0px -2px 6px rgb(20 20 20 / 12%),
|
||||||
z-index: 1;
|
0px -1px 0px 0px rgb(200 200 200 / 12%);
|
||||||
|
z-index: 4;
|
||||||
|
|
||||||
.app-chrome-playback-duration-bottom {
|
.app-chrome-playback-duration-bottom {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -197,16 +274,21 @@
|
||||||
|
|
||||||
.song-name {
|
.song-name {
|
||||||
text-align : left;
|
text-align : left;
|
||||||
font-size: 0.98em;
|
font-size : 0.8em;
|
||||||
font-weight : 500;
|
font-weight : 500;
|
||||||
width : 100%;
|
width : 100%;
|
||||||
-webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%);
|
-webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-artist, .song-album {
|
.song-artist,
|
||||||
|
.song-album {
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 360px;
|
||||||
|
-webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%);
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
@ -246,3 +328,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// screen width is less than 768px
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center {
|
||||||
|
flex: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item {
|
||||||
|
min-width: 110px;
|
||||||
|
font-size: 0em;
|
||||||
|
|
||||||
|
.sidebar-icon {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center {
|
||||||
|
flex: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item {
|
||||||
|
min-width: 60px;
|
||||||
|
font-size: 0em;
|
||||||
|
|
||||||
|
.sidebar-icon {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -291,8 +291,10 @@
|
||||||
|
|
||||||
/* queue item */
|
/* queue item */
|
||||||
.cd-queue-item {
|
.cd-queue-item {
|
||||||
border-bottom: 1px solid rgb(200 200 200 / 10%);
|
border-bottom : 0px solid rgb(200 200 200 / 10%);
|
||||||
padding: 8px;
|
padding : 1px;
|
||||||
|
padding-bottom: 9px;
|
||||||
|
padding-top : 9px;
|
||||||
|
|
||||||
.row,
|
.row,
|
||||||
.col {
|
.col {
|
||||||
|
@ -301,8 +303,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.artwork {
|
.artwork {
|
||||||
width: 32px;
|
width : 42px;
|
||||||
height: 32px;
|
height: 42px;
|
||||||
flex : 0 0 auto;
|
flex : 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,18 +322,46 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-info {
|
.queue-info {
|
||||||
|
justify-content: center;
|
||||||
display : flex;
|
display : flex;
|
||||||
flex-direction : column;
|
flex-direction : column;
|
||||||
|
flex-grow : 1;
|
||||||
|
|
||||||
.queue-title {
|
.queue-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-subtitle {
|
.queue-subtitle {
|
||||||
font-size: 13px;
|
font-size: 0.7em;
|
||||||
opacity: 0.85;
|
opacity : 0.7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.queue-duration-info {
|
||||||
|
display : flex;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-duration {
|
||||||
|
font-size : 14px;
|
||||||
|
justify-content: center;
|
||||||
|
min-width : 60px;
|
||||||
|
height : 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-explicit-icon {
|
||||||
|
display: flex;
|
||||||
|
width : 24px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explicit-icon {
|
||||||
|
background-image : url("./assets/explicit.svg");
|
||||||
|
height : 12px;
|
||||||
|
width : 36px;
|
||||||
|
filter : contrast(0);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* horizontal media scroller */
|
/* horizontal media scroller */
|
||||||
|
@ -363,11 +393,13 @@
|
||||||
align-items : center;
|
align-items : center;
|
||||||
border-radius : var(--mediaItemRadius);
|
border-radius : var(--mediaItemRadius);
|
||||||
position : relative;
|
position : relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.heart-icon {
|
.heart-icon {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.popular {
|
.popular {
|
||||||
background-image : url(assets/star.svg);
|
background-image : url(assets/star.svg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -492,27 +524,35 @@
|
||||||
10% {
|
10% {
|
||||||
box-shadow: inset 0 -4px 0
|
box-shadow: inset 0 -4px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
20% {
|
20% {
|
||||||
box-shadow: inset 0 -10px 0
|
box-shadow: inset 0 -10px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
30% {
|
30% {
|
||||||
box-shadow: inset 0 -12px 0
|
box-shadow: inset 0 -12px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
40% {
|
40% {
|
||||||
box-shadow: inset 0 -8px 0
|
box-shadow: inset 0 -8px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
box-shadow: inset 0 -4px 0
|
box-shadow: inset 0 -4px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
60% {
|
60% {
|
||||||
box-shadow: inset 0 -6px 0
|
box-shadow: inset 0 -6px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
80% {
|
80% {
|
||||||
box-shadow: inset 0 -12px 0
|
box-shadow: inset 0 -12px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
90% {
|
90% {
|
||||||
box-shadow: inset 0 -6px 0
|
box-shadow: inset 0 -6px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
box-shadow: inset 0 -2px 0
|
box-shadow: inset 0 -2px 0
|
||||||
}
|
}
|
||||||
|
@ -922,6 +962,7 @@
|
||||||
flex : 0 0 auto;
|
flex : 0 0 auto;
|
||||||
margin : 6px;
|
margin : 6px;
|
||||||
cursor : pointer;
|
cursor : pointer;
|
||||||
|
|
||||||
.mediaitem-artwork {
|
.mediaitem-artwork {
|
||||||
box-shadow: unset;
|
box-shadow: unset;
|
||||||
}
|
}
|
||||||
|
@ -997,6 +1038,7 @@
|
||||||
@media (min-width: 1600px) {
|
@media (min-width: 1600px) {
|
||||||
width : calc(200px * var(--scaleRate));
|
width : calc(200px * var(--scaleRate));
|
||||||
height: calc(200px * var(--scaleRate));
|
height: calc(200px * var(--scaleRate));
|
||||||
|
|
||||||
.artwork-container>.artwork {
|
.artwork-container>.artwork {
|
||||||
width : calc(190px * var(--scaleRateArtwork));
|
width : calc(190px * var(--scaleRateArtwork));
|
||||||
height: calc(190px * var(--scaleRateArtwork));
|
height: calc(190px * var(--scaleRateArtwork));
|
||||||
|
@ -1050,6 +1092,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mediaitem-video {
|
&.mediaitem-video {
|
||||||
|
--scaleRate : 1.25;
|
||||||
|
--scaleRateArtwork: 1.25;
|
||||||
height : 200px;
|
height : 200px;
|
||||||
width : 240px;
|
width : 240px;
|
||||||
|
|
||||||
|
@ -1057,6 +1101,16 @@
|
||||||
height: 120px;
|
height: 120px;
|
||||||
width : 212px;
|
width : 212px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1600px) {
|
||||||
|
width : calc(240px * var(--scaleRate));
|
||||||
|
height: calc(200px * var(--scaleRate));
|
||||||
|
|
||||||
|
.artwork-container>.artwork {
|
||||||
|
width : calc(212px * var(--scaleRateArtwork));
|
||||||
|
height: calc(120px * var(--scaleRateArtwork));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mediaitem-brick {
|
&.mediaitem-brick {
|
||||||
|
@ -1134,6 +1188,7 @@
|
||||||
font-size : 0.9em;
|
font-size : 0.9em;
|
||||||
font-weight : 500;
|
font-weight : 500;
|
||||||
z-index : 1;
|
z-index : 1;
|
||||||
|
|
||||||
&+.subtitle {
|
&+.subtitle {
|
||||||
max-height: none !important;
|
max-height: none !important;
|
||||||
margin-top: -0.5em;
|
margin-top: -0.5em;
|
||||||
|
@ -1539,10 +1594,28 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
background-repeat : no-repeat;
|
background-repeat : no-repeat;
|
||||||
opacity : 0.70;
|
opacity : 0.70;
|
||||||
border-radius : 6px;
|
border-radius : 6px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
top:0;left:0;right:0;bottom:0;
|
||||||
|
background: var(--selected);
|
||||||
|
border-radius: inherit;
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: -1;
|
||||||
|
transform: scale(0.5);
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
|
||||||
}
|
}
|
||||||
|
|
||||||
.playback-button:active {
|
&:hover {
|
||||||
transform: scale(0.95);
|
&:before {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.playback-button--small {
|
.playback-button--small {
|
||||||
|
@ -1558,20 +1631,40 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
border : 0px;
|
border : 0px;
|
||||||
box-shadow : unset;
|
box-shadow : unset;
|
||||||
opacity : 0.70;
|
opacity : 0.70;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
top:0;left:0;right:0;bottom:0;
|
||||||
|
background: var(--selected);
|
||||||
|
border-radius: inherit;
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: -1;
|
||||||
|
transform: scale(0.5);
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&:before {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.playback-button--small.active {
|
||||||
|
background-color: rgb(200 200 200 / 25%);
|
||||||
|
}
|
||||||
.playback-button:hover,
|
.playback-button:hover,
|
||||||
.playback-button--small:hover {
|
.playback-button--small:hover {
|
||||||
background-color: rgb(200 200 200 / 10%);
|
// background-color: var(--selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
.playback-button:active,
|
.playback-button:active,
|
||||||
.playback-button--small:active {
|
.playback-button--small:active {
|
||||||
transform: scale(0.9);
|
background-color: var(--selected-click);
|
||||||
}
|
|
||||||
|
|
||||||
.playback-button--small.active {
|
|
||||||
background-color: rgb(200 200 200 / 25%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.playback-button--small.search {
|
.playback-button--small.search {
|
||||||
|
@ -1614,6 +1707,17 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.playback-button.collapseLibrary {
|
||||||
|
font-family: "codicon";
|
||||||
|
font-size : 1em;
|
||||||
|
color: var(--textColor);
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
span {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.playback-button.pause {
|
.playback-button.pause {
|
||||||
background-image : url('./assets/cider-icons/pause.svg');
|
background-image : url('./assets/cider-icons/pause.svg');
|
||||||
background-size : 38px;
|
background-size : 38px;
|
||||||
|
@ -1637,10 +1741,13 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
background-size : 60%;
|
background-size : 60%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
.playback-button.disabled, .playback-button--small.disabled {
|
|
||||||
|
.playback-button.disabled,
|
||||||
|
.playback-button--small.disabled {
|
||||||
opacity : 0.25 !important;
|
opacity : 0.25 !important;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transform : none !important;
|
transform : none !important;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
transform : none !important;
|
transform : none !important;
|
||||||
|
@ -1653,6 +1760,7 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items : center;
|
align-items : center;
|
||||||
color : white;
|
color : white;
|
||||||
|
|
||||||
>svg {
|
>svg {
|
||||||
height : 16px;
|
height : 16px;
|
||||||
width : 16px;
|
width : 16px;
|
||||||
|
@ -1866,6 +1974,7 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.artist-chip__name {
|
.artist-chip__name {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
@ -1949,6 +2058,7 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
// fancy pills
|
// fancy pills
|
||||||
.nav-pills {
|
.nav-pills {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.nav-link {
|
.nav-link {
|
||||||
transition: transform .3s var(--appleEase);
|
transition: transform .3s var(--appleEase);
|
||||||
position : relative;
|
position : relative;
|
||||||
|
@ -2054,6 +2164,7 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
display : grid;
|
display : grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap : 16px;
|
gap : 16px;
|
||||||
|
|
||||||
.grouping-btn {
|
.grouping-btn {
|
||||||
padding : 16px;
|
padding : 16px;
|
||||||
appearance : none;
|
appearance : none;
|
||||||
|
@ -2084,3 +2195,36 @@ input[type=checkbox][switch]:checked:active::before {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-sidebar-header .search-input-container .search-hints-container {
|
||||||
|
top : 38px;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-inner {
|
||||||
|
&.library-page {
|
||||||
|
.heart-icon {
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cd-mediaitem-list-item {
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.library-artists-page {
|
||||||
|
.inner-container .list-container .podcasts-list {
|
||||||
|
background : rgba(27, 27, 27);
|
||||||
|
padding-top: 14px;
|
||||||
|
width : 272px;
|
||||||
|
|
||||||
|
.cd-mediaitem-list-item {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cd-mediaitem-list-item:hover {
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,15 +114,27 @@
|
||||||
margin: 2em;
|
margin: 2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search Page
|
// Search Page
|
||||||
&.search-page {
|
&.search-page {
|
||||||
|
|
||||||
|
.searchToggle {
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
> button {
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.cd-mediaitem-square.mediaitem-brick {
|
.cd-mediaitem-square.mediaitem-brick {
|
||||||
width: 530px !important;
|
width: 530px !important;
|
||||||
|
|
||||||
.artwork-container .artwork {
|
.artwork-container .artwork {
|
||||||
height: 168px !important;
|
height: 168px !important;
|
||||||
width: 507px !important;
|
width: 507px !important;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
|
@ -667,8 +679,6 @@
|
||||||
.nameEdit {
|
.nameEdit {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
margin-bottom: 6px;
|
|
||||||
margin-right : 6px;
|
|
||||||
flex-shrink: unset;
|
flex-shrink: unset;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
|
@ -676,6 +686,16 @@
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.descriptionEdit {
|
||||||
|
font-size: 14px;
|
||||||
|
flex-shrink: unset;
|
||||||
|
background: transparent;
|
||||||
|
border: 0px;
|
||||||
|
color: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
width: 60vw;
|
||||||
|
}
|
||||||
|
|
||||||
.playlist-artist {
|
.playlist-artist {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
@ -848,7 +868,8 @@
|
||||||
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;
|
||||||
|
@ -1158,6 +1179,7 @@
|
||||||
&.addon {
|
&.addon {
|
||||||
background: rgb(86 86 86 / 20%);
|
background: rgb(86 86 86 / 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.applied {
|
&.applied {
|
||||||
background: var(--keyColor-disabled);
|
background: var(--keyColor-disabled);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
@ -1221,6 +1243,7 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
|
@ -1425,8 +1448,6 @@
|
||||||
|
|
||||||
//Home
|
//Home
|
||||||
.home-page {
|
.home-page {
|
||||||
top : 0;
|
|
||||||
//padding-top: var(--navbarHeight);
|
|
||||||
|
|
||||||
.md-btn-replay {
|
.md-btn-replay {
|
||||||
background-image: linear-gradient(-45deg, #2e2173, #925042);
|
background-image: linear-gradient(-45deg, #2e2173, #925042);
|
||||||
|
@ -1639,24 +1660,131 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content-inner.oobe {
|
||||||
|
position: absolute;
|
||||||
|
overflow: hidden;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
width: 100%;
|
||||||
|
background: #1e1e1e;
|
||||||
|
|
||||||
|
.oobe-view {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 32px;
|
||||||
|
max-width: 1280px;
|
||||||
|
max-height: 720px;
|
||||||
|
align-self: center;
|
||||||
|
justify-self: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
|
||||||
|
.oobe-header {
|
||||||
|
font-size: 3em;
|
||||||
|
text-shadow: var(--replayTextShadow);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oobe-body {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
background: #ffffff0d;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 3em;
|
||||||
|
|
||||||
|
&.text {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blurb {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
margin: 16px;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.visual {
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
.stylePicker {
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .25s all;
|
||||||
|
box-shadow: 0px 2px 6px rgb(0 0 0 / 25%);
|
||||||
|
|
||||||
|
.visualPreview {
|
||||||
|
pointer-events: none;
|
||||||
|
transition: .25s all;
|
||||||
|
width: 100%;
|
||||||
|
filter: drop-shadow(0px 8px 6px rgb(0 0 0 / 30%));
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.10) translateZ(-1px);
|
||||||
|
z-index: 1;
|
||||||
|
box-shadow: 0px 12px 16px rgb(0 0 0 / 25%);
|
||||||
|
|
||||||
|
.visualPreview {
|
||||||
|
transform: scale(1.5) translateZ(-1px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.oobe-footer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
.md-btn {
|
||||||
|
font-size: 18px;
|
||||||
|
min-width: 128px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.content-inner.cider-multiroom {
|
.content-inner.cider-multiroom {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
||||||
.detail {
|
.detail {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-desc {
|
.header-desc {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.artworkContainer {
|
.artworkContainer {
|
||||||
height: 300px;
|
height: 300px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
filter: unset;
|
filter: unset;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
transform: unset;
|
transform: unset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,47 @@
|
||||||
import { CiderCache } from "./cidercache.js"
|
import { CiderCache } from "./cidercache.js";
|
||||||
|
|
||||||
async function spawnMica() {
|
async function spawnMica() {
|
||||||
if (typeof window.micaSpawned !== "undefined") {
|
if (typeof window.micaSpawned !== "undefined") {
|
||||||
return
|
return;
|
||||||
} else {
|
} else {
|
||||||
window.micaSpawned = true
|
window.micaSpawned = true;
|
||||||
}
|
}
|
||||||
const micaDiv = document.createElement('div');
|
const micaDiv = document.createElement("div");
|
||||||
const blurIterations = 6
|
const blurIterations = 6;
|
||||||
micaDiv.id = 'micaEffect';
|
micaDiv.id = "micaEffect";
|
||||||
micaDiv.style.position = "fixed"
|
micaDiv.style.position = "fixed";
|
||||||
micaDiv.style.top = "0"
|
micaDiv.style.top = "0";
|
||||||
micaDiv.style.left = "0"
|
micaDiv.style.left = "0";
|
||||||
micaDiv.style.right = "0"
|
micaDiv.style.right = "0";
|
||||||
micaDiv.style.bottom = "0"
|
micaDiv.style.bottom = "0";
|
||||||
micaDiv.style.zIndex = -1
|
micaDiv.style.zIndex = -1;
|
||||||
|
|
||||||
let lastScreenX;
|
let lastScreenX;
|
||||||
let lastScreenY;
|
let lastScreenY;
|
||||||
let lastScreenWidth;
|
let lastScreenWidth;
|
||||||
let lastScreenHeight;
|
let lastScreenHeight;
|
||||||
|
|
||||||
let regen = true
|
let regen = true;
|
||||||
let imgSrc = await ipcRenderer.sendSync("get-wallpaper")
|
let imgSrc = await ipcRenderer.sendSync("get-wallpaper", {
|
||||||
|
blurAmount: 256
|
||||||
|
});
|
||||||
|
|
||||||
let micaCache = await CiderCache.getCache("mica-cache")
|
// let micaCache = await CiderCache.getCache("mica-cache");
|
||||||
if (!micaCache) {
|
// if (!micaCache) {
|
||||||
micaCache = {
|
// micaCache = {
|
||||||
path: "",
|
// path: "",
|
||||||
data: ""
|
// data: "",
|
||||||
}
|
// };
|
||||||
}
|
// }
|
||||||
if (micaCache.path == imgSrc.path) {
|
// if (micaCache.path == imgSrc.path) {
|
||||||
regen = false
|
// regen = false;
|
||||||
imgSrc = micaCache
|
// imgSrc = micaCache;
|
||||||
}
|
// }
|
||||||
let canvas = document.createElement('canvas');
|
let canvas = document.createElement("canvas");
|
||||||
let ctx = canvas.getContext('2d');
|
let ctx = canvas.getContext("2d");
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = imgSrc.data;
|
micaDiv.style.backgroundImage = `url(${imgSrc.data})`;
|
||||||
img.onload = function () {
|
|
||||||
canvas.width = img.width;
|
|
||||||
canvas.height = img.height;
|
|
||||||
ctx.drawImage(img, 0, 0);
|
|
||||||
if (regen) {
|
|
||||||
for (let i = 0; i < blurIterations; i++) {
|
|
||||||
StackBlur.canvasRGB(canvas, 0, 0, img.width, img.height, 128);
|
|
||||||
}
|
|
||||||
micaCache.path = imgSrc.path
|
|
||||||
micaCache.data = canvas.toDataURL()
|
|
||||||
CiderCache.putCache("mica-cache", micaCache)
|
|
||||||
}
|
|
||||||
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
||||||
micaDiv.style.backgroundImage = `url(${micaCache.data})`;
|
|
||||||
document.body.appendChild(micaDiv);
|
document.body.appendChild(micaDiv);
|
||||||
// on animation finished set animation to unset
|
|
||||||
micaDiv.addEventListener('animationend', function () {
|
|
||||||
micaDiv.style.opacity = '1';
|
|
||||||
micaDiv.style.animation = 'unset';
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function onScreenMove(cb) {
|
function onScreenMove(cb) {
|
||||||
function detectScreenMove() {
|
function detectScreenMove() {
|
||||||
|
@ -70,7 +51,10 @@ async function spawnMica() {
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
// window size change
|
// window size change
|
||||||
if (lastScreenWidth !== window.innerWidth || lastScreenHeight !== window.innerHeight) {
|
if (
|
||||||
|
lastScreenWidth !== window.innerWidth ||
|
||||||
|
lastScreenHeight !== window.innerHeight
|
||||||
|
) {
|
||||||
lastScreenWidth = window.innerWidth;
|
lastScreenWidth = window.innerWidth;
|
||||||
lastScreenHeight = window.innerHeight;
|
lastScreenHeight = window.innerHeight;
|
||||||
cb();
|
cb();
|
||||||
|
@ -101,7 +85,7 @@ async function spawnMica() {
|
||||||
micaDiv.style.backgroundPosition = `-${x}px -${y}px`;
|
micaDiv.style.backgroundPosition = `-${x}px -${y}px`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { spawnMica }
|
export { spawnMica };
|
||||||
|
|
|
@ -26,6 +26,7 @@ const app = new Vue({
|
||||||
showHints: false,
|
showHints: false,
|
||||||
results: {},
|
results: {},
|
||||||
resultsSocial: {},
|
resultsSocial: {},
|
||||||
|
resultsLibrary: {},
|
||||||
limit: 10
|
limit: 10
|
||||||
},
|
},
|
||||||
fullscreenLyrics: false,
|
fullscreenLyrics: false,
|
||||||
|
@ -159,6 +160,7 @@ const app = new Vue({
|
||||||
tmpVar: [],
|
tmpVar: [],
|
||||||
notification: false,
|
notification: false,
|
||||||
chrome: {
|
chrome: {
|
||||||
|
sidebarCollapsed: false,
|
||||||
nativeControls: false,
|
nativeControls: false,
|
||||||
contentScrollPosY: 0,
|
contentScrollPosY: 0,
|
||||||
appliedTheme: {
|
appliedTheme: {
|
||||||
|
@ -176,9 +178,7 @@ const app = new Vue({
|
||||||
"artwork": {"url": "./assets/logocut.png"}
|
"artwork": {"url": "./assets/logocut.png"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
forceDirectives: {
|
forceDirectives: {},
|
||||||
|
|
||||||
},
|
|
||||||
menuOpened: false,
|
menuOpened: false,
|
||||||
maximized: false,
|
maximized: false,
|
||||||
drawerOpened: false,
|
drawerOpened: false,
|
||||||
|
@ -273,6 +273,15 @@ const app = new Vue({
|
||||||
}, false)
|
}, false)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async oobeInit() {
|
||||||
|
this.appMode = "oobe"
|
||||||
|
this.setLz(this.cfg.general.language)
|
||||||
|
this.setLzManual()
|
||||||
|
clearTimeout(this.hangtimer)
|
||||||
|
document.body.removeAttribute("loading")
|
||||||
|
ipcRenderer.invoke("renderer-ready", true)
|
||||||
|
document.querySelector("#LOADER").remove()
|
||||||
|
},
|
||||||
setTimeout(func, time) {
|
setTimeout(func, time) {
|
||||||
return setTimeout(func, time);
|
return setTimeout(func, time);
|
||||||
},
|
},
|
||||||
|
@ -296,9 +305,14 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
formatVolumeTooltip() {
|
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'
|
let advancedTooltip = 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'
|
||||||
|
return this.cfg.audio.advanced ? advancedTooltip : (this.mk.volume * 100).toFixed(0) + '%'
|
||||||
},
|
},
|
||||||
mainMenuVisibility(val) {
|
mainMenuVisibility(val, isContextMenu) {
|
||||||
|
if (this.chrome.sidebarCollapsed && !isContextMenu) {
|
||||||
|
this.chrome.sidebarCollapsed = false
|
||||||
|
return
|
||||||
|
}
|
||||||
if (val) {
|
if (val) {
|
||||||
(this.mk.isAuthorized) ? this.chrome.menuOpened = !this.chrome.menuOpened : false;
|
(this.mk.isAuthorized) ? this.chrome.menuOpened = !this.chrome.menuOpened : false;
|
||||||
if (!this.mk.isAuthorized) {
|
if (!this.mk.isAuthorized) {
|
||||||
|
@ -329,7 +343,8 @@ const app = new Vue({
|
||||||
this.listennow.timestamp = 0;
|
this.listennow.timestamp = 0;
|
||||||
this.browsepage.timestamp = 0;
|
this.browsepage.timestamp = 0;
|
||||||
this.radio.timestamp = 0;
|
this.radio.timestamp = 0;
|
||||||
} catch (e) { }
|
} catch (e) {
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Grabs translation for localization.
|
* Grabs translation for localization.
|
||||||
|
@ -492,11 +507,9 @@ const app = new Vue({
|
||||||
history.forward()
|
history.forward()
|
||||||
},
|
},
|
||||||
getHTMLStyle() {
|
getHTMLStyle() {
|
||||||
if (app.cfg.visual.uiScale != 1) {
|
|
||||||
document.querySelector("#app").style.zoom = app.cfg.visual.uiScale
|
ipcRenderer.send("setScreenScale", app.cfg.visual.uiScale);
|
||||||
} else {
|
|
||||||
document.querySelector("#app").style.zoom = ""
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
resetState() {
|
resetState() {
|
||||||
this.menuPanel.visible = false;
|
this.menuPanel.visible = false;
|
||||||
|
@ -809,8 +822,7 @@ const app = new Vue({
|
||||||
try {
|
try {
|
||||||
if (app.mk.nowPlayingItem.type !== 'song') {
|
if (app.mk.nowPlayingItem.type !== 'song') {
|
||||||
CiderAudio.audioNodes.gainNode.gain.value = 0.70794578438;
|
CiderAudio.audioNodes.gainNode.gain.value = 0.70794578438;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
let soundcheck = tag.split(" ")
|
let soundcheck = tag.split(" ")
|
||||||
let numbers = []
|
let numbers = []
|
||||||
for (let item of soundcheck) {
|
for (let item of soundcheck) {
|
||||||
|
@ -819,18 +831,23 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
numbers.shift()
|
numbers.shift()
|
||||||
let peak = Math.max(numbers[6], numbers[7]) / 32768.0
|
let peak = Math.max(numbers[6], numbers[7]) / 32768.0
|
||||||
let gain = Math.pow(10, ((-1.3 - (Math.log10(peak) * 20)) / 20))// EBU R 128 Compliant
|
let gain = Math.pow(10, ((-1.7 - (Math.log10(peak) * 20)) / 20))// EBU R 128 Compliant
|
||||||
console.debug(`[Cider][MaikiwiSoundCheck] Peak Gain: '${(Math.log10(peak) * 20).toFixed(2)}' dB | Adjusting '${(Math.log10(gain) * 20).toFixed(2)}' dB`)
|
console.debug(`[Cider][MaikiwiSoundCheck] Peak Gain: '${(Math.log10(peak) * 20).toFixed(2)}' dB | Adjusting '${(Math.log10(gain) * 20).toFixed(2)}' dB`)
|
||||||
try {
|
try {
|
||||||
//CiderAudio.audioNodes.gainNode.gain.value = (Math.min(Math.pow(10, (replaygain.gain / 20)), (1 / replaygain.peak)))
|
//CiderAudio.audioNodes.gainNode.gain.value = (Math.min(Math.pow(10, (replaygain.gain / 20)), (1 / replaygain.peak)))
|
||||||
CiderAudio.audioNodes.gainNode.gain.value = gain
|
CiderAudio.audioNodes.gainNode.gain.value = gain
|
||||||
} catch (e) { }
|
} catch (e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
try { ipcRenderer.send('SoundCheckTag', event, tag); }
|
try {
|
||||||
catch (e) {
|
ipcRenderer.send('SoundCheckTag', event, tag);
|
||||||
try {ipcRenderer.send('SoundCheckTag', event, tag);}
|
} catch (e) {
|
||||||
catch (e) {console.log("[Cider][MaikiwiSoundCheck] Error [Gave up after 3 consecutive attempts]: " + e)}
|
try {
|
||||||
|
ipcRenderer.send('SoundCheckTag', event, tag);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("[Cider][MaikiwiSoundCheck] Error [Gave up after 3 consecutive attempts]: " + e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // brute force until it works
|
} // brute force until it works
|
||||||
})
|
})
|
||||||
|
@ -879,14 +896,12 @@ const app = new Vue({
|
||||||
localStorage.setItem("playingBitrate", "64")
|
localStorage.setItem("playingBitrate", "64")
|
||||||
CiderAudio.hierarchical_loading();
|
CiderAudio.hierarchical_loading();
|
||||||
}
|
}
|
||||||
}
|
} else if (app.mk.nowPlayingItem.flavor.includes("256")) {
|
||||||
else if (app.mk.nowPlayingItem.flavor.includes("256")) {
|
|
||||||
if (localStorage.getItem("playingBitrate") !== "256") {
|
if (localStorage.getItem("playingBitrate") !== "256") {
|
||||||
localStorage.setItem("playingBitrate", "256")
|
localStorage.setItem("playingBitrate", "256")
|
||||||
CiderAudio.hierarchical_loading();
|
CiderAudio.hierarchical_loading();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
localStorage.setItem("playingBitrate", "256")
|
localStorage.setItem("playingBitrate", "256")
|
||||||
CiderAudio.hierarchical_loading();
|
CiderAudio.hierarchical_loading();
|
||||||
}
|
}
|
||||||
|
@ -1014,7 +1029,11 @@ const app = new Vue({
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res[0].sha != theme.commit) {
|
if (res[0].sha != theme.commit) {
|
||||||
const notify = notyf.open({ className: "notyf-info", type: "info", message: `[Themes] ${theme.name} has an update available.` })
|
const notify = notyf.open({
|
||||||
|
className: "notyf-info",
|
||||||
|
type: "info",
|
||||||
|
message: `[Themes] ${theme.name} has an update available.`
|
||||||
|
})
|
||||||
notify.on("click", () => {
|
notify.on("click", () => {
|
||||||
app.appRoute("themes-github")
|
app.appRoute("themes-github")
|
||||||
notyf.dismiss(notify)
|
notyf.dismiss(notify)
|
||||||
|
@ -1262,10 +1281,12 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (e) { }
|
} catch (e) {
|
||||||
|
}
|
||||||
if (playlist.type == "library-playlist-folders") {
|
if (playlist.type == "library-playlist-folders") {
|
||||||
try {
|
try {
|
||||||
await deepScan(playlist.id).catch(e => { })
|
await deepScan(playlist.id).catch(e => {
|
||||||
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1344,6 +1365,21 @@ const app = new Vue({
|
||||||
self.refreshPlaylists(false, false)
|
self.refreshPlaylists(false, false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
async editPlaylistDescription(id, name = app.getLz('term.newPlaylist')) {
|
||||||
|
let self = this
|
||||||
|
this.mk.api.v3.music(
|
||||||
|
`/v1/me/library/playlists/${id}`, {}, {
|
||||||
|
fetchOptions: {
|
||||||
|
method: "PATCH",
|
||||||
|
body: JSON.stringify({
|
||||||
|
attributes: {description: name}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(res => {
|
||||||
|
self.refreshPlaylists(false, false)
|
||||||
|
})
|
||||||
|
},
|
||||||
copyToClipboard(str) {
|
copyToClipboard(str) {
|
||||||
// if (navigator.userAgent.includes('Darwin') || navigator.appVersion.indexOf("Mac") != -1) {
|
// if (navigator.userAgent.includes('Darwin') || navigator.appVersion.indexOf("Mac") != -1) {
|
||||||
// this.darwinShare(str)
|
// this.darwinShare(str)
|
||||||
|
@ -1634,8 +1670,7 @@ const app = new Vue({
|
||||||
const mDisplay = m > 0 ? `${m} ${app.getLz("term.time.minute", {"count": m})}` : "";
|
const mDisplay = m > 0 ? `${m} ${app.getLz("term.time.minute", {"count": m})}` : "";
|
||||||
|
|
||||||
return dDisplay + (dDisplay && hDisplay ? ", " : "") + hDisplay + (hDisplay && mDisplay ? ", " : "") + mDisplay;
|
return dDisplay + (dDisplay && hDisplay ? ", " : "") + hDisplay + (hDisplay && mDisplay ? ", " : "") + mDisplay;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
let returnTime = datetime.toISOString().substring(11, 19);
|
let returnTime = datetime.toISOString().substring(11, 19);
|
||||||
|
|
||||||
const timeGates = {
|
const timeGates = {
|
||||||
|
@ -1746,7 +1781,8 @@ const app = new Vue({
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
window.open(item.attributes.link.url)}
|
window.open(item.attributes.link.url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (kind == "multirooms") {
|
} else if (kind == "multirooms") {
|
||||||
|
@ -1995,8 +2031,7 @@ const app = new Vue({
|
||||||
app.mk.setStationQueue({artist: 'a-' + id}).then(() => {
|
app.mk.setStationQueue({artist: 'a-' + id}).then(() => {
|
||||||
app.mk.play()
|
app.mk.play()
|
||||||
})
|
})
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '')
|
app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2272,8 +2307,7 @@ const app = new Vue({
|
||||||
try {
|
try {
|
||||||
if (method.includes(`multiroom`)) {
|
if (method.includes(`multiroom`)) {
|
||||||
return await this.mk.api.v3.music(`v1/editorial/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2)
|
return await this.mk.api.v3.music(`v1/editorial/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2)
|
||||||
}
|
} else if (library) {
|
||||||
else if (library) {
|
|
||||||
return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2)
|
return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2)
|
||||||
} else {
|
} else {
|
||||||
return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2)
|
return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2)
|
||||||
|
@ -3022,7 +3056,8 @@ const app = new Vue({
|
||||||
} else { //4xx rejected
|
} else { //4xx rejected
|
||||||
getToken(2, '', '', id, lang, '');
|
getToken(2, '', '', id, lang, '');
|
||||||
}
|
}
|
||||||
} catch (e) { }
|
} catch (e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
req2.send();
|
req2.send();
|
||||||
}
|
}
|
||||||
|
@ -3080,8 +3115,7 @@ const app = new Vue({
|
||||||
translation: ''
|
translation: ''
|
||||||
});
|
});
|
||||||
app.lyrics = preLrc.reverse();
|
app.lyrics = preLrc.reverse();
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
app.lyrics = "";
|
app.lyrics = "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3123,6 +3157,7 @@ const app = new Vue({
|
||||||
function b64_to_utf8(str) {
|
function b64_to_utf8(str) {
|
||||||
return decodeURIComponent(escape(window.atob(str)));
|
return decodeURIComponent(escape(window.atob(str)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const htmlDecode = (input) => {
|
const htmlDecode = (input) => {
|
||||||
const doc = new DOMParser().parseFromString(input, "text/html");
|
const doc = new DOMParser().parseFromString(input, "text/html");
|
||||||
return doc.documentElement.textContent;
|
return doc.documentElement.textContent;
|
||||||
|
@ -3153,8 +3188,7 @@ const app = new Vue({
|
||||||
translation: ''
|
translation: ''
|
||||||
});
|
});
|
||||||
app.lyrics = preLrc.reverse();
|
app.lyrics = preLrc.reverse();
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
console.log(e)
|
console.log(e)
|
||||||
app.loadNeteaseLyrics();
|
app.loadNeteaseLyrics();
|
||||||
app.lyrics = "";
|
app.lyrics = "";
|
||||||
|
@ -3512,6 +3546,18 @@ const app = new Vue({
|
||||||
friendlyTypes(type) {
|
friendlyTypes(type) {
|
||||||
// use switch statement to return friendly name for media types "songs,artists,albums,playlists,music-videos,stations,apple-curators,curators"
|
// use switch statement to return friendly name for media types "songs,artists,albums,playlists,music-videos,stations,apple-curators,curators"
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case "library-songs":
|
||||||
|
return app.getLz('term.songs')
|
||||||
|
break;
|
||||||
|
case "library-artists":
|
||||||
|
return app.getLz('term.artists')
|
||||||
|
break;
|
||||||
|
case "library-albums":
|
||||||
|
return app.getLz('term.albums')
|
||||||
|
break;
|
||||||
|
case "library-playlists":
|
||||||
|
return app.getLz('term.playlists')
|
||||||
|
break;
|
||||||
case "song":
|
case "song":
|
||||||
return app.getLz('term.songs')
|
return app.getLz('term.songs')
|
||||||
break;
|
break;
|
||||||
|
@ -3594,6 +3640,13 @@ const app = new Vue({
|
||||||
results.data.results["meta"] = results.data.meta
|
results.data.results["meta"] = results.data.meta
|
||||||
self.search.resultsSocial = results.data.results
|
self.search.resultsSocial = results.data.results
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.search.resultsLibrary = await app.mk.api.library.search(app.search.term, {
|
||||||
|
types: 'library-songs,library-albums,library-playlists,library-artists',
|
||||||
|
limit: 25,
|
||||||
|
offset: 0
|
||||||
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
async inLibrary(items = []) {
|
async inLibrary(items = []) {
|
||||||
let types = []
|
let types = []
|
||||||
|
@ -3746,6 +3799,9 @@ const app = new Vue({
|
||||||
if (app.mk.nowPlayingItem != null && app.mk.nowPlayingItem.attributes != null && app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url != '') {
|
if (app.mk.nowPlayingItem != null && app.mk.nowPlayingItem.attributes != null && app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url != '') {
|
||||||
this.currentArtUrlRaw = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '')
|
this.currentArtUrlRaw = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '')
|
||||||
this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '').replace('{w}', artworkSize).replace('{h}', artworkSize);
|
this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '').replace('{w}', artworkSize).replace('{h}', artworkSize);
|
||||||
|
if (this.mk.nowPlayingItem._assets[0].artworkURL) {
|
||||||
|
this.currentArtUrl = this.mk.nowPlayingItem._assets[0].artworkURL
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
|
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -3756,6 +3812,9 @@ const app = new Vue({
|
||||||
if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) {
|
if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) {
|
||||||
this.currentArtUrlRaw = (data["attributes"]["artwork"]["url"] ?? '')
|
this.currentArtUrlRaw = (data["attributes"]["artwork"]["url"] ?? '')
|
||||||
this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', artworkSize).replace('{h}', artworkSize);
|
this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', artworkSize).replace('{h}', artworkSize);
|
||||||
|
if (this.mk.nowPlayingItem._assets[0].artworkURL) {
|
||||||
|
this.currentArtUrl = this.mk.nowPlayingItem._assets[0].artworkURL
|
||||||
|
}
|
||||||
ipcRenderer.send('updateRPCImage', this.currentArtUrl ?? '');
|
ipcRenderer.send('updateRPCImage', this.currentArtUrl ?? '');
|
||||||
try {
|
try {
|
||||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
|
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
|
||||||
|
@ -4421,9 +4480,12 @@ const app = new Vue({
|
||||||
xhr.open("GET", e, true);
|
xhr.open("GET", e, true);
|
||||||
xhr.send();
|
xhr.send();
|
||||||
let self = this
|
let self = this
|
||||||
|
|
||||||
function process() {
|
function process() {
|
||||||
if (xhr.readyState == 4) {
|
if (xhr.readyState == 4) {
|
||||||
let sources = xhr.responseText.match(/^(?!#)(?!\s).*$/mg).filter(function(element){return (element);});
|
let sources = xhr.responseText.match(/^(?!#)(?!\s).*$/mg).filter(function (element) {
|
||||||
|
return (element);
|
||||||
|
});
|
||||||
// Load first source
|
// Load first source
|
||||||
let src = sources[0];
|
let src = sources[0];
|
||||||
app.mk._services.mediaItemPlayback._currentPlayer._playAssetURL(src, false)
|
app.mk._services.mediaItemPlayback._currentPlayer._playAssetURL(src, false)
|
||||||
|
|
|
@ -6,6 +6,14 @@ const store = new Vuex.Store({
|
||||||
// recentlyAdded: ipcRenderer.sendSync("get-library-recentlyAdded"),
|
// recentlyAdded: ipcRenderer.sendSync("get-library-recentlyAdded"),
|
||||||
// playlists: ipcRenderer.sendSync("get-library-playlists")
|
// playlists: ipcRenderer.sendSync("get-library-playlists")
|
||||||
},
|
},
|
||||||
|
pageState: {
|
||||||
|
recentlyAdded: {
|
||||||
|
loaded: false,
|
||||||
|
nextUrl: null,
|
||||||
|
items: [],
|
||||||
|
size: "normal"
|
||||||
|
}
|
||||||
|
},
|
||||||
artwork: {
|
artwork: {
|
||||||
playerLCD: ""
|
playerLCD: ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap");
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap");
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap");
|
||||||
|
@import url("less/appvars.less");
|
||||||
@import url("less/bootstrap-vue.min.less");
|
@import url("less/bootstrap-vue.min.less");
|
||||||
@import url("less/ameframework.less");
|
@import url("less/ameframework.less");
|
||||||
@import url("less/codicon.css");
|
@import url("less/codicon.css");
|
||||||
|
@ -29,7 +30,8 @@
|
||||||
--selected: rgb(130 130 130 / 30%);
|
--selected: rgb(130 130 130 / 30%);
|
||||||
--selected-click: rgb(80 80 80 / 30%);
|
--selected-click: rgb(80 80 80 / 30%);
|
||||||
--hover: rgb(200 200 200 / 10%);
|
--hover: rgb(200 200 200 / 10%);
|
||||||
--keyColor: #fa586a;
|
// --keyColor: #fa586a;
|
||||||
|
--keyColor: @keyColor;
|
||||||
--keyColor-rgb: 250, 88, 106;
|
--keyColor-rgb: 250, 88, 106;
|
||||||
--keyColor-rollover: #ff8a9c;
|
--keyColor-rollover: #ff8a9c;
|
||||||
--keyColor-rollover-rgb: 255, 138, 156;
|
--keyColor-rollover-rgb: 255, 138, 156;
|
||||||
|
@ -46,6 +48,7 @@
|
||||||
--textColor: #eee;
|
--textColor: #eee;
|
||||||
--replayGradient: linear-gradient(45deg, hsl(248deg 58% 29%), hsl(13deg 41% 42%));
|
--replayGradient: linear-gradient(45deg, hsl(248deg 58% 29%), hsl(13deg 41% 42%));
|
||||||
--glassFilter: blur(16px) saturate(180%);
|
--glassFilter: blur(16px) saturate(180%);
|
||||||
|
--sidebarWidth: 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
*:focus-visible {
|
*:focus-visible {
|
||||||
|
@ -164,7 +167,7 @@ body.notransparency::before {
|
||||||
--chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2));
|
--chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2));
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: var(--color1);
|
background: transparent;
|
||||||
color: var(--textColor);
|
color: var(--textColor);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -174,22 +177,6 @@ body.notransparency::before {
|
||||||
|
|
||||||
&.simplebg {
|
&.simplebg {
|
||||||
background: #0e0e0e;
|
background: #0e0e0e;
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
opacity: 0.5;
|
|
||||||
z-index: 0;
|
|
||||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-chrome {
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,16 +370,19 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background-color: rgba(20 20 20 / .7);
|
||||||
}
|
}
|
||||||
|
|
||||||
#app-sidebar {
|
#app-sidebar {
|
||||||
/* background-color: var(--color1); */
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 260px;
|
width: var(--sidebarWidth);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background: linear-gradient(180deg, var(--baseColorMix) calc(var(--chromeHeight1) + 1px), var(--sidebarColorMix) calc(var(--chromeHeight1) + 1px));
|
||||||
|
max-width: var(--sidebarWidth);
|
||||||
|
padding-top: var(--chromeHeight1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#app-navbar {
|
#app-navbar {
|
||||||
|
@ -407,16 +397,21 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
}
|
}
|
||||||
|
|
||||||
#app-content {
|
#app-content {
|
||||||
background-color: var(--color3);
|
--navigationBarHeight: var(--chromeHeight1);
|
||||||
|
background-color: var(--baseColorMix);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
overflow-y: overlay;
|
overflow-y: overlay;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
border-radius: 10px 0px 0px 0px;
|
border-radius: 0;
|
||||||
border-left: 1px solid rgb(0 0 0 / 25%);
|
border-left: 1px solid var(--baseColorMix);
|
||||||
border-top: 1px solid rgb(0 0 0 / 25%);
|
// border-top: 1px solid rgb(0 0 0 / 25%);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track-piece {
|
||||||
|
margin-top: var(--chromeHeight1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-drawer {
|
.app-drawer {
|
||||||
|
@ -424,14 +419,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 16px;
|
right: 16px;
|
||||||
top: 3%;
|
|
||||||
background: var(--color2);
|
background: var(--color2);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
height: 94%;
|
|
||||||
backdrop-filter: blur(40px) saturate(180%);
|
backdrop-filter: blur(40px) saturate(180%);
|
||||||
box-shadow: var(--ciderShadow-Generic);
|
box-shadow: var(--ciderShadow-Generic);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
height: calc(calc(100% - 6%) - var(--chromeHeight1));
|
||||||
|
top: calc(var(--chromeHeight1) + 3%);
|
||||||
|
|
||||||
.bgArtworkMaterial {
|
.bgArtworkMaterial {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -453,15 +448,16 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid rgb(200 200 200 / 10%);
|
border: 1px solid rgba(100, 100, 100, 0.35);
|
||||||
|
border-top: 1px solid rgba(100, 100, 100, 0.5);
|
||||||
|
border-bottom: 1px solid rgb(60 60 60 / 62%);
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
background: rgb(100 100 100 / 25%);
|
background: #1e1e1e99;
|
||||||
color: rgb(200 200 200);
|
color: #c8c8c8;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
position: relative;
|
position: relative;
|
||||||
filter: contrast(0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input:focus {
|
.search-input:focus {
|
||||||
|
@ -531,6 +527,40 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.collapseTab {
|
||||||
|
display:flex;
|
||||||
|
padding:6px;
|
||||||
|
border:0;
|
||||||
|
>button {
|
||||||
|
appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 40px;
|
||||||
|
text-align: left;
|
||||||
|
font-family: inherit;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--selected);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--selected-click);
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 46px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1em;
|
||||||
|
font-family: "codicon";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-sidebar-button {
|
.app-sidebar-button {
|
||||||
|
@ -633,7 +663,9 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
#cmenu() {
|
#cmenu() {
|
||||||
.container {
|
.container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
left: 0px;
|
||||||
|
width: var(--sidebarWidth);
|
||||||
|
max-width: var(--sidebarWidth);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +722,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
}
|
}
|
||||||
|
|
||||||
.usermenu-container {
|
.usermenu-container {
|
||||||
top: 0px;
|
top: var(--chromeHeight1);
|
||||||
z-index: 200001 !important;
|
z-index: 200001 !important;
|
||||||
#cmenu.container();
|
#cmenu.container();
|
||||||
|
|
||||||
|
@ -874,36 +906,61 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-sidebar-item.active::after {
|
|
||||||
content: '';
|
|
||||||
width: 4px;
|
|
||||||
height: 16px;
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(100% - 72%);
|
|
||||||
border-radius: 10px;
|
|
||||||
left: 0px;
|
|
||||||
background: var(--keyColor);
|
|
||||||
// animation: expandIndicator .2s cubic-bezier(0.25, 1, 0.5, 1);
|
|
||||||
|
|
||||||
// @keyframes expandIndicator {
|
|
||||||
// 0% {
|
|
||||||
// transform: scaleY(0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 100% {
|
|
||||||
// transform: scaleY(1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-chrome {
|
.app-chrome {
|
||||||
background: var(--color1);
|
background-color: var(--baseColorMix);
|
||||||
|
box-shadow: 0px 3px 6px rgb(20 20 20 / 12%),
|
||||||
|
0px 1px 0px 0px rgb(200 200 200 / 12%);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: var(--chromeHeight1);
|
height: var(--chromeHeight1);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
|
z-index: 4;
|
||||||
|
|
||||||
|
&:not(.chrome-bottom) {
|
||||||
|
// box-shadow: 0px 0px
|
||||||
|
z-index: 16;
|
||||||
|
position: fixed;
|
||||||
|
backdrop-filter: var(--glassFilter);
|
||||||
|
|
||||||
|
.app-chrome--center {
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-nav-group {
|
||||||
|
background: var(--baseColor);
|
||||||
|
border: 1px solid lighten(@baseColor, 8);
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
.app-sidebar-item {
|
||||||
|
background-color: var(--baseColor);
|
||||||
|
border-radius: 10px!important;
|
||||||
|
border:0px;
|
||||||
|
min-width: 120px;
|
||||||
|
padding:6px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten(@baseColor, @colorMixRate * 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: lighten(@baseColor, @colorMixRate * 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.md-btn-primary {
|
||||||
|
box-shadow: 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8);
|
||||||
|
background-color: lighten(@baseColor, @colorMixRate * 5);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.vdiv {
|
.vdiv {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
|
@ -959,18 +1016,23 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.app-chrome .app-chrome-item.generic {
|
|
||||||
|
&.generic {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
opacity: 0.70;
|
opacity: 0.70;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-chrome .app-chrome-item.volume {
|
&.volume {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.search {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.volume-button {
|
.volume-button {
|
||||||
background-image: url("./assets/feather/volume-2.svg");
|
background-image: url("./assets/feather/volume-2.svg");
|
||||||
height: 15px;
|
height: 15px;
|
||||||
|
@ -1442,8 +1504,11 @@ div[data-type="musicVideo"] .info-rect .title::before {
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-navigation {
|
.app-navigation {
|
||||||
|
background : transparent;
|
||||||
|
align-items : center;
|
||||||
|
justify-content: center;
|
||||||
background: var(--color1);
|
background: var(--color1);
|
||||||
height: calc(100% - var(--chromeHeight));
|
height: calc(100% - var(--chromeHeight2));
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -1579,7 +1644,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
font-family: 'Inter', 'Noto Sans JP', 'Source Han Sans SC', 'Source Han Sans HK', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans HK', 'Noto Sans KR', sans-serif;
|
font-family: "Pretendard Variable", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lyric-body .no-lyrics {
|
.lyric-body .no-lyrics {
|
||||||
|
@ -1613,6 +1678,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
|
|
||||||
.lyric-line.active .verse.verse-active {
|
.lyric-line.active .verse.verse-active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
transition: opacity 0.35s var(--appleEase);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lyric-line:hover {
|
.lyric-line:hover {
|
||||||
|
@ -1638,7 +1704,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
/*background: var(--keyColor);*/
|
/*background: var(--keyColor);*/
|
||||||
transition: transform 0.2s var(--appleEase);
|
transition: transform 0.2s var(--appleEase), opacity 0.35s var(--appleEase);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lyric-line:not(.active) {
|
.lyric-line:not(.active) {
|
||||||
|
@ -1683,7 +1749,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
.lyrics-translation {
|
.lyrics-translation {
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
font-weight: 450;
|
font-weight: 450;
|
||||||
font-family: 'Inter', 'Noto Sans JP', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans HK', 'Noto Sans KR', sans-serif;
|
font-family: "Pretendard Variable", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
filter: contrast(0.5);
|
filter: contrast(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1909,7 +1975,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
background: rgba(200, 200, 200, 0.05);
|
background: rgba(200, 200, 200, 0.05);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: var(--contentInnerPadding);
|
padding: var(--contentInnerPadding);
|
||||||
box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
|
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1917,6 +1982,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
.cd-mediaitem-square-container{
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.cd-mediaitem-square {
|
.cd-mediaitem-square {
|
||||||
width: 220px;
|
width: 220px;
|
||||||
height: 260px;
|
height: 260px;
|
||||||
|
@ -1930,12 +1998,27 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
max-width: 240px;
|
max-width: 240px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.collection-list-square {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(200px, 1fr));
|
||||||
|
|
||||||
|
// screen size > 1200px
|
||||||
|
@media screen and (min-width: 1500px) {
|
||||||
|
grid-template-columns: repeat(6, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
// less than 1100px
|
||||||
|
@media screen and (max-width: 1150px) {
|
||||||
|
grid-template-columns: repeat(3, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cd-mediaitem-square-container{
|
.cd-mediaitem-square-container{
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reasonSP{
|
.reasonSP{
|
||||||
|
@ -2755,7 +2838,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
#micaEffect {
|
#micaEffect {
|
||||||
opacity:1;
|
opacity:1;
|
||||||
// animation: micaEnter 1s ease-in-out forwards;
|
// animation: micaEnter 1s ease-in-out forwards;
|
||||||
filter: brightness(0.5);
|
filter: brightness(1) saturate(320%);
|
||||||
@keyframes micaEnter {
|
@keyframes micaEnter {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -2781,6 +2864,16 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
|
|
||||||
// Modular
|
// Modular
|
||||||
.modular-fs {
|
.modular-fs {
|
||||||
|
.app-chrome.chrome-bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 14!important;
|
||||||
|
backdrop-filter: var(--glassFilter);
|
||||||
|
}
|
||||||
|
.app-navigation {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
.app-drawer {
|
.app-drawer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
|
@ -2862,6 +2955,16 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
transform: translateY(20px);
|
transform: translateY(20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity .15s var(--appleEase);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-enter-active,
|
.modal-enter-active,
|
||||||
.modal-leave-active {
|
.modal-leave-active {
|
||||||
transition: opacity .1s var(--appleEase), transform .1s var(--appleEase);
|
transition: opacity .1s var(--appleEase), transform .1s var(--appleEase);
|
||||||
|
@ -2943,6 +3046,15 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebartransition-enter-active,
|
||||||
|
.sidebartransition-leave-active {
|
||||||
|
transition: margin-left .35s var(--appleEase);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebartransition-enter,
|
||||||
|
.sidebartransition-leave-to {
|
||||||
|
margin-left: calc(var(--sidebarWidth) * -1);
|
||||||
|
}
|
||||||
|
|
||||||
.drawertransition-enter-active,
|
.drawertransition-enter-active,
|
||||||
.drawertransition-leave-active {
|
.drawertransition-leave-active {
|
||||||
|
@ -3056,7 +3168,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
}
|
}
|
||||||
|
|
||||||
#app.twopanel #apple-music-video-container {
|
#app.twopanel #apple-music-video-container {
|
||||||
top: var(--chromeHeight1);
|
top:0;
|
||||||
bottom: unset;
|
bottom: unset;
|
||||||
}
|
}
|
||||||
.inactive {
|
.inactive {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div id="app-content" @scroll.passive="setContentScrollPos" :scrollpos="chrome.contentScrollPosY" scrollaxis="y" :style="{'overflow': (chrome.contentAreaScrolling ? '' : 'hidden')}">
|
<div id="app-content" :scrollpos="chrome.contentScrollPosY" scrollaxis="y" :style="{'overflow': (chrome.contentAreaScrolling ? '' : 'hidden')}">
|
||||||
<div id="navigation-bar" v-if="getThemeDirective('appNavigation') == 'seperate'">
|
<div id="navigation-bar" v-if="getThemeDirective('appNavigation') == 'seperate'">
|
||||||
<button class="nav-item" @click="navigateBack()">
|
<button class="nav-item" @click="navigateBack()">
|
||||||
<%- include('../svg/chevron-left.svg') %>
|
<%- include('../svg/chevron-left.svg') %>
|
||||||
|
@ -24,11 +24,6 @@
|
||||||
</template>
|
</template>
|
||||||
</transition>
|
</transition>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<!-- Library - Recently Added -->
|
|
||||||
<transition :name="chrome.desiredPageTransition" v-on:enter="getLibraryAlbumsFull(null, 0); searchLibraryAlbums(0);">
|
|
||||||
<%- include('../pages/library-recentlyadded') %>');
|
|
||||||
</transition>
|
|
||||||
<!-- Library - Made For You -->
|
<!-- Library - Made For You -->
|
||||||
<transition :name="chrome.desiredPageTransition" v-on:enter="getMadeForYou()">
|
<transition :name="chrome.desiredPageTransition" v-on:enter="getMadeForYou()">
|
||||||
<template v-if="page == 'library-madeforyou'">
|
<template v-if="page == 'library-madeforyou'">
|
||||||
|
|
|
@ -1,5 +1,132 @@
|
||||||
<div class="app-navigation" v-cloak>
|
<div class="app-navigation" v-cloak>
|
||||||
|
<transition name="wpfade">
|
||||||
|
<div class="usermenu-container" v-if="chrome.menuOpened">
|
||||||
|
<div class="usermenu-body">
|
||||||
|
<button
|
||||||
|
class="app-sidebar-button"
|
||||||
|
style="width: 100%"
|
||||||
|
@click="appRoute('apple-account-settings')"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="sidebar-user-icon"
|
||||||
|
loading="lazy"
|
||||||
|
:src="getMediaItemArtwork(chrome.hideUserInfo ? 'http://localhost:9000/assets/logocut.png' : (chrome.userinfo.attributes['artwork'] ? chrome.userinfo.attributes['artwork']['url'] : ''), 26)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="sidebar-user-text" v-if="!chrome.hideUserInfo">
|
||||||
|
<template v-if="chrome.userinfo.id || mk.isAuthorized">
|
||||||
|
<div class="fullname text-overflow-elipsis">
|
||||||
|
{{
|
||||||
|
chrome.userinfo != null &&
|
||||||
|
chrome.userinfo.attributes != null
|
||||||
|
? chrome.userinfo.attributes.name ?? ""
|
||||||
|
: ""
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<div class="handle-text text-overflow-elipsis">
|
||||||
|
{{
|
||||||
|
chrome.userinfo != null &&
|
||||||
|
chrome.userinfo.attributes != null
|
||||||
|
? chrome.userinfo.attributes.handle ?? ""
|
||||||
|
: ""
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div @click="mk.authorize()">
|
||||||
|
{{ $root.getLz("term.login") }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-user-text" v-else>
|
||||||
|
{{ $root.getLz("app.name") }}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<!-- Use 20px SVG for usermenu icon -->
|
||||||
|
<button
|
||||||
|
class="usermenu-item"
|
||||||
|
v-if="cfg.general.privateEnabled"
|
||||||
|
@click="cfg.general.privateEnabled = false"
|
||||||
|
>
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/x.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.disablePrivateSession")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button class="usermenu-item" @click="appRoute('remote-pair')">
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/smartphone.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("action.showWebRemoteQR")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="usermenu-item"
|
||||||
|
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||||
|
>
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/cast.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.cast")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="usermenu-item"
|
||||||
|
@click="cfg.advanced.AudioContext ? modals.audioSettings = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||||
|
>
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/headphones.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.audioSettings")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="usermenu-item"
|
||||||
|
v-if="pluginInstalled"
|
||||||
|
@click="modals.pluginMenu = true"
|
||||||
|
>
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/grid.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.plugin")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button class="usermenu-item" @click="appRoute('about')">
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/info.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.about")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button class="usermenu-item" @click="appRoute('settings')">
|
||||||
|
<span class="usermenu-item-icon">
|
||||||
|
<%- include("../svg/settings.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.settings")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button class="usermenu-item" @click="unauthorize()">
|
||||||
|
<span class="usermenu-item-icon" style="right: 2.5px">
|
||||||
|
<%- include("../svg/log-out.svg") %>
|
||||||
|
</span>
|
||||||
|
<span class="usermenu-item-name">{{
|
||||||
|
$root.getLz("term.logout")
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
<transition name="sidebartransition">
|
||||||
<%- include("sidebar") %>
|
<%- include("sidebar") %>
|
||||||
|
</transition>
|
||||||
<%- include("app-content") %>
|
<%- include("app-content") %>
|
||||||
<transition name="drawertransition">
|
<transition name="drawertransition">
|
||||||
<div class="app-drawer"
|
<div class="app-drawer"
|
||||||
|
|
|
@ -1,239 +1,483 @@
|
||||||
<div class="app-chrome" :style="{'display': chrome.topChromeVisible ? '' : 'none'}">
|
<div
|
||||||
|
class="app-chrome"
|
||||||
|
:style="{'display': chrome.topChromeVisible ? '' : 'none'}"
|
||||||
|
>
|
||||||
<div class="app-chrome--left">
|
<div class="app-chrome--left">
|
||||||
<div class="app-chrome-item full-height" v-if="chrome.windowControlPosition == 'left' && !chrome.nativeControls">
|
<div
|
||||||
|
class="app-chrome-item full-height"
|
||||||
|
v-if="chrome.windowControlPosition == 'left' && !chrome.nativeControls"
|
||||||
|
>
|
||||||
<div class="window-controls-macos">
|
<div class="window-controls-macos">
|
||||||
<div class="close" @click="ipcRenderer.send('close')"></div>
|
<div class="close" @click="ipcRenderer.send('close')"></div>
|
||||||
<div class="minimize" @click="ipcRenderer.send('minimize')"></div>
|
<div class="minimize" @click="ipcRenderer.send('minimize')"></div>
|
||||||
<div class="minmax restore" v-if="chrome.maximized"
|
<div
|
||||||
@click="ipcRenderer.send('maximize')">
|
class="minmax restore"
|
||||||
</div>
|
v-if="chrome.maximized"
|
||||||
|
@click="ipcRenderer.send('maximize')"
|
||||||
|
></div>
|
||||||
<div class="minmax" v-else @click="ipcRenderer.send('maximize')"></div>
|
<div class="minmax" v-else @click="ipcRenderer.send('maximize')"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item full-height" v-else>
|
<div class="app-chrome-item full-height" v-else>
|
||||||
<button class="app-mainmenu"
|
<button
|
||||||
@blur="mainMenuVisibility(false)"
|
class="app-mainmenu"
|
||||||
@click="mainMenuVisibility(true)"
|
@blur="mainMenuVisibility(false, true)"
|
||||||
|
@click="mainMenuVisibility(true, false)"
|
||||||
|
@contextmenu="mainMenuVisibility(true, true)"
|
||||||
:class="{active: chrome.menuOpened}"
|
:class="{active: chrome.menuOpened}"
|
||||||
:aria-label="$root.getLz('term.quickNav')"></button>
|
:aria-label="$root.getLz('term.quickNav')"
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="getThemeDirective('appNavigation') != 'seperate'">
|
<template v-if="getThemeDirective('appNavigation') != 'seperate'">
|
||||||
<div class="vdiv display--large" v-if="getThemeDirective('windowLayout') == 'twopanel'"></div>
|
<div
|
||||||
|
class="vdiv"
|
||||||
|
v-if="getThemeDirective('windowLayout') == 'twopanel'"
|
||||||
|
></div>
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button navigation" @click="navigateBack()"
|
<button
|
||||||
:title="$root.getLz('term.navigateBack')" v-b-tooltip.hover>
|
class="playback-button navigation"
|
||||||
|
@click="navigateBack()"
|
||||||
|
:title="$root.getLz('term.navigateBack')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
>
|
||||||
<%- include('../svg/chevron-left.svg') %>
|
<%- include('../svg/chevron-left.svg') %>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button navigation" @click="navigateForward()"
|
<button
|
||||||
:title="$root.getLz('term.navigateForward')" v-b-tooltip.hover>
|
class="playback-button navigation"
|
||||||
|
@click="navigateForward()"
|
||||||
|
:title="$root.getLz('term.navigateForward')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
>
|
||||||
<%- include('../svg/chevron-right.svg') %>
|
<%- include('../svg/chevron-right.svg') %>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="vdiv display--large" v-if="getThemeDirective('windowLayout') != 'twopanel'"></div>
|
<div class="app-chrome-item" v-if="cfg.advanced.experiments.includes('collapseSidebar')">
|
||||||
|
<button
|
||||||
|
class="playback-button collapseLibrary"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
:title="chrome.sidebarCollapsed ? getLz('action.showLibrary') : getLz('action.hideLibrary')"
|
||||||
|
@click="chrome.sidebarCollapsed = !chrome.sidebarCollapsed">
|
||||||
|
<transition name="fade">
|
||||||
|
<span v-if="chrome.sidebarCollapsed"></span>
|
||||||
|
</transition>
|
||||||
|
<transition name="fade">
|
||||||
|
<span v-if="!chrome.sidebarCollapsed"></span>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="vdiv display--large"
|
||||||
|
v-if="getThemeDirective('windowLayout') != 'twopanel'"
|
||||||
|
></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||||
<div class="app-chrome-item display--large">
|
<div class="app-chrome-item display--large">
|
||||||
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0" :class="isDisabled() && 'disabled'"
|
<button
|
||||||
@click="mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')"
|
class="playback-button--small shuffle"
|
||||||
v-b-tooltip.hover></button>
|
v-if="mk.shuffleMode == 0"
|
||||||
<button class="playback-button--small shuffle active" v-else :class="isDisabled() && 'disabled'"
|
:class="isDisabled() && 'disabled'"
|
||||||
@click="mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')"
|
@click="mk.shuffleMode = 1"
|
||||||
v-b-tooltip.hover></button>
|
:title="$root.getLz('term.enableShuffle')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button--small shuffle active"
|
||||||
|
v-else
|
||||||
|
:class="isDisabled() && 'disabled'"
|
||||||
|
@click="mk.shuffleMode = 0"
|
||||||
|
:title="$root.getLz('term.disableShuffle')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item display--large">
|
<div class="app-chrome-item display--large">
|
||||||
<button class="playback-button previous" @click="prevButton()" :class="isPrevDisabled() && 'disabled'"
|
<button
|
||||||
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
|
class="playback-button previous"
|
||||||
|
@click="prevButton()"
|
||||||
|
:class="isPrevDisabled() && 'disabled'"
|
||||||
|
:title="$root.getLz('term.previous')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item display--large">
|
<div class="app-chrome-item display--large">
|
||||||
<button class="playback-button stop" @click="mk.stop()" v-if="mk.isPlaying && mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
|
<button
|
||||||
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
|
class="playback-button stop"
|
||||||
<button class="playback-button pause" @click="mk.pause()" v-else-if="mk.isPlaying"
|
@click="mk.stop()"
|
||||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
v-if="mk.isPlaying && mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
|
||||||
<button class="playback-button play" @click="mk.play()" v-else
|
:title="$root.getLz('term.stop')"
|
||||||
:title="$root.getLz('term.play')" v-b-tooltip.hover></button>
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button pause"
|
||||||
|
@click="mk.pause()"
|
||||||
|
v-else-if="mk.isPlaying"
|
||||||
|
:title="$root.getLz('term.pause')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button play"
|
||||||
|
@click="mk.play()"
|
||||||
|
v-else
|
||||||
|
:title="$root.getLz('term.play')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item display--large">
|
<div class="app-chrome-item display--large">
|
||||||
<button class="playback-button next" @click="skipToNextItem()" :class="isNextDisabled() && 'disabled'"
|
<button
|
||||||
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
|
class="playback-button next"
|
||||||
|
@click="skipToNextItem()"
|
||||||
|
:class="isNextDisabled() && 'disabled'"
|
||||||
|
:title="$root.getLz('term.next')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item display--large">
|
<div class="app-chrome-item display--large">
|
||||||
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0" :class="isDisabled() && 'disabled'"
|
<button
|
||||||
@click="mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')"
|
class="playback-button--small repeat"
|
||||||
v-b-tooltip.hover></button>
|
v-if="mk.repeatMode == 0"
|
||||||
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2" :class="isDisabled() && 'disabled'"
|
:class="isDisabled() && 'disabled'"
|
||||||
v-else-if="mk.repeatMode == 1" :title="$root.getLz('term.disableRepeatOne')"
|
@click="mk.repeatMode = 1"
|
||||||
v-b-tooltip.hover></button>
|
:title="$root.getLz('term.enableRepeatOne')"
|
||||||
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0" :class="isDisabled() && 'disabled'"
|
v-b-tooltip.hover
|
||||||
v-else-if="mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
|
></button>
|
||||||
v-b-tooltip.hover></button>
|
<button
|
||||||
|
class="playback-button--small repeat repeatOne"
|
||||||
|
@click="mk.repeatMode = 2"
|
||||||
|
:class="isDisabled() && 'disabled'"
|
||||||
|
v-else-if="mk.repeatMode == 1"
|
||||||
|
:title="$root.getLz('term.disableRepeatOne')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button--small repeat active"
|
||||||
|
@click="mk.repeatMode = 0"
|
||||||
|
:class="isDisabled() && 'disabled'"
|
||||||
|
v-else-if="mk.repeatMode == 2"
|
||||||
|
:title="$root.getLz('term.disableRepeat')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome--center">
|
<div class="app-chrome--center">
|
||||||
<div class="app-chrome-item playback-controls" v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
<div
|
||||||
|
class="app-chrome-item playback-controls"
|
||||||
|
v-if="getThemeDirective('windowLayout') != 'twopanel'"
|
||||||
|
>
|
||||||
<template v-if="mkReady()">
|
<template v-if="mkReady()">
|
||||||
<div class="app-playback-controls" @mouseover="chrome.progresshover = true"
|
<div
|
||||||
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
|
class="app-playback-controls"
|
||||||
|
@mouseover="chrome.progresshover = true"
|
||||||
|
@mouseleave="chrome.progresshover = false"
|
||||||
|
@contextmenu="nowPlayingContextMenu"
|
||||||
|
>
|
||||||
<div class="artwork" id="artworkLCD">
|
<div class="artwork" id="artworkLCD">
|
||||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||||
</div>
|
</div>
|
||||||
<b-popover custom-class="mediainfo-popover" target="artworkLCD" triggers="hover" placement="bottom">
|
<b-popover
|
||||||
|
custom-class="mediainfo-popover"
|
||||||
|
target="artworkLCD"
|
||||||
|
triggers="hover"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="shadow-artwork">
|
<div class="shadow-artwork">
|
||||||
<mediaitem-artwork :url="currentArtUrl" :url="currentArtUrlRaw"></mediaitem-artwork>
|
<mediaitem-artwork
|
||||||
|
:url="currentArtUrl"
|
||||||
|
:url="currentArtUrlRaw"
|
||||||
|
></mediaitem-artwork>
|
||||||
</div>
|
</div>
|
||||||
<div class="popover-artwork">
|
<div class="popover-artwork">
|
||||||
<mediaitem-artwork :size="210" :url="currentArtUrlRaw"></mediaitem-artwork>
|
<mediaitem-artwork
|
||||||
|
:size="210"
|
||||||
|
:url="currentArtUrlRaw"
|
||||||
|
></mediaitem-artwork>
|
||||||
</div>
|
</div>
|
||||||
<div class="song-name">{{ mk.nowPlayingItem["attributes"]["name"] }}</div>
|
<div class="song-name">
|
||||||
<div class="song-artist" @click="getNowPlayingItemDetailed(`artist`)">{{ mk.nowPlayingItem["attributes"]["artistName"] }}</div>
|
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
||||||
<div class="song-album" @click="getNowPlayingItemDetailed(`album`)">
|
|
||||||
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
|
|
||||||
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<div
|
||||||
<div class="btn-group" style="width:100%;">
|
class="song-artist"
|
||||||
<button class="md-btn md-btn-small" style="width: 100%;" @click="drawer.open = false; miniPlayer(true)">{{ $root.getLz("term.miniplayer") }}</button>
|
@click="getNowPlayingItemDetailed(`artist`)"
|
||||||
<button class="md-btn md-btn-small" style="width: 100%;" @click="drawer.open = false; fullscreen(true)">{{ $root.getLz("term.fullscreenView") }}</button>
|
>
|
||||||
|
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="song-album"
|
||||||
|
@click="getNowPlayingItemDetailed(`album`)"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
mk.nowPlayingItem["attributes"]["albumName"]
|
||||||
|
? mk.nowPlayingItem["attributes"]["albumName"]
|
||||||
|
: ""
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="btn-group" style="width: 100%">
|
||||||
|
<button
|
||||||
|
class="md-btn md-btn-small"
|
||||||
|
style="width: 100%"
|
||||||
|
@click="drawer.open = false; miniPlayer(true)"
|
||||||
|
>
|
||||||
|
{{ $root.getLz("term.miniplayer") }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="md-btn md-btn-small"
|
||||||
|
style="width: 100%"
|
||||||
|
@click="drawer.open = false; fullscreen(true)"
|
||||||
|
>
|
||||||
|
{{ $root.getLz("term.fullscreenView") }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</b-popover>
|
</b-popover>
|
||||||
<div class="playback-info">
|
<div class="playback-info">
|
||||||
<div class="chrome-icon-container">
|
<div class="chrome-icon-container">
|
||||||
<div class="audio-type private-icon" v-if="cfg.general.privateEnabled === true"></div>
|
<div
|
||||||
<div class="audio-type ppe-icon" v-if="cfg.audio.maikiwiAudio.ciderPPE === true"></div>
|
class="audio-type private-icon"
|
||||||
|
v-if="cfg.general.privateEnabled === true"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="audio-type ppe-icon"
|
||||||
|
v-if="cfg.audio.maikiwiAudio.ciderPPE === true"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="song-name"
|
<div
|
||||||
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']">
|
class="song-name"
|
||||||
|
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']"
|
||||||
|
>
|
||||||
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
||||||
<div class="explicit-icon"
|
<div
|
||||||
|
class="explicit-icon"
|
||||||
v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'"
|
v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'"
|
||||||
style="display: inline-block"></div>
|
style="display: inline-block"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="song-artist-album">
|
<div class="song-artist-album">
|
||||||
<div class="song-artist-album-content"
|
<div
|
||||||
|
class="song-artist-album-content"
|
||||||
:class="[isElementOverflowing('#app-main > .app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album > .song-artist-album-content') ? 'marquee' : '']"
|
:class="[isElementOverflowing('#app-main > .app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album > .song-artist-album-content') ? 'marquee' : '']"
|
||||||
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap;">
|
style="
|
||||||
<div class="item-navigate song-artist" style="display: inline-block"
|
display: inline-block;
|
||||||
@click="getNowPlayingItemDetailed(`artist`)">
|
-webkit-box-orient: horizontal;
|
||||||
|
white-space: nowrap;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="item-navigate song-artist"
|
||||||
|
style="display: inline-block"
|
||||||
|
@click="getNowPlayingItemDetailed(`artist`)"
|
||||||
|
>
|
||||||
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
|
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="song-artist item-navigate" style="display: inline-block"
|
<div
|
||||||
|
class="song-artist item-navigate"
|
||||||
|
style="display: inline-block"
|
||||||
@click="getNowPlayingItemDetailed('album')"
|
@click="getNowPlayingItemDetailed('album')"
|
||||||
v-if="mk.nowPlayingItem['attributes']['albumName'] != ''">
|
v-if="mk.nowPlayingItem['attributes']['albumName'] != ''"
|
||||||
<div class="separator" style="display: inline-block;">{{"—"}}</div>
|
>
|
||||||
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
|
<div class="separator" style="display: inline-block">
|
||||||
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
|
{{ "—" }}
|
||||||
|
</div>
|
||||||
|
{{
|
||||||
|
mk.nowPlayingItem["attributes"]["albumName"]
|
||||||
|
? mk.nowPlayingItem["attributes"]["albumName"]
|
||||||
|
: ""
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="song-progress">
|
<div class="song-progress">
|
||||||
<div class="song-duration"
|
<div
|
||||||
style="justify-content: space-between; height: 1px;"
|
class="song-duration"
|
||||||
:style="[chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
style="justify-content: space-between; height: 1px"
|
||||||
|
:style="[chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]"
|
||||||
|
>
|
||||||
<p style="width: auto">{{ convertTime(getSongProgress()) }}</p>
|
<p style="width: auto">{{ convertTime(getSongProgress()) }}</p>
|
||||||
<p style="width: auto">{{ convertTime(mk.currentPlaybackDuration) }}
|
<p style="width: auto">
|
||||||
|
{{ convertTime(mk.currentPlaybackDuration) }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
|
<input
|
||||||
|
type="range"
|
||||||
|
step="0.01"
|
||||||
|
min="0"
|
||||||
|
:style="progressBarStyle()"
|
||||||
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
|
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
|
||||||
@mouseup="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
@mouseup="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
||||||
@touchend="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
@touchend="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
||||||
:max="mk.currentPlaybackDuration" :value="getSongProgress()">
|
:max="mk.currentPlaybackDuration"
|
||||||
|
:value="getSongProgress()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
|
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="lcdMenu" @click="nowPlayingContextMenu"
|
<button
|
||||||
:title="$root.getLz('term.more')" v-b-tooltip.hover>
|
class="lcdMenu"
|
||||||
|
@click="nowPlayingContextMenu"
|
||||||
|
:title="$root.getLz('term.more')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
>
|
||||||
<div class="svg-icon"></div>
|
<div class="svg-icon"></div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item" v-else>
|
<div class="app-chrome-item" v-else>
|
||||||
<div class="search-input-container">
|
<div class="top-nav-group">
|
||||||
<div class="search-input--icon"></div>
|
<sidebar-library-item
|
||||||
<input type="search" spellcheck="false" @click="showSearch()" @focus="search.showHints = true"
|
:name="$root.getLz('home.title')"
|
||||||
@blur="setTimeout(()=>{search.showHints = false}, 300)"
|
svg-icon="./assets/feather/home.svg"
|
||||||
v-on:keyup.enter="searchQuery();search.showHints = false" @change="showSearch();"
|
page="home"
|
||||||
@input="getSearchHints()" :placeholder="$root.getLz('term.search') + '...'" v-model="search.term"
|
>
|
||||||
ref="searchInput" class="search-input">
|
</sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
|
:name="$root.getLz('term.listenNow')"
|
||||||
<div class="search-hints">
|
svg-icon="./assets/feather/play-circle.svg"
|
||||||
<button class="search-hint text-overflow-elipsis" v-for="hint in search.hints"
|
page="listen_now"
|
||||||
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
|
></sidebar-library-item>
|
||||||
{{ hint }}
|
<sidebar-library-item
|
||||||
</button>
|
:name="$root.getLz('term.browse')"
|
||||||
</div>
|
svg-icon="./assets/feather/globe.svg"
|
||||||
</div>
|
page="browse"
|
||||||
|
>
|
||||||
|
</sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
|
:name="$root.getLz('term.radio')"
|
||||||
|
svg-icon="./assets/feather/radio.svg"
|
||||||
|
page="radio"
|
||||||
|
></sidebar-library-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome--right">
|
<div class="app-chrome--right">
|
||||||
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||||
<div class="app-chrome-item volume display--large">
|
<div class="app-chrome-item volume display--large">
|
||||||
<button class="volume-button--small volume" @click="muteButtonPressed()"
|
<button
|
||||||
|
class="volume-button--small volume"
|
||||||
|
@click="muteButtonPressed()"
|
||||||
:class="{'active': this.cfg.audio.volume == 0}"
|
:class="{'active': this.cfg.audio.volume == 0}"
|
||||||
:title="cfg.audio.muted ? $root.getLz('term.unmute') : $root.getLz('term.mute')"
|
:title="cfg.audio.muted ? $root.getLz('term.unmute') : $root.getLz('term.mute')"
|
||||||
v-b-tooltip.hover></button>
|
v-b-tooltip.hover
|
||||||
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
|
></button>
|
||||||
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
|
<input
|
||||||
v-b-tooltip.hover :title="formatVolumeTooltip()">
|
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-b-tooltip.hover
|
||||||
|
:title="formatVolumeTooltip()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item generic">
|
<div class="app-chrome-item generic">
|
||||||
<button class="playback-button--small cast"
|
<button
|
||||||
|
class="playback-button--small cast"
|
||||||
:title="$root.getLz('term.cast')"
|
:title="$root.getLz('term.cast')"
|
||||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item generic">
|
<div class="app-chrome-item generic">
|
||||||
<button class="playback-button--small queue"
|
<button
|
||||||
|
class="playback-button--small queue"
|
||||||
:title="$root.getLz('term.queue')"
|
:title="$root.getLz('term.queue')"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
:class="{'active': drawer.panel == 'queue'}"
|
:class="{'active': drawer.panel == 'queue'}"
|
||||||
@click="invokeDrawer('queue')"></button>
|
@click="invokeDrawer('queue')"
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item generic">
|
<div class="app-chrome-item generic">
|
||||||
<template v-if="lyrics && lyrics != [] && lyrics.length > 0">
|
<template v-if="lyrics && lyrics != [] && lyrics.length > 0">
|
||||||
<button class="playback-button--small lyrics"
|
<button
|
||||||
|
class="playback-button--small lyrics"
|
||||||
:title="$root.getLz('term.lyrics')"
|
:title="$root.getLz('term.lyrics')"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
:class="{'active': drawer.panel == 'lyrics'}"
|
:class="{'active': drawer.panel == 'lyrics'}"
|
||||||
@click="invokeDrawer('lyrics')"></button>
|
@click="invokeDrawer('lyrics')"
|
||||||
|
></button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<button class="playback-button--small lyrics"
|
<button
|
||||||
:style="{'opacity': 0.3, 'pointer-events': 'none'}"></button>
|
class="playback-button--small lyrics"
|
||||||
|
:style="{'opacity': 0.3, 'pointer-events': 'none'}"
|
||||||
|
></button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="app-chrome-item full-height" id="window-controls-container"
|
<template v-else>
|
||||||
v-if="chrome.windowControlPosition == 'right' && !chrome.nativeControls">
|
<div class="app-chrome-item search">
|
||||||
|
<div class="search-input-container">
|
||||||
|
<div class="search-input--icon"></div>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
spellcheck="false"
|
||||||
|
@click="showSearch()"
|
||||||
|
@focus="search.showHints = true"
|
||||||
|
@blur="setTimeout(()=>{search.showHints = false}, 300)"
|
||||||
|
v-on:keyup.enter="searchQuery();search.showHints = false"
|
||||||
|
@change="showSearch();"
|
||||||
|
@input="getSearchHints()"
|
||||||
|
:placeholder="$root.getLz('term.search') + '...'"
|
||||||
|
v-model="search.term"
|
||||||
|
ref="searchInput"
|
||||||
|
class="search-input"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="search-hints-container"
|
||||||
|
v-if="search.showHints && search.hints.length != 0"
|
||||||
|
>
|
||||||
|
<div class="search-hints">
|
||||||
|
<button
|
||||||
|
class="search-hint text-overflow-elipsis"
|
||||||
|
v-for="hint in search.hints"
|
||||||
|
@click="search.term = hint;search.showHints = false;searchQuery(hint)"
|
||||||
|
>
|
||||||
|
{{ hint }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
class="app-chrome-item full-height"
|
||||||
|
id="window-controls-container"
|
||||||
|
v-if="chrome.windowControlPosition == 'right' && !chrome.nativeControls"
|
||||||
|
>
|
||||||
<div class="window-controls">
|
<div class="window-controls">
|
||||||
<div class="minimize" @click="ipcRenderer.send('minimize')"></div>
|
<div class="minimize" @click="ipcRenderer.send('minimize')"></div>
|
||||||
<div class="minmax restore" v-if="chrome.maximized"
|
<div
|
||||||
@click="ipcRenderer.send('maximize')">
|
class="minmax restore"
|
||||||
</div>
|
v-if="chrome.maximized"
|
||||||
|
@click="ipcRenderer.send('maximize')"
|
||||||
|
></div>
|
||||||
<div class="minmax" v-else @click="ipcRenderer.send('maximize')"></div>
|
<div class="minmax" v-else @click="ipcRenderer.send('maximize')"></div>
|
||||||
<div class="close" @click="ipcRenderer.send('close')"></div>
|
<div class="close" @click="ipcRenderer.send('close')"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item full-height" v-else-if="platform != 'darwin' && !chrome.nativeControls">
|
<div
|
||||||
<button class="app-mainmenu"
|
class="app-chrome-item full-height"
|
||||||
@blur="mainMenuVisibility(false)"
|
v-else-if="platform != 'darwin' && !chrome.nativeControls"
|
||||||
@click="mainMenuVisibility(true)"
|
>
|
||||||
:class="{active: chrome.menuOpened}"></button>
|
<button
|
||||||
|
class="app-mainmenu"
|
||||||
|
@blur="mainMenuVisibility(false, true)"
|
||||||
|
@click="mainMenuVisibility(true, false)"
|
||||||
|
@contextmenu="mainMenuVisibility(true, true)"
|
||||||
|
:class="{active: chrome.menuOpened}"
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<add-to-playlist :playlists="playlists.listing" v-if="modals.addToPlaylist"></add-to-playlist>
|
<add-to-playlist :playlists="playlists.listing" v-if="modals.addToPlaylist"></add-to-playlist>
|
||||||
</transition>
|
</transition>
|
||||||
<transition name="modal">
|
|
||||||
<spatial-properties v-if="modals.spatialProperties"></spatial-properties>
|
|
||||||
</transition>
|
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<audio-controls v-if="modals.audioControls"></audio-controls>
|
<audio-controls v-if="modals.audioControls"></audio-controls>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
|
@ -1,18 +1,34 @@
|
||||||
<div id="app-sidebar">
|
<div id="app-sidebar" v-if="!chrome.sidebarCollapsed">
|
||||||
|
<template >
|
||||||
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||||
<div class="app-sidebar-header">
|
<div class="app-sidebar-header">
|
||||||
<div class="search-input-container">
|
<div class="search-input-container">
|
||||||
<div class="search-input--icon"></div>
|
<div class="search-input--icon"></div>
|
||||||
<input type="search" spellcheck="false" @click="showSearch()" @focus="search.showHints = true"
|
<input
|
||||||
|
type="search"
|
||||||
|
spellcheck="false"
|
||||||
|
@click="showSearch()"
|
||||||
|
@focus="search.showHints = true"
|
||||||
@blur="setTimeout(()=>{search.showHints = false}, 300)"
|
@blur="setTimeout(()=>{search.showHints = false}, 300)"
|
||||||
v-on:keyup.enter="searchQuery();search.showHints = false" @change="showSearch();"
|
v-on:keyup.enter="searchQuery();search.showHints = false"
|
||||||
@input="getSearchHints()" :placeholder="$root.getLz('term.search') + '...'" v-model="search.term"
|
@change="showSearch();"
|
||||||
ref="searchInput" class="search-input">
|
@input="getSearchHints()"
|
||||||
|
:placeholder="$root.getLz('term.search') + '...'"
|
||||||
|
v-model="search.term"
|
||||||
|
ref="searchInput"
|
||||||
|
class="search-input"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
|
<div
|
||||||
|
class="search-hints-container"
|
||||||
|
v-if="search.showHints && search.hints.length != 0"
|
||||||
|
>
|
||||||
<div class="search-hints">
|
<div class="search-hints">
|
||||||
<button class="search-hint text-overflow-elipsis" v-for="hint in search.hints"
|
<button
|
||||||
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
|
class="search-hint text-overflow-elipsis"
|
||||||
|
v-for="hint in search.hints"
|
||||||
|
@click="search.term = hint;search.showHints = false;searchQuery(hint)"
|
||||||
|
>
|
||||||
{{ hint }}
|
{{ hint }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,224 +38,266 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="app-sidebar-content" scrollaxis="y">
|
<div class="app-sidebar-content" scrollaxis="y">
|
||||||
<div class="app-sidebar-header-text"
|
<!-- AM Navigation -->
|
||||||
|
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||||
|
<div
|
||||||
|
class="app-sidebar-header-text"
|
||||||
@click="cfg.general.sidebarCollapsed.cider = !cfg.general.sidebarCollapsed.cider"
|
@click="cfg.general.sidebarCollapsed.cider = !cfg.general.sidebarCollapsed.cider"
|
||||||
:class="{collapsed: cfg.general.sidebarCollapsed.cider}">
|
:class="{collapsed: cfg.general.sidebarCollapsed.cider}"
|
||||||
{{$root.getLz('app.name')}}
|
>
|
||||||
|
{{ $root.getLz("app.name") }}
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!cfg.general.sidebarCollapsed.cider">
|
<template v-if="!cfg.general.sidebarCollapsed.cider">
|
||||||
<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>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="app-sidebar-header-text"
|
<div
|
||||||
|
class="app-sidebar-header-text"
|
||||||
@click="cfg.general.sidebarCollapsed.applemusic = !cfg.general.sidebarCollapsed.applemusic"
|
@click="cfg.general.sidebarCollapsed.applemusic = !cfg.general.sidebarCollapsed.applemusic"
|
||||||
:class="{collapsed: cfg.general.sidebarCollapsed.applemusic}">
|
:class="{collapsed: cfg.general.sidebarCollapsed.applemusic}"
|
||||||
{{$root.getLz('term.appleMusic')}}
|
>
|
||||||
|
{{ $root.getLz("term.appleMusic") }}
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!cfg.general.sidebarCollapsed.applemusic">
|
<template v-if="!cfg.general.sidebarCollapsed.applemusic">
|
||||||
<sidebar-library-item :name="$root.getLz('term.listenNow')" svg-icon="./assets/feather/play-circle.svg"
|
<sidebar-library-item
|
||||||
page="listen_now"></sidebar-library-item>
|
:name="$root.getLz('term.listenNow')"
|
||||||
<sidebar-library-item :name="$root.getLz('term.browse')" svg-icon="./assets/feather/globe.svg"
|
svg-icon="./assets/feather/play-circle.svg"
|
||||||
page="browse">
|
page="listen_now"
|
||||||
|
></sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
|
:name="$root.getLz('term.browse')"
|
||||||
|
svg-icon="./assets/feather/globe.svg"
|
||||||
|
page="browse"
|
||||||
|
>
|
||||||
</sidebar-library-item>
|
</sidebar-library-item>
|
||||||
<sidebar-library-item :name="$root.getLz('term.radio')" svg-icon="./assets/feather/radio.svg"
|
<sidebar-library-item
|
||||||
page="radio"></sidebar-library-item>
|
:name="$root.getLz('term.radio')"
|
||||||
|
svg-icon="./assets/feather/radio.svg"
|
||||||
|
page="radio"
|
||||||
|
></sidebar-library-item>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="app-sidebar-header-text"
|
<div
|
||||||
|
class="app-sidebar-header-text"
|
||||||
@click="cfg.general.sidebarCollapsed.library = !cfg.general.sidebarCollapsed.library"
|
@click="cfg.general.sidebarCollapsed.library = !cfg.general.sidebarCollapsed.library"
|
||||||
:class="{collapsed: cfg.general.sidebarCollapsed.library}">
|
:class="{collapsed: cfg.general.sidebarCollapsed.library}"
|
||||||
{{$root.getLz('term.library')}}
|
>
|
||||||
|
{{ $root.getLz("term.library") }}
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!cfg.general.sidebarCollapsed.library">
|
<template v-if="!cfg.general.sidebarCollapsed.library">
|
||||||
<sidebar-library-item :name="$root.getLz('term.recentlyAdded')" svg-icon="./assets/feather/plus-circle.svg"
|
<sidebar-library-item
|
||||||
v-if="cfg.general.sidebarItems.recentlyAdded" page="library-recentlyadded"></sidebar-library-item>
|
:name="$root.getLz('term.recentlyAdded')"
|
||||||
<sidebar-library-item :name="$root.getLz('term.songs')" svg-icon="./assets/feather/music.svg"
|
svg-icon="./assets/feather/plus-circle.svg"
|
||||||
v-if="cfg.general.sidebarItems.songs" page="library-songs"></sidebar-library-item>
|
v-if="cfg.general.sidebarItems.recentlyAdded"
|
||||||
<sidebar-library-item :name="$root.getLz('term.albums')" svg-icon="./assets/feather/disc.svg"
|
page="library-recentlyadded"
|
||||||
v-if="cfg.general.sidebarItems.albums" page="library-albums"></sidebar-library-item>
|
></sidebar-library-item>
|
||||||
<sidebar-library-item :name="$root.getLz('term.artists')" svg-icon="./assets/feather/user.svg"
|
<sidebar-library-item
|
||||||
v-if="cfg.general.sidebarItems.artists" page="library-artists"></sidebar-library-item>
|
:name="$root.getLz('term.songs')"
|
||||||
<sidebar-library-item :name="$root.getLz('term.videos')" svg-icon="./assets/feather/video.svg"
|
svg-icon="./assets/feather/music.svg"
|
||||||
v-if="cfg.general.sidebarItems.videos" page="library-videos"></sidebar-library-item>
|
v-if="cfg.general.sidebarItems.songs"
|
||||||
<sidebar-library-item :name="$root.getLz('term.podcasts')" svg-icon="./assets/feather/mic.svg"
|
page="library-songs"
|
||||||
v-if="cfg.general.sidebarItems.podcasts" page="podcasts">
|
></sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
|
:name="$root.getLz('term.albums')"
|
||||||
|
svg-icon="./assets/feather/disc.svg"
|
||||||
|
v-if="cfg.general.sidebarItems.albums"
|
||||||
|
page="library-albums"
|
||||||
|
></sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
|
:name="$root.getLz('term.artists')"
|
||||||
|
svg-icon="./assets/feather/user.svg"
|
||||||
|
v-if="cfg.general.sidebarItems.artists"
|
||||||
|
page="library-artists"
|
||||||
|
></sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
|
:name="$root.getLz('term.videos')"
|
||||||
|
svg-icon="./assets/feather/video.svg"
|
||||||
|
v-if="cfg.general.sidebarItems.videos"
|
||||||
|
page="library-videos"
|
||||||
|
></sidebar-library-item>
|
||||||
|
<sidebar-library-item
|
||||||
|
:name="$root.getLz('term.podcasts')"
|
||||||
|
svg-icon="./assets/feather/mic.svg"
|
||||||
|
v-if="cfg.general.sidebarItems.podcasts"
|
||||||
|
page="podcasts"
|
||||||
|
>
|
||||||
</sidebar-library-item>
|
</sidebar-library-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="getPlaylistFolderChildren('p.applemusic').length != 0">
|
<template v-if="getPlaylistFolderChildren('p.applemusic').length != 0">
|
||||||
<div class="app-sidebar-header-text"
|
<div
|
||||||
|
class="app-sidebar-header-text"
|
||||||
@click="cfg.general.sidebarCollapsed.amplaylists = !cfg.general.sidebarCollapsed.amplaylists"
|
@click="cfg.general.sidebarCollapsed.amplaylists = !cfg.general.sidebarCollapsed.amplaylists"
|
||||||
@contextmenu="playlistHeaderContextMenu"
|
@contextmenu="playlistHeaderContextMenu"
|
||||||
:class="{collapsed: cfg.general.sidebarCollapsed.amplaylists}">
|
:class="{collapsed: cfg.general.sidebarCollapsed.amplaylists}"
|
||||||
{{ $root.getLz('term.appleMusic') }} {{ $root.getLz('term.playlists') }}
|
>
|
||||||
|
{{ $root.getLz("term.appleMusic") }}
|
||||||
|
{{ $root.getLz("term.playlists") }}
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!cfg.general.sidebarCollapsed.amplaylists">
|
<template v-if="!cfg.general.sidebarCollapsed.amplaylists">
|
||||||
<sidebar-playlist v-for="item in getPlaylistFolderChildren('p.applemusic')" :item="item">
|
<sidebar-playlist
|
||||||
|
v-for="item in getPlaylistFolderChildren('p.applemusic')"
|
||||||
|
:item="item"
|
||||||
|
>
|
||||||
</sidebar-playlist>
|
</sidebar-playlist>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<div class="app-sidebar-header-text"
|
<div
|
||||||
|
class="app-sidebar-header-text"
|
||||||
@click="cfg.general.sidebarCollapsed.playlists = !cfg.general.sidebarCollapsed.playlists"
|
@click="cfg.general.sidebarCollapsed.playlists = !cfg.general.sidebarCollapsed.playlists"
|
||||||
@contextmenu="playlistHeaderContextMenu"
|
@contextmenu="playlistHeaderContextMenu"
|
||||||
:class="{collapsed: cfg.general.sidebarCollapsed.playlists}">
|
:class="{collapsed: cfg.general.sidebarCollapsed.playlists}"
|
||||||
{{ $root.getLz('term.playlists') }}
|
>
|
||||||
|
{{ $root.getLz("term.playlists") }}
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!cfg.general.sidebarCollapsed.playlists">
|
<template v-if="!cfg.general.sidebarCollapsed.playlists">
|
||||||
<button class="app-sidebar-item" @click="playlistHeaderContextMenu">
|
<button class="app-sidebar-item" @click="playlistHeaderContextMenu">
|
||||||
<div class="sidebar-icon">
|
<div class="sidebar-icon">
|
||||||
<svg width="46" height="46" fill="none" stroke="currentColor" stroke-linecap="round"
|
<svg
|
||||||
stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
width="46"
|
||||||
|
height="46"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
<path d="M12 5v14"></path>
|
<path d="M12 5v14"></path>
|
||||||
<path d="M5 12h14"></path>
|
<path d="M5 12h14"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
{{ getLz('action.createNew') }}
|
{{ getLz("action.createNew") }}
|
||||||
</button>
|
</button>
|
||||||
<sidebar-playlist v-for="item in getPlaylistFolderChildren('p.playlistsroot')" :item="item">
|
<sidebar-playlist
|
||||||
|
v-for="item in getPlaylistFolderChildren('p.playlistsroot')"
|
||||||
|
:item="item"
|
||||||
|
>
|
||||||
</sidebar-playlist>
|
</sidebar-playlist>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<transition name="wpfade">
|
|
||||||
<div class="usermenu-container" v-if="chrome.menuOpened">
|
|
||||||
<div class="usermenu-body">
|
|
||||||
<button class="app-sidebar-button" style="width:100%" @click="appRoute('apple-account-settings')">
|
|
||||||
|
|
||||||
<img class="sidebar-user-icon" loading="lazy"
|
|
||||||
:src="getMediaItemArtwork(chrome.hideUserInfo ? 'http://localhost:9000/assets/logocut.png' : (chrome.userinfo.attributes['artwork'] ? chrome.userinfo.attributes['artwork']['url'] : ''), 26)" />
|
|
||||||
|
|
||||||
<div class="sidebar-user-text" v-if="!chrome.hideUserInfo">
|
|
||||||
<template v-if="chrome.userinfo.id || mk.isAuthorized">
|
|
||||||
<div class="fullname text-overflow-elipsis">{{ (chrome.userinfo != null &&
|
|
||||||
chrome.userinfo.attributes != null) ? (chrome.userinfo.attributes.name ?? "") :
|
|
||||||
""
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
<div class="handle-text text-overflow-elipsis">{{
|
|
||||||
(chrome.userinfo != null && chrome.userinfo.attributes != null) ?
|
|
||||||
(chrome.userinfo.attributes.handle ?? "") : ""
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<div @click="mk.authorize()">
|
|
||||||
{{$root.getLz('term.login')}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-user-text" v-else>
|
|
||||||
{{$root.getLz('app.name')}}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
<!-- Use 20px SVG for usermenu icon -->
|
|
||||||
<button class="usermenu-item" v-if="cfg.general.privateEnabled" @click="cfg.general.privateEnabled = false">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/x.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.disablePrivateSession')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" @click="appRoute('remote-pair')">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/smartphone.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('action.showWebRemoteQR')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" @click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/cast.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.cast')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" @click="cfg.advanced.AudioContext ? modals.audioSettings = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/headphones.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.audioSettings')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" v-if="pluginInstalled" @click="modals.pluginMenu = true">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/grid.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.plugin')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" @click="appRoute('about')">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/info.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.about')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" @click="appRoute('settings')">
|
|
||||||
<span class="usermenu-item-icon">
|
|
||||||
<%- include("../svg/settings.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.settings')}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="usermenu-item" @click="unauthorize()">
|
|
||||||
<span class="usermenu-item-icon" style="right:2.5px;">
|
|
||||||
<%- include("../svg/log-out.svg") %>
|
|
||||||
</span>
|
|
||||||
<span class="usermenu-item-name">{{$root.getLz('term.logout')}}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
<div class="app-sidebar-footer display--small app-sidebar-footer--controls">
|
<div class="app-sidebar-footer display--small app-sidebar-footer--controls">
|
||||||
|
<div
|
||||||
<div class="app-playback-controls " v-if="mkReady()" @contextmenu="nowPlayingContextMenu">
|
class="app-playback-controls"
|
||||||
|
v-if="mkReady()"
|
||||||
|
@contextmenu="nowPlayingContextMenu"
|
||||||
|
>
|
||||||
<div class="control-buttons">
|
<div class="control-buttons">
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
|
<button
|
||||||
@click="mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')"
|
class="playback-button--small shuffle"
|
||||||
v-b-tooltip.hover.righttop></button>
|
v-if="mk.shuffleMode == 0"
|
||||||
<button class="playback-button--small shuffle active" v-else
|
@click="mk.shuffleMode = 1"
|
||||||
@click="mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')"
|
:title="$root.getLz('term.enableShuffle')"
|
||||||
v-b-tooltip.hover.righttop></button>
|
v-b-tooltip.hover.righttop
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button--small shuffle active"
|
||||||
|
v-else
|
||||||
|
@click="mk.shuffleMode = 0"
|
||||||
|
:title="$root.getLz('term.disableShuffle')"
|
||||||
|
v-b-tooltip.hover.righttop
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button previous" @click="prevButton()"
|
<button
|
||||||
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
|
class="playback-button previous"
|
||||||
|
@click="prevButton()"
|
||||||
|
:title="$root.getLz('term.previous')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button pause" @click="mk.pause()" v-if="mk.isPlaying"
|
<button
|
||||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
class="playback-button pause"
|
||||||
<button class="playback-button play" @click="mk.play()" v-else
|
@click="mk.pause()"
|
||||||
:title="$root.getLz('term.play')" v-b-tooltip.hover></button>
|
v-if="mk.isPlaying"
|
||||||
|
:title="$root.getLz('term.pause')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button play"
|
||||||
|
@click="mk.play()"
|
||||||
|
v-else
|
||||||
|
:title="$root.getLz('term.play')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button next" @click="skipToNextItem()"
|
<button
|
||||||
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
|
class="playback-button next"
|
||||||
|
@click="skipToNextItem()"
|
||||||
|
:title="$root.getLz('term.next')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item">
|
<div class="app-chrome-item">
|
||||||
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
|
<button
|
||||||
@click="mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')"
|
class="playback-button--small repeat"
|
||||||
v-b-tooltip.hover></button>
|
v-if="mk.repeatMode == 0"
|
||||||
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
|
@click="mk.repeatMode = 1"
|
||||||
v-else-if="mk.repeatMode == 1" :title="$root.getLz('term.disableRepeatOne')"
|
:title="$root.getLz('term.enableRepeatOne')"
|
||||||
v-b-tooltip.hover></button>
|
v-b-tooltip.hover
|
||||||
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0"
|
></button>
|
||||||
v-else-if="mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
|
<button
|
||||||
v-b-tooltip.hover></button>
|
class="playback-button--small repeat repeatOne"
|
||||||
|
@click="mk.repeatMode = 2"
|
||||||
|
v-else-if="mk.repeatMode == 1"
|
||||||
|
:title="$root.getLz('term.disableRepeatOne')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
class="playback-button--small repeat active"
|
||||||
|
@click="mk.repeatMode = 0"
|
||||||
|
v-else-if="mk.repeatMode == 2"
|
||||||
|
:title="$root.getLz('term.disableRepeat')"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome-item volume">
|
<div class="app-chrome-item volume">
|
||||||
<div class="input-container">
|
<div class="input-container">
|
||||||
<button class="volume-button--small volume" @click="muteButtonPressed()"
|
<button
|
||||||
|
class="volume-button--small volume"
|
||||||
|
@click="muteButtonPressed()"
|
||||||
:class="{'active': this.cfg.audio.volume == 0}"
|
:class="{'active': this.cfg.audio.volume == 0}"
|
||||||
:title="cfg.audio.muted ? $root.getLz('term.unmute') : $root.getLz('term.mute')"
|
:title="cfg.audio.muted ? $root.getLz('term.unmute') : $root.getLz('term.mute')"
|
||||||
v-b-tooltip.hover></button>
|
v-b-tooltip.hover
|
||||||
<input type="range" class="" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0"
|
></button>
|
||||||
:max="cfg.audio.maxVolume" v-model="mk.volume" v-if="typeof mk.volume != 'undefined'"
|
<input
|
||||||
@change="checkMuteChange()" v-b-tooltip.hover
|
type="range"
|
||||||
:title="formatVolumeTooltip()">
|
class=""
|
||||||
|
@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-b-tooltip.hover
|
||||||
|
:title="formatVolumeTooltip()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-sidebar-notification backgroundNotification" v-if="library.backgroundNotification.show">
|
<div
|
||||||
<div class="message">{{ library.backgroundNotification.message }} ({{
|
class="app-sidebar-notification backgroundNotification"
|
||||||
library.backgroundNotification.progress }} / {{ library.backgroundNotification.total }})
|
v-if="library.backgroundNotification.show"
|
||||||
|
>
|
||||||
|
<div class="message">
|
||||||
|
{{ library.backgroundNotification.message }} ({{
|
||||||
|
library.backgroundNotification.progress
|
||||||
|
}}
|
||||||
|
/ {{ library.backgroundNotification.total }})
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
|
@ -35,6 +35,16 @@
|
||||||
v-model="maxVolume"/>
|
v-model="maxVolume"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="md-option-line">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
{{$root.getLz('settings.option.audio.advanced')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" v-model="app.cfg.audio.advanced" switch/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<div v-if="reasonShown" class="reasonSP ">{{item?.meta?.reason?.stringForDisplay ?? ''}}</div>
|
<div v-if="reasonShown" class="reasonSP ">{{item?.meta?.reason?.stringForDisplay ?? ''}}</div>
|
||||||
<div style="{'--spcolor': getBgColor()}"
|
<div style="{'--spcolor': getBgColor()}"
|
||||||
class="cd-mediaitem-square" :class="getClasses()" @contextmenu="getContextMenu">
|
class="cd-mediaitem-square" :class="getClasses()" @contextmenu="getContextMenu">
|
||||||
<template>
|
<template v-if="isVisible">
|
||||||
<div class="artwork-container">
|
<div class="artwork-container">
|
||||||
<div class="unavailable-overlay" v-if="unavailable">
|
<div class="unavailable-overlay" v-if="unavailable">
|
||||||
<div class="codicon codicon-circle-slash"></div>
|
<div class="codicon codicon-circle-slash"></div>
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
<div class="queue-panel">
|
<div class="queue-panel">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h3 class="queue-header-text">{{app.getLz('term.queue')}}</h3>
|
<h3 class="queue-header-text" v-if="page == 'queue'">{{app.getLz('term.queue')}}</h3>
|
||||||
|
<h3 class="queue-header-text" v-if="page == 'history'">{{app.getLz('term.history')}}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<button class="autoplay" :style="{'background': app.mk.autoplayEnabled ? 'var(--keyColor)' : ''}"
|
<button class="autoplay" :style="{'background': app.mk.autoplayEnabled ? 'var(--keyColor)' : ''}"
|
||||||
|
@ -33,6 +34,12 @@
|
||||||
<div class="queue-title text-overflow-elipsis">{{ queueItem.item.attributes.name }}</div>
|
<div class="queue-title text-overflow-elipsis">{{ queueItem.item.attributes.name }}</div>
|
||||||
<div class="queue-subtitle text-overflow-elipsis">{{ queueItem.item.attributes.artistName }} — {{ queueItem.item.attributes.albumName }}</div>
|
<div class="queue-subtitle text-overflow-elipsis">{{ queueItem.item.attributes.artistName }} — {{ queueItem.item.attributes.albumName }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="queue-explicit-icon flex-center" v-if="queueItem.item.attributes.contentRating == 'explicit'">
|
||||||
|
<div class="explicit-icon"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col queue-duration-info">
|
||||||
|
<div class="queue-duration flex-center">{{convertTimeToString(queueItem.item.attributes.durationInMillis)}}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -167,6 +174,10 @@
|
||||||
this.selected = -1
|
this.selected = -1
|
||||||
app.mk.queue._queueItems = this.queueItems;
|
app.mk.queue._queueItems = this.queueItems;
|
||||||
app.mk.queue._reindex()
|
app.mk.queue._reindex()
|
||||||
|
},
|
||||||
|
convertTimeToString(timeInMilliseconds) {
|
||||||
|
var seconds = ((timeInMilliseconds % 60000) / 1000).toFixed(0);
|
||||||
|
return Math.floor(timeInMilliseconds/60000) + ":" + (seconds < 10 ? '0' : '') + seconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,355 +0,0 @@
|
||||||
<script type="text/x-template" id="spatial-properties">
|
|
||||||
<div class="modal-fullscreen spatialproperties-panel" @click.self="close()" @contextmenu.self="close()">
|
|
||||||
<div class="modal-window" v-if="ready">
|
|
||||||
<div class="modal-header">
|
|
||||||
<div class="modal-title">{{$root.getLz('spatial.spatialProperties')}}</div>
|
|
||||||
<button class="close-btn" @click="close()" :aria-label="$root.getLz('action.close')"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-content">
|
|
||||||
<template v-if="roomEditType == 'dimensions'">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col"><h3>{{$root.getLz('spatial.roomDimensions')}}</h3></div>
|
|
||||||
<div class="col-auto flex-center">
|
|
||||||
<button class="md-btn" @click="roomEditType = 'positions'">{{$root.getLz('spatial.setPositions')}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
{{$root.getLz('spatial.width')}}
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="room_dimensions.width" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="room_dimensions.width" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
{{$root.getLz('spatial.height')}}
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="room_dimensions.height" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="room_dimensions.height" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
{{$root.getLz('spatial.depth')}}
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="room_dimensions.depth" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="room_dimensions.depth" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<label v-if="!app.cfg.audio.normalization">
|
|
||||||
{{$root.getLz('spatial.gain')}}
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="app.cfg.audio.spatial_properties.gain" step="0.1"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col visual-container">
|
|
||||||
<div class="visual" :style="objectContainerStyle()">
|
|
||||||
<div class="face" :style="[faceStyle()]"></div>
|
|
||||||
<div class="face" :style="[faceStyle(), topFaceStyle()]"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-if="roomEditType == 'positions'">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col"><h3>{{$root.getLz('spatial.roomPositions')}}</h3></div>
|
|
||||||
<div class="col-auto flex-center">
|
|
||||||
<button class="md-btn" @click="roomEditType = 'dimensions'">{{$root.getLz('spatial.setDimensions')}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
X ({{$root.getLz('spatial.listener')}})
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="listener_position[0]" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="listener_position[0]" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
Y ({{$root.getLz('spatial.listener')}})
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="listener_position[1]" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="listener_position[1]" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
Z ({{$root.getLz('spatial.listener')}})
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="listener_position[2]" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="listener_position[2]" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
X ({{$root.getLz('spatial.audioSource')}})
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="audio_position[0]" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="audio_position[0]" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
Y ({{$root.getLz('spatial.audioSource')}})
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="audio_position[1]" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="audio_position[1]" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
Z ({{$root.getLz('spatial.audioSource')}})
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
|
||||||
v-model="audio_position[2]" step="1"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 flex-center">
|
|
||||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
|
||||||
v-model="audio_position[2]" step="1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col visual-container">
|
|
||||||
<div class="visual">
|
|
||||||
<div class="face" :style="[faceStyle()]"></div>
|
|
||||||
<div class="face" :style="[faceStyle(), topFaceStyle()]"></div>
|
|
||||||
|
|
||||||
<!-- <div class="listener" :style="[listenerStyle()]">L</div> -->
|
|
||||||
<!-- <div class="audiosource" :style="[audioSourceStyle()]">A</div> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col"><h3>{{$root.getLz('spatial.roomMaterials')}}</h3></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col"></div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<label>
|
|
||||||
{{$root.getLz('spatial.up')}}
|
|
||||||
<select class="md-select" @change="setRoom()"
|
|
||||||
v-model="room_materials.up">
|
|
||||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col"></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col flex-center">
|
|
||||||
<label>
|
|
||||||
{{$root.getLz('spatial.left')}}
|
|
||||||
<select class="md-select" @change="setRoom()"
|
|
||||||
v-model="room_materials.left">
|
|
||||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<label>
|
|
||||||
{{$root.getLz('spatial.front')}}
|
|
||||||
<select class="md-select" @change="setRoom()"
|
|
||||||
v-model="room_materials.front">
|
|
||||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
{{$root.getLz('spatial.back')}}
|
|
||||||
<select class="md-select" @change="setRoom()"
|
|
||||||
v-model="room_materials.back">
|
|
||||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<label>
|
|
||||||
{{$root.getLz('spatial.right')}}
|
|
||||||
<select class="md-select" @change="setRoom()"
|
|
||||||
v-model="room_materials.right">
|
|
||||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col"></div>
|
|
||||||
<div class="col flex-center">
|
|
||||||
<label>
|
|
||||||
{{$root.getLz('spatial.down')}}
|
|
||||||
<select class="md-select" @change="setRoom()"
|
|
||||||
v-model="room_materials.down">
|
|
||||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
Vue.component('spatial-properties', {
|
|
||||||
template: '#spatial-properties',
|
|
||||||
data: function () {
|
|
||||||
return {
|
|
||||||
app: this.$root,
|
|
||||||
room_dimensions: null,
|
|
||||||
room_materials: null,
|
|
||||||
listener_position: null,
|
|
||||||
audio_position: null,
|
|
||||||
roomEditType: "dimensions",
|
|
||||||
roomProps: [
|
|
||||||
'transparent',
|
|
||||||
'acoustic-ceiling-tiles',
|
|
||||||
'brick-bare',
|
|
||||||
'brick-painted',
|
|
||||||
'concrete-block-coarse',
|
|
||||||
'concrete-block-painted',
|
|
||||||
'curtain-heavy',
|
|
||||||
'fiber-glass-insulation',
|
|
||||||
'glass-thin',
|
|
||||||
'glass-thick',
|
|
||||||
'grass',
|
|
||||||
'linoleum-on-concrete',
|
|
||||||
'marble',
|
|
||||||
'metal',
|
|
||||||
'parquet-on-concrete',
|
|
||||||
'plaster-smooth',
|
|
||||||
'plywood-panel',
|
|
||||||
'polished-concrete-or-tile',
|
|
||||||
'sheetrock',
|
|
||||||
'water-or-ice-surface',
|
|
||||||
'wood-ceiling',
|
|
||||||
'wood-panel',
|
|
||||||
'uniform'
|
|
||||||
],
|
|
||||||
visualMultiplier: 4,
|
|
||||||
ready: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {},
|
|
||||||
mounted() {
|
|
||||||
this.room_dimensions = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.room_dimensions))
|
|
||||||
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.listener_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.listener_position))
|
|
||||||
if (typeof this.app.mk.nowPlayingItem != "undefined") {
|
|
||||||
this.setRoom()
|
|
||||||
}
|
|
||||||
this.ready = true
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
listenerStyle() {
|
|
||||||
let style = {
|
|
||||||
transform: `rotateX(60deg) rotateZ(-45deg) translateX(${this.listener_position[0]}px) translateY(${this.listener_position[2]}px) translateZ(${100 + +this.listener_position[1]}px)`
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
audioSourceStyle() {
|
|
||||||
let style = {
|
|
||||||
transform: `rotateX(60deg) rotateZ(-45deg) translateX(${this.audio_position[0]}px) translateY(${this.audio_position[2]}px) translateZ(${100 + +this.audio_position[1]}px)`
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
topFaceStyle() {
|
|
||||||
let style = {
|
|
||||||
transform: `rotateX(60deg) rotateZ(-45deg) translateZ(${this.room_dimensions.height * this.visualMultiplier}px)`
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
objectContainerStyle() {
|
|
||||||
let scale = 1
|
|
||||||
if (this.room_dimensions.width * this.visualMultiplier > 300) {
|
|
||||||
scale = 300 / (this.room_dimensions.width * this.visualMultiplier)
|
|
||||||
}
|
|
||||||
let style = {
|
|
||||||
transform: `scale(${scale})`
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
faceStyle() {
|
|
||||||
let style = {
|
|
||||||
width: `${this.room_dimensions.width * this.visualMultiplier}px`,
|
|
||||||
height: `${this.room_dimensions.depth * this.visualMultiplier}px`,
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.$root.cfg.audio.spatial_properties.room_dimensions = this.room_dimensions
|
|
||||||
this.$root.cfg.audio.spatial_properties.room_materials = this.room_materials
|
|
||||||
this.$root.cfg.audio.spatial_properties.audio_position = this.audio_position
|
|
||||||
this.$root.cfg.audio.spatial_properties.listener_position = this.listener_position
|
|
||||||
app.resetState()
|
|
||||||
},
|
|
||||||
setRoom() {
|
|
||||||
window.CiderAudio.audioNodes.spatialNode.setRoomProperties(this.room_dimensions, this.room_materials);
|
|
||||||
CiderAudio.audioNodes.spatialInput.setPosition(...this.audio_position)
|
|
||||||
CiderAudio.audioNodes.spatialNode.setListenerPosition(...this.listener_position)
|
|
||||||
if (!this.app.cfg.audio.normalization) {
|
|
||||||
window.CiderAudio.audioNodes.gainNode.gain.value = app.cfg.audio.spatial_properties.gain
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
|
@ -58,6 +58,12 @@
|
||||||
#LOADER>svg {
|
#LOADER>svg {
|
||||||
width: 128px;
|
width: 128px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
#LOADER {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -85,6 +91,11 @@
|
||||||
</mini-view>
|
</mini-view>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
<transition name="fsModeSwitch">
|
||||||
|
<div class="fullscreen-view-container oobe" v-if="appMode == 'oobe'">
|
||||||
|
<cider-oobe></cider-oobe>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
<%- include('app/panels'); %>
|
<%- include('app/panels'); %>
|
||||||
<div class="cursor" v-if="chrome.showCursor"></div>
|
<div class="cursor" v-if="chrome.showCursor"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -198,14 +198,6 @@
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleSpatial: function () {
|
|
||||||
if (app.cfg.audio.maikiwiAudio.spatial) {
|
|
||||||
CiderAudio.spatialOn()
|
|
||||||
CiderAudio.hierarchical_loading();
|
|
||||||
} else {
|
|
||||||
CiderAudio.spatialOff()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleMaikiwiSpatial: function () {
|
toggleMaikiwiSpatial: function () {
|
||||||
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
||||||
CiderAudio.spatialOn()
|
CiderAudio.spatialOn()
|
||||||
|
|
|
@ -54,9 +54,16 @@
|
||||||
class="content"
|
class="content"
|
||||||
v-html="data.attributes.description?.short ?? data.attributes.editorialNotes?.short"
|
v-html="data.attributes.description?.short ?? data.attributes.editorialNotes?.short"
|
||||||
@click="openInfoModal()"></div>
|
@click="openInfoModal()"></div>
|
||||||
<div v-else-if="(data.attributes.description?.standard ?? data.attributes.editorialNotes?.standard) != null"
|
<div v-else-if="((data.attributes.description?.standard ?? data.attributes.editorialNotes?.standard) != null) && (descriptionEditing == false)"
|
||||||
class="content"
|
@mouseover="minClass(false)" @click="editPlaylistDescription()">{{data.attributes.description?.standard ?? data.attributes.editorialNotes?.standard}}</div>
|
||||||
v-html="data.attributes.description?.standard ?? data.attributes.editorialNotes?.standard"></div>
|
<div v-else-if="((data.attributes.description?.standard ?? data.attributes.editorialNotes?.standard) != null) && (descriptionEditing)"
|
||||||
|
@mouseover="minClass(false)"><input type="text"
|
||||||
|
spellcheck="false"
|
||||||
|
class="descriptionEdit"
|
||||||
|
v-model="data.attributes.description.standard"
|
||||||
|
@blur="editPlaylist"
|
||||||
|
@change="editPlaylist"
|
||||||
|
@keydown.enter="editPlaylist"/></div>
|
||||||
<!-- <button v-if="(data.attributes.description?.short ?? data.attributes.editorialNotes?.short ) != null" class="more-btn"
|
<!-- <button v-if="(data.attributes.description?.short ?? data.attributes.editorialNotes?.short ) != null" class="more-btn"
|
||||||
@click="editorialNotesExpanded = !editorialNotesExpanded">
|
@click="editorialNotesExpanded = !editorialNotesExpanded">
|
||||||
{{app.getLz('term.showMore')}}
|
{{app.getLz('term.showMore')}}
|
||||||
|
@ -265,6 +272,7 @@
|
||||||
editorialNotesExpanded: false,
|
editorialNotesExpanded: false,
|
||||||
drag: false,
|
drag: false,
|
||||||
nameEditing: false,
|
nameEditing: false,
|
||||||
|
descriptionEditing: false,
|
||||||
inLibrary: null,
|
inLibrary: null,
|
||||||
confirm: false,
|
confirm: false,
|
||||||
app: this.$root,
|
app: this.$root,
|
||||||
|
@ -412,12 +420,24 @@
|
||||||
},
|
},
|
||||||
editPlaylist() {
|
editPlaylist() {
|
||||||
this.app.editPlaylist(this.data.id, this.data.attributes.name);
|
this.app.editPlaylist(this.data.id, this.data.attributes.name);
|
||||||
|
this.app.editPlaylistDescription(this.data.id, this.data.attributes.description.standard);
|
||||||
this.app.playlists.listing.forEach(playlist => {
|
this.app.playlists.listing.forEach(playlist => {
|
||||||
if (playlist.id === this.data.id) {
|
if (playlist.id === this.data.id) {
|
||||||
playlist.attributes.name = this.data.attributes.name
|
playlist.attributes.name = this.data.attributes.name
|
||||||
|
playlist.attributes.description = this.data.attributes.description.standard
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.nameEditing = false
|
this.nameEditing = false
|
||||||
|
this.descriptionEditing = false
|
||||||
|
},
|
||||||
|
editPlaylistDescription() {
|
||||||
|
this.app.editPlaylistDescription(this.data.id, this.data.attributes.description.standard);
|
||||||
|
this.app.playlists.listing.forEach(playlist => {
|
||||||
|
if (playlist.id === this.data.id) {
|
||||||
|
playlist.attributes.description = this.data.attributes.description.standard
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.descriptionEditing = false
|
||||||
},
|
},
|
||||||
addToLibrary(id) {
|
addToLibrary(id) {
|
||||||
app.mk.addToLibrary(id)
|
app.mk.addToLibrary(id)
|
||||||
|
@ -450,6 +470,14 @@
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
editPlaylistDescription() {
|
||||||
|
if (this.data.attributes.canEdit && this.data.type === "library-playlists") {
|
||||||
|
this.descriptionEditing = true
|
||||||
|
setTimeout(() => {
|
||||||
|
document.querySelector(".descriptionEdit").focus()
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
},
|
||||||
buildContextMenu(index) {
|
buildContextMenu(index) {
|
||||||
let self = this
|
let self = this
|
||||||
if (!this.data.attributes.canEdit) {
|
if (!this.data.attributes.canEdit) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script type="text/x-template" id="cider-collection-list">
|
<script type="text/x-template" id="cider-collection-list">
|
||||||
<div class="content-inner collection-page">
|
<div class="content-inner collection-page">
|
||||||
<h3 class="header-text" v-observe-visibility="{callback: headerVisibility}">{{ title }}</h3>
|
<h3 class="header-text" v-observe-visibility="{callback: headerVisibility}">{{ title }}</h3>
|
||||||
<div v-if="data['data'] != 'null'" class="well itemContainer">
|
<div v-if="data['data'] != 'null'" class="well itemContainer" :class="getClasses()">
|
||||||
<template v-for="(item, key) in data.data">
|
<template v-for="(item, key) in data.data">
|
||||||
<template v-if="item.type == 'artists'">
|
<template v-if="item.type == 'artists'">
|
||||||
<mediaitem-square :item="item"></mediaitem-square>
|
<mediaitem-square :item="item"></mediaitem-square>
|
||||||
|
@ -57,6 +57,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getClasses() {
|
||||||
|
if(this.commonKind != "song") {
|
||||||
|
return "collection-list-square";
|
||||||
|
}else{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
getKind(item) {
|
getKind(item) {
|
||||||
if (typeof item.kind != "undefined") {
|
if (typeof item.kind != "undefined") {
|
||||||
this.commonKind = item.kind;
|
this.commonKind = item.kind;
|
||||||
|
|
|
@ -1,58 +1,70 @@
|
||||||
<template v-if="page == 'library-recentlyadded'">
|
<script type="text/x-template" id="cider-recentlyadded">
|
||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
<div class="row">
|
|
||||||
<div class="col" style="padding:0;">
|
|
||||||
<h1 class="header-text">{{$root.getLz('term.recentlyAdded')}}</h1>
|
<h1 class="header-text">{{$root.getLz('term.recentlyAdded')}}</h1>
|
||||||
|
<div class="well itemContainer" v-if="itemSize == 'normal'">
|
||||||
|
<mediaitem-square v-for="item in items" :item="item"></mediaitem-square>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="well itemContainer" v-else="itemSize == 'compact'">
|
||||||
<button v-if="library.albums.downloadState == 2" @click="getLibraryAlbumsFull(true, 0)"
|
<mediaitem-list-item :show-meta-data="true" :show-library-status="false" v-for="item in items" :item="item"></mediaitem-list-item>
|
||||||
class="reload-btn" :aria-label="app.getLz('menubar.options.reload')"><%- include('../svg/redo.svg') %></button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="well itemContainer" v-show="loading">
|
||||||
|
<div class="spinner"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<button v-if="nextUrl && !loading" style="opacity:0;height: 32px;" v-observe-visibility="{callback: visibilityChanged}">{{$root.getLz('term.showMore')}}
|
||||||
<div class="col" style="padding:0;">
|
</button>
|
||||||
<div class="search-input-container" style="width:100%;margin: 16px 0;">
|
|
||||||
<div class="search-input--icon"></div>
|
|
||||||
<input type="search"
|
|
||||||
style="width:100%;"
|
|
||||||
spellcheck="false"
|
|
||||||
:placeholder="$root.getLz('term.search') + '...'"
|
|
||||||
@input="searchLibraryAlbums"
|
|
||||||
v-model="library.albums.search" class="search-input">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</script>
|
||||||
<div class="col-auto flex-center">
|
|
||||||
<div class="row">
|
<script>
|
||||||
<div class="col">
|
Vue.component("cider-recentlyadded", {
|
||||||
<select class="md-select" v-model="library.albums.sortOrder[0]"
|
template: "#cider-recentlyadded",
|
||||||
@change="searchLibraryAlbums(0)">
|
computed: {
|
||||||
<optgroup :label="$root.getLz('term.sortOrder')">
|
items() {
|
||||||
<option value="asc">{{$root.getLz('term.sortOrder.ascending')}}</option>
|
return this.$store.state.pageState['recentlyAdded'].items;
|
||||||
<option value="desc">{{$root.getLz('term.sortOrder.descending')}}</option>
|
},
|
||||||
</optgroup>
|
nextUrl() {
|
||||||
</select>
|
return this.$store.state.pageState['recentlyAdded'].nextUrl;
|
||||||
</div>
|
},
|
||||||
<div class="col">
|
itemSize() {
|
||||||
<select class="md-select" v-model="library.albums.viewAs">
|
return this.$store.state.pageState['recentlyAdded'].size
|
||||||
<optgroup :label="$root.getLz('term.viewAs')">
|
}
|
||||||
<option value="covers">{{$root.getLz('term.viewAs.coverArt')}}</option>
|
},
|
||||||
<option value="list">{{$root.getLz('term.viewAs.list')}}</option>
|
data: function () {
|
||||||
</optgroup>
|
return {
|
||||||
</select>
|
loading: false,
|
||||||
</div>
|
firstRoute: `/v1/me/library/recently-added?l=${app.mklang}&platform=web&include[library-albums]=artists&include[library-artists]=catalog&fields[artists]=url&fields%5Balbums%5D=artistName%2CartistUrl%2Cartwork%2CcontentRating%2CeditorialArtwork%2Cname%2CplayParams%2CreleaseDate%2Curl&includeOnly=catalog%2Cartists&limit=25`
|
||||||
</div>
|
}
|
||||||
</div>
|
},
|
||||||
</div>
|
async mounted() {
|
||||||
<div class="well">
|
if(this.$store.state.pageState['recentlyAdded'].items.length !== 0) return
|
||||||
<div class="albums-square-container">
|
|
||||||
<mediaitem-square v-if="library.albums.viewAs == 'covers'" :item="item"
|
const firstResult = await app.mk.api.v3.music(this.firstRoute)
|
||||||
v-for="item in library.albums.displayListing">
|
this.$store.state.pageState["recentlyAdded"].items = firstResult.data.data
|
||||||
</mediaitem-square>
|
this.$store.state.pageState["recentlyAdded"].nextUrl = firstResult.data.next
|
||||||
</div>
|
},
|
||||||
<mediaitem-list-item v-if="library.albums.viewAs == 'list'" :show-duration="false" :show-meta-data="true"
|
beforeDestroy() {
|
||||||
:show-library-status="false" :item="item"
|
// this.$store.state.pageState["recently-added"].scrollPosY = $("#app-content").scrollTop()
|
||||||
v-for="item in library.albums.displayListing">
|
},
|
||||||
</mediaitem-list-item>
|
methods: {
|
||||||
</div>
|
visibilityChanged: function(isVisible, entry) {
|
||||||
</div>
|
if (isVisible && !this.loading) {
|
||||||
</template>
|
this.getNextData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getNextData() {
|
||||||
|
if (this.$store.state.pageState["recentlyAdded"].nextUrl) {
|
||||||
|
this.loading = true;
|
||||||
|
const nextResult = await app.mk.api.v3.music(this.$store.state.pageState["recentlyAdded"].nextUrl)
|
||||||
|
this.$store.state.pageState["recentlyAdded"].items = this.$store.state.pageState["recentlyAdded"].items.concat(nextResult.data.data)
|
||||||
|
if (nextResult.data.next) {
|
||||||
|
this.$store.state.pageState["recentlyAdded"].nextUrl = nextResult.data.next
|
||||||
|
} else {
|
||||||
|
this.$store.state.pageState["recentlyAdded"].nextUrl = null
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
143
src/renderer/views/pages/oobe.ejs
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
<script type="text/x-template" id="cider-oobe">
|
||||||
|
<div class="content-inner oobe">
|
||||||
|
<!-- before_we_start-->
|
||||||
|
<transition name="wpfade">
|
||||||
|
<div class="oobe-view" v-if="screen == 'before_we_start'">
|
||||||
|
<div class="oobe-header">
|
||||||
|
{{ getLz("oobe.amupsell.title") }}
|
||||||
|
</div>
|
||||||
|
<div class="oobe-body text">{{ getLz("oobe.amupsell.text") }}</div>
|
||||||
|
<div class="oobe-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
<div class="md-btn" @click="screen = 'welcome'">{{ getLz("oobe.next") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- Welcome -->
|
||||||
|
<transition name="wpfade">
|
||||||
|
<div class="oobe-view" v-if="screen == 'welcome'">
|
||||||
|
<div class="oobe-header">
|
||||||
|
{{ getLz("oobe.intro.title") }}
|
||||||
|
</div>
|
||||||
|
<div class="oobe-body text">{{ getLz("oobe.intro.text") }}</div>
|
||||||
|
<div class="oobe-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
<div class="md-btn" @click="screen = 'before_we_start'">{{ getLz("oobe.previous") }}</div>
|
||||||
|
<div class="md-btn" @click="screen = 'general'">{{ getLz("oobe.next") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- General -->
|
||||||
|
<transition name="wpfade">
|
||||||
|
<div class="oobe-view" v-if="screen == 'general'">
|
||||||
|
<div class="oobe-header">
|
||||||
|
{{ getLz("oobe.general.title") }}
|
||||||
|
</div>
|
||||||
|
<div class="oobe-body text">{{ getLz("oobe.general.text") }}</div>
|
||||||
|
<div class="oobe-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
<div class="md-btn" @click="screen = 'welcome'">{{ getLz("oobe.previous") }}</div>
|
||||||
|
<div class="md-btn" @click="screen = 'visual'">{{ getLz("oobe.next") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- Visual -->
|
||||||
|
<transition name="wpfade">
|
||||||
|
<div class="oobe-view" v-if="screen == 'visual'">
|
||||||
|
<div class="oobe-header">
|
||||||
|
{{ getLz("oobe.visual.title") }}
|
||||||
|
</div>
|
||||||
|
<div class="oobe-body visual">
|
||||||
|
<b-row>
|
||||||
|
<b-col>
|
||||||
|
<div class="card bg-dark text-white stylePicker">
|
||||||
|
<div class="card-body">
|
||||||
|
<img class="visualPreview" src="./assets/oobe/ss1.png" alt="TEMP">
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
Mojave
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
<b-col>
|
||||||
|
<div class="card bg-dark text-white stylePicker">
|
||||||
|
<div class="card-body">
|
||||||
|
<img class="visualPreview" src="./assets/oobe/ss2.png" alt="TEMP">
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
Maverick
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<div class="blurb">{{getLz("oobe.visual.layout.text")}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="oobe-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
<div class="md-btn" @click="screen = 'general'">{{ getLz("oobe.previous") }}</div>
|
||||||
|
<div class="md-btn" @click="screen = 'audio'">{{ getLz("oobe.next") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- Audio -->
|
||||||
|
<transition name="wpfade">
|
||||||
|
<div class="oobe-view" v-if="screen == 'audio'">
|
||||||
|
<div class="oobe-header">
|
||||||
|
{{ getLz("oobe.audio.title") }}
|
||||||
|
</div>
|
||||||
|
<div class="oobe-body">
|
||||||
|
<div class="blurb">{{ getLz("oobe.audio.text") }}</div>
|
||||||
|
<div class="md-option-container">
|
||||||
|
<div class="settings-option-body">
|
||||||
|
<div class="md-option-line">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
{{getLz('settings.option.audio.enableAdvancedFunctionality')}}
|
||||||
|
<br>
|
||||||
|
<small>{{getLz('settings.option.audio.enableAdvancedFunctionality.description')}}</small>
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" v-model="$root.cfg.advanced.AudioContext"
|
||||||
|
switch/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="oobe-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
<div class="md-btn" @click="screen = 'visual'">{{ getLz("oobe.previous") }}</div>
|
||||||
|
<div class="md-btn">{{ getLz("oobe.next") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
Vue.component('cider-oobe', {
|
||||||
|
template: '#cider-oobe',
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
screen: "before_we_start"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getLz() {
|
||||||
|
return this.$root.getLz.apply(this.$root, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,6 +1,15 @@
|
||||||
<script type="text/x-template" id="cider-search">
|
<script type="text/x-template" id="cider-search">
|
||||||
<div class="content-inner search-page">
|
<div class="content-inner search-page">
|
||||||
|
<div class="btn-group searchToggle">
|
||||||
|
<button
|
||||||
|
@click="searchType = 'catalog'"
|
||||||
|
class="md-btn md-btn-small" :class="{'md-btn-primary': searchType == 'catalog'}">{{ $root.getLz("term.appleMusic") }}</button>
|
||||||
|
<button
|
||||||
|
@click="searchType = 'library';"
|
||||||
|
class="md-btn md-btn-small" :class="{'md-btn-primary': searchType == 'library'}">{{ $root.getLz("term.library") }}</button>
|
||||||
|
</div>
|
||||||
<div v-if="search != null && search != [] && search.term != ''">
|
<div v-if="search != null && search != [] && search.term != ''">
|
||||||
|
<template v-if="searchType == 'catalog'">
|
||||||
<h3>{{app.getLz('term.topResult')}}</h3>
|
<h3>{{app.getLz('term.topResult')}}</h3>
|
||||||
<mediaitem-scroller-horizontal
|
<mediaitem-scroller-horizontal
|
||||||
:items="search.results[search.results.meta.results.order[0]]['data']"></mediaitem-scroller-horizontal>
|
:items="search.results[search.results.meta.results.order[0]]['data']"></mediaitem-scroller-horizontal>
|
||||||
|
@ -78,6 +87,20 @@
|
||||||
<mediaitem-scroller-horizontal-large
|
<mediaitem-scroller-horizontal-large
|
||||||
:items="search.resultsSocial.profile.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
:items="search.resultsSocial.profile.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<h1>{{ $root.getLz("term.library") }}</h1>
|
||||||
|
<div v-for="(section, key) in $root.search.resultsLibrary">
|
||||||
|
<h3>{{app.friendlyTypes(key)}}</h3>
|
||||||
|
<div class="mediaitem-list-item__grid" v-if="key.includes('songs')">
|
||||||
|
<listitem-horizontal :items="section.data"></listitem-horizontal>
|
||||||
|
</div>
|
||||||
|
<div class="well" v-else>
|
||||||
|
<mediaitem-scroller-horizontal-large
|
||||||
|
:items="section.data"></mediaitem-scroller-horizontal-large>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div v-if="categoriesReady || getCategories()">
|
<div v-if="categoriesReady || getCategories()">
|
||||||
|
@ -111,6 +134,7 @@
|
||||||
recentlyPlayed: [],
|
recentlyPlayed: [],
|
||||||
categoriesView: [],
|
categoriesView: [],
|
||||||
categoriesReady: false,
|
categoriesReady: false,
|
||||||
|
searchType: "catalog",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -329,7 +329,7 @@
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="app.cfg.audio.normalization"
|
<input type="checkbox" v-model="app.cfg.audio.normalization"
|
||||||
v-on:change="toggleNormalization"
|
v-on:change="toggleNormalization"
|
||||||
:disabled="app.cfg.audio.spatial === true || app.cfg.audio.maikiwiAudio.spatial === true || app.cfg.audio.maikiwiAudio.ciderPPE === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true"
|
:disabled="app.cfg.audio.maikiwiAudio.spatial === true || app.cfg.audio.maikiwiAudio.ciderPPE === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true"
|
||||||
switch/>
|
switch/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -385,8 +385,8 @@
|
||||||
<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="$root.cfg.visual.directives.windowLayout">
|
<select class="md-select" v-model="$root.cfg.visual.directives.windowLayout">
|
||||||
<option value="default">Cupertino</option>
|
<option value="default">Maverick</option>
|
||||||
<option value="twopanel">Redmond</option>
|
<option value="twopanel">Mojave</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1138,6 +1138,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="md-option-line">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
Collapsable Sidebar
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" v-model="app.cfg.advanced.experiments.includes('collapseSidebar')"
|
||||||
|
@click="app.cfg.advanced.experiments.includes('collapseSidebar') ? removeExperiment('collapseSidebar') : addExperiment('collapseSidebar')"
|
||||||
|
switch/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
|
@ -1381,7 +1393,7 @@
|
||||||
if (app.cfg.audio.normalization === true) {
|
if (app.cfg.audio.normalization === true) {
|
||||||
CiderAudio.normalizerOn()
|
CiderAudio.normalizerOn()
|
||||||
}
|
}
|
||||||
if (app.cfg.audio.spatial === true) {
|
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
||||||
CiderAudio.spatialOn()
|
CiderAudio.spatialOn()
|
||||||
CiderAudio.hierarchical_loading();
|
CiderAudio.hierarchical_loading();
|
||||||
}
|
}
|
||||||
|
@ -1392,7 +1404,7 @@
|
||||||
if (app.cfg.audio.normalization === true) {
|
if (app.cfg.audio.normalization === true) {
|
||||||
CiderAudio.normalizerOn()
|
CiderAudio.normalizerOn()
|
||||||
}
|
}
|
||||||
if (app.cfg.audio.spatial === true) {
|
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
||||||
CiderAudio.spatialOn()
|
CiderAudio.spatialOn()
|
||||||
CiderAudio.hierarchical_loading();
|
CiderAudio.hierarchical_loading();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
"resolveJsonModule": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"*": ["node_modules/*"]
|
"*": ["node_modules/*"]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"electronVersion": "18.3.0",
|
"electronVersion": "19.0.1",
|
||||||
"electronDownload": {
|
"electronDownload": {
|
||||||
"version": "18.3.0+wvcus",
|
"version": "19.0.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",
|
||||||
|
|