diff --git a/.circleci/config.yml b/.circleci/config.yml index 3d5bb5ff..72af7eb5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: - yarn-packages-{{ checksum "yarn.lock" }} - run: name: Install Dependencies - command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn + command: yarn install --cache-folder ~/.cache/yarn - save_cache: name: Save Yarn Package Cache key: yarn-packages-{{ checksum "yarn.lock" }} @@ -34,6 +34,9 @@ jobs: sudo apt-get install -y wine32 - store_test_results: path: test-results + - run: + name: Append Commit SHA to Version + command: yarn circle:append-sha - run: name: Generate Builds (Linux) command: yarn dist -l -p never diff --git a/.gitignore b/.gitignore index 475cb6f3..acc6dfb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Building dist build +.flatpak* +yarn-cache # Misc .idea @@ -135,7 +137,6 @@ dist .vscode-test # yarn v2 -yarn.lock .pnp.* .yarn/* .yarn/cache @@ -316,3 +317,4 @@ src/renderer/workbox-962786f2.js.map keys.sh package-lock.json +yarn.lock diff --git a/package.json b/package.json index 7b288392..6a001a8b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "dist": "yarn build && electron-builder", "dist:all": "yarn build && electron-builder -mwl", "msft": "yarn build && electron-builder -c msft-package.json", - "postinstall": "electron-builder install-app-deps" + "postinstall": "electron-builder install-app-deps", + "circle:append-sha": "node resources/appendCommitToVersion" }, "dependencies": { "@sentry/electron": "^2.5.4", @@ -34,7 +35,6 @@ "electron-fetch": "^1.7.4", "electron-log": "^4.4.4", "electron-notarize": "^1.1.1", - "electron-packager": "^15.4.0", "electron-store": "^8.0.1", "electron-updater": "^4.6.1", "electron-window-state": "^5.0.3", @@ -47,7 +47,6 @@ "music-metadata": "^7.11.4", "node-gyp": "^8.4.1", "qrcode": "^1.5.0", - "qrcode-terminal": "^0.12.0", "react": "^17.0.2", "react-dom": "^17.0.2", "run-script-os": "^1.1.6", diff --git a/resources/appendCommitToVersion.js b/resources/appendCommitToVersion.js new file mode 100644 index 00000000..b22c418e --- /dev/null +++ b/resources/appendCommitToVersion.js @@ -0,0 +1,20 @@ +if (!process.env['CIRCLECI']) { + console.log(`[CIRCLECI SCRIPT] CircleCI not found... Aborting script`) + return +} + +let fs = require('fs') + +var data = fs.readFileSync('package.json'); +var package = JSON.parse(data); + + +// https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables +package.version = `${package.version}.${process.env['CIRCLE_BUILD_NUM']}` + + +fs.writeFile('package.json', JSON.stringify(package), err => { + // error checking + if(err) throw err; + console.log("VERSION CHANGED"); +}); diff --git a/src/i18n/README.md b/src/i18n/README.md index cdbba71d..1f5d47d4 100644 --- a/src/i18n/README.md +++ b/src/i18n/README.md @@ -16,4 +16,52 @@ Several changes have been made to configuration options and will be listed below been modified, the ones not mentioned in the list need modifying. * `settings.option.experimental.closeButtonBehaviour`: Changed to `close_button_hide` - Should be "Close Button Should Hide the Application". `.quit`, `.minimizeTaskbar` and `.minimizeTray` have been removed. Translations done for en_US. -* `action.update`: Added for `en_US`. \ No newline at end of file +* `action.update`: Added for `en_US`. +* `term.topResult`: "Top Result" - Added for `en_US`. +* `term.sharedPlaylists`: "Shared Playlists" - Added for `en_US`. +* `term.people`: "People" - Added for `en_US`. + +Updated 02/02/2022 17:16 UTC + +* `term.newpreset.name`: Added for `en_US`. +* `term.addedpreset`: Added for `en_US`. +* `term.deletepreset.warn`: Added for `en_US`. +* `term.deletedpreset`: Added for `en_US`. +* `term.musicVideos`: Added for `en_US`. +* `term.stations`: Added for `en_US`. +* `term.curators`: Added for `en_US`. +* `term.appleCurators`: Added for `en_US`. +* `term.radioShows`: Added for `en_US`. +* `term.recordLabels`: Added for `en_US`. +* `term.videoExtras`: Added for `en_US`. +* `term.top`: Added for `en_US`. +* `action.newpreset`: Added for `en_US`. +* `action.deletepreset`: Added for `en_US`. + +Updated 04/02/2022 10:00 UTC + +* `term.history`: Added for `en_US`. +* `action.copy`: Added for `en_US`. +* `settings.header.visual.theme`: Added for `en_US`. +* `settings.option.visual.theme.default`: Added for `en_US`. +* `settings.option.visual.theme.dark`: Added for `en_US`. +* `settings.option.experimental.copy_log`: Added for `en_US`. +* `settings.option.experimental.inline_playlists`: Added for `en_US`. + +Update 05/02/2022 09:00 UTC + +* `settings.header.audio.quality.hireslossless`: Added for `en_US`. +* `settings.header.audio.quality.hireslossless.description`: Added for `en_US`. +* `settings.header.audio.quality.lossless`: Added for `en_US`. +* `settings.header.audio.quality.lossless.description`: Added for `en_US`. +* `settings.option.audio.enableAdvancedFunctionality.ciderPPE`: Added for `en_US`. +* `settings.option.audio.enableAdvancedFunctionality.ciderPPE.description`: Added for `en_US`. + +Update 06/02/2022 10:35 UTC + +* `settings.header.audio.quality.hireslossless.description`: Brackets removed, handled in renderer. +* `settings.header.audio.quality.lossless.description`: Brackets removed, handled in renderer. +* `settings.header.audio.quality.high.description`: Added for `en_US`. +* `settings.header.audio.quality.auto`: Removed as default for MusicKit is 256. +* `settings.header.audio.quality.standard`: Replaced `settings.header.audio.quality.low` to match MusicKit naming. +* `settings.header.audio.quality.standard.description`: Added for `en_US`. \ No newline at end of file diff --git a/src/i18n/en_OWO.jsonc b/src/i18n/en_OWO.jsonc new file mode 100644 index 00000000..7e15e260 --- /dev/null +++ b/src/i18n/en_OWO.jsonc @@ -0,0 +1,347 @@ +{ // Base File + // i18n Info + "i18n.languageName": "Engwish (OwO)", // name of language in native language + "i18n.languageNameEnglish": "Engwish (OwO)", // name of language in English + "i18n.category": "fun", // main = real language, fun = fun community languages + "i18n.authors": "@deerwithacurl @gamingliamstudios", // Authors, if you contribute to this file feel free to add your name seperated with a space + + // App info + "app.name": "Cidew", + + "date.format": "${m} ${d}, ${y}", + + // Dialogs + "dialog.cancel": "Nu", + "dialog.ok": "Oki", + + // Notification + "notification.updatingLibrarySongs": "Updating wibwawy songs...", + "notification.updatingLibraryAlbums": "Updating wibwawy awbums...", + "notification.updatingLibraryArtists": "Updating wibwawy awtists...", + + // Terms + "term.appleInc": "Appwe Inc.", + "term.appleMusic": "Appwe Mewsic", + "term.applePodcasts": "Appwe Pawdcasts", + "term.itunes": "iTuwunes", + "term.github": "GitHuwub", + "term.discord": "Discowd", + "term.learnMore": "Weawn moar", + "term.accountSettings": "Accownt Settings", + "term.logout": "Wogout", + "term.login": "Wogin", + "term.about": "Abowt", + "term.privateSession": "Pwivate Session OwO", + "term.queue": "Quwue", + "term.search": "Seawch", + "term.library": "Wibwawy", + "term.listenNow": "Wisten Nao", + "term.browse": "Bwowse", + "term.radio": "Wadio", + "term.recentlyAdded": "Wecentwy Added", + "term.songs": "Sawngs", + "term.albums": "Awbums", + "term.artists": "Awtists", + "term.podcasts": "Pawdcasts", + "term.playlists": "Pwaywists", + "term.playlist": "Pwaywist", + "term.newPlaylist": "Nyew Pwaywist", + "term.newPlaylistFolder": "New Pwaywist Fowdew", + "term.createNewPlaylist": "Cweate New Pwaywist", + "term.createNewPlaylistFolder": "Cweate New Pwaywist Fowdew", + "term.deletePlaylist": "Awe chu suwe chu wan to dewete dis pwaywist?", + "term.play": "Pway", + "term.pause": "Pawse", + "term.previous": "Pwevious", + "term.next": "Next", + "term.shuffle": "Shuffwe", + "term.repeat": "Wepeat", + "term.volume": "Vowume", + "term.mute": "Muwute", + "term.unmute": "Unmuwute", + "term.share": "Shawe", + "term.share.success": "Copied to cwipboawd", + "term.settings": "Settings", + "term.seeAll": "See Aww", + "term.sortBy": "Sowt By", + "term.sortBy.album": "Awbum", + "term.sortBy.artist": "Awtist", + "term.sortBy.name": "Name", + "term.sortBy.genre": "Genwe", + "term.sortBy.releaseDate": "Wewease Date", + "term.sortBy.duration": "Duwation", + "term.sortOrder": "A-Z", + "term.sortOrder.ascending": "Ascending", + "term.sortOrder.descending": "Descending", + "term.viewAs": "View As", + "term.viewAs.coverArt": "Covew Awt", + "term.viewAs.list": "Wist", + "term.size": "Size", + "term.size.normal": "Nowmaw", + "term.size.compact": "Wittwe", + "term.enable": "Enabwe", + "term.disable": "Disabwe", + "term.enabled": "Enabwed", + "term.disabled": "Disabwed", + "term.connect": "Connect", + "term.connecting": "Connecting", + "term.disconnect": "Disconnect", + "term.authed": "Authed", + "term.confirm": "Confiwm?", + "term.more": "Moar", + "term.less": "Wess", + "term.showMore": "Show moar", + "term.showLess": "Show wess", + "term.topSongs": "Top Songs", + "term.latestReleases": "Watest Weweases", + "term.time.added": "Added", + "term.time.released": "Weweased", + "term.time.updated": "Updated", + "term.time.hours": "houws", + "term.time.hour": "houw", + "term.time.minutes": "minuwtes", + "term.time.minute": "minuwte", + "term.time.seconds": "seconds", + "term.time.second": "second", + "term.fullscreenView": "Fuwwwscween View", + "term.defaultView": "Defauwt View", + "term.audioSettings": "Audiowo Settings", + "term.clearAll": "Cweaw Aww", + "term.recentStations": "Wecent Stations", + "term.language": "Wanguage", + "term.funLanguages": "Fun", + "term.noLyrics": "Woading... / Wywics not found./ Instwumentaw.", + "term.copyright": "Copywight", + "term.rightsReserved": "All Wights Wesewved.", + "term.sponsor": "Sponsow dis pwoject", + "term.ciderTeam": "Cidew Team", + "term.developer": "Devewopew", + "term.socialTeam": "Sociaw Team", + "term.socials": "Sociaws", + "term.contributors": "Contwibutows", + "term.equalizer": "Equawizew", + "term.reset": "Weset", + "term.tracks": "twacks", // Assume x amount of tracks. e.g. 50 tracks + "term.videos": "Videowos", + "term.menu": "Menuwu", + "term.check": "Check", + "term.aboutArtist": "About {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "Top Wesuwt", // Search Results + "term.sharedPlaylists": "Shawed Pwaywists", // Search Results + "term.people": "Peopwe", // Search Results + "term.newpreset.name": "New EQ Pweset Name", // Equalizer Preset + "term.addedpreset": "Added Pweset", + "term.deletepreset.warn": "Awe chu suwe chu want to dewete dis pweset?", + "term.deletedpreset": "Wemoved pweset", + "term.musicVideos": "Music Videowos", // Search page friendlyTypes + "term.stations": "Stations", + "term.curators": "Cuwatows", + "term.appleCurators": "Appwe Cuwatows", + "term.radioShows": "Wadio Shows", + "term.recordLabels": "Wecowd Wabews", + "term.videoExtras": "Videowo Extwas", + "term.top": "Top", + + // Home + "home.title": "Home", + "home.recentlyPlayed": "Wecentwy Pwayed", + "home.recentlyAdded": "Wecentwy Added", + "home.artistsFeed": "Youw Awtists Feed", + "home.artistsFeed.noArtist": "Fowwow some awtists fiwst and theiw watest weleases wiww be here", + "home.madeForYou": "Made Fow Chu", + "home.friendsListeningTo": "Fwiends Wistening To", + "home.followedArtists": "Fowwowed Awtists", + + // Errors + "error.appleMusicSubRequired": "Appwe Music wequiwes a subscwiption.", + "error.connectionError": "Thewe was a pwobwem connecting to Appwe Mewsic.", + "error.noResults": "No Wesuwts.", + "error.noResults.description": "Twy a new seawch.", + + // Podcasts + "podcast.followOnCider": "Fowwow On Cidew", + "podcast.followedOnCider": "Fowwowing On Cidew", + "podcast.subscribeOnItunes": "Subscwibe On iTuwunes", + "podcast.subscribedOnItunes": "Subscwibed On iTuwunes", + "podcast.itunesStore": "iTuwunes Stowe", + "podcast.episodes": "Episowodes", + "podcast.playEpisode": "Pway Episowode", + "podcast.website": "Pawdcast Website", + + // Actions + "action.addToLibrary": "Add to Wibwawy", + "action.addToLibrary.success": "Added to Wibwawy", + "action.addToLibrary.error": "Ewwow Adding to Wibwawy", + "action.removeFromLibrary": "Wemove fwom Wibwawy", + "action.removeFromLibrary.success": "Wemoved fwom Wibwawy", + "action.addToQueue": "Add to Quwue", + "action.addToQueue.success": "Added to Quwue", + "action.addToQueue.error": "Ewwow Adding to Quwue", + "action.removeFromQueue": "Wemove fwom Quwue", + "action.removeFromQueue.success": "Wemoved fwom Quwue", + "action.removeFromQueue.error": "Ewwow Wemoving fwom Quwue", + "action.createPlaylist": "Cweate a New Pwaywist", + "action.addToPlaylist": "Add to Pwaywist", + "action.removeFromPlaylist": "Wemove fwom Pwaywist", + "action.addToFavorites": "Add to Favowites", + "action.follow": "Fowwow", + "action.follow.success": "Fowwowed", + "action.follow.error": "Ewwow Fowwowing", + "action.unfollow": "Unfowwow", + "action.unfollow.success": "Unfowwowed", + "action.unfollow.error": "Ewwow Unfowwowing", + "action.playNext": "Pway Next", + "action.playLater": "Pway Watew", + "action.startRadio": "Stawt Wadio", + "action.goToArtist": "Go to Awtist", + "action.goToAlbum": "Go to Awbum", + "action.moveToTop": "Move to top", + "action.share": "Shawe", + "action.rename": "Wename", + "action.love": "Wuv", + "action.unlove": "Unwuv", + "action.dislike": "Diswike", + "action.undoDislike": "Undo diswike", + "action.showWebRemoteQR": "Web Wiimote", + "action.playTracksNext": "Pway ${app.selectedMediaItems.length} twacks next", + "action.playTracksLater": "Pway ${app.selectedMediaItems.length} twacks latew", + "action.removeTracks": "Wemove ${self.selectedItems.length} twacks fwom quwue", + "action.import": "Impowt", + "action.export": "Expowt", + "action.showAlbum": "Show Compwete Awbum", + "action.tray.minimize": "Minimize to Tway", + "action.tray.quit": "Quit", + "action.tray.show": "Show", + "action.update": "Update", + "action.newpreset": "New Pweset...", // Equalizer Preset + "action.deletepreset": "Dewete Pweset", + + // Settings - General + "settings.header.general": "Genewaw", + "settings.header.general.description": "Adjust the genewaw settings fow Cidew.", + "settings.option.general.language": "Wanguage", + + // Language optgroups + "settings.option.general.language.main": "Wanguages", + "settings.option.general.language.fun": "Fun Wanguages", + "settings.option.general.language.unsorted": "Unsowted", + + // Update Cider + "settings.option.general.updateCider": "Update Cidew", // Button + "settings.option.general.updateCider.branch": "Cidew Update Bwanch", // Dropdown + "settings.option.general.updateCider.branch.description": "Sewect the bwanch to uwpdate Cidew to", + "settings.option.general.updateCider.branch.main": "Stabwe", + "settings.option.general.updateCider.branch.develop": "Devewopment", + + // Settings - Audio + "settings.header.audio": "Audiowo", + "settings.header.audio.description": "Adjust the audiowo settings fow Cidew.", + "settings.option.audio.quality": "Audiowo Quawity", // Dropdown + "settings.header.audio.quality.hireslossless": "Hi-res losswess", + "settings.header.audio.quality.hireslossless.description": "(uwp to 24-bit/192 khz)", + "settings.header.audio.quality.lossless": "Losswess", + "settings.header.audio.quality.lossless.description": "(uwp to 24-bit/48 khz)", + "settings.header.audio.quality.high": "High", + "settings.header.audio.quality.low": "Low", // keeping as low because confusion with the word wow + "settings.header.audio.quality.auto": "Autowo", + "settings.option.audio.seamlessTransition": "Seamwess Audiowo Twansition", // Toggle + "settings.option.audio.enableAdvancedFunctionality": "Enabwe Advanced Functionawity", // Toggle + "settings.option.audio.enableAdvancedFunctionality.description": "Enabwing AudiowoContext functionawity wiww awwow fow extended audiowo featuwes wike Audiowo Nowmawization, Equalizews and Visuawizews, howevew on some systems dis may cause stuttewing in audiowo twacks.", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cidew Adwenawine Pwocessow™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Psychoacouwstic enhancements that makes evewything souwnd both wichew and mowe wivewy. | Designed by Maikiwi", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Stwength", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Changes the stwength of the pwocessing done to the auwdio. (Aggwessive may yiewd uwndesiwabwe wesuwwts)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standawd", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Aggwessive", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audiowo Nowmawization", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Nowmawizes peak vowume fow individuaw twacks to cweate a moar unifowm wistening expewience.", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Audiowo Spatiawization", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatiawize audiowo and make audiowo moar 3-dimensionaw (note: Dis is not Dowby Atmos)", + + // Settings - Visual + "settings.header.visual": "Visuaw", + "settings.header.visual.description": "Adjust the visuaw settings fow Cidew.", + "settings.option.visual.windowBackgroundStyle": "Window Backgwound Stywe", // Toggle + "settings.header.visual.windowBackgroundStyle.none": "None", + "settings.header.visual.windowBackgroundStyle.artwork": "Awtwowk", + "settings.header.visual.windowBackgroundStyle.image": "Image", + "settings.option.visual.animatedArtwork": "Animated Awtwowk", // Dropdown + "settings.header.visual.animatedArtwork.always": "Awways", + "settings.header.visual.animatedArtwork.limited": "Wimited to pages and speciaw entwies", + "settings.header.visual.animatedArtwork.disable": "Disabwe evewywhewe", + "settings.option.visual.animatedArtworkQuality": "Animated Awtwowk Quawity", // Dropdown + "settings.header.visual.animatedArtworkQuality.low": "Low", + "settings.header.visual.animatedArtworkQuality.medium": "Medium", + "settings.header.visual.animatedArtworkQuality.high": "High", + "settings.header.visual.animatedArtworkQuality.veryHigh": "Vewy High", + "settings.header.visual.animatedArtworkQuality.extreme": "Extweme", + "settings.option.visual.animatedWindowBackground": "Animated Window Backgwound", // Toggle + "settings.option.visual.hardwareAcceleration": "Hawdwawe Accewewation", // Dropdown + "settings.option.visual.hardwareAcceleration.description": "Wequiwes wewaunch", + "settings.header.visual.hardwareAcceleration.default": "Defauwt", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + // Refer to term.disabled for the disabled option + "settings.option.visual.showPersonalInfo": "Show Pewsonaw Info", // Toggle + + // Settings - Lyrics + "settings.header.lyrics": "Wywics", + "settings.header.lyrics.description": "Adjust the wywics settings fow Cidew.", + "settings.option.lyrics.enableMusixmatch": "Enabwe Musixmatch Wywics", // Toggle + "settings.option.lyrics.enableMusixmatchKaraoke": "Enabwe Kawaoke Mode (Musixmatch onwy)", // Toggle + "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch Twanswation Pwefewwed Wanguage", // Dropdown + "settings.option.lyrics.enableYoutubeLyrics": "Enabwe YouTube Wywics fow Mewsic Videowos", // Toggle + + // Settings - Connectivity + "settings.header.connectivity": "Connectivity", + "settings.header.connectivity.description": "Adjust the connectivity settings fow Cidew.", + "settings.option.connectivity.discordRPC": "Discowd Wich Pwesence", // Dropdown + "settings.option.connectivity.playbackNotifications": "Pwayback Notifications", // Toggle + // Refer to term.disabled for the disabled option + "settings.header.connectivity.discordRPC.cider": "Disway as 'Cider'", + "settings.header.connectivity.discordRPC.appleMusic": "Dispway as 'Apple Music'", + "settings.option.connectivity.discordRPC.clearOnPause": "Cweaw Discowd Wich Pwesence on Paws", // Toggle + "settings.option.connectivity.lastfmScrobble": "Wast.fm Scwobbwing", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "Wast.fm Scwobble Deway (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Enabwe Wast.fm Nao Pwaying", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Wemove featuwing awtists fwom song titwe (Wast.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Fiwtew wooped twack (Wast.fm)", + // Refer to term.connect for the connect button + + // Settings - Experimental + "settings.header.experimental": "Expewimentaw", + "settings.header.experimental.description": "Adjust the expewimentaw settings fow Cidew.", + "settings.option.experimental.compactUI": "Wittwe UI", // Toggle + "settings.option.experimental.close_button_hide": "Cwose Button Shouwd Hide the Appwication", + + // Refer to term.disabled & term.enabled + // Spatialization Menu + "spatial.notTurnedOn": "Audiowo Spatiawization is disabwed. To use, pwease enabwe it fiwst.", + "spatial.spatialProperties": "Spatiaw Pwopewties", + "spatial.width": "Width", + "spatial.height": "Height", + "spatial.depth": "Depth", + "spatial.gain": "Gain", + "spatial.roomMaterials": "Woom Matewiaws", + "spatial.roomDimensions": "Woom Dimensions", + "spatial.roomPositions": "Woom Positions", + "spatial.setDimensions": "Set Dimensions", + "spatial.setPositions": "Set Positions", + "spatial.up": "Up", + "spatial.front": "Fwont", + "spatial.left": "Weft", + "spatial.right": "Wight", + "spatial.back": "Back", + "spatial.down": "Down", + "spatial.listener": "Wistenew", + "spatial.audioSource": "Audiowo Souwce", + + // Settings - Unfinished + "settings.header.unfinished": "Unfinished", + + // Web Remote + "remote.web.title": "Cidew Wiimote", + "remote.web.description": "Scan da QR code to paiw chur phone up with dis Cidew instance", + + // About + "about.thanks": "Majow tanks to da Cidew Cowwective Team and aww of ouw contwibutows." +} \ No newline at end of file diff --git a/src/i18n/en_PISS.jsonc b/src/i18n/en_PISS.jsonc index ddd831a0..619ca375 100644 --- a/src/i18n/en_PISS.jsonc +++ b/src/i18n/en_PISS.jsonc @@ -1,16 +1,15 @@ { // Base File - // i18n Info - "i18n.languageName": "piss", // name of language in native language + "i18n.languageName": "piss", // name of language in native language "i18n.languageNameEnglish": "English (piss)", // name of language in English "i18n.category": "fun", // main = real language, fun = fun community languages - "i18n.authors": "@SoNothingMC", // Authors, if you contribute to this file feel free to add your name seperated with a space - + "i18n.authors": "@SoNothingMC @saboooor", // Authors, if you contribute to this file feel free to add your name seperated with a space + // App info "app.name": "piss", - - "date.format": "${y}-${m}-${d}", // ISO 8601 for the win! + "date.format": "${y}-${m}-${d}", // ISO 8601 for the win! + // Dialogs "dialog.cancel": "no piss", "dialog.ok": "yes piss", @@ -19,6 +18,7 @@ "notification.updatingLibrarySongs": "pisssing all over your songs", "notification.updatingLibraryAlbums": "pissing all over your albums", "notification.updatingLibraryArtists": "pissing all over your idols", + // Terms "term.appleInc": "piss Inc.", "term.appleMusic": "piss music", @@ -32,7 +32,8 @@ "term.login": "piss in", "term.about": "piss info", "term.privateSession": "piss in private", - "term.queue": "to be pissed", + "term.queue": "the toilet", + "term.history": "the sewage", "term.search": "find piss", "term.library": "obtained piss", "term.listenNow": "piss now", @@ -60,6 +61,7 @@ "term.mute": "piss without sound", "term.unmute": "piss with sound", "term.share": "piss on your friends", + "term.share.success": "copied piss, go piss on your friends", "term.settings": "pissettings", "term.seeAll": "all of the piss", "term.sortBy": "piss by", @@ -91,10 +93,10 @@ "term.less": "piss less", "term.showMore": "more piss", "term.showLess": "less piss", - "term.topSongs" : "top piss", + "term.topSongs": "top piss", "term.latestReleases": "latest piss collection", "term.time.added": "pissed", - "term.time.released": "pissed", + "term.time.released": "pissed", "term.time.updated": "pissed", "term.time.hours": "hours", "term.time.hour": "hour", @@ -121,9 +123,25 @@ "term.equalizer": "advanced piss configuration", "term.reset": "repiss", "term.tracks": "pisses", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "piss videos 😳", + "term.videos": "piss videos", "term.menu": "piss menu", "term.check": "piss!", + "term.aboutArtist": "about pisser {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "top piss", // Search Results + "term.sharedPlaylists": "shared pisslists", // Search Results + "term.people": "pissers", // Search Results + "term.newpreset.name": "new advanced piss prepiss name", // Equalizer Preset + "term.addedpreset": "pissed prepiss", + "term.deletepreset.warn": "are you sure you want to unpiss this prepiss?", + "term.deletedpreset": "unpissed prepiss", + "term.musicVideos": "piss music videos", // Search page friendlyTypes + "term.stations": "pisses", + "term.curators": "pissators", + "term.appleCurators": "piss pissators", + "term.radioShows": "shows that piss everywhere", + "term.recordLabels": "piss labels", + "term.videoExtras": "extra piss videos", + "term.top": "topiss", // Home "home.title": "piss central", @@ -134,13 +152,14 @@ "home.madeForYou": "pissed for you", "home.friendsListeningTo": "friends pissing to", "home.followedArtists": "followed pissers", + // Errors "error.appleMusicSubRequired": "piss music requires, like y'know, an actual piss music subscription to actually use.", "error.connectionError": "oh, piss.", "error.noResults": "no piss found", "error.noResults.description": "try pissing somewhere else (or press Enter/Return to search)", - //Podcasts + // Podcasts "podcast.followOnCider": "piss on Cider", "podcast.followedOnCider": "pissed on Cider", "podcast.subscribeOnItunes": "piss on iPiss", @@ -154,8 +173,8 @@ "action.addToLibrary": "obtain piss", "action.addToLibrary.success": "piss obtained", "action.addToLibrary.error": "error obtaining piss", - "action.removeFromLibrary": "unobtain piss", - "action.removeFromLibrary.success": "piss unobtained", + "action.removeFromLibrary": "dump piss", + "action.removeFromLibrary.success": "piss dumped", "action.addToQueue": "add to toilet", "action.addToQueue.success": "added to toilet", "action.addToQueue.error": "error adding to toilet", @@ -191,37 +210,51 @@ "action.import": "impiss", "action.export": "expiss", "action.showAlbum": "show complete piss collection", - // Waiting on Core for moving plugin to app.ts "action.tray.minimize": "piss off to tray", "action.tray.quit": "piss off", "action.tray.show": "piss back", + "action.update": "piss!", + "action.copy": "copiss", + "action.newpreset": "new prepiss...", // Equalizer Preset + "action.deletepreset": "unpiss prepiss", // Settings - General "settings.header.general": "general", "settings.header.general.description": "the dumping place for settings when there are no other places to put them into", - "settings.option.general.language": "piss around the world", + "settings.option.general.language": "piss around the world", // Language optgroups "settings.option.general.language.main": "actaul human languages", "settings.option.general.language.fun": "piss languages", "settings.option.general.language.unsorted": "???? who put this here", - + + // Update Cider + "settings.option.general.updateCider": "piss on cider", // Button + // Settings - Audio "settings.header.audio": "piss sounds", "settings.header.audio.description": "change how your piss sounds", "settings.option.audio.quality": "piss quality", // Dropdown + "settings.header.audio.quality.hireslossless": "ungodly piss", + "settings.header.audio.quality.hireslossless.description": "(up to 24-pisses/192 piss hertz)", + "settings.header.audio.quality.lossless": "colorful piss", + "settings.header.audio.quality.lossless.description": "(up to 24-pisses/48 piss hertz)", + "settings.header.audio.quality.enhanced": "enhanced piss", "settings.header.audio.quality.high": "nice piss", "settings.header.audio.quality.low": "piss with blood", "settings.header.audio.quality.auto": "automatic piss", "settings.option.audio.seamlessTransition": "seamless piss-to-piss transition", // Toggle "settings.option.audio.enableAdvancedFunctionality": "cool piss tricks", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "enabling the AudioContext thingy allows you to do cool stuffs, however on some systems your song may stutter", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "clear piss™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "makes your bladder go overboard and makes your piss crisp and clear.", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "piss normaliztion", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "protect your eardrums from overly loud/slient pisses", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "3D piss", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "this aint the dolby atmos you are looking for but its still pretty crazy so check it out", + // Settings - Visual - "settings.header.visual": "piss appearance", + "settings.header.visual": "piss appearance", "settings.header.visual.description": "change how your piss looks", "settings.option.visual.windowBackgroundStyle": "background piss", // Toggle "settings.header.visual.windowBackgroundStyle.none": "no piss", @@ -240,8 +273,13 @@ "settings.option.visual.animatedWindowBackground": "moving background piss", // Toggle "settings.option.visual.hardwareAcceleration": "make Cider piss faster", // Dropdown "settings.option.visual.hardwareAcceleration.description": "you need to relaunch Cider", - "settings.header.visual.hardwareAcceleration.default": "default piss", - "settings.header.visual.hardwareAcceleration.webGPU": "WebPISS", + "settings.header.visual.hardwareAcceleration.default": "default piss", + "settings.header.visual.hardwareAcceleration.webGPU": "WebPISS", + "settings.header.visual.theme": "colored piss", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "regular piss", + "settings.option.visual.theme.dark": "black piss", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "show yourself to the pissiverse", // Toggle @@ -263,22 +301,21 @@ "settings.header.connectivity.discordRPC.appleMusic": "piss as 'piss music'", "settings.option.connectivity.discordRPC.clearOnPause": "flush Pisscord rich pissence when holding your piss", // Toggle "settings.option.connectivity.lastfmScrobble": "Piss.fm scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Piss.fm scrobble delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "push now playing data to Piss.fm", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "remove featured pissers from piss names (Piss.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "filter same piss (Piss.fm)", + "settings.option.connectivity.lastfmScrobble.delay": "Piss.fm scrobble delay (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "push now playing data to Piss.fm", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "remove featured pissers from piss names (Piss.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "filter same piss (Piss.fm)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "piss lab", "settings.header.experimental.description": "mitochondria is the powerhouse of the cell", "settings.option.experimental.compactUI": "compact piss", // Toggle - "settings.option.experimental.closeButtonBehaviour": "piss off button behaviour", - "settings.option.experimental.closeButtonBehaviour.quit": "ask cider to piss off", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "piss off to the taskbar", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "piss off to the tray", - // Refer to term.disabled & term.enabled + "settings.option.experimental.close_button_hide": "play hide-and-seek when clicking close button", + "settings.option.experimental.copy_log": "copy sewage to pissboard", + "settings.option.experimental.inline_playlists": "inpiss pisslists and piss collections", + // Refer to term.disabled & term.enabled // Spatialization Menu "spatial.notTurnedOn": "3D piss is not on. turn it on lol", "spatial.spatialProperties": "3D properties", @@ -299,7 +336,7 @@ "spatial.down": "the piss on the floor", "spatial.listener": "you", "spatial.audioSource": "piss source", - + // Settings - Unfinished "settings.header.unfinished": "DLC piss", @@ -309,4 +346,4 @@ // About "about.thanks": "thanks to the Cider Collective team and all the pisseneers putting this together" -} +} \ No newline at end of file diff --git a/src/i18n/en_SGA.jsonc b/src/i18n/en_SGA.jsonc index ab6a1138..a04520b5 100644 --- a/src/i18n/en_SGA.jsonc +++ b/src/i18n/en_SGA.jsonc @@ -1,7 +1,6 @@ { - // i18n Info - "i18n.languageName": "┤ᖋ|:ᖋᔮᒣ╎ᔮ ᖋ|:i!⍑ᖋᕊᒷᒣ", // name of language in native language + "i18n.languageName": "┤ᖋ|:ᖋᔮᒣ╎ᔮ ᖋ|:i!⍑ᖋᕊᒷᒣ", // name of language in native language "i18n.languageNameEnglish": "Galactic Alphabet", // name of language in English "i18n.category": "fun", // main = real language, fun = fun community languages "i18n.authors": "@kyw504100", // Authors, if you contribute to this file feel free to add your name seperated with a space @@ -10,7 +9,7 @@ "app.name": "ᔮ╎↸ᒷ∷", "date.format": "${m} ${d}, ${y}", - + // Dialogs "dialog.cancel": "ᔮᖋリᔮᒷ|:", "dialog.ok": "ᒍ·ǀ·", @@ -19,6 +18,7 @@ "notification.updatingLibrarySongs": "⚍i!↸ᖋᒣ╎リ┤ |:╎ᕊ∷ᖋ∷॥ ϟᒍリ┤ϟ...", "notification.updatingLibraryAlbums": "⚍i!↸ᖋᒣ╎リ┤ |:╎ᕊ∷ᖋ∷॥ ᖋ|:ᕊ⚍ᒲϟ...", "notification.updatingLibraryArtists": "⚍i!↸ᖋᒣ╎リ┤ |:╎ᕊ∷ᖋ∷॥ ᖋ∷ᒣ╎ϟᒣϟ...", + // Terms "term.appleInc": "ᖋi!i!|:ᒷ ╎リᔮ.", "term.appleMusic": "ᖋi!i!|:ᒷ ᒲ⚍ϟ╎ᔮ", @@ -29,10 +29,11 @@ "term.learnMore": "|:ᒷᖋ∷リ ᒲᒍ∷ᒷ", "term.accountSettings": "ᖋᔮᔮᒍ⚍リᒣ ϟᒷᒣᒣ╎リ┤ϟ", "term.logout": "|:ᒍ┤ᒍ⚍ᒣ", - "term.login": "|:ᒍ┤╎リ", + "term.login": "|:ᒍ┤ ╎リ", "term.about": "ᖋᕊᒍ⚍ᒣ", "term.privateSession": "I!∷╎⍊ᖋᒣᒷ ϟᒷϟϟ╎ᒍリ", "term.queue": "ᑑ⚍ᒷ⚍ᒷ", + "term.history": "⍑╎ϟᒣᒍ∷॥", "term.search": "ϟᒷᖋ∷ᔮ⍑", "term.library": "|:╎ᕊ∷ᖋ∷॥", "term.listenNow": "|:╎ϟᒣᒷリ", @@ -45,6 +46,11 @@ "term.podcasts": "I!ᒍ↸ᔮᖋϟᒣϟ", "term.playlists": "i!|:ᖋ॥|:╎ϟᒣϟ", "term.playlist": "i!|:ᖋ॥|:╎ϟᒣ", + "term.newPlaylist": "リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ", + "term.newPlaylistFolder": "リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ ⎓ᒍ|:↸ᒷ∷", + "term.createNewPlaylist": "ᔮ∷ᒷᖋᒣᒷ リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ", + "term.createNewPlaylistFolder": "ᔮ∷ᒷᖋᒣᒷ リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ ⎓ᒍ|:↸ᒷ∷", + "term.deletePlaylist": "ᖋ∷ᒷ ॥ᒍ⚍ ϟ⚍∷ᒷ ॥ᒍ⚍ ∴ᖋリᒣ ᒣᒍ ↸ᒷ|:ᒷᒣᒷ ᒣ⍑╎ϟ i!|:ᖋ॥|:╎ϟᒣ?", "term.play": "i!|:ᖋ॥", "term.pause": "I!ᖋ⚍ϟᒷ", "term.previous": "I!∷ᒷ⍊╎ᒍ⚍ϟ", @@ -55,6 +61,7 @@ "term.mute": "ᒲ⚍ᒣᒷ", "term.unmute": "⚍リᒲ⚍ᒣᒷ", "term.share": "ϟ⍑ᖋ∷ᒷ", + "term.share.success": "ᔮᒍi!╎ᒷ↸ ᒣᒍ ᔮ|:╎i!ᕊᒍᖋ∷↸", "term.settings": "ϟᒷᒣᒣ╎リ┤ϟ", "term.seeAll": "ϟᒷᒷ ᖋ|:|:", "term.sortBy": "ϟᒍ∷ᒣ ᕊ॥", @@ -86,10 +93,10 @@ "term.less": "|:ᒷϟϟ", "term.showMore": "ϟ⍑ᒍ∴ ᒲᒍ∷ᒷ", "term.showLess": "ϟ⍑ᒍ∴ |:ᒷϟϟ", - "term.topSongs" : "ᒣᒍi! ϟᒍリ┤ϟ", + "term.topSongs": "ᒣᒍi! ϟᒍリ┤ϟ", "term.latestReleases": "|:ᖋᒣᒷϟᒣ ∷ᒷ|:ᒷᖋϟᒷϟ", "term.time.added": "ᖋ↸↸ᒷ↸", - "term.time.released": "∷ᒷ|:ᒷᖋϟᒷ↸", + "term.time.released": "∷ᒷ|:ᒷᖋϟᒷ↸", "term.time.updated": "⚍i!↸ᖋᒣᒷ↸", "term.time.hours": "⍑ᒍ⚍∷ϟ", "term.time.hour": "⍑ᒍ⚍∷", @@ -117,9 +124,25 @@ "term.reset": "∷ᒷϟᒷᒣ", "term.tracks": "ᒣ∷ᖋᔮ·ǀ·ϟ", // Assume x amount of tracks. e.g. 50 tracks "term.videos": "⍊╎↸ᒷᒍ", - "term.menu": "ᒲᒷ⚍リ", - "term.showAlbum": "ϟ⍑ᒍ∴ ᔮᒍᒲi!|:ᒷᒣᒷ ᖋ|:ᕊ⚍ᒲ", - + "term.menu": "ᒲᒷ⚍リ", + "term.check": "ᔮ⍑ᒷᔮ·ǀ·", + "term.aboutArtist": "ᖋᕊᒍ⚍ᒣ {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "ᒣᒍi! ∷ᒷϟ⚍|:ᒣ", // Search Results + "term.sharedPlaylists": "ϟ⍑ᖋ∷ᒷ↸ i!|:ᖋ॥|:╎ϟᒣϟ", // Search Results + "term.people": "i!ᒷᒍi!|:ᒷ", // Search Results + "term.newpreset.name": "リᒷ∴ ᒷᑑ i!∷ᒷϟᒷᒣ リᖋᒲᒷ", // Equalizer Preset + "term.addedpreset": "ᖋ↸↸ᒷ↸ i!∷ᒷϟᒷᒣ", + "term.deletepreset.warn": "ᖋ∷ᒷ ॥ᒍ⚍ ϟ⚍∷ᒷ ॥ᒍ⚍ ∴ᖋリᒣ ᒣᒍ ↸ᒷ|:ᒷᒣᒷ ᒣ⍑╎ϟ i!∷ᒷϟᒷᒣ?", + "term.deletedpreset": "∷ᒷᒲᒍ⍊ᒷ↸ i!∷ᒷϟᒷᒣ", + "term.musicVideos": "ᒲ⚍ϟ╎ᔮ ⍊╎↸ᒷᒍϟ", // Search page friendlyTypes + "term.stations": "ϟᒣᖋᒣ╎ᒍリϟ", + "term.curators": "ᔮ⚍∷ᖋᒣᒍ∷ϟ", + "term.appleCurators": "ᖋi!i!|:ᒷ ᔮ⚍∷ᖋᒣᒍ∷ϟ", + "term.radioShows": "∷ᖋ↸╎ᒍ ϟ⍑ᒍ∴ϟ", + "term.recordLabels": "∷ᒷᔮᒍ∷↸ |:ᖋᕊᒷ|:ϟ", + "term.videoExtras": "⍊╎↸ᒷᒍ ᒷ/ᒣ∷ᖋϟ", + "term.top": "ᒣᒍi!", + // Home "home.title": "⍑ᒍᒲᒷ", "home.recentlyPlayed": "∷ᒷᔮᒷリᒣ|:॥ i!|:ᖋ॥ᒷ↸", @@ -129,13 +152,14 @@ "home.madeForYou": "ᒲᖋ↸ᒷ ⎓ᒍ∷ ॥ᒍ⚍", "home.friendsListeningTo": "⎓∷╎ᒷリ↸ϟ |:╎ϟᒣᒷリ╎リ┤ ᒣᒍ", "home.followedArtists": "⎓ᒍ|:|:ᒍ∴ᒷ↸ ᖋ∷ᒣ╎ϟᒣϟ", + // Errors "error.appleMusicSubRequired": "ᖋi!i!|:ᒷ ᒲ⚍ϟ╎ᔮ ∷ᒷᑑ⚍╎∷ᒷϟ ᖋ ϟ⚍ᕊϟᔮ∷╎i!ᒣ╎ᒍリ.", "error.connectionError": "ᒣ⍑ᒷ∷ᒷ ∴ᖋϟ ᖋ i!∷ᒍᕊ|:ᒷᒲ ᔮᒍリリᒷᔮᒣ╎リ┤ ᒣᒍ ᖋi!i!|:ᒷ ᒲ⚍ϟ╎ᔮ.", "error.noResults": "リᒍ ∷ᒷϟ⚍|:ᒣϟ.", "error.noResults.description": "ᒣ∷॥ ᖋ リᒷ∴ ϟᒷᖋ∷ᔮ⍑.", - //Podcasts + // Podcasts "podcast.followOnCider": "⎓ᒍ|:|:ᒍ∴ ᒍリ ᔮ╎↸ᒷ∷", "podcast.followedOnCider": "⎓ᒍ|:|:ᒍ∴╎リ┤ ᒍリ ᔮ╎↸ᒷ∷", "podcast.subscribeOnItunes": "ϟ⚍ᕊϟᔮ∷╎ᕊᒷ ᒍリ ╎ᒣ⚍リᒷϟ", @@ -185,6 +209,14 @@ "action.removeTracks": "∷ᒷᒲᒍ⍊ᒷ ${self.selectedItems.length} ᒣ∷ᖋᔮ·ǀ·ϟ ⎓∷ᒍᒲ ᑑ⚍ᒷ⚍ᒷ", "action.import": "╎ᒲi!ᒍ∷ᒣ", "action.export": "ᒷ/i!ᒍ∷ᒣ", + "action.showAlbum": "ϟ⍑ᒍ∴ ᔮᒍᒲi!|:ᒷᒣᒷ ᖋ|:ᕊ⚍ᒲ", + "action.tray.minimize": "ᒲ╎リ╎ᒲ╎∩ᒷ ᒣᒍ ᒣ∷ᖋ॥", + "action.tray.quit": "ᑑ⚍╎ᒣ", + "action.tray.show": "ϟ⍑ᒍ∴", + "action.update": "⚍i!↸ᖋᒣᒷ", + "action.copy": "ᔮᒍi!॥", + "action.newpreset": "リᒷ∴ i!∷ᒷϟᒷᒣ...", // Equalizer Preset + "action.deletepreset": "↸ᒷ|:ᒷᒣᒷ i!∷ᒷϟᒷᒣ", // Settings - General "settings.header.general": "┤ᒷリᒷ∷ᖋ|:", @@ -196,22 +228,32 @@ "settings.option.general.language.fun": "⎓⚍リ |:ᖋリ┤⚍ᖋ┤ᒷϟ", "settings.option.general.language.unsorted": "⚍リϟᒍ∷ᒣᒷ↸", + // Update Cider + "settings.option.general.updateCider": "⚍i!↸ᖋᒣᒷ ᔮ╎↸ᒷ∷", + // Settings - Audio "settings.header.audio": "ᖋ⚍↸╎ᒍ", "settings.header.audio.description": "ᖋ↸⋮⚍ϟᒣ ᒣ⍑ᒷ ᖋ⚍↸╎ᒍ ϟᒷᒣᒣ╎リ┤ϟ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", "settings.option.audio.quality": "ᖋ⚍↸╎ᒍ ᑑ⚍ᖋ|:╎ᒣ॥", // Dropdown + "settings.header.audio.quality.hireslossless": "⍑╎-∷ᒷϟ |:ᒍϟϟ|:ᒷϟϟ", + "settings.header.audio.quality.hireslossless.description": "(⚍i! ᒣᒍ 24-ᕊ╎ᒣ/192 ·ǀ·⍑∩)", + "settings.header.audio.quality.lossless": "|:ᒍϟϟ|:ᒷϟϟ", + "settings.header.audio.quality.lossless.description": "(⚍i! ᒣᒍ 24-ᕊ╎ᒣ/48 ·ǀ·⍑∩)", "settings.header.audio.quality.high": "⍑╎┤⍑", "settings.header.audio.quality.low": "|:ᒍ∴", "settings.header.audio.quality.auto": "ᖋ⚍ᒣᒍ", "settings.option.audio.seamlessTransition": "ϟᒷᖋᒲ|:ᒷϟϟ ᖋ⚍↸╎ᒍ ᒣ∷ᖋリϟ╎ᒣ╎ᒍリ", // Toggle "settings.option.audio.enableAdvancedFunctionality": "ᒷリᖋᕊ|:ᒷ ᖋ↸⍊ᖋリᔮᒷ↸ ⎓⚍リᔮᒣ╎ᒍリᖋ|:╎ᒣ॥", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "ᒷリᖋᕊ|:╎リ┤ ᖋ⚍↸╎ᒍᔮᒍリᒣᒷ/ᒣ ⎓⚍リᔮᒣ╎ᒍリᖋ|:╎ᒣ॥ ∴╎|:|: ᖋ|:|:ᒍ∴ ⎓ᒍ∷ ᒷ/ᒣᒷリ↸ᒷ↸ ᖋ⚍↸╎ᒍ ⎓ᒷᖋᒣ⚍∷ᒷϟ |:╎·ǀ·ᒷ ᖋ⚍↸╎ᒍ リᒍ∷ᒲᖋ|:╎∩ᖋᒣ╎ᒍリ , ᒷᑑ⚍ᖋ|:╎∩ᒷ∷ϟ ᖋリ↸ ⍊╎ϟ⚍ᖋ|:╎∩ᒷ∷ϟ, ⍑ᒍ∴ᒷ⍊ᒷ∷ ᒍリ ϟᒍᒲᒷ ϟ॥ϟᒣᒷᒲϟ ᒣ⍑╎ϟ ᒲᖋ॥ ᔮᖋ⚍ϟᒷ ϟᒣ⚍ᒣᒣᒷ∷╎リ┤ ╎リ ᖋ⚍↸╎ᒍ ᒣ∷ᖋᔮ·ǀ·ϟ.", + "settings.option.audio.enableAdvancedFunctionality.decryptLLPW": "↸ᒷᔮ∷॥i!ᒣ |:ᒍϟϟ|:ᒷϟϟ i!|:ᖋ॥ᕊᖋᔮ·ǀ· ∴ᒍ∷·ǀ·⎓|:ᒍ∴", // Toggle + "settings.option.audio.enableAdvancedFunctionality.decryptLLPW.description": "ᒷリᖋᕊ|:ᒷϟ ᒣ⍑ᒷ ᖋᕊ╎|:╎ᒣ॥ ⎓ᒍ∷ ᔮ╎↸ᒷ∷ ᒣᒍ ↸ᒷᔮ∷॥i!ᒣ |:ᒍϟϟ|:ᒷϟϟ ᖋ⚍↸╎ᒍ ⎓╎|:ᒷϟ. ᖋ ᒲ╎リᒍ∷ i!ᒷ∷⎓ᒍ∷ᒲᖋリᔮᒷ ⍑╎ᒣ ∴╎|:|: ᒍᔮᔮ⚍∷.", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "ᖋ⚍↸╎ᒍ リᒍ∷ᒲᖋ|:╎∩ᖋᒣ╎ᒍリ", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "リᒍ∷ᒲᖋ|:╎∩ᒷϟ i!ᒷᖋ·ǀ· ⍊ᒍ|:⚍ᒲᒷ ⎓ᒍ∷ ╎リ↸╎⍊╎↸⚍ᖋ|: ᒣ∷ᖋᔮ·ǀ·ϟ ᒣᒍ ᔮ∷ᒷᖋᒣᒷ ᖋ ᒲᒍ∷ᒷ ⚍リ╎⎓ᒍ∷ᒲ |:╎ϟᒣᒷリ╎リ┤ ᒷ/i!ᒷ∷╎ᒷリᔮᒷ.", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "ᖋ⚍↸╎ᒍ ϟi!ᖋᒣ╎ᖋ|:╎∩ᖋᒣ╎ᒍリ", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "ϟi!ᖋᒣ╎ᖋ|:╎∩ᒷ ᖋ⚍↸╎ᒍ ᖋリ↸ ᒲᖋ·ǀ·ᒷ ᖋ⚍↸╎ᒍ ᒲᒍ∷ᒷ 3-↸╎ᒲᒷリϟ╎ᒍリᖋ|: (リᒍᒣᒷ: ᒣ⍑╎ϟ ╎ϟ リᒍᒣ ↸ᒍ|:ᕊ॥ ᖋᒣᒲᒍϟ)", + // Settings - Visual - "settings.header.visual": "⍊╎ϟ⚍ᖋ|:", + "settings.header.visual": "⍊╎ϟ⚍ᖋ|:", "settings.header.visual.description": "ᖋ↸⋮⚍ϟᒣ ᒣ⍑ᒷ ⍊╎ϟ⚍ᖋ| ϟᒷᒣᒣ╎リ┤ϟ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", "settings.option.visual.windowBackgroundStyle": "∴╎リ↸ᒍ∴ ᕊᖋᔮ·ǀ·┤∷ᒍ⚍リ↸ ϟᒣ॥|:ᒷ", // Toggle "settings.header.visual.windowBackgroundStyle.none": "リᒍリᒷ", @@ -230,8 +272,13 @@ "settings.option.visual.animatedWindowBackground": "ᖋリ╎ᒲᖋᒣᒷ↸ ∴╎リ↸ᒍ∴ ᕊᖋᔮ·ǀ·┤∷ᒍ⚍リ↸", // Toggle "settings.option.visual.hardwareAcceleration": "⍑ᖋ∷↸∴ᖋ∷ᒷ ᖋᔮᔮᒷ|:ᒷ∷ᖋᒣ╎ᒍリ", // Dropdown "settings.option.visual.hardwareAcceleration.description": "∷ᒷᑑ⚍╎∷ᒷϟ ∷ᒷ|:ᖋ⚍リᔮ⍑", - "settings.header.visual.hardwareAcceleration.default": "↸ᒷ⎓ᖋ⚍|:ᒣ", - "settings.header.visual.hardwareAcceleration.webGPU": "∴ᒷᕊ┤i!⚍", + "settings.header.visual.hardwareAcceleration.default": "↸ᒷ⎓ᖋ⚍|:ᒣ", + "settings.header.visual.hardwareAcceleration.webGPU": "∴ᒷᕊ┤i!⚍", + "settings.header.visual.theme": "ᒣ⍑ᒷᒲᒷ", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "ᔮ╎↸ᒷ∷", + "settings.option.visual.theme.dark": "↸ᖋ∷·ǀ·", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "ϟ⍑ᒍ∴ i!ᒷ∷ϟᒍリᖋ|: ╎リ⎓ᒍ", // Toggle @@ -242,7 +289,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "ᒷリᖋᕊ|:ᒷ ·ǀ·ᖋ∷ᖋᒍ·ǀ·ᒷ ᒲᒍ↸ᒷ (ᒲ⚍ϟ╎̇/ᒲᖋᒣᔮ⍑ ᒍリ|:॥)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "ᒲ⚍ϟ╎̇/ᒲᖋᒣᔮ⍑ ᒣ∷ᖋリϟ|:ᖋᒣ╎ᒍリ i!∷ᒷ⎓ᒷ∷∷ᒷ↸ |:ᖋリ┤⚍ᖋ┤ᒷ", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "ᒷリᖋᕊ|:ᒷ ॥ᒍ⚍ᒣ⚍ᕊᒷ |:॥∷╎ᔮϟ ⎓ᒍ∷ ᒲ⚍ϟ╎ᔮ ⍊╎↸ᒷᒍϟ", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "ᔮᒍリリᒷᔮᒣ╎⍊╎ᒣ॥", "settings.header.connectivity.description": "ᖋ↸⋮⚍ϟᒣ ᒣ⍑ᒷ ᔮᒍリリᒷᔮᒣ╎⍊╎ᒣ॥ ϟᒷᒣᒣ╎リ┤ϟ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", @@ -252,50 +299,50 @@ "settings.header.connectivity.discordRPC.cider": "↸╎ϟi!|:ᖋ॥ ᖋϟ 'ᔮ╎↸ᒷ∷'", "settings.header.connectivity.discordRPC.appleMusic": "↸╎ϟi!|:ᖋ॥ ᖋϟ 'ᖋi!i!|:ᒷ ᒲ⚍ϟ╎ᔮ'", "settings.option.connectivity.discordRPC.clearOnPause": "ᔮ|:ᒷᖋ∷ ↸╎ϟᔮᒍ∷↸ ∷╎ᔮ⍑ i!∷ᒷϟᒷリᔮᒷ ᒍリ i!ᖋ⚍ϟᒷ", // Toggle - "settings.option.connectivity.lastfmScrobble": "|:ᖋϟᒣ⎓ᒲ ϟᔮ∷ᒍᕊᕊ|:╎リ┤", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "|:ᖋϟᒣ⎓ᒲ ϟᔮ∷ᒍᕊᕊ|:ᒷ ↸ᒷ|:ᖋ॥ (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "ᒷリᖋᕊ|:ᒷ |:ᖋϟᒣ⎓ᒲ リᒍ∴ i!|:ᖋ॥╎リ┤", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "∷ᒷᒲᒍ⍊ᒷ ⎓ᒷᖋᒣ⚍∷╎リ┤ ᖋ∷ᒣ╎ϟᒣϟ ⎓∷ᒍᒲ ϟᒍリ┤ ᒣ╎ᒣ|:ᒷ (|:ᖋϟᒣ⎓ᒲ)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "⎓╎|:ᒣᒷ∷ |:ᒍᒍi!ᒷ↸ ᒣ∷ᖋᔮ·ǀ· (|:ᖋϟᒣ⎓ᒲ)", + "settings.option.connectivity.lastfmScrobble": "|:ᖋϟᒣ.⎓ᒲ ϟᔮ∷ᒍᕊᕊ|:╎リ┤", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "|:ᖋϟᒣ.⎓ᒲ ϟᔮ∷ᒍᕊᕊ|:ᒷ ↸ᒷ|:ᖋ॥ (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "ᒷリᖋᕊ|:ᒷ |:ᖋϟᒣ.⎓ᒲ リᒍ∴ i!|:ᖋ॥╎リ┤", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "∷ᒷᒲᒍ⍊ᒷ ⎓ᒷᖋᒣ⚍∷╎リ┤ ᖋ∷ᒣ╎ϟᒣϟ ⎓∷ᒍᒲ ϟᒍリ┤ ᒣ╎ᒣ|:ᒷ (|:ᖋϟᒣ.⎓ᒲ)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "⎓╎|:ᒣᒷ∷ |:ᒍᒍi!ᒷ↸ ᒣ∷ᖋᔮ·ǀ· (|:ᖋϟᒣ.⎓ᒲ)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "ᒷ/i!ᒷ∷╎ᒲᒷリᒣᖋ|:", "settings.header.experimental.description": "ᖋ↸⋮⚍ϟᒣ ᒣ⍑ᒷ ᒷ/i!ᒷ∷╎ᒲᒷリᒣᖋ|: ϟᒷᒣᒣ╎リ┤ϟ ⎓ᒍ∷ ᔮ╎↸ᒷ∷.", "settings.option.experimental.compactUI": "ᔮᒍᒲi!ᖋᔮᒣ ⚍╎", // Toggle - "settings.option.experimental.closeButtonBehaviour": "ᔮ|:ᒍϟᒷ ᕊ⚍ᒣᒣᒍリ ᕊᒷ⍑ᖋ⍊╎ᒍ⚍∷", - "settings.option.experimental.closeButtonBehaviour.quit": "ᑑ⚍╎ᒣ ᔮ╎↸ᒷ∷", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "ᒲ╎リ╎ᒲ╎∩ᒷ ᒣᒍ ᒣᖋϟ·ǀ·ᕊᖋ∷", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "ᒲ╎リ╎ᒲ╎∩ᒷ ᒣᒍ ϟ॥ϟᒣᒷᒲ ᒣ∷ᖋ॥", + "settings.option.experimental.close_button_hide": "ᔮ|:ᒍϟᒷ ᕊ⚍ᒣᒣᒍリ ϟ⍑ᒍ⚍|:↸ ⍑╎↸ᒷ ᒣ⍑ᒷ ᖋi!i!|:╎ᔮᖋᒣ╎ᒍリ", + "settings.option.experimental.copy_log": "ᔮᒍi!॥ |:ᒍ┤ϟ ᒣᒍ ᔮ|:╎i!ᕊᒍᖋ∷↸", + "settings.option.experimental.inline_playlists": "╎リ|:╎リᒷ i!|:ᖋ॥|:╎ϟᒣϟ ᖋリ↸ ᖋ|:ᕊ⚍ᒲϟ", + // Refer to term.disabled & term.enabled - // Spatialization Menu - "spatial.spatialProperties" : "ϟi!ᖋᒣ╎ᖋ|: i!∷ᒍi!ᒷ∷ᒣ╎ᒷϟ", - "spatial.width" : "∴╎↸ᒣ⍑", - "spatial.height" : "⍑ᒷ╎┤⍑ᒣ", - "spatial.depth" : "↸ᒷi!ᒣ⍑", - "spatial.gain" : "┤ᖋ╎リ", - "spatial.roomMaterials" : "∷ᒍᒍᒲ ᒲᖋᒣᒷ∷╎ᖋ|:ϟ", - "spatial.roomDimensions" : "∷ᒍᒍᒲ ↸╎ᒲᒷリϟ╎ᒍリϟ", - "spatial.roomPositions" : "∷ᒍᒍᒲ i!ᒍϟ╎ᒣ╎ᒍリϟ", - "spatial.setDimensions" : "ϟᒷᒣ ↸╎ᒲᒷリϟ╎ᒍリϟ", - "spatial.setPositions" : "ϟᒷᒣ i!ᒍϟ╎ᒣ╎ᒍリϟ", - "spatial.up" : "⚍i!", - "spatial.front" : "⎓∷ᒍリᒣ", - "spatial.left" : "|:ᒷ⎓ᒣ", - "spatial.right" : "∷╎┤⍑ᒣ", - "spatial.back" : "ᕊᖋᔮ·ǀ·", - "spatial.down" : "↸ᒍ∴リ", - "spatial.listener" : "|:╎ϟᒣᒷリᒷ∷", - "spatial.audioSource" : "ᖋ⚍↸╎ᒍ ϟᒍ⚍∷ᔮᒷ", + "spatial.notTurnedOn": "ᖋ⚍↸╎ᒍ ϟi!ᖋᒣ╎ᖋ|:╎∩ᖋᒣ╎ᒍリ ╎ϟ ↸╎ϟᖋᕊ|:ᒷ↸. ᒣᒍ ⚍ϟᒷ, i!|:ᒷᖋϟᒷ ᒷリᖋᕊ|:ᒷ ╎ᒣ ⎓╎∷ϟᒣ.", + "spatial.spatialProperties": "ϟi!ᖋᒣ╎ᖋ|: i!∷ᒍi!ᒷ∷ᒣ╎ᒷϟ", + "spatial.width": "∴╎↸ᒣ⍑", + "spatial.height": "⍑ᒷ╎┤⍑ᒣ", + "spatial.depth": "↸ᒷi!ᒣ⍑", + "spatial.gain": "┤ᖋ╎リ", + "spatial.roomMaterials": "∷ᒍᒍᒲ ᒲᖋᒣᒷ∷╎ᖋ|:ϟ", + "spatial.roomDimensions": "∷ᒍᒍᒲ ↸╎ᒲᒷリϟ╎ᒍリϟ", + "spatial.roomPositions": "∷ᒍᒍᒲ i!ᒍϟ╎ᒣ╎ᒍリϟ", + "spatial.setDimensions": "ϟᒷᒣ ↸╎ᒲᒷリϟ╎ᒍリϟ", + "spatial.setPositions": "ϟᒷᒣ i!ᒍϟ╎ᒣ╎ᒍリϟ", + "spatial.up": "⚍i!", + "spatial.front": "⎓∷ᒍリᒣ", + "spatial.left": "|:ᒷ⎓ᒣ", + "spatial.right": "∷╎┤⍑ᒣ", + "spatial.back": "ᕊᖋᔮ·ǀ·", + "spatial.down": "↸ᒍ∴リ", + "spatial.listener": "|:╎ϟᒣᒷリᒷ∷", + "spatial.audioSource": "ᖋ⚍↸╎ᒍ ϟᒍ⚍∷ᔮᒷ", // Settings - Unfinished "settings.header.unfinished": "⚍リ⎓╎リ╎ϟ⍑ᒷ↸", - + // Web Remote "remote.web.title": "ᔮ╎↸ᒷ∷ ∷ᒷᒲᒍᒣᒷ", "remote.web.description": "ϟᔮᖋリ ᒣ⍑ᒷ ᑑ∷ ᔮᒍ↸ᒷ ᒣᒍ i!ᖋ╎∷ ॥ᒍ⚍∷ i!⍑ᒍリᒷ ⚍i! ∴╎ᒣ⍑ ᒣ⍑╎ϟ ᔮ╎↸ᒷ∷ ╎リϟᒣᖋリᔮᒷ", - + // About "about.thanks": "ᒲᖋ⋮ᒍ∷ ᒣ⍑ᖋリ·ǀ·ϟ ᒣᒍ ᒣ⍑ᒷ ᔮ╎↸ᒷ∷ ᔮᒍ|:|:ᒷᔮᒣ╎⍊ᒷ ᒣᒷᖋᒲ ᖋリ↸ ᖋ|:|: ᒍ⎓ ᒍ⚍∷ ᔮᒍリᒣ∷╎ᕊ⚍ᒣᒍ∷ϟ." } \ No newline at end of file diff --git a/src/i18n/en_US.jsonc b/src/i18n/en_US.jsonc index 0436c4e7..2bce04b9 100644 --- a/src/i18n/en_US.jsonc +++ b/src/i18n/en_US.jsonc @@ -1,24 +1,24 @@ { // Base File - // i18n Info - "i18n.languageName": "English (US)", // name of language in native language + "i18n.languageName": "English (US)", // name of language in native language "i18n.languageNameEnglish": "English (US)", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - + // App info "app.name": "Cider", - + "date.format": "${m} ${d}, ${y}", // Dialogs "dialog.cancel": "Cancel", "dialog.ok": "OK", - + // Notification "notification.updatingLibrarySongs": "Updating library songs...", "notification.updatingLibraryAlbums": "Updating library albums...", "notification.updatingLibraryArtists": "Updating library artists...", + // Terms "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", @@ -29,10 +29,11 @@ "term.learnMore": "Learn more", "term.accountSettings": "Account Settings", "term.logout": "Logout", - "term.login": "Login", + "term.login": "Log In", "term.about": "About", "term.privateSession": "Private Session", "term.queue": "Queue", + "term.history": "History", "term.search": "Search", "term.library": "Library", "term.listenNow": "Listen Now", @@ -60,6 +61,7 @@ "term.mute": "Mute", "term.unmute": "Unmute", "term.share": "Share", + "term.share.success": "Copied to clipboard", "term.settings": "Settings", "term.seeAll": "See All", "term.sortBy": "Sort By", @@ -86,15 +88,15 @@ "term.connecting": "Connecting", "term.disconnect": "Disconnect", "term.authed": "Authed", - "term.confirm": "Confirm ?", + "term.confirm": "Confirm?", "term.more": "More", "term.less": "Less", "term.showMore": "Show more", "term.showLess": "Show less", - "term.topSongs" : "Top Songs", + "term.topSongs": "Top Songs", "term.latestReleases": "Latest Releases", "term.time.added": "Added", - "term.time.released": "Released", + "term.time.released": "Released", "term.time.updated": "Updated", "term.time.hours": "hours", "term.time.hour": "hour", @@ -121,12 +123,26 @@ "term.equalizer": "Equalizer", "term.reset": "Reset", "term.tracks": "tracks", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videos", + "term.videos": "Videos", "term.menu": "Menu", "term.check": "Check", "term.aboutArtist": "About {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Update Cider", - + "term.topResult": "Top Result", // Search Results + "term.sharedPlaylists": "Shared Playlists", // Search Results + "term.people": "People", // Search Results + "term.newpreset.name": "New EQ Preset Name", // Equalizer Preset + "term.addedpreset": "Added Preset", + "term.deletepreset.warn": "Are you sure you want to delete this preset?", + "term.deletedpreset": "Removed preset", + "term.musicVideos": "Music Videos", // Search page friendlyTypes + "term.stations": "Stations", + "term.curators": "Curators", + "term.appleCurators": "Apple Curators", + "term.radioShows": "Radio Shows", + "term.recordLabels": "Record Labels", + "term.videoExtras": "Video Extras", + "term.top": "Top", + // Home "home.title": "Home", "home.recentlyPlayed": "Recently Played", @@ -136,13 +152,14 @@ "home.madeForYou": "Made For You", "home.friendsListeningTo": "Friends Listening To", "home.followedArtists": "Followed Artists", + // Errors "error.appleMusicSubRequired": "Apple Music requires a subscription.", "error.connectionError": "There was a problem connecting to Apple Music.", "error.noResults": "No Results.", "error.noResults.description": "Try a new search.", - - //Podcasts + + // Podcasts "podcast.followOnCider": "Follow On Cider", "podcast.followedOnCider": "Following On Cider", "podcast.subscribeOnItunes": "Subscribe On iTunes", @@ -151,7 +168,7 @@ "podcast.episodes": "Episodes", "podcast.playEpisode": "Play Episode", "podcast.website": "Podcast Website", - + // Actions "action.addToLibrary": "Add to Library", "action.addToLibrary.success": "Added to Library", @@ -197,33 +214,55 @@ "action.tray.quit": "Quit", "action.tray.show": "Show", "action.update": "Update", - + "action.copy": "Copy", + "action.newpreset": "New Preset...", // Equalizer Preset + "action.deletepreset": "Delete Preset", + // Settings - General "settings.header.general": "General", "settings.header.general.description": "Adjust the general settings for Cider.", "settings.option.general.language": "Language", - + // Language optgroups "settings.option.general.language.main": "Languages", "settings.option.general.language.fun": "Fun Languages", "settings.option.general.language.unsorted": "Unsorted", + + // Update Cider + "settings.option.general.updateCider": "Update Cider", // Button. Refer to term.check for the check button + "settings.option.general.updateCider.branch": "Cider Update Branch", // Dropdown + "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 - Audio "settings.header.audio": "Audio", "settings.header.audio.description": "Adjust the audio settings for Cider.", "settings.option.audio.quality": "Audio Quality", // Dropdown + "settings.header.audio.quality.hireslossless": "Hi-Res Lossless", + "settings.header.audio.quality.hireslossless.description": "up to 24-bit/192 kHz", + "settings.header.audio.quality.lossless": "Lossless", + "settings.header.audio.quality.lossless.description": "up to 24-bit/48 kHz", "settings.header.audio.quality.high": "High", - "settings.header.audio.quality.low": "Low", - "settings.header.audio.quality.auto": "Auto", + "settings.header.audio.quality.high.description": "256 kbps", + "settings.header.audio.quality.standard": "Standard", + "settings.header.audio.quality.standard.description": "64 kbps", "settings.option.audio.seamlessTransition": "Seamless Audio Transition", // Toggle "settings.option.audio.enableAdvancedFunctionality": "Enable Advanced Functionality", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "Enabling AudioContext functionality will allow for extended audio features like Audio Normalization , Equalizers and Visualizers, however on some systems this may cause stuttering in audio tracks.", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Psychoacoustic Enhancements that makes everything sound both richer and more lively | Designed by Maikiwi.", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Strength", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Changes the strength of the processing done to the audio. (Aggressive may yield undesirable results)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Aggressive", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Audio Normalization", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizes peak volume for individual tracks to create a more uniform listening experience.", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Audio Spatialization", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatialize audio and make audio more 3-dimensional (note: This is not Dolby Atmos)", + // Settings - Visual - "settings.header.visual": "Visual", + "settings.header.visual": "Visual", "settings.header.visual.description": "Adjust the visual settings for Cider.", "settings.option.visual.windowBackgroundStyle": "Window Background Style", // Toggle "settings.header.visual.windowBackgroundStyle.none": "None", @@ -242,11 +281,16 @@ "settings.option.visual.animatedWindowBackground": "Animated Window Background", // Toggle "settings.option.visual.hardwareAcceleration": "Hardware Acceleration", // Dropdown "settings.option.visual.hardwareAcceleration.description": "Requires relaunch", - "settings.header.visual.hardwareAcceleration.default": "Default", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "Default", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "Theme", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "Cider", + "settings.option.visual.theme.dark": "Dark", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "Show Personal Info", // Toggle - + // Settings - Lyrics "settings.header.lyrics": "Lyrics", "settings.header.lyrics.description": "Adjust the lyrics settings for Cider.", @@ -254,7 +298,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Enable Karaoke Mode (Musixmatch only)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch Translation Preferred Language", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "Enable Youtube Lyrics for Music Videos", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "Connectivity", "settings.header.connectivity.description": "Adjust the connectivity settings for Cider.", @@ -265,19 +309,21 @@ "settings.header.connectivity.discordRPC.appleMusic": "Display as 'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause", // Toggle "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble Delay (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable Last.fm Now Playing", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (Last.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)", + "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble Delay (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable Last.fm Now Playing", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (Last.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "Experimental", "settings.header.experimental.description": "Adjust the experimental settings for Cider.", "settings.option.experimental.compactUI": "Compact UI", // Toggle "settings.option.experimental.close_button_hide": "Close Button Should Hide the Application", + "settings.option.experimental.copy_log": "Copy logs to clipboard", + "settings.option.experimental.inline_playlists": "Inline Playlists and Albums", + // Refer to term.disabled & term.enabled - // Spatialization Menu "spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.", "spatial.spatialProperties": "Spatial Properties", @@ -298,14 +344,14 @@ "spatial.down": "Down", "spatial.listener": "Listener", "spatial.audioSource": "Audio Source", - + // Settings - Unfinished "settings.header.unfinished": "Unfinished", - + // Web Remote "remote.web.title": "Cider Remote", "remote.web.description": "Scan the QR code to pair your phone up with this Cider instance", - + // About "about.thanks": "Major thanks to the Cider Collective Team and all of our contributors." -} +} \ No newline at end of file diff --git a/src/i18n/es_ES.jsonc b/src/i18n/es_ES.jsonc index 6ad1ee9d..9a0bf149 100644 --- a/src/i18n/es_ES.jsonc +++ b/src/i18n/es_ES.jsonc @@ -1,312 +1,316 @@ { // Base File + // i18n Info + "i18n.languageName": "Español (ES)", // name of language in native language + "i18n.languageNameEnglish": "Spanish (Spain)", // name of language in English + "i18n.category": "main", // main = real language, fun = fun community languages + "i18n.authors": "@j.fl220", // Authors, if you contribute to this file feel free to add your name seperated with a space + + // App info + "app.name": "Cider", + + "date.format": "${d} ${m}, ${y}", + + // Dialogs + "dialog.cancel": "Cancelar", + "dialog.ok": "Aceptar", + + // Notification + "notification.updatingLibrarySongs": "Actualizando canciones de la biblioteca...", + "notification.updatingLibraryAlbums": "Actualizando álbumes de la biblioteca...", + "notification.updatingLibraryArtists": "Actualizando biblioteca de artistas...", + + // Terms + "term.appleInc": "Apple Inc.", + "term.appleMusic": "Apple Music", + "term.applePodcasts": "Apple Podcasts", + "term.itunes": "iTunes", + "term.github": "GitHub", + "term.discord": "Discord", + "term.learnMore": "Leer más", + "term.accountSettings": "Ajustes de la cuenta", + "term.logout": "Cerrar sesión", + "term.login": "Iniciar sesión", + "term.about": "Más información", + "term.privateSession": "Sesión privada", + "term.queue": "En cola", + "term.search": "Buscar", + "term.library": "Biblioteca", + "term.listenNow": "Escuchar", + "term.browse": "Explorar", + "term.radio": "Radio", + "term.recentlyAdded": "Añadido recientemente", + "term.songs": "Canciones", + "term.albums": "Álbumes", + "term.artists": "Artistas", + "term.podcasts": "Podcasts", + "term.playlists": "Playlists", + "term.playlist": "Playlist", + "term.newPlaylist": "Nueva playlist", + "term.newPlaylistFolder": "Nueva carpeta de playlists", + "term.createNewPlaylist": "Crear nueva playlists", + "term.createNewPlaylistFolder": "Crear nueva carpeta de playlists", + "term.deletePlaylist": "¿Está seguro que desea eliminar esta playlist?", + "term.play": "Reproducir", + "term.pause": "Pausar", + "term.previous": "Anterior", + "term.next": "Siguiente", + "term.shuffle": "Aleatorio", + "term.repeat": "Repetir", + "term.volume": "Volumen", + "term.mute": "Silenciar", + "term.unmute": "Desilenciar", + "term.share": "Compartir", + "term.settings": "Ajustes", + "term.seeAll": "Ver todo", + "term.sortBy": "Ordenar por", + "term.sortBy.album": "Álbum", + "term.sortBy.artist": "Artista", + "term.sortBy.name": "Nombre", + "term.sortBy.genre": "Género", + "term.sortBy.releaseDate": "Fecha de lanzamiento", + "term.sortBy.duration": "Duración", + "term.sortOrder": "A-Z", + "term.sortOrder.ascending": "Ascendiente", + "term.sortOrder.descending": "Descendiente", + "term.viewAs": "Ver como", + "term.viewAs.coverArt": "Carátula", + "term.viewAs.list": "Lista", + "term.size": "Tamaño", + "term.size.normal": "Normal", + "term.size.compact": "Compacto", + "term.enable": "Habilitar", + "term.disable": "Deshabilitar", + "term.enabled": "Activado", + "term.disabled": "Desactivado", + "term.connect": "Conectar", + "term.connecting": "Conectando", + "term.disconnect": "Desconectado", + "term.authed": "Autentificado", + "term.confirm": "¿Confirmar?", + "term.more": "Más", + "term.less": "Menos", + "term.showMore": "Mostrar más", + "term.showLess": "Mostrar menos", + "term.topSongs": "Top canciones", + "term.latestReleases": "Últimos lanzamientos", + "term.time.added": "Añadido", + "term.time.released": "Lanzado", + "term.time.updated": "Actualizado", + "term.time.hours": "horas", + "term.time.hour": "hora", + "term.time.minutes": "minutos", + "term.time.minute": "minuto", + "term.time.seconds": "segundos", + "term.time.second": "segundo", + "term.fullscreenView": "Pantalla completa", + "term.defaultView": "Vista por defecto", + "term.audioSettings": "Ajustes de audio", + "term.clearAll": "Borrar todo", + "term.recentStations": "Radios recientes", + "term.language": "Idioma", + "term.funLanguages": "Divertido", + "term.noLyrics": "Cargando... / Letra no encontrada./ Instrumental.", + "term.copyright": "Copyright", + "term.rightsReserved": "Todos los derechos reservados.", + "term.sponsor": "Apoya este proyecto", + "term.ciderTeam": "Equipo Cider", + "term.developer": "Desarrollador", + "term.socialTeam": "Equipo RRSS", + "term.socials": "Redes sociales", + "term.contributors": "Contribuidores", + "term.equalizer": "Equalizador", + "term.reset": "Resetear", + "term.tracks": "canciones", // Assume x amount of tracks. e.g. 50 tracks + "term.videos": "Vídeos", + "term.menu": "Menú", + "term.check": "Comprobar", + "term.aboutArtist": "Más sobre {{artistName}}", // e.g. 'About Doja Cat' + + // Home + "home.title": "Inicio", + "home.recentlyPlayed": "Reproducciones recientes", + "home.recentlyAdded": "Añadido recientemente", + "home.artistsFeed": "Historial de tus artistas", + "home.artistsFeed.noArtist": "Sigue primero a algunos artistas y sus últimos lanzamientos aparecerán aquí", + "home.madeForYou": "Hecho para ti", + "home.friendsListeningTo": "Tus amigos están escuchando", + "home.followedArtists": "Artistas que sigues", + + // Errors + "error.appleMusicSubRequired": "Apple Music necesita una suscripción.", + "error.connectionError": "Ha habido un problema al conectar con Apple Music.", + "error.noResults": "Sin resultados", + "error.noResults.description": "Intenta otra búsqueda.", + + // Podcasts + "podcast.followOnCider": "Seguir en Cider", + "podcast.followedOnCider": "Siguiendo en Cider", + "podcast.subscribeOnItunes": "Suscribirse en iTunes", + "podcast.subscribedOnItunes": "Suscrito en iTunes", + "podcast.itunesStore": "Tienda de iTunes", + "podcast.episodes": "Episodios", + "podcast.playEpisode": "Iniciar Episodio", + "podcast.website": "Pagina del podcast", + + // Actions + "action.addToLibrary": "Añadir a la biblioteca", + "action.addToLibrary.success": "Añadido a la biblioteca", + "action.addToLibrary.error": "Error al añadir a la biblioteca", + "action.removeFromLibrary": "Eliminar de la biblioteca", + "action.removeFromLibrary.success": "Eliminado de la biblioteca", + "action.addToQueue": "Añadir a la cola", + "action.addToQueue.success": "Añadido a la cola", + "action.addToQueue.error": "Error al añadirlo a la cola", + "action.removeFromQueue": "Elimiar de la cola", + "action.removeFromQueue.success": "Eliminado de la cola", + "action.removeFromQueue.error": "Error al eliminarlo de la cola", + "action.createPlaylist": "Crear nueva playlist", + "action.addToPlaylist": "Añadir a la playlist", + "action.removeFromPlaylist": "Eliminar de la playlist", + "action.addToFavorites": "Añadir a favoritos", + "action.follow": "Seguir", + "action.follow.success": "Siguiendo", + "action.follow.error": "Error al seguir", + "action.unfollow": "Dejar de seguir", + "action.unfollow.success": "Has dejado de seguirle", + "action.unfollow.error": "Error al dejar de seguir", + "action.playNext": "Reproducir a continuación", + "action.playLater": "Reproducir al final", + "action.startRadio": "Crear emisora", + "action.goToArtist": "Ir al artista", + "action.goToAlbum": "Mostrar álbum", + "action.moveToTop": "Mover a arriba", + "action.share": "Compartir", + "action.rename": "Renombrar", + "action.love": "Me gusta", + "action.unlove": "Eliminar me gusta", + "action.dislike": "Sugerir menos este estilo", + "action.undoDislike": "Sugerir este estilo", + "action.showWebRemoteQR": "Conexión remota", + "action.playTracksNext": "Reproducir ${app.selectedMediaItems.length} siguiente canción", + "action.playTracksLater": "Reproducir ${app.selectedMediaItems.length} como última canción", + "action.removeTracks": "Eliminar ${self.selectedItems.length} canciones de la cola", + "action.import": "Importar", + "action.export": "Exportar", + "action.showAlbum": "Mostrar álbum completo", + "action.tray.minimize": "Mover a la bandeja", + "action.tray.quit": "Salir", + "action.tray.show": "Abrir", + "action.update": "Actualizar", + + // Settings - General + "settings.header.general": "General", + "settings.header.general.description": "Ajustes generales de Cider.", + "settings.option.general.language": "Idioma", + + // Language optgroups + "settings.option.general.language.main": "Idiomas", + "settings.option.general.language.fun": "Idiomas divertidos", + "settings.option.general.language.unsorted": "Sin clasificar", - // i18n Info - "i18n.languageName": "Español (ES)", // name of language in native language - "i18n.languageNameEnglish": "Spanish (Spain)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@j.fl220", // Authors, if you contribute to this file feel free to add your name seperated with a space + // Update Cider + "settings.option.general.updateCider": "Actualizar Cider", // Button - // App info - "app.name": "Cider", + // Settings - Audio + "settings.header.audio": "Audio", + "settings.header.audio.description": "Ajustes del audio de Cider.", + "settings.option.audio.quality": "Calidad de audio", // Dropdown + "settings.header.audio.quality.high": "Alto", + "settings.header.audio.quality.low": "Bajo", + "settings.header.audio.quality.auto": "Auto", + "settings.option.audio.seamlessTransition": "Transición de audio perfecta", // Toggle + "settings.option.audio.enableAdvancedFunctionality": "Activar funciones avanzadas", // Toggle + "settings.option.audio.enableAdvancedFunctionality.description": "Habilitar la funcionalidad de AudioContext permitirá funciones de audio extendidas como Normalización de audio, Ecualizadores y Visualizadores; sin embargo, en algunos sistemas esto puede causar interrupciones en las canciones.", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizar volumen", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza los picos altos de canciones para hacer la experiencia de escucha mejor.", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Espacialización del audio", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Espacializa más el audio y conviértelo más 3-dimensional (nota: Esto no es Dolby Atmos)", - "date.format": "${d} ${m}, ${y}", - - // Dialogs - "dialog.cancel": "Cancelar", - "dialog.ok": "Aceptar", + // Settings - Visual + "settings.header.visual": "Visual", + "settings.header.visual.description": "Ajustes visuales para Cider.", + "settings.option.visual.windowBackgroundStyle": "Estilo del fondo de la ventana", // Toggle + "settings.header.visual.windowBackgroundStyle.none": "Nada", + "settings.header.visual.windowBackgroundStyle.artwork": "Carátula", + "settings.header.visual.windowBackgroundStyle.image": "Imagen", + "settings.option.visual.animatedArtwork": "Carátula animada", // Dropdown + "settings.header.visual.animatedArtwork.always": "Habilitar siempre", + "settings.header.visual.animatedArtwork.limited": "Limitado a algunas páginas", + "settings.header.visual.animatedArtwork.disable": "Deshabilitar en todas partes", + "settings.option.visual.animatedArtworkQuality": "Calidad de la carátula animada", // Dropdown + "settings.header.visual.animatedArtworkQuality.low": "Bajo", + "settings.header.visual.animatedArtworkQuality.medium": "Medio", + "settings.header.visual.animatedArtworkQuality.high": "Alto", + "settings.header.visual.animatedArtworkQuality.veryHigh": "Muy alto", + "settings.header.visual.animatedArtworkQuality.extreme": "Extrema", + "settings.option.visual.animatedWindowBackground": "Fondo de la ventana animado", // Toggle + "settings.option.visual.hardwareAcceleration": "Aceleración del hardware", // Dropdown + "settings.option.visual.hardwareAcceleration.description": "La app requiere reinicio", + "settings.header.visual.hardwareAcceleration.default": "Por defecto", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + // Refer to term.disabled for the disabled option + "settings.option.visual.showPersonalInfo": "Mostrar información personal", // Toggle - // Notification - "notification.updatingLibrarySongs": "Actualizando canciones de la biblioteca...", - "notification.updatingLibraryAlbums": "Actualizando álbumes de la biblioteca...", - "notification.updatingLibraryArtists": "Actualizando biblioteca de artistas...", - // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "Leer más", - "term.accountSettings": "Ajustes de la cuenta", - "term.logout": "Cerrar sesión", - "term.login": "Iniciar sesión", - "term.about": "Más información", - "term.privateSession": "Sesión privada", - "term.queue": "En cola", - "term.search": "Buscar", - "term.library": "Biblioteca", - "term.listenNow": "Escuchar", - "term.browse": "Explorar", - "term.radio": "Radio", - "term.recentlyAdded": "Añadido recientemente", - "term.songs": "Canciones", - "term.albums": "Álbumes", - "term.artists": "Artistas", - "term.podcasts": "Podcasts", - "term.playlists": "Playlists", - "term.playlist": "Playlist", - "term.newPlaylist": "Nueva playlist", - "term.newPlaylistFolder": "Nueva carpeta de playlists", - "term.createNewPlaylist": "Crear nueva playlists", - "term.createNewPlaylistFolder": "Crear nueva carpeta de playlists", - "term.deletePlaylist": "¿Está seguro que desea eliminar esta playlist?", - "term.play": "Reproducir", - "term.pause": "Pausar", - "term.previous": "Anterior", - "term.next": "Siguiente", - "term.shuffle": "Aleatorio", - "term.repeat": "Repetir", - "term.volume": "Volumen", - "term.mute": "Silenciar", - "term.unmute": "Desilenciar", - "term.share": "Compartir", - "term.settings": "Ajustes", - "term.seeAll": "Ver todo", - "term.sortBy": "Ordenar por", - "term.sortBy.album": "Álbum", - "term.sortBy.artist": "Artista", - "term.sortBy.name": "Nombre", - "term.sortBy.genre": "Género", - "term.sortBy.releaseDate": "Fecha de lanzamiento", - "term.sortBy.duration": "Duración", - "term.sortOrder": "A-Z", - "term.sortOrder.ascending": "Ascendiente", - "term.sortOrder.descending": "Descendiente", - "term.viewAs": "Ver como", - "term.viewAs.coverArt": "Carátula", - "term.viewAs.list": "Lista", - "term.size": "Tamaño", - "term.size.normal": "Normal", - "term.size.compact": "Compacto", - "term.enable": "Habilitar", - "term.disable": "Deshabilitar", - "term.enabled": "Activado", - "term.disabled": "Desactivado", - "term.connect": "Conectar", - "term.connecting": "Conectando", - "term.disconnect": "Desconectado", - "term.authed": "Autentificado", - "term.confirm": "¿Confirmar?", - "term.more": "Más", - "term.less": "Menos", - "term.showMore": "Mostrar más", - "term.showLess": "Mostrar menos", - "term.topSongs" : "Top canciones", - "term.latestReleases": "Últimos lanzamientos", - "term.time.added": "Añadido", - "term.time.released": "Lanzado", - "term.time.updated": "Actualizado", - "term.time.hours": "horas", - "term.time.hour": "hora", - "term.time.minutes": "minutos", - "term.time.minute": "minuto", - "term.time.seconds": "segundos", - "term.time.second": "segundo", - "term.fullscreenView": "Pantalla completa", - "term.defaultView": "Vista por defecto", - "term.audioSettings": "Ajustes de audio", - "term.clearAll": "Borrar todo", - "term.recentStations": "Radios recientes", - "term.language": "Idioma", - "term.funLanguages": "Divertido", - "term.noLyrics": "Cargando... / Letra no encontrada./ Instrumental.", - "term.copyright": "Copyright", - "term.rightsReserved": "Todos los derechos reservados.", - "term.sponsor": "Apoya este proyecto", - "term.ciderTeam": "Equipo Cider", - "term.developer": "Desarrollador", - "term.socialTeam": "Equipo RRSS", - "term.socials": "Redes sociales", - "term.contributors": "Contribuidores", - "term.equalizer": "Equalizador", - "term.reset": "Resetear", - "term.tracks": "canciones", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Vídeos", - "term.menu": "Menú", - "term.check": "Comprobar", - "term.aboutArtist": "Más sobre {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Actualizar Cider", - - // Home - "home.title": "Inicio", - "home.recentlyPlayed": "Reproducciones recientes", - "home.recentlyAdded": "Añadido recientemente", - "home.artistsFeed": "Historial de tus artistas", - "home.artistsFeed.noArtist": "Sigue primero a algunos artistas y sus últimos lanzamientos aparecerán aquí", - "home.madeForYou": "Hecho para ti", - "home.friendsListeningTo": "Tus amigos están escuchando", - "home.followedArtists": "Artistas que sigues", - // Errors - "error.appleMusicSubRequired": "Apple Music necesita una suscripción.", - "error.connectionError": "Ha habido un problema al conectar con Apple Music.", - "error.noResults": "Sin resultados", - "error.noResults.description": "Intenta otra búsqueda.", + // Settings - Lyrics + "settings.header.lyrics": "Letras", + "settings.header.lyrics.description": "Ajuste las letras para Cider", + "settings.option.lyrics.enableMusixmatch": "Habilitar las letras de Musixmatch", // Toggle + "settings.option.lyrics.enableMusixmatchKaraoke": "Habilita el modo Karaoke (solo con Musixmatch)", // Toggle + "settings.option.lyrics.musixmatchPreferredLanguage": "Idioma de traducción por defecto en Musixmatch", // Dropdown + "settings.option.lyrics.enableYoutubeLyrics": "Habilitar las letras de Youtube para los videos con música", // Toggle - //Podcasts - "podcast.followOnCider": "Seguir en Cider", - "podcast.followedOnCider": "Siguiendo en Cider", - "podcast.subscribeOnItunes": "Suscribirse en iTunes", - "podcast.subscribedOnItunes": "Suscrito en iTunes", - "podcast.itunesStore": "Tienda de iTunes", - "podcast.episodes": "Episodios", - "podcast.playEpisode": "Iniciar Episodio", - "podcast.website": "Pagina del podcast", + // Settings - Connectivity + "settings.header.connectivity": "Conectividad", + "settings.header.connectivity.description": "Ajusta la conectividad para Cider.", + "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown + "settings.option.connectivity.playbackNotifications": "Notificaciones de reproducción", // Toggle + // Refer to term.disabled for the disabled option + "settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'", + "settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'", + "settings.option.connectivity.discordRPC.clearOnPause": "Quitar Discord Rich Presence en pausa", // Toggle + "settings.option.connectivity.lastfmScrobble": "Scrobbling Last.fm", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "Delay del Scrobbling en Last.fm (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Habilitar 'Escuchando ahora' en Last.fm", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Eliminar artistas destacados del título de la canción (Last.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrar pista en bucle (Last.fm)", + // Refer to term.connect for the connect button - // Actions - "action.addToLibrary": "Añadir a la biblioteca", - "action.addToLibrary.success": "Añadido a la biblioteca", - "action.addToLibrary.error": "Error al añadir a la biblioteca", - "action.removeFromLibrary": "Eliminar de la biblioteca", - "action.removeFromLibrary.success": "Eliminado de la biblioteca", - "action.addToQueue": "Añadir a la cola", - "action.addToQueue.success": "Añadido a la cola", - "action.addToQueue.error": "Error al añadirlo a la cola", - "action.removeFromQueue": "Elimiar de la cola", - "action.removeFromQueue.success": "Eliminado de la cola", - "action.removeFromQueue.error": "Error al eliminarlo de la cola", - "action.createPlaylist": "Crear nueva playlist", - "action.addToPlaylist": "Añadir a la playlist", - "action.removeFromPlaylist": "Eliminar de la playlist", - "action.addToFavorites": "Añadir a favoritos", - "action.follow": "Seguir", - "action.follow.success": "Siguiendo", - "action.follow.error": "Error al seguir", - "action.unfollow": "Dejar de seguir", - "action.unfollow.success": "Has dejado de seguirle", - "action.unfollow.error": "Error al dejar de seguir", - "action.playNext": "Reproducir a continuación", - "action.playLater": "Reproducir al final", - "action.startRadio": "Crear emisora", - "action.goToArtist": "Ir al artista", - "action.goToAlbum": "Mostrar álbum", - "action.moveToTop": "Mover a arriba", - "action.share": "Compartir", - "action.rename": "Renombrar", - "action.love": "Me gusta", - "action.unlove": "Eliminar me gusta", - "action.dislike": "Sugerir menos este estilo", - "action.undoDislike": "Sugerir este estilo", - "action.showWebRemoteQR": "Conexión remota", - "action.playTracksNext": "Reproducir ${app.selectedMediaItems.length} siguiente canción", - "action.playTracksLater": "Reproducir ${app.selectedMediaItems.length} como última canción", - "action.removeTracks": "Eliminar ${self.selectedItems.length} canciones de la cola", - "action.import": "Importar", - "action.export": "Exportar", - "action.showAlbum": "Mostrar álbum completo", - "action.tray.minimize": "Mover a la bandeja", - "action.tray.quit": "Salir", - "action.tray.show": "Abrir", - "action.update": "Actualizar", + // Settings - Experimental + "settings.header.experimental": "En pruebas", + "settings.header.experimental.description": "Ajustes en pruebas para Cider.", + "settings.option.experimental.compactUI": "Interfaz de usuario compacto", // Toggle + "settings.option.experimental.close_button_hide": "El botón de cerrar minimizará la aplicación en la bandeja", - // Settings - General - "settings.header.general": "General", - "settings.header.general.description": "Ajustes generales de Cider.", - "settings.option.general.language": "Idioma", + // Refer to term.disabled & term.enabled + // Spatialization Menu + "spatial.notTurnedOn": "La espacialización del audio esta desactivada. Para usarlo primero actívelo.", + "spatial.spatialProperties": "Propiedades espaciales", + "spatial.width": "Ancho", + "spatial.height": "Altura", + "spatial.depth": "Profundidad", + "spatial.gain": "Ganancia", + "spatial.roomMaterials": "Material de la habitación", + "spatial.roomDimensions": "Dimensión de la habitación", + "spatial.roomPositions": "Posiciones de la habitación", + "spatial.setDimensions": "Establecer dimensiones", + "spatial.setPositions": "Establecer posiciones", + "spatial.up": "Arriba", + "spatial.front": "Delante", + "spatial.left": "Izquierda", + "spatial.right": "Derecha", + "spatial.back": "Atrás", + "spatial.down": "Abajo", + "spatial.listener": "Oyente", + "spatial.audioSource": "Salida del audio", - // Language optgroups - "settings.option.general.language.main": "Idiomas", - "settings.option.general.language.fun": "Idiomas divertidos", - "settings.option.general.language.unsorted": "Sin clasificar", - - // Settings - Audio - "settings.header.audio": "Audio", - "settings.header.audio.description": "Ajustes del audio de Cider.", - "settings.option.audio.quality": "Calidad de audio", // Dropdown - "settings.header.audio.quality.high": "Alto", - "settings.header.audio.quality.low": "Bajo", - "settings.header.audio.quality.auto": "Auto", - "settings.option.audio.seamlessTransition": "Transición de audio perfecta", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "Activar funciones avanzadas", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Habilitar la funcionalidad de AudioContext permitirá funciones de audio extendidas como Normalización de audio, Ecualizadores y Visualizadores; sin embargo, en algunos sistemas esto puede causar interrupciones en las canciones.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizar volumen", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza los picos altos de canciones para hacer la experiencia de escucha mejor.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Espacialización del audio", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Espacializa más el audio y conviértelo más 3-dimensional (nota: Esto no es Dolby Atmos)", - // Settings - Visual - "settings.header.visual": "Visual", - "settings.header.visual.description": "Ajustes visuales para Cider.", - "settings.option.visual.windowBackgroundStyle": "Estilo del fondo de la ventana", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Nada", - "settings.header.visual.windowBackgroundStyle.artwork": "Carátula", - "settings.header.visual.windowBackgroundStyle.image": "Imagen", - "settings.option.visual.animatedArtwork": "Carátula animada", // Dropdown - "settings.header.visual.animatedArtwork.always": "Habilitar siempre", - "settings.header.visual.animatedArtwork.limited": "Limitado a algunas páginas", - "settings.header.visual.animatedArtwork.disable": "Deshabilitar en todas partes", - "settings.option.visual.animatedArtworkQuality": "Calidad de la carátula animada", // Dropdown - "settings.header.visual.animatedArtworkQuality.low": "Bajo", - "settings.header.visual.animatedArtworkQuality.medium": "Medio", - "settings.header.visual.animatedArtworkQuality.high": "Alto", - "settings.header.visual.animatedArtworkQuality.veryHigh": "Muy alto", - "settings.header.visual.animatedArtworkQuality.extreme": "Extrema", - "settings.option.visual.animatedWindowBackground": "Fondo de la ventana animado", // Toggle - "settings.option.visual.hardwareAcceleration": "Aceleración del hardware", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "La app requiere reinicio", - "settings.header.visual.hardwareAcceleration.default": "Por defecto", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "Mostrar información personal", // Toggle + // Settings - Unfinished + "settings.header.unfinished": "Sin acabar", + "settings.header.unfinished.description": "Ajustes siendo testeados, no están acabados.", - // Settings - Lyrics - "settings.header.lyrics": "Letras", - "settings.header.lyrics.description": "Ajuste las letras para Cider", - "settings.option.lyrics.enableMusixmatch": "Habilitar las letras de Musixmatch", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Habilita el modo Karaoke (solo con Musixmatch)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Idioma de traducción por defecto en Musixmatch", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "Habilitar las letras de Youtube para los videos con música", // Toggle + // Web Remote + "remote.web.title": "Cider Remoto", + "remote.web.description": "Escanee el código QR para emparejar su teléfono con su cliente de Cider", - // Settings - Connectivity - "settings.header.connectivity": "Conectividad", - "settings.header.connectivity.description": "Ajusta la conectividad para Cider.", - "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Notificaciones de reproducción", // Toggle - // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "Mostrar como 'Cider'", - "settings.header.connectivity.discordRPC.appleMusic": "Mostrar como 'Apple Music'", - "settings.option.connectivity.discordRPC.clearOnPause": "Quitar Discord Rich Presence en pausa", // Toggle - "settings.option.connectivity.lastfmScrobble": "Scrobbling Last.fm", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Delay del Scrobbling en Last.fm (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Habilitar 'Escuchando ahora' en Last.fm", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Eliminar artistas destacados del título de la canción (Last.fm)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrar pista en bucle (Last.fm)", - // Refer to term.connect for the connect button - - // Settings - Experimental - "settings.header.experimental": "En pruebas", - "settings.header.experimental.description": "Ajustes en pruebas para Cider.", - "settings.option.experimental.compactUI": "Interfaz de usuario compacto", // Toggle - "settings.option.experimental.close_button_hide": "El botón de cerrar minimizará la aplicación en la bandeja", - // Refer to term.disabled & term.enabled - - // Spatialization Menu - "spatial.notTurnedOn": "La espacialización del audio esta desactivada. Para usarlo primero actívelo.", - "spatial.spatialProperties": "Propiedades espaciales", - "spatial.width": "Ancho", - "spatial.height": "Altura", - "spatial.depth": "Profundidad", - "spatial.gain": "Ganancia", - "spatial.roomMaterials": "Material de la habitación", - "spatial.roomDimensions": "Dimensión de la habitación", - "spatial.roomPositions": "Posiciones de la habitación", - "spatial.setDimensions": "Establecer dimensiones", - "spatial.setPositions": "Establecer posiciones", - "spatial.up": "Arriba", - "spatial.front": "Delante", - "spatial.left": "Izquierda", - "spatial.right": "Derecha", - "spatial.back": "Atrás", - "spatial.down": "Abajo", - "spatial.listener": "Oyente", - "spatial.audioSource": "Salida del audio", - - // Settings - Unfinished - "settings.header.unfinished": "Sin acabar", - "settings.header.unfinished.description": "Ajustes siendo testeados, no están acabados.", - - // Web Remote - "remote.web.title": "Cider Remoto", - "remote.web.description": "Escanee el código QR para emparejar su teléfono con su cliente de Cider", - - // About - "about.thanks": "Muchísimas gracias al equipo de Cider Collective y también a todos nuestros contribuidores." - } + // About + "about.thanks": "Muchísimas gracias al equipo de Cider Collective y también a todos nuestros contribuidores." +} \ No newline at end of file diff --git a/src/i18n/fr_FR.jsonc b/src/i18n/fr_FR.jsonc index 83ecc9e2..cf05144b 100644 --- a/src/i18n/fr_FR.jsonc +++ b/src/i18n/fr_FR.jsonc @@ -1,24 +1,24 @@ { // Base File - // i18n Info - "i18n.languageName": "Français", // name of language in native language + "i18n.languageName": "Français", // name of language in native language "i18n.languageNameEnglish": "French", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages "i18n.authors": "@ErwanGit", // Authors, if you contribute to this file feel free to add your name seperated with a space - + // App info "app.name": "Cider", - + "date.format": "${d} ${m} ${y}", // Dialogs "dialog.cancel": "Annuler", "dialog.ok": "OK", - + // Notification "notification.updatingLibrarySongs": "Mise à jour des chansons de la bibliothèque...", "notification.updatingLibraryAlbums": "Mise à jour des albums de la bibliothèque...", "notification.updatingLibraryArtists": "Mise à jour des artistes de la bibliothèque...", + // Terms "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", @@ -33,6 +33,7 @@ "term.about": "À propos", "term.privateSession": "Session privée", "term.queue": "File d'attente", + "term.history": "Historique", "term.search": "Recherche", "term.library": "Bibliothèque", "term.listenNow": "Écoutez maintenant", @@ -45,6 +46,11 @@ "term.podcasts": "Podcasts", "term.playlists": "Playlists", "term.playlist": "Playlist", + "term.newPlaylist": "Nouvelle Playlist", + "term.newPlaylistFolder": "Nouveau dossier de playlist", + "term.createNewPlaylist": "Créer une nouvelle playlist", + "term.createNewPlaylistFolder": "Create New Playlist Folder", + "term.deletePlaylist": "Êtes-vous sûr de vouloir supprimer cette playlist ?", "term.play": "Lecture", "term.pause": "Pause", "term.previous": "Précédent", @@ -56,6 +62,7 @@ "term.unmute": "Ne plus rendre muet", "term.share": "Partager", "term.settings": "Paramètres", + "term.share.success": "Copié dans le presse-papier", "term.seeAll": "Voir tout", "term.sortBy": "Trier par", "term.sortBy.album": "Album", @@ -86,10 +93,10 @@ "term.less": "Moins", "term.showMore": "Afficher plus", "term.showLess": "Afficher moins", - "term.topSongs" : "Meilleurs titres", + "term.topSongs": "Meilleurs titres", "term.latestReleases": "Dernières sorties", "term.time.added": "Ajouté", - "term.time.released": "Publié", + "term.time.released": "Publié", "term.time.updated": "Mis à jour", "term.time.hours": "heures", "term.time.hour": "heure", @@ -111,14 +118,31 @@ "term.ciderTeam": "Équipe Cider", "term.developer": "Développeur", "term.socialTeam": "Équipe de communication", + "term.socials": "Réseaux sociaux", "term.contributors": "Contributeurs", "term.equalizer": "Égaliseur", "term.reset": "Réinitialiser", "term.tracks": "musiques", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Vidéos", + "term.videos": "Vidéos", "term.menu": "Menu", - "action.showAlbum": "Afficher l'album complet", - + "term.check": "Vérifier", + "term.aboutArtist": "À propos de {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "Meilleurs résultats", // Search Results + "term.sharedPlaylists": "Playlists partagées", // Search Results + "term.people": "Personnes", // Search Results + "term.newpreset.name": "Nouveau nom du préréglage de l'égaliseur", // Equalizer Preset + "term.addedpreset": "Ajout d'un préréglage", + "term.deletepreset.warn": "Êtes-vous sûr de vouloir supprimer ce préréglage ?", + "term.deletedpreset": "Suppression d'un préréglage", + "term.musicVideos": "Vidéos musicales", // Search page friendlyTypes + "term.stations": "Stations", + "term.curators": "Curateurs", + "term.appleCurators": "Curateurs Apple", + "term.radioShows": "Émissions de radio", + "term.recordLabels": "Labels de disques", + "term.videoExtras": "Vidéos bonus", + "term.top": "Top", + // Home "home.title": "Accueil", "home.recentlyPlayed": "Joué récemment", @@ -128,13 +152,14 @@ "home.madeForYou": "Fait pour vous", "home.friendsListeningTo": "Vos amis écoutent", "home.followedArtists": "Artistes suivis", + // Errors "error.appleMusicSubRequired": "Apple Music nécessite un abonnement.", "error.connectionError": "Il y a eu un problème de connexion à Apple Music.", "error.noResults": "Aucun résultat.", "error.noResults.description": "Essayez une nouvelle recherche.", - - //Podcasts + + // Podcasts "podcast.followOnCider": "Suivre sur Cider", "podcast.followedOnCider": "Suivi sur Cider", "podcast.subscribeOnItunes": "Suivre sur iTunes", @@ -143,7 +168,7 @@ "podcast.episodes": "Épisodes", "podcast.playEpisode": "Lire l'épisode", "podcast.website": "Site du podcast", - + // Actions "action.addToLibrary": "Ajouter à la bibliothèque", "action.addToLibrary.success": "Ajouté à la bibliothèque", @@ -156,6 +181,7 @@ "action.removeFromQueue": "Retirer de la file d'attente", "action.removeFromQueue.success": "Retiré de la file d'attente", "action.removeFromQueue.error": "Erreur lors du retrait de la file d'attente", + "action.createPlaylist": "Créer une nouvelle playlist", "action.addToPlaylist": "Ajouter à une playlist", "action.removeFromPlaylist": "Retirer de la playlist", "action.addToFavorites": "Ajouter aux favoris", @@ -183,33 +209,52 @@ "action.removeTracks": "Retirer ${self.selectedItems.length} musiques de la file d'attente", "action.import": "Importer", "action.export": "Exporter", - + "action.showAlbum": "Afficher l'album complet", + "action.tray.minimize": "Réduire dans la barre d'outils", + "action.tray.quit": "Quitter", + "action.tray.show": "Afficher", + "action.update": "Mettre à jour", + "action.copy": "Copier", + "action.newpreset": "Nouveau préréglage...", // Equalizer Preset + "action.deletepreset": "Supprimer le préréglage", + // Settings - General "settings.header.general": "Général", "settings.header.general.description": "Ajuster les paramètres généraux de Cider.", "settings.option.general.language": "Langue", - + // Language optgroups "settings.option.general.language.main": "Langues", "settings.option.general.language.fun": "Langues amusantes", "settings.option.general.language.unsorted": "Non trié", + + // Update Cider + "settings.option.general.updateCider": "Mettre à jour Cider", // Button // Settings - Audio "settings.header.audio": "Audio", "settings.header.audio.description": "Ajuster les paramètres audio de Cider.", "settings.option.audio.quality": "Qualité Audio", // Dropdown + "settings.header.audio.quality.hireslossless": "Lossless haute qualité (Hi-Res)", + "settings.header.audio.quality.hireslossless.description": "(jusqu'à 24 bits/192 kHz)", + "settings.header.audio.quality.lossless": "Lossless", + "settings.header.audio.quality.lossless.description": "(jusqu'à 24 bits/48 kHz)", + "settings.header.audio.quality.enhanced": "Amélioré", "settings.header.audio.quality.high": "Élevée", "settings.header.audio.quality.low": "Faible", "settings.header.audio.quality.auto": "Automatique", "settings.option.audio.seamlessTransition": "Fondu audio transparent", // Toggle "settings.option.audio.enableAdvancedFunctionality": "Activer les fonctions avancées", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "L'activation de la fonctionnalité AudioContext permet d'utiliser des fonctions audio étendues telles que la normalisation du son, les égaliseurs et les visualiseurs. Toutefois, sur certains systèmes, cela peut provoquer des bégaiements dans les pistes audio.", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Moteur de traitement psycho-acoustique Cider", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Un processus de traitement qui fait croire à votre cerveau que les fichiers sont de meilleure qualité.", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalisation du son", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalise le volume maximal des pistes individuelles pour créer une expérience d'écoute plus uniforme.", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spatialisation audio", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spatialiser l'audio et rendre l'audio plus tridimensionnel (note: Ce n'est pas Dolby Atmos)", + // Settings - Visual - "settings.header.visual": "Visuel", + "settings.header.visual": "Visuel", "settings.header.visual.description": "Ajuster les paramètres visuels de Cider.", "settings.option.visual.windowBackgroundStyle": "Style d'arrière-plan de la fenêtre", // Toggle "settings.header.visual.windowBackgroundStyle.none": "Aucun", @@ -228,11 +273,16 @@ "settings.option.visual.animatedWindowBackground": "Arrière-plan de fenêtre animé", // Toggle "settings.option.visual.hardwareAcceleration": "Accélération matérielle", // Dropdown "settings.option.visual.hardwareAcceleration.description": "Nécessite un relancement", - "settings.header.visual.hardwareAcceleration.default": "Défaut", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "Défaut", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "Thème", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "Cider", + "settings.option.visual.theme.dark": "Sombre", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "Afficher vos informations personnelles", // Toggle - + // Settings - Lyrics "settings.header.lyrics": "Paroles", "settings.header.lyrics.description": "Ajuster les paramètres des paroles pour Cider.", @@ -240,7 +290,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Activer le mode karaoké (Musixmatch seulement)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Langue préférée pour les traductions Musixmatch", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "Activer les paroles YouTube pour les vidéos de musique", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "Connectivité", "settings.header.connectivity.description": "Ajuster les paramètres de connectivité de Cider.", @@ -251,23 +301,23 @@ "settings.header.connectivity.discordRPC.appleMusic": "Afficher comme 'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "Désactiver le Discord Rich Presence quand la musique est en pause", // Toggle "settings.option.connectivity.lastfmScrobble": "Scrobble LastFM", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Délai de Scrobble LastFM (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Activer la lecture en cours sur LastFM", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Supprimer les artistes en vedette du titre de la chanson (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrer les titres en boucle (LastFM)", + "settings.option.connectivity.lastfmScrobble.delay": "Délai de Scrobble LastFM (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Activer la lecture en cours sur LastFM", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Supprimer les artistes en vedette du titre de la chanson (LastFM)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrer les titres en boucle (LastFM)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "Expérimental", "settings.header.experimental.description": "Ajuster les paramètres expérimentaux de Cider.", "settings.option.experimental.compactUI": "Interface utilisateur compacte", // Toggle - "settings.option.experimental.closeButtonBehaviour": "Comportement du bouton de fermeture", - "settings.option.experimental.closeButtonBehaviour.quit": "Quitter Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "Réduire dans la barre des tâches", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "Réduire dans la barre d'outils", + "settings.option.experimental.close_button_hide": "Le bouton de fermeture doit masquer l'application", + "settings.option.experimental.copy_log": "Copier les logs dans le presse-papier", + "settings.option.experimental.inline_playlists": "Playlists et albums en ligne", + // Refer to term.disabled & term.enabled - // Spatialization Menu + "spatial.notTurnedOn": "La spatialisation audio est désactivée. Pour l'utiliser, vous devez d'abord l'activer.", "spatial.spatialProperties": "Propriétés spatiales", "spatial.width": "Largeur", "spatial.height": "Hauteur", @@ -289,12 +339,11 @@ // Settings - Unfinished "settings.header.unfinished": "Inachevée", - + // Web Remote - "remote.web.title": "Cider Remote", + "remote.web.title": "Cider à distance", "remote.web.description": "Scanner le QR code pour associer votre téléphone avec cette instance Cider", - + // About "about.thanks": "Un grand merci à l'équipe de la Cider Collective et à tous nos contributeurs." - } - \ No newline at end of file +} \ No newline at end of file diff --git a/src/i18n/hu_HU.jsonc b/src/i18n/hu_HU.jsonc index 005590c3..7f2e65ff 100644 --- a/src/i18n/hu_HU.jsonc +++ b/src/i18n/hu_HU.jsonc @@ -1,28 +1,28 @@ { // Base File - // i18n Info - "i18n.languageName": "Magyar", // name of language in native language + "i18n.languageName": "Magyar", // name of language in native language "i18n.languageNameEnglish": "Hungarian", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@Greenoliv @Rias @BenjaminStonawski", // Authors, if you contribute to this file feel free to add your name seperated with a space + "i18n.authors": "@Greenoliv @Amaru @BenjaminStonawski", // Authors, if you contribute to this file feel free to add your name seperated with a space // App info "app.name": "Cider", - + "date.format": "${m} ${d}, ${y}", - + // Dialogs "dialog.cancel": "Mégsem", "dialog.ok": "OK", - + // Notification "notification.updatingLibrarySongs": "Zenekönyvtár frissítése...", "notification.updatingLibraryAlbums": "Albumok frissítése...", "notification.updatingLibraryArtists": "Előadók frissítése...", + // Terms "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", + "term.applePodcasts": "Apple Podcastok", "term.itunes": "iTunes", "term.github": "GitHub", "term.discord": "Discord", @@ -46,9 +46,9 @@ "term.playlists": "Lejátszási listák", "term.playlist": "Lejátszási lista", "term.newPlaylist": "Új lejátszási lista", - "term.newPlaylistFolder": "Új lejátszási lista mappa", + "term.newPlaylistFolder": "Új mappa", "term.createNewPlaylist": "Új lejátszási lista létrehozása", - "term.createNewPlaylistFolder": "Új lejátszási lista mappa létrehozása", + "term.createNewPlaylistFolder": "Új mappa létrehozása", "term.deletePlaylist": "Biztosan szeretné törölni a lejátszási listát?", "term.play": "Lejátszás", "term.pause": "Megállítás", @@ -60,6 +60,7 @@ "term.mute": "Némítás", "term.unmute": "Némítás feloldása", "term.share": "Megosztás", + "term.share.success": "Másolva a vágólapra", "term.settings": "Beállítások", "term.seeAll": "Összes", "term.sortBy": "Rendezés", @@ -91,10 +92,10 @@ "term.less": "Kevesebb", "term.showMore": "Mutass többet", "term.showLess": "Mutass kevesebbet", - "term.topSongs" : "A legjobb dalok", + "term.topSongs": "A legjobb dalok", "term.latestReleases": "Új megjelenések", "term.time.added": "Hozzáadva", - "term.time.released": "Kiadva", + "term.time.released": "Kiadva", "term.time.updated": "Frissítve", "term.time.hours": "óra", "term.time.hour": "óra", @@ -104,45 +105,60 @@ "term.time.second": "másodperc", "term.fullscreenView": "Teljes képernyős mód", "term.defaultView": "Alapértelmezett nézet", - "term.spacializedAudioSetting": "Térbeli hangzás", + "term.spacializedAudioSetting": "Térbeli hang", "term.clearAll": "Összes törlése", "term.recentStations": "Nemrég játszott", "term.language": "Nyelv", - "term.funLanguages": "Mókás", + "term.funLanguages": "Fantázianyelvek", "term.noLyrics": "Betöltés... / Dalszöveg nem található. / Instrumentális.", "term.copyright": "Szerzői jog", "term.rightsReserved": "Minden jog fenntartva.", "term.sponsor": "Támogasd a projektet", "term.ciderTeam": "A Cider csapata", "term.developer": "Fejlesztő", - "term.socialTeam": "Szociális csapat", + "term.socialTeam": "Közösségi csapat", "term.socials": "Szociális", - "term.contributors": "Közreműködők", + "term.contributors": "Hozzájárulók", "term.equalizer": "Hangszínszabályozó", "term.reset": "Visszaállítás", "term.tracks": "zeneszám", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videók", + "term.videos": "Videók", "term.menu": "Menü", - "term.check": "Bejelöl", - "term.aboutArtist": "További információ {{artistName}} előadóról", // e.g. 'About Doja Cat' - "term.updateCider": "Cider frissítése", - + "term.check": "Ellenőrzés", + "term.aboutArtist": "About {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "Legjobb találatok", // Search Results + "term.sharedPlaylists": "Megosztott lejátszási listák", // Search Results + "term.people": "Profilok", // Search Results + "term.newpreset.name": "New EQ Preset Name", // Equalizer Preset + "term.addedpreset": "Preset hozzáadva", + "term.deletepreset.warn": "Are you sure you want to delete this preset?", + "term.deletedpreset": "Preset törölve", + "term.musicVideos": "Videóklipek", // Search page friendlyTypes + "term.stations": "Állomások", + "term.curators": "Curators", + "term.appleCurators": "Apple Curators", + "term.radioShows": "Radio Shows", + "term.recordLabels": "Record Labels", + "term.videoExtras": "Videóextrák", + "term.top": "Top", + // Home "home.title": "Kezdőlap", "home.recentlyPlayed": "Nemrég játszott", "home.recentlyAdded": "Nemrég hozzáadott", "home.artistsFeed": "Az előadóid feedje", - "home.artistsFeed.noArtist": "Kövess néhány előadót, hogy a legújabb zenéi itt megjelenhessenek.", + "home.artistsFeed.noArtist": "Kövess néhány előadót, hogy a legújabb zenéik itt megjelenjenek", "home.madeForYou": "Személyre szabva", "home.friendsListeningTo": "A barátaid épp ezt hallgatják", "home.followedArtists": "Követett előadók", + // Errors "error.appleMusicSubRequired": "Apple Music előfizetés szükséges.", "error.connectionError": "Hiba történt az Apple Musichoz való csatlakozás közben.", "error.noResults": "Nincs találat", "error.noResults.description": "Próbálkozzon új kereséssel", - - //Podcasts + + // Podcasts "podcast.followOnCider": "Követés a Cideren", "podcast.followedOnCider": "Követve a Cideren", "podcast.subscribeOnItunes": "Feliratkozás az iTunesban", @@ -151,13 +167,13 @@ "podcast.episodes": "Epizódok", "podcast.playEpisode": "Epizód lejátszása", "podcast.website": "Podcast weboldala", - + // Actions - "action.addToLibrary": "Hozzáadás a könyvtárhoz", - "action.addToLibrary.success": "Hozzáadva a könyvtárhoz", + "action.addToLibrary": "Hozzáadás a Könyvtárhoz", + "action.addToLibrary.success": "Hozzáadva a Könyvtárhoz", "action.addToLibrary.error": "Hiba a hozzáadáskor.", "action.removeFromLibrary": "Törlés a Könytárból", - "action.removeFromLibrary.success": "Törölve a könyvtárból", + "action.removeFromLibrary.success": "Törölve a Könyvtárból", "action.addToQueue": "Hozzáadás a várólistához", "action.addToQueue.success": "Hozzáadva a várólistához", "action.addToQueue.error": "Sikertelen hozzáadás a várólistához", @@ -182,51 +198,69 @@ "action.moveToTop": "Mozgatás legfelülre", "action.share": "Megosztás", "action.rename": "Átnevezés", - "action.love": "Kedvelés", - "action.unlove": "Kedvelés visszavonása", - "action.dislike": "Nem kedvelem", - "action.undoDislike": "Nem kedvelés visszavonása", - "action.showWebRemoteQR": "Távirányító QR kód megjelenítése", + "action.love": "Szeretem", + "action.unlove": "Mégsem szeretem", + "action.dislike": "Kevesebb ilyen javasolása", + "action.undoDislike": "A Kevesebb ilyen javasolása visszavonása", + "action.showWebRemoteQR": "Távirányító QR kód", "action.playTracksNext": "${app.selectedMediaItems.length} zenék lejátszása következőnek", "action.playTracksLater": "${app.selectedMediaItems.length} zenék lejátszása később", "action.removeTracks": "${self.selectedItems.length} zenék eltávolítása a várólistáról", "action.import": "Importálás", "action.export": "Exportálás", "action.showAlbum": "Teljes album megjelenítése", - // Waiting on Core for moving plugin to app.ts "action.tray.minimize": "Kicsinyítés a tálcára", "action.tray.quit": "Kilépés", "action.tray.show": "Megjelenítés", - + "action.update": "Frissítés", + "action.copy": "Másolás", + "action.newpreset": "Új Preset...", // Equalizer Preset + "action.deletepreset": "Preset törlése", + // Settings - General "settings.header.general": "Általános", - "settings.header.general.description": "A Cider általános beállításainak módosítása", + "settings.header.general.description": "A Cider általános beállításainak módosítása.", "settings.option.general.language": "Nyelv", - + // Language optgroups "settings.option.general.language.main": "Nyelvek", - "settings.option.general.language.fun": "Mókás nyelvek", - "settings.option.general.language.unsorted": "Nem besorolható", + "settings.option.general.language.fun": "Fantázianyelvek", + "settings.option.general.language.unsorted": "Azonosítatlan", + + // Update Cider + "settings.option.general.updateCider": "A Cider frissítése", // Button // Settings - Audio "settings.header.audio": "Hang", - "settings.header.audio.description": "A Cider hangbeállításainak módosítása", + "settings.header.audio.description": "A Cider hangbeállításainak módosítása.", "settings.option.audio.quality": "Hangminőség", // Dropdown - "settings.header.audio.quality.high": "Magas", - "settings.header.audio.quality.low": "Alacsony", - "settings.header.audio.quality.auto": "Automatikus", + "settings.header.audio.quality.hireslossless": "Nagy felbontású veszteségmentes", + "settings.header.audio.quality.hireslossless.description": "max. 24-bit/192 kHz sebességen", + "settings.header.audio.quality.lossless": "Veszteségmentes", + "settings.header.audio.quality.lossless.description": "max. up to 24-bit/48 kHz sebességen", + "settings.header.audio.quality.high": "High", + "settings.header.audio.quality.high.description": "256 kbps", + "settings.header.audio.quality.standard": "Standard", + "settings.header.audio.quality.standard.description": "64 kbps", "settings.option.audio.seamlessTransition": "Szünetmentes lejátszás", // Toggle "settings.option.audio.enableAdvancedFunctionality": "Haladó funkcionalitás engedélyezése", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "Az AudioContext funkció engedélyezése lehetővé teszi a fejlettebb hangfunkciókat, például a normalizásást, a hangszínszabályozót és a vizualizáció funkciókat, azonban egyes számítógépeken ez akadozást okozhat a hangsávokban.", + "settings.option.audio.enableAdvancedFunctionality.description": "Az AudioContext funkció engedélyezése lehetővé teszi a fejlettebb hangfunkciókat, például a Normalizásást, az Equalizereket és a Visualizer funkciókat, azonban egyes számítógépeken ez akadozást okozhat a hangsávokban.", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Pszichoakusztikus Módosítások amik minden hangot felerősítenek és ütősebbé tesznek | Készítette Maikiwi", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Erősség", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Megváltoztatja a hangra végzett feldolgozás erősségét. (Az Agresszív mód nemkívánatos eredményeket hozhat!)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Szokásos", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Agresszív", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizálás", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizálja az egyes zeneszámok hangosabb részeit, hogy egységesebb hallgatási élményt hozzon létre.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Térbeli hangzás", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Térbeli hangzás és a hang háromdimenziósabbá tétele (Ez nem összekeverendő a Dolby Atmos-szal!)", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Térbeli hang", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Térbeli hang és a hang háromdimenziósabbá tétele (Ez nem összekeverendő a Dolby Atmos-szal!)", + // Settings - Visual - "settings.header.visual": "Vizuális", + "settings.header.visual": "Vizuális", "settings.header.visual.description": "A Cider vizuális beállításainak módosítása.", "settings.option.visual.windowBackgroundStyle": "Ablak háttér stílusa", // Toggle - "settings.header.visual.windowBackgroundStyle.none": "Egyik sem", + "settings.header.visual.windowBackgroundStyle.none": "Sehol", "settings.header.visual.windowBackgroundStyle.artwork": "Borító", "settings.header.visual.windowBackgroundStyle.image": "Kép", "settings.option.visual.animatedArtwork": "Animált borító", // Dropdown @@ -242,45 +276,52 @@ "settings.option.visual.animatedWindowBackground": "Animált ablakháttér", // Toggle "settings.option.visual.hardwareAcceleration": "Hardveres gyorsítás", // Dropdown "settings.option.visual.hardwareAcceleration.description": "Újraindítás szükséges", - "settings.header.visual.hardwareAcceleration.default": "Alap", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "Alap", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "Téma", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "Cider", + "settings.option.visual.theme.dark": "Sötét", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "Személyes adatok mutatása", // Toggle - + // Settings - Lyrics "settings.header.lyrics": "Dalszöveg", "settings.header.lyrics.description": "A Cider dalszöveg beállításainak módosítása.", "settings.option.lyrics.enableMusixmatch": "MusixMatch dalszövegek engedélyezése", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "Karaoke mód bekapcsolása (Csak MusixMatch esetén)", // Toggle + "settings.option.lyrics.enableMusixmatchKaraoke": "Karaoke mód bekapcsolása (Csak MusixMatch)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "MusixMatch fordítás nyelve", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "YouTube dalszövegek engedélyezése a zenei videóknál", // Toggle - + // Settings - Connectivity - "settings.header.connectivity": "Csatlakozhatóságok", + "settings.header.connectivity": "Csatlakozások", "settings.header.connectivity.description": "A Cider csatlakozás beállításainak módosítása.", "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown - "settings.option.connectivity.playbackNotifications": "Értesítés új dal lejátszásakor", // Toggle + "settings.option.connectivity.playbackNotifications": "Lejátszás értesítések", // Toggle // Refer to term.disabled for the disabled option "settings.header.connectivity.discordRPC.cider": "Megjelenítés 'Cider'-ként", "settings.header.connectivity.discordRPC.appleMusic": "Megjelenítés 'Apple Music'-ként", "settings.option.connectivity.discordRPC.clearOnPause": "Discord Rich Presence törlése megállításnál", // Toggle "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble Késleltetés (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "LastFM Now Playing engedélyezése", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "A közreműködő előadók eltávolítása a dal címéből (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Loopolt zeneszám szűrése (LastFM)", + "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble Késleltetés (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "LastFM Now Playing engedélyezése", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (LastFM)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Loopolt zeneszám szűrése (LastFM)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "Kísérleti", "settings.header.experimental.description": "A Cider kísérleti beállításainak módosítása.", "settings.option.experimental.compactUI": "Kompakt UI", // Toggle "settings.option.experimental.close_button_hide": "A bezárás gomb rejtse el az alkalmazást", + "settings.option.experimental.copy_log": "Napló másolása a vágólapra", + "settings.option.experimental.inline_playlists": "Inline Playlists and Albums", + // Refer to term.disabled & term.enabled - // Spatialization Menu "spatial.notTurnedOn": "A térbeli hangzás ki van kapcsolva, használatához kapcsolja be.", - "spatial.spatialProperties": "Térbeli hangzás", + "spatial.spatialProperties": "Térbeli hang", "spatial.width": "Szélesség", "spatial.height": "Magasság", "spatial.depth": "Hosszúság", @@ -301,11 +342,11 @@ // Settings - Unfinished "settings.header.unfinished": "Befejezetlen", - + // Web Remote "remote.web.title": "Cider Remote", "remote.web.description": "Olvasd be ezt a QR-kódot a telefonoddal, hogy tudd vezérelni a lejátszót.", - + // About - "about.thanks": "Köszönet a Cider Collective csapatának és minden közreműködőnek." -} + "about.thanks": "Köszönet a Cider Collective csapatának és minden hozzájárulónak." +} \ No newline at end of file diff --git a/src/i18n/ja_JP.jsonc b/src/i18n/ja_JP.jsonc index 8c178de1..7b31f748 100644 --- a/src/i18n/ja_JP.jsonc +++ b/src/i18n/ja_JP.jsonc @@ -1,24 +1,24 @@ { - // App info - "app.name": "Cider", - - "date.format": "${y}年${m}月${d}日", - - // i18n Info - "i18n.languageName": "日本語", // name of language in native language + // i18n Info + "i18n.languageName": "日本語", // name of language in native language "i18n.languageNameEnglish": "Japanese", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space + // App info + "app.name": "Cider", + + "date.format": "${y}年${m}月${d}日", + // Dialogs "dialog.cancel": "キャンセル", "dialog.ok": "OK", - + // Notification "notification.updatingLibrarySongs": "ライブラリの更新中...", "notification.updatingLibraryAlbums": "ライブラリの更新中...", "notification.updatingLibraryArtists": "ライブラリの更新中...", - + // Terms "term.appleMusic": "Apple Music", // Follows brand term "term.applePodcasts": "Apple Podcasts", // Follows brand term @@ -85,10 +85,10 @@ "term.less": "減らす", "term.showMore": "もっと見る", "term.showLess": "表示数を少なくする", - "term.topSongs" : "トップソング", + "term.topSongs": "トップソング", "term.latestReleases": "ニューリリース", "term.time.added": "追加日", - "term.time.released": "配信開始日", + "term.time.released": "配信開始日", "term.time.updated": "最終更新日", "term.time.hours": "時間", "term.time.hour": "時間", @@ -114,12 +114,11 @@ "term.equalizer": "イコライザー", "term.reset": "リセット", "term.tracks": "曲", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "ビデオ", + "term.videos": "ビデオ", "term.menu": "メニュー", "term.check": "確認", "term.aboutArtist": "{{artistName}}について", // e.g. 'About Doja Cat' - "term.updateCider": "Cider 更新", - + // Home "home.title": "ホーム", "home.recentlyPlayed": "最近の再生", @@ -129,6 +128,7 @@ "home.madeForYou": "あなたにおすすめ", "home.friendsListeningTo": "友達が聴いている", "home.followedArtists": "フォローしているアーティスト", + // Errors "error.appleMusicSubRequired": "Apple Musicのサブスクリプションが必要です。", "error.connectionError": "Apple Musicに接続できません。", @@ -144,7 +144,7 @@ "podcast.episodes": "番組", "podcast.playEpisode": "再生", "podcast.website": "Podcast ウェブ", - + // Actions "action.addToLibrary": "ライブラリに追加", "action.addToLibrary.success": "ライブラリに追加されました", @@ -189,21 +189,36 @@ "action.tray.quit": "終了", "action.tray.show": "表示", "action.update": "アップデート", - + "action.copy": "コピー", + "action.newpreset": "ニュープリセット", // Equalizer Preset + "action.deletepreset": "プリセットを削除", // Equalizer Preset + // Settings - Audio "settings.header.audio": "オーディオ", "settings.header.audio.description": "Ciderのオーディオ設定", "settings.option.audio.quality": "音質", // Dropdown + "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.low": "高効率", + "settings.header.audio.quality.standard": "高効率", "settings.header.audio.quality.auto": "自動", "settings.option.audio.seamlessTransition": "曲間なしで再生", // Toggle "settings.option.audio.enableAdvancedFunctionality": "先進的な機能", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "AudioContext 機能を有効にすると、オーディオノーマライズ、空間オーディオ、イコライザーなどの機能を使用できますが、音が途切れるかもしれません。", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider AEP™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "圧縮音源を高解像度に処理することによって、ロスレス相当の音質に向上させます。", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "AEPの強さ", // Toggle + "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": "オーディオノーマライズ", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "さまざまな曲の音量を均一にし、より整った音を楽しめるようにする機能です。", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "オーディオ空間化", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "オーディオを空間に分散させる機能です。 (ドルビーアトモスではありません)", + // Settings - Visual "settings.header.visual": "ビジュアル", "settings.header.visual.description": "Ciderのビジュアル設定", @@ -223,10 +238,11 @@ "settings.option.visual.animatedWindowBackground": "アプリウィンドウの背景をアニメーション化", // Toggle "settings.option.visual.hardwareAcceleration": "ハードウェア アクセラレーション", // Dropdown "settings.option.visual.hardwareAcceleration.description": "アプリを再起動する必要があります", - "settings.header.visual.hardwareAcceleration.default": "既定", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "既定", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "プロフィールを表示", // Toggle + // Settings - General (Reserved) "settings.header.general": "一般", "settings.header.general.description": "Ciderの一般設定", @@ -238,7 +254,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "カラオケモードを有効にする (Musixmatchのみ)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "歌詞の優先言語", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "YouTubeの歌詞をミュージックビデオに使用する", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "アプリと連携", "settings.header.connectivity.description": "Ciderの連携設定", @@ -248,46 +264,48 @@ "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music' を表示する", "settings.option.connectivity.discordRPC.clearOnPause": "一時停止時にDiscord Rich Presenceをクリアする", // Toggle "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling", // Option to Connect - "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.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)", // Refer to term.connect for the connect button + // Settings - General - Update Cider + "settings.option.general.updateCider": "Cider 更新", // Button + // Settings - Experimental "settings.header.experimental": "試験的な機能", "settings.header.experimental.description": "開発中の実験的な機能は不完全で不安定である可能性があります", "settings.option.experimental.compactUI": "コンパクトインターフェース", // Toggle "settings.option.experimental.close_button_hide": "「閉じる」ボタンでアプリを隠します", // Dropdown - // Refer to term.disabled & term.enabled + // Refer to term.disabled & term.enabled // Spatialization Menu - "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" : "音源", - + "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 - Unfinished "settings.header.unfinished": "未完成", - + // Web Remote "remote.web.title": "Cider リモート", "remote.web.description": "QRコードを使用して、Ciderとスマートフォンをペアリングする", - + //About "about.thanks": "Cider Collective とご協力いただいた貢献者様に感謝申し上げます。" - -} +} \ No newline at end of file diff --git a/src/i18n/ko_KR.jsonc b/src/i18n/ko_KR.jsonc index 76d94149..b821d188 100644 --- a/src/i18n/ko_KR.jsonc +++ b/src/i18n/ko_KR.jsonc @@ -1,40 +1,41 @@ { // Base File - // i18n Info - "i18n.languageName": "한국어", // name of language in native language - "i18n.languageNameEnglish": "Korean", // name of language in English + "i18n.languageName": "한국어 (KR)", // name of language in native language + "i18n.languageNameEnglish": "Korean (KR)", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@sj8923", // Authors, if you contribute to this file feel free to add your name seperated with a space - + "i18n.authors": "@Hazealign", // Authors, if you contribute to this file feel free to add your name seperated with a space + // App info "app.name": "Cider", - - "date.format": "${y}년 ${m}월 ${d}일", + + "date.format": "${y}. ${m}. ${d}", // Dialogs "dialog.cancel": "취소", "dialog.ok": "확인", - + // Notification - "notification.updatingLibrarySongs": "라이브러리 곡 업데이트 중...", - "notification.updatingLibraryAlbums": "라이브러리 앨범 업데이트 중...", - "notification.updatingLibraryArtists": "라이브러리 아티스트 업데이트 중...", + "notification.updatingLibrarySongs": "라이브러리의 노래를 업데이트하는 중입니다...", + "notification.updatingLibraryAlbums": "라이브러리의 앨범을 업데이트하는 중입니다...", + "notification.updatingLibraryArtists": "라이브러리의 아티스트를 업데이트하는 중입니다...", + // Terms - "term.appleInc": "Apple Inc.", - "term.appleMusic": "Apple Music", - "term.applePodcasts": "Apple Podcasts", - "term.itunes": "iTunes", - "term.github": "GitHub", - "term.discord": "Discord", - "term.learnMore": "더보기", + "term.appleInc": "Apple Inc.", // Follows brand term + "term.appleMusic": "Apple Music", // Follows brand term + "term.applePodcasts": "Apple Podcasts", // Follows brand term + "term.itunes": "iTunes", // Follows brand term + "term.github": "GitHub", // Follows brand term + "term.discord": "Discord", // Follows brand term + "term.learnMore": "더 알아보기", "term.accountSettings": "계정 설정", "term.logout": "로그아웃", "term.login": "로그인", "term.about": "정보", "term.privateSession": "개인 세션", "term.queue": "대기열", + "term.history": "청취 기록", "term.search": "검색", - "term.library": "라이브러리", + "term.library": "보관함", "term.listenNow": "지금 듣기", "term.browse": "둘러보기", "term.radio": "라디오", @@ -43,76 +44,77 @@ "term.albums": "앨범", "term.artists": "아티스트", "term.podcasts": "팟캐스트", - "term.playlists": "플레이리스트", - "term.playlist": "플레이리스트", - "term.newPlaylist": "새 플레이리스트", - "term.newPlaylistFolder": "새 플레이리스트 폴더", - "term.createNewPlaylist": "새 플레이리스트 만들기", - "term.createNewPlaylistFolder": "새 플레이리스트 폴더 만들기", - "term.deletePlaylist": "정말 플레이리스트를 삭제하시겠습니까?", + "term.playlists": "재생 목록", + "term.playlist": "재생 목록", + "term.newPlaylist": "새 재생 목록", + "term.newPlaylistFolder": "새 재생 목록 폴더", + "term.createNewPlaylist": "새 재생 목록 만들기", + "term.createNewPlaylistFolder": "새 재생 목록 폴더 만들기", + "term.deletePlaylist": "정말로 이 재생 목록을 삭제하시겠습니까?", "term.play": "재생", - "term.pause": "정지", + "term.pause": "일시 정지", "term.previous": "이전", "term.next": "다음", "term.shuffle": "셔플", - "term.repeat": "반복재생", + "term.repeat": "반복", "term.volume": "볼륨", "term.mute": "음소거", "term.unmute": "음소거 해제", "term.share": "공유", + "term.share.success": "클립보드에 복사됨", "term.settings": "설정", "term.seeAll": "모두 보기", - "term.sortBy": "정렬방식", - "term.sortBy.album": "앨범", - "term.sortBy.artist": "아티스트", - "term.sortBy.name": "이름", + "term.sortBy": "정렬", + "term.sortBy.album": "앨범명", + "term.sortBy.artist": "아티스트 이름", + "term.sortBy.name": "제목", "term.sortBy.genre": "장르", - "term.sortBy.releaseDate": "출시일", - "term.sortBy.duration": "재생시간", - "term.sortOrder": "ㄱ-ㅎ", + "term.sortBy.releaseDate": "발매일", + "term.sortBy.duration": "길이", + "term.sortOrder": "A-Z", "term.sortOrder.ascending": "오름차순", "term.sortOrder.descending": "내림차순", - "term.viewAs": "표시방식", - "term.viewAs.coverArt": "커버아트", + "term.viewAs": "표시", + "term.viewAs.coverArt": "커버 아트", "term.viewAs.list": "리스트", "term.size": "크기", - "term.size.normal": "일반", + "term.size.normal": "표준", "term.size.compact": "컴팩트", - "term.enable": "활성화", - "term.disable": "비활성화", - "term.enabled": "활성화", - "term.disabled": "비활성화", + "term.enable": "켜기", + "term.disable": "끄기", + "term.enabled": "켜짐", + "term.disabled": "꺼짐", "term.connect": "연결", "term.connecting": "연결 중", - "term.disconnect": "연결 끊김", + "term.disconnect": "연결 해제", "term.authed": "인증됨", - "term.confirm": "확인하시겠습니까 ?", - "term.more": "더", - "term.less": "적게", + "term.confirm": "진행하시겠습니까?", + "term.more": "추가", + "term.less": "줄이기", "term.showMore": "더 보기", - "term.showLess": "적게 보기", - "term.topSongs" : "인기곡", - "term.latestReleases": "최신곡", - "term.time.added": "추가", - "term.time.released": "발매일", - "term.time.updated": "업데이트일", + "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.fullscreenView": "전체 화면 보기", + "term.defaultView": "윈도우 보기", "term.audioSettings": "오디오 설정", - "term.clearAll": "비우기", + "term.clearAll": "모두 지우기", "term.recentStations": "최근 스테이션", "term.language": "언어", - "term.funLanguages": "재미있는", - "term.noLyrics": "불러오는 중... / 가사를 찾을 수 없습니다/ 연주곡", - "term.copyright": "Copyright", // Used in Korea w/o translation + "term.funLanguages": "재미를 위한 언어", + "term.noLyrics": "로딩 중... / 가사를 찾지 못했습니다. / Instrumental 곡일 수 있습니다.", + "term.copyright": "저작권", "term.rightsReserved": "All Rights Reserved.", - "term.sponsor": "이 프로젝트를 후원하세요", + "term.sponsor": "이 프로젝트를 후원하기", "term.ciderTeam": "Cider 팀", "term.developer": "개발자", "term.socialTeam": "소셜 팀", @@ -120,56 +122,71 @@ "term.contributors": "기여자", "term.equalizer": "이퀄라이저", "term.reset": "초기화", - "term.tracks": "트랙", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "비디오", + "term.tracks": "곡", // Assume x amount of tracks. e.g. 50 tracks + "term.videos": "비디오", "term.menu": "메뉴", "term.check": "확인", - "term.aboutArtist": "{{artistName}}에 대해", // e.g. 'About Doja Cat' - "term.updateCider": "Cider 업데이트", - + "term.aboutArtist": "{{artistName}}에 대하여", // e.g. 'About Doja Cat' + "term.topResult": "Top Result", // Search Results + "term.sharedPlaylists": "공유 플레이리스트", // Search Results + "term.people": "프로필", // Search Results + "term.newpreset.name": "새 이퀄라이저 프리셋", // Equalizer Preset + "term.addedpreset": "추가된 프리셋", + "term.deletepreset.warn": "정말로 프리셋을 삭제하시겠습니까?", + "term.deletedpreset": "프리셋 삭제", + "term.musicVideos": "뮤직 비디오", // Search page friendlyTypes + "term.stations": "스테이션", + "term.curators": "큐레이터", + "term.appleCurators": "애플 큐레이터", + "term.radioShows": "라디오 쇼", + "term.recordLabels": "레코드 레이블", + "term.videoExtras": "추가 비디오", + "term.top": "Top", + // Home "home.title": "홈", - "home.recentlyPlayed": "최근 재생된 항목", + "home.recentlyPlayed": "최근 재생한 항목", "home.recentlyAdded": "최근 추가된 항목", - "home.artistsFeed": "내 아티스트 피드", - "home.artistsFeed.noArtist": "아티스트를 팔로우하면 최근 발매곡이 표시됩니다", + "home.artistsFeed": "아티스트 피드", + "home.artistsFeed.noArtist": "좋아하는 아티스트를 팔로우해보세요.", "home.madeForYou": "나만을 위한 추천", - "home.friendsListeningTo": "친구들이 듣는", + "home.friendsListeningTo": "친구가 듣는 음악", "home.followedArtists": "팔로우한 아티스트", + // Errors - "error.appleMusicSubRequired": "애플뮤직 구독이 필요합니다.", - "error.connectionError": "애플뮤직 연결에 문제가 발생했습니다.", - "error.noResults": "결과 없음.", - "error.noResults.description": "새로 검색해주세요.", - - //Podcasts - "podcast.followOnCider": "Cider 팔로우", - "podcast.followedOnCider": "Cider 팔로우됨", - "podcast.subscribeOnItunes": "iTunes 구독하기", - "podcast.subscribedOnItunes": "iTunes 구독 중", - "podcast.itunesStore": "iTunes 스토어", - "podcast.episodes": "에피소드", - "podcast.playEpisode": "에피소드 재생", - "podcast.website": "팟캐스트 웹사이트", - + "error.appleMusicSubRequired": "Apple Music은 구독을 필요로 합니다.", + "error.connectionError": "Apple Music에 연결하지 못했습니다.", + "error.noResults": "결과 없음", + "error.noResults.description": "다시 시도해주세요.", + + // Podcasts + "podcast.followOnCider": "Cider에서 팔로우하기", + "podcast.followedOnCider": "팔로우 중", + "podcast.subscribeOnItunes": "iTunes에서 구독", + "podcast.subscribedOnItunes": "구독 중", + "podcast.itunesStore": "iTunes Store", + "podcast.episodes": "방송", + "podcast.playEpisode": "재생", + "podcast.website": "팟캐스트 사이트", + // Actions "action.addToLibrary": "보관함에 추가", "action.addToLibrary.success": "보관함에 추가됨", - "action.addToLibrary.error": "보관함에 추가 실패", + "action.addToLibrary.error": "보관함에 추가하는데 실패함", "action.removeFromLibrary": "보관함에서 삭제", "action.removeFromLibrary.success": "보관함에서 삭제됨", "action.addToQueue": "대기열에 추가", "action.addToQueue.success": "대기열에 추가됨", - "action.addToQueue.error": "대기열에 추가 실패", + "action.addToQueue.error": "대기열에 추가하는데 실패함", "action.removeFromQueue": "대기열에서 삭제", "action.removeFromQueue.success": "대기열에서 삭제됨", - "action.removeFromQueue.error": "대기열에서 삭제 실패", - "action.createPlaylist": "새 플레이리스트", - "action.addToPlaylist": "플레이리스트에 추가...", - "action.removeFromPlaylist": "플레이리스트에서 삭제", - "action.addToFavorites": "선호항목에 추가", + "action.removeFromQueue.error": "대기열에서 삭제하는데 실패함", + "action.createPlaylist": "새 재생 목록 만들기", + "action.addToPlaylist": "재생 목록에 추가", + "action.removeFromPlaylist": "재생 목록에서 삭제", + "action.addToFavorites": "즐겨찾기에 추가", "action.follow": "팔로우", - "action.follow.success": "팔로우됨", + "action.follow.success": "팔로우 중", "action.follow.error": "팔로우 실패", "action.unfollow": "언팔로우", "action.unfollow.success": "언팔로우됨", @@ -179,112 +196,126 @@ "action.startRadio": "스테이션 생성", "action.goToArtist": "아티스트 보기", "action.goToAlbum": "앨범 보기", - "action.moveToTop": "맨 위로 이동", - "action.share": "공유하기", - "action.rename": "이름 편집하기", + "action.moveToTop": "위로 가기", + "action.share": "공유", + "action.rename": "편집", "action.love": "좋아요", "action.unlove": "좋아요 취소", - "action.dislike": "비슷한 항목의 제안 줄이기", - "action.undoDislike": "비슷한 항목의 제안 줄이기 실행 취소", + "action.dislike": "싫어요", + "action.undoDislike": "싫어요 취소", "action.showWebRemoteQR": "웹 리모트", - "action.playTracksNext": "${app.selectedMediaItems.length} 바로 다음에 재생", - "action.playTracksLater": "${app.selectedMediaItems.length} 맨 나중에 재생", - "action.removeTracks": "${self.selectedItems.length} 대기열에서 삭제", - "action.import": "가져오기", + "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.minimize": "트레이에 최소화", "action.tray.quit": "종료", - "action.tray.show": "", // None is Better in Korean + "action.tray.show": "보기", "action.update": "업데이트", - + "action.copy": "복사", + "action.newpreset": "새 프리셋", // Equalizer Preset + "action.deletepreset": "프리셋 삭제", + // Settings - General - "settings.header.general": "일반 설정", - "settings.header.general.description": "Cider를 위한 일반 설정을 조절합니다.", + "settings.header.general": "일반", + "settings.header.general.description": "Cider의 일반 기능을 설정합니다.", "settings.option.general.language": "언어", - + // Language optgroups "settings.option.general.language.main": "언어", - "settings.option.general.language.fun": "실험적인 언어", - "settings.option.general.language.unsorted": "정리되지않음", + "settings.option.general.language.fun": "재미를 위한 언어", + "settings.option.general.language.unsorted": "미분류", + + // Update Cider + "settings.option.general.updateCider": "Cider 업데이트", // Button // Settings - Audio "settings.header.audio": "오디오", - "settings.header.audio.description": "Cider를 위한 오디오 설정을 조절하세요.", - "settings.option.audio.quality": "오디오 품질", // Dropdown - "settings.header.audio.quality.high": "높음", + "settings.header.audio.description": "Cider의 오디오 기능을 설정합니다.", + "settings.option.audio.quality": "오디오 음질", // Dropdown + "settings.header.audio.quality.high": "고품질", "settings.header.audio.quality.low": "낮음", "settings.header.audio.quality.auto": "자동", - "settings.option.audio.seamlessTransition": "간격 없는 재생", // Toggle - "settings.option.audio.enableAdvancedFunctionality": "실험적인 기능", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "노멀라이즈와 이퀄라이저와 같은 확장기능을 사용할 수 있지만 일부 시스템에서 끊김 현상이 발생할 수 있습니다.", - "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "사운드 자동 조절", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "각각 트랙의 볼륨을 자동 조절합니다.", - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "공간 음향", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "소리를 공간 음향으로 만들고 3d효과를 줍니다. (주의: 돌비 애트모스가 아님)", + "settings.option.audio.seamlessTransition": "크로스페이드 기능", // Toggle + "settings.option.audio.enableAdvancedFunctionality": "추가 기능 설정", // Toggle + "settings.option.audio.enableAdvancedFunctionality.description": "AudioContext 기능을 활성화하여 오디오 정규화, 이퀄라이저, 비쥬얼라이저 등의 기능을 쓸 수 있게 해줍니다. 일부 시스템에서는 오디오가 끊길 수 있습니다.", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "오디오 정규화", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "개별 트랙의 최대 볼륨을 정규화하여 보다 균일한 청취 경험을 제공합니다.", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "오디오 공간화", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "오디오를 공간화하고 더욱 3차원적으로 만들어줍니다. (참고: 이 기능은 Dolby Atmos가 아닙니다.)", + // Settings - Visual - "settings.header.visual": "시각 효과", - "settings.header.visual.description": "Cider를 위한 시각 효과 설정을 조절하세요.", - "settings.option.visual.windowBackgroundStyle": "창 배경 설정", // Toggle + "settings.header.visual": "시각", + "settings.header.visual.description": "Cider의 시각 기능을 설정합니다.", + "settings.option.visual.windowBackgroundStyle": "윈도우 배경 스타일", // Toggle "settings.header.visual.windowBackgroundStyle.none": "없음", - "settings.header.visual.windowBackgroundStyle.artwork": "아트워크", + "settings.header.visual.windowBackgroundStyle.artwork": "앨범 아트", "settings.header.visual.windowBackgroundStyle.image": "이미지", - "settings.option.visual.animatedArtwork": "움직이는 아트워크", // Dropdown - "settings.header.visual.animatedArtwork.always": "활성화", - "settings.header.visual.animatedArtwork.limited": "특정 페이지에 한정", - "settings.header.visual.animatedArtwork.disable": "비활성화", - "settings.option.visual.animatedArtworkQuality": "움직이는 아트워크 품질", // Dropdown + "settings.option.visual.animatedArtwork": "애니메이션 앨범 표지", // Dropdown + "settings.header.visual.animatedArtwork.always": "항상 활성화", + "settings.header.visual.animatedArtwork.limited": "페이지나 특정 화면에서만 활성화", + "settings.header.visual.animatedArtwork.disable": "항상 비활성화", + "settings.option.visual.animatedArtworkQuality": "애니메이션 앨범 표지 화질", // Dropdown "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": "움직이는 창 배경", // Toggle + "settings.header.visual.animatedArtworkQuality.extreme": "최상", + "settings.option.visual.animatedWindowBackground": "움직이는 윈도우 배경", // Toggle "settings.option.visual.hardwareAcceleration": "하드웨어 가속", // Dropdown - "settings.option.visual.hardwareAcceleration.description": "재실행 필요", - "settings.header.visual.hardwareAcceleration.default": "기본", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.option.visual.hardwareAcceleration.description": "재시작을 필요로 합니다.", + "settings.header.visual.hardwareAcceleration.default": "기본", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "테마", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "Cider", + "settings.option.visual.theme.dark": "다크", // Refer to term.disabled for the disabled option - "settings.option.visual.showPersonalInfo": "ID 표시", // Toggle - + "settings.option.visual.showPersonalInfo": "개인 정보 보기", // Toggle + // Settings - Lyrics "settings.header.lyrics": "가사", - "settings.header.lyrics.description": "Cider를 위한 가사 설정을 조절하세요.", - "settings.option.lyrics.enableMusixmatch": "Musixmatch 가사", // Toggle - "settings.option.lyrics.enableMusixmatchKaraoke": "노래방 모드 (Musixmatch만)", // Toggle - "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 선호 번역 언어", // Dropdown - "settings.option.lyrics.enableYoutubeLyrics": "뮤직비디오 재생 시 유튜브에서 가사 가져오기", // Toggle - + "settings.header.lyrics.description": "Cider의 가사 기능을 설정합니다.", + "settings.option.lyrics.enableMusixmatch": "Musixmatch 가사 활성화", // Toggle + "settings.option.lyrics.enableMusixmatchKaraoke": "노래방 모드 활성화 (Musixmatch만 가능)", // Toggle + "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 번역 선호 언어", // Dropdown + "settings.option.lyrics.enableYoutubeLyrics": "뮤직 비디오에 대한 유튜브 자막 활성화", // Toggle + // Settings - Connectivity - "settings.header.connectivity": "연결", - "settings.header.connectivity.description": "Cider를 위한 연결 설정을 조절하세요.", - "settings.option.connectivity.discordRPC": "Discord 상태 표시", // Dropdown - "settings.option.connectivity.playbackNotifications": "재생 상태 표시", // Toggle + "settings.header.connectivity": "연동", + "settings.header.connectivity.description": "Cider의 연동 기능을 설정합니다.", + "settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown + "settings.option.connectivity.playbackNotifications": "재생 알림", // Toggle // Refer to term.disabled for the disabled option - "settings.header.connectivity.discordRPC.cider": "'Cider'로 표시", - "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music'으로 표시", - "settings.option.connectivity.discordRPC.clearOnPause": "일시 정지 상태에서 Discord 상태 표시 끄기", // Toggle - "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble 지연 (%)", - "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.connectivity.discordRPC.cider": "'Cider'로 표시하기", + "settings.header.connectivity.discordRPC.appleMusic": "'Apple Music'으로 표시하기", + "settings.option.connectivity.discordRPC.clearOnPause": "일시 정지 시 Discord Rich Presence을 끄기", // Toggle + "settings.option.connectivity.lastfmScrobble": "Last.fm 스크로블링", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "Last.fm 스크로블 딜레이 (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Last.fm Now Playing 기능 활성화", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "곡 제목에서 피쳐링 아티스트를 제외하기 (Last.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "루프 트랙을 필터하기 (Last.fm)", // Refer to term.connect for the connect button - + // Settings - Experimental - "settings.header.experimental": "실험 기능", - "settings.header.experimental.description": "Cider를 위한 실험 기능을 조절하세요.", + "settings.header.experimental": "실험실", + "settings.header.experimental.description": "Cider의 실험적 기능을 설정합니다.", "settings.option.experimental.compactUI": "컴팩트 UI", // Toggle - "settings.option.experimental.close_button_hide": "닫기 버튼으로 프로그램 숨기기", + "settings.option.experimental.close_button_hide": "닫기 버튼이 애플리케이션을 가릴 것입니다", + "settings.option.experimental.copy_log": "로그를 클립보드에 복사하기", + "settings.option.experimental.inline_playlists": "인라인 플레이리스트 및 앨범", + // Refer to term.disabled & term.enabled - // Spatialization Menu - "spatial.notTurnedOn": "먼저 공간 음향 설정을 활성화해주세요.", - "spatial.spatialProperties": "공간 속성", - "spatial.width": "너비", + "spatial.notTurnedOn": "오디오 공간화가 비활성화되어있습니다. 사용하기 전에 먼저 활성화해주세요.", + "spatial.spatialProperties": "공간 설정", + "spatial.width": "길이", "spatial.height": "높이", "spatial.depth": "깊이", - "spatial.gain": "게인", + "spatial.gain": "출력", "spatial.roomMaterials": "방 재질", "spatial.roomDimensions": "방 차원", "spatial.roomPositions": "방 위치", @@ -292,20 +323,20 @@ "spatial.setPositions": "위치 설정", "spatial.up": "위", "spatial.front": "앞", - "spatial.left": "왼쪽", - "spatial.right": "오른쪽", + "spatial.left": "좌", + "spatial.right": "우", "spatial.back": "뒤", "spatial.down": "아래", - "spatial.listener": "청취자", - "spatial.audioSource": "오디오 출처", + "spatial.listener": "사용자", + "spatial.audioSource": "오디오 소스", // Settings - Unfinished "settings.header.unfinished": "미완성", - + // Web Remote "remote.web.title": "Cider 리모트", - "remote.web.description": "Cider 인스턴스와 휴대 전화를 연결하려면 QR 코드를 스캔해주세요", - + "remote.web.description": "QR 코드를 스캔해서 Cider와 스마트폰을 연결하기", + // About - "about.thanks": "Cider 컬렉티브 팀과 우리의 모든 기여자들께 대단히 감사를 표합니다." -} + "about.thanks": "Cider Collective Team과 모든 기여자들에게 감사합니다." +} \ No newline at end of file diff --git a/src/i18n/sk_SK.jsonc b/src/i18n/sk_SK.jsonc new file mode 100644 index 00000000..95100010 --- /dev/null +++ b/src/i18n/sk_SK.jsonc @@ -0,0 +1,311 @@ +{ // Base File + + // i18n Info + "i18n.languageName": "Slovenčina (SK)", // name of language in native language + "i18n.languageNameEnglish": "Slovak (SK)", // name of language in English + "i18n.category": "main", // main = real language, fun = fun community languages + "i18n.authors": "@jurosic", // Authors, if you contribute to this file feel free to add your name seperated with a space + + // App info + "app.name": "Cider", + + "date.format": "${d} ${m}, ${y}", + + // Dialogs + "dialog.cancel": "Zrušit", + "dialog.ok": "OK", + + // Notification + "notification.updatingLibrarySongs": "Aktualizujem pesničky v knižnici...", + "notification.updatingLibraryAlbums": "Aktualizujem albumy v knižnici...", + "notification.updatingLibraryArtists": "Aktualizujem tvorcov v knižnici...", + // Terms + "term.appleInc": "Apple Inc.", + "term.appleMusic": "Apple Music", + "term.applePodcasts": "Apple Podcasts", + "term.itunes": "iTunes", + "term.github": "GitHub", + "term.discord": "Discord", + "term.learnMore": "Zistiť viac", + "term.accountSettings": "Nastavenia účtu", + "term.logout": "Odhlásiť", + "term.login": "Prihlásiť", + "term.about": "About", + "term.privateSession": "Osobný Session", + "term.queue": "Poradie", + "term.search": "Vyhládavať", + "term.library": "Knižnica", + "term.listenNow": "Počúvať teraz", + "term.browse": "Prehliadávať", + "term.radio": "Rádio", + "term.recentlyAdded": "Nedávno Pridané", + "term.songs": "Pesničky", + "term.albums": "Albumy", + "term.artists": "Tvorcovia", + "term.podcasts": "Podcasty", + "term.playlists": "Playlisty", + "term.playlist": "Playlist", + "term.newPlaylist": "Nový Playlist", + "term.newPlaylistFolder": "Nový Priečinok Playlistov", + "term.createNewPlaylist": "Urobiť Nový Playlist", + "term.createNewPlaylistFolder": "Urobiť Nový Priečinok Playlistov", + "term.deletePlaylist": "Ste si istý že chcete zmazat tento playlist?", + "term.play": "Play", + "term.pause": "Pause", + "term.previous": "Previous", + "term.next": "Next", + "term.shuffle": "Shuffle", + "term.repeat": "Repeat", + "term.volume": "Hlasitosť", + "term.mute": "Ztlmiť", + "term.unmute": "Vypnúť Ztlmenie", + "term.share": "Zdielať", + "term.settings": "Nastavenia", + "term.seeAll": "Vidieť Všetko", + "term.sortBy": "Zodariť Podľa", + "term.sortBy.album": "Album", + "term.sortBy.artist": "Tvorca", + "term.sortBy.name": "Názov", + "term.sortBy.genre": "Žáner", + "term.sortBy.releaseDate": "Dátum Vydania", + "term.sortBy.duration": "Dĺžka", + "term.sortOrder": "A-Z", + "term.sortOrder.ascending": "Vzostupne", + "term.sortOrder.descending": "Zostupne", + "term.viewAs": "Zobraziť Ako", + "term.viewAs.coverArt": "Náhľadovka", + "term.viewAs.list": "List", + "term.size": "Velkosť", + "term.size.normal": "Normal", + "term.size.compact": "Compact", + "term.enable": "Zapnúť", + "term.disable": "Vypnúť", + "term.enabled": "Zapnuté", + "term.disabled": "Vypnuté", + "term.connect": "Pripojiť", + "term.connecting": "Pripájam", + "term.disconnect": "Odpojiť", + "term.authed": "Authentikovaný", + "term.confirm": "Podvrdiť ?", + "term.more": "Viac", + "term.less": "Menej", + "term.showMore": "Ukázať viac", + "term.showLess": "Ukázať menej", + "term.topSongs" : "Top Pesničky", + "term.latestReleases": "Najnovšie vydania", + "term.time.added": "Pridané", + "term.time.released": "Vydané", + "term.time.updated": "Aktualizované", + "term.time.hours": "hodín", + "term.time.hour": "hodina", + "term.time.minutes": "minút", + "term.time.minute": "minúta", + "term.time.seconds": "sekúnd", + "term.time.second": "sekunda", + "term.fullscreenView": "Zobrazenie na celej obrazovke", + "term.defaultView": "Default View", + "term.audioSettings": "Nastavenia Zvuku", + "term.clearAll": "Vyčistiť Všetko", + "term.recentStations": "Nedávne Stanice", + "term.language": "Jazyk", + "term.funLanguages": "Zábava", + "term.noLyrics": "Načítavam... / Text nebol najdený./ Instrumental.", + "term.copyright": "Copyright", + "term.rightsReserved": "All Rights Reserved.", + "term.sponsor": "Sponzoruj tento projekt", + "term.ciderTeam": "Cider Team", + "term.developer": "Developer", + "term.socialTeam": "Social Team", + "term.socials": "Socials", + "term.contributors": "Contributors", + "term.equalizer": "Equalizer", + "term.reset": "Resetovať", + "term.tracks": "pesničiek", // Assume x amount of tracks. e.g. 50 tracks + "term.videos": "Videá", + "term.menu": "Menu", + "term.check": "Skontrolovať", + "term.aboutArtist": "Viac o {{artistName}}", // e.g. 'About Doja Cat' + "term.updateCider": "Aktualizovať Cider", + + // Home + "home.title": "Domov", + "home.recentlyPlayed": "Nedávno Prehrané", + "home.recentlyAdded": "Nedávno Pridané", + "home.artistsFeed": "Feed Tvojho Tvorcu", + "home.artistsFeed.noArtist": "Najprv sleduj niektorých tvorcov, ich pesničky potom budú tu", + "home.madeForYou": "Robené Pre Teba", + "home.friendsListeningTo": "Kamaráti počúvajú", + "home.followedArtists": "Sledovaný Tvorcovia", + // Errors + "error.appleMusicSubRequired": "Apple Music potrebuje subscription.", + "error.connectionError": "Pri pripojovaní ku Apple Music sa vyskytol problém", + "error.noResults": "Žiadne výsledky", + "error.noResults.description": "Skús nové vyhľádavanie", + + //Podcasts + "podcast.followOnCider": "Sleduj na Cider", + "podcast.followedOnCider": "Sledované na Cider", + "podcast.subscribeOnItunes": "Odoberaj na iTunes", + "podcast.subscribedOnItunes": "Odoberane na iTunes", + "podcast.itunesStore": "iTunes Obchod", + "podcast.episodes": "Epizódy", + "podcast.playEpisode": "Prehraj Epizódu", + "podcast.website": "Stránka Podcastu", + + // Actions + "action.addToLibrary": "Pridaj do Knižnice", + "action.addToLibrary.success": "Pridané do Knižnice", + "action.addToLibrary.error": "Pri pridávani do Knižnice sa vzskytol problém", + "action.removeFromLibrary": "Odstrániť z Knižnice", + "action.removeFromLibrary.success": "Odstránene z Knižnice", + "action.addToQueue": "Pridať do Poradia", + "action.addToQueue.success": "Pridané do Poradia", + "action.addToQueue.error": "Pri pridávaní do Poradia sa vyskytol problém", + "action.removeFromQueue": "Odstrániť z Poradia", + "action.removeFromQueue.success": "Odstránené z Poradia", + "action.removeFromQueue.error": "Pri odstranovaní z Poradia sa vyskytol probém", + "action.createPlaylist": "Urobiť nový Playlist", + "action.addToPlaylist": "Pridať do Playlistu", + "action.removeFromPlaylist": "Odstrániť z Playlistu", + "action.addToFavorites": "Pridať do Obľubéných", + "action.follow": "Sledovať", + "action.follow.success": "Sleduješ", + "action.follow.error": "Pri Sledovaní sa vyskytol problém", + "action.unfollow": "Zrušit Sledovanie", + "action.unfollow.success": "Sledovanie Zrušené", + "action.unfollow.error": "Pri zrušení sledovania sa vyskytol problém", + "action.playNext": "Hrať Ďalšie", + "action.playLater": "Hrať Neskor", + "action.startRadio": "Zapnúť Rádio", + "action.goToArtist": "Ku Tvorcovi", + "action.goToAlbum": "Ku Albumu", + "action.moveToTop": "Premiestniť Hore", + "action.share": "Zdielať", + "action.rename": "Premenovať", + "action.love": "Love", + "action.unlove": "Unlove", + "action.dislike": "Dislike", + "action.undoDislike": "Zrušiť dislike", + "action.showWebRemoteQR": "Web Remote", + "action.playTracksNext": "Hrať ${app.selectedMediaItems.length} pesničiek ďalej", + "action.playTracksLater": "Hrať ${app.selectedMediaItems.length} pesničiek neskôr", + "action.removeTracks": "Odstrániť ${self.selectedItems.length} pesničiek z poradia", + "action.import": "Importovať", + "action.export": "Exportovať", + "action.showAlbum": "Zobraziť Celý Album", + "action.tray.minimize": "Minimaizovať", + "action.tray.quit": "Odísť", + "action.tray.show": "Ukázať", + "action.update": "Aktualizovať", + + // Settings - General + "settings.header.general": "všeobecné", + "settings.header.general.description": "Zmeniť všeobecné nastavenia pre Cider.", + "settings.option.general.language": "Jazyk", + + // Language optgroups + "settings.option.general.language.main": "Jazyky", + "settings.option.general.language.fun": "Zábanve Jazyky", + "settings.option.general.language.unsorted": "Nepotriedené", + + // Settings - Audio + "settings.header.audio": "Zvuk", + "settings.header.audio.description": "Zmeniť nastavenia zvuku pre Cider.", + "settings.option.audio.quality": "Kvalita zvuku", // Dropdown + "settings.header.audio.quality.high": "Vysoká", + "settings.header.audio.quality.low": "Nizká", + "settings.header.audio.quality.auto": "Automatické", + "settings.option.audio.seamlessTransition": "Hladký Prevod Zvuku", // Toggle + "settings.option.audio.enableAdvancedFunctionality": "Zapnút Pokročilé Nastavenia Zvuku", // Toggle + "settings.option.audio.enableAdvancedFunctionality.description": "Zapnutie AudioContext funkcionality dovolí rozšírené funkcie zvuku ako Zvuková Normalizávia , Equalizéry a Visualízery, ale na niektorých systémoch to može spôsobiť problémy so zvukom.", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalízacia Zvuku", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizuje silu zvuku v pesničkách pre hľadší počúvací zážitok", + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Priestorový Zvuk", // Toggle + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Priestorový zvuk urobí zvuk 3-dimenzionálny (poznámka: Toto nie je Dolby Atmos)", + // Settings - Visual + "settings.header.visual": "Visuálne", + "settings.header.visual.description": "Zmenit Visuálne nastavenia pre Cider.", + "settings.option.visual.windowBackgroundStyle": "Štýl pozadia okna", // Toggle + "settings.header.visual.windowBackgroundStyle.none": "Žiadne", + "settings.header.visual.windowBackgroundStyle.artwork": "Náhľadovka", + "settings.header.visual.windowBackgroundStyle.image": "Obrátok", + "settings.option.visual.animatedArtwork": "Animované Náhľadovky", // Dropdown + "settings.header.visual.animatedArtwork.always": "Vždy", + "settings.header.visual.animatedArtwork.limited": "Limitované pre stránky a špecialne vydania", + "settings.header.visual.animatedArtwork.disable": "Vypnuť Všade", + "settings.option.visual.animatedArtworkQuality": "Kvalita Animovanej Náhľadovky", // Dropdown + "settings.header.visual.animatedArtworkQuality.low": "Nízka", + "settings.header.visual.animatedArtworkQuality.medium": "Stredná", + "settings.header.visual.animatedArtworkQuality.high": "Vysoká", + "settings.header.visual.animatedArtworkQuality.veryHigh": "Veľmi Vysoká", + "settings.header.visual.animatedArtworkQuality.extreme": "Extrémna", + "settings.option.visual.animatedWindowBackground": "Pozadie Animováneho Okna", // Toggle + "settings.option.visual.hardwareAcceleration": "Hardvérova Akcelerácia", // Dropdown + "settings.option.visual.hardwareAcceleration.description": "Vyžaduje Reštart", + "settings.header.visual.hardwareAcceleration.default": "Predvoľba", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + // Refer to term.disabled for the disabled option + "settings.option.visual.showPersonalInfo": "Zobraziť osobné informácie", // Toggle + + // Settings - Lyrics + "settings.header.lyrics": "Text", + "settings.header.lyrics.description": "Zmenit nastavenia textu pre Cider.", + "settings.option.lyrics.enableMusixmatch": "Zapnúť Musixmatch Texty", // Toggle + "settings.option.lyrics.enableMusixmatchKaraoke": "Zapnúť Karaoke Režim (Iba pre Musixmatch)", // Toggle + "settings.option.lyrics.musixmatchPreferredLanguage": "Predvolený jazyk pre Musixmatch prekladanie", // Dropdown + "settings.option.lyrics.enableYoutubeLyrics": "Zapnúť Youtube Lyrics pre videá", // Toggle + + // Settings - Connectivity + "settings.header.connectivity": "Konektivita", + "settings.header.connectivity.description": "Zmeniť nastavenia konektivity pre Cider.", + "settings.option.connectivity.discordRPC": "Zobraziť status v Discord", // Dropdown + "settings.option.connectivity.playbackNotifications": "Notifikácie", // Toggle + // Refer to term.disabled for the disabled option + "settings.header.connectivity.discordRPC.cider": "Zobraziť ako 'Cider'", + "settings.header.connectivity.discordRPC.appleMusic": "Zobraziť ako 'Apple Music'", + "settings.option.connectivity.discordRPC.clearOnPause": "Vypnút Discord status pri Pauze", // Toggle + "settings.option.connectivity.lastfmScrobble": "Last.fm zaznamenanie počúvanej hudby", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Oneskorenie (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Zapnúť Last.fm Now Playing", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Odstrániť tvorcov z počúvanej pesničky (Last.fm)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrovať loopované pesničky (Last.fm)", + // Refer to term.connect for the connect button + + // Settings - Experimental + "settings.header.experimental": "Experimentálne", + "settings.header.experimental.description": "Zmeniť experimentálne nastavenia pre Cider.", + "settings.option.experimental.compactUI": "Compact UI", // Toggle + "settings.option.experimental.close_button_hide": "Zatvoriť by malo skriť aplikáciu", + // Refer to term.disabled & term.enabled + + // Spatialization Menu + "spatial.notTurnedOn": "Priestorový Zvuk je vypnutý. Prosím najprv ho zapnite.", + "spatial.spatialProperties": "Špeciálne Nastavenia", + "spatial.width": "Šírka", + "spatial.height": "Výška", + "spatial.depth": "Hĺbka", + "spatial.gain": "Gain", + "spatial.roomMaterials": "Materiály Priestoru", + "spatial.roomDimensions": "Velkosť Priestoru", + "spatial.roomPositions": "Pozicia v Priestoru", + "spatial.setDimensions": "Nastaviť Rozmery", + "spatial.setPositions": "Nastavit Pozíciu", + "spatial.up": "Hore", + "spatial.front": "V predu", + "spatial.left": "V ľavo", + "spatial.right": "V pravo", + "spatial.back": "V zadu", + "spatial.down": "Dole", + "spatial.listener": "Listener", + "spatial.audioSource": "Zdroj zvuku", + + // Settings - Unfinished + "settings.header.unfinished": "Nedokončené", + + // Web Remote + "remote.web.title": "Cider Remote", + "remote.web.description": "Naskenujte QR kód aby ste si spárovali telefón s touto Cider session", + + // About + "about.thanks": "Ďakujeme Cider Tímu, Komunite a Kontribútorom, bez vás by to nebolo možné." +} diff --git a/src/i18n/sv_SE.jsonc b/src/i18n/sv_SE.jsonc index 22953aee..abdd2d29 100644 --- a/src/i18n/sv_SE.jsonc +++ b/src/i18n/sv_SE.jsonc @@ -1,24 +1,24 @@ { // Base File - // i18n Info - "i18n.languageName": "Svenska (SE)", // name of language in native language + "i18n.languageName": "Svenska (SE)", // name of language in native language "i18n.languageNameEnglish": "Swedish (SE)", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages "i18n.authors": "@thisismemeboi", // Authors, if you contribute to this file feel free to add your name seperated with a space - + // App info "app.name": "Cider", - + "date.format": "${d} ${m}, ${y}", // Dialogs "dialog.cancel": "Avbryt", "dialog.ok": "OK", - + // Notification "notification.updatingLibrarySongs": "Uppdaterar låtar i biblioteket...", "notification.updatingLibraryAlbums": "Uppdaterar album i biblioteket...", "notification.updatingLibraryArtists": "Uppdaterar artister i biblioteket...", + // Terms "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", @@ -91,10 +91,10 @@ "term.less": "Mindre", "term.showMore": "Visa mer", "term.showLess": "Visa mindre", - "term.topSongs" : "Topplåtar", + "term.topSongs": "Topplåtar", "term.latestReleases": "Senaste releaserna", "term.time.added": "Tillagd", - "term.time.released": "Tillagd den", + "term.time.released": "Tillagd den", "term.time.updated": "Uppdaterad", "term.time.hours": "timmar", "term.time.hour": "timme", @@ -121,12 +121,11 @@ "term.equalizer": "EQ", "term.reset": "Återställ", "term.tracks": "låtar", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "Videor", + "term.videos": "Videor", "term.menu": "Meny", "term.check": "Sök efter uppdateringar", "term.aboutArtist": "Om {{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "Uppdatera Cider", - + // Home "home.title": "Hem", "home.recentlyPlayed": "Senast spelade", @@ -136,13 +135,14 @@ "home.madeForYou": "Skapat för dig", "home.friendsListeningTo": "Vänner lyssnar på", "home.followedArtists": "Följda artister", + // Errors "error.appleMusicSubRequired": "Apple Music kräver en prenumeration.", "error.connectionError": "Ojdå. Det gick inte att ansluta till Apple Music.", "error.noResults": "Inga träffar.", "error.noResults.description": "Prova en ny sökning.", - - //Podcasts + + // Podcasts "podcast.followOnCider": "Följ på Cider", "podcast.followedOnCider": "Följer på Cider", "podcast.subscribeOnItunes": "Följ på iTunes", @@ -151,7 +151,7 @@ "podcast.episodes": "Avsnitt", "podcast.playEpisode": "Spela avsnitt", "podcast.website": "Öppna webbsida", - + // Actions "action.addToLibrary": "Lägg till i bibliotek", "action.addToLibrary.success": "Tillagd i biblioteket", @@ -197,16 +197,19 @@ "action.tray.quit": "Avsluta", "action.tray.show": "Visa Cider", "action.update": "Uppdatera", - + // Settings - General "settings.header.general": "Allmänt", "settings.header.general.description": "Ändra Ciders allmänna inställningar.", "settings.option.general.language": "Språk", - + // Language optgroups "settings.option.general.language.main": "Språk", "settings.option.general.language.fun": "Roliga språk", "settings.option.general.language.unsorted": "Osorterade", + + // Update Cider + "settings.option.general.updateCider": "Uppdatera Cider", // Button // Settings - Audio "settings.header.audio": "Ljud", @@ -222,8 +225,9 @@ "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliserar höga ljudnivåer för att förbättra ljudkvaliteten.", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spiralljud", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Gör ljudet mer 3D (Ej Dolby Atmos)", + // Settings - Visual - "settings.header.visual": "Visuellt", + "settings.header.visual": "Visuellt", "settings.header.visual.description": "Ändra Ciders visuella inställningar.", "settings.option.visual.windowBackgroundStyle": "Stil för bakgrunden", // Toggle "settings.header.visual.windowBackgroundStyle.none": "Ingen", @@ -242,11 +246,11 @@ "settings.option.visual.animatedWindowBackground": "Animerad fönsterbakgrund", // Toggle "settings.option.visual.hardwareAcceleration": "Hårdvaruacceleration", // Dropdown "settings.option.visual.hardwareAcceleration.description": "kräver omstart", - "settings.header.visual.hardwareAcceleration.default": "Standard", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "Standard", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "Visa personlig information", // Toggle - + // Settings - Lyrics "settings.header.lyrics": "Låttext", "settings.header.lyrics.description": "Ändra Ciders låttextsinställningar.", @@ -254,7 +258,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "Aktivera karaokeläge (Endast Musixmatch)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Språk för låttextsöversättning (Endast Musixmatch)", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "Använd YouTube Lyrcis för videor", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "Anslutning", "settings.header.connectivity.description": "Ändra Ciders anslutningsinställningar.", @@ -265,19 +269,19 @@ "settings.header.connectivity.discordRPC.appleMusic": "På, visa som 'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "Rensa Discord notiser från Cider när du pausar", // Toggle "settings.option.connectivity.lastfmScrobble": "Last.fm integration", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "Last.fm fördröjning i %", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "Visa vad som spelas nu i Last.fm", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "Visa inte extraartister i Last.fm", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrera bort loopade låtar i Last.fm", + "settings.option.connectivity.lastfmScrobble.delay": "Last.fm fördröjning i %", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "Visa vad som spelas nu i Last.fm", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "Visa inte extraartister i Last.fm", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrera bort loopade låtar i Last.fm", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "Experimentellt", "settings.header.experimental.description": "Ändra Ciders experimentella inställningar.", "settings.option.experimental.compactUI": "Kompakt gränssnitt", // Toggle "settings.option.experimental.close_button_hide": "Stängknappen gömmer Cider istället", + // Refer to term.disabled & term.enabled - // Spatialization Menu "spatial.notTurnedOn": "Spiralljud är av. Akrtivera det först.", "spatial.spatialProperties": "Spiralljudsintällningar", @@ -301,11 +305,11 @@ // Settings - Unfinished "settings.header.unfinished": "Ej tillgängligt", - + // Web Remote "remote.web.title": "Cider fjärrkontroll", "remote.web.description": "Skanna QR koden för att ansluta din telefon till Cider.", - + // About "about.thanks": "Stort tack till Ciders Collective Team och alla som har bidragit!" -} +} \ No newline at end of file diff --git a/src/i18n/zh_CN.jsonc b/src/i18n/zh_CN.jsonc index 370c226e..8844e83b 100644 --- a/src/i18n/zh_CN.jsonc +++ b/src/i18n/zh_CN.jsonc @@ -1,24 +1,24 @@ -{ +{ + // i18n Info + "i18n.languageName": "简体中文(中国)", // name of language in native language + "i18n.languageNameEnglish": "Simp. Chinese (China)", // name of language in English + "i18n.category": "main", // main = real language, fun = fun community languages + "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space + // App info "app.name": "Cider", "date.format": "${y}年${m}月${d}日", - // i18n Info - "i18n.languageName": "简体中文(中国)", // name of language in native language - "i18n.languageNameEnglish": "Simp. Chinese (China)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - // Dialogs "dialog.cancel": "取消", "dialog.ok": "确定", - + // Notification "notification.updatingLibrarySongs": "正在更新资料库的歌曲信息...", "notification.updatingLibraryAlbums": "正在更新资料库的专辑信息...", "notification.updatingLibraryArtists": "正在更新资料库的艺人信息...", - + // Terms "term.appleMusic": "Apple Music", // Follows brand term "term.applePodcasts": "Apple Podcasts", // Follows brand term @@ -85,10 +85,10 @@ "term.less": "较少", "term.showMore": "显示更多", "term.showLess": "显示更少", - "term.topSongs" : "热门歌曲", + "term.topSongs": "热门歌曲", "term.latestReleases": "最新发行", "term.time.added": "添加于", - "term.time.released": "发行于", + "term.time.released": "发行于", "term.time.updated": "更新于", "term.time.hours": "小时", "term.time.hour": "小时", @@ -114,12 +114,11 @@ "term.equalizer": "均衡器", "term.reset": "重置", "term.tracks": "首歌曲", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "视频", + "term.videos": "视频", "term.menu": "菜单", "term.check": "检查", "term.aboutArtist": "关于{{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "更新 Cider", - + // Home "home.title": "主页", "home.recentlyPlayed": "最近播放", @@ -129,14 +128,14 @@ "home.madeForYou": "专属推荐", "home.friendsListeningTo": "朋友正在听", "home.followedArtists": "关注的艺人", - + // Errors "error.appleMusicSubRequired": "需要订阅 Apple Music 以使用 Cider", "error.connectionError": "无法连接到 Apple Music。", "error.noResults": "没有结果", "error.noResults.description": "尝试更改搜索条件。", - //Podcasts + // Podcasts "podcast.followOnCider": "在 Cider 中追踪", "podcast.followedOnCider": "已追踪", "podcast.subscribeOnItunes": "在 iTunes 上订阅", @@ -145,8 +144,7 @@ "podcast.episodes": "单集", "podcast.playEpisode": "播放单集", "podcast.website": "Podcast 网站", - - + // Actions "action.addToLibrary": "加入资料库", "action.addToLibrary.success": "成功加入资料库", @@ -192,21 +190,28 @@ "action.tray.show": "显示", "action.update": "更新", - // Settings - Audio "settings.header.audio": "音频", "settings.header.audio.description": "调整 Cider 的音频设置", "settings.option.audio.quality": "音质", // Dropdown + "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.low": "高效率", + "settings.header.audio.quality.standard": "高效率", "settings.header.audio.quality.auto": "自动", "settings.option.audio.seamlessTransition": "无缝播放", // Toggle "settings.option.audio.enableAdvancedFunctionality": "进阶功能", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "启用 AudioContext 将解锁例如音量标准化和音频空间化的功能,但可能会在小部分设备上出现音频上的卡顿。", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 数字增强引擎™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "将欺骗您的大脑来感知到近似无损音频的效果。", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量标准化", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "使所感知到的音频响度统一", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "音频空间化", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "使所感知到的音频更有立体感 (注: 这不是杜比全景声)", + // Settings - Visual "settings.header.visual": "外观", "settings.header.visual.description": "调整 Cider 的外观", @@ -226,13 +231,17 @@ "settings.option.visual.animatedWindowBackground": "动态窗口背景", // Toggle "settings.option.visual.hardwareAcceleration": "硬件加速", // Dropdown "settings.option.visual.hardwareAcceleration.description": "需要重启 Cider 才会生效", - "settings.header.visual.hardwareAcceleration.default": "默认", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "默认", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "显示个人资料", // Toggle + // Settings - General (Reserved) "settings.header.general": "通用", "settings.header.general.description": "调整 Cider 的通用设置", + + // Settings - General - Update Cider + "settings.option.general.updateCider": "更新 Cider", // Button // Settings - Lyrics "settings.header.lyrics": "歌词", @@ -241,7 +250,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "启用卡拉 OK 模式(仅 Musixmatch)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌词语言偏好", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "播放 MV 时使用 YouTube 歌词", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "外部连接", "settings.header.connectivity.description": "调整Cider与外部应用的交互设置", @@ -251,45 +260,45 @@ "settings.header.connectivity.discordRPC.appleMusic": "显示正在玩 'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "暂停时清除Discord 动态", // Toggle "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 记录", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延迟 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "启用 LastFM 正在播放", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除艺人推荐 (LastFM)", + "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延迟 (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "启用 LastFM 正在播放", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除艺人推荐 (LastFM)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "实验性功能", "settings.header.experimental.description": "调整Cider的实验性功能", "settings.option.experimental.compactUI": "紧凑型 UI", // Toggle "settings.option.experimental.close_button_hide": "点击关闭按钮时仅隐藏窗口", - // Refer to term.disabled & term.enabled + // Refer to term.disabled & term.enabled // Spatialization Menu - "spatial.spatialProperties" : "空间属性", - "spatial.width" : "宽度", - "spatial.height" : "高度", - "spatial.depth" : "深度", + "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" : "音源", - + "spatial.roomMaterials": "空间材质", + "spatial.roomDimensions": "空间尺寸", + "spatial.roomPositions": "空间位置", + "spatial.setDimensions": "设置尺寸", + "spatial.setPositions": "设置位置", + "spatial.up": "上", + "spatial.front": "前", + "spatial.left": "左", + "spatial.right": "右", + "spatial.back": "后", + "spatial.down": "下", + "spatial.listener": "您", + "spatial.audioSource": "音源", + // Settings - Unfinished "settings.header.unfinished": "未完成", - + // Web Remote "remote.web.title": "Cider 远程控制", "remote.web.description": "扫描以下的二维码以控制 Cider", - + //About "about.thanks": "郑重感谢 Cider Collective 以及为这个项目提供支持的贡献者。" -} +} \ No newline at end of file diff --git a/src/i18n/zh_HK.jsonc b/src/i18n/zh_HK.jsonc index 97bc8481..b0618dae 100644 --- a/src/i18n/zh_HK.jsonc +++ b/src/i18n/zh_HK.jsonc @@ -1,24 +1,24 @@ { - // i18n Info - "i18n.languageName": "繁體中文(香港)", // name of language in native language + "i18n.languageName": "繁體中文(香港)", // name of language in native language "i18n.languageNameEnglish": "Trad. Chinese (Hong Kong)", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages "i18n.authors": "@kyw504100 @maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - + // App info "app.name": "Cider", - - "date.format": "${y}年${m}月${d}日", - + + "date.format": "${y}年${m}月${d}日", + // Dialogs "dialog.cancel": "取消", "dialog.ok": "確認", - + // Notification "notification.updatingLibrarySongs": "正在更新資料庫的歌曲...", "notification.updatingLibraryAlbums": "正在更新資料庫的專輯...", "notification.updatingLibraryArtists": "正在更新資料庫的藝人...", + // Terms "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", // Follows brand term @@ -33,6 +33,7 @@ "term.about": "關於", "term.privateSession": "私人模式", "term.queue": "待播清單", + "term.history": "歷史紀錄", "term.search": "搜尋", "term.library": "資料庫", "term.listenNow": "立即聆聽", @@ -45,6 +46,11 @@ "term.podcasts": "Podcasts", "term.playlists": "播放列表", "term.playlist": "播放列表", + "term.newPlaylist": "新播放列表", + "term.newPlaylistFolder": "新資料夾", + "term.createNewPlaylist": "新增播放列表", + "term.createNewPlaylistFolder": "新增資料夾", + "term.deletePlaylist": "你確認要刪除這個播放列表?", "term.play": "播放", "term.pause": "暫停", "term.previous": "上一首", @@ -55,6 +61,7 @@ "term.mute": "靜音", "term.unmute": "取消靜音", "term.share": "分享", + "term.share.success": "已複製至剪貼簿", "term.settings": "設定", "term.seeAll": "顯示全部", "term.sortBy": "排序", @@ -86,10 +93,10 @@ "term.less": "較少", "term.showMore": "顯示更多", "term.showLess": "顯示較少", - "term.topSongs" : "熱門歌曲", + "term.topSongs": "熱門歌曲", "term.latestReleases": "最新發行", "term.time.added": "加入於", - "term.time.released": "發行於", + "term.time.released": "發行於", "term.time.updated": "更新於", "term.time.hours": "小時", "term.time.hour": "小時", @@ -116,10 +123,26 @@ "term.equalizer": "均衡器", "term.reset": "重設", "term.tracks": "首歌曲", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "影片", - "term.menu": "選項", - "term.showAlbum": "顯示完整的專輯", - + "term.videos": "影片", + "term.menu": "選項", + "term.check": "檢查", + "term.aboutArtist": "關於 {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "熱門搜尋結果", // Search Results + "term.sharedPlaylists": "播放列表", // Search Results + "term.people": "個人檔案", // Search Results + "term.newpreset.name": "新均衡器範本名稱", // Equalizer Preset + "term.addedpreset": "已新增", + "term.deletepreset.warn": "你確認要刪除這個範本?", + "term.deletedpreset": "已刪除", + "term.musicVideos": "MV", // Search page friendlyTypes + "term.stations": "電台", + //"term.curators": "Curators", + //"term.appleCurators": "Apple Curators", + "term.radioShows": "廣播單集", + "term.recordLabels": "唱片公司", + "term.videoExtras": "影片特輯", + //"term.top": "Top", + // Home "home.title": "主頁", "home.recentlyPlayed": "最近播放", @@ -129,13 +152,14 @@ "home.madeForYou": "為您推薦", "home.friendsListeningTo": "朋友正在聆聽", "home.followedArtists": "追蹤的藝人", + // Errors "error.appleMusicSubRequired": "需要訂閱Apple Music以使用Cider", "error.connectionError": "無法連接到 Apple Music。", "error.noResults": "沒有結果", "error.noResults.description": "請嘗試新的搜尋內容。", - - //Podcasts + + // Podcasts "podcast.followOnCider": "在Cider上追蹤", "podcast.followedOnCider": "已在Cider上追蹤", "podcast.subscribeOnItunes": "在iTunes上訂閱", @@ -144,7 +168,7 @@ "podcast.episodes": "單集", "podcast.playEpisode": "播放單集", "podcast.website": "Podcast 網頁", - + // Actions "action.addToLibrary": "加入資料庫", "action.addToLibrary.success": "成功加入資料庫", @@ -185,6 +209,14 @@ "action.removeTracks": "從待播清單刪除 ${self.selectedItems.length} 首歌曲", "action.import": "匯入", "action.export": "匯出", + "action.showAlbum": "顯示完整的專輯", + "action.tray.minimize": "縮小至系統托盤", + "action.tray.quit": "結束", + "action.tray.show": "顯示", + "action.update": "更新", + "action.copy": "複製", + "action.newpreset": "新增範本", //Equallizer preset + "action.deletepreset": "刪除範本", // Settings - General "settings.header.general": "一般", @@ -195,21 +227,31 @@ "settings.option.general.language.main": "語言", "settings.option.general.language.fun": "惡搞語言", "settings.option.general.language.unsorted": "未分類", + + // Update Cider + "settings.option.general.updateCider": "更新 Cider", // Button // Settings - Audio "settings.header.audio": "音訊", "settings.header.audio.description": "調整Cider的音訊設定", "settings.option.audio.quality": "音訊音質", // Dropdown + "settings.header.audio.quality.hireslossless": "高清無損壓縮", + "settings.header.audio.quality.hireslossless.description": "(高達 24-bit/192 kHz)", + "settings.header.audio.quality.lossless": "無損壓縮", + "settings.header.audio.quality.lossless.description": "(高達 24-bit/48 kHz)", "settings.header.audio.quality.high": "高素質", "settings.header.audio.quality.low": "高效率", "settings.header.audio.quality.auto": "自動", "settings.option.audio.seamlessTransition": "無縫播放", // Toggle "settings.option.audio.enableAdvancedFunctionality": "進階功能", // Toggle "settings.option.audio.enableAdvancedFunctionality.description": "啟用 AudioContext 將解鎖類似音量平衡和均衡器的進階功能。但是會在一些電腦造成音樂卡頓。", + "settings.option.audio.enableAdvancedFunctionality.decryptLLPW": "無損壓縮解碼", // Toggle + "settings.option.audio.enableAdvancedFunctionality.decryptLLPW.description": "提供 Cider 解碼無損壓縮檔案的能力,但相應地會增加電腦的工作量。", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量平衡", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "將平衡輕柔和響亮的歌曲,建立更統一的聆聽體驗。", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空間音訊", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "將音訊進行空間化處理來製造一個更立體的聆聽體驗(注:此功能不是官方的杜比全景聲)", + // Settings - Visual "settings.header.visual": "外觀", "settings.header.visual.description": "調整Cider的外觀", @@ -230,8 +272,13 @@ "settings.option.visual.animatedWindowBackground": "動態窗口背景", // Toggle "settings.option.visual.hardwareAcceleration": "硬體加速", // Dropdown "settings.option.visual.hardwareAcceleration.description": "需要重啓 Cider 才能生效", - "settings.header.visual.hardwareAcceleration.default": "預設", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "預設", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "主題", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "預設", + "settings.option.visual.theme.dark": "午夜暗", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "顯示個人檔案", // Toggle @@ -242,7 +289,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "啟用卡拉OK模式(僅限Musixmatch)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "播放 MV 時使用 YouTube 歌詞", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "外部連結", "settings.header.connectivity.description": "調整Cider與外部的連結", @@ -252,50 +299,50 @@ "settings.header.connectivity.discordRPC.cider": "顯示為'Cider'", "settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延遲 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 LastFM 正在播放", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (LastFM)", + "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling 記錄", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble 延遲 (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 Last.fm 正在播放", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (Last.fm)", + //"settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "實驗性功能", "settings.header.experimental.description": "調整Cider的實驗性功能", "settings.option.experimental.compactUI": "緊凑型 UI", // Toggle - "settings.option.experimental.closeButtonBehaviour": "關閉按鈕行為", - "settings.option.experimental.closeButtonBehaviour.quit": "結束 Cider", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "縮小至工作列", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "縮小至系統托盤", - // Refer to term.disabled & term.enabled + "settings.option.experimental.close_button_hide": "以關閉按鈕來隱藏 Cider", + "settings.option.experimental.copy_log": "複製運行記錄檔至剪貼簿", + //"settings.option.experimental.inline_playlists": "Inline Playlists and Albums", + // Refer to term.disabled & term.enabled // Spatialization Menu - "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" : "音源", - + "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 - Unfinished "settings.header.unfinished": "未完成", - + // Web Remote "remote.web.title": "遙距控制 Cider", "remote.web.description": "掃描以下的二維碼以控制 Cider", - - //About + + // About "about.thanks": "感謝 Cider Collective 以及所有貢獻者所作出的貢獻。" } \ No newline at end of file diff --git a/src/i18n/zh_TW.jsonc b/src/i18n/zh_TW.jsonc index c6d24f49..5a7ef4da 100644 --- a/src/i18n/zh_TW.jsonc +++ b/src/i18n/zh_TW.jsonc @@ -1,24 +1,24 @@ { + // i18n Info + "i18n.languageName": "繁體中文(台灣)", // name of language in native language + "i18n.languageNameEnglish": "Trad. Chinese (Taiwan)", // name of language in English + "i18n.category": "main", // main = real language, fun = fun community languages + "i18n.authors": "@maikirakiwi @jay900604", // Authors, if you contribute to this file feel free to add your name seperated with a space + // App info "app.name": "Cider", "date.format": "${y}年${m}月${d}日", - - // i18n Info - "i18n.languageName": "繁體中文(台灣)", // name of language in native language - "i18n.languageNameEnglish": "Trad. Chinese (Taiwan)", // name of language in English - "i18n.category": "main", // main = real language, fun = fun community languages - "i18n.authors": "@maikirakiwi", // Authors, if you contribute to this file feel free to add your name seperated with a space - // Dialogs "dialog.cancel": "取消", "dialog.ok": "確定", - + // Notification "notification.updatingLibrarySongs": "正在更新資料庫的歌曲...", "notification.updatingLibraryAlbums": "正在更新資料庫的專輯...", "notification.updatingLibraryArtists": "正在更新資料庫的藝人...", + // Terms "term.appleMusic": "Apple Music", // Follows brand term "term.applePodcasts": "Apple Podcasts", // Follows brand term @@ -54,6 +54,7 @@ "term.mute": "靜音", "term.unmute": "取消靜音", "term.share": "分享", + "term.share.success": "已複製至剪貼簿", "term.settings": "設定", "term.seeAll": "顯示全部", "term.sortBy": "排序", @@ -71,7 +72,7 @@ "term.viewAs.list": "列表", "term.size": "大小", "term.size.normal": "正常", - "term.size.compact": "緊凑", + "term.size.compact": "緊密", "term.enable": "啟用", "term.disable": "停用", "term.enabled": "已啟用", @@ -85,10 +86,10 @@ "term.less": "更少", "term.showMore": "顯示更多", "term.showLess": "顯示更少", - "term.topSongs" : "熱門歌曲", + "term.topSongs": "熱門歌曲", "term.latestReleases": "最新發行", "term.time.added": "加入於", - "term.time.released": "發行於", + "term.time.released": "發行於", "term.time.updated": "更改於", "term.time.hours": "小時", "term.time.hour": "小時", @@ -96,18 +97,18 @@ "term.time.minute": "分鐘", "term.time.seconds": "秒", "term.time.second": "秒", - "term.fullscreenView": "全螢幕顯示歌詞", + "term.fullscreenView": "全螢幕顯示", "term.defaultView": "預設顯示", "term.audioSettings": "音訊設定", - "term.spacializedAudioSetting": "音訊空間設定", + "term.spacializedAudioSetting": "空間音訊設定", "term.clearAll": "清空", "term.recentStations": "最近收聽的廣播", "term.language": "語言", "term.noLyrics": "正在載入。。/ 無歌詞結果 / 純音樂", "term.copyright": "版權聲明", "term.rightsReserved": "保留所有權利。", - "term.sponsor": "贊助", - "term.socials": "社群", + "term.sponsor": "贊助我們", + "term.socials": "社群平台", "term.ciderTeam": "Cider 團隊", "term.developer": "開發者", "term.socialTeam": "公關團隊", @@ -115,11 +116,10 @@ "term.equalizer": "等化器", "term.reset": "重設", "term.tracks": "首歌曲", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "影片", + "term.videos": "影片", "term.menu": "選單", "term.check": "檢查", "term.aboutArtist": "關於{{artistName}}", // e.g. 'About Doja Cat' - "term.updateCider": "更新 Cider", // Home "home.title": "首頁", @@ -130,13 +130,14 @@ "home.madeForYou": "為您推薦", "home.friendsListeningTo": "朋友正在聆聽", "home.followedArtists": "追蹤的藝人", + // Errors "error.appleMusicSubRequired": "需要訂閱 Apple Music 以使用 Cider", - "error.connectionError": "無法連線到 Apple Music。", + "error.connectionError": "無法連接到 Apple Music。", "error.noResults": "沒有結果", "error.noResults.description": "嘗試新的搜尋項目。", - - //Podcasts + + // Podcasts "podcast.followOnCider": "在 Cider 上追蹤", "podcast.followedOnCider": "已追蹤", "podcast.subscribeOnItunes": "在 iTunes 上訂閱", @@ -145,7 +146,7 @@ "podcast.episodes": "單集", "podcast.playEpisode": "播放單集", "podcast.website": "Podcast 網站", - + // Actions "action.addToLibrary": "加入資料庫", "action.addToLibrary.success": "成功加入資料庫", @@ -190,11 +191,17 @@ "action.tray.quit": "關閉", "action.tray.show": "顯示", "action.update": "更新", + "action.copy": "複製", + "action.newpreset": "新增預設", // Equalizer Preset + "action.deletepreset": "刪除預設", // Equalizer Preset // Language optgroups "settings.option.general.language.main": "語言", - "settings.option.general.language.fun": "惡搞語言", + "settings.option.general.language.fun": "特殊語言", "settings.option.general.language.unsorted": "未分類", + + // Update Cider + "settings.option.general.updateCider": "更新 Cider", // Button // Settings - Audio "settings.header.audio": "音訊", @@ -204,25 +211,31 @@ "settings.header.audio.quality.hireslossless.description": "(高達 24-bit/192 kHz)", "settings.header.audio.quality.lossless": "無損壓縮", "settings.header.audio.quality.lossless.description": "(高達 24-bit/48 kHz)", + "settings.header.audio.quality.enhanced": "數位增強", "settings.header.audio.quality.high": "高品質", - "settings.header.audio.quality.low": "高效率", + "settings.header.audio.quality.standard": "高效率", "settings.header.audio.quality.auto": "自動", "settings.option.audio.seamlessTransition": "無間斷播放", // Toggle "settings.option.audio.enableAdvancedFunctionality": "進階音訊功能", // Toggle - "settings.option.audio.enableAdvancedFunctionality.description": "啟用 AudioContext 將解鎖類似音訊標準和等化器的進階功能。但這並不一定適合每部電腦,可能會發生音樂卡頓。", - "settings.option.audio.enableAdvancedFunctionality.decryptLLPW": "無損壓縮解碼", // Toggle - "settings.option.audio.enableAdvancedFunctionality.decryptLLPW.description": "提供 Cider 解碼無損壓縮檔案的能力,但相對應的也會提升對電腦效能的使用率。", + "settings.option.audio.enableAdvancedFunctionality.description": "啟用 AudioContext 將開啟類似音訊平衡和等化器的進階設定。但這並不一定適合每部電腦,可能會發生音樂卡頓。", + "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 數位增強音訊處理™️", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "將欺騙您的大腦讓您感受到近似保真壓縮的音質。| 由 Maikiwi 設計", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "數位增強音訊處理設定", // Toggle + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "將更改音訊處理的激進/振奮程度(增強選項有可能會引起雜訊)", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "標準", + "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "增強", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音訊平衡", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "將平衡輕柔和響亮的歌曲,建立更統一的聆聽體驗。", + "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "將平衡輕柔和響亮的歌曲,建立更統一舒適的聆聽體驗。", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空間音訊", // Toggle - "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "將音訊進行空間化處理來製造一個更立體的聆聽體驗(註:此功能不是官方的杜比全景聲)。", - + "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "將音訊進行空間化處理來製造一個更立體的聆聽體驗(註:此功能不是官方的杜比全景聲)", + // Settings - Visual "settings.header.visual": "外觀", "settings.header.visual.description": "調整 Cider 的外觀", "settings.option.visual.windowBackgroundStyle": "視窗背景樣式", // Toggle "settings.header.visual.windowBackgroundStyle.none": "空白", "settings.header.visual.windowBackgroundStyle.artwork": "專輯封面", + "settings.header.visual.windowBackgroundStyle.image": "圖片", "settings.option.visual.animatedArtwork": "動態專輯封面", // Dropdown "settings.header.visual.animatedArtwork.always": "總是顯示", "settings.header.visual.animatedArtwork.limited": "只在藝人頁面和專輯封面顯示", @@ -236,12 +249,15 @@ "settings.option.visual.animatedWindowBackground": "動態視窗背景", // Toggle "settings.option.visual.hardwareAcceleration": "硬體加速", // Dropdown "settings.option.visual.hardwareAcceleration.description": "需要重新啟動 Cider 才會套用", - "settings.header.visual.hardwareAcceleration.default": "預設", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", - + "settings.header.visual.hardwareAcceleration.default": "預設", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "主題", + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "Cider", + "settings.option.visual.theme.dark": "暗黑模式", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "顯示個人檔案", // Toggle - + // Settings - General (Reserved) "settings.header.general": "一般", "settings.header.general.description": "調整 Cider 的一般設定", @@ -253,31 +269,35 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "啟用K歌模式(僅限Musixmatch)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "播放 MV 時使用 YouTube 歌詞", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "外部連接", "settings.header.connectivity.description": "調整 Cider 與外部的連接", "settings.option.connectivity.discordRPC": "Discord 動態", // Dropdown + "settings.option.connectivity.playbackNotifications": "歌曲播放通知", // Toggle // Refer to term.disabled for the disabled option "settings.header.connectivity.discordRPC.cider": "顯示正在玩 'Cider'", "settings.header.connectivity.discordRPC.appleMusic": "顯示正在玩 'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 動態", // Toggle "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延遲 (%)", + "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延遲 (%)", "settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 LastFM 目前聆聽", // Toggle - "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (LastFM)", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (LastFM)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "實驗性功能", "settings.header.experimental.description": "調整 Cider 的實驗性功能", - "settings.option.experimental.compactUI": "緊凑的介面", // Toggle + "settings.option.experimental.compactUI": "使用緊密的介面設計", // Toggle "settings.option.experimental.closeButtonBehaviour": "關閉按鈕操作", // Dropdown "settings.option.experimental.close_button_hide": "關閉按鈕將 Cider 隱藏至系統列", - // Refer to term.disabled & term.enabled + "settings.option.experimental.copy_log": "複製執行紀錄檔至剪貼簿", + "settings.option.experimental.inline_playlists": "將播放列表做為行内元素顯示", + // Refer to term.disabled & term.enabled // Spatialization Menu - "spatial.spatialProperties" : "音訊空間屬性", + "spatial.notTurnedOn": "空間音訊目前是關閉狀態,請先啟用再使用。", + "spatial.spatialProperties" : "空間音訊屬性設定", "spatial.width" : "寬度", "spatial.height" : "高度", "spatial.depth" : "深度", @@ -286,7 +306,7 @@ "spatial.roomDimensions" : "空間尺寸", "spatial.roomPositions" : "空間位置", "spatial.setDimensions" : "設定尺寸", - "spatial.setPositions" : "設定位置", + "spatial.setPositions" : "套用設定", "spatial.up" : "上", "spatial.front" : "前", "spatial.left" : "左", @@ -297,12 +317,12 @@ "spatial.audioSource" : "音訊來源", // Settings - Unfinished - "settings.header.unfinished": "未完成", + "settings.header.unfinished": "未開發完成的功能", // Web Remote "remote.web.title": "Cider 遠端操控", "remote.web.description": "掃描以下的行動條碼以操控 Cider", - + //About "about.thanks": "著重感謝 Cider Collective 的成員以及所有為項目付出的貢獻者。" -} +} \ No newline at end of file diff --git a/src/i18n/zh_yue.jsonc b/src/i18n/zh_yue.jsonc index 41abc873..6fec3bfb 100644 --- a/src/i18n/zh_yue.jsonc +++ b/src/i18n/zh_yue.jsonc @@ -1,24 +1,24 @@ { - // i18n Info - "i18n.languageName": "廣東話(香港﹚", // name of language in native language + "i18n.languageName": "廣東話(香港)", // name of language in native language "i18n.languageNameEnglish": "Cantonese (Hong Kong)", // name of language in English "i18n.category": "main", // main = real language, fun = fun community languages "i18n.authors": "@tszngaiyip @strikesnc", // Authors, if you contribute to this file feel free to add your name seperated with a space - + // App info "app.name": "Cider", - + "date.format": "${y}年${m}月${d}日", // Dialogs "dialog.cancel": "取消", "dialog.ok": "確認", - + // Notification "notification.updatingLibrarySongs": "更新緊資料庫嘅歌曲...", "notification.updatingLibraryAlbums": "更新緊資料庫嘅專輯...", "notification.updatingLibraryArtists": "更新緊資料庫嘅藝人...", + // Terms "term.appleInc": "Apple Inc.", "term.appleMusic": "Apple Music", @@ -33,6 +33,7 @@ "term.about": "關於", "term.privateSession": "無痕模式", "term.queue": "待播清單", + "term.history": "播放歷史", "term.search": "搵野", "term.library": "資料庫", "term.listenNow": "即刻聽", @@ -45,6 +46,11 @@ "term.podcasts": "Podcasts", "term.playlists": "播放清單", "term.playlist": "播放清單", + "term.newPlaylist": "新播放清單", + "term.newPlaylistFolder": "新資料夾", + "term.createNewPlaylist": "新增播放清單", + "term.createNewPlaylistFolder": "新增資料夾", + "term.deletePlaylist": "你係咪要刪除呢個播放清單?", "term.play": "播放", "term.pause": "暫停", "term.previous": "前一首", @@ -55,6 +61,7 @@ "term.mute": "靜音", "term.unmute": "取消靜音", "term.share": "分享", + "term.share.success": "複製咗喺剪貼簿", "term.settings": "設定", "term.seeAll": "睇哂全部", "term.sortBy": "排序", @@ -86,10 +93,10 @@ "term.less": "少啲", "term.showMore": "顯示多啲", "term.showLess": "顯示少啲", - "term.topSongs" : "熱門歌曲", + "term.topSongs": "熱門歌曲", "term.latestReleases": "最新出嘅", "term.time.added": "加入於", - "term.time.released": "發行於", + "term.time.released": "發行於", "term.time.updated": "更新於", "term.time.hours": "粒鐘", "term.time.hour": "粒鐘", @@ -116,9 +123,25 @@ "term.equalizer": "均衡器 (EQ)", "term.reset": "重設", "term.tracks": "首歌", // Assume x amount of tracks. e.g. 50 tracks - "term.videos": "影片", - "term.menu": "選項", - "term.showAlbum": "顯示完整嘅專輯", + "term.videos": "影片", + "term.menu": "選項", + "term.check": "檢查", + "term.aboutArtist": "關於 {{artistName}}", // e.g. 'About Doja Cat' + "term.topResult": "熱門搜尋結果", // Search Results + "term.sharedPlaylists": "播放清單", // Search Results + "term.people": "個人檔案", // Search Results + "term.newpreset.name": "新EQ範本嘅名", // Equalizer Preset + "term.addedpreset": "新增咗", + "term.deletepreset.warn": "你係咪要刪除呢個範本?", + "term.deletedpreset": "刪除咗", + "term.musicVideos": "MV", // Search page friendlyTypes + "term.stations": "電台", + //"term.curators": "Curators", + //"term.appleCurators": "Apple Curators", + "term.radioShows": "電台單集", + "term.recordLabels": "唱片公司", + "term.videoExtras": "相關嘅片", + //"term.top": "Top", // Home "home.title": "主頁", @@ -129,13 +152,14 @@ "home.madeForYou": "為你而整", "home.friendsListeningTo": "你啲Friend聽緊", "home.followedArtists": "Follow左嘅藝人", + // Errors "error.appleMusicSubRequired": "需要訂閱Apple Music先可以用Cider。", "error.connectionError": "連接唔到Apple Music。", "error.noResults": "冇結果。", "error.noResults.description": "重新搵過啦。", - - //Podcasts + + // Podcasts "podcast.followOnCider": "喺Cider上Follow", "podcast.followedOnCider": "喺Cider上Follow左", "podcast.subscribeOnItunes": "喺iTunes上訂閱", @@ -144,7 +168,7 @@ "podcast.episodes": "單集", "podcast.playEpisode": "播呢集", "podcast.website": "Podcast 網頁", - + // Actions "action.addToLibrary": "加入資料庫", "action.addToLibrary.success": "加入咗資料庫", @@ -185,16 +209,27 @@ "action.removeTracks": "喺待播清單到刪除 ${self.selectedItems.length} 首歌曲", "action.import": "匯入", "action.export": "匯出", - + "action.showAlbum": "顯示完整嘅專輯", + "action.tray.minimize": "收埋喺系統托盤", + "action.tray.quit": "結束", + "action.tray.show": "顯示", + "action.update": "更新", + "action.copy": "複製", + "action.newpreset": "新增範本", // Equalizer Preset + "action.deletepreset": "刪除範本", + // Settings - General "settings.header.general": "一般", "settings.header.general.description": "調整Cider嘅一般設定", "settings.option.general.language": "語言", - + // Language optgroups "settings.option.general.language.main": "語言", "settings.option.general.language.fun": "惡搞語言", "settings.option.general.language.unsorted": "未分類", + + // Update Cider + "settings.option.general.updateCider": "更新 Cider", // Button // Settings - Audio "settings.header.audio": "音訊", @@ -210,8 +245,9 @@ "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "平衡輕柔同響亮嘅歌曲,令你有統一嘅聆聽體驗。", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空間音訊", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "空間化音訊,製造一個更立體嘅聆聽體驗(注意:呢個功能唔係官方嘅杜比全景聲)", + // Settings - Visual - "settings.header.visual": "外觀", + "settings.header.visual": "外觀", "settings.header.visual.description": "調整Cider嘅外觀", "settings.option.visual.windowBackgroundStyle": "視窗背景樣式", // Toggle "settings.header.visual.windowBackgroundStyle.none": "空白", @@ -230,11 +266,16 @@ "settings.option.visual.animatedWindowBackground": "動態視窗背景", // Toggle "settings.option.visual.hardwareAcceleration": "硬體加速", // Dropdown "settings.option.visual.hardwareAcceleration.description": "需要重開Cider先會生效", - "settings.header.visual.hardwareAcceleration.default": "預設", - "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.hardwareAcceleration.default": "預設", + "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", + "settings.header.visual.theme": "主題", + + // Settings - Visual - Theme name + "settings.option.visual.theme.default": "預設", + "settings.option.visual.theme.dark": "黑色", // Refer to term.disabled for the disabled option "settings.option.visual.showPersonalInfo": "顯示個人檔案", // Toggle - + // Settings - Lyrics "settings.header.lyrics": "歌詞", "settings.header.lyrics.description": "調整Cider嘅歌詞設定", @@ -242,7 +283,7 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "開啟唱K模式(僅限Musixmatch)", // Toggle "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好", // Dropdown "settings.option.lyrics.enableYoutubeLyrics": "播放MV嘅時候用YouTube字幕", // Toggle - + // Settings - Connectivity "settings.header.connectivity": "外部連結", "settings.header.connectivity.description": "調整Cider同外部嘅連結", @@ -252,50 +293,50 @@ "settings.header.connectivity.discordRPC.cider": "顯示為'Cider'", "settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", // Toggle - "settings.option.connectivity.lastfmScrobble": "LastFM Scrobbling 記錄", // Option to Connect - "settings.option.connectivity.lastfmScrobble.delay": "LastFM Scrobble 延遲 (%)", - "settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 LastFM 正在播放", - "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (LastFM)", - "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (LastFM)", + "settings.option.connectivity.lastfmScrobble": "Last.FM Scrobbling 記錄", // Option to Connect + "settings.option.connectivity.lastfmScrobble.delay": "Last.FM Scrobble 延遲 (%)", + "settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 Last.FM 正在播放", + "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (Last.FM)", + "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.FM)", // Refer to term.connect for the connect button - + // Settings - Experimental "settings.header.experimental": "實驗性功能", "settings.header.experimental.description": "調整Cider嘅實驗性功能", "settings.option.experimental.compactUI": "逼啲既 UI", // Toggle - "settings.option.experimental.closeButtonBehaviour": "關閉按鈕行為", - "settings.option.experimental.closeButtonBehaviour.quit": "熄左Cider佢", - "settings.option.experimental.closeButtonBehaviour.minimizeTaskbar": "收埋Cider喺工作列", - "settings.option.experimental.closeButtonBehaviour.minimizeTray": "收埋Cider喺系統托盤", + "settings.option.experimental.close_button_hide": "㩒交叉制嚟隱藏 Cider", + "settings.option.experimental.copy_log": "將log複製喺剪貼簿", + //"settings.option.experimental.inline_playlists": "Inline Playlists and Albums", + // Refer to term.disabled & term.enabled - // Spatialization Menu - "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" : "音源", + "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 - Unfinished "settings.header.unfinished": "未搞掂", - + // Web Remote "remote.web.title": "遙距控制 Cider", "remote.web.description": "Scan 呢個 QR Code 去控制 Cider", - + // About "about.thanks": "多謝 Cider Collective 同埋所有合作人作出嘅貢獻。" -} +} \ No newline at end of file diff --git a/src/main/base/app.ts b/src/main/base/app.ts index b6415152..7aae7e89 100644 --- a/src/main/base/app.ts +++ b/src/main/base/app.ts @@ -1,6 +1,8 @@ -import {app, Menu, nativeImage, Tray} from 'electron'; +import {app, Menu, nativeImage, Tray, ipcMain, clipboard, shell} from 'electron'; +import {readFileSync} from "fs"; import * as path from 'path'; -import {utils} from './utils' +import * as log from 'electron-log'; +import {utils} from './utils'; export class AppEvents { private protocols: string[] = [ @@ -24,6 +26,7 @@ export class AppEvents { * @returns {void} */ private start(): void { + AppEvents.initLogging() console.info('[AppEvents] App started'); /********************************************************************************************************************** @@ -169,6 +172,18 @@ export class AppEvents { let url = arg.split('//')[1] console.warn(`[LinkHandler] Attempting to load url: ${url}`); utils.getWindow().webContents.send('play', 'url', url) + } else if (arg.includes('/debug/appdata')) { + shell.openPath(app.getPath('userData')) + } else if (arg.includes('/debug/logs')) { + shell.openPath(app.getPath('logs')) + } else if (arg.includes('/discord')) { + shell.openExternal('https://discord.gg/applemusic') + } else if (arg.includes('/github')) { + shell.openExternal('https://github.com/ciderapp/cider') + } else if (arg.includes('/donate')) { + shell.openExternal('https://opencollective.com/ciderapp') + } else if (arg.includes('/beep')) { + shell.beep() } } @@ -264,7 +279,7 @@ export class AppEvents { const menu = Menu.buildFromTemplate([ { - label: (visible ? this.i18n['action.tray.minimize'] : this.i18n['action.tray.show'].includes("{appName}") ? `${this.i18n['action.tray.show'].replace("{appName}", app.getName())}` : `${this.i18n['action.tray.show']} ${app.getName()}`), + label: (visible ? this.i18n['action.tray.minimize'] : `${this.i18n['action.tray.show']} ${app.getName()}`), click: () => { if (utils.getWindow()) { if (visible) { @@ -284,4 +299,18 @@ export class AppEvents { ]) this.tray.setContextMenu(menu) } + + /** + * Initializes logging in the application + * @private + */ + private static initLogging() { + log.transports.console.format = '[{h}:{i}:{s}.{ms}] [{level}] {text}'; + Object.assign(console, log.functions); + + ipcMain.on('fetch-log', (_event) => { + const data = readFileSync(log.transports.file.getFile().path, {encoding: 'utf8', flag: 'r'}); + clipboard.writeText(data) + }) + } } diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts index d7729c16..991ccbdf 100644 --- a/src/main/base/browserwindow.ts +++ b/src/main/base/browserwindow.ts @@ -1,31 +1,24 @@ -import * as path from "path"; -import {app, BrowserWindow as bw, ipcMain, shell} from "electron"; +import {join} from "path"; +import {app, BrowserWindow as bw, ipcMain, ShareMenu, shell} from "electron"; import * as windowStateKeeper from "electron-window-state"; import * as express from "express"; import * as getPort from "get-port"; -import * as yt from "youtube-search-without-api-key"; -import * as fs from "fs"; +import {search} from "youtube-search-without-api-key"; +import {existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync} from "fs"; import {Stream} from "stream"; -import * as qrcode from "qrcode-terminal"; -import * as os from "os"; +import {networkInterfaces} from "os"; import * as mm from 'music-metadata'; import fetch from 'electron-fetch' import {wsapi} from "./wsapi"; import {jsonc} from "jsonc"; -import {NsisUpdater} from "electron-updater"; -import {utils} from './utils' +import {AppImageUpdater, NsisUpdater} from "electron-updater"; +import {utils} from './utils'; + export class BrowserWindow { public static win: any | undefined = null; private devMode: boolean = !app.isPackaged; - private paths: any = { - srcPath: path.join(__dirname, "../../src"), - resourcePath: path.join(__dirname, "../../resources"), - ciderCache: path.resolve(app.getPath("userData"), "CiderCache"), - themes: path.resolve(app.getPath("userData"), "Themes"), - plugins: path.resolve(app.getPath("userData"), "Plugins"), - }; private audioStream: any = new Stream.PassThrough(); private clientPort: number = 0; private remotePort: number = 6942; @@ -33,11 +26,55 @@ export class BrowserWindow { env: { platform: process.platform, dev: app.isPackaged, + components: [ + "pages/podcasts", + "pages/apple-account-settings", + "pages/library-songs", + "pages/browse", + "pages/settings", + "pages/listen_now", + "pages/home", + "pages/artist-feed", + "pages/cider-playlist", + "pages/playlist-inline", + "pages/recordLabel", + "pages/collection-list", + "pages/apple-curator", + "pages/artist", + "pages/search", + "pages/about", + "pages/library-videos", + "components/mediaitem-artwork", + "components/artwork-material", + "components/menu-panel", + "components/sidebar-playlist", + "components/spatial-properties", + "components/audio-settings", + "components/qrcode-modal", + "components/equalizer", + "components/add-to-playlist", + "components/queue", + "components/mediaitem-scroller-horizontal", + "components/mediaitem-scroller-horizontal-large", + "components/mediaitem-scroller-horizontal-sp", + "components/mediaitem-scroller-horizontal-mvview", + "components/mediaitem-list-item", + "components/mediaitem-hrect", + "components/mediaitem-square", + "components/mediaitem-mvview", + "components/libraryartist-item", + "components/listennow-child", + "components/mediaitem-mvview-sp", + "components/animatedartwork-view", + "components/lyrics-view", + "components/fullscreen", + "components/miniplayer", + ] }, }; private options: any = { - icon: path.join( - this.paths.resourcePath, + icon: join( + utils.getPath('resourcePath'), `icons/icon.` + (process.platform === "win32" ? "ico" : "png") ), width: 1024, @@ -48,11 +85,13 @@ export class BrowserWindow { minHeight: 390, frame: false, title: "Cider", - vibrancy: "dark", + vibrancy: "fullscreen-ui", transparent: process.platform === "darwin", hasShadow: false, show: false, backgroundColor: "#1E1E1E", + titleBarStyle: 'hidden', + trafficLightPosition: {x: 15, y: 20}, webPreferences: { nodeIntegration: true, sandbox: true, @@ -62,7 +101,7 @@ export class BrowserWindow { plugins: true, nodeIntegrationInWorker: false, webSecurity: false, - preload: path.join(this.paths.srcPath, "./preload/cider-preload.js"), + preload: join(utils.getPath('srcPath'), "./preload/cider-preload.js"), }, }; @@ -71,7 +110,7 @@ export class BrowserWindow { */ async createWindow(): Promise { this.clientPort = await getPort({port: 9000}); - this.verifyFiles(); + BrowserWindow.verifyFiles(); // Load the previous state with fallback to defaults const windowState = windowStateKeeper({ @@ -101,7 +140,7 @@ export class BrowserWindow { /** * Verifies the files for the renderer to use (Cache, library info, etc.) */ - private verifyFiles(): void { + private static verifyFiles(): void { const expectedDirectories = ["CiderCache"]; const expectedFiles = [ "library-songs.json", @@ -112,19 +151,19 @@ export class BrowserWindow { ]; for (let i = 0; i < expectedDirectories.length; i++) { if ( - !fs.existsSync( - path.join(app.getPath("userData"), expectedDirectories[i]) + !existsSync( + join(app.getPath("userData"), expectedDirectories[i]) ) ) { - fs.mkdirSync( - path.join(app.getPath("userData"), expectedDirectories[i]) + mkdirSync( + join(app.getPath("userData"), expectedDirectories[i]) ); } } for (let i = 0; i < expectedFiles.length; i++) { - const file = path.join(this.paths.ciderCache, expectedFiles[i]); - if (!fs.existsSync(file)) { - fs.writeFileSync(file, JSON.stringify([])); + const file = join(utils.getPath('ciderCache'), expectedFiles[i]); + if (!existsSync(file)) { + writeFileSync(file, JSON.stringify([])); } } } @@ -135,8 +174,8 @@ export class BrowserWindow { private startWebServer(): void { const app = express(); - app.use(express.static(path.join(this.paths.srcPath, "./renderer/"))); - app.set("views", path.join(this.paths.srcPath, "./renderer/views")); + app.use(express.static(join(utils.getPath('srcPath'), "./renderer/"))); + app.set("views", join(utils.getPath('srcPath'), "./renderer/views")); app.set("view engine", "ejs"); let firstRequest = true; app.use((req, res, next) => { @@ -155,6 +194,53 @@ export class BrowserWindow { res.render("main", this.EnvironmentVariables); }); + app.get("/api/playback/:action", (req, res) => { + const action = req.params.action; + switch (action) { + case "playpause": + BrowserWindow.win.webContents.executeJavaScript("wsapi.togglePlayPause()") + res.send("Play/Pause toggle") + break; + case "play": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().play()") + res.send("Playing") + break; + case "pause": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().pause()") + res.send("Paused") + break; + case "stop": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().stop()") + res.send("Stopped") + break; + case "next": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().skipToNextItem()") + res.send("Next") + break; + case "previous": + BrowserWindow.win.webContents.executeJavaScript("MusicKit.getInstance().skipToPreviousItem()") + res.send("Previous") + break; + default: { + res.send("Invalid action") + } + } + }) + + app.get("/themes/:theme", (req, res) => { + const theme = req.params.theme.toLowerCase(); + const themePath = join(utils.getPath('srcPath'), "./renderer/themes/", theme); + const userThemePath = join(utils.getPath('themes'), theme); + if (existsSync(userThemePath)) { + res.sendFile(userThemePath); + } else if (existsSync(themePath)) { + res.sendFile(themePath); + } else { + res.send(`// Theme not found - ${userThemePath}`); + } + + }); + app.get("/audio.webm", (req, res) => { try { req.socket.setTimeout(Number.MAX_SAFE_INTEGER); @@ -183,13 +269,12 @@ export class BrowserWindow { }); /* - * Remote Client (I had no idea how to add it to our existing express server, so I just made another one) -@quacksire - * TODO: Broadcast the remote so that /web-remote/ can connect - * https://github.com/ciderapp/Apple-Music-Electron/blob/818ed18940ff600d76eb59d22016723a75885cd5/resources/functions/handler.js#L1173 + * Remote Client -@quacksire + * https://github.com/ciderapp/Apple-Music-Electron/blob/818189ed40ff600d76eb59d22016723a75885cd5/resources/functions/handler.js#L1173 */ const remote = express(); - remote.use(express.static(path.join(this.paths.srcPath, "./web-remote/"))) - remote.set("views", path.join(this.paths.srcPath, "./web-remote/views")); + remote.use(express.static(join(utils.getPath('srcPath'), "./web-remote/"))) + remote.set("views", join(utils.getPath('srcPath'), "./web-remote/views")); remote.set("view engine", "ejs"); getPort({port: 6942}).then((port) => { this.remotePort = port; @@ -197,17 +282,6 @@ export class BrowserWindow { this.broadcastRemote() remote.listen(this.remotePort, () => { console.log(`Cider remote port: ${this.remotePort}`); - if (firstRequest) { - console.log("---- Ignore Me ;) ---"); - qrcode.generate(`http://${os.hostname}:${this.remotePort}`); - console.log("---- Ignore Me ;) ---"); - /* - * - * USING https://www.npmjs.com/package/qrcode-terminal for terminal - * WE SHOULD USE https://www.npmjs.com/package/qrcode for the remote (or others) for showing to user via an in-app dialog - * -@quacksire - */ - } firstRequest = false; }) remote.get("/", (_req, res) => { @@ -281,16 +355,24 @@ export class BrowserWindow { event.returnValue = process.platform; }); + ipcMain.on("get-themes", (event, _key) => { + if (existsSync(utils.getPath("themes"))) { + event.returnValue = readdirSync(utils.getPath("themes")); + } else { + event.returnValue = []; + } + }); + ipcMain.on("get-i18n", (event, key) => { event.returnValue = utils.getLocale(key); }); ipcMain.on("get-i18n-listing", event => { - let i18nFiles = fs.readdirSync(path.join(__dirname, "../../src/i18n")).filter(file => file.endsWith(".jsonc")); + let i18nFiles = readdirSync(join(__dirname, "../../src/i18n")).filter(file => file.endsWith(".jsonc")); // read all the files and parse them let i18nListing = [] for (let i = 0; i < i18nFiles.length; i++) { - const i18n: { [index: string]: Object } = jsonc.parse(fs.readFileSync(path.join(__dirname, `../../src/i18n/${i18nFiles[i]}`), "utf8")); + const i18n: { [index: string]: Object } = jsonc.parse(readFileSync(join(__dirname, `../../src/i18n/${i18nFiles[i]}`), "utf8")); i18nListing.push({ "code": i18nFiles[i].replace(".jsonc", ""), "nameNative": i18n["i18n.languageName"] ?? i18nFiles[i].replace(".jsonc", ""), @@ -311,75 +393,75 @@ export class BrowserWindow { }); ipcMain.on("put-library-songs", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-songs.json"), + writeFileSync( + join(utils.getPath('ciderCache'), "library-songs.json"), JSON.stringify(arg) ); }); ipcMain.on("put-library-artists", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-artists.json"), + writeFileSync( + join(utils.getPath('ciderCache'), "library-artists.json"), JSON.stringify(arg) ); }); ipcMain.on("put-library-albums", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-albums.json"), + writeFileSync( + join(utils.getPath('ciderCache'), "library-albums.json"), JSON.stringify(arg) ); }); ipcMain.on("put-library-playlists", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-playlists.json"), + writeFileSync( + join(utils.getPath('ciderCache'), "library-playlists.json"), JSON.stringify(arg) ); }); ipcMain.on("put-library-recentlyAdded", (_event, arg) => { - fs.writeFileSync( - path.join(this.paths.ciderCache, "library-recentlyAdded.json"), + writeFileSync( + join(utils.getPath('ciderCache'), "library-recentlyAdded.json"), JSON.stringify(arg) ); }); ipcMain.on("get-library-songs", (event) => { - let librarySongs = fs.readFileSync( - path.join(this.paths.ciderCache, "library-songs.json"), + let librarySongs = readFileSync( + join(utils.getPath('ciderCache'), "library-songs.json"), "utf8" ); event.returnValue = JSON.parse(librarySongs); }); ipcMain.on("get-library-artists", (event) => { - let libraryArtists = fs.readFileSync( - path.join(this.paths.ciderCache, "library-artists.json"), + let libraryArtists = readFileSync( + join(utils.getPath('ciderCache'), "library-artists.json"), "utf8" ); event.returnValue = JSON.parse(libraryArtists); }); ipcMain.on("get-library-albums", (event) => { - let libraryAlbums = fs.readFileSync( - path.join(this.paths.ciderCache, "library-albums.json"), + let libraryAlbums = readFileSync( + join(utils.getPath('ciderCache'), "library-albums.json"), "utf8" ); event.returnValue = JSON.parse(libraryAlbums); }); ipcMain.on("get-library-playlists", (event) => { - let libraryPlaylists = fs.readFileSync( - path.join(this.paths.ciderCache, "library-playlists.json"), + let libraryPlaylists = readFileSync( + join(utils.getPath('ciderCache'), "library-playlists.json"), "utf8" ); event.returnValue = JSON.parse(libraryPlaylists); }); ipcMain.on("get-library-recentlyAdded", (event) => { - let libraryRecentlyAdded = fs.readFileSync( - path.join(this.paths.ciderCache, "library-recentlyAdded.json"), + let libraryRecentlyAdded = readFileSync( + join(utils.getPath('ciderCache'), "library-recentlyAdded.json"), "utf8" ); event.returnValue = JSON.parse(libraryRecentlyAdded); @@ -387,14 +469,14 @@ export class BrowserWindow { ipcMain.handle("getYTLyrics", async (_event, track, artist) => { const u = track + " " + artist + " official video"; - return await yt.search(u); + return await search(u); }); - ipcMain.on("close", () => { + ipcMain.on("close", (_event) => { BrowserWindow.win.close(); }); - ipcMain.on("maximize", () => { + ipcMain.on("maximize", (_event) => { // listen for maximize event if (BrowserWindow.win.isMaximized()) { BrowserWindow.win.unmaximize(); @@ -443,18 +525,27 @@ export class BrowserWindow { ipcMain.on('play', (_event, type, id) => { BrowserWindow.win.webContents.executeJavaScript(` - MusicKit.getInstance().setQueue({ ${type}: '${id}'}).then(function(queue) { - MusicKit.getInstance().play(); - }); - `) - }) + MusicKit.getInstance().setQueue({ ${type}: '${id}'}).then(function(queue) { + MusicKit.getInstance().play(); + }); + `) + }); //QR Code - ipcMain.handle('showQR', async (event, _) => { + ipcMain.handle('showQR', async (_event, _) => { let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`; shell.openExternal(`https://cider.sh/pair-remote?url=${Buffer.from(encodeURI(url)).toString('base64')}`).catch(console.error); - }) + }); + ipcMain.on('get-remote-pair-url', (_event, _) => { + let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`; + BrowserWindow.win.webContents.send('send-remote-pair-url', url); + }); + if (process.platform === "darwin") { + app.setUserActivity('com.CiderCollective.remote.pair', { + ip: `${BrowserWindow.getIP()}` + }, `http://${BrowserWindow.getIP()}:${this.remotePort}`); + } // Get previews for normalization ipcMain.on("getPreviewURL", (_event, url) => { @@ -466,19 +557,49 @@ export class BrowserWindow { console.log('sc', SoundCheckTag) BrowserWindow.win.webContents.send('SoundCheckTag', SoundCheckTag) }).catch(err => { - console.log(err) - }); + console.log(err) + }); }); - ipcMain.on('check-for-update', async (_event, url) => { + ipcMain.on('check-for-update', async (_event) => { + const branch = utils.getStoreValue('general.update_branch') + let latestbranch = await fetch(`https://circleci.com/api/v1.1/project/gh/ciderapp/Cider/latest/artifacts?branch=${branch}&filter=successful`) + if (latestbranch.status != 200) { + console.log(`Error fetching latest artifact from the **${branch}** branch`) + return + } + + let latestbranchjson = await latestbranch.json() + let base_url = latestbranchjson[0].url + base_url = base_url.substr(0, base_url.lastIndexOf('/')) + const options: any = { provider: 'generic', - url: 'https://43-429851205-gh.circle-artifacts.com/0/%7E/Cider/dist/artifacts' //Base URL + url: `${base_url}` } - const autoUpdater = new NsisUpdater(options) //Windows Only (for now) -q - await autoUpdater.checkForUpdatesAndNotify() + /* + * Have to handle the auto updaters seperatly until we can support macOS. electron-builder limitation -q + */ + const win_autoUpdater = new NsisUpdater(options) //Windows + const linux_autoUpdater = new AppImageUpdater(options) //Linux + await win_autoUpdater.checkForUpdatesAndNotify() + await linux_autoUpdater.checkForUpdatesAndNotify() + }); + + ipcMain.on('share-menu', async (_event, url) => { + if (process.platform != 'darwin') return; + //https://www.electronjs.org/docs/latest/api/share-menu + console.log('[Share Sheet - App.ts]', url) + const options = { + title: 'Share', + urls: [url] + }; + // @ts-ignore + const shareMenu = new ShareMenu(options); + shareMenu.popup(); }) + /* ********************************************************************************************* * Window Events * **********************************************************************************************/ @@ -545,10 +666,14 @@ export class BrowserWindow { }); } + /** + * Gets ip + * @private + */ private static getIP(): string { let ip: string = ''; let alias = 0; - const ifaces: any = os.networkInterfaces(); + const ifaces: any = networkInterfaces(); for (let dev in ifaces) { ifaces[dev].forEach((details: any) => { if (details.family === 'IPv4') { diff --git a/src/main/base/store.ts b/src/main/base/store.ts index 54ca5ba9..df5edc19 100644 --- a/src/main/base/store.ts +++ b/src/main/base/store.ts @@ -6,12 +6,13 @@ export class Store { private defaults: any = { "general": { - "close_button_hide": true, + "close_button_hide": false, "open_on_startup": false, "discord_rpc": 1, // 0 = disabled, 1 = enabled as Cider, 2 = enabled as Apple Music "discord_rpc_clear_on_pause": true, "language": "en_US", // electron.app.getLocale().replace('-', '_') this can be used in future - "playbackNotifications": true + "playbackNotifications": true, + "update_branch": "main" }, "home": { "followedArtists": [], @@ -26,16 +27,15 @@ export class Store { }, "audio": { "volume": 1, + "volumeStep": 0.02, "lastVolume": 1, "muted": false, - "quality": "256", + "quality": "HIGH", "seamless_audio": true, "normalization": false, + "ciderPPE": false, + "ciderPPE_value": 0.5, "spatial": false, - "maxVolume": 1, - "volumePrecision": 0.1, - "volumeRoundMax": 0.9, - "volumeRoundMin": 0.1, "spatial_properties": { "presets": [], "gain": 0.8, @@ -59,10 +59,9 @@ export class Store { 'preset': "default", 'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000], 'gain': [0,0,0,0,0,0,0,0,0,0], - 'Q' : [1,1,1,1,1,1,1,1,1,1], - 'preamp' : 0, - 'mix' : 1, - 'vibrantBass' : 0, + 'Q': [1,1,1,1,1,1,1,1,1,1], + 'mix': 1, + 'vibrantBass': 0, 'presets': [], 'userGenerated': false }, @@ -142,11 +141,11 @@ export class Store { * IPC Handler */ private ipcHandler(): void { - electron.ipcMain.handle('getStoreValue', (event, key, defaultValue) => { + electron.ipcMain.handle('getStoreValue', (_event, key, defaultValue) => { return (defaultValue ? Store.cfg.get(key, true) : Store.cfg.get(key)); }); - electron.ipcMain.handle('setStoreValue', (event, key, value) => { + electron.ipcMain.handle('setStoreValue', (_event, key, value) => { Store.cfg.set(key, value); }); @@ -154,7 +153,7 @@ export class Store { event.returnValue = Store.cfg.store }) - electron.ipcMain.on('setStore', (event, store) => { + electron.ipcMain.on('setStore', (_event, store) => { Store.cfg.store = store }) } diff --git a/src/main/base/utils.ts b/src/main/base/utils.ts index 89301c0f..96b937d0 100644 --- a/src/main/base/utils.ts +++ b/src/main/base/utils.ts @@ -3,9 +3,33 @@ import * as path from "path"; import {jsonc} from "jsonc"; import {Store} from "./store"; import {BrowserWindow as bw} from "./browserwindow"; +import {app} from "electron"; export class utils { + /** + * Paths for the application to use + */ + private static paths: any = { + srcPath: path.join(__dirname, "../../src"), + rendererPath: path.join(__dirname, "../../src/renderer"), + mainPath: path.join(__dirname, "../../src/main"), + resourcePath: path.join(__dirname, "../../resources"), + i18nPath: path.join(__dirname, "../../src/i18n"), + ciderCache: path.resolve(app.getPath("userData"), "CiderCache"), + themes: path.resolve(app.getPath("userData"), "Themes"), + plugins: path.resolve(app.getPath("userData"), "Plugins"), + }; + + /** + * Get the path + * @returns {string} + * @param name + */ + static getPath(name: string): string { + return this.paths[name]; + } + /** * Fetches the i18n locale for the given language. * @param language {string} The language to fetch the locale for. @@ -13,10 +37,10 @@ export class utils { * @returns {string | Object} The locale value. */ static getLocale(language: string, key?: string): string | object { - let i18n: { [index: string]: Object } = jsonc.parse(fs.readFileSync(path.join(__dirname, "../../src/i18n/en_US.jsonc"), "utf8")); + let i18n: { [index: string]: Object } = jsonc.parse(fs.readFileSync(path.join(this.paths.i18nPath, "en_US.jsonc"), "utf8")); - if (language !== "en_US" && fs.existsSync(path.join(__dirname, `../../src/i18n/${language}.jsonc`))) { - i18n = Object.assign(i18n, jsonc.parse(fs.readFileSync(path.join(__dirname, `../../src/i18n/${language}.jsonc`), "utf8"))); + if (language !== "en_US" && fs.existsSync(path.join(this.paths.i18nPath, `${language}.jsonc`))) { + i18n = Object.assign(i18n, jsonc.parse(fs.readFileSync(path.join(this.paths.i18nPath, `${language}.jsonc`), "utf8"))); } if (key) { @@ -58,4 +82,25 @@ export class utils { static getWindow(): Electron.BrowserWindow { return bw.win } + + /** + * Playback Functions + */ + static playback = { + pause: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.pause()") + }, + play: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.play()") + }, + playPause: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.playPause()") + }, + next: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.next()") + }, + previous: () => { + bw.win.webContents.executeJavaScript("MusicKitInterop.previous()") + } + } } \ No newline at end of file diff --git a/src/main/plugins/menubar.ts b/src/main/plugins/menubar.ts new file mode 100644 index 00000000..ec484b40 --- /dev/null +++ b/src/main/plugins/menubar.ts @@ -0,0 +1,239 @@ +import {app, Menu, shell} from "electron"; + +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) + */ + public name: string = 'Menubar Plugin'; + public description: string = 'Creates the menubar'; + public version: string = '1.0.0'; + public author: string = 'Core / Quack'; + + /** + * 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(), + } + */ + + /** + * Menubar Assets + * @private + */ + private isMac: boolean = process.platform === 'darwin'; + private menubarTemplate: any = [ + { + label: app.getName(), + submenu: [ + { role: 'about' }, + { type: 'separator' }, + { role: 'services' }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideOthers' }, + { role: 'unhide' }, + { type: 'separator' }, + { role: 'quit' } + ] + }, + { + label: 'View', + submenu: [ + {role: 'reload'}, + {role: 'forceReload'}, + {role: 'toggleDevTools'}, + {type: 'separator'}, + {role: 'resetZoom'}, + {role: 'zoomIn'}, + {role: 'zoomOut'}, + {type: 'separator'}, + {role: 'togglefullscreen'}, + ] + }, + { + label: 'Window', + submenu: [ + {role: 'minimize'}, + {role: 'zoom'}, + ...(this.isMac ? [ + {type: 'separator'}, + {role: 'front'}, + {type: 'separator'}, + {role: 'window'} + ] : [ + {role: 'close'} + ]), + {type: 'separator'}, + { + label: 'Web Remote', + accelerator: 'CommandOrControl+Shift+W', + sublabel: 'Opens in external window', + click: () => this._win.webContents.executeJavaScript(`ipcRenderer.invoke('showQR')`) + }, + { + label: 'Audio Settings', + accelerator: 'CommandOrControl+Shift+A', + click: () => this._win.webContents.executeJavaScript(`app.modals.audioSettings = true`) + }, + { + label: 'Settings', + accelerator: 'CommandOrControl+,', + click: () => this._win.webContents.executeJavaScript(`app.appRoute('settings')`) + } + ] + }, + { + label: 'Controls', + submenu: [ + { + label: 'Pause / Play', + accelerator: 'Space', + click: () => this._win.webContents.executeJavaScript(`MusicKitInterop.playPause()`) + }, + { + label: 'Next', + accelerator: 'CommandOrControl+Right', + click: () => this._win.webContents.executeJavaScript(`MusicKitInterop.next()`) + }, + { + label: 'Previous', + accelerator: 'CommandOrControl+Left', + click: () => this._win.webContents.executeJavaScript(`MusicKitInterop.previous()`) + }, + { type: 'separator' }, + { + label: 'Volume Up', + accelerator: 'CommandOrControl+Up', + click: () => this._win.webContents.executeJavaScript(`app.volumeUp()`) + }, + { + label: 'Volume Down', + accelerator: 'CommandOrControl+Down', + click: () => this._win.webContents.executeJavaScript(`app.volumeDown()`) + } + ] + }, + { + label: 'Account', + submenu: [ + { + label: 'Account Settings', + click: () => this._win.webContents.executeJavaScript(`app.appRoute('apple-account-settings')`) + }, + { + label: 'Sign Out', + click: () => this._win.webContents.executeJavaScript(`app.unauthorize()`) + } + ] + }, + { + label: 'Support', + role: 'help', + submenu: [ + { + label: 'Discord', + click: () => shell.openExternal("https://discord.gg/AppleMusic").catch(console.error) + }, + { + label: 'GitHub Wiki', + click: () => shell.openExternal("https://github.com/ciderapp/Cider/wiki/Troubleshooting").catch(console.error) + }, + { + label: 'About', + click: () => this._win.webContents.executeJavaScript(`app.appRoute('about')`) + }, + {type: 'separator'}, + { + label: 'Report a...', + submenu: [ + { + label: 'Bug', + click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug%2Ctriage&template=bug_report.yaml&title=%5BBug%5D%3A+").catch(console.error) + }, + { + label: 'Feature Request', + click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=enhancement%2Ctriage&template=feature_request.yaml&title=%5BEnhancement%5D%3A+").catch(console.error) + }, + { + label: 'Translation Report/Request', + click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=%F0%9F%8C%90+Translations&template=translation.yaml&title=%5BTranslation%5D%3A+").catch(console.error) + }, + ] + }, + {type: 'separator'}, + { + label: 'View License', + click: () => shell.openExternal("https://github.com/ciderapp/Cider/blob/main/LICENSE").catch(console.error) + }, + {type: 'separator'}, + { + label: 'Toggle Developer Tools', + accelerator: 'Option+CommandOrControl+I', + click: () => this._win.webContents.openDevTools() + }, + { + label: 'Open Configuration File in Editor', + click: () => this._store.openInEditor() + } + ] + } + ] + + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(app: any, store: any) { + this._app = app; + this._store = store + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } + + /** + * Runs on app ready + */ + onReady(win: Electron.BrowserWindow): void { + this._win = win; + Menu.setApplicationMenu(Menu.buildFromTemplate(this.menubarTemplate)) + } + + /** + * Runs on app stop + */ + onBeforeQuit(): void { + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: object): void { + + } + + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: object): void { + + } + +} diff --git a/src/main/plugins/thumbar.ts b/src/main/plugins/thumbar.ts new file mode 100644 index 00000000..2ba1f1a9 --- /dev/null +++ b/src/main/plugins/thumbar.ts @@ -0,0 +1,133 @@ +import {nativeImage, nativeTheme} from "electron"; +import {utils} from "../base/utils"; +import {join} from "path"; + +export default class Thumbar { + /** + * Private variables for interaction in plugins + */ + private _win: any; + private _app: any; + + /** + * Base Plugin Details (Eventually implemented into a GUI in settings) + */ + public name: string = 'Thumbnail Toolbar Plugin'; + public description: string = 'Creates and managed the thumbnail toolbar buttons and their events'; + public version: string = '1.0.0'; + public author: string = 'Core'; + + /** + * Thumbnail Toolbar Assets + */ + private icons: { [key: string]: Electron.NativeImage } = { + pause: nativeImage.createFromPath(join(utils.getPath('resourcePath'), 'icons/thumbar', `${nativeTheme.shouldUseDarkColors ? 'light' : 'dark'}_pause.png`)), + play: nativeImage.createFromPath(join(utils.getPath('resourcePath'), 'icons/thumbar', `${nativeTheme.shouldUseDarkColors ? 'light' : 'dark'}_play.png`)), + next: nativeImage.createFromPath(join(utils.getPath('resourcePath'), 'icons/thumbar', `${nativeTheme.shouldUseDarkColors ? 'light' : 'dark'}_next.png`)), + previous: nativeImage.createFromPath(join(utils.getPath('resourcePath'), 'icons/thumbar', `${nativeTheme.shouldUseDarkColors ? 'light' : 'dark'}_previous.png`)), + } + + /******************************************************************************************* + * Private Methods + * ****************************************************************************************/ + + /** + * Blocks non-windows systems from running this plugin + * @private + * @decorator + */ + private static windowsOnly(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) { + if (process.platform !== 'win32') { + descriptor.value = function () { + return + } + } + } + + /** + * Update the thumbnail toolbar + */ + @Thumbar.windowsOnly + private updateButtons(attributes: any) { + + console.log(attributes) + + if (!attributes) { + return + } + + const buttons = [ + { + tooltip: 'Previous', + icon: this.icons.previous, + click() { + utils.playback.previous() + } + }, + { + tooltip: attributes.status ? 'Pause' : 'Play', + icon: attributes.status ? this.icons.pause : this.icons.play, + click() { + utils.playback.playPause() + } + }, + { + tooltip: 'Next', + icon: this.icons.next, + click() { + utils.playback.next() + } + } + ]; + + if (!attributes.playParams || attributes.playParams.id === 'no-id-found') { + this._win.setThumbarButtons([]) + } else { + this._win.setThumbarButtons(buttons); + } + } + + /******************************************************************************************* + * Public Methods + * ****************************************************************************************/ + + /** + * Runs on plugin load (Currently run on application start) + */ + constructor(app: any, _store: any) { + this._app = app; + console.debug(`[Plugin][${this.name}] Loading Complete.`); + } + + /** + * Runs on app ready + */ + onReady(win: Electron.BrowserWindow): void { + this._win = win; + console.debug(`[Plugin][${this.name}] Ready.`); + } + + /** + * Runs on app stop + */ + onBeforeQuit(): void { + console.debug(`[Plugin][${this.name}] Stopped.`); + } + + /** + * Runs on playback State Change + * @param attributes Music Attributes (attributes.status = current state) + */ + onPlaybackStateDidChange(attributes: object): void { + this.updateButtons(attributes) + } + + /** + * Runs on song change + * @param attributes Music Attributes + */ + onNowPlayingItemDidChange(attributes: object): void { + this.updateButtons(attributes) + } + +} diff --git a/src/renderer/assets/ppe.svg b/src/renderer/assets/ppe.svg new file mode 100644 index 00000000..49848f52 --- /dev/null +++ b/src/renderer/assets/ppe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/audio/audio.js b/src/renderer/audio/audio.js index 56b2ad01..c22ef29c 100644 --- a/src/renderer/audio/audio.js +++ b/src/renderer/audio/audio.js @@ -8,6 +8,8 @@ var CiderAudio = { audioBands : null, preampNode : null, vibrantbassNode: null, + llpw: null, + llpwEnabled: null }, init: function (cb = function () { }) { //AudioOutputs.fInit = true; @@ -29,14 +31,29 @@ var CiderAudio = { try{ CiderAudio.audioNodes.spatialNode.disconnect();} catch(e){} try{ CiderAudio.audioNodes.preampNode.disconnect(); - CiderAudio.audioNodes.vibrantbassNode.disconnect(); - CiderAudio.audioNodes.audioBands[0].disconnect(); - CiderAudio.audioNodes.audioBands[9].disconnect(); + for (var i of CiderAudio.audioNodes.llpw){ + i.disconnect(); + } + for (var i of CiderAudio.audioNodes.vibrantbassNode){ + i.disconnect(); + } + for (var i of CiderAudio.audioNodes.audioBands){ + i.disconnect(); + } } catch(e){} + try{ + CiderAudio.audioNodes = { + gainNode : null, + spatialNode : null, + spatialInput: null, + audioBands : null, + preampNode : null, + vibrantbassNode: null, + } + } catch (e) {} CiderAudio.source.connect(CiderAudio.context.destination);} catch(e){} }, connectContext: function (mediaElem){ - if (!CiderAudio.context){ CiderAudio.context = new (window.AudioContext || window.webkitAudioContext); } @@ -109,7 +126,10 @@ var CiderAudio = { let VIBRANTBASSBANDS = app.cfg.audio.vibrantBass.frequencies; let VIBRANTBASSGAIN = app.cfg.audio.vibrantBass.gain; let VIBRANTBASSQ = app.cfg.audio.vibrantBass.Q; - CiderAudio.audioNodes.audioBands = []; CiderAudio.audioNodes.vibrantbassNode = []; + let LLPW_Q = [5, 1, 3.536, 1.25, 8.409, 1.25, 14.14, 7.071, 5, 0.625, 16.82, 20, 20, 20, 28.28, 28.28, 28.28, 20, 33.64, 33.64, 10, 28.28, 7.071, 3.856]; + let LLPW_GAIN = [0.38, -1.81, -0.23, -0.51, 0.4, 0.84, 0.36, -0.34, 0.27, -1.2, -0.42, -0.67, 0.81, 1.31, -0.71, 0.68, -1.04, 0.79, -0.73, -1.33, 1.17, 0.57, 0.35, 6.33]; + let LLPW_FREQUENCIES = [16.452, 24.636, 37.134, 74.483, 159.54, 308.18, 670.21, 915.81, 1200.7, 2766.4, 2930.6, 4050.6, 4409.1, 5395.2, 5901.6, 6455.5, 7164.1, 7724.1, 8449, 10573, 12368, 14198, 17910, 18916]; + CiderAudio.audioNodes.audioBands = []; CiderAudio.audioNodes.vibrantbassNode = []; CiderAudio.audioNodes.llpw = []; for (i = 0; i < BANDS.length; i++) { CiderAudio.audioNodes.audioBands[i] = CiderAudio.context.createBiquadFilter(); @@ -119,18 +139,27 @@ var CiderAudio = { CiderAudio.audioNodes.audioBands[i].gain.value = GAIN[i] * app.cfg.audio.equalizer.mix; } + for (i = 0; i < LLPW_FREQUENCIES.length; i++) { + CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); + CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking'; + CiderAudio.audioNodes.llpw[i].frequency.value = LLPW_FREQUENCIES[i]; + CiderAudio.audioNodes.llpw[i].Q.value = LLPW_Q[i]; + CiderAudio.audioNodes.llpw[i].gain.value = LLPW_GAIN[i] * app.cfg.audio.ciderPPE_value * CiderAudio.audioNodes.llpwEnabled; + } + CiderAudio.audioNodes.preampNode = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.preampNode.type = 'highshelf'; - CiderAudio.audioNodes.preampNode.frequency.value = 0; // allow all - CiderAudio.audioNodes.preampNode.gain.value = app.cfg.audio.equalizer.preamp; + CiderAudio.audioNodes.preampNode.frequency.value = 0; // Passthrough + if (CiderAudio.audioNodes.llpwEnabled === 1) {CiderAudio.audioNodes.preampNode.gain.value = (-Math.max(...app.cfg.audio.equalizer.gain.concat(CiderAudio.audioNodes.llpw[23].gain.value)));} + else {CiderAudio.audioNodes.preampNode.gain.value = (-Math.max(...app.cfg.audio.equalizer.gain));} for (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].Q.value = VIBRANTBASSQ[i]; - CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * app.cfg.audio.vibrantBass.multiplier; - } + 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].Q.value = VIBRANTBASSQ[i]; + CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * app.cfg.audio.vibrantBass.multiplier;} + if (app.cfg.audio.spatial) { try{ @@ -142,12 +171,17 @@ var CiderAudio = { CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.preampNode); } - CiderAudio.audioNodes.preampNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]); + CiderAudio.audioNodes.preampNode.connect(CiderAudio.audioNodes.llpw[0]); + for (i = 1; i < LLPW_FREQUENCIES.length; i ++) { + CiderAudio.audioNodes.llpw[i-1].connect(CiderAudio.audioNodes.llpw[i]); + } + CiderAudio.audioNodes.llpw[LLPW_FREQUENCIES.length-1].connect(CiderAudio.audioNodes.vibrantbassNode[0]); for (i = 1; i < VIBRANTBASSBANDS.length; i ++) { CiderAudio.audioNodes.vibrantbassNode[i-1].connect(CiderAudio.audioNodes.vibrantbassNode[i]); } CiderAudio.audioNodes.vibrantbassNode[VIBRANTBASSBANDS.length-1].connect(CiderAudio.audioNodes.audioBands[0]); + for (i = 1; i < BANDS.length; i ++) { CiderAudio.audioNodes.audioBands[i-1].connect(CiderAudio.audioNodes.audioBands[i]); diff --git a/src/renderer/index.js b/src/renderer/index.js index a7075497..5dc7a5d8 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -1,81 +1,8 @@ Vue.use(VueObserveVisibility); var notyf = new Notyf(); -// This is going to suck to code -var CiderContextMenu = { - Menu: function(event) { - this.items = [] - }, - async Create(event, menudata) { - var menuBackground = document.createElement("div"); - var menu = document.createElement("div"); - menu.classList.add("context-menu-body"); - menu.classList.add("context-menu-open"); - menuBackground.classList.add("context-menu"); - menu.style.left = 0 + "px"; - menu.style.top = 0 + "px"; - menu.style.position = "absolute"; - menu.style.zIndex = "99909"; - menu.addEventListener("animationend", function() { - menu.classList.remove("context-menu-open"); - }, { once: true }); - - function close() { - menuBackground.style.pointerEvents = "none"; - menu.classList.add("context-menu-close"); - menu.addEventListener("animationend", function() { - menuBackground.remove(); - menu.remove(); - }, { once: true }); - } - - // when menubackground is clicked, remove it - menuBackground.addEventListener("click", close); - menuBackground.addEventListener("contextmenu", close); - - // add menu to menuBackground - menuBackground.appendChild(menu); - - document.body.appendChild(menuBackground); - - if (typeof menudata.items == "object") { - menudata.items = Object.values(menudata.items); - } - - console.log(menudata); - - // for each item in menudata create a menu item - for (var i = 0; i < menudata.items.length; i++) { - let item = document.createElement("button") - - if (menudata.items[i]["disabled"] === true) { - continue - } - item.tabIndex = 0 - item.classList.add("context-menu-item") - if (menudata.items[i]["icon"]) { - item.innerHTML += `` - } - item.innerHTML += menudata.items[i].name - item.onclick = menudata.items[i].action - menu.appendChild(item) - } - menu.style.width = (menu.offsetWidth + 10) + "px"; - menu.style.left = event.clientX + "px"; - menu.style.top = event.clientY + "px"; - // if menu would be off the screen, move it into view, but preserve the width - if (menu.offsetLeft + menu.offsetWidth > window.innerWidth) { - menu.style.left = (window.innerWidth - menu.offsetWidth) + "px"; - } - if (menu.offsetTop + menu.offsetHeight > window.innerHeight) { - menu.style.top = (window.innerHeight - menu.offsetHeight) + "px"; - } - - return menuBackground; - } -} const MusicKitObjects = { - LibraryPlaylist: function() { + LibraryPlaylist: function () { this.id = "" this.type = "library-playlist-folders" this.href = "" @@ -99,7 +26,7 @@ const MusicKitTools = { } // limit an array to a certain number of items -Array.prototype.limit = function(n) { +Array.prototype.limit = function (n) { return this.slice(0, n); }; @@ -178,7 +105,7 @@ const app = new Vue({ progress: 0 }, songs: { - sortingOptions: { + sortingOptions: { "albumName": "0", "artistName": "0", "name": "0", @@ -189,7 +116,7 @@ const app = new Vue({ sorting: "name", sortOrder: "asc", listing: [], - meta: { total: 0, progress: 0 }, + meta: {total: 0, progress: 0}, search: "", displayListing: [], downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library @@ -205,7 +132,7 @@ const app = new Vue({ sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page listing: [], - meta: { total: 0, progress: 0 }, + meta: {total: 0, progress: 0}, search: "", displayListing: [], downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library @@ -221,7 +148,7 @@ const app = new Vue({ sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page listing: [], - meta: { total: 0, progress: 0 }, + meta: {total: 0, progress: 0}, search: "", displayListing: [], downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library @@ -233,7 +160,7 @@ const app = new Vue({ loadingState: 0, // 0 loading, 1 loaded, 2 error id: "" }, - webremoteurl : "", + webremoteurl: "", webremoteqr: "", mxmtoken: "", mkIsReady: false, @@ -258,8 +185,8 @@ const app = new Vue({ platform: "web" } }, - tmpHeight : '', - tmpWidth : '', + tmpHeight: '', + tmpWidth: '', tmpVar: [], notification: false, chrome: { @@ -270,7 +197,7 @@ const app = new Vue({ "attributes": { "name": "Cider User", "handle": "CiderUser", - "artwork": { "url": "./assets/logocut.png" } + "artwork": {"url": "./assets/logocut.png"} } }, menuOpened: false, @@ -279,7 +206,8 @@ const app = new Vue({ drawerState: "queue", topChromeVisible: true, progresshover: false, - windowControlPosition: "right" + windowControlPosition: "right", + contentAreaScrolling: true }, collectionList: { response: {}, @@ -301,6 +229,7 @@ const app = new Vue({ qrcode: false, equalizer: false, audioSettings: false, + showPlaylist: false, }, socialBadges: { badgeMap: {}, @@ -320,7 +249,7 @@ const app = new Vue({ }, watch: { cfg: { - handler: function(val, oldVal) { + handler: function (val, oldVal) { console.log(`cfg changed from ${oldVal} to ${val}`); ipcRenderer.send("setStore", val); }, @@ -331,8 +260,10 @@ const app = new Vue({ app.resetState() }, showingPlaylist: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() + if (!app.modals.showPlaylist) { + document.getElementById("app-content").scrollTo(0, 0); + app.resetState() + } }, artistPage: () => { document.getElementById("app-content").scrollTo(0, 0); @@ -340,6 +271,34 @@ const app = new Vue({ }, }, methods: { + songLinkShare(amUrl) { + notyf.open({type: "info", message: "Getting song.link share URL..."}) + let self = this + httpRequest = new XMLHttpRequest(); + httpRequest.open('GET', `https://api.song.link/v1-alpha.1/links?url=${amUrl}&userCountry=US`, true); + httpRequest.send(); + httpRequest.onreadystatechange = function () { + if (httpRequest.readyState === 4) { + if (httpRequest.status === 200) { + let response = JSON.parse(httpRequest.responseText); + console.log(response); + self.copyToClipboard(response.pageUrl) + } else { + console.log('There was a problem with the request.'); + notyf.error("There was a problem with the request.") + } + } + } + }, + mainMenuVisibility(val) { + if (val) { + (this.chrome.userinfo.id) ? this.chrome.menuOpened = !this.chrome.menuOpened : false + } else { + setTimeout(() => { + this.chrome.menuOpened = false + }, 100) + } + }, stringTemplateParser(expression, valueObj) { const templateMatcher = /{{\s?([^{}\s]*)\s?}}/g; let text = expression.replace(templateMatcher, (substring, value, index) => { @@ -350,15 +309,15 @@ const app = new Vue({ // stringTemplateParser('my name is {{name}} and age is {{age}}', {name: 'Tom', age:100}) }, setLz(lang) { - if(lang == "") { + if (lang == "") { lang = this.cfg.general.language } this.lz = ipcRenderer.sendSync("get-i18n", lang) }, getLz(message) { - if(this.lz[message]) { + if (this.lz[message]) { return this.lz[message] - }else{ + } else { return message } }, @@ -371,13 +330,13 @@ const app = new Vue({ "releaseDate": app.getLz('term.sortBy.releaseDate'), "durationInMillis": app.getLz('term.sortBy.duration') } - + app.$data.library.albums.sortingOptions = { - "albumName": app.getLz('term.sortBy.album'), - "artistName": app.getLz('term.sortBy.artist'), - "name": app.getLz('term.sortBy.name'), - "genre": app.getLz('term.sortBy.genre') - } + "albumName": app.getLz('term.sortBy.album'), + "artistName": app.getLz('term.sortBy.artist'), + "name": app.getLz('term.sortBy.name'), + "genre": app.getLz('term.sortBy.genre') + } app.$data.library.artists.sortingOptions = { "artistName": app.getLz('term.sortBy.artist'), @@ -388,12 +347,12 @@ const app = new Vue({ }, async showSocialListeningTo() { let contentIds = Object.keys(app.socialBadges.badgeMap) - app.showCollection({ data: this.socialBadges.mediaItems }, "Friends Listening To", "albums") + app.showCollection({data: this.socialBadges.mediaItems}, "Friends Listening To", "albums") if (this.socialBadges.mediaItemDLState == 1 || this.socialBadges.mediaItemDLState == 2) { return } this.socialBadges.mediaItemDLState = 2 - await asyncForEach(contentIds, async(item) => { + await asyncForEach(contentIds, async (item) => { try { let type = "albums" if (item.includes("pl.")) { @@ -438,7 +397,8 @@ const app = new Vue({ let data = await response.text(); return data; }, - getSocialBadges(cb = () => {}) { + getSocialBadges(cb = () => { + }) { let self = this try { app.mk.api.v3.music("/v1/social/badging-map").then(data => { @@ -476,6 +436,7 @@ const app = new Vue({ resetState() { this.menuPanel.visible = false; app.selectedMediaItems = []; + this.chrome.contentAreaScrolling = true for (let key in app.modals) { app.modals[key] = false; } @@ -536,8 +497,8 @@ const app = new Vue({ } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { self.selectedMediaItems[i].kind = "albums" let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function(i) { - return { id: i.id, type: i.type } + let ids = res.data.data.map(function (i) { + return {id: i.id, type: i.type} }) pl_items = pl_items.concat(ids) } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { @@ -549,8 +510,8 @@ const app = new Vue({ } else if ((self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums") || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { self.selectedMediaItems[i].kind = "library-albums" let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function(i) { - return { id: i.id, type: i.type } + let ids = res.data.data.map(function (i) { + return {id: i.id, type: i.type} }) pl_items = pl_items.concat(ids) } else { @@ -579,6 +540,9 @@ const app = new Vue({ }, async init() { let self = this + if (this.cfg.visual.theme != "default.less" && this.cfg.visual.theme != "") { + this.setTheme(this.cfg.visual.theme) + } this.setLz(this.cfg.general.language) this.setLzManual() clearTimeout(this.hangtimer) @@ -586,7 +550,7 @@ const app = new Vue({ let needsReload = (typeof localStorage["music.ampwebplay.media-user-token"] == "undefined") this.mk.authorize().then(() => { self.mkIsReady = true - if(needsReload) { + if (needsReload) { document.location.reload() } }) @@ -594,7 +558,6 @@ const app = new Vue({ if (this.isDev) { this.mk.privateEnabled = true // Hide UserInfo if Dev mode - this.chrome.hideUserInfo = true } else { // Get Hide User from Settings this.chrome.hideUserInfo = !this.cfg.visual.showuserinfo @@ -608,7 +571,8 @@ const app = new Vue({ try { // Set profile name this.chrome.userinfo = (await app.mk.api.v3.music(`/v1/me/social-profile`)).data.data[0] - } catch (err) {} + } catch (err) { + } // API Fallback if (!this.chrome.userinfo) { @@ -617,7 +581,7 @@ const app = new Vue({ "attributes": { "name": "Cider User", "handle": "CiderUser", - "artwork": { "url": "./assets/logocut.png" } + "artwork": {"url": "./assets/logocut.png"} } } } @@ -625,17 +589,16 @@ const app = new Vue({ // Set the volume // Check the value of this.cfg.audio.muted - if( !this.cfg.audio.muted ) - { + if (!this.cfg.audio.muted) { // Set the mk.volume to the last stored volume data this.mk.volume = this.cfg.audio.volume - } else if( this.cfg.audio.muted ) { + } else if (this.cfg.audio.muted) { // Set mk.volume to -1 (setting to 0 wont work, so temp solution setting to -1) this.mk.volume = -1; } - // ipcRenderer.invoke('getStoreValue', 'audio.volume').then((value) => { - // self.mk.volume = value - // }) + // ipcRenderer.invoke('getStoreValue', 'audio.volume').then((value) => { + // self.mk.volume = value + // }) // load cached library if (localStorage.getItem("librarySongs") != null) { @@ -647,29 +610,19 @@ const app = new Vue({ this.library.albums.displayListing = this.library.albums.listing } - window.onbeforeunload = function(e) { + window.onbeforeunload = function (e) { window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem)) window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime)) window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue.items)) }; - // Load saved quality - switch (app.cfg.audio.quality) { - /** case "extreme": - app.mk.bitrate = app.cfg.audio.quality = 990 - break; **/ - case "high": - app.mk.bitrate = app.cfg.audio.quality = 256 - break; - case "low": - app.mk.bitrate = app.cfg.audio.quality = 64 - break; - default: - // app.mk.bitrate = app.cfg.audio.quality - break; + if (typeof MusicKit.PlaybackBitrate[app.cfg.audio.quality] !== "string") { + app.mk.bitrate = MusicKit.PlaybackBitrate[app.cfg.audio.quality] + } else { + app.mk.bitrate = 256 + app.cfg.audio.quality = "HIGH" } - // load last played track try { let lastItem = window.localStorage.getItem("currentTrack") @@ -699,8 +652,9 @@ const app = new Vue({ for (id of ids) { if (!(i == 0 && ids[0] == lastItem.attributes.playParams.id)) { try { - app.mk.playLater({ songs: [id] }) - } catch (err) {} + app.mk.playLater({songs: [id]}) + } catch (err) { + } } i++; } @@ -735,12 +689,13 @@ const app = new Vue({ self.mk.setQueue({[mode]: id}).then(() => { app.mk.play() }) + } else { app.openAppleMusicURL(id) - } + } }); - this.mk.addEventListener(MusicKit.Events.playbackStateDidChange, ()=>{ + this.mk.addEventListener(MusicKit.Events.playbackStateDidChange, () => { ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes()); }) @@ -757,7 +712,7 @@ const app = new Vue({ self.$refs.queue.updateQueue(); } this.currentSongInfo = a - + if (app.cfg.audio.normalization) { // get unencrypted audio previews to get SoundCheck's normalization tag @@ -765,7 +720,8 @@ const app = new Vue({ let previewURL = null try { previewURL = app.mk.nowPlayingItem.previewURL - } catch (e) {} + } catch (e) { + } if (!previewURL) { app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id}`).then((response) => { previewURL = response.data.data[0].attributes.previews[0].url @@ -777,12 +733,15 @@ const app = new Vue({ ipcRenderer.send('getPreviewURL', previewURL) } - } catch (e) {} + } catch (e) { + } } + try { a = a.item.attributes; - } catch (_) {} + } catch (_) { + } let type = (self.mk.nowPlayingItem != null) ? self.mk.nowPlayingItem["type"] ?? '' : ''; if (type.includes("musicVideo") || type.includes("uploadedVideo") || type.includes("music-movie")) { @@ -799,6 +758,7 @@ const app = new Vue({ // app.getNowPlayingArtwork(42); app.getNowPlayingArtworkBG(32); app.loadLyrics(); + app.losslessBadge(); // Playback Notifications if (this.cfg.general.playbackNotifications && !document.hasFocus() && a.artistName && a.artwork && a.name) { @@ -833,6 +793,22 @@ const app = new Vue({ this.$forceUpdate() }, 500) }, + setTheme(theme = "") { + console.log(theme) + if (this.cfg.visual.theme == "") { + this.cfg.visual.theme = "default.less" + } + if (theme == "") { + theme = this.cfg.visual.theme + } else { + this.cfg.visual.theme = theme + } + document.querySelector("#userTheme").href = `themes/${this.cfg.visual.theme}` + document.querySelectorAll(`[id*='less']`).forEach(el => { + el.remove() + }); + less.refresh() + }, unauthorize() { this.mk.unauthorize() document.location.reload() @@ -842,9 +818,9 @@ const app = new Vue({ if (this.cfg.advanced.experiments.includes('compactui')) { classes.compact = true } - if(this.cfg.visual.window_background_style == "none") { + if (this.cfg.visual.window_background_style == "none") { classes.simplebg = true - } + } return classes }, invokeDrawer(panel) { @@ -919,11 +895,11 @@ const app = new Vue({ playlistHeaderContextMenu(event) { let menu = { items: [{ - name: app.getLz('term.createNewPlaylist'), - action: () => { - this.newPlaylist() - } - }, + name: app.getLz('term.createNewPlaylist'), + action: () => { + this.newPlaylist() + } + }, { name: app.getLz('term.createNewPlaylistFolder'), action: () => { @@ -941,7 +917,7 @@ const app = new Vue({ fetchOptions: { method: "PATCH", body: JSON.stringify({ - attributes: { name: name } + attributes: {name: name} }) } } @@ -956,7 +932,7 @@ const app = new Vue({ fetchOptions: { method: "PATCH", body: JSON.stringify({ - attributes: { name: name } + attributes: {name: name} }) } } @@ -965,7 +941,12 @@ const app = new Vue({ }) }, copyToClipboard(str) { - navigator.clipboard.writeText(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.")) + } }, newPlaylist(name = app.getLz('term.newPlaylist'), tracks = []) { let self = this @@ -979,9 +960,9 @@ const app = new Vue({ fetchOptions: { method: "POST", body: JSON.stringify({ - "attributes": { "name": name }, + "attributes": {"name": name}, "relationships": { - "tracks": { "data": tracks }, + "tracks": {"data": tracks}, } }) } @@ -1031,7 +1012,7 @@ const app = new Vue({ app.appRoute("collection-list") }, async showArtistView(artist, title, view) { - let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}`,{}, {includeResponseMeta: !0})).data + let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}`, {}, {includeResponseMeta: !0})).data console.log(response) await this.showCollection(response, title, "artists") }, @@ -1068,7 +1049,7 @@ const app = new Vue({ }, groups: group } - let response = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${term}`, requestBody , { + let response = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${term}`, requestBody, { includeResponseMeta: !0 }) @@ -1146,7 +1127,7 @@ const app = new Vue({ "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount", "limit[artists:top-songs]": 20, "art[url]": "f" - }, { includeResponseMeta: !0 }) + }, {includeResponseMeta: !0}) console.log(artistData.data.data[0]) this.artistPage.data = artistData.data.data[0] this.page = "artist-page" @@ -1207,10 +1188,24 @@ const app = new Vue({ return this.playerLCD.playbackDuration } }, - convertToMins(time) { - let mins = Math.floor(time / 60) - let seconds = (Math.floor(time % 60) / 100).toFixed(2) - return `${mins}:${seconds.replace("0.", "")}` + convertTime(time) { + if (typeof time !== "number") { + time = parseInt(time) + } + + const timeGates = { + 600: 15, + 3600: 14, + 36000: 12, + } + + for (let key in timeGates) { + if (time < key) { + return new Date(time * 1000).toISOString().substring(timeGates[key], 19) + } + } + + return new Date(time * 1000).toISOString().substring(11, 19) }, hashCode(str) { let hash = 0, @@ -1229,7 +1224,7 @@ const app = new Vue({ return; } route = route.replace(/#/g, "") - // if the route contains does not include a / then route to the page directly + // if the route contains does not include a / then route to the page directly if (route.indexOf("/") == -1) { this.page = route window.location.hash = this.page @@ -1244,64 +1239,77 @@ const app = new Vue({ kind: page, id: id, attributes: { - playParams: { kind: page, id: id, isLibrary: isLibrary } + playParams: {kind: page, id: id, isLibrary: isLibrary} } }) }, routeView(item) { let kind = (item.attributes.playParams ? (item.attributes.playParams.kind ?? (item.type ?? '')) : (item.type ?? '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id ?? (item.id ?? '')) : (item.id ?? ''));; + let id = (item.attributes.playParams ? (item.attributes.playParams.id ?? (item.id ?? '')) : (item.id ?? '')); + ; let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary ?? false) : false; console.log(kind, id, isLibrary) - - if (true) { - if (kind.includes("playlist") || kind.includes("album")) { - app.showingPlaylist = []; - } - if (kind.toString().includes("apple-curator")) { - kind = "appleCurator" - app.getTypeFromID("appleCurator", (id), false, { - platform: "web", - include: "grouping,playlists", - extend: "editorialArtwork", - "art[url]": "f" - }); - window.location.hash = `${kind}/${id}` - document.querySelector("#app-content").scrollTop = 0 - } else if (kind.toString().includes("artist")) { - app.getArtistInfo(id, isLibrary) - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - document.querySelector("#app-content").scrollTop = 0 - - } else if (kind.toString().includes("record-label") || kind.toString().includes("curator")) { - if (kind.toString().includes("record-label")) { - kind = "recordLabel" - } else { - kind = "curator" - } - app.page = (kind) + "_" + (id); - app.getTypeFromID((kind), (id), (isLibrary), { - extend: "editorialVideo", - include: 'grouping,playlists', - views: 'top-releases,latest-releases,top-artists' - }); - window.location.hash = `${kind}/${id}` - document.querySelector("#app-content").scrollTop = 0 - } else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) { - let params = { - extend: "offers,editorialVideo", - "views": "appears-on,more-by-artist,related-videos,other-versions,you-might-also-like,video-extras,audio-extras", - } - app.page = (kind) + "_" + (id); - app.getTypeFromID((kind), (id), (isLibrary), params); - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - document.querySelector("#app-content").scrollTop = 0 - } else { - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') - } - + if (kind.includes("playlist") || kind.includes("album")) { + app.showingPlaylist = []; } + if (kind.toString().includes("apple-curator")) { + kind = "appleCurator" + app.getTypeFromID("appleCurator", (id), false, { + platform: "web", + include: "grouping,playlists", + extend: "editorialArtwork", + "art[url]": "f" + }); + window.location.hash = `${kind}/${id}` + document.querySelector("#app-content").scrollTop = 0 + } else if (kind.toString().includes("artist")) { + app.getArtistInfo(id, isLibrary) + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` + document.querySelector("#app-content").scrollTop = 0 + } else if (kind.toString().includes("record-label") || kind.toString().includes("curator")) { + if (kind.toString().includes("record-label")) { + kind = "recordLabel" + } else { + kind = "curator" + } + app.page = (kind) + "_" + (id); + app.getTypeFromID((kind), (id), (isLibrary), { + extend: "editorialVideo", + include: 'grouping,playlists', + views: 'top-releases,latest-releases,top-artists' + }); + window.location.hash = `${kind}/${id}` + document.querySelector("#app-content").scrollTop = 0 + } else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) { + let params = { + extend: "offers,editorialVideo", + "views": "appears-on,more-by-artist,related-videos,other-versions,you-might-also-like,video-extras,audio-extras", + } + + if (this.cfg.advanced.experiments.includes('inline-playlists')) { + 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 { + app.page = (kind) + "_" + (id); + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` + } + + + app.getTypeFromID((kind), (id), (isLibrary), params); + // document.querySelector("#app-content").scrollTop = 0 + } else { + app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') + } }, prevButton() { if (!app.prevButtonBackIndicator && app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) { @@ -1313,7 +1321,7 @@ const app = new Vue({ } }, async getNowPlayingItemDetailed(target) { - let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind, (app.mk.nowPlayingItem.songId == -1), (app.mk.nowPlayingItem.songId != -1) ? app.mk.nowPlayingItem.songId : app.mk.nowPlayingItem["id"], { "include[songs]": "albums,artists" }); + let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind, (app.mk.nowPlayingItem.songId == -1), (app.mk.nowPlayingItem.songId != -1) ? app.mk.nowPlayingItem.songId : app.mk.nowPlayingItem["id"], {"include[songs]": "albums,artists"}); app.searchAndNavigate(u.data.data[0], target) }, async searchAndNavigate(item, target) { @@ -1335,7 +1343,8 @@ const app = new Vue({ artistId = artistId.substring(artistId.lastIndexOf('ids=') + 4, artistId.lastIndexOf('-')) } } - } catch (_) {} + } catch (_) { + } if (artistId == "") { let artistQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.artistName}`, { @@ -1347,7 +1356,8 @@ const app = new Vue({ artistId = artistQuery.artists.data[0].id; console.log(artistId) } - } catch (e) {} + } catch (e) { + } } console.log(artistId); if (artistId != "") @@ -1356,7 +1366,9 @@ const app = new Vue({ case "album": let albumId = ''; try { - if (item.relationships.albums && item.relationships.albums.data.length > 0 && !item.relationships.albums.data[0].type.includes("library")) { + if ((item.type ?? item.playParams?.kind ?? "") == "albums") { + albumId = item.id ?? "" + } else if (item.relationships.albums && item.relationships.albums.data.length > 0 && !item.relationships.albums.data[0].type.includes("library")) { if (item.relationships.albums.data[0].type === "album" || item.relationships.albums.data[0].type === "albums") { albumId = item.relationships.albums.data[0].id } @@ -1368,11 +1380,12 @@ const app = new Vue({ albumId = albumId.substring(0, albumId.indexOf("?i=")) } } - } catch (_) {} + } catch (_) { + } if (albumId == "") { try { - let albumQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.albumName + " " + (item.attributes.artistName ?? "")}`, { + let albumQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${(item.attributes.albumName ?? item.attributes.name ?? "") + " " + (item.attributes.artistName ?? "")}`, { limit: 1, types: 'albums' })).data.results; @@ -1380,7 +1393,8 @@ const app = new Vue({ albumId = albumQuery.albums.data[0].id; console.log(albumId) } - } catch (e) {} + } catch (e) { + } } if (albumId != "") { self.appRoute(`album/${albumId}`) @@ -1390,7 +1404,8 @@ const app = new Vue({ let labelId = ''; try { labelId = item.relationships['record-labels'].data[0].id - } catch (_) {} + } catch (_) { + } if (labelId == "") { try { @@ -1402,11 +1417,12 @@ const app = new Vue({ labelId = labelQuery["record-labels"].data[0].id; console.log(labelId) } - } catch (e) {} + } catch (e) { + } } if (labelId != "") { app.showingPlaylist = [] - await app.getTypeFromID("recordLabel", labelId, false, { views: 'top-releases,latest-releases,top-artists' }); + await app.getTypeFromID("recordLabel", labelId, false, {views: 'top-releases,latest-releases,top-artists'}); app.page = "recordLabel_" + labelId; } @@ -1419,85 +1435,86 @@ const app = new Vue({ }, getArtistInfo(id, isLibrary) { this.getArtistFromID(id) - //this.getTypeFromID("artist",id,isLibrary,query) + //this.getTypeFromID("artist",id,isLibrary,query) }, playMediaItem(item) { let kind = (item.attributes.playParams ? (item.attributes.playParams.kind ?? (item.type ?? '')) : (item.type ?? '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id ?? (item.id ?? '')) : (item.id ?? ''));; + let id = (item.attributes.playParams ? (item.attributes.playParams.id ?? (item.id ?? '')) : (item.id ?? '')); + ; let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary ?? false) : false; let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; console.log(kind, id, isLibrary) app.mk.stop().then(() => { if (kind.includes("artist")) { - app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { + app.mk.setStationQueue({artist: 'a-' + id}).then(() => { app.mk.play() }) } - // else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))){ - // /* Randomize array in-place using Durstenfeld shuffle algorithm */ - // function shuffleArray(array) { - // for (var i = array.length - 1; i > 0; i--) { - // var j = Math.floor(Math.random() * (i + 1)); - // var temp = array[i]; - // array[i] = array[j]; - // array[j] = temp; - // } - // } - // app.mk.clearQueue().then(function () { { - // app.mk.setQueue({[truekind]: [item.attributes.playParams.id ?? item.id]}).then(function () { - // app.mk.play().then(function (){ - // app.mk.clearQueue().then(function (){ - // var playlistId = id - // const params = { - // include: "tracks", - // platform: "web", - // "include[library-playlists]": "catalog,tracks", - // "fields[playlists]": "curatorName,playlistType,name,artwork,url", - // "include[library-songs]": "catalog,artists,albums", - // "fields[catalog]": "artistUrl,albumUrl", - // "fields[songs]": "artistUrl,albumUrl" - // } - // var playlistId = '' + // else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))){ + // /* Randomize array in-place using Durstenfeld shuffle algorithm */ + // function shuffleArray(array) { + // for (var i = array.length - 1; i > 0; i--) { + // var j = Math.floor(Math.random() * (i + 1)); + // var temp = array[i]; + // array[i] = array[j]; + // array[j] = temp; + // } + // } + // app.mk.clearQueue().then(function () { { + // app.mk.setQueue({[truekind]: [item.attributes.playParams.id ?? item.id]}).then(function () { + // app.mk.play().then(function (){ + // app.mk.clearQueue().then(function (){ + // var playlistId = id + // const params = { + // include: "tracks", + // platform: "web", + // "include[library-playlists]": "catalog,tracks", + // "fields[playlists]": "curatorName,playlistType,name,artwork,url", + // "include[library-songs]": "catalog,artists,albums", + // "fields[catalog]": "artistUrl,albumUrl", + // "fields[songs]": "artistUrl,albumUrl" + // } + // var playlistId = '' - // try { - // function getPlaylist(id, params, isLibrary){ - // if (isLibrary){ - // return app.mk.api.library.playlist(id, params) - // } else { return app.mk.api.playlist(id, params)} - // } - // getPlaylist(id, params, isLibrary).then(res => { - // let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - // app.mk.queue.append(query) - // if (!res.relationships.tracks.next) { - // return - // } else { - // getPlaylistTracks(res.relationships.tracks.next) - // } + // try { + // function getPlaylist(id, params, isLibrary){ + // if (isLibrary){ + // return app.mk.api.library.playlist(id, params) + // } else { return app.mk.api.playlist(id, params)} + // } + // getPlaylist(id, params, isLibrary).then(res => { + // let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); + // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} + // app.mk.queue.append(query) + // if (!res.relationships.tracks.next) { + // return + // } else { + // getPlaylistTracks(res.relationships.tracks.next) + // } - // function getPlaylistTracks(next) { - // app.apiCall(app.musicBaseUrl + next, res => { - // if (res.id != playlistId) { - // return - // } - // let query = res.data.map(item => new MusicKit.MediaItem(item)) - // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - // app.mk.queue.append(query) + // function getPlaylistTracks(next) { + // app.apiCall(app.musicBaseUrl + next, res => { + // if (res.id != playlistId) { + // return + // } + // let query = res.data.map(item => new MusicKit.MediaItem(item)) + // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} + // app.mk.queue.append(query) - // if (res.next) { - // getPlaylistTracks(res.next) - // } - // }) - // } - // }) - // } catch (e) {} + // if (res.next) { + // getPlaylistTracks(res.next) + // } + // }) + // } + // }) + // } catch (e) {} - // }) - // }) - // }) - // } - // }) + // }) + // }) + // }) + // } + // }) // } else { app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') @@ -1531,7 +1548,8 @@ const app = new Vue({ } else { this.getPlaylistContinuous(a) } - }; + } + ; }, searchLibrarySongs() { let self = this @@ -1708,12 +1726,12 @@ const app = new Vue({ let searchTerm = this.library.artists.search.toLowerCase() let artistName = "" let albumName = "" - // if (item.attributes.artistName != null) { - // artistName = item.attributes.artistName.toLowerCase() - // } - // if (item.attributes.albumName != null) { - // albumName = item.attributes.albumName.toLowerCase() - // } + // if (item.attributes.artistName != null) { + // artistName = item.attributes.artistName.toLowerCase() + // } + // if (item.attributes.albumName != null) { + // albumName = item.attributes.albumName.toLowerCase() + // } // remove any non-alphanumeric characters and spaces from search term and item name searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") @@ -1735,8 +1753,12 @@ const app = new Vue({ } }, async mkapi(method, library = false, term, params = {}, params2 = {}, attempts = 0) { - if (method.includes(`recordLabel`)) { method = `record-labels` } - if (method.includes(`appleCurator`)) { method = `apple-curators` } + if (method.includes(`recordLabel`)) { + method = `record-labels` + } + if (method.includes(`appleCurator`)) { + method = `apple-curators` + } if (attempts > 3) { return } @@ -1807,9 +1829,11 @@ const app = new Vue({ console.log('safe loading'); app.mk.api.v3.music(`/v1/me/library/songs/`, safeparams).then((response) => { processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.songs.downloadState = 2 - app.library.backgroundNotification.show = false}) + }).catch((error) => { + console.log('safe loading failed', error) + app.library.songs.downloadState = 2 + app.library.backgroundNotification.show = false + }) }) } else { if (downloaded.next != null) { @@ -1819,9 +1843,11 @@ const app = new Vue({ console.log('safe loading'); app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.songs.downloadState = 2 - app.library.backgroundNotification.show = false}) + }).catch((error) => { + console.log('safe loading failed', error) + app.library.songs.downloadState = 2 + app.library.backgroundNotification.show = false + }) }) } else { console.log("Download next", downloaded.next) @@ -1911,9 +1937,11 @@ const app = new Vue({ console.log('safe loading'); app.mk.api.v3.music(`/v1/me/library/albums/`, safeparams).then((response) => { processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.albums.downloadState = 2 - app.library.backgroundNotification.show = false}) + }).catch((error) => { + console.log('safe loading failed', error) + app.library.albums.downloadState = 2 + app.library.backgroundNotification.show = false + }) }) } else { if (downloaded.next != null) { @@ -1923,9 +1951,11 @@ const app = new Vue({ console.log('safe loading'); app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error); - app.library.albums.downloadState = 2 - app.library.backgroundNotification.show = false}) + }).catch((error) => { + console.log('safe loading failed', error); + app.library.albums.downloadState = 2 + app.library.backgroundNotification.show = false + }) }) } else { console.log("Download next", downloaded.next) @@ -2011,9 +2041,11 @@ const app = new Vue({ console.log('safe loading'); app.mk.api.v3.music(`/v1/me/library/artists/`, safeparams).then((response) => { processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.artists.downloadState = 2 - app.library.backgroundNotification.show = false}) + }).catch((error) => { + console.log('safe loading failed', error) + app.library.artists.downloadState = 2 + app.library.backgroundNotification.show = false + }) }) } else { @@ -2024,9 +2056,11 @@ const app = new Vue({ console.log('safe loading'); app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { processChunk(response.data) - }).catch((error) => {console.log('safe loading failed', error) - app.library.artists.downloadState = 2 - app.library.backgroundNotification.show = false}) + }).catch((error) => { + console.log('safe loading failed', error) + app.library.artists.downloadState = 2 + app.library.backgroundNotification.show = false + }) }) } else { console.log("Download next", downloaded.next) @@ -2073,23 +2107,23 @@ const app = new Vue({ getTotalTime() { try { if (app.showingPlaylist.relationships.tracks.data.length > 0) { - let time = Math.round([].concat(...app.showingPlaylist.relationships.tracks.data).reduce((a, { attributes: { durationInMillis } }) => a + durationInMillis, 0) / 1000); + let time = Math.round([].concat(...app.showingPlaylist.relationships.tracks.data).reduce((a, {attributes: {durationInMillis}}) => a + durationInMillis, 0) / 1000); let hours = Math.floor(time / 3600) let mins = Math.floor(time / 60) % 60 let secs = time % 60 - return app.showingPlaylist.relationships.tracks.data.length + " " + app.getLz('term.tracks') +", " + ((hours > 0) ? (hours + (" " + ((hours > 1) ? app.getLz('term.time.hours') + ", " : app.getLz('term.time.hour') +", "))) : "") + ((mins > 0) ? (mins + ((mins > 1) ? " " + app.getLz('term.time.minutes') + ", " : " " + app.getLz('term.time.minute') + ", ")) : "") + secs + ((secs > 1) ? " " + app.getLz('term.time.seconds') + "." : " " + app.getLz('term.time.second') + "."); + return app.showingPlaylist.relationships.tracks.data.length + " " + app.getLz('term.tracks') + ", " + ((hours > 0) ? (hours + (" " + ((hours > 1) ? app.getLz('term.time.hours') + ", " : app.getLz('term.time.hour') + ", "))) : "") + ((mins > 0) ? (mins + ((mins > 1) ? " " + app.getLz('term.time.minutes') + ", " : " " + app.getLz('term.time.minute') + ", ")) : "") + secs + ((secs > 1) ? " " + app.getLz('term.time.seconds') + "." : " " + app.getLz('term.time.second') + "."); } else return "" } catch (err) { return "" } }, async getLibrarySongs() { - let response = await this.mkapi("songs", true, "", { limit: 100 }, { includeResponseMeta: !0 }) + let response = await this.mkapi("songs", true, "", {limit: 100}, {includeResponseMeta: !0}) this.library.songs.listing = response.data.data this.library.songs.meta = response.data.meta }, async getLibraryAlbums() { - let response = await this.mkapi("albums", true, "", { limit: 100 }, { includeResponseMeta: !0 }) + let response = await this.mkapi("albums", true, "", {limit: 100}, {includeResponseMeta: !0}) this.library.albums.listing = response.data.data this.library.albums.meta = response.data.meta }, @@ -2195,7 +2229,7 @@ const app = new Vue({ fetchOptions: { method: "POST", body: JSON.stringify({ - attributes: { name: name } + attributes: {name: name} }) } } @@ -2221,7 +2255,7 @@ const app = new Vue({ showSearch() { this.page = "search" }, - loadLyrics() { + loadLyrics() { const musicType = (MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem["type"] ?? '' : ''; console.log("mt", musicType) if (musicType === "musicVideo") { @@ -2250,6 +2284,7 @@ const app = new Vue({ this.mk.addToLibrary(id).then((data) => { self.getLibrarySongsFull(true) }) + notyf.success('Added to library.'); }, removeFromLibrary(kind, id) { let self = this @@ -2261,6 +2296,26 @@ const app = new Vue({ }).then((data) => { self.getLibrarySongsFull(true) }) + notyf.success('Removed from library.') + }, + + async losslessBadge() { + const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ?? -1 : -1; + if (app.cfg.advanced.ciderPPE && songID != -1) { + /**let extendedAssets = await app.mk.api.song(songID, {extend : 'extendedAssetUrls'}) + if (extendedAssets.attributes.audioTraits.includes('lossless')) {*/ + app.mk.nowPlayingItem['attributes']['lossless'] = true + CiderAudio.audioNodes.llpwEnabled = 1 + console.log("[Cider][Enhanced] Audio being processed by PPE") + /**} + else { + CiderAudio.audioNodes.llpwEnabled = 0 + } */ + } + + else { + CiderAudio.audioNodes.llpwEnabled = 0 + } }, async loadYTLyrics() { const track = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : ''; @@ -2282,10 +2337,10 @@ const app = new Vue({ let req = new XMLHttpRequest(); let url = `https://www.youtube.com/watch?&v=${id}`; req.open('GET', url, true); - req.onerror = function(e) { + req.onerror = function (e) { this.loadMXM(); } - req.onload = function() { + req.onload = function () { // console.log(this.responseText); res = this.responseText; let captionurl1 = res.substring(res.indexOf(`{"playerCaptionsRenderer":{"baseUrl":"`) + (`{"playerCaptionsRenderer":{"baseUrl":"`).length); @@ -2297,10 +2352,10 @@ const app = new Vue({ let req2 = new XMLHttpRequest(); req2.open('GET', newurl, true); - req2.onerror = function(e) { + req2.onerror = function (e) { app.loadMXM(); } - req2.onload = function() { + req2.onload = function () { try { const ttmlLyrics = this.responseText; if (ttmlLyrics) { @@ -2349,7 +2404,7 @@ const app = new Vue({ req.overrideMimeType("application/json"); req.open('GET', url, true); req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req.onload = function() { + req.onload = function () { let jsonResponse = JSON.parse(this.responseText); let status2 = jsonResponse["message"]["header"]["status_code"]; if (status2 == 200) { @@ -2374,7 +2429,7 @@ const app = new Vue({ } }; - req.onerror = function() { + req.onerror = function () { console.log('error'); app.loadAMLyrics(); }; @@ -2392,7 +2447,7 @@ const app = new Vue({ req.overrideMimeType("application/json"); req.open('GET', url, true); req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req.onload = function() { + req.onload = function () { let jsonResponse = JSON.parse(this.responseText); console.log(jsonResponse); let status1 = jsonResponse["message"]["header"]["status_code"]; @@ -2408,7 +2463,8 @@ const app = new Vue({ lrcrich = jsonResponse["message"]["body"]["macro_calls"]["track.richsync.get"]["message"]["body"]["richsync"]["richsync_body"]; richsync = JSON.parse(lrcrich); app.richlyrics = richsync; - } catch (_) {} + } catch (_) { + } } if (lrcfile == "") { @@ -2439,7 +2495,7 @@ const app = new Vue({ }); app.lyrics = preLrc.reverse(); } else { - preLrc = richsync.map(function(item) { + preLrc = richsync.map(function (item) { return { startTime: item.ts, endTime: item.te, @@ -2482,7 +2538,7 @@ const app = new Vue({ req2.overrideMimeType("application/json"); req2.open('GET', url2, true); req2.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req2.onload = function() { + req2.onload = function () { let jsonResponse2 = JSON.parse(this.responseText); console.log(jsonResponse2); let status2 = jsonResponse2["message"]["header"]["status_code"]; @@ -2553,15 +2609,15 @@ const app = new Vue({ line: "lrcInstrumental" }); } - preLrc.push({ startTime: start, endTime: end, line: element.textContent }); + preLrc.push({startTime: start, endTime: end, line: element.textContent}); endTimes.push(end); } // first line dot if (preLrc.length > 0) - preLrc.unshift({ startTime: 0, endTime: preLrc[0].startTime, line: "lrcInstrumental" }); + preLrc.unshift({startTime: 0, endTime: preLrc[0].startTime, line: "lrcInstrumental"}); } else { for (element of lyricsLines) { - preLrc.push({ startTime: 9999999, endTime: 9999999, line: element.textContent }); + preLrc.push({startTime: 9999999, endTime: 9999999, line: element.textContent}); } } this.lyrics = preLrc; @@ -2611,8 +2667,8 @@ const app = new Vue({ // let duration = this.mk.nowPlayingItem.attributes.durationInMillis let start2 = this.hmsToSecondsOnly(start) let end2 = this.hmsToSecondsOnly(end) - // let currentProgress = ((100 * (currentTime)) / (end2)) - // check if currenttime is between start and end + // let currentProgress = ((100 * (currentTime)) / (end2)) + // check if currenttime is between start and end this.player.lyricsDebug.start = start2 this.player.lyricsDebug.end = end2 this.player.lyricsDebug.current = currentTime @@ -2629,17 +2685,17 @@ const app = new Vue({ console.log(id, truekind, isLibrary) try { if (truekind.includes("artist")) { - app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { + app.mk.setStationQueue({artist: 'a-' + id}).then(() => { app.mk.play() }) } else if (truekind == "radioStations") { - this.mk.setStationQueue({ url: raurl }).then(function(queue) { + this.mk.setStationQueue({url: raurl}).then(function (queue) { MusicKit.getInstance().play() }); } else { this.mk.setQueue({ [truekind]: [id] - }).then(function(queue) { + }).then(function (queue) { MusicKit.getInstance().play() }) } @@ -2685,11 +2741,13 @@ const app = new Vue({ shuffleArray(query) } else { for (let i = 0; i < query.length; i++) { - if (query[i].id == item.id) {query.splice(0, i+1); - break;} + if (query[i].id == item.id) { + query.splice(0, i + 1); + break; + } } } - app.mk.queue.append(query) + app.mk.queue.append(query) }) }) } else { @@ -2711,8 +2769,8 @@ const app = new Vue({ if (truekind == "playlists" && (id.startsWith("p.") || id.startsWith("pl.u"))) { app.mk.setQueue({ [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1).then(function() { + }).then(function () { + app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1).then(function () { if ((app.showingPlaylist && app.showingPlaylist.id == id)) { let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); let u = query; @@ -2720,19 +2778,25 @@ const app = new Vue({ shuffleArray(u) } else { for (let i = 0; i < app.showingPlaylist.relationships.tracks.data.length; i++) { - if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) {u.splice(0, i+1); break;} + if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) { + u.splice(0, i + 1); + break; + } } } app.mk.queue.append(u) } else { - app.getPlaylistFromID(id, true).then(function() { + app.getPlaylistFromID(id, true).then(function () { let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); let u = query; if (app.mk.shuffleMode == 1) { shuffleArray(u) } else { for (let i = 0; i < app.showingPlaylist.relationships.tracks.data.length; i++) { - if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) {u.splice(0, i+1); break;} + if (app.showingPlaylist.relationships.tracks.data[i].id == item.id) { + u.splice(0, i + 1); + break; + } } } app.mk.queue.append(u) @@ -2744,7 +2808,7 @@ const app = new Vue({ } else { this.mk.setQueue({ [truekind]: [id] - }).then(function(queue) { + }).then(function (queue) { if (item && ((queue._itemIDs[childIndex] != item.id))) { childIndex = queue._itemIDs.indexOf(item.id) } @@ -2753,7 +2817,7 @@ const app = new Vue({ } else if (item) { app.mk.playNext({ [item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id - }).then(function() { + }).then(function () { app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1) app.mk.play() }) @@ -2768,7 +2832,8 @@ const app = new Vue({ console.log(err) try { app.mk.stop() - } catch (e) {} + } catch (e) { + } this.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url) } @@ -2777,43 +2842,43 @@ const app = new Vue({ // use switch statement to return friendly name for media types "songs,artists,albums,playlists,music-videos,stations,apple-curators,curators" switch (type) { case "song": - return "Songs" + return app.getLz('term.songs') break; case "artist": - return "Artists" + return app.getLz('term.artists') break; case "album": - return "Albums" + return app.getLz('term.albums') break; case "playlist": - return "Playlists" + return app.getLz('term.playlists') break; case "music_video": - return "Music Videos" + return app.getLz('term.musicVideos') break; case "station": - return "Stations" + return app.getLz('term.stations') break; case "apple-curator": - return "Apple Curators" + return app.getLz('term.appleCurators') break; case "radio_show": - return "Radio Shows" + return app.getLz('term.radioShows') break; case "record_label": - return "Record Labels" + return app.getLz('term.recordLabels') break; case "radio_episode": - return "Episodes" + return app.getLz('podcast.episodes') break; case "video_extra": - return "Video Extras" + return app.getLz('term.videoExtras') break; case "curator": - return "Curators" + return app.getLz('term.curators') break; case "top": - return "Top" + return app.getLz('term.top') break; default: return type @@ -2842,7 +2907,7 @@ const app = new Vue({ "omit[resource]": "autos", "platform": "web", limit: 25 - }).then(function(results) { + }).then(function (results) { results.data.results["meta"] = results.data.meta self.search.results = results.data.results }) @@ -2853,7 +2918,7 @@ const app = new Vue({ with: ["serverBubbles", "lyricSnippet"], "art[url]": "f", "art[social-profiles:url]": "c" - }, { includeResponseMeta: !0 }).then(function(results) { + }, {includeResponseMeta: !0}).then(function (results) { results.data.results["meta"] = results.data.meta self.search.resultsSocial = results.data.results }) @@ -2866,29 +2931,30 @@ const app = new Vue({ if (type.slice(-1) != "s") { type += "s" } - type = type.replace("library-", "") + type = type.replace("library-", "") let id = item.attributes.playParams.catalogId ?? item.id - let index = types.findIndex(function(type) { + let index = types.findIndex(function (type) { return type.type == this }, type) if (index == -1) { - types.push({ type: type, id: [id] }) + types.push({type: type, id: [id]}) } else { types[index].id.push(id) } } - types2 = types.map(function(item) { + types2 = types.map(function (item) { return { [`ids[${item.type}]`]: [item.id] } }) - types2 = types2.reduce(function(result, item) { + types2 = types2.reduce(function (result, item) { var key = Object.keys(item)[0]; //first property: a, b, c result[key] = item[key]; return result; }, {}); - return (await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}`, {... { + return (await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}`, { + ...{ "omit[resource]": "autos", relate: "library", fields: "inLibrary" @@ -2899,7 +2965,7 @@ const app = new Vue({ isInLibrary(playParams) { let self = this let id = "" - // ugly code to check if current playback item is in library + // ugly code to check if current playback item is in library if (typeof playParams == "undefined") { return true } @@ -2967,85 +3033,30 @@ const app = new Vue({ }) self.$store.commit("setLCDArtwork", img) }) - - // Vibrant.from(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace('{w}', size).replace('{h}', size)).getPalette().then(palette=>{ - // let angle = "140deg" - // let gradient = "" - // let colors = Object.values(palette).filter(color=>color!=null) - // if(colors.length > 0){ - // let stops = [] - // colors.forEach(color=>{ - // stops.push(`${self._rgbToRgb(color._rgb)} 0%`) - // }) - // stops.push(`${self._rgbToRgb(colors[0]._rgb)} 100%`) - // gradient = `linear-gradient(${angle}, ${stops.join(", ")}` - // } - // - // document.querySelector("#app").style.setProperty("--bgColor", gradient) - // }).setQuantizer(Vibrant.Quantizer.WebWorker) - try { clearInterval(bginterval); - } catch (err) {} + } catch (err) { + } } else { this.setLibraryArtBG() } } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { try { clearInterval(bginterval); - } catch (err) {} + } catch (err) { + } } } catch (e) { if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector('.bg-artwork')) { this.setLibraryArtBG() try { clearInterval(bginterval); - } catch (err) {} + } catch (err) { + } } } }, 200) }, - - // getNowPlayingArtwork(size = 600) { - // if (typeof this.mk.nowPlayingItem === "undefined") return; - // let interval = setInterval(() => { - - // try { - // if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] != this.currentTrackIDBG && document.querySelector('.app-playback-controls .artwork')) { - // this.currentTrackIDBG = this.mk.nowPlayingItem["id"]; - // if (document.querySelector('.app-playback-controls .artwork') != null) { - // clearInterval(interval); - // } - // if (app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url!= '' ) { - // document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${decodeURI((this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"])).replace('{w}', size).replace('{h}', size)}")`); - // try { - // clearInterval(interval); - // } catch (err) { - // } - // } else { - // this.setLibraryArt() - // } - // } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { - // try { - // clearInterval(interval); - // } catch (err) { - // } - // } - // } catch (e) { - // if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector('.app-playback-controls .artwork')) { - // this.setLibraryArt() - // try { - // clearInterval(interval); - // } catch (err) { - // } - - // } - - // } - // }, 200) - - - // }, async getCurrentArtURL() { try { this.currentArtUrl = ''; @@ -3053,25 +3064,23 @@ const app = new Vue({ this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50); try { document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} + } catch (e) { + } } else { let data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); data = data.data.data[0]; if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) { - this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50); - // if (this.currentArtUrl != ""){ - // let attr = MusicKitInterop.getAttributes(); - // attr.artwork.url = this.currentArtUrl; - // ipcRenderer.send('forceUpdateRPC',attr) - // } + this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50); try { document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} + } catch (e) { + } } else { this.currentArtUrl = ''; try { document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} + } catch (e) { + } } } } catch (e) { @@ -3089,7 +3098,8 @@ const app = new Vue({ } else { document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("")`); } - } catch (e) {} + } catch (e) { + } }, async setLibraryArtBG() { if (typeof this.mk.nowPlayingItem === "undefined") return; @@ -3105,13 +3115,14 @@ const app = new Vue({ self.$store.commit("setLCDArtwork", img) }) } - } catch (e) {} + } catch (e) { + } }, quickPlay(query) { let self = this - MusicKit.getInstance().api.search(query, { limit: 2, types: 'songs' }).then(function(data) { - MusicKit.getInstance().setQueue({ song: data["songs"]['data'][0]["id"] }).then(function(queue) { + MusicKit.getInstance().api.search(query, {limit: 2, types: 'songs'}).then(function (data) { + MusicKit.getInstance().setQueue({song: data["songs"]['data'][0]["id"]}).then(function (queue) { MusicKit.getInstance().play() setTimeout(() => { self.$forceUpdate() @@ -3193,32 +3204,35 @@ const app = new Vue({ } }) }, - volumeWheel(event) { - if (this.cfg.audio.maxVolume < 1.0 && this.cfg.audio.maxVolume > 0.01) { - this.cfg.audio.volumePrecision = 0.01 - this.cfg.audio.volumeRoundMax = this.cfg.audio.maxVolume - 0.01 - this.cfg.audio.volumeRoundMin = 0.01 + checkScrollDirectionIsUp(event) { + if (event.wheelDelta) { + return event.wheelDelta > 0; } - if (event.deltaY < 0) { - if (this.mk.volume < this.cfg.audio.maxVolume) { - if (this.mk.volume <= this.cfg.audio.volumeRoundMax) { - this.mk.volume += this.cfg.audio.volumePrecision - } else { - this.mk.volume = this.cfg.audio.maxVolume - } - } - } else if (event.deltaY > 0) { - if (this.mk.volume > 0) { - if (this.mk.volume >= this.cfg.audio.volumeRoundMin) { - this.mk.volume -= this.cfg.audio.volumePrecision - } else { - this.mk.volume = 0 - } - } + return event.deltaY < 0; + }, + volumeUp() { + if ((app.mk.volume + app.cfg.audio.volumeStep) > 1) { + app.mk.volume = 1; + console.log('setting to 1') + } else { + console.log('volume up') + app.mk.volume += app.cfg.audio.volumeStep; } }, + volumeDown() { + if ((app.mk.volume - app.cfg.audio.volumeStep) < 0) { + app.mk.volume = 0; + console.log('settings to 0') + } else { + console.log('volume down') + app.mk.volume -= app.cfg.audio.volumeStep; + } + }, + volumeWheel(event) { + app.checkScrollDirectionIsUp(event) ? app.volumeUp() : app.volumeDown() + }, muteButtonPressed() { - if( this.cfg.audio.muted ) { + if (this.cfg.audio.muted) { this.mk.volume = this.cfg.audio.lastVolume; this.cfg.audio.muted = false; } else { @@ -3228,7 +3242,7 @@ const app = new Vue({ } }, checkMuteChange() { - if( this.cfg.audio.muted ) { + if (this.cfg.audio.muted) { this.cfg.audio.muted = false; } }, @@ -3270,27 +3284,22 @@ const app = new Vue({ document.querySelectorAll(".animated-artwork-video").forEach(el => { el.play() }) + document.querySelector("body").classList.remove("stopanimation") this.animateBackground = true } else { document.querySelectorAll(".animated-artwork-video").forEach(el => { el.pause() }) + document.querySelector("body").classList.add("stopanimation") this.animateBackground = false } }, async nowPlayingContextMenu(event) { - // function revisedRandId() { - // return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); - // } let self = this let data_type = this.mk.nowPlayingItem.playParams.kind let item_id = this.mk.nowPlayingItem.attributes.playParams.id ?? this.mk.nowPlayingItem.id let isLibrary = this.mk.nowPlayingItem.attributes.playParams.isLibrary ?? false - let params = { "fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library", "t": "1" } - // let res = await app.mkapi(data_type, isLibrary , item_id, params); - // if (res && res.relationships && res.relationships.library && res.relationships.library.data && res.relationships.library.data.length > 0) { - // item_id = res.relationships.library.data[0].id - // } + let params = {"fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library", "t": "1"} app.selectedMediaItems = [] app.select_selectMediaItem(item_id, data_type, 0, '12344', isLibrary) let useMenu = "normal" @@ -3300,22 +3309,22 @@ const app = new Vue({ }, normal: { headerItems: [{ - "icon": "./assets/feather/heart.svg", - "id": "love", - "name": app.getLz('action.love'), - "hidden": false, - "disabled": true, - "action": function() { - app.love(app.mk.nowPlayingItem) - } - }, + "icon": "./assets/feather/heart.svg", + "id": "love", + "name": app.getLz('action.love'), + "hidden": false, + "disabled": true, + "action": function () { + app.love(app.mk.nowPlayingItem) + } + }, { "icon": "./assets/feather/heart.svg", "id": "unlove", "active": true, "name": app.getLz('action.unlove'), "hidden": true, - "action": function() { + "action": function () { app.unlove(app.mk.nowPlayingItem) } }, @@ -3325,7 +3334,7 @@ const app = new Vue({ "name": app.getLz('action.dislike'), "hidden": false, "disabled": true, - "action": function() { + "action": function () { app.dislike(app.mk.nowPlayingItem) } }, @@ -3335,57 +3344,63 @@ const app = new Vue({ "name": app.getLz('action.undoDislike'), "active": true, "hidden": true, - "action": function() { + "action": function () { app.unlove(app.mk.nowPlayingItem) } }, ], items: [{ - "icon": "./assets/feather/list.svg", - "name": app.getLz('action.addToPlaylist')+" ...", - "action": function() { - app.promptAddToPlaylist() - } - }, + "icon": "./assets/feather/list.svg", + "name": app.getLz('action.addToPlaylist') + " ...", + "action": function () { + app.promptAddToPlaylist() + } + }, { "icon": "./assets/feather/plus.svg", "id": "addToLibrary", - "name": app.getLz('action.addToLibrary')+" ...", + "name": app.getLz('action.addToLibrary') + " ...", "disabled": false, - "action": function() { + "action": function () { app.addToLibrary(app.mk.nowPlayingItem.id); - // if (!isLibrary) {app.addToLibrary(item_id); this.mk.nowPlayingItem.attributes.playParams["isLibrary"] = true} else { app.removeFromLibrary(data_type,item_id); this.mk.nowPlayingItem.attributes.playParams["isLibrary"] = false}; } }, { "icon": "./assets/feather/radio.svg", "name": app.getLz('action.startRadio'), - "action": function() { - app.mk.setStationQueue({ song: app.mk.nowPlayingItem.id }).then(() => { + "action": function () { + app.mk.setStationQueue({song: app.mk.nowPlayingItem.id}).then(() => { app.mk.play() app.selectedMediaItems = [] }) } }, + { + "icon": "./assets/feather/share.svg", + "name": app.getLz('action.share'), + "action": function () { + app.mkapi(app.mk.nowPlayingItem.attributes?.playParams?.kind ?? app.mk.nowPlayingItem.type ?? 'songs', false, app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.id ?? '').then(u => { + app.copyToClipboard((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url) + }) + } + }, + { + "icon": "./assets/feather/share.svg", + "name": `${app.getLz('action.share')} (song.link)`, + "action": function () { + app.mkapi(app.mk.nowPlayingItem.attributes?.playParams?.kind ?? app.mk.nowPlayingItem.type ?? 'songs', false, app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.id ?? '').then(u => { + app.songLinkShare((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url) + }) + } + } ] } } if (this.contextExt) { - // if this.context-ext.normal is true append all options to the 'normal' menu which is a kvp of arrays if (this.contextExt.normal) { menus.normal.items = menus.normal.items.concat(this.contextExt.normal) } } - - // isLibrary = await app.inLibrary([this.mk.nowPlayingItem]) - // console.warn(isLibrary) - // if(isLibrary.length != 0) { - // if (isLibrary[0].attributes.inLibrary) { - // menus.normal.items.find(x => x.id == "addToLibrary").disabled = true - // } - // }else{ - // menus.normal.items.find(x => x.id == "addToLibrary").disabled = true - // } this.showMenuPanel(menus[useMenu], event) try { @@ -3422,20 +3437,20 @@ const app = new Vue({ /* Just a timeout for the button */ setTimeout(() => { - if (element.innerText === app.getLz('term.connecting') +'...') { + if (element.innerText === app.getLz('term.connecting') + '...') { element.innerText = app.getLz('term.connect'); console.warn('[LastFM] Attempted connection timed out.'); } }, 20000); - ipcRenderer.on('LastfmAuthenticated', function(_event, lfmAuthKey) { + ipcRenderer.on('LastfmAuthenticated', function (_event, lfmAuthKey) { app.cfg.lastfm.auth_token = lfmAuthKey; app.cfg.lastfm.enabled = true; element.innerHTML = `${app.getLz('term.disconnect')}\n

(${app.getLz('term.authed')}: ${lfmAuthKey})

`; element.onclick = app.LastFMDeauthorize; }); }, - parseSCTagToRG: function(tag) { + parseSCTagToRG: function (tag) { let soundcheck = tag.split(" ") let numbers = [] for (item of soundcheck) { @@ -3509,7 +3524,7 @@ const app = new Vue({ `${h}${leadingZeros(n, 2)}:${leadingZeros(d, 2)}` }, toggleHideUserInfo() { - if(this.chrome.hideUserInfo) { + if (this.chrome.hideUserInfo) { this.cfg.visual.showuserinfo = true this.chrome.hideUserInfo = false } else { @@ -3518,42 +3533,48 @@ const app = new Vue({ } }, isElementOverflowing(selector) { - try{ + try { let element = document.querySelector(selector); var overflowX = element.offsetWidth < element.scrollWidth, - overflowY = element.offsetHeight < element.scrollHeight; + overflowY = element.offsetHeight < element.scrollHeight; element.setAttribute('data-value', '\xa0\xa0\xa0\xa0' + element.textContent); - - return (overflowX || overflowY); } catch (e) { return false} + + return (overflowX || overflowY); + } catch (e) { + return false + } }, - async showWebRemoteQR(){ - //this.webremoteqr = await ipcRenderer.invoke('setRemoteQR','') - this.webremoteurl = await ipcRenderer.invoke('showQR','') - //this.modals.qrcode = true; + async showWebRemoteQR() { + //this.webremoteqr = await ipcRenderer.invoke('setRemoteQR','') + this.webremoteurl = await ipcRenderer.invoke('showQR', '') + //this.modals.qrcode = true; }, checkMarquee() { - if(isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-artist') == true) { + if (isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-artist') == true) { document.getElementsByClassName('song-artist')[0].classList.add('marquee'); document.getElementsByClassName('song-artist')[1].classList.add('marquee-after'); } - if(isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') == true) { + if (isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') == true) { document.getElementsByClassName('song-name')[0].classList.add('marquee'); document.getElementsByClassName('song-name')[1].classList.add('marquee-after'); } }, - closeWindow(){ + closeWindow() { ipcRenderer.send('close'); }, - checkForUpdate(){ + checkForUpdate() { ipcRenderer.send('check-for-update') - } + }, + darwinShare(url) { + ipcRenderer.send('share-menu', url) + }, } }) Vue.component('animated-number', { template: "
{{ displayNumber }}
", - props: { 'number': { default: 0 } }, + props: {'number': {default: 0}}, data() { return { @@ -3606,7 +3627,7 @@ Vue.component('sidebar-library-item', { required: false } }, - data: function() { + data: function () { return { app: app, svgIconData: "" @@ -3621,7 +3642,7 @@ Vue.component('sidebar-library-item', { }); // Key binds -document.addEventListener('keydown', function(e) { +document.addEventListener('keydown', function (e) { if (e.keyCode === 70 && e.ctrlKey) { app.$refs.searchInput.focus() app.$refs.searchInput.select() @@ -3636,7 +3657,7 @@ app.hangtimer = setTimeout(() => { }, 10000) // add event listener for when window.location.hash changes -window.addEventListener("hashchange", function() { +window.addEventListener("hashchange", function () { app.appRoute(window.location.hash) }); @@ -3666,7 +3687,7 @@ function fallbackinitMusicKit() { request.send(); } -document.addEventListener('musickitloaded', function() { +document.addEventListener('musickitloaded', function () { // MusicKit global is now defined function initMusicKit() { let parsedJson = JSON.parse(this.responseText) @@ -3689,7 +3710,7 @@ document.addEventListener('musickitloaded', function() { const request = new XMLHttpRequest(); request.timeout = 5000; request.addEventListener("load", initMusicKit); - request.onreadystatechange = function(aEvt) { + request.onreadystatechange = function (aEvt) { if (request.readyState == 4) { if (request.status != 200) fallbackinitMusicKit() @@ -3699,7 +3720,7 @@ document.addEventListener('musickitloaded', function() { request.send(); // check for widevine failure and reconfigure the instance. - window.addEventListener("drmUnsupported", function() { + window.addEventListener("drmUnsupported", function () { initMusicKit() }); }); @@ -3711,7 +3732,7 @@ if ('serviceWorker' in navigator) { }); } -const getBase64FromUrl = async(url) => { +const getBase64FromUrl = async (url) => { const data = await fetch(url); const blob = await data.blob(); return new Promise((resolve) => { @@ -3724,7 +3745,7 @@ const getBase64FromUrl = async(url) => { }); } -function Clone (obj) { +function Clone(obj) { return JSON.parse(JSON.stringify(obj)); } @@ -3770,10 +3791,10 @@ function xmlToJson(xml) { for (var i = 0; i < xml.childNodes.length; i++) { var item = xml.childNodes.item(i); var nodeName = item.nodeName; - if (typeof(obj[nodeName]) == "undefined") { + if (typeof (obj[nodeName]) == "undefined") { obj[nodeName] = xmlToJson(item); } else { - if (typeof(obj[nodeName].push) == "undefined") { + if (typeof (obj[nodeName].push) == "undefined") { var old = obj[nodeName]; obj[nodeName] = []; obj[nodeName].push(old); @@ -3796,10 +3817,11 @@ var checkIfScrollIsStatic = setInterval(() => { try { if (position === document.getElementsByClassName('lyric-body')[0].scrollTop) { clearInterval(checkIfScrollIsStatic) - // do something + // do something } position = document.getElementsByClassName('lyric-body')[0].scrollTop - } catch (e) {} + } catch (e) { + } }, 50); @@ -3819,21 +3841,24 @@ let screenWidth = screen.width; let screenHeight = screen.height; // Key bind to unjam MusicKit in case it fails: CTRL+F10 -document.addEventListener('keydown', function(event) { +document.addEventListener('keydown', function (event) { if (event.ctrlKey && event.keyCode == 121) { try { app.mk._services.mediaItemPlayback._currentPlayer.stop() - } catch (e) { } + } catch (e) { + } try { app.mk._services.mediaItemPlayback._currentPlayer.destroy() - } catch (e) { } + } catch (e) { + } } }); -document.addEventListener('keydown', function(event) { +document.addEventListener('keydown', function (event) { if (event.ctrlKey && event.keyCode == 122) { try { - ipcRenderer.send('detachDT','') - } catch (e) { } + ipcRenderer.send('detachDT', '') + } catch (e) { + } } }); diff --git a/src/renderer/ameframework.css b/src/renderer/less/ameframework.less similarity index 100% rename from src/renderer/ameframework.css rename to src/renderer/less/ameframework.less diff --git a/src/renderer/style.less b/src/renderer/style.less index 8ed97e9d..4b88be9c 100644 --- a/src/renderer/style.less +++ b/src/renderer/style.less @@ -1,10 +1,10 @@ -@import url("ameframework.css"); @import url("assets/fonts/Inter/inter.css"); @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;300;400;500;700;900&display=swap'); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap"); +@import url("less/ameframework.less"); @import url("less/bootstrap.less"); @import url("less/notyf.less"); @@ -68,10 +68,6 @@ body[loading] { } } -body[platform='linux'] { - background: #222; -} - body.notransparency::before { content: ""; position: absolute; @@ -83,6 +79,14 @@ body.notransparency::before { 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==); } +body.stopanimation * { + animation: unset !important; + + .loadbar-sound { + display: none; + } +} + *, *:before, *:after { @@ -151,7 +155,7 @@ body.notransparency::before { right: 0; bottom: 0; opacity: 0.5; - z-index:0; + z-index: 0; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==); } @@ -159,6 +163,7 @@ body.notransparency::before { z-index: 1; } } + //&::before { // position: absolute; // top: -50%; @@ -287,25 +292,25 @@ input[type="text"], input[type="number"] { .artworkMaterial { position: relative; - height:100%; - width:100%; + height: 100%; + width: 100%; overflow: hidden; pointer-events: none; - >img { + > img { position: absolute; width: 200%; opacity: 0.5; filter: brightness(200%) blur(180px) saturate(280%) contrast(2); } - >img:first-child { - top:0; - left:0; + > img:first-child { + top: 0; + left: 0; } - >img:last-child { - bottom:0; + > img:last-child { + bottom: 0; right: 0; transform: rotate(180deg); } @@ -493,9 +498,11 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } .app-sidebar-footer { + border-top: 1px solid rgba(200, 200, 200, 0.15); padding: 11px; .app-playback-controls { + margin: 0 auto; .control-buttons { display: flex; justify-content: center; @@ -557,7 +564,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { font-size: 14px; flex-direction: column; text-align: center; - margin-right: 35px ; + margin-right: 35px; } .app-sidebar-button > .sidebar-user-text .fullname { @@ -655,7 +662,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { } .usermenu-container { - bottom: 66px; + top: 0px; #cmenu.container(); .usermenu-body { @@ -663,19 +670,19 @@ input[type=range].web-slider::-webkit-slider-runnable-track { .usermenu-item { #cmenu.item(); - + .usermenu-item-icon { - position:relative; - top:1.5px; - right:3px; - display:table-cell; + position: relative; + top: 1.5px; + right: 3px; + display: table-cell; } .usermenu-item-name { - position:relative; - bottom:2px; + position: relative; + bottom: 2px; padding-left: 5px; - display:table-cell; + display: table-cell; } } } @@ -869,6 +876,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { .app-chrome .app-chrome--left { width: 30%; justify-content: left; + -webkit-app-region: drag; } .app-chrome .app-chrome--center { @@ -986,18 +994,31 @@ input[type=range].web-slider::-webkit-slider-runnable-track { height: 100%; } -.app-chrome .app-chrome-item > .app-title { - width: 100px; +.app-chrome .app-chrome-item > .app-mainmenu { + width: 110px; font-size: 13px; - background: url("./AppHeader.svg"); - background-size: 95px; + background: url("./assets/AppChromeBtn.svg"); + background-size: contain; background-repeat: no-repeat; background-position: center; - height: 100%; + height: 70%; margin-right: 16px; margin-left: 16px; - image-rendering: -webkit-optimize-contrast; - -webkit-app-region: drag; + margin-top: 1.5px; + border: 0px; + border-radius: 6px; + + &:hover { + background-color: var(--selected); + } + + &:active, &.active { + background-color: var(--selected-click); + } + + &.active { + background-image: url("./assets/AppChromeBtn-Open.svg"); + } } .app-chrome .app-chrome-item > .window-controls { @@ -1051,6 +1072,44 @@ input[type=range].web-slider::-webkit-slider-runnable-track { height: 100%; } +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minimize { + height: 12px; + width: 12px; + background-color: rgb(255, 92, 92); + border-radius: 50%; + display: inline-block; + margin: auto 4px; + color: rgb(130, 0, 5); + -webkit-app-region: no-drag; + background-image: unset; +} + +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls { + width: 67px; +} + +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minmax { + height: 12px; + width: 12px; + background-color: rgb(255, 189, 76); + border-radius: 50%; + display: inline-block; + margin: auto 4px; + -webkit-app-region: no-drag; + background-image: unset; +} + +body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.close { + height: 12px; + width: 12px; + background-color: rgb(0, 202, 86); + border-radius: 50%; + display: inline-block; + margin: auto 4px auto 4px; + -webkit-app-region: no-drag; + background-image: unset; +} + .app-chrome .app-chrome-item.playback-controls { width: 80%; height: 90%; @@ -1067,32 +1126,53 @@ input[type=range].web-slider::-webkit-slider-runnable-track { width: 100%; } -.app-chrome .app-chrome-item > .app-playback-controls .song-name { - font-weight: 600; - text-align: center; - font-size: 13px; - height: 1.3em; - line-height: 1.3em; - white-space: nowrap; - max-width: 360px; +.app-chrome .app-chrome-item > .app-playback-controls { + .song-name { + font-weight: 600; + text-align: center; + font-size: 13px; + height: 1.3em; + line-height: 1.3em; + white-space: nowrap; + max-width: 360px; - .song-name-normal { - height: inherit; - } + .song-name-normal { + height: inherit; + } - &.song-artist-marquee { - > marquee { - //margin-bottom: -3px; + &.song-artist-marquee { + > marquee { + //margin-bottom: -3px; + } + } + + .explicit-icon { + background-image: url("./assets/explicit.svg"); + height: 9px; + width: 13px; + filter: contrast(0); + background-repeat: no-repeat; + margin-left: 3px; } } - .explicit-icon { - background-image: url("./assets/explicit.svg"); - height: 9px; - width: 36px; + .lossless-icon { + background-image: url("./assets/lossless.svg") !important; + } + + .ppe-icon { + background-image: url("./assets/ppe.svg") !important; + } + + .audio-type { filter: contrast(0); background-repeat: no-repeat; - margin-left: 3px; + background-size: contain; + height: 15px; + width: 15px; + position: absolute; + right: 0; + margin-bottom: 15px; } } @@ -1105,43 +1185,49 @@ input[type=range].web-slider::-webkit-slider-runnable-track { margin: 0 0 0 0.25em; } -.app-playback-controls:hover .marquee{ - animation: unset; - &.song-artist{ +.app-playback-controls:hover .marquee { + animation: unset; + + &.song-artist { overflow: hidden; } - .song-artist{ + + .song-artist { overflow: hidden; } - &.song-name{ + + &.song-name { overflow: hidden; } - &::after{ + + &::after { content: none !important; display: none; } } -.marquee{ - animation: marquee 15s linear infinite; - &.song-artist{ - overflow: unset ; +.marquee { + animation: marquee 15s linear infinite; + + &.song-artist { + overflow: unset; } - .song-artist{ - overflow: unset ; + + .song-artist { + overflow: unset; } - &.song-name{ - overflow: unset ; + + &.song-name { + overflow: unset; } - &::after{ + + &::after { content: attr(data-value); } } - - .app-chrome .app-chrome-item > .app-playback-controls .song-progress { @bgColor: transparent; //height: 16px; @@ -1241,15 +1327,18 @@ input[type=range].web-slider::-webkit-slider-runnable-track { &:focus { outline: none; } + &:hover { background: var(--hover); } + &:active { background: var(--selected-click); transform: scale(0.95); } + .svg-icon { - --url: url('views/svg/more.svg')!important; + --url: url('views/svg/more.svg') !important; } } } @@ -1264,7 +1353,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { overflow: hidden; } -.app-chrome .app-chrome-item > .app-playback-controls .playback-info > .song-progress{ +.app-chrome .app-chrome-item > .app-playback-controls .playback-info > .song-progress { width: 100%; } @@ -1275,7 +1364,8 @@ input[type=range].web-slider::-webkit-slider-runnable-track { display: flex; position: relative; } -.app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album { + +.app-chrome .app-chrome-item > .app-playback-controls > div > .song-artist-album { font-weight: 400; font-size: 12px; text-align: center; @@ -1288,17 +1378,17 @@ input[type=range].web-slider::-webkit-slider-runnable-track { max-width: 340px; overflow: hidden; - .song-artist-album-content{ + .song-artist-album-content { font-weight: 400; font-size: 12px; text-align: center; - width:100%; + width: 100%; &.song-artist-normal { height: inherit; } } - + &.song-artist-marquee { > marquee { @@ -1326,7 +1416,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } /* Window is smaller <= 1023px width */ -@media only screen and (max-width: 1023px) { +@media only screen and (max-width: 1120px) { .display--small { display: inherit !important;; @@ -1361,12 +1451,12 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); transition: all var(--appleTransition); } - + &::-webkit-slider-thumb:hover { background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); transform: scale(1.2); } - + &::-webkit-slider-thumb:active { background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); transform: scale(1); @@ -1382,7 +1472,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } - .display--large { display: none !important; } @@ -2164,15 +2253,16 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { border: 1px solid rgba(100, 100, 100, 0.35); border-top: 1px solid rgba(100, 100, 100, 0.5); color: #eee; + white-space: nowrap; transition: transform 0.2s var(--appleEase), box-shadow 0.2s var(--appleEase); &.md-btn-block { display: block; - width:100%; + width: 100%; } &.md-btn-glyph { - display:flex; + display: flex; align-items: center; justify-content: center; width: 100%; @@ -2185,6 +2275,11 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { border-top: 1px solid rgb(220 53 69 / 50%); } + &.md-btn-small { + padding: 6px 8px; + font-size: 13px; + } + &:hover { filter: brightness(125%); } @@ -2211,16 +2306,37 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } +.btn-group { + display:inline-flex; + justify-content: center; + align-items: center; + > .md-btn { + border-radius:0px; + width:100%; + } + > .md-btn:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + } + > .md-btn:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + } + > .md-btn:not(:first-child):not(:last-child) { + border-radius: 0px; + } +} + .md-ico-play { - content:url("./assets/play.svg"); + content: url("./assets/play.svg"); width: 10px; - height: 12px; + height: 12px; margin-right: 1px; align-self: center; } .md-ico-shuffle { - content:url("./assets/shuffle.svg"); + content: url("./assets/shuffle.svg"); width: 1em; height: 1em; margin-right: 1px; @@ -2229,16 +2345,16 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } .md-ico-remove { - content:url("./assets/feather/x-circle-white.svg"); + content: url("./assets/feather/x-circle-white.svg"); width: 16px; - height: 16px; + height: 16px; margin-right: 1px; margin-bottom: -1.5px; align-self: center; } .md-ico-add { - content:url("./assets/feather/plus-circle-white.svg"); + content: url("./assets/feather/plus-circle-white.svg"); width: 1em; height: 1em; margin-right: 1px; @@ -2737,7 +2853,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { margin: 32px 6px; font-size: 0.8rem; white-space: pre-wrap; - display:block; + display: block; } .podcast-artwork { @@ -2776,6 +2892,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { top: 0; z-index: 2; } + .close-btn { width: 50px; height: 42px; @@ -2810,7 +2927,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } .podcast-header { - text-align:center; + text-align: center; } .podcast-play-btn { @@ -2823,11 +2940,11 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { margin: 12px; font-size: 0.75em; white-space: pre-wrap; - display:block; + display: block; line-break: anywhere; } - + } } @@ -2851,8 +2968,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } - - /* Album / Playlist Page */ .playlist-page { --bgColor: transparent; @@ -2898,7 +3013,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { opacity: .7; animation: playlistArtworkFadeIn 1s var(--appleEase); - .artworkMaterial>img { + .artworkMaterial > img { filter: brightness(100%) blur(80px) saturate(100%) contrast(1); object-position: center; object-fit: cover; @@ -2921,7 +3036,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { width: 100%; height: 100%; - >.row { + > .row { width: calc(100% - 32px); } @@ -3062,16 +3177,58 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { margin: 6px; opacity: 0.7; } + + &.inline-playlist { + overflow: hidden; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 6; + position: sticky; + margin-top: calc(var(--navigationBarHeight) * -1); + + .floating-header { + opacity: 1; + top: 0px; + z-index: 6; + padding: 1em; + backdrop-filter: unset; + background: black; + h3 { + display: none; + } + } + .playlist-inner { + background: black; + width: 80%; + height: 100%; + overflow: overlay; + box-shadow: var(--ciderShadow-Generic); + border-radius: var(--mediaItemRadius) var(--mediaItemRadius) 0px 0px; + + .close-btn { + position: sticky; + top: 16px; + left: 16px; + margin-left: 16px; + z-index: 7; + } + } + } } @keyframes playlistArtworkFadeIn { - 0%{ + 0% { opacity: 0; } - 100%{ + 100% { opacity: 0.7; } } + // Collection Page .collection-page { padding-bottom: 128px; @@ -3145,6 +3302,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .header-content { z-index: 1; + margin-top: -16px; } @@ -3160,7 +3318,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { opacity: .7; animation: playlistArtworkFadeIn 1s var(--appleEase); - .artworkMaterial>img { + .artworkMaterial > img { filter: brightness(100%) blur(80px) saturate(100%) contrast(1); object-position: center; object-fit: cover; @@ -3205,7 +3363,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { width: 200px; height: 200px; margin: 32px; - margin-top: -5px; position: relative; .overlay-play { @@ -3264,6 +3421,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase); } } + .artist-title { .artist-play { @@ -3412,11 +3570,13 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { display: flex; justify-content: center; align-items: center; + -webkit-app-region: no-drag; .menu-header-body { padding: 6px; display: flex; background: rgb(200 200 200 / 10%); + .menu-option-header { width: 40px; height: 40px; @@ -3429,7 +3589,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { background: transparent; &.active { - .sidebar-icon>.svg-icon { + .sidebar-icon > .svg-icon { --color: var(--keyColor); } } @@ -3443,6 +3603,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } } + .menu-panel-body { display: flex; flex-flow: column; @@ -3540,7 +3701,8 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 32px; width: 32px; } - .infinity{ + + .infinity { content: url("./assets/infinity.svg"); margin: auto; } @@ -3720,15 +3882,33 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { /* CSS.gg */ @keyframes load-bar { - 10% {box-shadow: inset 0 -4px 0} - 20% {box-shadow: inset 0 -10px 0} - 30% {box-shadow: inset 0 -12px 0} - 40% {box-shadow: inset 0 -8px 0} - 50% {box-shadow: inset 0 -4px 0} - 60% {box-shadow: inset 0 -6px 0} - 80% {box-shadow: inset 0 -12px 0} - 90% {box-shadow: inset 0 -6px 0} - to {box-shadow: inset 0 -2px 0} + 10% { + box-shadow: inset 0 -4px 0 + } + 20% { + box-shadow: inset 0 -10px 0 + } + 30% { + box-shadow: inset 0 -12px 0 + } + 40% { + box-shadow: inset 0 -8px 0 + } + 50% { + box-shadow: inset 0 -4px 0 + } + 60% { + box-shadow: inset 0 -6px 0 + } + 80% { + box-shadow: inset 0 -12px 0 + } + 90% { + box-shadow: inset 0 -6px 0 + } + to { + box-shadow: inset 0 -2px 0 + } } .loadbar-sound, @@ -3740,24 +3920,28 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 28px; box-shadow: inset 0 -12px 0; } + .loadbar-sound { margin-left: 22px; margin-top: -16px; position: relative; - transform: scale(var(--load-bar,1)); + transform: scale(var(--load-bar, 1)); color: var(--keyColor); display: block; } + .loadbar-sound::after, .loadbar-sound::before { content: ""; position: absolute; bottom: 0 } + .loadbar-sound::before { left: -4.5px; animation-delay: -2.4s } + .loadbar-sound::after { right: -4.2px; animation-delay: -3.7s @@ -4486,7 +4670,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 50vh; } - @media only screen and (max-width: 1023px) { + @media only screen and (max-width: 1121px) { .display--large { display: flex !important; } @@ -4525,7 +4709,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .volume-button--small:active { transform: scale(0.9); } - + .volume-button--small.active { background-image: url("./assets/feather/volume.svg"); } @@ -4548,12 +4732,12 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); transition: all var(--appleTransition); } - + &::-webkit-slider-thumb:hover { background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); transform: scale(1.2); } - + &::-webkit-slider-thumb:active { background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); transform: scale(1); @@ -4854,14 +5038,14 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .player-pin { z-index: 3; position: absolute; - min-width: 20px; + min-width: 20px; min-height: 20px; top: 5px; right: 30px; -webkit-app-region: no-drag; } - - #mini-pin{ + + #mini-pin { display: none; } @@ -4877,7 +5061,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 50vh; } - @media only screen and (max-width: 1023px) { + @media only screen and (max-width: 1121px) { .display--large { display: flex !important; } @@ -4916,7 +5100,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .volume-button--small:active { transform: scale(0.9); } - + .volume-button--small.active { background-image: url("./assets/feather/volume.svg"); } @@ -4939,12 +5123,12 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4); transition: all var(--appleTransition); } - + &::-webkit-slider-thumb:hover { background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px); transform: scale(1.2); } - + &::-webkit-slider-thumb:active { background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px); transform: scale(1); @@ -5091,7 +5275,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { width: 100%; height: 100%; - .mediaitem-artwork{ + .mediaitem-artwork { border-radius: unset; } } @@ -5105,11 +5289,12 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { z-index: 3; opacity: 0; padding: 3%; + &:hover { - opacity : 1; + opacity: 1; } } - + .app-playback-controls { -webkit-app-region: no-drag; @@ -5250,6 +5435,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 300px; display: flex; align-items: center; + .grid-body { display: grid; grid-auto-flow: column dense; @@ -5264,19 +5450,19 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { width: 350px; height: 60px; } - + &::-webkit-scrollbar { display: none; } - + &:hover::-webkit-scrollbar { display: initial; - + } } .settings-page { - padding:0px; + padding: 0px; .md-option-header { padding: 1.25em 1.25em; @@ -5286,6 +5472,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { font-size: 1.0em; background: rgb(255 255 255 / 3%); } + .settings-option-body { margin: 16px; } @@ -5755,7 +5942,7 @@ body.no-gpu { .modal-window { height: 330px; max-height: 330px; - width: 800px; + width: 740px; max-width: 800px; overflow: hidden; @@ -5770,7 +5957,7 @@ body.no-gpu { overflow: hidden; } - + .modal-header { padding: 16px; position: relative; @@ -5799,43 +5986,49 @@ body.no-gpu { } } } - .modal-content{ + + .modal-content { display: block; - - .inputs-container{ + + .inputs-container { margin-left: 8px; } - .input-container{ + .input-container { display: inline-grid; width: 54px; justify-items: center; font-size: 0.7em; } - .input-container.mini{ + + .input-container.mini { display: inline-grid; width: 43px; justify-items: center; font-size: 0.7em; } - .freq-header{ + + .freq-header { margin-bottom: 2px; } - - .reset-button{ + + .reset-button { width: 50%; margin-left: 25%; text-align: center; } + input.eq-slider { -webkit-appearance: slider-vertical; width: 5%; } - input[type="number"]{ + + input[type="number"] { padding: unset; width: 55px; } - .header input.eq-slider { + + .header input.eq-slider { -webkit-appearance: slider-vertical; width: 5%; opacity: 0; @@ -5849,5 +6042,17 @@ body.no-gpu { } } +body[platform='darwin'] { + #window-controls-container { + display: none; + } + + .app-chrome .app-chrome-item > .app-mainmenu { + opacity: 0; + pointer-events: none; + -webkit-app-region: drag; + } +} + @import url("less/compact.less"); diff --git a/src/renderer/views/app/chrome-top.ejs b/src/renderer/views/app/chrome-top.ejs new file mode 100644 index 00000000..e38ee43e --- /dev/null +++ b/src/renderer/views/app/chrome-top.ejs @@ -0,0 +1,141 @@ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + + +
+
+
+
+ + +
+
+
+
+ + +
+
+ +
+
+ +
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/views/components/equalizer.ejs b/src/renderer/views/components/equalizer.ejs index f5086eca..5f95ab43 100644 --- a/src/renderer/views/components/equalizer.ejs +++ b/src/renderer/views/components/equalizer.ejs @@ -23,11 +23,6 @@ Vibrant Bass -
- - - Preamp -
{{$root.cfg.audio.equalizer.mix}} @@ -128,7 +123,6 @@ this.frequencies = [] this.gain = [] this.Q = [] - this.preamp = 0 this.mix = 1 this.vibrantBass = 0 this.userGenerated = true @@ -140,7 +134,6 @@ 'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000], 'gain': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Q': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -150,7 +143,6 @@ 'frequencies': [32, 75, 125, 197, 500, 1000, 2000, 3040, 8000, 16000], 'gain': [0, 2.1, 0, 0.8, 0, 0, 0, -1.5, 0, 0], 'Q': [1, 0.7, 1, 1.5, 1, 1, 1, 2, 1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -160,7 +152,6 @@ 'frequencies': [32, 63, 125, 250, 466, 1000, 2000, 4000, 8000, 20000], 'gain': [0, 0, 0, 0, -2, 0, 0, 0, 0, 10], 'Q': [1, 1, 1, 1, 0.6, 1, 1, 1, 1, 0.1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -170,7 +161,6 @@ 'frequencies': [32, 75, 125, 220, 700, 1000, 2000, 4000, 10000, 16000], 'gain': [0, -8, 0, -0.1, -3, 0, 0, 0, 4, 0], 'Q': [1, 0.2, 1, 2.0, 1.4, 1, 1, 1, 0.1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -180,7 +170,6 @@ 'frequencies': [20, 63, 125, 250, 400, 1000, 2000, 4000, 8000, 20000], 'gain': [-22, 0, 0, 0, -3, 0, 1.8, 0, 0, 3.5], 'Q': [0.3, 1, 1, 1, 2.0, 1, 0.7, 1, 1, 0.8], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -190,7 +179,6 @@ 'frequencies': [20, 63, 155, 250, 500, 1000, 2000, 5000, 11000, 16000], 'gain': [-15, 0, -3, 0, 0, 0, 0, 3.1, 0, 0], 'Q': [0.5, 1, 2, 1, 1, 1, 1, 1.5, 0.1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -200,7 +188,6 @@ 'frequencies': [32, 63, 125, 250, 500, 1128, 2000, 4057, 8000, 16000], 'gain': [0, 0, 0, 0, 0, 2, 0, -6.4, 0, 0], 'Q': [1, 1, 1, 1, 1, 2, 1, 1, 1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -210,7 +197,6 @@ 'frequencies': [35, 63, 125, 250, 500, 800, 2000, 4000, 8000, 20000], 'gain': [5, 0, 0, 0, 0, -5, 0, 0, 0, 5], 'Q': [0.1, 1, 1, 1, 1, 0.6, 1, 1, 1, 0.2], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -221,7 +207,6 @@ 'frequencies': [45.53,88.06,116.18,161.3,247.05,295.6,365.79,495.13,716.85,960.76], 'gain': [-0.36,4.07,-1.3,1.92,0.77,-0.53,-1.33,0.44,0.46,-0.5], 'Q': [1.768,0.625,5,8.409,10,16.82,5.946,7.071,20,10], - 'preamp': -2, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -232,7 +217,6 @@ 'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000], 'gain': [2.7, 2.2, 1.6, 1.4, 0.6, 0, 0, 0, 0, 0], 'Q': [1.4, 1.4, 1.4, 1.4, 1.4, 1, 1, 1, 1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -242,7 +226,6 @@ 'frequencies': [32, 63, 160, 250, 500, 1000, 2000, 3500, 8000, 20000], 'gain': [2.7, 2.2, 1.6, 1.4, 0.6, 0, 0, 0, 0, 0], 'Q': [0.7, 0.7, 0.7, 0.7, 0.7, 1, 1, 1, 1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, 'userGenerated': false @@ -333,18 +316,20 @@ app.cfg.audio.vibrantBass.multiplier = app.cfg.audio.equalizer.vibrantBass / 10 for (var i = 0; i < 21; i++) { CiderAudio.audioNodes.vibrantbassNode[i].gain.value = app.cfg.audio.vibrantBass.gain[i] * (app.cfg.audio.equalizer.vibrantBass / 10); - } - }, - changePreamp() { - CiderAudio.audioNodes.preampNode.gain.value = app.cfg.audio.equalizer.preamp; + } }, changeMix() { for (var i = 0; i < 10; i++) { CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer.gain[i] * app.cfg.audio.equalizer.mix } }, + changePreamp() { + if (CiderAudio.audioNodes.llpwEnabled === 1) {CiderAudio.audioNodes.preampNode.gain.value = (-Math.max(...app.cfg.audio.equalizer.gain.concat(CiderAudio.audioNodes.llpw[23].gain.value)));} + else {CiderAudio.audioNodes.preampNode.gain.value = (-Math.max(...app.cfg.audio.equalizer.gain));} + }, changeGain(i) { CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer.gain[i] * app.cfg.audio.equalizer.mix + this.changePreamp() }, changeFreq(i) { CiderAudio.audioNodes.audioBands[i].frequency.value = app.cfg.audio.equalizer.frequencies[i] @@ -357,10 +342,10 @@ 'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000], 'gain': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Q': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - 'preamp': 0, 'mix': 1, 'vibrantBass': 0, }) + CiderAudio.audioNodes.preampNode.gain.value = 0; if (app.cfg.audio.equalizer.userGenerated) { this.saveSelectedPreset() } @@ -375,7 +360,6 @@ newPreset.frequencies = eqSettings.frequencies newPreset.gain = eqSettings.gain newPreset.Q = eqSettings.Q - newPreset.preamp = eqSettings.preamp newPreset.mix = eqSettings.mix newPreset.vibrantBass = eqSettings.vibrantBass app.cfg.audio.equalizer.presets.push(newPreset) @@ -393,14 +377,13 @@ preset.frequencies = app.cfg.audio.equalizer.frequencies preset.gain = app.cfg.audio.equalizer.gain preset.Q = app.cfg.audio.equalizer.Q - preset.preamp = app.cfg.audio.equalizer.preamp preset.mix = app.cfg.audio.equalizer.mix preset.vibrantBass = app.cfg.audio.equalizer.vibrantBass notyf.success("Saved Preset") }, exportPreset() { const preset = app.cfg.audio.equalizer.presets.find(p => p.preset == app.cfg.audio.equalizer.preset) - const jsonObj = {"name": preset.name, "author": app.chrome.userinfo.attributes.name, "frequency": preset.frequencies, "gain": preset.gain, "q": preset.Q, "preamp": preset.preamp, "mix": preset.mix, "vibrantBass": preset.vibrantBass}; + const jsonObj = {"name": preset.name, "author": app.chrome.userinfo.attributes.name, "frequency": preset.frequencies, "gain": preset.gain, "q": preset.Q, "mix": preset.mix, "vibrantBass": preset.vibrantBass}; ipcRenderer.send("export-eq", jsonObj) }, importPreset() { @@ -411,7 +394,6 @@ newPreset.frequencies = result.frequency newPreset.gain = result.gain newPreset.Q = result.q - newPreset.preamp = result.preamp newPreset.mix = result.mix newPreset.vibrantBass = result.vibrantBass app.cfg.audio.equalizer.presets.push(newPreset) @@ -423,7 +405,6 @@ }, applyPreset(preset) { Object.assign(this.$root.cfg.audio.equalizer, preset) - this.changePreamp() this.changeVibrantBass() for (var i = 0; i < 10; i++) { this.changeGain(i) diff --git a/src/renderer/views/components/fullscreen.ejs b/src/renderer/views/components/fullscreen.ejs index e35c760b..cbe0eb00 100644 --- a/src/renderer/views/components/fullscreen.ejs +++ b/src/renderer/views/components/fullscreen.ejs @@ -41,8 +41,8 @@
-

{{ app.convertToMins(app.getSongProgress()) }}

-

{{ app.convertToMins(app.mk.currentPlaybackDuration) }}

+

{{ app.convertTime(app.getSongProgress()) }}

+

{{ app.convertTime(app.mk.currentPlaybackDuration) }}

0) { - app.mk.playNext({[kind + "s"]: itemsToPlay[kind]}) + app.mk.playNext({ [kind + "s"]: itemsToPlay[kind] }) } } console.log(itemsToPlay) @@ -281,7 +281,7 @@ for (let kind in itemsToPlay) { let ids = itemsToPlay[kind] if (ids.length > 0) { - app.mk.playLater({[kind + "s"]: itemsToPlay[kind]}) + app.mk.playLater({ [kind + "s"]: itemsToPlay[kind] }) } } app.selectedMediaItems = [] @@ -363,7 +363,7 @@ "name": app.getLz('action.playNext'), "icon": "./assets/arrow-bend-up.svg", "action": function () { - app.mk.playNext({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id}) + app.mk.playNext({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id }) app.mk.queue._reindex() app.selectedMediaItems = [] } @@ -372,7 +372,7 @@ "name": app.getLz('action.playLater'), "icon": "./assets/arrow-bend-down.svg", "action": function () { - app.mk.playLater({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id}) + app.mk.playLater({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id }) app.mk.queue._reindex() app.selectedMediaItems = [] } @@ -381,7 +381,7 @@ "icon": "./assets/feather/radio.svg", "name": app.getLz('action.startRadio'), "action": function () { - app.mk.setStationQueue({song: self.item.attributes.playParams.id ?? self.item.id}).then(() => { + app.mk.setStationQueue({ song: self.item.attributes.playParams.id ?? self.item.id }).then(() => { app.mk.play() app.selectedMediaItems = [] }) @@ -405,12 +405,26 @@ "icon": "./assets/feather/share.svg", "name": app.getLz('action.share'), "action": function () { - if (!self.item.attributes.url && self.item.relationships){ - if (self.item.relationships.catalog){ - app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)}) + if (!self.item.attributes.url && self.item.relationships) { + if (self.item.relationships.catalog) { + app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => { self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url) }) } - }else { - self.app.copyToClipboard(self.item.attributes.url)} + } else { + self.app.copyToClipboard(self.item.attributes.url) + } + } + }, + { + "icon": "./assets/feather/share.svg", + "name": `${app.getLz('action.share')} (song.link)`, + "action": function () { + if (!self.item.attributes.url && self.item.relationships) { + if (self.item.relationships.catalog) { + app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => { self.app.songLinkShare((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url) }) + } + } else { + self.app.songLinkShare(self.item.attributes.url) + } } } ] @@ -430,30 +444,30 @@ try { await this.checkLibrary().then(res => { console.log(res) - if(res) { + if (res) { menus.normal.items.find(x => x.id == 'addToLibrary').hidden = true menus.normal.items.find(x => x.id == 'removeFromLibrary').hidden = false - }else{ + } else { menus.normal.items.find(x => x.id == 'addToLibrary').disabled = false } }) - }catch(e) { + } catch (e) { } - try{ - let rating = await app.getRating(self.item) - if (rating == 0) { - menus.normal.headerItems.find(x => x.id == 'love').disabled = false - menus.normal.headerItems.find(x => x.id == 'dislike').disabled = false - } else if (rating == 1) { - menus.normal.headerItems.find(x => x.id == 'unlove').hidden = false - menus.normal.headerItems.find(x => x.id == 'love').hidden = true - } else if (rating == -1) { - menus.normal.headerItems.find(x => x.id == 'undo_dislike').hidden = false - menus.normal.headerItems.find(x => x.id == 'dislike').hidden = true - } - } catch(err) { + try { + let rating = await app.getRating(self.item) + if (rating == 0) { + menus.normal.headerItems.find(x => x.id == 'love').disabled = false + menus.normal.headerItems.find(x => x.id == 'dislike').disabled = false + } else if (rating == 1) { + menus.normal.headerItems.find(x => x.id == 'unlove').hidden = false + menus.normal.headerItems.find(x => x.id == 'love').hidden = true + } else if (rating == -1) { + menus.normal.headerItems.find(x => x.id == 'undo_dislike').hidden = false + menus.normal.headerItems.find(x => x.id == 'dislike').hidden = true + } + } catch (err) { } }, @@ -474,7 +488,7 @@ }, async removeFromLibrary() { let item = this.item - let params = {"fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library"} + let params = { "fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library" } let id = item.id ?? item.attributes.playParams.id let res = await app.mkapi(item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.playParams.id ?? item.id, params); if (res && res.relationships && res.relationships.library && res.relationships.library.data && res.relationships.library.data.length > 0) { @@ -502,10 +516,10 @@ let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; console.log(item, parent, childIndex, kind, id, isLibrary, kind == "playlists", id.startsWith("p.") || id.startsWith("pl.u")) app.mk.stop().then(() => { - if (parent != null && childIndex != null) { - app.queueParentandplayChild(parent, childIndex, item); - } - else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))){ + if (parent != null && childIndex != null) { + app.queueParentandplayChild(parent, childIndex, item); + } + else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))) { function shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); @@ -514,58 +528,59 @@ array[j] = temp; } } - app.mk.setQueue({[truekind]: [item.attributes.playParams.id ?? item.id]}).then(function () { - app.mk.play().then(function (){ - var playlistId = id - function getPlaylist(id, isLibrary){ - if (isLibrary){ - return this.app.mk.api.v3.music(`/v1/me/library/playlists/${id}`) - } else { return this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`)} + app.mk.setQueue({ [truekind]: [item.attributes.playParams.id ?? item.id] }).then(function () { + app.mk.play().then(function () { + var playlistId = id + function getPlaylist(id, isLibrary) { + if (isLibrary) { + return this.app.mk.api.v3.music(`/v1/me/library/playlists/${id}`) + } else { return this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`) } + } + try { + getPlaylist(id, isLibrary).then(res => { + //let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); + //if (app.mk.shuffleMode == 1){shuffleArray(query); } + // console.log(query) + // app.mk.queue.append(query) + if (!res.data.relationships.tracks.next) { + return + } else { + getPlaylistTracks(res.data.relationships.tracks.next) } - try { - getPlaylist(id, isLibrary).then(res => { - //let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - //if (app.mk.shuffleMode == 1){shuffleArray(query); } - // console.log(query) - // app.mk.queue.append(query) - if (!res.data.relationships.tracks.next) { - return - } else { - getPlaylistTracks(res.data.relationships.tracks.next) - } - function getPlaylistTracks(next) { - app.apiCall(app.musicBaseUrl + next, res => { - // if (res.id != playlistId || next.includes(playlistId)) { - // return - // } - console.log('nextres', res) - let query = res.data.map(item => new MusicKit.MediaItem(item)) - if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - app.mk.queue.append(query) + function getPlaylistTracks(next) { + app.apiCall(app.musicBaseUrl + next, res => { + // if (res.id != playlistId || next.includes(playlistId)) { + // return + // } + console.log('nextres', res) + let query = res.data.map(item => new MusicKit.MediaItem(item)) + if (app.mk.shuffleMode == 1) { shuffleArray(query); console.log('shf') } + app.mk.queue.append(query) - if (res.next) { - getPlaylistTracks(res.next) - } - }) + if (res.next) { + getPlaylistTracks(res.next) } }) - } catch (e) {} + } + }) + } catch (e) { } - }) - }) + }) + }) - } - else { - app.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url) - }}) + } + else { + app.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url) + } + }) }, - route(){ + route() { let kind = (this.item.attributes.playParams ? (this.item.attributes.playParams.kind ?? (this.item.type ?? '')) : (this.item.type ?? '')); - if (kind.toLowerCase().includes('album') || kind.toLowerCase().includes('playlist')){ + if (kind.toLowerCase().includes('album') || kind.toLowerCase().includes('playlist')) { app.routeView(this.item) } else { this.playTrack() @@ -573,4 +588,4 @@ } } }); - + \ No newline at end of file diff --git a/src/renderer/views/components/mediaitem-square-large.ejs b/src/renderer/views/components/mediaitem-square-large.ejs deleted file mode 100644 index a969e10b..00000000 --- a/src/renderer/views/components/mediaitem-square-large.ejs +++ /dev/null @@ -1,244 +0,0 @@ - - - \ No newline at end of file diff --git a/src/renderer/views/components/mediaitem-square-sp.ejs b/src/renderer/views/components/mediaitem-square-sp.ejs deleted file mode 100644 index 89859695..00000000 --- a/src/renderer/views/components/mediaitem-square-sp.ejs +++ /dev/null @@ -1,293 +0,0 @@ - - - \ No newline at end of file diff --git a/src/renderer/views/components/mediaitem-square.ejs b/src/renderer/views/components/mediaitem-square.ejs index bdb39c17..6bf861d9 100644 --- a/src/renderer/views/components/mediaitem-square.ejs +++ b/src/renderer/views/components/mediaitem-square.ejs @@ -402,6 +402,18 @@ }else { self.app.copyToClipboard(self.item.attributes.url)} } + }, + { + "icon": "./assets/feather/share.svg", + "name": `${app.getLz('action.share')} (song.link)`, + "action": function () { + if (!self.item.attributes.url && self.item.relationships){ + if (self.item.relationships.catalog){ + app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.songLinkShare((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)}) + } + }else { + self.app.songLinkShare(self.item.attributes.url)} + } } ] } diff --git a/src/renderer/views/components/miniplayer.ejs b/src/renderer/views/components/miniplayer.ejs index ad9d33e2..40ecabe9 100644 --- a/src/renderer/views/components/miniplayer.ejs +++ b/src/renderer/views/components/miniplayer.ejs @@ -44,8 +44,8 @@
-

{{ app.convertToMins(app.getSongProgress()) }}

-

{{ app.convertToMins(app.mk.currentPlaybackDuration) }}

+

{{ app.convertTime(app.getSongProgress()) }}

+

{{ app.convertTime(app.mk.currentPlaybackDuration) }}

- - - - \ No newline at end of file diff --git a/src/renderer/views/components/share-sheet.ejs b/src/renderer/views/components/share-sheet.ejs new file mode 100644 index 00000000..ee093413 --- /dev/null +++ b/src/renderer/views/components/share-sheet.ejs @@ -0,0 +1,88 @@ + + + \ No newline at end of file diff --git a/src/renderer/views/pages/settings.ejs b/src/renderer/views/pages/settings.ejs index fbd751d1..0ed575bc 100644 --- a/src/renderer/views/pages/settings.ejs +++ b/src/renderer/views/pages/settings.ejs @@ -6,6 +6,9 @@
+
+ {{$root.getLz('term.accountSettings')}} +
@@ -58,6 +61,31 @@ switch/>
+
+
+ {{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')}} +
+ {{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE.description')}} +
+
+ +
+
+
+
+ {{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength')}} +
+ {{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description')}} +
+
+ + +
+
{{$root.getLz('term.equalizer')}} @@ -94,6 +122,18 @@ {{$root.getLz('settings.header.visual')}}
+
+
+ {{$root.getLz('settings.header.visual.theme')}} +
+
+ +
+
{{$root.getLz('settings.option.visual.windowBackgroundStyle')}} @@ -581,6 +621,15 @@
+
+
+ {{$root.getLz('settings.option.experimental.inline_playlists')}} +
+
+ +
+
+
{{$root.getLz('term.language')}} @@ -606,7 +655,7 @@
- {{$root.getLz('term.updateCider')}} + {{$root.getLz('settings.option.general.updateCider')}}
+
+
+ {{$root.getLz('settings.option.general.updateCider.branch')}}
+ ({{$root.getLz('settings.option.general.updateCider.branch.description')}}) +
+
+ +
+
+
+
+ {{$root.getLz('settings.option.experimental.copy_log')}} +
+
+ +
+
{{$root.getLz('settings.header.unfinished')}}
-
-
- Theme -
-
- -
-
+
Theme Options @@ -686,86 +752,109 @@ + ipcRenderer.invoke('update-store-mtt', app.cfg.general.close_behavior); + } + } + }) + \ No newline at end of file