diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index f1befd57..be849760 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -139,8 +139,8 @@ jobs: dist/Cider.pkg body: signed Develop MacOS Builds name: macOS builds - tag_name: macos-beta - prerelease : true + tag_name: macos-beta + target_commitish: ${{ env.GITHUB_SHA }} + prerelease: true generate_release_notes: true - append_body : false - fail_on_unmatched_files: false \ No newline at end of file + fail_on_unmatched_files: false diff --git a/msft-test.json b/msft-test.json new file mode 100644 index 00000000..ddcf14f9 --- /dev/null +++ b/msft-test.json @@ -0,0 +1,63 @@ +{ + "electronVersion": "16.0.7", + "electronDownload": { + "version": "16.0.7+wvcus", + "mirror": "https://github.com/castlabs/electron-releases/releases/download/v" + }, + "appId": "cider", + "protocols": [ + { + "name": "Cider", + "schemes": [ + "ame", + "cider", + "itms", + "itmss", + "musics", + "music" + ] + } + ], + "extends": null, + "files": [ + "**/*", + "./src/**/*", + "./resources/icons/icon.*" + ], + "linux": { + "target": [ + "AppImage", + "deb", + "snap", + "rpm" + ], + "synopsis": "A new look into listening and enjoying music in style and performance. ", + "category": "AudioVideo", + "icon": "cider", + "executableName": "cider" + }, + "appx": { + "applicationId": "CiderAlpha", + "publisher": "CN=CiderCollective, OID.2.25.311729368913984317654407730594956997722=1", + "displayName": "Cider (Alpha)", + "identityName": "CiderCollective.CiderAlpha", + "backgroundColor": "transparent", + "setBuildNumber": true + }, + "win": { + "target": [ + "appx" + ], + "icon": "resources/icons/icon.ico" + }, + "directories": { + "buildResources": ".", + "output": "dist" + }, + "mac": { + "icon": "./resources/icons/icon.icns", + "category": "public.app-category.music", + "entitlements": "resources/entitlements.mac.plist", + "darkModeSupport": true + } +} \ No newline at end of file diff --git a/package.json b/package.json index 4b2b54da..70e22263 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "cider", "applicationId": "Cider", "productName": "Cider", - "version": "1.4.4", + "version": "1.4.5", "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", "main": "./build/index.js", @@ -31,6 +31,7 @@ "dist:all": "yarn build && electron-builder -mwl", "winget": "yarn build && electron-builder --win -c winget.json", "msft": "yarn build && electron-builder -c msft-package.json", + "mstest": "yarn build && electron-builder -c msft-test.json", "postinstall": "electron-builder install-app-deps", "circle:script": "node resources/circle" }, @@ -38,6 +39,7 @@ "@sentry/electron": "^3.0.7", "@sentry/integrations": "^6.19.6", "adm-zip": "0.4.10", + "airtunes2": "git+https://github.com/vapormusic/node_airtunes2.git", "castv2-client": "^1.2.0", "chokidar": "^3.5.3", "discord-rpc": "^4.0.1", diff --git a/src/ciderkit/public.js b/src/ciderkit/public.js new file mode 100644 index 00000000..d3c26637 --- /dev/null +++ b/src/ciderkit/public.js @@ -0,0 +1,26 @@ +const CiderKit = { + v1: { + musickit: { + async mkv3(route, body, options) { + let opts = { + method: 'POST', + cache: 'no-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: {} + } + opts.body = JSON.stringify({ + route: route, + body: body, + options: options + }) + let response = await fetch("http://localhost:9000/api/musickit/v3", opts); + return response.json() + } + } + } +} \ No newline at end of file diff --git a/src/i18n/README.md b/src/i18n/README.md index 98c4e36c..4246957d 100644 --- a/src/i18n/README.md +++ b/src/i18n/README.md @@ -290,3 +290,12 @@ Update 25/04/2022 00:21 UTC * `settings.description.cast`: Added for `en_US` * `settings.description.settings`: Added for `en_US` * `settings.description.developer`: Added for `en_US` + +Update 28/04/2022 21:45 UTC + +* `settings.option.general.resumetabs`: Added for `en_US` +* `settings.option.general.resumetabs.description`: Added for `en_US` +* `settings.option.general.resumetabs.dynamic`: Added for `en_US` +* `settings.option.general.resumetabs.dynamic.description`: Added for `en_US` + + diff --git a/src/i18n/de_DE.json b/src/i18n/de_DE.json index 28d148f1..8927b95d 100644 --- a/src/i18n/de_DE.json +++ b/src/i18n/de_DE.json @@ -276,6 +276,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Aktiviere Karaoke-Modus (nur mit Musixmatch)", "settings.option.lyrics.musixmatchPreferredLanguage": "Bevorzugte Sprache für Musixmatch-Übersetzung", "settings.option.lyrics.enableYoutubeLyrics": "Aktiviere YouTube-Liedtexte für Musikvideos", + "settings.option.lyrics.enableQQLyrics": "Aktiviere QQ Liedtexte", "settings.header.connectivity": "Konnektivität", "settings.header.connectivity.description": "Passe die Konnektivitäts-Einstellungen für Cider an.", "settings.option.connectivity.discordRPC": "Discord Rich Presence", diff --git a/src/i18n/en_OWO.json b/src/i18n/en_OWO.json index 9b7efd65..940d93fd 100644 --- a/src/i18n/en_OWO.json +++ b/src/i18n/en_OWO.json @@ -279,6 +279,19 @@ "settings.option.general.updateCider.branch.develop": "Devewopment", "settings.option.general.customizeSidebar": "Customize Sidebaw Items", "settings.option.general.customizeSidebar.customize": "Customize", + "settings.option.general.keybindings": "Keybindings", + "settings.option.general.keybindings.open": "Open", + "settings.description.search": "Seawch", + "settings.description.albums": "Wibwawy Awbums", + "settings.description.artists": "Wibwawy Awtists", + "settings.description.browse": "Bwowse", + "settings.description.private": "Toggwe Pwivate Session", + "settings.description.remote": "Web Wemote", + "settings.description.audio": "Audio Settings", + "settings.description.plugins": "Pwugins Menyu", + "settings.description.cast": "Cast to Devices", + "settings.description.settings": "Settings", + "settings.description.developer": "Devewopew Toows", "settings.notyf.updateCider.update-not-available": "Nyo update avaiwabwe", "settings.notyf.updateCider.update-downloaded": "Update has been downwoaded, westawt to appwy", "settings.notyf.updateCider.update-error": "Ewwow updating Cidew", @@ -287,6 +300,9 @@ "settings.header.audio.description": "Adjust the audio settings fow Cidew.", "settings.option.audio.volumeStep": "Vowume Step", "settings.option.audio.maxVolume": "Max Vowume", + "settings.option.audio.changePlaybackRate": "Change Pwayback Wate", + "settings.option.audio.playbackRate": "Pwayback Wate", + "settings.option.audio.playbackRate.change": "Change", "settings.option.audio.quality": "Audio Quawity", "settings.header.audio.quality.hireslossless": "Hi-Wes Wosswess", "settings.header.audio.quality.hireslossless.description": "up to 24-bit/192 kHz", @@ -361,6 +377,7 @@ "settings.option.visual.uiscale": "UI Scawe", "settings.header.visual.theme": "Theme", "settings.option.visual.theme.github.download": "Instaww fwom GitHub UWW", + "settings.option.visual.theme.github.openfolder": "Open Themes Fowdew", "settings.option.visual.theme.github.explore": "Expwowe GitHub Themes", "settings.header.visual.theme.github.page": "Themes fwom GitHub", "settings.option.visual.theme.github.install.confirm": "Awe you suwe you want to instaww {{ repo }}?", @@ -393,6 +410,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Enyabwe Kawaoke Mode (Musixmatch onwy)", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch Twanswation Pwefewwed Wanguage", "settings.option.lyrics.enableYoutubeLyrics": "Enyabwe Youtube Wywics fow Music Videos", + "settings.option.lyrics.enableQQLyrics": "Enyabwe QQ Wywics", "settings.header.connectivity": "Connyectivity", "settings.header.connectivity.description": "Adjust the connyectivity settings fow Cidew.", "settings.option.connectivity.playbackNotifications": "Pwayback Nyotifications", @@ -422,9 +440,11 @@ "settings.option.advanced.playlistTrackMapping": "Pwaywist Twack Mapping", "settings.option.advanced.playlistTrackMapping.description": "Enyabwes deep scannying of pwaywists to detewminye which twacks awe in which pwaywists. Pwaywist cache buiwd times can incwease signyificantwy.", "settings.option.visual.transparent": "Twanspawent fwame", - "settings.option.visual.transparent.description": "Twanspawent fwame (nyeeds Theme Suppowt , wequiwes wewaunch)", + "settings.option.visual.transparent.description": "(nyeeds Theme Suppowt, wequiwes wewaunch)", "settings.header.advanced": "Advanced", - "settings.header.connect": "Connyect", + "settings.header.connect": "Sync", + "settings.option.connect.link_account": "Enyabwe Sync with Cidew Connyect", + "settings.option.connect.link_account.description": "Winking youw Discowd account with Cidew Connyect awwows you to stowe usewdata incwuding Settings, EQ's, and eventuawwy mowe once finyished. (Wowk In Pwogwess)", "spatial.notTurnedOn": "Audio Spatiawization is disabwed. To use, pwease enyabwe it fiwst.", "spatial.spatialProperties": "Spatiaw Pwopewties", "spatial.width": "Width", diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json index 56cb0c9b..78413968 100644 --- a/src/i18n/en_US.json +++ b/src/i18n/en_US.json @@ -199,6 +199,9 @@ "podcast.episodes": "Episodes", "podcast.playEpisode": "Play Episode", "podcast.website": "Podcast Website", + "action.edit": "Edit", + "action.done": "Done", + "action.editTracklist": "Edit Tracklist", "action.addToLibrary": "Add to Library", "action.addToLibrary.success": "Added to Library", "action.addToLibrary.error": "Error Adding to Library", @@ -269,6 +272,10 @@ "settings.option.general.resumebehavior.locally.description": "Cider will resume your last session on this machine.", "settings.option.general.resumebehavior.history": "History", "settings.option.general.resumebehavior.history.description": "Cider will queue the last song from your overall Apple Music history, across devices.", + "settings.option.general.resumetabs" : "Open Tab on Launch", + "settings.option.general.resumetabs.description" : "You can choose what tab you want to open when you launch Cider.", + "settings.option.general.resumetabs.dynamic" : "Dynamic", + "settings.option.general.resumetabs.dynamic.description" : "Cider will open the tab that you last used.", "settings.option.general.language.main": "Languages", "settings.option.general.language.fun": "Fun Languages", "settings.option.general.language.unsorted": "Unsorted", @@ -280,12 +287,14 @@ "settings.option.general.customizeSidebar": "Customize Sidebar Items", "settings.option.general.customizeSidebar.customize": "Customize", "settings.option.general.keybindings": "Keybindings", + "settings.notyf.general.keybindings.update.success": "Keybind updated successfully", + "settings.prompt.general.keybindings.update.success": "Keybind updated successfully. Press OK to relaunch Cider", "settings.option.general.keybindings.open": "Open", "settings.description.search": "Search", "settings.description.albums": "Library Albums", "settings.description.artists": "Library Artists", "settings.description.browse": "Browse", - "settings.description.private": "Toogle Private Session", + "settings.description.private": "Toggle Private Session", "settings.description.remote": "Web Remote", "settings.description.audio": "Audio Settings", "settings.description.plugins": "Plugins Menu", @@ -410,6 +419,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Enable Karaoke Mode (Musixmatch only)", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch Translation Preferred Language", "settings.option.lyrics.enableYoutubeLyrics": "Enable Youtube Lyrics for Music Videos", + "settings.option.lyrics.enableQQLyrics": "Enable QQ Lyrics", "settings.header.connectivity": "Connectivity", "settings.header.connectivity.description": "Adjust the connectivity settings for Cider.", "settings.option.connectivity.playbackNotifications": "Playback Notifications", diff --git a/src/i18n/es_ES.json b/src/i18n/es_ES.json index 1a6cadb7..e10bab53 100644 --- a/src/i18n/es_ES.json +++ b/src/i18n/es_ES.json @@ -10,6 +10,7 @@ "notification.updatingLibrarySongs": "Actualizando Canciones de la Biblioteca...", "notification.updatingLibraryAlbums": "Actualizando Álbumes de la Biblioteca...", "notification.updatingLibraryArtists": "Actualizando Artistas de la Biblioteca...", + "term.variables": "Variables", "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", "term.applePodcasts": "Apple Podcasts", @@ -26,7 +27,7 @@ "term.disablePrivateSession": "Deshabilitar Sesión Privada", "term.queue": "Cola", "term.lyrics": "Letras", - "term.miniplayer": "Mini Reproductor", + "term.miniplayer": "Mini-Reproductor", "term.history": "Historial", "term.search": "Buscar", "term.library": "Biblioteca", @@ -130,7 +131,7 @@ "term.socialTeam": "Equipo Social", "term.socials": "Redes Sociales", "term.contributors": "Contribuidores", - "term.equalizer": "Equalizador", + "term.equalizer": "Ecualizador", "term.reset": "Reiniciar", "term.tracks": "Pistas", "term.track": { @@ -141,15 +142,15 @@ "term.menu": "Menú", "term.check": "Comprobar", "term.aboutArtist": "Acerca de {{artistName}}", - "term.topResult": "Mejor resultado", + "term.topResult": "Mejor Resultado", "term.sharedPlaylists": "Listas de Reproducción Compartidas", "term.people": "Personas", - "term.newpreset.name": "Nuevo nombre de preestablecido de ecualizador", - "term.addedpreset": "Preajuste Agregado", - "term.deletepreset.warn": "¿Estas seguro de que quieres eliminar este Preajuste?", - "term.deletedpreset": "Preajuste Eliminado", - "term.defaultPresets": "Preajustes Predeterminados", - "term.userPresets": "Preajustes de Usuario", + "term.newpreset.name": "Nuevo nombre de Preset de Ecualizador", + "term.addedpreset": "Preset Agregado", + "term.deletepreset.warn": "¿Estas seguro de que quieres eliminar este Preset?", + "term.deletedpreset": "Preset Eliminado", + "term.defaultPresets": "Preset Predeterminados", + "term.userPresets": "Preset de Usuario", "term.requestError": "Hubo un problema con la solicitud.", "term.song.link.generate": "Obtener URL de la Canción compartida...", "term.musicVideos": "Videos Musicales", @@ -157,14 +158,14 @@ "term.curators": "Curadores", "term.appleCurators": "Curadores de Apple", "term.radioShows": "Programas de Radio", - "term.recordLabels": "Etiquetas discográficas", + "term.recordLabels": "Etiquetas Discográficas", "term.videoExtras": "Extras de Video", "term.top": "Top", - "term.version": "Version", - "term.noVideos": "No hay videos disponibles.", + "term.version": "Versión", + "term.noVideos": "No hay Videos Disponibles.", "term.plugin": "Plug-in", - "term.pluginMenu": "Plug-in Menu", - "term.pluginMenu.none": "Sin plugins interactivos", + "term.pluginMenu": "Plug-in Menú", + "term.pluginMenu.none": "Sin Plugins Interactivos", "term.replay": "Repetir", "term.uniqueAlbums": "Álbumes Únicos", "term.uniqueArtists": "Artistas Únicos", @@ -181,12 +182,12 @@ "home.title": "Principal", "home.recentlyPlayed": "Escuchado Recientemente", "home.recentlyAdded": "Agregado Recientemente", - "home.artistsFeed": "Tu feed de artistas", - "home.artistsFeed.noArtist": "Sigue a algunos artistas para ver sus últimos lanzamientos", - "home.madeForYou": "Hecho para ti", - "home.friendsListeningTo": "Amigos escuchando", - "home.followedArtists": "Artistas seguidos", - "error.appleMusicSubRequired": "Apple Music requiere una suscripción.", + "home.artistsFeed": "Tu Feed de artistas", + "home.artistsFeed.noArtist": "Sigue a algunos Artistas para ver sus últimos Lanzamientos", + "home.madeForYou": "Hecho para Ti", + "home.friendsListeningTo": "Amigos Escuchando", + "home.followedArtists": "Artistas Seguidos", + "error.appleMusicSubRequired": "Apple Music Requiere una Suscripción.", "error.connectionError": "Hubo un problema al conectarse a Apple Music.", "error.noResults": "No hay Resultados.", "error.noResults.description": "Prueba una Nueva Búsqueda", @@ -239,14 +240,14 @@ "action.removeTracks": "Eliminar ${self.selectedItems.length} pistas de la cola", "action.import": "Importar", "action.export": "Exportar", - "action.showAlbum": "Mostrar Album Completo", + "action.showAlbum": "Mostrar Álbum Completo", "action.tray.minimize": "Minimizar a la bandeja", "action.tray.quit": "Salir", "action.tray.show": "Mostrar Cider", "action.update": "Actualizar", "action.install": "Instalar", "action.copy": "Copiar", - "action.newpreset": "Nuevo preset...", + "action.newpreset": "Nuevo Preset...", "action.deletepreset": "Borrar Preset", "action.open": "Abrir", "action.relaunch.confirm": "¿Quieres reiniciar Cider?", @@ -258,6 +259,7 @@ "action.cast.scan": "Escanear", "action.cast.scanning": "Escaneando...", "action.createNew": "Crear Nuevo...", + "action.openArtworkInBrowser": "Abrir Ilustración en el navegador", "settings.header.general": "General", "settings.header.general.description": "Ajuste la configuración general de Cider.", "settings.option.general.language": "Idioma", @@ -277,14 +279,30 @@ "settings.option.general.updateCider.branch.develop": "Desarrollo", "settings.option.general.customizeSidebar": "Personalizar elementos de la barra lateral", "settings.option.general.customizeSidebar.customize": "Personalizar", + "settings.option.general.keybindings": "Combinaciones de Teclas", + "settings.option.general.keybindings.open": "Abrir", + "settings.description.search": "Buscar", + "settings.description.albums": "Álbumes de la biblioteca", + "settings.description.artists": "Artistas de la biblioteca", + "settings.description.browse": "Navegar", + "settings.description.private": "Cambiar a Sesión Privada", + "settings.description.remote": "Web Remoto", + "settings.description.audio": "Configuraciones de Audio", + "settings.description.plugins": "Menú de Plugins", + "settings.description.cast": "Transmitir a los Dispositivos", + "settings.description.settings": "Configuraciones", + "settings.description.developer": "Herramientas para Desarrolladores", "settings.notyf.updateCider.update-not-available": "No hay actualizaciones disponibles", - "settings.notyf.updateCider.update-downloaded": "La actualización se ha descargado, reinicie para aplicarla", + "settings.notyf.updateCider.update-downloaded": "La actualización se ha descargado, Reinicie para aplicarla", "settings.notyf.updateCider.update-error": "Error al actualizar Cider", "settings.notyf.updateCider.update-timeout": "Tiempo de espera agotado para actualizar Cider", "settings.header.audio": "Audio", - "settings.header.audio.description": "Ajuste la configuración de audio para Cider.", + "settings.header.audio.description": "Ajuste la Configuración de Audio para Cider.", "settings.option.audio.volumeStep": "Paso de Volumen", "settings.option.audio.maxVolume": "Volumen Máximo", + "settings.option.audio.changePlaybackRate": "Cambiar la Velocidad de Reproducción", + "settings.option.audio.playbackRate": "Velocidad de Reproducción", + "settings.option.audio.playbackRate.change": "Cambiar", "settings.option.audio.quality": "Calidad de Audio", "settings.header.audio.quality.hireslossless": "Hi-Res Lossless", "settings.header.audio.quality.hireslossless.description": "arriba de 24-bit/192 kHz", @@ -300,6 +318,7 @@ "settings.warn.audio.enableAdvancedFunctionality.lowcores": "Cider cree que su PC no puede manejar estas funciones. ¿Estás seguro de que quieres continuar?", "settings.option.audio.audioLab": "Cider Audio Lab", "settings.option.audio.audioLab.description": "Una variedad de efectos de audio desarrollados internamente para Cider.", + "settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California", "settings.warn.audioLab.withoutAF": "Se requiere AudioContext (funcionalidad avanzada) para habilitar Laboratorio de audio de Cider.", "settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Calidez analógica", "settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simula la calidez analógica inspirada en el Korg Nutube 6P1", @@ -307,9 +326,16 @@ "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Cambia la intensidad del procesamiento del módulo de Calidez analógica", "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "Suave", "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "Calido", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider Atmosphere Realizer™️", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Realiza una Atmósfera musical diferente modelada a partir de las configuraciones de audio de última generación.", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider Atmosphere Realizer™️ Mode", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Cambia el modo de funcionamiento del módulo Atmosphere Realizer.", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural1": "Natural (Estándar)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural2": "Natural (Alto)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural3": "Natural (Plus)", "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️", "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Mejora la calidad de audio percibida del audio AAC de 256 kbps mediante el uso de un algoritmo en tiempo real que aprovecha los modelos psicoacústicos de la audición humana y las características de codificación AAC.", - "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP no es compatible con la espacialización. Desactive la espacialización para continuar.", + "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP no es compatible con la Espacialización. Desactive la Espacialización para continuar.", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Intensidad de CAP", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Cambia la intensidad del procesamiento realizado en el audio. (Agresivo puede producir resultados no deseados)", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Estándar", @@ -318,18 +344,18 @@ "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza el volumen máximo de pistas individuales para crear una experiencia auditiva más uniforme. (No funciona en las pistas cargadas por el usuario)", "settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Gestionado por AudioLab", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Espacialización de audio", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Espacialice el audio y haga que el audio sea más tridimensional (Nota: esto NO es Dolby Atmos)", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Espacializa el Audio y haga que el Sonido sea más tridimensional (Nota: esto NO es Dolby Atmos)", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Espacialización Sintonizada de Cider", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Efecto de preajuste de espacialización, deshabilita la configuración personalizable de la espacialización de audio. La espacialización debe estar habilitada como requisito previo.", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Perfil de espacialización de Cider", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Cambia el Perfil de Ajuste de Espacialización.", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Estándar", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiófilo", - "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "La espacialización no es compatible con CAP. Deshabilite CAP para continuar.", + "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "La Espacialización no es compatible con CAP. Deshabilite CAP para continuar.", "settings.header.visual": "Visual", "settings.header.visual.description": "Ajuste la configuración visual de Cider.", - "settings.option.visual.windowStyle": "Estilo de ventana", - "settings.option.visual.windowBackgroundStyle": "Estilo de fondo de ventana", + "settings.option.visual.windowStyle": "Estilo de Ventana", + "settings.option.visual.windowBackgroundStyle": "Estilo de Fondo de Ventana", "settings.header.visual.windowBackgroundStyle.none": "Ninguno", "settings.header.visual.windowBackgroundStyle.artwork": "ilustración", "settings.header.visual.windowBackgroundStyle.image": "Imagen", @@ -348,14 +374,16 @@ "settings.option.visual.hardwareAcceleration.description": "Requiere reinicio", "settings.header.visual.hardwareAcceleration.default": "Por defecto", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.option.visual.uiscale": "Escalado de IU", "settings.header.visual.theme": "Tema", "settings.option.visual.theme.github.download": "Instalar desde la URL de GitHub", - "settings.option.visual.theme.github.explore": "Explorar temas de GitHub", + "settings.option.visual.theme.github.openfolder": "Abrir Carpeta de Temas", + "settings.option.visual.theme.github.explore": "Explorar Temas de GitHub", "settings.header.visual.theme.github.page": "Temas de GitHub", "settings.option.visual.theme.github.install.confirm": "¿Está seguro de que desea instalar {{ repo }}?", - "settings.prompt.visual.theme.github.URL": "Ingrese la URL del tema que desea instalar", - "settings.notyf.visual.theme.install.success": "Tema instalado correctamente", - "settings.notyf.visual.theme.install.error": "La instalación del tema falló", + "settings.prompt.visual.theme.github.URL": "Introduce la URL del tema que quieres instalar", + "settings.notyf.visual.theme.install.success": "Tema Instalado Correctamente", + "settings.notyf.visual.theme.install.error": "La Instalación del Tema Falló", "settings.header.visual.plugin": "Plugin", "settings.option.visual.plugin.github.download": "Instalar desde la URL de GitHub", "settings.option.visual.plugin.github.explore": "Explorar Plugins de GitHub", @@ -364,7 +392,7 @@ "settings.prompt.visual.plugin.github.URL": "Ingrese la URL del tema que desea instalar", "settings.prompt.visual.plugin.github.success": "El Plugin instalado correctamente, Presione OK para reiniciar Cider", "settings.notyf.visual.plugin.install.success": "El Plugin instalado correctamente", - "settings.notyf.visual.plugin.install.error": "La instalación del Plugin falló", + "settings.notyf.visual.plugin.install.error": "La instalación del Plugin Falló", "settings.option.visual.theme.default": "Cider", "settings.option.visual.theme.dark": "Oscuro", "settings.option.visual.showPersonalInfo": "Mostrar información personal", @@ -373,7 +401,7 @@ "settings.option.window.openOnStartup": "Abrir Cider al Iniciar", "settings.option.window.openOnStartup.hidden": "Abrir oculto", "settings.option.window.useNativeTitleBar": "Usar barra de título nativa", - "settings.option.window.windowControlStyle": "Estilo de control de ventanaEstilo de control de ventana", + "settings.option.window.windowControlStyle": "Estilo de control de ventana", "settings.option.window.windowControlStyle.right": "Derecha", "settings.option.window.windowControlStyle.left": "Izquierda", "settings.header.lyrics": "Letras", @@ -384,12 +412,13 @@ "settings.option.lyrics.enableYoutubeLyrics": "Habilitar letras de YouTube para videos musicales", "settings.header.connectivity": "Conectividad", "settings.header.connectivity.description": "Ajuste la configuración de conectividad para Cider.", + "settings.option.connectivity.playbackNotifications": "Notificaciones de Reproducción", "settings.option.connectivity.discordRPC": "Discord Rich Presence", - "settings.option.connectivity.playbackNotifications": "Notificaciones de reproducción", - "settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Borrar Discord Rich Presence en Pausa", + "settings.option.connectivity.discordRPC.clientName": "Nombre del Cliente", + "settings.option.connectivity.discordRPC.clearOnPause": "Borrar Discord Rich Presence en pausa", "settings.option.connectivity.discordRPC.hideButtons": "Ocultar botones en Discord Rich Presence", + "settings.option.connectivity.discordRPC.detailsFormat": "Formato de los detalles", + "settings.option.connectivity.discordRPC.stateFormat": "Formato de Estado", "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling", "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Retraso de Scrobble (%)", "settings.option.connectivity.lastfmScrobble.nowPlaying": "Activar Last.fm Now Playing", @@ -404,7 +433,7 @@ "settings.option.experimental.reinstallwidevine.confirm": "¿Estás seguro de que quieres reinstalar Widevine?", "settings.option.experimental.unknownPlugin": "Fuentes desconocidas", "settings.option.experimental.unknownPlugin.description": "Permitir la instalación de Plugins desde otros repos que no sean el repositorio de Plugins de Cider", - "settings.option.experimental.compactUI": "UI compacta", + "settings.option.experimental.compactUI": "UI Compacto", "settings.option.window.close_button_hide": "El botón Cerrar oculta la aplicación", "settings.option.experimental.inline_playlists": "Álbumes y listas de reproducción en línea", "settings.option.advanced.playlistTrackMapping": "Mapeo de pistas de listas de reproducción", @@ -412,6 +441,7 @@ "settings.option.visual.transparent": "Marco transparente", "settings.option.visual.transparent.description": "Marco transparente (necesita compatibilidad con temas, requiere reiniciar)", "settings.header.advanced": "Avanzado", + "settings.header.connect": "Conectar", "spatial.notTurnedOn": "La espacialización de audio está deshabilitada. Para usar, habilítelo primero.", "spatial.spatialProperties": "Propiedades de Espacialización", "spatial.width": "Ancho", diff --git a/src/i18n/hu_HU.json b/src/i18n/hu_HU.json index 89db1fe3..f1c47c8b 100644 --- a/src/i18n/hu_HU.json +++ b/src/i18n/hu_HU.json @@ -269,6 +269,10 @@ "settings.option.general.resumebehavior.locally.description": "A Cider az ezen az eszközön utoljára játszott zenét fogja folytatni.", "settings.option.general.resumebehavior.history": "Előzmények", "settings.option.general.resumebehavior.history.description": "A Cider az utolsó zeneszámot fogja lekérni az Apple Music előzményeidből, eszközökön keresztül.", + "settings.option.general.resumetabs" : "Fül megnyitása indításkor", + "settings.option.general.resumetabs.description" : "Itt tudod kiválasztani, hogy a Ciderbe való visszatérésnél melyik fül nyíljon meg.", + "settings.option.general.resumetabs.dynamic" : "Dinamikus", + "settings.option.general.resumetabs.dynamic.description" : "A Cider a legutóbb használt fület fogja megnyitni.", "settings.option.general.language.main": "Nyelvek", "settings.option.general.language.fun": "Fantázianyelvek", "settings.option.general.language.unsorted": "Kategorizálatlan", @@ -281,6 +285,17 @@ "settings.option.general.customizeSidebar.customize": "Testreszabás", "settings.option.general.keybindings": "Billentyűparancsok", "settings.option.general.keybindings.open": "Megnyitás", + "settings.description.search": "Keresés", + "settings.description.albums": "Albumkönyvtár", + "settings.description.artists": "Előadókönyvtár", + "settings.description.browse": "Böngészés", + "settings.description.private": "Privát hallgatás ki/be", + "settings.description.remote": "Távirányító", + "settings.description.audio": "Hangbeállítások", + "settings.description.plugins": "Plugin Menü", + "settings.description.cast": "Tükrözés", + "settings.description.settings": "Beállítások", + "settings.description.developer": "Fejlesztői eszközök", "settings.notyf.updateCider.update-not-available": "Nem található frissítés", "settings.notyf.updateCider.update-downloaded": "A frissítés le lett töltve, a telepítéshez indítsa újra az alkalmazást", "settings.notyf.updateCider.update-error": "Hiba történt a frissítés közben", diff --git a/src/i18n/ja_JP.json b/src/i18n/ja_JP.json index a8d0eafa..60531a5b 100644 --- a/src/i18n/ja_JP.json +++ b/src/i18n/ja_JP.json @@ -1,283 +1,486 @@ -{ - "i18n.languageName": "日本語", - "i18n.languageNameEnglish": "Japanese", - "i18n.category": "main", - "i18n.authors": "@maikirakiwi", - "app.name": "Cider", - "date.format": "${y}年${m}月${d}日", - "dialog.cancel": "キャンセル", - "dialog.ok": "OK", - "notification.updatingLibrarySongs": "ライブラリの更新中...", - "notification.updatingLibraryAlbums": "ライブラリの更新中...", - "notification.updatingLibraryArtists": "ライブラリの更新中...", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "詳しい情報", - "term.accountSettings": "アカウント設定", - "term.logout": "サインアウト", - "term.login": "サインイン", - "term.about": "Ciderについて", - "term.privateSession": "プライベートセッション", - "term.queue": "次はこちら", - "term.search": "検索", - "term.library": "ライブラリ", - "term.listenNow": "今すぐ聴く", - "term.browse": "見つける", - "term.radio": "ラジオ", - "term.recentlyAdded": "最近追加した項目", - "term.songs": "曲", - "term.albums": "アルバム", - "term.artists": "アーティスト", - "term.podcasts": "Podcast", - "term.playlists": "プレイリスト", - "term.playlist": "プレイリスト", - "term.play": "再生", - "term.pause": "停止", - "term.previous": "戻る", - "term.next": "次へ", - "term.shuffle": "シャッフル", - "term.repeat": "リピート", - "term.volume": "音量", - "term.mute": "ミュート", - "term.unmute": "ミュート解除", - "term.share": "共有", - "term.settings": "設定", - "term.seeAll": "すべて見る", - "term.sortBy": "並べ替え", - "term.sortBy.album": "アルバム", - "term.sortBy.artist": "アーティスト", - "term.sortBy.name": "曲名", - "term.sortBy.genre": "ジャンル", - "term.sortBy.releaseDate": "配信開始日", - "term.sortBy.duration": "時間", - "term.sortBy.dateAdded": "追加日", - "term.sortOrder": "並べ替え", - "term.sortOrder.ascending": "昇順", - "term.sortOrder.descending": "降順", - "term.viewAs": "表示", - "term.viewAs.coverArt": "カバーアート", - "term.viewAs.list": "リスト", - "term.size": "サイズ", - "term.size.normal": "普通", - "term.size.compact": "コンパクト", - "term.enable": "ON", - "term.disable": "OFF", - "term.enabled": "ON", - "term.disabled": "OFF", - "term.connect": "接続", - "term.connecting": "接続中", - "term.disconnect": "切断", - "term.authed": "認証済み", - "term.confirm": "よろしいでしょうか?", - "term.more": "もっと", - "term.less": "減らす", - "term.showMore": "もっと見る", - "term.showLess": "表示数を少なくする", - "term.topSongs": "トップソング", - "term.latestReleases": "ニューリリース", - "term.time.added": "追加日", - "term.time.released": "配信開始日", - "term.time.updated": "最終更新日", - "term.time.hours": "時間", - "term.time.hour": "時間", - "term.time.minutes": "分", - "term.time.minute": "分", - "term.time.seconds": "秒", - "term.time.second": "秒", - "term.fullscreenView": "全画面表示", - "term.defaultView": "ウィンドウ表示", - "term.audioSettings": "オーディオ設定", - "term.spacializedAudioSetting": "オーディオ空間化設定", - "term.clearAll": "消去", - "term.recentStations": "最近の再生", - "term.language": "言語", - "term.noLyrics": "ローディング。。 / 歌詞が見つからない / 器楽曲.", - "term.copyright": "著作権", - "term.rightsReserved": "All Rights Reserved.", - "term.sponsor": "スポンサーになりましょう", - "term.ciderTeam": "Cider チーム", - "term.developer": "開発者", - "term.socialTeam": "ソーシャル チーム", - "term.contributors": "貢献者", - "term.equalizer": "イコライザー", - "term.reset": "リセット", - "term.track": { - "one": "曲", - "other": "曲" - }, - "term.tracks": "曲", - "term.videos": "ビデオ", - "term.menu": "メニュー", - "term.check": "確認", - "term.aboutArtist": "{{artistName}}について", - "term.version": "バージョン", - "home.title": "ホーム", - "home.recentlyPlayed": "最近の再生", - "home.recentlyAdded": "最近追加した項目", - "home.artistsFeed": "アーティストのフィード", - "home.artistsFeed.noArtist": "自分の好きなアーティストをフォローしましょう・", - "home.madeForYou": "あなたにおすすめ", - "home.friendsListeningTo": "友達が聴いている", - "home.followedArtists": "フォローしているアーティスト", - "error.appleMusicSubRequired": "Apple Musicのサブスクリプションが必要です。", - "error.connectionError": "Apple Musicに接続できません。", - "error.noResults": "見つかりませんでした", - "error.noResults.description": "もう一度お試しください。", - "podcast.followOnCider": "Ciderでフォロー", - "podcast.followedOnCider": "フォロー中", - "podcast.subscribeOnItunes": "iTunesで購読", - "podcast.subscribedOnItunes": "購読中", - "podcast.itunesStore": "iTunes Store", - "podcast.episodes": "番組", - "podcast.playEpisode": "再生", - "podcast.website": "Podcast ウェブ", - "action.addToLibrary": "ライブラリに追加", - "action.addToLibrary.success": "ライブラリに追加されました", - "action.addToLibrary.error": "ライブラリへの追加に失敗しました", - "action.removeFromLibrary": "ライブラリから削除", - "action.removeFromLibrary.success": "ライブラリから削除されました", - "action.addToQueue": "「次はこちら」に項目を追加", - "action.addToQueue.success": "「次はこちら」に項目を追加されました", - "action.addToQueue.error": "操作を完了できませんでした", - "action.addToPlaylist": "プレイリストに追加", - "action.removeFromPlaylist": "プレイリストから削除", - "action.addToFavorites": "ラブに追加", - "action.removeFromQueue": "「次はこちら」から項目を削除", - "action.removeFromQueue.success": "「次はこちら」から項目を削除されました", - "action.removeFromQueue.error": "操作を完了できませんでした", - "action.follow": "フォロー", - "action.follow.success": "フォロー中", - "action.follow.error": "操作を完了できませんでした", - "action.unfollow": "フォロー解除", - "action.unfollow.success": "フォローをやめました", - "action.unfollow.error": "操作を完了できませんでした", - "action.playNext": "次に再生", - "action.playLater": "最後に再生", - "action.startRadio": "ステーションを作成", - "action.goToArtist": "アーティストへ移動", - "action.goToAlbum": "アルバムへ移動", - "action.moveToTop": "上に戻る", - "action.share": "曲を共有", - "action.rename": "名前の変更", - "action.love": "ラブ", - "action.unlove": "ラブを解除", - "action.dislike": "これに似たものをすすめない", - "action.undoDislike": "「これと似た曲のおすすめを減らす」を取り消す", - "action.showWebRemoteQR": "WEBリモコンQRコードを表示", - "action.playTracksNext": "${app.selectedMediaItems.length}曲が次に再生", - "action.playTracksLater": "${app.selectedMediaItems.length}曲が最後に再生", - "action.removeTracks": "${self.selectedItems.length}曲が「次はこちら」から削除", - "action.import": "インポート", - "action.export": "エクスポート", - "action.showAlbum": "すべて見る", - "action.tray.minimize": "最小化", - "action.tray.quit": "終了", - - "action.update": "アップデート", - "action.copy": "コピー", - "action.newpreset": "ニュープリセット", - "action.deletepreset": "プリセットを削除", - "settings.header.general": "一般", - "settings.header.general.description": "Ciderの一般設定", - "settings.option.general.language.main": "メイン", - "settings.option.general.language.fun": "荒らし", - "settings.option.general.language.unsorted": "未分類", - "settings.option.general.updateCider": "Cider 更新", - "settings.header.audio": "オーディオ", - "settings.header.audio.description": "Ciderのオーディオ設定", - "settings.option.audio.volumeStep": "音量調整のステップ", - "settings.option.audio.maxVolume": "最大音量", - "settings.option.audio.quality": "音質", - "settings.header.audio.quality.hireslossless": "ハイレゾロスレス", - "settings.header.audio.quality.hireslossless.description": "(最大解像度 24 ビット/192 kHz)", - "settings.header.audio.quality.lossless": "ロスレス", - "settings.header.audio.quality.lossless.description": "(最大解像度 24 ビット/48 kHz)", - "settings.header.audio.quality.enhanced": "エンハンスド", - "settings.header.audio.quality.high": "高品質", - "settings.header.audio.quality.standard": "高効率", - "settings.header.audio.quality.auto": "自動", - "settings.option.audio.seamlessTransition": "曲間なしで再生", - "settings.option.audio.enableAdvancedFunctionality": "先進的な機能", - "settings.option.audio.enableAdvancedFunctionality.description": "AudioContext 機能を有効にすると、オーディオノーマライズ、空間オーディオ、イコライザーなどの機能を使用できますが、音が途切れるかもしれません。", - "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️", - - "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAPの強さ", - "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": "標準", - "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "高", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "オーディオノーマライズ", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "さまざまな曲の音量を均一にし、より整った音を楽しめるようにする機能です。", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "オーディオ空間化", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "オーディオを空間に分散させる機能です。 (ドルビーアトモスではありません)", - "settings.header.visual": "ビジュアル", - "settings.header.visual.description": "Ciderのビジュアル設定", - "settings.option.visual.windowBackgroundStyle": "アプリウインドウの背景スタイル", - "settings.header.visual.windowBackgroundStyle.none": "なし", - "settings.header.visual.windowBackgroundStyle.artwork": "アートワーク", - "settings.option.visual.animatedArtwork": "アニメーションアートワーク", - "settings.header.visual.animatedArtwork.always": "常に表示", - "settings.header.visual.animatedArtwork.limited": "アーティストページのみ表示", - "settings.header.visual.animatedArtwork.disable": "オフ", - "settings.option.visual.animatedArtworkQuality": "アニメーションアートワークの品質", - "settings.header.visual.animatedArtworkQuality.low": "低", - "settings.header.visual.animatedArtworkQuality.medium": "中", - "settings.header.visual.animatedArtworkQuality.high": "高", - "settings.header.visual.animatedArtworkQuality.veryHigh": "超高", - "settings.header.visual.animatedArtworkQuality.extreme": "最高", - "settings.option.visual.animatedWindowBackground": "アプリウィンドウの背景をアニメーション化", - "settings.option.visual.hardwareAcceleration": "ハードウェア アクセラレーション", - "settings.option.visual.hardwareAcceleration.description": "アプリを再起動する必要があります", - "settings.header.visual.hardwareAcceleration.default": "既定", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - "settings.header.visual.theme": "テーマ", - "settings.option.visual.theme.default": "Cider", - "settings.option.visual.theme.dark": "ダーク", - "settings.option.visual.showPersonalInfo": "プロフィールを表示", - "settings.header.lyrics": "歌詞", - "settings.header.lyrics.description": "歌詞の表示設定", - "settings.option.lyrics.enableMusixmatch": "Musixmatchで歌詞を表示する", - "settings.option.lyrics.enableMusixmatchKaraoke": "カラオケモードを有効にする (Musixmatchのみ)", - "settings.option.lyrics.musixmatchPreferredLanguage": "歌詞の優先言語", - "settings.option.lyrics.enableYoutubeLyrics": "YouTubeの歌詞をミュージックビデオに使用する", - "settings.header.connectivity": "アプリと連携", - "settings.header.connectivity.description": "Ciderの連携設定", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", - "settings.header.connectivity.discordRPC.cider": "'Cider' を表示する", - "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music' を表示する", - "settings.option.connectivity.discordRPC.clearOnPause": "一時停止時にDiscord Rich Presenceをクリアする", - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble Delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable LastFM Now Playing", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (LastFM)", - "settings.header.experimental": "試験的な機能", - "settings.header.experimental.description": "開発中の実験的な機能は不完全で不安定である可能性があります", - "settings.option.experimental.compactUI": "コンパクトインターフェース", - "settings.option.window.close_button_hide": "「閉じる」ボタンでアプリを隠します", - "settings.option.experimental.copy_log": "ログをコピーする", - "settings.option.experimental.inline_playlists": "プレイリストをインラインで表示", - "spatial.spatialProperties": "空間化のプロパティ", - "spatial.width": "幅", - "spatial.height": "高さ", - "spatial.depth": "奥行", - "spatial.gain": "ゲイン", - "spatial.roomMaterials": "部屋のマテリアル", - "spatial.roomDimensions": "部屋の大きさ", - "spatial.roomPositions": "部屋の位置", - "spatial.setDimensions": "大きさを設定", - "spatial.setPositions": "位置を設定", - "spatial.up": "上", - "spatial.front": "前", - "spatial.left": "左", - "spatial.right": "右", - "spatial.back": "後", - "spatial.down": "下", - "spatial.listener": "リスナー", - "spatial.audioSource": "音源", - "settings.header.unfinished": "未完成", - "remote.web.title": "Cider リモート", - "remote.web.description": "QRコードを使用して、Ciderとスマートフォンをペアリングする", - "about.thanks": "Cider Collective とご協力いただいた貢献者様に感謝申し上げます。" -} \ No newline at end of file +{ + "i18n.languageName": "日本語", + "i18n.languageNameEnglish": "Japanese", + "i18n.category": "main", + "i18n.authors": "@maikirakiwi @aduki_0628", + "app.name": "Cider", + "date.format": "${y}年${m}月${d}日", + "dialog.cancel": "キャンセル", + "dialog.ok": "完了", + "notification.updatingLibrarySongs": "ライブラリの更新中...", + "notification.updatingLibraryAlbums": "ライブラリの更新中...", + "notification.updatingLibraryArtists": "ライブラリの更新中...", + "term.variables": "Variables", + "term.appleInc": "Apple Inc.", + "term.appleMusic": "Apple Music", + "term.applePodcasts": "Apple Podcasts", + "term.itunes": "iTunes", + "term.github": "GitHub", + "term.discord": "Discord", + "term.learnMore": "詳しい情報", + "term.accountSettings": "アカウント設定", + "term.logout": "サインアウト", + "term.login": "サインイン", + "term.cast": "Cast", + "term.about": "Ciderについて", + "term.privateSession": "プライベートセッション", + "term.disablePrivateSession": "プライベートセッションを無効にする", + "term.queue": "次はこちら", + "term.lyrics": "歌詞", + "term.miniplayer": "MiniPlayer", + "term.history": "History", + "term.search": "検索", + "term.library": "ライブラリ", + "term.listenNow": "今すぐ聴く", + "term.browse": "見つける", + "term.radio": "ラジオ", + "term.recentlyAdded": "最近追加した項目", + "term.songs": "曲", + "term.albums": "アルバム", + "term.artists": "アーティスト", + "term.podcasts": "Podcasts", + "term.playlists": "プレイリスト", + "term.playlist": "プレイリスト", + "term.newPlaylist": "New Playlist", + "term.newPlaylistFolder": "New Playlist Folder", + "term.createNewPlaylist": "Create New Playlist", + "term.createNewPlaylistFolder": "Create New Playlist Folder", + "term.deletePlaylist": "Are you sure you want to delete this playlist?", + "term.play": "再生", + "term.pause": "停止", + "term.previous": "戻る", + "term.next": "次へ", + "term.shuffle": "シャッフル", + "term.repeat": "リピート", + "term.volume": "音量", + "term.mute": "ミュート", + "term.unmute": "ミュート解除", + "term.share": "共有", + "term.settings": "設定", + "term.seeAll": "すべて見る", + "term.sortBy": "並べ替え", + "term.sortBy.album": "アルバム", + "term.sortBy.artist": "アーティスト", + "term.sortBy.name": "曲名", + "term.sortBy.genre": "ジャンル", + "term.sortBy.releaseDate": "配信開始日", + "term.sortBy.duration": "時間", + "term.sortBy.dateAdded": "追加日", + "term.sortOrder": "並べ替え", + "term.sortOrder.ascending": "昇順", + "term.sortOrder.descending": "降順", + "term.viewAs": "表示", + "term.viewAs.coverArt": "カバーアート", + "term.viewAs.list": "リスト", + "term.size": "サイズ", + "term.size.normal": "普通", + "term.size.compact": "コンパクト", + "term.enabled": "ON", + "term.disable": "OFF", + "term.disabled": "OFF", + "term.enable": "ON", + "term.connect": "接続", + "term.connecting": "接続中", + "term.disconnect": "切断", + "term.authed": "認証済み", + "term.confirm": "よろしいでしょうか?", + "term.more": "もっと", + "term.less": "減らす", + "term.showMore": "もっと見る", + "term.showLess": "表示数を少なくする", + "term.topSongs": "トップソング", + "term.latestReleases": "ニューリリース", + "term.time.added": "追加日", + "term.time.released": "配信開始日", + "term.time.updated": "最終更新日", + "term.time.days": "日", + "term.time.day": { + "one": "日", + "other": "日" + }, + "term.time.hours": "時間", + "term.time.hour": { + "one": "時間", + "other": "時間" + }, + "term.time.minutes": "分", + "term.time.minute": { + "one": "分", + "other": "分" + }, + "term.time.seconds": "秒", + "term.time.second": { + "one": "秒", + "other": "秒" + }, + "term.fullscreenView": "全画面表示", + "term.defaultView": "ウィンドウ表示", + "term.audioSettings": "オーディオ設定", + "term.audioControls": "Volume Controls", + "term.clearAll": "消去", + "term.recentStations": "最近の再生", + "term.language": "言語", + "term.funLanguages": "Fun", + "term.noLyrics": "ローディング。。 / 歌詞が見つからない / 器楽曲.", + "term.copyright": "Copyright", + "term.rightsReserved": "All Rights Reserved.", + "term.sponsor": "スポンサーになりましょう", + "term.ciderTeam": "Cider チーム", + "term.developer": "開発者", + "term.socialTeam": "ソーシャル チーム", + "term.socials": "Socials", + "term.contributors": "貢献者", + "term.equalizer": "イコライザー", + "term.reset": "リセット", + "term.tracks": "曲", + "term.track": { + "one": "曲", + "other": "曲" + }, + "term.videos": "ビデオ", + "term.menu": "メニュー", + "term.check": "確認", + "term.aboutArtist": "{{artistName}}について", + "term.topResult": "Top Result", + "term.sharedPlaylists": "プレイリストを共有", + "term.people": "ユーサ", + "term.newpreset.name": "名前を入力", + "term.addedpreset": "Added Preset", + "term.deletepreset.warn": "Are you sure you want to delete this preset?", + "term.deletedpreset": "Removed preset", + "term.defaultPresets": "Default Presets", + "term.userPresets": "User Presets", + "term.requestError": "There was a problem with the request.", + "term.song.link.generate": "Getting song.link share URL...", + "term.musicVideos": "ミュージックビデオ", + "term.stations": "ステーション", + "term.curators": "Curators", + "term.appleCurators": "Apple Curators", + "term.radioShows": "Radio Shows", + "term.recordLabels": "Record Labels", + "term.videoExtras": "Video Extras", + "term.top": "Top", + "term.version": "バージョン", + "term.noVideos": "No videos found.", + "term.plugin": "Plug-in", + "term.pluginMenu": "Plug-in Menu", + "term.pluginMenu.none": "プラグインが見つかりませんでした", + "term.replay": "リプレイ", + "term.uniqueAlbums": "Unique Albums", + "term.uniqueArtists": "Unique Artists", + "term.uniqueSongs": "Unique Songs", + "term.topArtists": "Top Artists", + "term.listenedTo": "Listened to:", + "term.times": "times", + "term.topAlbums": "Top Albums", + "term.plays": "Plays", + "term.topGenres": "Top Genres", + "term.confirmLogout": "本当にログアウトしますか?", + "term.creditDesignedBy": "${authorUsername}によってデザインされました", + "term.discNumber": "Disc ${discNumber}", + "home.title": "ホーム", + "home.recentlyPlayed": "最近の再生", + "home.recentlyAdded": "最近追加した項目", + "home.artistsFeed": "アーティストのフィード", + "home.artistsFeed.noArtist": "アーティストをフォローすると最新情報を手に入れられます", + "home.madeForYou": "あなたにおすすめ", + "home.friendsListeningTo": "友達が聴いている", + "home.followedArtists": "フォローしているアーティスト", + "error.appleMusicSubRequired": "Apple Musicのサブスクリプションが必要です。", + "error.connectionError": "Apple Musicに接続できません。", + "error.noResults": "見つかりませんでした", + "error.noResults.description": "もう一度お試しください。", + "podcast.followOnCider": "Ciderでフォロー", + "podcast.followedOnCider": "フォロー中", + "podcast.subscribeOnItunes": "iTunesで購読", + "podcast.subscribedOnItunes": "Subscribed On iTunes", + "podcast.itunesStore": "iTunes Store", + "podcast.episodes": "番組", + "podcast.playEpisode": "再生", + "podcast.website": "Podcastウェブ", + "action.edit": "Edit", + "action.done": "Done", + "action.editTracklist": "Edit Tracklist", + "action.addToLibrary": "ライブラリに追加", + "action.addToLibrary.success": "ライブラリに追加されました", + "action.addToLibrary.error": "ライブラリへの追加に失敗しました", + "action.removeFromLibrary": "ライブラリから削除", + "action.removeFromLibrary.success": "ライブラリから削除されました", + "action.addToQueue": "「次はこちら」に項目を追加", + "action.addToQueue.success": "「次はこちら」に項目を追加されました", + "action.addToQueue.error": "操作を完了できませんでした", + "action.removeFromQueue": "「次はこちら」から項目を削除", + "action.removeFromQueue.success": "「次はこちら」から項目を削除されました", + "action.removeFromQueue.error": "操作を完了できませんでした", + "action.createPlaylist": "Create a New Playlist", + "action.addToPlaylist": "Add to Playlist", + "action.removeFromPlaylist": "Remove from Playlist", + "action.addToFavorites": "ラブに追加", + "action.follow": "フォロー", + "action.follow.success": "フォロー中", + "action.follow.error": "操作を完了できませんでした", + "action.unfollow": "フォロー解除", + "action.unfollow.success": "フォローをやめました", + "action.unfollow.error": "操作を完了できませんでした", + "action.playNext": "次に再生", + "action.playLater": "最後に再生", + "action.startRadio": "ステーションを作成", + "action.goToArtist": "アーティストへ移動", + "action.goToAlbum": "アルバムへ移動", + "action.moveToTop": "上に戻る", + "action.share": "曲を共有", + "action.rename": "名前の変更", + "action.love": "ラブ", + "action.unlove": "ラブを解除する", + "action.dislike": "これに似たものをすすめない", + "action.undoDislike": "「これと似た曲のおすすめを減らす」を取り消す", + "action.showWebRemoteQR": "WEBリモコンQRコードを表示", + "action.playTracksNext": "${app.selectedMediaItems.length}曲が次に再生", + "action.playTracksLater": "${app.selectedMediaItems.length}曲が最後に再生", + "action.removeTracks": "${self.selectedItems.length}をキューから除外する", + "action.import": "インポート", + "action.export": "エクスポート", + "action.showAlbum": "アルバムを表示", + "action.tray.minimize": "最小化", + "action.tray.quit": "終了", + "action.tray.show": "Show Cider", + "action.update": "アップデート", + "action.install": "インストール", + "action.copy": "コピー", + "action.newpreset": "新しいプリセット", + "action.deletepreset": "プリセットを削除", + "action.open": "開く", + "action.relaunch.confirm": "Ciderを再開しますか?", + "action.cast.chromecast": "Chromecast", + "action.cast.todevices": "Cast to Devices", + "action.cast.stop": "Stop casting to all devices", + "action.cast.airplay": "AirPlay", + "action.cast.airplay.underdevelopment": "AirPlay is still under development", + "action.cast.scan": "Scan", + "action.cast.scanning": "Scanning...", + "action.createNew": "Create New...", + "action.openArtworkInBrowser": "Open artwork in browser", + "settings.header.general": "一般", + "settings.header.general.description": "Ciderの一般設定", + "settings.option.general.language": "言語", + "settings.option.general.resumebehavior": "Resume behavior", + "settings.option.general.resumebehavior.description": "Resume behavior affects how Cider will resume your session when you return to the app.", + "settings.option.general.resumebehavior.locally": "Locally", + "settings.option.general.resumebehavior.locally.description": "このコンピューターでの最終セッションを復元", + "settings.option.general.resumebehavior.history": "History", + "settings.option.general.resumebehavior.history.description": "Apple Musicの履歴から曲を復元", + "settings.option.general.resumetabs" : "Open Tab on Launch", + "settings.option.general.resumetabs.description" : "You can choose what tab you want to open when you launch Cider.", + "settings.option.general.resumetabs.dynamic" : "Dynamic", + "settings.option.general.resumetabs.dynamic.description" : "Cider will open the tab that you last used.", + "settings.option.general.language.main": "メイン", + "settings.option.general.language.fun": "荒らし", + "settings.option.general.language.unsorted": "未分類", + "settings.option.general.updateCider": "アップデート", + "settings.option.general.updateCider.branch": "Cider Update Branch", + "settings.option.general.updateCider.branch.description": "Select the branch to update Cider to", + "settings.option.general.updateCider.branch.main": "Stable", + "settings.option.general.updateCider.branch.develop": "Development", + "settings.option.general.customizeSidebar": "Customize Sidebar Items", + "settings.option.general.customizeSidebar.customize": "Customize", + "settings.option.general.keybindings": "Keybindings", + "settings.notyf.general.keybindings.update.success": "Keybind updated successfully", + "settings.prompt.general.keybindings.update.success": "Keybind updated successfully. Press OK to relaunch Cider", + "settings.option.general.keybindings.open": "Open", + "settings.description.search": "Search", + "settings.description.albums": "Library Albums", + "settings.description.artists": "Library Artists", + "settings.description.browse": "Browse", + "settings.description.private": "Toggle Private Session", + "settings.description.remote": "Web Remote", + "settings.description.audio": "Audio Settings", + "settings.description.plugins": "Plugins Menu", + "settings.description.cast": "Cast to Devices", + "settings.description.settings": "Settings", + "settings.description.developer": "Developer Tools", + "settings.notyf.updateCider.update-not-available": "現在最新版です", + "settings.notyf.updateCider.update-downloaded": "アップデートは再起動後に適用されます", + "settings.notyf.updateCider.update-error": "アップデートに失敗しました", + "settings.notyf.updateCider.update-timeout": "アップデートはタイムアウトしました", + "settings.header.audio": "オーディオ", + "settings.header.audio.description": "Ciderのオーディオ設定", + "settings.option.audio.volumeStep": "音量調整のステップ", + "settings.option.audio.maxVolume": "最大音量", + "settings.option.audio.changePlaybackRate": "Change Playback Rate", + "settings.option.audio.playbackRate": "Playback Rate", + "settings.option.audio.playbackRate.change": "Change", + "settings.option.audio.quality": "音質", + "settings.header.audio.quality.hireslossless": "ハイレゾロスレス", + "settings.header.audio.quality.hireslossless.description": "(最大解像度 24 ビット/192 kHz)", + "settings.header.audio.quality.lossless": "ロスレス", + "settings.header.audio.quality.lossless.description": "(最大解像度 24 ビット/48 kHz)", + "settings.header.audio.quality.enhanced": "エンハンスド", + "settings.header.audio.quality.high": "高品質", + "settings.header.audio.quality.standard": "高効率", + "settings.option.audio.seamlessTransition": "曲間なしで再生", + "settings.option.audio.enableAdvancedFunctionality": "先進的な機能", + "settings.option.audio.enableAdvancedFunctionality.description": "AudioContextを有効にすると、オーディオノーマライズ、空間オーディオ、イコライザーなどの機能を使用できますが、音が途切れるかもしれません。", + "settings.warn.audio.enableAdvancedFunctionality.lowcores": "Cider thinks your PC can't handle these features. Are you sure you want to continue?", + "settings.option.audio.audioLab": "Cider Audio Lab", + "settings.option.audio.audioLab.description": "An assortment of in-house developed audio effects for Cider.", + "settings.warn.audioLab.withoutAF": "AudioContext (Advanced Functionality) is required to enable Cider Audio Laboratory.", + "settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Analog Warmth", + "settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Korg Nutube 6P1をモデルにしたオーディオをシミュレートします", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Changes the intensity of the Analog Warmth Module processing.", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "Smooth", + "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "Warm", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider Atmosphere Realizer™️", + "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.description": "Changes the mode of operation of the Atmosphere Realizer module.", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural1": "Natural (Standard)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural2": "Natural (High)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural3": "Natural (Plus)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "音楽をより豊かに、生き生きとさせます", + "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAPはSpatializationと互換性がありません", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAPの強さ", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "音に施す処理の強さを設定します (強くしすぎると望ましい結果が得られないかもしれません)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "標準", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "高", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "オーディオノーマライズ", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "さまざまな曲の音量を均一にし、より整った音を楽しめるようにする機能です。", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Managed by Audio Lab", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "オーディオ空間化", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "音声を空間化しすることで、より立体的にできます(Dolby Atmosではありません)", + "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Cider Tuned Spatialization", + "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "開発チームがチューニングした設定を使用することができます。(オーディオ空間化を有効にする必要があります)", + "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.standard": "Standard", + "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile", + "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "オーディオ空間化はCAPと互換性がありません", + "settings.header.visual": "ビジュアル", + "settings.header.visual.description": "Ciderのビジュアル設定", + "settings.option.visual.windowStyle": "Window Style", + "settings.option.visual.windowBackgroundStyle": "背景の設定", + "settings.header.visual.windowBackgroundStyle.none": "なし", + "settings.header.visual.windowBackgroundStyle.artwork": "アートワーク", + "settings.header.visual.windowBackgroundStyle.image": "画像", + "settings.option.visual.animatedArtwork": "アニメーションアートワーク", + "settings.header.visual.animatedArtwork.always": "常に表示", + "settings.header.visual.animatedArtwork.limited": "アーティストページのみ表示", + "settings.header.visual.animatedArtwork.disable": "オフ", + "settings.option.visual.animatedArtworkQuality": "アニメーションアートワークの品質", + "settings.header.visual.animatedArtworkQuality.low": "低", + "settings.header.visual.animatedArtworkQuality.medium": "中", + "settings.header.visual.animatedArtworkQuality.high": "高", + "settings.header.visual.animatedArtworkQuality.veryHigh": "超高", + "settings.header.visual.animatedArtworkQuality.extreme": "最高", + "settings.option.visual.animatedWindowBackground": "背景のアニメーション", + "settings.option.visual.hardwareAcceleration": "ハードウェアアクセラレーション", + "settings.option.visual.hardwareAcceleration.description": "再起動してください", + "settings.header.visual.hardwareAcceleration.default": "既定", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.option.visual.uiscale": "UI Scale", + "settings.header.visual.theme": "テーマ", + "settings.option.visual.theme.github.download": "GitHub URLからインストール", + "settings.option.visual.theme.github.openfolder": "Open Themes Folder", + "settings.option.visual.theme.github.explore": "GitHubで探す", + "settings.header.visual.theme.github.page": "GitHub", + "settings.option.visual.theme.github.install.confirm": "本当に {{ repo }} をインストールしますか?", + "settings.prompt.visual.theme.github.URL": "インストールしたいテーマのURLを入力してください", + "settings.notyf.visual.theme.install.success": "テーマのインストールが完了しました", + "settings.notyf.visual.theme.install.error": "テーマのインストールに失敗しました", + "settings.header.visual.plugin": "プラグイン", + "settings.option.visual.plugin.github.download": "GitHub URLからインストール", + "settings.option.visual.plugin.github.explore": "GitHubで探す", + "settings.header.visual.plugin.github.page": "GitHub", + "settings.option.visual.plugin.github.install.confirm": "本当に {{ repo }} をインストールしますか?", + "settings.prompt.visual.plugin.github.URL": "インストールしたいプラグインのURLを入力してください", + "settings.prompt.visual.plugin.github.success": "プラグインのインストールを完了させるには「完了」を押した後にCiderを再起動してください", + "settings.notyf.visual.plugin.install.success": "プラグインのインストールが完了しました", + "settings.notyf.visual.plugin.install.error": "プラグインのインストールに失敗しました", + "settings.option.visual.theme.default": "Cider", + "settings.option.visual.theme.dark": "Dark", + "settings.option.visual.showPersonalInfo": "個人情報を表示する", + "settings.header.window": "ウィンドウ", + "settings.header.window.description": "ウィンドウの設定", + "settings.option.window.openOnStartup": "Ciderをスタートアップに設定する", + "settings.option.window.openOnStartup.hidden": "パソコン起動時にCiderをトレイに最小化", + "settings.option.window.useNativeTitleBar": "Use Native Title Bar", + "settings.option.window.windowControlStyle": "Window Control Style", + "settings.option.window.windowControlStyle.right": "右側", + "settings.option.window.windowControlStyle.left": "左側", + "settings.header.lyrics": "歌詞", + "settings.header.lyrics.description": "Adjust the lyrics settings for Cider.", + "settings.option.lyrics.enableMusixmatch": "Musixmatchが提供する歌詞を表示する", + "settings.option.lyrics.enableMusixmatchKaraoke": "カラオケモードを有効にする (Musixmatchのみで利用できます)", + "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatchで表示する歌詞の言語", + "settings.option.lyrics.enableYoutubeLyrics": "YouTubeの歌詞をミュージックビデオで使用する", + "settings.option.lyrics.enableQQLyrics": "Enable QQ Lyrics", + "settings.header.connectivity": "接続", + "settings.header.connectivity.description": "Ciderの接続設定", + "settings.option.connectivity.playbackNotifications": "再生している曲を通知する", + "settings.option.connectivity.discordRPC": "Discord Rich Presence", + "settings.option.connectivity.discordRPC.clientName": "Client Name", + "settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause", + "settings.option.connectivity.discordRPC.hideButtons": "Hide buttons on Discord Rich Presence", + "settings.option.connectivity.discordRPC.detailsFormat": "Details Format", + "settings.option.connectivity.discordRPC.stateFormat": "State Format", + "settings.option.connectivity.lastfmScrobble": "Last.fm に接続する", + "settings.option.connectivity.lastfmScrobble.delay": "遅延 (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Last.fm Now Playingを有効化する", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "曲名からフューチャリングいているアーティストの名前を削除する (Last.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "ループトラックのフィルター(Last.fm)", + "settings.header.debug": "デバッグ", + "settings.option.debug.copy_log": "Copy logs to clipboard", + "settings.option.debug.openAppData": "Open Cider Folder", + "settings.header.experimental": "試験的な機能", + "settings.header.experimental.description": "試験的な設定", + "settings.option.experimental.reinstallwidevine": "Reinstall WidevineCDM", + "settings.option.experimental.reinstallwidevine.confirm": "Are you sure you want to reinstall Widevine?", + "settings.option.experimental.unknownPlugin": "未知のダウンロード元", + "settings.option.experimental.unknownPlugin.description": "外部からプラグインをインストールできるようにする", + "settings.option.experimental.compactUI": "コンパクトUI", + "settings.option.window.close_button_hide": "Ciderを閉じるとタスクに最小化する", + "settings.option.experimental.inline_playlists": "プレイリストをインラインに表示する", + "settings.option.advanced.playlistTrackMapping": "プレイリストをマッピング", + "settings.option.advanced.playlistTrackMapping.description": "プレイリストをスキャンすることで含まれる曲をより識別しやすくなります", + "settings.option.visual.transparent": "背景の透過", + "settings.option.visual.transparent.description": "(テーマがこの機能をサポートしている必要があります)", + "settings.header.advanced": "Advanced", + "settings.header.connect": "Sync", + "settings.option.connect.link_account": "Enable Sync with Cider Connect", + "settings.option.connect.link_account.description": "Linking your Discord account with Cider Connect allows you to store userdata including Settings, EQ's, and eventually more once finished. (Work In Progress)", + "spatial.notTurnedOn": "オーディオ空間化が無効になっています。この機能を使用するには有効にしてください!", + "spatial.spatialProperties": "空間化のプロパティ", + "spatial.width": "幅", + "spatial.height": "高さ", + "spatial.depth": "奥行", + "spatial.gain": "ゲイン", + "spatial.roomMaterials": "部屋のマテリアル", + "spatial.roomDimensions": "部屋の大きさ", + "spatial.roomPositions": "部屋の位置", + "spatial.setDimensions": "大きさを設定する", + "spatial.setPositions": "位置を設定する", + "spatial.up": "上", + "spatial.front": "手前", + "spatial.left": "左", + "spatial.right": "右", + "spatial.back": "奥", + "spatial.down": "下", + "spatial.listener": "リスナー", + "spatial.audioSource": "音源", + "settings.header.unfinished": "未完了", + "remote.web.title": "Cider リモート", + "remote.web.description": "QRコードを使用して、Ciderとスマートフォンをペアリングする", + "share.platform.twitter.tweet": "{{song}}をApple Musicで聞いています\n\n{{url}}\n\n#AppleMusic #Cider", + "share.platform.twitter": "Twitter", + "share.platform.facebook": "Facebook", + "share.platform.reddit": "Reddit", + "share.platform.telegram": "Telegram", + "share.platform.whatsapp": "WhatsApp", + "share.platform.messenger": "Messenger", + "share.platform.email": "Email", + "share.platform.songLink": "song.linkのURLをコピーする", + "share.platform.clipboard": "URLをコピーする", + "about.thanks": "Cider Collective とご協力いただいた貢献者様に感謝申し上げます。" + } + \ No newline at end of file diff --git a/src/i18n/source/en_US.json b/src/i18n/source/en_US.json index cb7cb1da..71d7a3d8 100644 --- a/src/i18n/source/en_US.json +++ b/src/i18n/source/en_US.json @@ -73,6 +73,7 @@ "term.viewAs": "View As", "term.viewAs.coverArt": "Cover Art", "term.viewAs.list": "List", + "term.dynamic": "Dynamic", "term.size": "Size", "term.size.normal": "Normal", "term.size.compact": "Compact", @@ -199,6 +200,9 @@ "podcast.episodes": "Episodes", "podcast.playEpisode": "Play Episode", "podcast.website": "Podcast Website", + "action.edit": "Edit", + "action.done": "Done", + "action.editTracklist": "Edit Tracklist", "action.addToLibrary": "Add to Library", "action.addToLibrary.success": "Added to Library", "action.addToLibrary.error": "Error Adding to Library", @@ -269,6 +273,10 @@ "settings.option.general.resumebehavior.locally.description": "Cider will resume your last session on this machine.", "settings.option.general.resumebehavior.history": "History", "settings.option.general.resumebehavior.history.description": "Cider will queue the last song from your overall Apple Music history, across devices.", + "settings.option.general.resumetabs" : "Open Tab on Launch", + "settings.option.general.resumetabs.description" : "You can choose what tab you want to open when you launch Cider.", + "settings.option.general.resumetabs.dynamic" : "Dynamic", + "settings.option.general.resumetabs.dynamic.description" : "Cider will open the tab that you last used.", "settings.option.general.language.main": "Languages", "settings.option.general.language.fun": "Fun Languages", "settings.option.general.language.unsorted": "Unsorted", @@ -280,12 +288,14 @@ "settings.option.general.customizeSidebar": "Customize Sidebar Items", "settings.option.general.customizeSidebar.customize": "Customize", "settings.option.general.keybindings": "Keybindings", + "settings.notyf.general.keybindings.update.success": "Keybind updated successfully", + "settings.prompt.general.keybindings.update.success": "Keybind updated successfully. Press OK to relaunch Cider", "settings.option.general.keybindings.open": "Open", "settings.description.search": "Search", "settings.description.albums": "Library Albums", "settings.description.artists": "Library Artists", "settings.description.browse": "Browse", - "settings.description.private": "Toogle Private Session", + "settings.description.private": "Toggle Private Session", "settings.description.remote": "Web Remote", "settings.description.audio": "Audio Settings", "settings.description.plugins": "Plugins Menu", @@ -410,6 +420,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Enable Karaoke Mode (Musixmatch only)", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch Translation Preferred Language", "settings.option.lyrics.enableYoutubeLyrics": "Enable Youtube Lyrics for Music Videos", + "settings.option.lyrics.enableQQLyrics": "Enable QQ Lyrics", "settings.header.connectivity": "Connectivity", "settings.header.connectivity.description": "Adjust the connectivity settings for Cider.", "settings.option.connectivity.playbackNotifications": "Playback Notifications", @@ -441,7 +452,9 @@ "settings.option.visual.transparent": "Transparent frame", "settings.option.visual.transparent.description": "(needs Theme Support, requires relaunch)", "settings.header.advanced": "Advanced", - "settings.header.connect": "Connect", + "settings.header.connect": "Sync", + "settings.option.connect.link_account": "Enable Sync with Cider Connect", + "settings.option.connect.link_account.description": "Linking your Discord account with Cider Connect allows you to store userdata including Settings, EQ's, and eventually more once finished. (Work In Progress)", "spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.", "spatial.spatialProperties": "Spatial Properties", "spatial.width": "Width", diff --git a/src/i18n/zh_HK.json b/src/i18n/zh_HK.json index 64f05a03..3717198f 100644 --- a/src/i18n/zh_HK.json +++ b/src/i18n/zh_HK.json @@ -115,7 +115,7 @@ "term.contributors": "貢獻者", "term.equalizer": "均衡器", "term.reset": "重設", - "term.tracks": "首歌曲", + "term.tracks": "歌曲", "term.videos": "MV", "term.menu": "選項", "term.check": "檢查", @@ -225,6 +225,10 @@ "settings.option.general.resumebehavior.locally.description": "Cider 將還原你在這台電腦上的最後一次操作。", "settings.option.general.resumebehavior.history": "歷史", "settings.option.general.resumebehavior.history.description": "Cider 將跨裝置將你的整個 Apple Music 歷史記錄中的最後一首歌曲排隊入列。", + "settings.option.general.resumetabs" : "啟動時打開的選項", + "settings.option.general.resumetabs.description" : "你可以選擇啟動 Cider 時要打開的選項。", + "settings.option.general.resumetabs.dynamic" : "動態", + "settings.option.general.resumetabs.dynamic.description" : "Cider 將打開你上次停留的選項。", "settings.option.general.language": "語言", "settings.option.general.language.main": "語言", "settings.option.general.language.fun": "惡搞語言", @@ -236,6 +240,8 @@ "settings.option.general.updateCider.branch.develop": "測試", "settings.option.general.customizeSidebar": "自訂側邊欄的功能", "settings.option.general.customizeSidebar.customize": "自訂", + "settings.option.general.keybindings": "快捷操作鍵", + "settings.option.general.keybindings.open": "開啟", "settings.notyf.updateCider.update-not-available": "沒有可用的更新", "settings.notyf.updateCider.update-downloaded": "更新已成功下載,重啟後進行更新", "settings.notyf.updateCider.update-error": "更新時,發生錯誤", @@ -281,6 +287,7 @@ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "標準", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "發燒友", "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "空間音訊無法與 CAP 相容,請關閉 CAP 再進行操作。", + "settings.option.visual.uiscale": "介面顯示大小", "settings.header.visual": "外觀", "settings.header.visual.description": "調整 Cider 的外觀", "settings.option.visual.windowBackgroundStyle": "視窗背景樣式", @@ -335,14 +342,18 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "開啟卡拉OK模式(僅限Musixmatch)", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好", "settings.option.lyrics.enableYoutubeLyrics": "播放 MV 時,使用 YouTube 歌詞", + "settings.option.lyrics.enableQQLyrics": "開啟 QQ 音樂的歌詞", "settings.header.connectivity": "外部連結", "settings.header.connectivity.description": "調整 Cider 與外部的連結", "settings.option.connectivity.discordRPC": "Discord 狀態", "settings.option.connectivity.playbackNotifications": "播放通知", + "settings.option.connectivity.discordRPC.clientName": "應用程式名稱", "settings.header.connectivity.discordRPC.cider": "顯示為'Cider'", "settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", "settings.option.connectivity.discordRPC.hideButtons": "隱藏 Discord 狀態上的按鈕", + "settings.option.connectivity.discordRPC.detailsFormat": "詳細資訊格式", + "settings.option.connectivity.discordRPC.stateFormat": "狀態格式", "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling 記錄", "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble 延遲 (%)", "settings.option.connectivity.lastfmScrobble.nowPlaying": "開啟 Last.fm 正在播放", @@ -366,6 +377,9 @@ "settings.option.visual.transparent": "透明視窗框架", "settings.option.visual.transparent.description": "需主題有支援透明框架,且須重新啟動才會套用。", "settings.header.advanced": "進階", + "settings.header.connect": "同步", + "settings.option.connect.link_account": "開啟與 Cider Connect 同步", + "settings.option.connect.link_account.description": "將您的 Discord 帳戶與 Cider Connect 連接後,你可以儲存使用者資料,包括設定、等化器,並最終在完成後儲存更多資料。(正在進行中)", "spatial.notTurnedOn": "請先在設定中開啟空間音訊。", "spatial.spatialProperties": "空間音訊屬性", "spatial.width": "闊度", diff --git a/src/i18n/zh_TW.json b/src/i18n/zh_TW.json index 5dd4bbd2..8c5083cc 100644 --- a/src/i18n/zh_TW.json +++ b/src/i18n/zh_TW.json @@ -119,7 +119,7 @@ "one": "首歌曲", "other": "首歌曲" }, - "term.tracks": "首歌曲", + "term.tracks": "歌曲", "term.videos": "音樂錄影帶", "term.menu": "選單", "term.check": "檢查", @@ -225,6 +225,8 @@ "settings.option.general.updateCider.branch.develop": "開發者測試版(不穩定)", "settings.option.general.customizeSidebar": "自訂側邊欄的功能", "settings.option.general.customizeSidebar.customize": "自訂", + "settings.option.general.keybindings": "快捷操作鍵", + "settings.option.general.keybindings.open": "開啟", "settings.notyf.updateCider.update-not-available": "沒有可用的更新", "settings.notyf.updateCider.update-downloaded": "更新已成功下載,重啟後進行更新", "settings.notyf.updateCider.update-error": "更新時,發生錯誤", @@ -254,6 +256,13 @@ "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "改變模擬溫暖模組處理的強度。", "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "溫和", "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "溫暖", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider 音樂氣氛實現器™️", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "以最先進的音訊設定為設計,實現不同的音樂氣氛。", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider 音樂氣氛™️模式", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "更改氣氛實現器模塊的操作模式。", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural1": "自然(標準)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural2": "自然(高)", + "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.natural3": "自然(增強)", "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 數位增強音訊處理™️", "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "透過人類的聽力心理學模型和 AAC 編碼特色的即時算法,強化 256 kbps AAC 音訊的感知音訊品質。", "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "數位增強音訊處理設定", @@ -326,14 +335,16 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "開啟K歌模式(僅限 Musixmatch)", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞優先語言偏好選項", "settings.option.lyrics.enableYoutubeLyrics": "播放 MV 時,使用 YouTube 歌詞", + "settings.option.lyrics.enableQQLyrics": "開啟 QQ 音樂的歌詞", "settings.header.connectivity": "外部連接", "settings.header.connectivity.description": "調整 Cider 與外部的連接", - "settings.option.connectivity.discordRPC": "Discord 動態", "settings.option.connectivity.playbackNotifications": "歌曲播放通知", - "settings.header.connectivity.discordRPC.cider": "顯示正在使用 Cider", - "settings.header.connectivity.discordRPC.appleMusic": "顯示正在使用 Apple Music", + "settings.option.connectivity.discordRPC": "Discord 動態", + "settings.option.connectivity.discordRPC.clientName": "應用程式名稱", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 動態", "settings.option.connectivity.discordRPC.hideButtons": "隱藏 Discord 動態上的按鈕", + "settings.option.connectivity.discordRPC.detailsFormat": "詳細資訊格式", + "settings.option.connectivity.discordRPC.stateFormat": "狀態格式", "settings.option.connectivity.lastfmScrobble": "Last.FM Scrobbling 記錄", "settings.option.connectivity.lastfmScrobble.delay": "Last.FM Scrobble 延遲 (%)", "settings.option.connectivity.lastfmScrobble.nowPlaying": "開啟 Last.FM 正在聆聽", @@ -357,6 +368,9 @@ "settings.option.visual.transparent": "透明視窗框架", "settings.option.visual.transparent.description": "需主題有支援透明框架,且須重新啟動才會套用。", "settings.header.advanced": "進階", + "settings.header.connect": "同步", + "settings.option.connect.link_account": "開啟與 Cider Connect 同步", + "settings.option.connect.link_account.description": "將您的 Discord 帳戶與 Cider Connect 連接後,你可以儲存使用者資料,包括設定、等化器,並最終在完成後儲存更多資料。(正在進行中)", "spatial.notTurnedOn": "空間音訊目前是關閉狀態,請先開啟再使用。", "spatial.spatialProperties": "空間音訊屬性設定", "spatial.width": "寬度", diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts index f08f1c98..afb38607 100644 --- a/src/main/base/browserwindow.ts +++ b/src/main/base/browserwindow.ts @@ -423,6 +423,14 @@ export class BrowserWindow { res.render("main", this.EnvironmentVariables); }); + app.get("/audio/cideraudio.js", (_req, res) => { + if (existsSync(join(utils.getPath("externals"), "/audio.js"))) { + res.sendFile(join(utils.getPath("externals"), "/audio.js")); + } else { + res.sendFile(join(utils.getPath('srcPath'), "./renderer/audio/audio.js")); + } + }) + app.get("/api/playback/:action", (req, res) => { const action = req.params.action; switch (action) { diff --git a/src/main/base/store.ts b/src/main/base/store.ts index fe9cd36e..1ffbc502 100644 --- a/src/main/base/store.ts +++ b/src/main/base/store.ts @@ -44,6 +44,57 @@ export class Store { "onStartup": { "enabled": false, "hidden": false, + }, + "resumeTabs": { + "tab": "home", + "dynamicData": "" + }, + "keybindings": { + "search": [ + process.platform == "darwin" ? "Command" : "Control", + "S" + ], + "albums": [ + process.platform == "darwin" ? "Command" : "Control", + "F" + ], + "artists": [ + process.platform == "darwin" ? "Command" : "Control", + "D" + ], + "browse": [ + process.platform == "darwin" ? "Command" : "Control", + "B" + ], + "togglePrivateSession": [ + process.platform == "darwin" ? "Command" : "Control", + "P" + ], + "webRemote": [ + process.platform == "darwin" ? "Command" : "Control", + "W" + ], + "audioSettings": [ + process.platform == "darwin" ? "Option" : "Shift", + "A" + ], + "pluginMenu": [ + process.platform == "darwin" ? "Option" : "Shift", + "P" + ], + "castToDevices": [ + process.platform == "darwin" ? "Option" : "Shift", + "C" + ], + "settings": [ + process.platform == "darwin" ? "Option" : "Shift", + "S" + ], + "openDeveloperTools": [ + process.platform == "darwin" ? "Command" : "Control", + process.platform == "darwin" ? "Option" : "Shift", + "I" + ] } }, "home": { @@ -123,7 +174,7 @@ export class Store { "styles": [], "scrollbars": 0, // 0 = show on hover, 2 = always hide, 3 = always show "refresh_rate": 0, - "window_background_style": "artwork", // "none", "artwork", "color" + "window_background_style": "none", // "none", "artwork", "color" "animated_artwork": "limited", // 0 = always, 1 = limited, 2 = never "animated_artwork_qualityLevel": 1, "bg_artwork_rotation": false, @@ -142,6 +193,7 @@ export class Store { "enable_mxm": false, "mxm_karaoke": false, "mxm_language": "en", + "enable_qq": false, "enable_yt": false, }, "lastfm": { diff --git a/src/main/base/utils.ts b/src/main/base/utils.ts index 337e6f79..9889c4ff 100644 --- a/src/main/base/utils.ts +++ b/src/main/base/utils.ts @@ -6,6 +6,7 @@ import {app, dialog, ipcMain, Notification, shell } from "electron"; import fetch from "electron-fetch"; import {AppImageUpdater, NsisUpdater} from "electron-updater"; import * as log from "electron-log"; +import ElectronStore from "electron-store"; export class utils { @@ -22,6 +23,7 @@ export class utils { ciderCache: path.resolve(app.getPath("userData"), "CiderCache"), themes: path.resolve(app.getPath("userData"), "Themes"), plugins: path.resolve(app.getPath("userData"), "Plugins"), + externals: path.resolve(app.getPath("userData"), "externals"), }; /** @@ -78,6 +80,14 @@ export class utils { return Store.cfg.store } + /** + * Get the store instance + * @returns {Store} + */ + static getStoreInstance(): ElectronStore { + return Store.cfg + } + /** * Sets a store value * @param key diff --git a/src/main/base/wsapi.ts b/src/main/base/wsapi.ts index bb48d86a..a10fd529 100644 --- a/src/main/base/wsapi.ts +++ b/src/main/base/wsapi.ts @@ -157,6 +157,10 @@ export class wsapi { this._win.webContents.executeJavaScript(`MusicKit.getInstance().pause()`); response.message = "Paused"; break; + case "playpause": + this._win.webContents.executeJavaScript(`MusicKitInterop.playPause()`); + response.message = "Play/Pause"; + break case "play": this._win.webContents.executeJavaScript(`MusicKit.getInstance().play()`); response.message = "Playing"; diff --git a/src/main/plugins/menubar.ts b/src/main/plugins/menubar.ts index 04236d5a..b47dcabe 100644 --- a/src/main/plugins/menubar.ts +++ b/src/main/plugins/menubar.ts @@ -2,12 +2,6 @@ import {app, Menu, shell} from "electron"; import {utils} from "../base/utils"; export default class Thumbar { - /** - * Private variables for interaction in plugins - */ - private _win: any; - private _app: any; - private _store: any; /** * Base Plugin Details (Eventually implemented into a GUI in settings) @@ -15,20 +9,8 @@ export default class Thumbar { public name: string = 'Menubar Plugin'; public description: string = 'Creates the menubar'; public version: string = '1.0.0'; - public author: string = 'Core / Quacksire'; - - /** - * Thumbnail Toolbar Assets - * NATIVE-IMAGE DOESN'T SUPPORT SVG - private icons: { [key: string]: Electron.NativeImage } = { - remoteIcon: nativeImage.createFromPath(join(utils.getPath('rendererPath'), 'views/svg/smartphone.svg')).toPNG(), - soundIcon: nativeImage.createFromPath(join(utils.getPath('rendererPath'), 'views/svg/headphones.svg')).toPNG(), - aboutIcon: nativeImage.createFromPath(join(utils.getPath('rendererPath'), 'views/svg/info.svg')).toPNG(), - settingsIcon: nativeImage.createFromPath(join(utils.getPath('rendererPath'), 'views/svg/settings.svg')).toPNG(), - logoutIcon: nativeImage.createFromPath(join(utils.getPath('rendererPath'), 'views/svg/log-out.svg')).toPNG(), - ciderIcon: nativeImage.createFromPath(join(utils.getPath('rendererPath'), 'assets/logocute.png')).toPNG(), - } - */ + public author: string = 'Core'; + public contributors: string[] = ['Core', 'Qwack', 'Monochromish']; /** * Menubar Assets @@ -41,13 +23,13 @@ export default class Thumbar { submenu: [ { label: 'About', - click: () => this._win.webContents.executeJavaScript(`app.appRoute('about')`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`) }, {type: 'separator'}, { label: 'Settings', - accelerator: 'CommandOrControl+,', - click: () => this._win.webContents.executeJavaScript(`app.appRoute('settings')`) + accelerator: utils.getStoreValue("general.keybindings.settings").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('settings')`) }, {type: 'separator'}, {role: 'services'}, @@ -104,27 +86,26 @@ export default class Thumbar { {type: 'separator'}, { label: 'Toggle Private Session', - accelerator: 'CommandOrControl+P', - click: () => this._win.webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`) + accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`) }, {type: 'separator'}, { label: 'Web Remote', - accelerator: 'CommandOrControl+Shift+W', + accelerator: utils.getStoreValue("general.keybindings.webRemote").join('+'), sublabel: 'Opens in external window', - click: () => this._win.webContents.executeJavaScript(`app.appRoute('remote-pair')`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('remote-pair')`) }, { label: 'Audio Settings', - accelerator: 'CommandOrControl+Shift+A', - click: () => this._win.webContents.executeJavaScript(`app.modals.audioSettings = true`) + accelerator: utils.getStoreValue("general.keybindings.audioSettings").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.audioSettings = true`) }, { label: 'Plug-in Menu', - accelerator: 'CommandOrControl+Shift+P', - click: () => this._win.webContents.executeJavaScript(`app.modals.pluginMenu = true`) + accelerator: utils.getStoreValue("general.keybindings.pluginMenu").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`) } - ] }, { @@ -133,34 +114,56 @@ export default class Thumbar { { label: 'Pause / Play', accelerator: 'Space', - click: () => this._win.webContents.executeJavaScript(`app.SpacePause()`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`) }, { label: 'Next', accelerator: 'CommandOrControl+Right', - click: () => this._win.webContents.executeJavaScript(`MusicKitInterop.next()`) + click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`) }, { label: 'Previous', accelerator: 'CommandOrControl+Left', - click: () => this._win.webContents.executeJavaScript(`MusicKitInterop.previous()`) + click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`) }, {type: 'separator'}, { label: 'Volume Up', accelerator: 'CommandOrControl+Up', - click: () => this._win.webContents.executeJavaScript(`app.volumeUp()`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`) }, { label: 'Volume Down', accelerator: 'CommandOrControl+Down', - click: () => this._win.webContents.executeJavaScript(`app.volumeDown()`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeDown()`) + }, + { + label: 'Browse', + accelerator: utils.getStoreValue("general.keybindings.browse").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`) + }, + {type: 'separator'}, + { + label: 'Artists', + accelerator: utils.getStoreValue("general.keybindings.artists").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-artists')`) + }, + { + label: 'Search', + accelerator: utils.getStoreValue("general.keybindings.search").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('search')`) + }, + {type: 'separator'}, + { + label: 'Album', + accelerator: utils.getStoreValue("general.keybindings.albums").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`) }, {type: 'separator'}, { label: 'Cast To Devices', - accelerator: 'CommandOrControl+Shift+C', - click: () => this._win.webContents.executeJavaScript(`app.modals.castMenu = true`) + accelerator: utils.getStoreValue("general.keybindings.castToDevices").join('+'), + click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`) } ] }, @@ -169,11 +172,11 @@ export default class Thumbar { submenu: [ { label: 'Account Settings', - click: () => this._win.webContents.executeJavaScript(`app.appRoute('apple-account-settings')`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('apple-account-settings')`) }, { label: 'Sign Out', - click: () => this._win.webContents.executeJavaScript(`app.unauthorize()`) + click: () => utils.getWindow().webContents.executeJavaScript(`app.unauthorize()`) } ] }, @@ -215,16 +218,16 @@ export default class Thumbar { {type: 'separator'}, { label: 'Toggle Developer Tools', - accelerator: 'Option+CommandOrControl+Shift+I', - click: () => this._win.webContents.openDevTools() + accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join('+'), + click: () => utils.getWindow().webContents.openDevTools() }, { label: 'Open Configuration File in Editor', - click: () => this._store.openInEditor() + click: () => utils.getStoreInstance().openInEditor() } ] } - ] + ]; /******************************************************************************************* * Public Methods @@ -233,17 +236,14 @@ export default class Thumbar { /** * Runs on plugin load (Currently run on application start) */ - constructor(utils: { getApp: () => any; getStore: () => any; }) { - this._app = utils.getApp(); - this._store = utils.getStore(); + constructor(_utils: utils) { console.debug(`[Plugin][${this.name}] Loading Complete.`); } /** * Runs on app ready */ - onReady(win: Electron.BrowserWindow): void { - this._win = win; + onReady(_win: Electron.BrowserWindow): void { const menu = Menu.buildFromTemplate(this._menuTemplate); Menu.setApplicationMenu(menu) } diff --git a/optional/Plugins/raop.ts b/src/main/plugins/raop.ts similarity index 96% rename from optional/Plugins/raop.ts rename to src/main/plugins/raop.ts index c466b915..e6908375 100644 --- a/optional/Plugins/raop.ts +++ b/src/main/plugins/raop.ts @@ -20,10 +20,10 @@ export default class RAOP { private _app: any; private _store: any; private _cacheAttr: any; - + private u: any; private ipairplay: any = ""; private portairplay: any = ""; - private u = require('airtunes2'); + private airtunes: any; private device: any; private mdns = require('mdns-js'); @@ -132,6 +132,7 @@ export default class RAOP { * Runs on app ready */ onReady(win: any): void { + this.u = require('airtunes2'); this._win = win; electron.ipcMain.on('getKnownAirplayDevices', (event) => { @@ -146,8 +147,8 @@ export default class RAOP { browser.on('ready', browser.discover); browser.on('update', (service: any) => { - if (service.addresses && service.fullname && service.fullname.includes('_raop._tcp')) { - console.log(service.txt) + if (service.addresses && service.fullname && (service.fullname.includes('_raop._tcp') || service.fullname.includes('_airplay._tcp'))) { + // console.log(service.txt) this._win.webContents.executeJavaScript(`console.log( "${service.name} ${service.host}:${service.port} ${service.addresses}" )`); @@ -158,7 +159,7 @@ export default class RAOP { - electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL) => { + electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL,txt) => { if (ipv4 != this.ipairplay || ipport != this.portairplay) { if (this.airtunes == null) { this.airtunes = new this.u()} @@ -168,7 +169,9 @@ export default class RAOP { port: ipport, volume: 60, password: sepassword, + txt: txt }); + // console.log('lol',txt) this.device.on('status', (status: any) => { console.log('device status', status); if (status == "ready"){ diff --git a/src/renderer/audio/audio.js b/src/renderer/audio/audio.js index 78ff5fef..c8c9c799 100644 --- a/src/renderer/audio/audio.js +++ b/src/renderer/audio/audio.js @@ -50,7 +50,7 @@ const CiderAudio = { }, connectContext: function (mediaElem) { if (!CiderAudio.context) { - CiderAudio.context = new window.AudioContext({sampleRate: 96000}); // Don't ever remove the sample rate arg. Ask Maikiwi. + CiderAudio.context = new window.AudioContext({ sampleRate: 96000 }); // Don't ever remove the sample rate arg. Ask Maikiwi. } if (!CiderAudio.source) { CiderAudio.source = CiderAudio.context.createMediaElementSource(mediaElem); @@ -62,7 +62,7 @@ const CiderAudio = { if (app.cfg.audio.normalization) { CiderAudio.normalizerOn() } - if (app.cfg.audio.spatial) { + if (app.cfg.audio.maikiwiAudio.spatial) { CiderAudio.spatialOn() } CiderAudio.hierarchical_loading(); @@ -127,57 +127,35 @@ const CiderAudio = { ], spatialOn: function () { CiderAudio.audioNodes.spatialNode = null; - if (app.cfg.audio.maikiwiAudio.spatial === true) { - CiderAudio.audioNodes.spatialNode = CiderAudio.context.createConvolver(); - CiderAudio.audioNodes.spatialNode.normalize = false; + CiderAudio.audioNodes.spatialNode = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.spatialNode.normalize = false; - let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { - return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; - }); - - if (spatialProfile === undefined) { - spatialProfile = CiderAudio.spatialProfiles[0]; - } - fetch(spatialProfile.file).then(async (impulseData) => { - let bufferedImpulse = await impulseData.arrayBuffer(); - CiderAudio.audioNodes.spatialNode.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); - }); + let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { + return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; + }); + if (spatialProfile === undefined) { + spatialProfile = CiderAudio.spatialProfiles[0]; } - else { - CiderAudio.audioNodes.spatialNode = new ResonanceAudio(CiderAudio.context); - let roomDimensions = { - width: 32, - height: 12, - depth: 32, - }; - let roomMaterials = { - // Room wall materials - left: 'metal', - right: 'metal', - front: 'brick-bare', - back: 'brick-bare', - down: 'acoustic-ceiling-tiles', - up: 'acoustic-ceiling-tiles', - }; - CiderAudio.audioNodes.spatialNode.setRoomProperties(roomDimensions, roomMaterials); - CiderAudio.audioNodes.spatialInput = CiderAudio.audioNodes.spatialNode.createSource(); - } + fetch(spatialProfile.file).then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.spatialNode.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); }, spatialOff: function () { CiderAudio.hierarchical_loading(); }, intelliGainComp_h0_0: function () { let filters = []; const precisionHz = 12; - if (CiderAudio.audioNodes.audioBands !== null) {filters = filters.concat(CiderAudio.audioNodes.audioBands)} - if (CiderAudio.audioNodes.vibrantbassNode !== null) {filters = filters.concat(CiderAudio.audioNodes.vibrantbassNode)} - if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length > 1) {filters = filters.concat(CiderAudio.audioNodes.llpw);} - if (CiderAudio.audioNodes.analogWarmth !== null) {filters = filters.concat(CiderAudio.audioNodes.analogWarmth)} + if (CiderAudio.audioNodes.audioBands !== null) { filters = filters.concat(CiderAudio.audioNodes.audioBands) } + if (CiderAudio.audioNodes.vibrantbassNode !== null) { filters = filters.concat(CiderAudio.audioNodes.vibrantbassNode) } + if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length > 1) { filters = filters.concat(CiderAudio.audioNodes.llpw); } + if (CiderAudio.audioNodes.analogWarmth !== null) { filters = filters.concat(CiderAudio.audioNodes.analogWarmth) } if (!filters || filters.length === 0) { let filterlessGain = 1; - if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length == 1) {filterlessGain = filterlessGain * 1.109174815262401} - if (app.cfg.audio.maikiwiAudio.atmosphereRealizer == true) {filterlessGain = filterlessGain * 1.096478196143185} + if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length == 1) { filterlessGain = filterlessGain * 1.109174815262401 } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer == true) { filterlessGain = filterlessGain * 1.096478196143185 } if (app.cfg.audio.maikiwiAudio.spatial == true) { let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; @@ -185,12 +163,13 @@ const CiderAudio = { if (spatialProfile === undefined) { spatialProfile = CiderAudio.spatialProfiles[0]; } - filterlessGain = filterlessGain * spatialProfile.gainComp} - filterlessGain = Math.pow(10, (-1 * (20 * Math.log10(filterlessGain))) / 20).toFixed(4); - filterlessGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(filterlessGain, CiderAudio.context.currentTime + 0.3); + filterlessGain = filterlessGain * spatialProfile.gainComp + } + filterlessGain = Math.pow(10, (-1 * (20 * Math.log10(filterlessGain))) / 20).toFixed(4); + filterlessGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(filterlessGain, CiderAudio.context.currentTime + 0.3); console.debug(`[Cider][Audio] IntelliGainComp: ${filterlessGain > 1.0 ? 0 : (20 * Math.log10(filterlessGain)).toFixed(2)} dB (${filterlessGain > 1.0 ? 1 : filterlessGain})`) return; - } + } filters.shift(); let steps = Math.ceil(96000 / precisionHz); @@ -221,8 +200,8 @@ const CiderAudio = { if (gain > maxGain) maxGain = gain; } - if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length == 1) {maxGain = maxGain * 1.109174815262401} - if (app.cfg.audio.maikiwiAudio.atmosphereRealizer == true) {maxGain = maxGain * 1.096478196143185} + if (CiderAudio.audioNodes.llpw !== null && CiderAudio.audioNodes.llpw.length == 1) { maxGain = maxGain * 1.109174815262401 } + if (app.cfg.audio.maikiwiAudio.atmosphereRealizer == true) { maxGain = maxGain * 1.096478196143185 } if (app.cfg.audio.maikiwiAudio.spatial == true) { let spatialProfile = CiderAudio.spatialProfiles.find(function (profile) { return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile; @@ -230,7 +209,8 @@ const CiderAudio = { if (spatialProfile === undefined) { spatialProfile = CiderAudio.spatialProfiles[0]; } - maxGain = maxGain * spatialProfile.gainComp} + maxGain = maxGain * spatialProfile.gainComp + } maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4); maxGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudio.context.currentTime + 0.3); console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`); @@ -376,7 +356,7 @@ const CiderAudio = { } } CiderAudio.audioNodes.recorderNode.parameters.get('isRecording').setValueAtTime(1, CiderAudio.context.currentTime); - CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.recorderNode); + CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.recorderNode); }); clearInterval(searchInt); @@ -399,37 +379,46 @@ const CiderAudio = { } }, atmosphereRealizer_h2_4: function (status, hierarchy) { - if (status === true) { + if (status === true) { switch (app.cfg.audio.maikiwiAudio.atmosphereRealizer_value) { - case "NATURAL_STANDARD": + case "NATURAL_STANDARD": CiderAudio.audioNodes.atmosphereRealizer = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.atmosphereRealizer.normalize = false; fetch('./audio/impulses/AtmosphereRealizer_NaturalStandard.wav').then(async (impulseData) => { let bufferedImpulse = await impulseData.arrayBuffer(); CiderAudio.audioNodes.atmosphereRealizer.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); - }); + }); break; - - - case "NATURAL_HIGH": + + + case "NATURAL_HIGH": CiderAudio.audioNodes.atmosphereRealizer = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.atmosphereRealizer.normalize = false; fetch('./audio/impulses/AtmosphereRealizer_NaturalHigh.wav').then(async (impulseData) => { let bufferedImpulse = await impulseData.arrayBuffer(); CiderAudio.audioNodes.atmosphereRealizer.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); - }); + }); break; - case "NATURAL_PLUS": + case "NATURAL_PLUS": CiderAudio.audioNodes.atmosphereRealizer = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.atmosphereRealizer.normalize = false; fetch('./audio/impulses/AtmosphereRealizer_Natural+.wav').then(async (impulseData) => { let bufferedImpulse = await impulseData.arrayBuffer(); CiderAudio.audioNodes.atmosphereRealizer.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); - }); + }); + break; + case "CRYPTO": + CiderAudio.audioNodes.atmosphereRealizer = CiderAudio.context.createConvolver(); + CiderAudio.audioNodes.atmosphereRealizer.normalize = false; + + fetch('./audio/impulses/AtmosphereRealizer_Cryptofyre.wav').then(async (impulseData) => { + let bufferedImpulse = await impulseData.arrayBuffer(); + CiderAudio.audioNodes.atmosphereRealizer.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); + }); break; default: @@ -439,16 +428,16 @@ const CiderAudio = { fetch('./audio/impulses/AtmosphereRealizer_Standard.wav').then(async (impulseData) => { let bufferedImpulse = await impulseData.arrayBuffer(); CiderAudio.audioNodes.atmosphereRealizer.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse); - }); + }); app.cfg.audio.maikiwiAudio.atmosphereRealizer_value = "STANDARD"; break; } switch (hierarchy) { - case 4: - try{ - CiderAudio.audioNodes.atmosphereRealizer.connect(CiderAudio.audioNodes.analogWarmth[0]); - } catch (e) {} + case 4: + try { + CiderAudio.audioNodes.atmosphereRealizer.connect(CiderAudio.audioNodes.analogWarmth[0]); + } catch (e) { } break; case 3: try { @@ -485,7 +474,7 @@ const CiderAudio = { for (let i = 0; i < WARMTH_FREQUENCIES.length; i++) { CiderAudio.audioNodes.analogWarmth[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.analogWarmth[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i] ; + CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i]; CiderAudio.audioNodes.analogWarmth[i].Q.value = WARMTH_Q[i]; CiderAudio.audioNodes.analogWarmth[i].gain.value = WARMTH_GAIN[i] * 1.25; } @@ -495,7 +484,7 @@ const CiderAudio = { for (let i = 0; i < WARMTH_FREQUENCIES.length; i++) { CiderAudio.audioNodes.analogWarmth[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.analogWarmth[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i] ; + CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i]; CiderAudio.audioNodes.analogWarmth[i].Q.value = WARMTH_Q[i]; CiderAudio.audioNodes.analogWarmth[i].gain.value = WARMTH_GAIN[i] * 1.75; } @@ -505,7 +494,7 @@ const CiderAudio = { for (let i = 0; i < WARMTH_FREQUENCIES.length; i++) { CiderAudio.audioNodes.analogWarmth[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.analogWarmth[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i] ; + CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i]; CiderAudio.audioNodes.analogWarmth[i].Q.value = WARMTH_Q[i]; CiderAudio.audioNodes.analogWarmth[i].gain.value = WARMTH_GAIN[i] * 1.25; } @@ -605,7 +594,7 @@ const CiderAudio = { for (let i = 0; i < c_LLPW_FREQUENCIES.length; i++) { CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.llpw[i].frequency.value = c_LLPW_FREQUENCIES[i] ; + CiderAudio.audioNodes.llpw[i].frequency.value = c_LLPW_FREQUENCIES[i]; CiderAudio.audioNodes.llpw[i].Q.value = c_LLPW_Q[i]; CiderAudio.audioNodes.llpw[i].gain.value = c_LLPW_GAIN[i]; } @@ -666,7 +655,7 @@ const CiderAudio = { for (let i = 0; i < VIBRANTBASSBANDS.length; i++) { CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.vibrantbassNode[i].type = 'peaking'; // 'peaking'; - CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i] ; + CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i]; CiderAudio.audioNodes.vibrantbassNode[i].Q.value = VIBRANTBASSQ[i]; CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * (app.cfg.audio.equalizer.vibrantBass / 10); } @@ -719,7 +708,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { // Vibrant Bass, CAP, Analog Warmth, Maikiwi Spatial app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -733,7 +722,7 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Analog Warmth, Spatial, Atmosphere Realizer') } } - else { + else { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Analog Warmth, Atmosphere Realizer') @@ -741,7 +730,7 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { // Vibrant Bass, CAP, Analog Warmth, Maikiwi Spatial app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -755,7 +744,7 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Analog Warmth, Spatial') } } - else { + else { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.analogWarmth[0]); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Analog Warmth') @@ -766,7 +755,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 3) - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -780,14 +769,14 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Spatial, Atmosphere Realizer') } } - else { + else { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Atmosphere Realizer') } } - else { - if (app.cfg.audio.spatial === true) { + else { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -801,7 +790,7 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP, Spatial') } } - else { + else { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, CAP') @@ -816,7 +805,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4) - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -830,15 +819,15 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, Analog Warmth, Spatial, Atmosphere Realizer') } } - else { + else { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, Analog Warmth, Atmosphere Realizer') } } - else { - if (app.cfg.audio.spatial === true) { + else { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -852,7 +841,7 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, Analog Warmth, Spatial') } } - else { + else { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.analogWarmth[0]); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, Analog Warmth') } @@ -862,8 +851,8 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 2) - if (app.cfg.audio.spatial === true) { - if (app.cfg.audio.maikiwiAudio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); @@ -881,11 +870,11 @@ const CiderAudio = { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Equalizer, Vibrant Bass, Atmosphere Realizer') } - } + } else { - if (app.cfg.audio.spatial === true) { - if (app.cfg.audio.maikiwiAudio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]); @@ -898,12 +887,12 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, Vibrant Bass, Spatial') } } - else { + else { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]); console.debug('[Cider][Audio] Equalizer, Vibrant Bass') } } - + } } } @@ -918,7 +907,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -939,13 +928,13 @@ const CiderAudio = { } } - else { - - if (app.cfg.audio.spatial === true) { + else { + + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.analogWarmth[0]); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.analogWarmth[0]); console.debug('[Cider][Audio] Equalizer, CAP, Analog Warmth, Maikiwi Spatial') } else { @@ -965,12 +954,12 @@ const CiderAudio = { else { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 3); - - if (app.cfg.audio.spatial === true) { + + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Equalizer, CAP, Maikiwi Spatial, Atmosphere Realizer') } else { @@ -986,9 +975,9 @@ const CiderAudio = { console.debug('[Cider][Audio] Equalizer, CAP, Atmosphere Realizer') } } - + else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1017,7 +1006,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1038,8 +1027,8 @@ const CiderAudio = { } } - else { - if (app.cfg.audio.spatial === true) { + else { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1063,7 +1052,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 1); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1084,8 +1073,8 @@ const CiderAudio = { } } - else { - if (app.cfg.audio.spatial === true) { + else { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1121,7 +1110,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { // Vibrant Bass, CAP, Analog Warmth, Maikiwi Spatial app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1140,10 +1129,10 @@ const CiderAudio = { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Vibrant Bass, CAP, Analog Warmth, Atmosphere Realizer') } - - } - else { - if (app.cfg.audio.spatial === true) { + + } + else { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { // Vibrant Bass, CAP, Analog Warmth, Maikiwi Spatial app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1168,11 +1157,11 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 3); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Vibrant Bass, CAP, Maikiwi Spatial, Atmosphere Realizer') } else { @@ -1190,11 +1179,11 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.llpw[0]); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.llpw[0]); console.debug('[Cider][Audio] Vibrant Bass, CAP, Maikiwi Spatial') } else { @@ -1209,7 +1198,7 @@ const CiderAudio = { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]); console.debug('[Cider][Audio] Vibrant Bass, CAP') } - } + } } } else { @@ -1219,7 +1208,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1241,7 +1230,7 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1261,13 +1250,13 @@ const CiderAudio = { console.debug('[Cider][Audio] Vibrant Bass, Analog Warmth') } } - + } else { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 2); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1289,7 +1278,7 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1322,11 +1311,11 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] CAP, Analog Warmth, Maikiwi Spatial, Atmosphere Realizer') } else { @@ -1344,11 +1333,11 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.analogWarmth[0]); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.analogWarmth[0]); console.debug('[Cider][Audio] CAP, Analog Warmth, Maikiwi Spatial') } else { @@ -1369,11 +1358,11 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 3); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] CAP, Maikiwi Spatial, Atmosphere Realizer') } else { @@ -1391,11 +1380,11 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.llpw[0]); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.llpw[0]); console.debug('[Cider][Audio] CAP, Maikiwi Spatial') } else { @@ -1420,7 +1409,7 @@ const CiderAudio = { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 4); - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); @@ -1442,11 +1431,11 @@ const CiderAudio = { } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.analogWarmth[0]); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.analogWarmth[0]); console.debug('[Cider][Audio] Analog Warmth, Maikiwi Spatial') } else { @@ -1461,17 +1450,17 @@ const CiderAudio = { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.analogWarmth[0]); console.debug('[Cider][Audio] Analog Warmth') } - } + } } else { if (app.cfg.audio.maikiwiAudio.atmosphereRealizer === true) { CiderAudio.atmosphereRealizer_h2_4(true, 0); - - if (app.cfg.audio.spatial === true) { + + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.audioNodes.atmosphereRealizer); console.debug('[Cider][Audio] Maikiwi Spatial, Atmosphere Realizer') } else { @@ -1488,11 +1477,11 @@ const CiderAudio = { } } else { - if (app.cfg.audio.spatial === true) { + if (app.cfg.audio.maikiwiAudio.spatial === true) { if (app.cfg.audio.maikiwiAudio.spatial === true) { app.cfg.audio.normalization = true; CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode); - CiderAudio.audioNodes.spatialNode.connect(CiderAudio.context.destination); + CiderAudio.audioNodes.spatialNode.connect(CiderAudio.context.destination); console.debug('[Cider][Audio] Maikiwi Spatial') } else { diff --git a/src/renderer/audio/impulses/AtmosphereRealizer_Cryptofyre.wav b/src/renderer/audio/impulses/AtmosphereRealizer_Cryptofyre.wav new file mode 100644 index 00000000..557f34a9 Binary files /dev/null and b/src/renderer/audio/impulses/AtmosphereRealizer_Cryptofyre.wav differ diff --git a/src/renderer/less/bootstrap.less b/src/renderer/less/bootstrap.less index 3c4ad54e..b1384a8a 100644 --- a/src/renderer/less/bootstrap.less +++ b/src/renderer/less/bootstrap.less @@ -1046,7 +1046,7 @@ background-color: var(--modalBackground); background-clip : padding-box; border : 1px solid rgba(0, 0, 0, 0.2); - border-radius : 0.3rem; + border-radius : var(--panelRadius); outline : 0; box-shadow : var(--ciderShadow-Generic); overflow : hidden; diff --git a/src/renderer/less/directives.less b/src/renderer/less/directives.less index 22f839ea..5c9253da 100644 --- a/src/renderer/less/directives.less +++ b/src/renderer/less/directives.less @@ -16,6 +16,7 @@ height: var(--chromeHeight1); &.chrome-bottom { + -webkit-app-region: no-drag; height : var(--chromeHeight2); box-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25); z-index : 1; @@ -30,6 +31,7 @@ .app-playback-controls .actions { align-self: center; } + -webkit-app-region: no-drag; .playback-button.play, .playback-button.pause { @@ -120,8 +122,9 @@ width : 30%; justify-content: flex-start; align-items : flex-start; - + -webkit-app-region: no-drag!important; .playback-controls { + -webkit-app-region: no-drag!important; .artwork { width : var(--chromeHeight2); height : var(--chromeHeight2); diff --git a/src/renderer/less/elements.less b/src/renderer/less/elements.less index 2ce34e73..716b71a4 100644 --- a/src/renderer/less/elements.less +++ b/src/renderer/less/elements.less @@ -891,6 +891,10 @@ margin: 6px; cursor: pointer; + .mediaitem-artwork { + box-shadow: unset; + } + &.round { border-radius: var(--mediaItemRadiusRound); } @@ -1912,6 +1916,7 @@ input[type=checkbox][switch]:checked:active::before { // background: #eee; background : transparent; color : #333; + font-weight: 600; &:after { opacity: 1; diff --git a/src/renderer/less/helpers.less b/src/renderer/less/helpers.less index acc2e2c6..db659232 100644 --- a/src/renderer/less/helpers.less +++ b/src/renderer/less/helpers.less @@ -1,6 +1,6 @@ .notyf__toast { -webkit-app-region: no-drag; - cursor: pointer; + cursor : pointer; } .notyf-info { @@ -9,142 +9,141 @@ .tooltip-inner { background: #2f2f2f; - opacity: 1; - border: 1px solid rgb(0 0 0 / 35%); + opacity : 1; + border : 1px solid rgb(0 0 0 / 35%); transition: all 0.3s ease-in-out; box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25); } .modal-fullscreen { - display: flex; + display : flex; justify-content: center; - align-items: center; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.3); - z-index: 1000; + align-items : center; + position : fixed; + top : 0; + left : 0; + width : 100%; + height : 100%; + background : rgba(0, 0, 0, 0.3); + z-index : 1000; .modal-window { - background: #333; + background : #333; border-radius: 10px; - box-shadow: var(--mediaItemShadow-Shadow); - display: flex; - flex-flow: column; - max-height: 500px; - max-width: 360px; - background: #121212; - width: 100%; - position: relative; + box-shadow : var(--mediaItemShadow-Shadow); + display : flex; + flex-flow : column; + max-height : 500px; + max-width : 360px; + background : #121212; + width : 100%; + position : relative; &:after { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; + content : ""; + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; pointer-events: none; - box-shadow: var(--mediaItemShadow); - z-index: 1; - border-radius: inherit; + box-shadow : var(--mediaItemShadow); + z-index : 1; + border-radius : inherit; } .modal-header { - width: 100%; + width : 100%; padding: 6px; } .modal-content { - width: 100%; - height: 100%; - overflow: hidden; + width : 100%; + height : 100%; + overflow : hidden; overflow-y: overlay; } - .modal-footer { - } + .modal-footer {} } } .spatialproperties-panel { .modal-window { - height: 700px; + height : 700px; max-height: 700px; - width: 800px; - max-width: 800px; - overflow: hidden; + width : 800px; + max-width : 800px; + overflow : hidden; .info-header { padding-left: 12px; } .visual-container { - display: flex; + display : flex; justify-content: center; - align-items: center; - overflow: hidden; + align-items : center; + overflow : hidden; } .visual { - position: relative; - height: 250px; - width: 300px; - display: inline-flex; - align-items: flex-end; + position : relative; + height : 250px; + width : 300px; + display : inline-flex; + align-items : flex-end; justify-content: center; - filter: drop-shadow(2px 12px 6px rgb(0 0 0 / 25%)); - margin: 0 auto; + filter : drop-shadow(2px 12px 6px rgb(0 0 0 / 25%)); + margin : 0 auto; .face { - position: absolute; - width: calc(12px * 6); - height: calc(12px * 6); + position : absolute; + width : calc(12px * 6); + height : calc(12px * 6); border-radius: 6px; - transform: rotateX(60deg) rotateZ(-45deg); - transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; + transform : rotateX(60deg) rotateZ(-45deg); + transition : transform 0.2s linear, width 0.2s linear, height 0.2s linear; } .listener { - position: absolute; - width: 32px; - height: 32px; + position : absolute; + width : 32px; + height : 32px; border-radius: 6px; - transform: rotateX(60deg) rotateZ(-45deg); - transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; - background: white; - color: black; - z-index: 2; + transform : rotateX(60deg) rotateZ(-45deg); + transition : transform 0.2s linear, width 0.2s linear, height 0.2s linear; + background : white; + color : black; + z-index : 2; } .audiosource { - position: absolute; - width: 32px; - height: 32px; + position : absolute; + width : 32px; + height : 32px; border-radius: 6px; - transform: rotateX(60deg) rotateZ(-45deg); - transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear; - background: yellow; - z-index: 2; + transform : rotateX(60deg) rotateZ(-45deg); + transition : transform 0.2s linear, width 0.2s linear, height 0.2s linear; + background : yellow; + z-index : 2; } .face:nth-of-type(1) { background: linear-gradient(45deg, #28223a, #1f2038); - z-index: 1; + z-index : 1; } .face:nth-of-type(2) { background: linear-gradient(45deg, #7d53ad, #5763ff); - transform: rotateX(60deg) rotateZ(-45deg) translateZ(30px); - opacity: 0.7; - z-index: 3; + transform : rotateX(60deg) rotateZ(-45deg) translateZ(30px); + opacity : 0.7; + z-index : 3; } } .modal-header { - padding: 16px; + padding : 16px; position: relative; overflow: hidden; @@ -153,18 +152,18 @@ } .close-btn { - width: 50px; - height: 100%; - background-image: var(--gfx-closeBtn); + width : 50px; + height : 100%; + background-image : var(--gfx-closeBtn); background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; + background-repeat : no-repeat; + -webkit-app-region : no-drag; + appearance : none; + border : 0; + background-color : transparent; + position : absolute; + top : 0; + right : 0; &:hover { background-color: rgb(196, 43, 28) @@ -176,14 +175,14 @@ .addtoplaylist-panel { .modal-window { - max-height: 600px; - max-width: 400px; - background: rgb(18 18 18 / 90%); - overflow: hidden; + max-height : 600px; + max-width : 400px; + background : rgb(18 18 18 / 90%); + overflow : hidden; backdrop-filter: blur(16px) saturate(180%); .modal-header { - padding: 16px; + padding : 16px; position: relative; .modal-title { @@ -191,18 +190,18 @@ } .close-btn { - width: 50px; - height: 100%; - background-image: var(--gfx-closeBtn); + width : 50px; + height : 100%; + background-image : var(--gfx-closeBtn); background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; + background-repeat : no-repeat; + -webkit-app-region : no-drag; + appearance : none; + border : 0; + background-color : transparent; + position : absolute; + top : 0; + right : 0; &:hover { background-color: rgb(196, 43, 28) @@ -211,34 +210,34 @@ } .modal-search { - width: 100%; - padding: 0px 16px; + width : 100%; + padding : 0px 16px; position: relative; } .playlist-item { - appearance: none; - border: 0px; - text-align: left; - width: 100%; - margin: 0; - display: flex; - background: rgba(32, 32, 32, 0.46); - color: #eee; + appearance : none; + border : 0px; + text-align : left; + width : 100%; + margin : 0; + display : flex; + background : rgba(32, 32, 32, 0.46); + color : #eee; font-family: inherit; - font-size: 0.98em; - padding: 6px 12px; + font-size : 0.98em; + padding : 6px 12px; align-items: center; - flex-flow: row; + flex-flow : row; .icon { - pointer-events: none; - width: 32px; - height: 32px; - display: flex; + pointer-events : none; + width : 32px; + height : 32px; + display : flex; justify-content: center; - align-items: center; - margin-right: 6px; + align-items : center; + margin-right : 6px; } .name { @@ -265,35 +264,35 @@ } .menu-panel { - width: 100%; - height: 100%; - position: fixed; - top: 0; - left: 0; - z-index: 100001; - display: flex; - justify-content: center; - align-items: center; + width : 100%; + height : 100%; + position : fixed; + top : 0; + left : 0; + z-index : 100001; + display : flex; + justify-content : center; + align-items : center; -webkit-app-region: no-drag; .menu-header-body { - padding: 6px; - display: flex; + padding : 6px; + display : flex; background: rgb(200 200 200 / 10%); .menu-option-header { - width: 40px; - height: 40px; - display: flex; + width : 40px; + height : 40px; + display : flex; justify-content: center; - align-items: center; - border-radius: var(--mediaItemRadius); - appearance: none; - border: 0; - background: transparent; + align-items : center; + border-radius : var(--mediaItemRadius); + appearance : none; + border : 0; + background : transparent; &.active { - .sidebar-icon > .svg-icon { + .sidebar-icon>.svg-icon { --color: var(--keyColor); } } @@ -309,33 +308,63 @@ } .menu-panel-body { - display: flex; - flex-flow: column; - background: #262626; - position: relative; - min-width: 200px; - box-shadow: var(--ciderShadow-Generic); - border-radius: var(--mediaItemRadius); - overflow: hidden; - font-size: 13px; + display : flex; + flex-flow : column; + background : rgb(30 30 30 / 45%); + backdrop-filter: blur(32px) saturate(180%); + position : relative; + min-width : 200px; + box-shadow : var(--ciderShadow-Generic); + border-radius : var(--panelRadius); + overflow : hidden; + font-size : 13px; + .menu-option { text-align: left; - display: flex; - width: 100%; - padding: 9px 16px; + display : flex; appearance: none; - border: 0px; - font: inherit; + border : 0px; + font : inherit; background: transparent; - color: inherit; + color : inherit; + margin : 0 auto; + position : relative; + width : 100%; + padding : 9px 14px; + + &::before { + background : var(--hover); + border-radius: 6px; + content : ""; + --sizeY : 3px; + --sizeX : 4px; + top : var(--sizeY); + left : var(--sizeX); + bottom : var(--sizeY); + right : var(--sizeX); + position : absolute; + opacity : 0; + transform : scale(0.98); + z-index : -1; + transition : transform .25s ease-out, opacity .25s ease-out; + } &:hover { - background: var(--selected); + &::before { + transition: transform .1s ease-in, opacity .1s ease-in; + opacity : 1; + transform : scale(1); + } } &:active { - background: var(--selected-click); + &::before { + transition: transform .1s ease-in-out, opacity .1s ease-in-out; + opacity : 1; + transform : scale(0.98); + background: var(--selected-click); + } } } } @@ -345,18 +374,18 @@ margin: 18px 6px; .close-btn { - width: 50px; - height: 42px; - background-image: var(--gfx-closeBtn); + width : 50px; + height : 42px; + background-image : var(--gfx-closeBtn); background-position: center; - background-repeat: no-repeat; - -webkit-app-region: no-drag; - appearance: none; - border: 0; - background-color: transparent; - position: absolute; - top: 0; - right: 0; + background-repeat : no-repeat; + -webkit-app-region : no-drag; + appearance : none; + border : 0; + background-color : transparent; + position : absolute; + top : 0; + right : 0; &:hover { background-color: rgb(196, 43, 28) @@ -365,20 +394,25 @@ } .menu-body { - overflow: overlay; - height: 100%; + overflow : overlay; + height : 100%; + display : flex; + flex-flow: column; + gap : 0px; + padding : 0px; + position : relative; } .menu-footer { - width: 100%; + width : 100%; padding: 12px; } } .queue-panel { - height: 100%; - width: 100%; - display: flex; + height : 100%; + width : 100%; + display : flex; flex-flow: column; .queue-header-text { @@ -387,59 +421,66 @@ .queue-body { overflow: overlay; - height: 100%; + height : 100%; } .queue-footer { - width: 100%; + width : 100%; padding: 12px; } .autoplay { - background: rgb(200 200 200 / 15%); - display: flex; + background : rgb(200 200 200 / 15%); + display : flex; justify-content: center; - appearance: none; - border: 0; - border-radius: 6px; - height: 32px; - width: 32px; + appearance : none; + border : 0; + border-radius : 6px; + height : 32px; + width : 32px; } .infinity { content: url("./assets/infinity.svg"); - margin: auto; + margin : auto; } } .moreinfo-modal { - .modal-window{ - height: 70%; - max-height: 100%; - width: 45%; - max-width: 100%; - overflow: hidden; + .modal-window { + height : 70%; + max-height : 100%; + width : 45%; + max-width : 100%; + overflow : hidden; line-height: 1.25; } - .modal-content{ - padding: 1em; + + .modal-content { + padding : 1em; font-size: 0.8rem; + br { - display: block; /* makes it have a width */ - content: ""; /* clears default height */ - margin: 2em; + display : block; + /* makes it have a width */ + content : ""; + /* clears default height */ + margin : 2em; margin-bottom: -0.6rem; - } + } } - .modal-header{ + + .modal-header { flex-direction: column; - .modal-title{ + + .modal-title { text-align: unset !important; - width: 100%; - &:not(.modal-subtitle){ + width : 100%; + + &:not(.modal-subtitle) { font-size: 25px; } } } -} +} \ No newline at end of file diff --git a/src/renderer/less/pages.less b/src/renderer/less/pages.less index 66c68f19..2e03391e 100644 --- a/src/renderer/less/pages.less +++ b/src/renderer/less/pages.less @@ -498,6 +498,18 @@ height: 100%; overflow: hidden; + .editTracksBtn { + position: absolute; + top: 20px; + right: 20px; + z-index: 1; + + >span { + display: flex; + gap: 8px; + } + } + .mediaContainer { transition: width 0.5s ease-in-out, height 0.5s ease-in-out; width: 260px;height:260px; @@ -909,7 +921,7 @@ .header-content { z-index : 1; - margin-top: -16px; + // margin-top: -16px; } @@ -1052,7 +1064,7 @@ .artist-body { padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding); - margin : -140px 20px; + margin : -64px 20px; .arow { display : flex; diff --git a/src/renderer/main/app.js b/src/renderer/main/app.js index a1b66680..476dfa47 100644 --- a/src/renderer/main/app.js +++ b/src/renderer/main/app.js @@ -2,7 +2,7 @@ import { app } from "./vueapp.js" import {CiderCache} from './cidercache.js' import {CiderFrontAPI} from './ciderfrontapi.js' import {simulateGamepad} from './gamepad.js' -import {CiderAudio} from '../audio/audio.js' +import {CiderAudio} from '../audio/cideraudio.js' import {Events} from './events.js' import { wsapi } from "./wsapi_interop.js" import { MusicKitTools } from "./musickittools.js" diff --git a/src/renderer/main/events.js b/src/renderer/main/events.js index 00726985..0b2e13d3 100644 --- a/src/renderer/main/events.js +++ b/src/renderer/main/events.js @@ -18,12 +18,6 @@ const Events = { }); document.addEventListener('keydown', async function (event) { - // CTRL + F - if (event.keyCode === 70 && event.ctrlKey) { - app.appRoute('search') - app.$refs.searchInput.focus() - app.$refs.searchInput.select() - } // CTRL + R if (event.keyCode === 82 && event.ctrlKey) { event.preventDefault() @@ -38,22 +32,6 @@ const Events = { event.preventDefault() window.location.reload() } - // CTRL + S - if (event.keyCode === 83 && event.ctrlKey) { - app.appRoute("settings") - } - // CTRL + A - if (event.keyCode === 65 && event.ctrlKey) { - app.appRoute("library-albums") - } - // CTRL + B - if (event.keyCode === 66 && event.ctrlKey) { - app.appRoute("browse") - } - // CTRL + D - if (event.keyCode === 68 && event.ctrlKey) { - app.appRoute("library-artists") - } // CTRL + E if (event.keyCode === 69 && event.ctrlKey) { app.invokeDrawer('queue') diff --git a/src/renderer/main/vueapp.js b/src/renderer/main/vueapp.js index 78937242..58b49752 100644 --- a/src/renderer/main/vueapp.js +++ b/src/renderer/main/vueapp.js @@ -234,7 +234,7 @@ const app = new Vue({ watch: { cfg: { handler: function (val, oldVal) { - console.log(`cfg changed from ${oldVal} to ${val}`); + console.debug(`cfg changed from ${oldVal} to ${val}`); ipcRenderer.send("setStore", val); }, deep: true @@ -254,6 +254,12 @@ const app = new Vue({ app.resetState() } }, + mounted() { + window.addEventListener("hashchange", function (event) { + let currentPath = window.location.hash.slice(1); + console.debug("hashchange", currentPath); + }, false) + }, methods: { setTimeout(func, time) { return setTimeout(func, time); @@ -268,10 +274,10 @@ const app = new Vue({ if (httpRequest.readyState === 4) { if (httpRequest.status === 200) { let response = JSON.parse(httpRequest.responseText); - console.log(response); + console.debug(response); self.copyToClipboard(response.pageUrl) } else { - console.log('There was a problem with the request.'); + console.warn('There was a problem with the request.'); notyf.error(app.getLz('term.requestError')) } } @@ -480,6 +486,13 @@ const app = new Vue({ app.modals[key] = false; } }, + resumeTabs() { + if (app.cfg.general.resumeTabs.tab == "dynamic") { + this.appRoute(app.cfg.general.resumeTabs.dynamicData) + } else { + this.appRoute(app.cfg.general.resumeTabs.tab) + } + }, promptAddToPlaylist() { app.modals.addToPlaylist = true; }, @@ -894,10 +907,9 @@ const app = new Vue({ document.body.removeAttribute("loading") if (window.location.hash != "") { this.appRoute(window.location.hash) - } else { - this.page = "home" } + this.resumeTabs() this.mediaKeyFixes() setTimeout(() => { @@ -907,7 +919,7 @@ const app = new Vue({ }, 500) ipcRenderer.invoke("renderer-ready", true) document.querySelector("#LOADER").remove() - if (this.cfg.general.themeUpdateNotification) { + if (this.cfg.general.themeUpdateNotification && !this.isDev) { this.checkForThemeUpdates() } }, @@ -934,7 +946,7 @@ const app = new Vue({ }) }, async setTheme(theme = "", onlyPrefs = false) { - console.log(theme) + console.debug(theme) if (this.cfg.visual.theme == "") { this.cfg.visual.theme = "default.less" } @@ -966,7 +978,7 @@ const app = new Vue({ async reloadStyles() { const styles = this.cfg.visual.styles document.querySelectorAll(`[id*='less']`).forEach(el => { - if(el.id != "less:style") { + if (el.id != "less:style") { el.remove() } }); @@ -1115,15 +1127,15 @@ const app = new Vue({ const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks") if (cachedPlaylist) { - console.log("using cached playlists") + console.debug("using cached playlists") this.playlists.listing = cachedPlaylist self.sortPlaylists() } else { - console.log("playlist has no cache") + console.debug("playlist has no cache") } if (cachedTrackMapping) { - console.log("using cached track mapping") + console.debug("using cached track mapping") this.playlists.trackMapping = cachedTrackMapping } if (localOnly) { @@ -1134,7 +1146,7 @@ const app = new Vue({ this.library.backgroundNotification.show = true async function deepScan(parent = "p.playlistsroot") { - console.log(`scanning ${parent}`) + console.debug(`scanning ${parent}`) const playlistData = await app.mk.api.v3.music(`/v1/me/library/playlist-folders/${parent}/children/`) await asyncForEach(playlistData.data.data, async (playlist) => { playlist.parent = parent @@ -1249,12 +1261,12 @@ const app = new Vue({ }) }, copyToClipboard(str) { - if (navigator.userAgent.includes('Darwin') || navigator.appVersion.indexOf("Mac") != -1) { - this.darwinShare(str) - } else { - notyf.success(app.getLz('term.share.success')) - navigator.clipboard.writeText(str).then(r => console.log("Copied to clipboard.")) - } + // if (navigator.userAgent.includes('Darwin') || navigator.appVersion.indexOf("Mac") != -1) { + // this.darwinShare(str) + // } else { + notyf.success(app.getLz('term.share.success')) + navigator.clipboard.writeText(str).then(r => console.debug("Copied to clipboard.")) + // } }, newPlaylist(name = app.getLz('term.newPlaylist'), tracks = []) { let self = this @@ -1276,7 +1288,7 @@ const app = new Vue({ } }).then(res => { res = res.data.data[0] - console.log(res) + console.debug(res) self.appRoute(`playlist_` + res.id); self.showingPlaylist = []; self.getPlaylistFromID(app.page.substring(9), true) @@ -1311,7 +1323,7 @@ const app = new Vue({ }, async showCollection(response, title, type, requestBody = {}) { let self = this - console.log(response) + console.debug(response) this.collectionList.requestBody = {} this.collectionList.response = response this.collectionList.title = title @@ -1321,7 +1333,7 @@ const app = new Vue({ }, async showArtistView(artist, title, view) { let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}?l=${this.mklang}`, {}, { includeResponseMeta: !0 })).data - console.log(response) + console.debug(response) await this.showCollection(response, title, "artists") }, async showRecordLabelView(label, title, view) { @@ -1361,7 +1373,7 @@ const app = new Vue({ includeResponseMeta: !0 }) - console.log('searchres', response) + console.debug('searchres', response) let responseFormat = { data: response.data.results[group].data, next: response.data.results[group].next, @@ -1415,13 +1427,13 @@ const app = new Vue({ app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, params).then(res => { self.getPlaylistContinuous(res, transient) }).catch((e) => { - console.log(e); + console.debug(e); try { app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`, params).then(res => { self.getPlaylistContinuous(res, transient) }) } catch (err) { - console.log(err) + console.debug(err) } }) @@ -1438,7 +1450,7 @@ const app = new Vue({ "art[url]": "f", l: this.mklang }, { includeResponseMeta: !0 }) - console.log(artistData.data.data[0]) + console.debug(artistData.data.data[0]) this.artistPage.data = artistData.data.data[0] this.page = "artist-page" }, @@ -1473,12 +1485,12 @@ const app = new Vue({ "meta": {} } if (response.next) { - console.log("has next") + console.debug("has next") returnData.data.concat(response.data) returnData.meta = response.meta return await this.getRecursive(await response.next()) } else { - console.log("no next") + console.debug("no next") returnData.data.concat(response.data) return returnData } @@ -1566,6 +1578,13 @@ const app = new Vue({ return; } route = route.replace(/#/g, "") + if (app.cfg.general.resumeTabs.tab == "dynamic") { + if (route == "home" || route == "listen_now" || route == "browse" || route == "radio" || route == "library-songs" || route == "library-albums" || route == "library-artists" || route == "library-videos" || route == "podcasts") { + app.cfg.general.resumeTabs.dynamicData = route + } else { + app.cfg.general.resumeTabs.dynamicData = "home" + } + } // if the route contains does not include a / then route to the page directly if (route.indexOf("/") == -1) { this.page = route @@ -1611,7 +1630,7 @@ const app = new Vue({ window.location.hash = `${kind}/${id}` document.querySelector("#app-content").scrollTop = 0 } else if (kind == "editorial-elements") { - console.log(item) + console.debug(item) if (item.relationships?.contents?.data != null && item.relationships?.contents?.data.length > 0) { this.routeView(item.relationships.contents.data[0]) } else if (item.attributes?.link?.url != null) { @@ -1652,28 +1671,16 @@ const app = new Vue({ params["meta[albums:tracks]"] = 'popularity' params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright" } - - // if (this.cfg.advanced.experiments.includes('inline-playlists')) { - if(false) { - let showModal = kind.toString().includes("album") || kind.toString().includes("playlist") - if (app.page.includes("playlist") || app.page.includes("album")) { - showModal = false - } - if (showModal) { - app.modals.showPlaylist = true - app.chrome.contentAreaScrolling = false - } else { - app.page = (kind) + "_" + (id); - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - } - } else { + if(kind.includes("playlist") || kind.includes("album")){ app.page = (kind) + "_" + (id); window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` + app.getTypeFromID((kind), (id), (isLibrary), params); + }else{ + app.page = (kind) + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` } - - app.getTypeFromID((kind), (id), (isLibrary), params); - // document.querySelector("#app-content").scrollTop = 0 + // app.getTypeFromID((kind), (id), (isLibrary), params); } else { app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') } @@ -1739,12 +1746,12 @@ const app = new Vue({ try { if (artistQuery.artists.data.length > 0) { artistId = artistQuery.artists.data[0].id; - console.log(artistId) + console.debug(artistId) } } catch (e) { } } - console.log(artistId); + console.debug(artistId); if (artistId != "") self.appRoute(`artist/${artistId}`) break; @@ -1776,7 +1783,7 @@ const app = new Vue({ })).data.results; if (albumQuery.albums.data.length > 0) { albumId = albumQuery.albums.data[0].id; - console.log(albumId) + console.debug(albumId) } } catch (e) { } @@ -1800,7 +1807,7 @@ const app = new Vue({ })).data.results; if (labelQuery["record-labels"].data.length > 0) { labelId = labelQuery["record-labels"].data[0].id; - console.log(labelId) + console.debug(labelId) } } catch (e) { } @@ -1833,7 +1840,7 @@ const app = new Vue({ } }, followingArtist(id) { - console.log(`check for ${id}`) + console.debug(`check for ${id}`) return this.cfg.home.followedArtists.includes(id) }, playMediaItem(item) { @@ -1863,7 +1870,7 @@ const app = new Vue({ try { a = await this.mkapi(kind.toString(), isLibrary, id.toString(), params, params2); } catch (e) { - console.log(e); + console.debug(e); try { a = await this.mkapi(kind.toString(), !isLibrary, id.toString(), params, params2); } catch (err) { @@ -2118,7 +2125,7 @@ const app = new Vue({ return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2) } } catch (e) { - console.log(e) + console.debug(e) return await this.mkapi(method, library, term, params, params2, attempts + 1) } }, @@ -2170,7 +2177,7 @@ const app = new Vue({ l: app.mklang, }, onProgress: (data) => { - console.log(`${data.total}/${data.response.data.meta.total}`) + console.debug(`${data.total}/${data.response.data.meta.total}`) self.library.backgroundNotification.show = true self.library.backgroundNotification.message = app.getLz('notification.updatingLibrarySongs') self.library.backgroundNotification.total = data.response.data.meta.total @@ -2186,7 +2193,7 @@ const app = new Vue({ self.library.backgroundNotification.show = false self.searchLibrarySongs() CiderCache.putCache(cacheId, library) - console.log("Done!") + console.debug("Done!") return }, @@ -2237,7 +2244,7 @@ const app = new Vue({ app.mk.api.v3.music(`/v1/me/library/albums/`, params).then((response) => { processChunk(response.data) }).catch((error) => { - console.log('safe loading'); + console.debug('safe loading'); app.mk.api.v3.music(`/v1/me/library/albums/`, safeparams).then((response) => { processChunk(response.data) }).catch((error) => { @@ -2251,7 +2258,7 @@ const app = new Vue({ app.mk.api.v3.music(downloaded.next, params).then((response) => { processChunk(response.data) }).catch((error) => { - console.log('safe loading'); + console.debug('safe loading'); app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { processChunk(response.data) }).catch((error) => { @@ -2261,7 +2268,7 @@ const app = new Vue({ }) }) } else { - console.log("Download next", downloaded.next) + console.debug("Download next", downloaded.next) } } } @@ -2278,7 +2285,7 @@ const app = new Vue({ return } if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") + console.debug("downloaded.next is undefined") self.library.albums.listing = library self.library.albums.downloadState = 2 self.library.backgroundNotification.show = false @@ -2286,7 +2293,7 @@ const app = new Vue({ self.searchLibraryAlbums(index) } if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length + console.debug(`downloading next chunk - ${library.length } albums so far`) downloadChunk() } else { @@ -2344,7 +2351,7 @@ const app = new Vue({ app.mk.api.v3.music(`/v1/me/library/artists/`, params).then((response) => { processChunk(response.data) }).catch((error) => { - console.log('safe loading'); + console.debug('safe loading'); app.mk.api.v3.music(`/v1/me/library/artists/`, safeparams).then((response) => { processChunk(response.data) }).catch((error) => { @@ -2472,7 +2479,7 @@ const app = new Vue({ reload: !0 })).data; this.listennow.timestamp = Date.now() - console.log(this.listennow) + console.debug(this.listennow) } catch (e) { console.log(e) this.getListenNow(attempt + 1) @@ -2500,7 +2507,7 @@ const app = new Vue({ }); this.browsepage = browse.data.data[0]; this.browsepage.timestamp = Date.now() - console.log(this.browsepage) + console.debug(this.browsepage) } catch (e) { console.log(e) this.getBrowsePage(attempt + 1) @@ -2686,7 +2693,7 @@ const app = new Vue({ function getToken(mode, track, artist, songid, lang, time, id) { if (attempt > 2) { app.loadNeteaseLyrics(); - // app.loadAMLyrics(); + // app.loadAMLyrics(); } else { attempt = attempt + 1; let url = "https://apic-desktop.musixmatch.com/ws/1.1/token.get?app_id=web-desktop-app-v1.0&t=" + revisedRandId(); @@ -2701,7 +2708,7 @@ const app = new Vue({ if (status2 == 200) { let token = jsonResponse["message"]["body"]["user_token"] ?? ''; if (token != "" && token != "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") { - console.log('200 token', mode); + console.debug('200 token', mode); // token good app.mxmtoken = token; @@ -2711,7 +2718,7 @@ const app = new Vue({ getMXMTrans(songid, lang, app.mxmtoken); } } else { - console.log('fake 200 token'); + console.debug('fake 200 token'); getToken(mode, track, artist, songid, lang, time) } } else { @@ -2727,7 +2734,7 @@ const app = new Vue({ req.onerror = function () { console.log('error'); app.loadQQLyrics(); - // app.loadAMLyrics(); + // app.loadAMLyrics(); }; req.send(); } @@ -2746,7 +2753,7 @@ const app = new Vue({ req.onload = function () { try { let jsonResponse = JSON.parse(this.responseText); - console.log(jsonResponse); + console.debug(jsonResponse); let status1 = jsonResponse["message"]["header"]["status_code"]; if (status1 == 200) { @@ -2766,7 +2773,7 @@ const app = new Vue({ if (lrcfile == "") { app.loadQQLyrics(); - // app.loadAMLyrics() + // app.loadAMLyrics() } else { if (richsync == [] || richsync.length == 0) { console.log("ok"); @@ -2810,18 +2817,18 @@ const app = new Vue({ }); app.lyrics = preLrc; } - if (lrcfile != null && lrcfile != '' && lang != "disabled") { + if (lrcfile != null && lrcfile != '') { // load translation getMXMTrans(id, lang, token); } else { - // app.loadAMLyrics() - app.loadQQLyrics(); + // app.loadAMLyrics() + app.loadQQLyrics(); } } } catch (e) { console.log(e); app.loadQQLyrics(); - // app.loadAMLyrics() + // app.loadAMLyrics() } } else { //4xx rejected getToken(1, track, artist, '', lang, time); @@ -2895,7 +2902,7 @@ const app = new Vue({ const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : ''); const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : ''); const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1); - var url = `http://music.163.com/api/search/get/?csrf_token=hlpretag=&hlposttag=&s=${track+" "+artist}&type=1&offset=0&total=true&limit=6`; + var url = `http://music.163.com/api/search/get/?csrf_token=hlpretag=&hlposttag=&s=${track + " " + artist}&type=1&offset=0&total=true&limit=6`; var req = new XMLHttpRequest(); req.overrideMimeType("application/json"); req.open('GET', url, true); @@ -2916,14 +2923,15 @@ const app = new Vue({ let preLrc = [] for (var i = u.length - 1; i >= 0; i--) { let xline = (/(\[[0-9.:\[\]]*\])+(.*)/).exec(u[i]) - if (xline != null) { - let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) ?? 99999) : 99999 - preLrc.push({ - startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, - endTime: end, - line: xline[2], - translation: '' - })} + if (xline != null) { + let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) ?? 99999) : 99999 + preLrc.push({ + startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, + endTime: end, + line: xline[2], + translation: '' + }) + } } if (preLrc.length > 0) preLrc.push({ @@ -2938,8 +2946,8 @@ const app = new Vue({ app.lyrics = ""; } }; - req2.onerror = function(){ - + req2.onerror = function () { + } req2.send(); } catch (e) { @@ -2947,16 +2955,17 @@ const app = new Vue({ } }; req.send(); - req.onerror = function(){ + req.onerror = function () { } }, loadQQLyrics() { + if (!app.cfg.lyrics.enable_qq) return; const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : ''); const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : ''); const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1); - var url = `https://c.y.qq.com/soso/fcgi-bin/client_search_cp?w=${track+" "+artist}&t=0&n=1&page=1&cr=1&new_json=1&format=json&platform=yqq.json`; - + var url = `https://c.y.qq.com/soso/fcgi-bin/client_search_cp?w=${track + " " + artist}&t=0&n=1&page=1&cr=1&new_json=1&format=json&platform=yqq.json`; + var req = new XMLHttpRequest(); req.overrideMimeType("application/json"); req.open('GET', url, true); @@ -2972,14 +2981,14 @@ const app = new Vue({ req2.open('GET', url2, true); req2.onload = function () { try { - function b64_to_utf8( str ) { - return decodeURIComponent(escape(window.atob( str ))); + function b64_to_utf8(str) { + return decodeURIComponent(escape(window.atob(str))); } const htmlDecode = (input) => { const doc = new DOMParser().parseFromString(input, "text/html"); return doc.documentElement.textContent; } - var jsonResponse2 = JSON.parse(req2.responseText.replace("MusicJsonCallback(","").replace("})","}")); + var jsonResponse2 = JSON.parse(req2.responseText.replace("MusicJsonCallback(", "").replace("})", "}")); var lrcfile = htmlDecode(b64_to_utf8(jsonResponse2["lyric"])); app.lyricsMediaItem = lrcfile let u = app.lyricsMediaItem.split(/[\n]/); @@ -2987,14 +2996,15 @@ const app = new Vue({ let preLrc = [] for (var i = u.length - 1; i >= 0; i--) { let xline = (/(\[[0-9.:\[\]]*\])+(.*)/).exec(u[i]) - if (xline != null) { - let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) ?? 99999) : 99999 - preLrc.push({ - startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, - endTime: end, - line: xline[2], - translation: '' - })} + if (xline != null) { + let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) ?? 99999) : 99999 + preLrc.push({ + startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ?? 0, + endTime: end, + line: xline[2], + translation: '' + }) + } } if (preLrc.length > 0) preLrc.push({ @@ -3011,7 +3021,7 @@ const app = new Vue({ app.lyrics = ""; } }; - req2.onerror = function(){ + req2.onerror = function () { app.loadNeteaseLyrics(); } req2.send(); @@ -3021,7 +3031,7 @@ const app = new Vue({ app.lyrics = ""; } } - req.onerror = function(){ + req.onerror = function () { app.loadNeteaseLyrics(); } req.send(); @@ -3129,7 +3139,7 @@ const app = new Vue({ }, playMediaItemById(id, kind, isLibrary, raurl = "") { let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(id, truekind, isLibrary) + console.debug(id, truekind, isLibrary) try { if (truekind.includes("artist")) { app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { @@ -3754,7 +3764,7 @@ const app = new Vue({ volumeUp() { if ((app.mk.volume + app.cfg.audio.volumeStep) > app.cfg.audio.maxVolume) { app.mk.volume = app.cfg.audio.maxVolume; - console.log('setting max volume') + console.debug('setting max volume') } else { console.log('volume up') app.mk.volume = ((app.mk.volume * 100) + (app.cfg.audio.volumeStep * 100)) / 100 @@ -3763,7 +3773,7 @@ const app = new Vue({ volumeDown() { if ((app.mk.volume - app.cfg.audio.volumeStep) < 0) { app.mk.volume = 0; - console.log('setting volume to 0') + console.debug('setting volume to 0') } else { console.log('volume down') app.mk.volume = ((app.mk.volume * 100) - (app.cfg.audio.volumeStep * 100)) / 100 @@ -4258,7 +4268,7 @@ const app = new Vue({ document.getElementById('settings.option.general.updateCider.check').innerHTML = app.getLz('term.check') }) }, - authCC(){ + authCC() { ipcRenderer.send('cc-auth') } } diff --git a/src/renderer/main/wsapi_interop.js b/src/renderer/main/wsapi_interop.js index 563b2e30..d9477a23 100644 --- a/src/renderer/main/wsapi_interop.js +++ b/src/renderer/main/wsapi_interop.js @@ -1,6 +1,14 @@ const wsapi = { cache: {playParams: {id: 0}, status: null, remainingTime: 0}, playbackCache: {status: null, time: Date.now()}, + async v3(encoded = "") { + let decoded = atob(encoded); + let json = JSON.parse(decoded); + console.log(json) + let response = await (await MusicKit.getInstance().api.v3.music(json.route, json.body, json.options)) + let ret = response.data + return JSON.stringify(ret) + }, search(term, limit) { MusicKit.getInstance().api.search(term, {limit: limit, types: 'songs,artists,albums,playlists'}).then((results)=>{ ipcRenderer.send('wsapi-returnSearch', JSON.stringify(results)) diff --git a/src/renderer/style.less b/src/renderer/style.less index e5d7d66f..13e7de3b 100644 --- a/src/renderer/style.less +++ b/src/renderer/style.less @@ -21,6 +21,7 @@ --ciderShadow-Generic: var(--mediaItemShadow), 0 8px 40px rgb(0 0 0 / 0.55); --mediaItemRadius: 6px; --mediaItemRadiusRound: 100%; + --panelRadius: 10px; --contentInnerPadding: 16px; --navbarHeight1: 48px; --navbarHeight2: 0px; @@ -100,6 +101,7 @@ body.notransparency::before { right: 0; bottom: 0; opacity: 0.5; + display: none; 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==); } @@ -629,11 +631,21 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } .body { - background: #242424; + background: rgb(30 30 30 / 45%); padding: 6px; - border-radius: 6px; + border-radius: var(--panelRadius); width: 100%; box-shadow: var(--ciderShadow-Generic); + backdrop-filter: var(--glassFilter); + animation: cmenuBodyIn .5s var(--appleEase); + @keyframes cmenuBodyIn { + 0% { + background: rgb(30 30 30); + } + 100% { + background: rgb(30 30 30 / 45%); + } + } } .item { @@ -651,7 +663,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { margin: 2px 0px; &:hover { - background: var(--keyColor); + background: var(--selected); } } } @@ -1085,7 +1097,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { display: flex; &-macos { - width: 96px; + width: 100px; } } diff --git a/src/renderer/themes/grain.less b/src/renderer/themes/grain.less new file mode 100644 index 00000000..61c97e8e --- /dev/null +++ b/src/renderer/themes/grain.less @@ -0,0 +1,3 @@ +body.notransparency::before { + display: block; +} \ No newline at end of file diff --git a/src/renderer/themes/sweetener.less b/src/renderer/themes/sweetener.less index 681f41d3..79b76138 100644 --- a/src/renderer/themes/sweetener.less +++ b/src/renderer/themes/sweetener.less @@ -5,11 +5,18 @@ .menu-panel-body { background-color: @panelColors; backdrop-filter : blur(32px) saturate(180%); - animation: menuIn .10s var(--appleEase); + + &.menu-panel-body-down { + animation: menuInDown .10s var(--appleEase); + } + + &.menu-panel-body-up { + animation: menuInUp .10s var(--appleEase); + } + } - - @keyframes menuIn { + @keyframes menuInUp { 0% { opacity : 0; transform : translateY(-10px) translate3d(0,0,0); @@ -23,6 +30,20 @@ } } + @keyframes menuInDown { + 0% { + opacity : 0; + transform : translateY(10px) translate3d(0,0,0); + background: @panelColorsFallback; + } + + 100% { + opacity : 1; + transform : translateY(0); + background: @panelColors; + } + } + } diff --git a/src/renderer/views/app/chrome-bottom.ejs b/src/renderer/views/app/chrome-bottom.ejs index fb6b37bd..4e88e841 100644 --- a/src/renderer/views/app/chrome-bottom.ejs +++ b/src/renderer/views/app/chrome-bottom.ejs @@ -90,6 +90,7 @@ diff --git a/src/renderer/views/app/chrome-top.ejs b/src/renderer/views/app/chrome-top.ejs index 9d2ca250..a64b36c0 100644 --- a/src/renderer/views/app/chrome-top.ejs +++ b/src/renderer/views/app/chrome-top.ejs @@ -107,6 +107,7 @@ diff --git a/src/renderer/views/components/castmenu.ejs b/src/renderer/views/components/castmenu.ejs index ad3bd209..7ab727f3 100644 --- a/src/renderer/views/components/castmenu.ejs +++ b/src/renderer/views/components/castmenu.ejs @@ -116,7 +116,7 @@ }, setAirPlayCast(device) { this.activeCasts.push(device); - ipcRenderer.send("performAirplayPCM",device.host,device.port,null,"","","","") + ipcRenderer.send("performAirplayPCM",device.host,device.port,null,"","","","",device.txt) }, stopCasting() { CiderAudio.stopAudio(); diff --git a/src/renderer/views/components/listitem-horizontal.ejs b/src/renderer/views/components/listitem-horizontal.ejs index ba00fe6f..25296c47 100644 --- a/src/renderer/views/components/listitem-horizontal.ejs +++ b/src/renderer/views/components/listitem-horizontal.ejs @@ -40,7 +40,7 @@ this.itemPages = app.arrayToChunk(this.items, 4); try{ this.simplifiedParent = JSON.stringify(this.items.map ( function(x){return x.attributes.playParams})); - console.log("simplifiedParent: " + this.simplifiedParent); + console.debug("simplifiedParent: " + this.simplifiedParent); } catch (e){} diff --git a/src/renderer/views/components/mediaitem-list-item.ejs b/src/renderer/views/components/mediaitem-list-item.ejs index 7f1d06c8..0a1ab179 100644 --- a/src/renderer/views/components/mediaitem-list-item.ejs +++ b/src/renderer/views/components/mediaitem-list-item.ejs @@ -23,7 +23,7 @@ - diff --git a/src/renderer/views/components/mediaitem-square.ejs b/src/renderer/views/components/mediaitem-square.ejs index fa44a94e..93fc2dfd 100644 --- a/src/renderer/views/components/mediaitem-square.ejs +++ b/src/renderer/views/components/mediaitem-square.ejs @@ -2,12 +2,12 @@
{{item?.meta?.reason?.stringForDisplay ?? ''}}
+ class="cd-mediaitem-square" :class="getClasses()" @contextmenu="getContextMenu">