Merge branch 'ciderapp:develop' into develop

This commit is contained in:
Bill Zhang 2022-02-11 12:37:53 +08:00 committed by GitHub
commit 4c9719fb05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 6078 additions and 185 deletions

1
.gitignore vendored
View file

@ -324,3 +324,4 @@ resources/b64.txt
savedconfig/cider-config.json
savedconfig/config.json
savedconfig/session.json
savedconfig/window-state.json

View file

@ -81,3 +81,7 @@ Update 08/02/2022 10:20 UTC
* `settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility`: Added for `en_US`.
* `term.requestError`: Added for `en_US`.
* `term.song.link.generate`: Added for `en_US`.
Update 10/02/2022 05:58 UTC
* `term.sortBy.dateAdded`: Added for `en_US`.

357
src/i18n/cz_CZ.jsonc Normal file
View file

@ -0,0 +1,357 @@
{ // Base File
// i18n Info
"i18n.languageName": "Čeština (CZ)", // name of language in native language
"i18n.languageNameEnglish": "Czech (CZ)", // name of language in English
"i18n.category": "main", // main = real language, fun = fun community languages
"i18n.authors": "@matuskoOk", // 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": "Aktualizace skladeb v knihovně...",
"notification.updatingLibraryAlbums": "Aktualizace alb knihovny...",
"notification.updatingLibraryArtists": "Aktualizace umělců knihovny...",
// Terms
"term.appleInc": "Apple Inc.",
"term.appleMusic": "Apple Music",
"term.applePodcasts": "Apple Podcasts",
"term.itunes": "iTunes",
"term.github": "GitHub",
"term.discord": "Discord",
"term.learnMore": "Zjistěte více",
"term.accountSettings": "Nastavení účtu",
"term.logout": "Odhlásit se",
"term.login": "Přihlásit se",
"term.about": "About",
"term.privateSession": "Soukromá relace",
"term.queue": "Fronta",
"term.history": "Historie",
"term.search": "Vyhledávání",
"term.library": "Knihovna",
"term.listenNow": "Poslouchejte hned",
"term.browse": "Procházet",
"term.radio": "Rádio",
"term.recentlyAdded": "Nedávno přidané",
"term.songs": "Písně",
"term.albums": "Alba",
"term.artists": "Umělci",
"term.podcasts": "Podcasty",
"term.playlists": "Playlists",
"term.playlist": "Playlist",
"term.newPlaylist": "Nový seznam playlistu",
"term.newPlaylistFolder": "Nová složka playlistov",
"term.createNewPlaylist": "Vytvořit nový seznam playlistov",
"term.createNewPlaylistFolder": "Vytvořit nový seznam playlist složka",
"term.deletePlaylist": "Opravdu chcete tento playlist smazat?",
"term.play": "Play",
"term.pause": "Pause",
"term.previous": "Předchozí",
"term.next": "Další",
"term.shuffle": "Zamíchat",
"term.repeat": "Repeat",
"term.volume": "Hlasitosť",
"term.mute": "Mute",
"term.unmute": "Ztlumit",
"term.share": "Zdílet",
"term.share.success": "Zkopírováno do clipboard",
"term.settings": "Nastavení",
"term.seeAll": "Vidět vše",
"term.sortBy": "Seřazeno podle",
"term.sortBy.album": "Album",
"term.sortBy.artist": "Umělec",
"term.sortBy.name": "Název",
"term.sortBy.genre": "Žánr",
"term.sortBy.releaseDate": "Datum vydání",
"term.sortBy.duration": "Doba trvání",
"term.sortOrder": "A-Z",
"term.sortOrder.ascending": "Vzestupně",
"term.sortOrder.descending": "Klesající",
"term.viewAs": "Zobrazit jako",
"term.viewAs.coverArt": "Obálka Art",
"term.viewAs.list": "Seznam",
"term.size": "Velikost",
"term.size.normal": "Normální",
"term.size.compact": "Kompaktní",
"term.enable": "Zapnout",
"term.disable": "Vypnout",
"term.enabled": "Zapnuto",
"term.disabled": "Vypnuto",
"term.connect": "Připojit",
"term.connecting": "Připojování",
"term.disconnect": "Odpojit",
"term.authed": "Ověřeno",
"term.confirm": "Potvrdit?",
"term.more": "Více",
"term.less": "Méně",
"term.showMore": "Zobrazit více",
"term.showLess": "Ukaž méně",
"term.topSongs": "Nejlepší skladby",
"term.latestReleases": "Nejnovější verze",
"term.time.added": "Přidané",
"term.time.released": "Vydáno",
"term.time.updated": "Aktualizováno",
"term.time.hours": "hodin",
"term.time.hour": "hodina",
"term.time.minutes": "minut",
"term.time.minute": "minuta",
"term.time.seconds": "sekundy",
"term.time.second": "sekunda",
"term.fullscreenView": "Zobrazení na celou obrazovku",
"term.defaultView": "Výchozí zobrazení",
"term.audioSettings": "Nastavení zvuku",
"term.clearAll": "Vymazat vše",
"term.recentStations": "Nedávné stanice",
"term.language": "Jazyk",
"term.funLanguages": "Zábava",
"term.noLyrics": "Načítání... / Text nenalezen./ Instrumentální.",
"term.copyright": "Autorská práva",
"term.rightsReserved": "Všechna práva vyhrazena.",
"term.sponsor": "Sponzorujte tento projekt",
"term.ciderTeam": "Cider Tým",
"term.developer": "Vývojář",
"term.socialTeam": "Sociální tým",
"term.socials": "Socials",
"term.contributors": "Přispěvatelé",
"term.equalizer": "Ekvalizér",
"term.reset": "Resetovat",
"term.tracks": "tracks", // Assume x amount of tracks. e.g. 50 tracks
"term.videos": "Videa",
"term.menu": "Menu",
"term.check": "Zkontrolovat",
"term.aboutArtist": "O {{artistName}}", // e.g. 'About Doja Cat'
"term.topResult": "Nejlepší výsledek", // Search Results
"term.sharedPlaylists": "Sdílený Playlists", // Search Results
"term.people": "Lidé", // Search Results
"term.newpreset.name": "Název nové předvolby EQ", // Equalizer Preset
"term.addedpreset": "Přidána předvolba",
"term.deletepreset.warn": "Opravdu chcete tuto předvolbu smazat?",
"term.deletedpreset": "Předvolba byla odstraněna",
"term.musicVideos": "Hudební videa", // Search page friendlyTypes
"term.stations": "Stanice",
"term.curators": "Kurátoři",
"term.appleCurators": "Apple Curators",
"term.radioShows": "Rozhlasové pořady",
"term.recordLabels": "Nahrávací štítky",
"term.videoExtras": "Video Extra",
"term.top": "Top",
// Home
"home.title": "Domů",
"home.recentlyPlayed": "Nedávno hrané",
"home.recentlyAdded": "Nedávno přidané",
"home.artistsFeed": "Váš kanál umělců",
"home.artistsFeed.noArtist": "Nejprve sledujte některé umělce a jejich nejnovější verze budou zde",
"home.madeForYou": "Uděláno pro tebe",
"home.friendsListeningTo": "Přátelé Poslouchají",
"home.followedArtists": "Sledované umělce",
// Errors
"error.appleMusicSubRequired": "Apple Music vyžaduje předplatné.",
"error.connectionError": "Došlo k problému s připojením k Apple Music.",
"error.noResults": "Žádné výsledky.",
"error.noResults.description": "Zkuste nové vyhledávání.",
// Podcasts
"podcast.followOnCider": "Sledujte Na Cider",
"podcast.followedOnCider": "Sledujete Na Cider",
"podcast.subscribeOnItunes": "Předplatit na iTunes",
"podcast.subscribedOnItunes": "Předplaceno na iTunes",
"podcast.itunesStore": "iTunes Store",
"podcast.episodes": "Epizody",
"podcast.playEpisode": "Přehrát epizodu",
"podcast.website": "Webová stránka podcastun ",
// Actions
"action.addToLibrary": "Přidat do knihovny",
"action.addToLibrary.success": "Přidáno do knihovny",
"action.addToLibrary.error": "Chyba při přidávání do knihovny",
"action.removeFromLibrary": "Odebrat z knihovny",
"action.removeFromLibrary.success": "Odebráno z knihovny",
"action.addToQueue": "Přidat do fronty",
"action.addToQueue.success": "Přidáno do fronty",
"action.addToQueue.error": "Chyba při přidávání do fronty",
"action.removeFromQueue": "Odebrat z fronty",
"action.removeFromQueue.success": "Odebráno z fronty",
"action.removeFromQueue.error": "Chyba při odstraňování z fronty",
"action.createPlaylist": "Vytvoř nový Playlist",
"action.addToPlaylist": "Přidat do Playlist",
"action.removeFromPlaylist": "Odstranit z Playlist",
"action.addToFavorites": "Přidat k oblíbeným",
"action.follow": "Sledovat",
"action.follow.success": "Sleduješ",
"action.follow.error": "Chyba sledování",
"action.unfollow": "Přestat sledovat",
"action.unfollow.success": "Nesledováno",
"action.unfollow.error": "Chyba při zrušení sledování",
"action.playNext": "Play Další",
"action.playLater": "Play Později",
"action.startRadio": "Start Rádio",
"action.goToArtist": "Přejít na Umělec",
"action.goToAlbum": "Přejděte do alba",
"action.moveToTop": "Přesunout nahoru",
"action.share": "Sdílet",
"action.rename": "Přejmenovat",
"action.love": "Milovat",
"action.unlove": "Nemilovat",
"action.dislike": "Dislike",
"action.undoDislike": "Undo dislike",
"action.showWebRemoteQR": "Web Remote",
"action.playTracksNext": "Play ${app.selectedMediaItems.length} tracks next",
"action.playTracksLater": "Play ${app.selectedMediaItems.length} tracks later",
"action.removeTracks": "Odstranit ${self.selectedItems.length} tracks from queue",
"action.import": "Importovať",
"action.export": "Exportovať",
"action.showAlbum": "Zobrazit kompletní album",
"action.tray.minimize": "Minimalizovat do lišty",
"action.tray.quit": "Přestat",
"action.tray.show": "Ukázat",
"action.update": "Aktualizace",
"action.copy": "kopírovat",
"action.newpreset": "Nová předvolba...", // Equalizer Preset
"action.deletepreset": "Smazat předvolbu",
// Settings - General
"settings.header.general": "Všeobecné",
"settings.header.general.description": "Upravte obecná nastavení pro Cider.",
"settings.option.general.language": "Jazyk",
// Language optgroups
"settings.option.general.language.main": "Jazyky",
"settings.option.general.language.fun": "Zábavné jazyky",
"settings.option.general.language.unsorted": "Neřazeno",
// Update Cider
"settings.option.general.updateCider": "Aktualizujte Cider", // Button. Refer to term.check for the check button
"settings.option.general.updateCider.branch": "Pobočka aktualizace cideru", // Dropdown
"settings.option.general.updateCider.branch.description": "Vyberte pobočku, do které chcete Cider aktualizovat",
"settings.option.general.updateCider.branch.main": "Stabilní",
"settings.option.general.updateCider.branch.develop": "Rozvoj",
// Settings - Audio
"settings.header.audio": "Zvuk",
"settings.header.audio.description": "Upravte nastavení zvuku pro Cider.",
"settings.option.audio.quality": "Kvalita zvuku", // Dropdown
"settings.header.audio.quality.hireslossless": "Hi-Res Lossless",
"settings.header.audio.quality.hireslossless.description": "až 24-bit/192 kHz",
"settings.header.audio.quality.lossless": "Lossless",
"settings.header.audio.quality.lossless.description": "až 24-bit/48 kHz",
"settings.header.audio.quality.high": "Vysoké",
"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": "Plynulý přechod zvuku", // Toggle
"settings.option.audio.enableAdvancedFunctionality": "Povolit pokročilé funkce", // Toggle
"settings.option.audio.enableAdvancedFunctionality.description": "Povolení funkce AudioContext umožní rozšířené zvukové funkce, jako je normalizace zvuku, ekvalizéry a vizualizéry, ale na některých systémech to může způsobit zadrhávání ve zvukových stopách.",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Psychoakustická vylepšení, díky nimž vše zní bohatěji a živěji | Navrhl Maikiwi.",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Síla CAP", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Změní sílu zpracování zvuku. (Agresivita může vést k nežádoucím výsledkům)",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Agresivní",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizace zvuku", // Toggle
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizuje špičkovou hlasitost pro jednotlivé stopy a vytváří jednotnější zážitek z poslechu.",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Prostorovost zvuku", // Toggle
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Prostorově upravte zvuk a udělejte zvuk více 3-rozměrný (poznámka: Toto není Dolby Atmos)",
// Settings - Visual
"settings.header.visual": "Vizuální",
"settings.header.visual.description": "Upravte vizuální nastavení pro Cider.",
"settings.option.visual.windowBackgroundStyle": "Styl pozadí okna", // Toggle
"settings.header.visual.windowBackgroundStyle.none": "Žádný",
"settings.header.visual.windowBackgroundStyle.artwork": "Umělecké dílo",
"settings.header.visual.windowBackgroundStyle.image": "obraz",
"settings.option.visual.animatedArtwork": "Animované umělecké dílo", // Dropdown
"settings.header.visual.animatedArtwork.always": "Vždy",
"settings.header.visual.animatedArtwork.limited": "Omezeno na stránky a speciální položky",
"settings.header.visual.animatedArtwork.disable": "Zakázat všude",
"settings.option.visual.animatedArtworkQuality": "Kvalita animovaného uměleckého díla", // Dropdown
"settings.header.visual.animatedArtworkQuality.low": "Nízký",
"settings.header.visual.animatedArtworkQuality.medium": "Střední",
"settings.header.visual.animatedArtworkQuality.high": "Vysoký",
"settings.header.visual.animatedArtworkQuality.veryHigh": "Velmi vysoký",
"settings.header.visual.animatedArtworkQuality.extreme": "Extrémní",
"settings.option.visual.animatedWindowBackground": "Animované pozadí okna", // Toggle
"settings.option.visual.hardwareAcceleration": "Hardwarová akcelerace", // Dropdown
"settings.option.visual.hardwareAcceleration.description": "Vyžaduje opětovné spuštění",
"settings.header.visual.hardwareAcceleration.default": "Výchozí",
"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": "Temný",
// Refer to term.disabled for the disabled option
"settings.option.visual.showPersonalInfo": "Zobrazit osobní údaje", // Toggle
// Settings - Lyrics
"settings.header.lyrics": "Text",
"settings.header.lyrics.description": "Upravte nastavení textů pro Cider.",
"settings.option.lyrics.enableMusixmatch": "Povolit texty Musixmatch", // Toggle
"settings.option.lyrics.enableMusixmatchKaraoke": "Povolit režim karaoke (pouze Musixmatch)", // Toggle
"settings.option.lyrics.musixmatchPreferredLanguage": "Preferovaný jazyk překladu Musixmatch", // Dropdown
"settings.option.lyrics.enableYoutubeLyrics": "Povolit texty YouTube pro hudební videa", // Toggle
// Settings - Connectivity
"settings.header.connectivity": "Konektivita",
"settings.header.connectivity.description": "Upravte nastavení připojení pro Cider.",
"settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown
"settings.option.connectivity.playbackNotifications": "Oznámení o přehrávání", // Toggle
// Refer to term.disabled for the disabled option
"settings.header.connectivity.discordRPC.cider": "Zobrazit jako 'Cider'",
"settings.header.connectivity.discordRPC.appleMusic": "Zobrazit jako 'Apple Music'",
"settings.option.connectivity.discordRPC.clearOnPause": "Vymazat 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": "Povolit Last.fm Now Playing",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Odebrat z názvu písně vystupující interprety (Last.fm)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrovaná stopa ve smyčce (Last.fm)",
// Refer to term.connect for the connect button
// Settings - Experimental
"settings.header.experimental": "Experimentální",
"settings.header.experimental.description": "Upravte experimentální nastavení pro Cider.",
"settings.option.experimental.compactUI": "Kompaktní uživatelské rozhraní", // Toggle
"settings.option.experimental.close_button_hide": "Tlačítko Zavřít by mělo aplikaci skrýt",
"settings.option.experimental.copy_log": "Zkopírujte protokoly do clipboard",
"settings.option.experimental.inline_playlists": "Vložené seznamy skladeb a alba",
// Refer to term.disabled & term.enabled
// Spatialization Menu
"spatial.notTurnedOn": "Prostorová funkce zvuku je zakázána. Chcete-li jej používat, nejprve jej povolte.",
"spatial.spatialProperties": "Prostorové vlastnosti",
"spatial.width": "Šířka",
"spatial.height": "Výška",
"spatial.depth": "Hloubka",
"spatial.gain": "Získat",
"spatial.roomMaterials": "Materiály místnosti",
"spatial.roomDimensions": "Rozměry místnosti",
"spatial.roomPositions": "Pozice místností",
"spatial.setDimensions": "Nastavit rozměry",
"spatial.setPositions": "Nastavení pozici",
"spatial.up": "Nahoru",
"spatial.front": "Přední",
"spatial.left": "Vlevo",
"spatial.right": "Pravo",
"spatial.back": "Zadní",
"spatial.down": "Dolů",
"spatial.listener": "Posluchač",
"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 a spárujte svůj telefon s touto instancí Cider",
// About
"about.thanks": "Velké poděkování patří týmu Cider Collective Team a všem našim přispěvatelům."
}

View file

@ -1,4 +1,4 @@
{
{ // en_PISS Note: This language uses the ellipsis symbol () instead of 3 dots.
// i18n Info
"i18n.languageName": "piss", // name of language in native language
@ -70,8 +70,9 @@
"term.sortBy.artist": "pissers",
"term.sortBy.name": "piss name",
"term.sortBy.genre": "way to piss",
"term.sortBy.releaseDate": "pissed date",
"term.sortBy.releaseDate": "repissed date",
"term.sortBy.duration": "piss duration",
"term.sortBy.dateAdded": "obtained date",
"term.sortOrder": "piss-PISS",
"term.sortOrder.ascending": "pissing upwards",
"term.sortOrder.descending": "pissing downwards",
@ -95,10 +96,10 @@
"term.showMore": "more piss",
"term.showLess": "less piss",
"term.topSongs": "top piss",
"term.latestReleases": "latest piss collection",
"term.time.added": "pissed",
"term.time.released": "pissed",
"term.time.updated": "pissed",
"term.latestReleases": "latest piss",
"term.time.added": "obtained",
"term.time.released": "repissed",
"term.time.updated": "pissdated",
"term.time.hours": "hours",
"term.time.hour": "hour",
"term.time.minutes": "minutes",
@ -132,11 +133,13 @@
"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.addedpreset": "obtained prepiss",
"term.deletepreset.warn": "are you sure you want to obliterate this prepiss?",
"term.deletedpreset": "obliterated prepiss",
"term.requestError": "the request got pissed on",
"term.song.link.generate": "pissing on piss.link…",
"term.musicVideos": "piss videos", // Search page friendlyTypes
"term.stations": "piss stations",
"term.curators": "pissators",
"term.appleCurators": "piss pissators",
"term.radioShows": "shows that piss everywhere",
@ -216,8 +219,8 @@
"action.tray.show": "piss back",
"action.update": "piss!",
"action.copy": "copiss",
"action.newpreset": "new prepiss...", // Equalizer Preset
"action.deletepreset": "unpiss prepiss",
"action.newpreset": "new prepiss", // Equalizer Preset
"action.deletepreset": "obliterate prepiss",
// Settings - General
"settings.header.general": "general",
@ -230,25 +233,35 @@
"settings.option.general.language.unsorted": "???? who put this here",
// Update Cider
"settings.option.general.updateCider": "piss on cider", // Button
"settings.option.general.updateCider": "piss on cider", // Button. Refer to term.check for the check button
"settings.option.general.updateCider.branch": "where to piss on cider", // Dropdown
"settings.option.general.updateCider.branch.description": "there are two toilets, where do you want to piss?",
"settings.option.general.updateCider.branch.main": "smooth pissing experience",
"settings.option.general.updateCider.branch.develop": "cutting-edge piss development",
// 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.hireslossless.description": "up to 24-piss/192 pissHz",
"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.lossless.description": "up to 24-piss/48 pissHz",
"settings.header.audio.quality.enhanced": "business class piss",
"settings.header.audio.quality.high": "nice piss",
"settings.header.audio.quality.low": "piss with blood",
"settings.header.audio.quality.auto": "automatic piss",
"settings.header.audio.quality.high.description": "256 kpiss",
"settings.header.audio.quality.standard": "piss with blood",
"settings.header.audio.quality.standard.description": "64 kpiss",
"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.ciderPPE": "Cider Audio Pissifier™", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "makes your bladder go overboard and makes your piss crisp and clear",
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "pissifier dont go well with 3d piss. turn it off and try again.",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "pissifier strength", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "tune your bladder (blood may appear with turbo strength)",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "normal piss",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "turbo piss",
"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
@ -279,7 +292,7 @@
"settings.header.visual.theme": "colored piss",
// Settings - Visual - Theme name
"settings.option.visual.theme.default": "regular piss",
"settings.option.visual.theme.default": "same old piss",
"settings.option.visual.theme.dark": "black piss",
// Refer to term.disabled for the disabled option
@ -305,7 +318,7 @@
"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.removeFeatured": "dump 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
@ -344,7 +357,7 @@
// Web Remote
"remote.web.title": "piss remote",
"remote.web.description": "piss on your phone camera to connect to Cider.",
"remote.web.description": "piss on your phone camera to pair with Cider.",
// About
"about.thanks": "thanks to the Cider Collective team and all the pisseneers putting this together"

View file

@ -72,6 +72,7 @@
"term.sortBy.genre": "Genre",
"term.sortBy.releaseDate": "Release Date",
"term.sortBy.duration": "Duration",
"term.sortBy.dateAdded": "Date Added",
"term.sortOrder": "A-Z",
"term.sortOrder.ascending": "Ascending",
"term.sortOrder.descending": "Descending",

364
src/i18n/vi_VN.jsonc Normal file
View file

@ -0,0 +1,364 @@
{ // Base File
// i18n Info
"i18n.languageName": "Tiếng Việt", // name of language in native language
"i18n.languageNameEnglish": "Vietnamese", // name of language in English
"i18n.category": "main", // main = real language, fun = fun community languages
"i18n.authors": "@vapormusic", // 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": "Cancel",
"dialog.ok": "OK",
// Notification
"notification.updatingLibrarySongs": "Cập nhật bài hát trong thư viện...",
"notification.updatingLibraryAlbums": "Cập nhật album trong thư viện...",
"notification.updatingLibraryArtists": "Cập nhật ca sĩ trong thư viện...",
// Terms
"term.appleInc": "Apple Inc.",
"term.appleMusic": "Apple Music",
"term.applePodcasts": "Apple Podcasts",
"term.itunes": "iTunes",
"term.github": "GitHub",
"term.discord": "Discord",
"term.learnMore": "Tìm hiểu thêm",
"term.accountSettings": "Cài đặt tài khoản",
"term.logout": "Đăng xuất",
"term.login": "Đăng nhập",
"term.about": "Giới thiệu",
"term.privateSession": "Phiên dùng riêng tư",
"term.queue": "Hàng đợi",
"term.history": "Lịch sử",
"term.search": "Tìm kiếm",
"term.library": "Thư viện",
"term.listenNow": "Nghe ngay",
"term.browse": "Khám phá",
"term.radio": "Radio",
"term.recentlyAdded": "Vừa được thêm",
"term.songs": "Bài hát",
"term.albums": "Album",
"term.artists": "Nghệ sĩ",
"term.podcasts": "Podcast",
"term.playlists": "Playlist",
"term.playlist": "Playlist",
"term.newPlaylist": "Playlist mới",
"term.newPlaylistFolder": "Cụm playlist mới",
"term.createNewPlaylist": "Tạo playlist",
"term.createNewPlaylistFolder": "Tạo cụm playlist",
"term.deletePlaylist": "Bạn có muốn xoá playlist này?",
"term.play": "Phát",
"term.pause": "Dừng",
"term.previous": "Trước đó",
"term.next": "Tiếp theo",
"term.shuffle": "Xáo trộn",
"term.repeat": "Lặp",
"term.volume": "Âm lượng",
"term.mute": "Tắt tiếng",
"term.unmute": "Huỷ tắt tiếng",
"term.share": "Chia sẻ",
"term.share.success": "Đã lưu vào bộ nhớ tạm",
"term.settings": "Cài đặt",
"term.seeAll": "Xem tất cả",
"term.sortBy": "Xếp theo",
"term.sortBy.album": "Album",
"term.sortBy.artist": "Nghệ sĩ",
"term.sortBy.name": "Tên",
"term.sortBy.genre": "Dòng nhạc",
"term.sortBy.releaseDate": "Ngày phát hành",
"term.sortBy.duration": "Thời lượng",
"term.sortBy.dateAdded": "Ngày thêm vào",
"term.sortOrder": "A-Z",
"term.sortOrder.ascending": "Tăng dần",
"term.sortOrder.descending": "Giảm dần",
"term.viewAs": "Xem theo kiểu",
"term.viewAs.coverArt": "Ảnh bìa",
"term.viewAs.list": "Danh sách",
"term.size": "Cỡ",
"term.size.normal": "Vừa",
"term.size.compact": "Thu gọn",
"term.enable": "Bật",
"term.disable": "Tắt",
"term.enabled": "Đã bật",
"term.disabled": "Đã tắt",
"term.connect": "Kết nối",
"term.connecting": "Đang kết nối",
"term.disconnect": "Dừng kết nối",
"term.authed": "Đã đăng nhập",
"term.confirm": "Bạn có chăc không?",
"term.more": "Thêm",
"term.less": "Ít hơn",
"term.showMore": "Hiện thêm",
"term.showLess": "Hiện ít hơn",
"term.topSongs": "Các bài hát nổi bật",
"term.latestReleases": "Mới nhất",
"term.time.added": "Thêm vào ngày",
"term.time.released": "Phát hành vào ngày",
"term.time.updated": "Cập nhật vào ngày",
"term.time.hours": "giờ",
"term.time.hour": "giờ",
"term.time.minutes": "phút",
"term.time.minute": "phút",
"term.time.seconds": "giây",
"term.time.second": "giây",
"term.fullscreenView": "Xem toàn màn hình",
"term.defaultView": "Xem gốc",
"term.audioSettings": "Cài đặt âm thanh",
"term.clearAll": "Xoá tất cả",
"term.recentStations": "Các đài gần đây",
"term.language": "Ngôn ngữ",
"term.funLanguages": "Vui vẻ",
"term.noLyrics": "Đang tìm... / Không có lời bài hát.",
"term.copyright": "Bản quyền",
"term.rightsReserved": "Mọi quyền thuộc về các chủ sở hữu.",
"term.sponsor": "Tài trợ cho dự án này",
"term.ciderTeam": "Cider Team",
"term.developer": "Lập trình viên",
"term.socialTeam": "Social Team",
"term.socials": "PR",
"term.contributors": "Các đóng góp viên",
"term.equalizer": "EQ",
"term.reset": "Đặt về mặc định",
"term.tracks": "bài", // Assume x amount of tracks. e.g. 50 tracks
"term.videos": "Video",
"term.menu": "Menu",
"term.check": "Kiểm tra",
"term.aboutArtist": "Về {{artistName}}", // e.g. 'About Doja Cat'
"term.topResult": "Kết quả gần nhất", // Search Results
"term.sharedPlaylists": "Playlist được chia sẻ", // Search Results
"term.people": "Người dùng", // Search Results
"term.newpreset.name": "Tạo thiét lập EQ", // Equalizer Preset
"term.addedpreset": "Các thiét lập EQ đã được thêm", // Equalizer Preset
"term.deletepreset.warn": "Bạn có muốn xoá thiết lập này?",
"term.deletedpreset": "Thiết lập đã bị xoá",
"term.requestError": "Có vấn đề khi thực hiện yêu cầu.",
"term.song.link.generate": "Tìm URL danh mục trên song.link ...",
"term.musicVideos": "Video ca nhạc", // Search page friendlyTypes
"term.stations": "Các đài",
"term.curators": "Nhà tuyển chọn",
"term.appleCurators": "Tuyển chọn từ Apple",
"term.radioShows": "Các chương trình radio",
"term.recordLabels": "Nhà phát hành âm nhạc",
"term.videoExtras": "Video khác",
"term.top": "Top",
// Home
"home.title": "Chính",
"home.recentlyPlayed": "Mới phát",
"home.recentlyAdded": "Mới thêm vào",
"home.artistsFeed": "Theo dõi",
"home.artistsFeed.noArtist": "Theo dõi các nhạc sĩ mà bạn yêu thích và nhận thông báo khi có bài hát mới.",
"home.madeForYou": "Dành cho bạn",
"home.friendsListeningTo": "Bạn bè đang nghe",
"home.followedArtists": "Các nghệ sĩ đang theo dõi",
// Errors
"error.appleMusicSubRequired": "Apple Music yêu cầu bạn đăng kí.",
"error.connectionError": "Có vấn đề kết nối tới Apple Music.",
"error.noResults": "Không có kết quả.",
"error.noResults.description": "Hãy thử tìm kiếm bẳng từ khoá khác.",
// Podcasts
"podcast.followOnCider": "Theo dõi trên Cider",
"podcast.followedOnCider": "Đang theo dõi trên Cider",
"podcast.subscribeOnItunes": "Theo dõi trên iTunes",
"podcast.subscribedOnItunes": "Đang theo dõi trên iTunes",
"podcast.itunesStore": "Cửa hàng iTunes",
"podcast.episodes": "Các tập",
"podcast.playEpisode": "Phát",
"podcast.website": "Trang chủ",
// Actions
"action.addToLibrary": "Thêm vào thư viện",
"action.addToLibrary.success": "Đã thêm vào thư viện",
"action.addToLibrary.error": "Có lỗi khi thêm vào thư viện",
"action.removeFromLibrary": "Xoá khỏi thư viện",
"action.removeFromLibrary.success": "Đã xoá khỏi thư viện",
"action.addToQueue": "Thêm vào hàng đợi",
"action.addToQueue.success": "Đã thêm vào hàng đợi",
"action.addToQueue.error": "Có lỗi khi thêm vào hàng đợi",
"action.removeFromQueue": "Xoá khỏi hàng đợi",
"action.removeFromQueue.success": "Đã xoá khỏi hàng đợi",
"action.removeFromQueue.error": "Có lỗi khi xoá khỏi hàng đợi",
"action.createPlaylist": "Tạo playlist",
"action.addToPlaylist": "Thêm vào playlist",
"action.removeFromPlaylist": "Xoá khỏi playlist",
"action.addToFavorites": "Thêm vào Yêu thích",
"action.follow": "Theo dõi",
"action.follow.success": "Đã theo dõi",
"action.follow.error": "Có lỗi khi theo dõi",
"action.unfollow": "Ngừng theo dõi",
"action.unfollow.success": "Đã ngừng theo dõi",
"action.unfollow.error": "Có lỗi khi ngừng theo dõi",
"action.playNext": "Phát tiếp theo",
"action.playLater": "Phát cuối cùng",
"action.startRadio": "Tạo đài phát",
"action.goToArtist": "Đi đến nghệ sĩ",
"action.goToAlbum": "Đi đến album",
"action.moveToTop": "Đưa lên đầu",
"action.share": "Chia sẻ",
"action.rename": "Đổi tên",
"action.love": "Yêu thích",
"action.unlove": "Bỏ yêu thích",
"action.dislike": "Không thích",
"action.undoDislike": "Bỏ không thích",
"action.showWebRemoteQR": "Điều khiển từ xa",
"action.playTracksNext": "Phát ${app.selectedMediaItems.length} bài tiếp theo",
"action.playTracksLater": "Phát ${app.selectedMediaItems.length} bài cuối cùng",
"action.removeTracks": "Bỏ ${self.selectedItems.length} bài khỏi hàng đợi",
"action.import": "Nhập",
"action.export": "Xuất",
"action.showAlbum": "Hiện album đầy đủ",
"action.tray.minimize": "Thu nhỏ xuống khay hệ thống",
"action.tray.quit": "Thoát",
"action.tray.show": "Hiện",
"action.update": "Cập nhật",
"action.copy": "Sao chép",
"action.newpreset": "Thiếp lập mới...", // Equalizer Preset
"action.deletepreset": "Xoá thiêt lập",
// Settings - General
"settings.header.general": "Cài đặt chung",
"settings.header.general.description": "Thay đổi các cài đặt chung của Cider.",
"settings.option.general.language": "Ngôn ngữ",
// Language optgroups
"settings.option.general.language.main": "Ngôn ngữ chính",
"settings.option.general.language.fun": "Ngôn ngữ hư cấu",
"settings.option.general.language.unsorted": "Ngôn ngữ khác",
// Update Cider
"settings.option.general.updateCider": "Cập nhật Cider", // Button. Refer to term.check for the check button
"settings.option.general.updateCider.branch": "Nhánh cập nhật", // Dropdown
"settings.option.general.updateCider.branch.description": "Chọn nhánh cập nhật của Cider:",
"settings.option.general.updateCider.branch.main": "Ổn định",
"settings.option.general.updateCider.branch.develop": "Thử nghiệm",
// Settings - Audio
"settings.header.audio": "Âm thanh",
"settings.header.audio.description": "Thay đổi các cài đặt âm thanh của Cider.",
"settings.option.audio.quality": "Chất lượng âm thanh", // Dropdown
"settings.header.audio.quality.hireslossless": "Hi-Res Lossless",
"settings.header.audio.quality.hireslossless.description": "lên tới 24-bit/192 kHz",
"settings.header.audio.quality.lossless": "Lossless",
"settings.header.audio.quality.lossless.description": "lên tới 24-bit/48 kHz",
"settings.header.audio.quality.high": "Cao",
"settings.header.audio.quality.high.description": "256 kbps",
"settings.header.audio.quality.standard": "Tiêu chuẩn",
"settings.header.audio.quality.standard.description": "64 kbps",
"settings.option.audio.seamlessTransition": "Gapless playback", // Toggle
"settings.option.audio.enableAdvancedFunctionality": "Kích hoạt chính năng nâng cao", // Toggle
"settings.option.audio.enableAdvancedFunctionality.description": "Bật các chức năng nâng cao sẽ kích hoạt các chức năng như EQ, Chuẩn hoá âm lượng hay Visualizer, tuy nhiên có thể sẽ ảnh hưởng tới chất lượng âm thanh",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Các tinh chỉnh về âm thanh giúp cho nhạc của bạn ấm và rõ hơn | Tạo bởi Maikiwi.",
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP không tương thích với Âm thanh đa chiều. Hãy tắt Âm thanh đa chiều để kích hoạt.",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "CAP Strength", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Chỉnh mức độ ảnh hưởng của CAP đến âm thanh. (Chế độ Mạnh có thể ảnh hưởng đến âm thanh của bạn)",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Tiêu chuẩn",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Mạnh",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Chuẩn hoá âm lượng", // Toggle
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Đặt cùng mức âm lượng cho mọi bài hát",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Tạo Âm thanh đa chiều ", // Toggle
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Làm cho âm thanh trở nên nhiều chiều hơn (Ghi chú: Đây không phải là Dolby Atmos)",
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Âm thanh đa chiều không tương thích với CAP. Hãy tắt CAP để kích hoạt.",
// Settings - Visual
"settings.header.visual": "Hiển thị",
"settings.header.visual.description": "Thay đổi các cài đặt hiển thị của Cider.",
"settings.option.visual.windowBackgroundStyle": "Chế độ ảnh nền", // Toggle
"settings.header.visual.windowBackgroundStyle.none": "Không",
"settings.header.visual.windowBackgroundStyle.artwork": "Ảnh bìa",
"settings.header.visual.windowBackgroundStyle.image": "Ảnh",
"settings.option.visual.animatedArtwork": "Ảnh bìa động", // Dropdown
"settings.header.visual.animatedArtwork.always": "Luôn bật",
"settings.header.visual.animatedArtwork.limited": "Chỉ hiện ở mốt số trang cá nhân",
"settings.header.visual.animatedArtwork.disable": "Tắt",
"settings.option.visual.animatedArtworkQuality": "Chất lượng ảnh bìa động", // Dropdown
"settings.header.visual.animatedArtworkQuality.low": "Thấp",
"settings.header.visual.animatedArtworkQuality.medium": "Trung bình",
"settings.header.visual.animatedArtworkQuality.high": "Cao",
"settings.header.visual.animatedArtworkQuality.veryHigh": "Rất cao",
"settings.header.visual.animatedArtworkQuality.extreme": "Rất rất cao",
"settings.option.visual.animatedWindowBackground": "Hình nền chuyển động", // Toggle
"settings.option.visual.hardwareAcceleration": "Chế độ Hiển thị", // Dropdown
"settings.option.visual.hardwareAcceleration.description": "Yêu cầu restart lại Cider để kích hoạt",
"settings.header.visual.hardwareAcceleration.default": "Gốc",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.header.visual.theme": "Chủ đề",
// Settings - Visual - Theme name
"settings.option.visual.theme.default": "Cider",
"settings.option.visual.theme.dark": "Tối hơn",
// Refer to term.disabled for the disabled option
"settings.option.visual.showPersonalInfo": "Hiện thông tin cá nhân", // Toggle
// Settings - Lyrics
"settings.header.lyrics": "Lời bài hát",
"settings.header.lyrics.description": "Thay đổi các cài đặt lời bài hát của Cider.",
"settings.option.lyrics.enableMusixmatch": "Dùng lời từ Musixmatch", // Toggle
"settings.option.lyrics.enableMusixmatchKaraoke": "Bật chế độ karaoke (chỉ trên lời từ Musixmatch)", // Toggle
"settings.option.lyrics.musixmatchPreferredLanguage": "Ngôn ngữ dịch của Musixmatch", // Dropdown
"settings.option.lyrics.enableYoutubeLyrics": "Dùng lời từ Youtube cho các Video ca nhạc", // Toggle
// Settings - Connectivity
"settings.header.connectivity": "Kết nối",
"settings.header.connectivity.description": "Thay đổi các cài đặt lời kết nối của Cider.",
"settings.option.connectivity.discordRPC": "Discord Rich Presence", // Dropdown
"settings.option.connectivity.playbackNotifications": "Thông báo chuyển bài", // Toggle
// Refer to term.disabled for the disabled option
"settings.header.connectivity.discordRPC.cider": "Hiện là 'Cider'",
"settings.header.connectivity.discordRPC.appleMusic": "Hiện là 'Apple Music'",
"settings.option.connectivity.discordRPC.clearOnPause": "Xoá Discord Rich Presence khi dừng nhạc", // 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": "Bật Last.fm Now Playing",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Xoá các nghệ sĩ phối hợp ở tên bài hát (Last.fm)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Lọc các bài trùng (Last.fm)",
// Refer to term.connect for the connect button
// Settings - Experimental
"settings.header.experimental": "Thử nghiệm",
"settings.header.experimental.description": "Thay đổi các cài đặt lời thử nghiệm của Cider.",
"settings.option.experimental.compactUI": "UI thu gọn", // Toggle
"settings.option.experimental.close_button_hide": "Nút thoát cửa số sẽ ẩn Cider xuống khay hệ thống",
"settings.option.experimental.copy_log": "Sao chép logs ra bộ nhớ tạm",
"settings.option.experimental.inline_playlists": "Playlists and Albums hiện nổi lên trên",
// Refer to term.disabled & term.enabled
// Spatialization Menu
"spatial.notTurnedOn": "Âm thanh đa chiều chưa được kích hoạt. Hãy kích hoạt nó trước",
"spatial.spatialProperties": "Tinh chỉnh cho Âm thanh đa chiều",
"spatial.width": "Chiều rộng",
"spatial.height": "Chiều cao",
"spatial.depth": "Chiều sâu",
"spatial.gain": "Gain",
"spatial.roomMaterials": "Chất liệu phòng",
"spatial.roomDimensions": "Kích thước phòng",
"spatial.roomPositions": "Vị trí phòng",
"spatial.setDimensions": "Chỉnh kích thước",
"spatial.setPositions": "Chỉnh vị trí",
"spatial.up": "Trên",
"spatial.front": "Trước",
"spatial.left": "Trái",
"spatial.right": "Phải",
"spatial.back": "Sau",
"spatial.down": "Dưới",
"spatial.listener": "Người nghe",
"spatial.audioSource": "Nguồn âm thanh",
// Settings - Unfinished
"settings.header.unfinished": "Chưa hoàn thiện",
// Web Remote
"remote.web.title": "Điều khiển từ xa của Cider",
"remote.web.description": "Quét mã QR để kết nối thiết bị của bạn với Cider",
// About
"about.thanks": "Trân trọng cảm ơn Cider Collective Team và tất cả các đóng góp viên của chúng tôi."
}

View file

@ -49,7 +49,7 @@
"term.newPlaylistFolder": "新播放列表資料夾",
"term.createNewPlaylist": "新增播放列表",
"term.createNewPlaylistFolder": "新增播放列表資料夾",
"term.deletePlaylist": "您確認要删除该播放列表吗?",
"term.deletePlaylist": "您確定要刪除此播放列表嗎?",
"term.play": "播放",
"term.pause": "暫停",
"term.previous": "上一首",
@ -60,7 +60,7 @@
"term.mute": "靜音",
"term.unmute": "取消靜音",
"term.share": "分享",
"term.share.success": "已複製剪貼簿",
"term.share.success": "已複製剪貼簿",
"term.settings": "設定",
"term.seeAll": "顯示全部",
"term.sortBy": "排序",

View file

@ -44,6 +44,7 @@ export class BrowserWindow {
"pages/search",
"pages/about",
"pages/library-videos",
"pages/remote-pair",
"components/mediaitem-artwork",
"components/artwork-material",
"components/menu-panel",
@ -66,6 +67,7 @@ export class BrowserWindow {
"components/listennow-child",
"components/mediaitem-mvview-sp",
"components/animatedartwork-view",
"components/listitem-horizontal",
"components/lyrics-view",
"components/fullscreen",
"components/miniplayer",
@ -525,7 +527,7 @@ export class BrowserWindow {
ipcMain.on('play', (_event, type, id) => {
BrowserWindow.win.webContents.executeJavaScript(`
MusicKit.getInstance().setQueue({ ${type}: '${id}'}).then(function(queue) {
MusicKit.getInstance().setQueue({ ${type}: '${id}', parameters : {l : app.mklang}}).then(function(queue) {
MusicKit.getInstance().play();
});
`)
@ -539,7 +541,7 @@ export class BrowserWindow {
ipcMain.on('get-remote-pair-url', (_event, _) => {
let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`;
BrowserWindow.win.webContents.send('send-remote-pair-url', url);
BrowserWindow.win.webContents.send('send-remote-pair-url', (`https://cider.sh/pair-remote?url=${Buffer.from(encodeURI(url)).toString('base64')}`).toString());
});
if (process.platform === "darwin") {
app.setUserActivity('com.CiderCollective.remote.pair', {

View file

@ -15,6 +15,7 @@ export default class LastFMPlugin {
private _app: any;
private _lastfm: any;
private _store: any;
private _timer: any;
private authenticateFromFile() {
let sessionData = require(this.sessionPath)
@ -77,27 +78,29 @@ export default class LastFMPlugin {
}
}
private async scrobbleSong(attributes: any) {
await new Promise(resolve => setTimeout(resolve, Math.round(attributes.durationInMillis * (this._store.lastfm.scrobble_after / 100))));
private scrobbleSong(attributes: any) {
if(this._timer) clearTimeout(this._timer);
var self = this;
this._timer = setTimeout(() => {
const currentAttributes = attributes;
if (!this._lastfm || this._lastfm.cachedAttributes === attributes) {
if (!self._lastfm || self._lastfm.cachedAttributes === attributes) {
return
}
if (this._lastfm.cachedAttributes) {
if (this._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return;
if (self._lastfm.cachedAttributes) {
if (self._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return;
}
if (currentAttributes.status && currentAttributes === attributes) {
if (fs.existsSync(this.sessionPath)) {
// Scrobble playing song.
if (attributes.status === true) {
this._lastfm.track.scrobble({
self._lastfm.track.scrobble({
'artist': this.filterArtistName(attributes.artistName),
'track': attributes.name,
'album': attributes.albumName,
'albumArtist': this.filterArtistName(attributes.artistName),
'albumArtist': self.filterArtistName(attributes.artistName),
'timestamp': new Date().getTime() / 1000
}, function (err: any, scrobbled: any) {
if (err) {
@ -106,14 +109,14 @@ export default class LastFMPlugin {
console.log('[LastFM] Successfully scrobbled: ', scrobbled);
});
this._lastfm.cachedAttributes = attributes
self._lastfm.cachedAttributes = attributes
}
} else {
this.authenticate();
self.authenticate();
}
} else {
return console.log('[LastFM] Did not add ', attributes.name, '—', this.filterArtistName(attributes.artistName), 'because now playing a other song.');
}
return console.log('[LastFM] Did not add ', attributes.name, '—', self.filterArtistName(attributes.artistName), 'because now playing a other song.');
}},Math.round(attributes.durationInMillis * (self._store.lastfm.scrobble_after / 100)));
}
private filterArtistName(artist: any) {
@ -234,8 +237,8 @@ export default class LastFMPlugin {
* @param attributes Music Attributes (attributes.status = current state)
*/
onPlaybackStateDidChange(attributes: object): void {
this.scrobbleSong(attributes)
this.updateNowPlayingSong(attributes)
this.scrobbleSong(attributes)
}
/**
@ -246,8 +249,8 @@ export default class LastFMPlugin {
if (!this._store.lastfm.filterLoop){
this._lastfm.cachedNowPlayingAttributes = false;
this._lastfm.cachedAttributes = false}
this.scrobbleSong(attributes)
this.updateNowPlayingSong(attributes)
this.scrobbleSong(attributes)
}
}

View file

@ -22,7 +22,8 @@ const MusicKitInterop = {
});
/** wsapi */
MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, () => {
MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, async () => {
await MusicKitInterop.modifyNamesOnLocale();
if (MusicKitInterop.filterTrack(MusicKitInterop.getAttributes(), false, true) || !app.cfg.lastfm.filterLoop) {
global.ipcRenderer.send('nowPlayingItemDidChange', MusicKitInterop.getAttributes());
}
@ -36,7 +37,28 @@ const MusicKitInterop = {
console.warn(`[mediaPlaybackError] ${e}`);
})
},
async modifyNamesOnLocale() {
if (app.mklang == '' || app.mklang == null) {
return;
}
const mk = MusicKit.getInstance()
const nowPlayingItem = mk.nowPlayingItem;
if ((nowPlayingItem?._songId ?? nowPlayingItem?.songId) == null){
return;
}
const id = nowPlayingItem?._songId ?? (nowPlayingItem?.songId ?? nowPlayingItem?.id)
if (id != null) {
try{
const query = await mk.api.v3.music(`/v1${((nowPlayingItem?._songId ?? nowPlayingItem?.songId) != null) ? `/catalog/${mk.storefrontId}/` : `/me/library/`}songs/${id}?l=${app.mklang}`);
if (query?.data?.data[0]){
let attrs = query?.data?.data[0]?.attributes;
if (attrs?.name) { nowPlayingItem.attributes.name = attrs?.name ?? ''}
if (attrs?.albumName) { nowPlayingItem.attributes.albumName = attrs?.albumName ?? ''}
if (attrs?.artistName) { nowPlayingItem.attributes.artistName = attrs?.artistName ?? ''}
}} catch (e) { return;}
} else {return;}
},
getAttributes: function () {
const mk = MusicKit.getInstance()
const nowPlayingItem = mk.nowPlayingItem;
@ -51,8 +73,8 @@ const MusicKitInterop = {
attributes.playParams = attributes?.playParams ?? {id: 'no-id-found'};
attributes.playParams.id = attributes?.playParams?.id ?? 'no-id-found';
attributes.url = {
cider: `cider://play/s/${nowPlayingItem?._songId ?? 'no-id-found'}`,
appleMusic: attributes.websiteUrl ? attributes.websiteUrl : `https://music.apple.com/${mk.storefrontId}/song/${nowPlayingItem?._songId ?? 'no-id-found'}`
cider: `cider://play/s/${nowPlayingItem?._songId ?? (nowPlayingItem?.songId ??'no-id-found')}`,
appleMusic: attributes.websiteUrl ? attributes.websiteUrl : `https://music.apple.com/${mk.storefrontId}/song/${nowPlayingItem?._songId ?? (nowPlayingItem?.songId ??'no-id-found')}`
}
if (attributes.playParams.id === 'no-id-found') {
attributes.playParams.id = nowPlayingItem?.id ?? 'no-id-found';

View file

@ -88,6 +88,7 @@ const app = new Vue({
radio: {
personal: []
},
mklang : 'en',
webview: {
url: "",
title: "",
@ -112,7 +113,8 @@ const app = new Vue({
"name": "0",
"genre": "0",
"releaseDate": "0",
"durationInMillis": "0"
"durationInMillis": "0",
"dateAdded": "0"
},
sorting: "name",
sortOrder: "asc",
@ -312,11 +314,12 @@ const app = new Vue({
return text
// stringTemplateParser('my name is {{name}} and age is {{age}}', {name: 'Tom', age:100})
},
setLz(lang) {
async setLz(lang) {
if (lang == "") {
lang = this.cfg.general.language
}
this.lz = ipcRenderer.sendSync("get-i18n", lang)
this.mklang = await this.MKJSLang()
},
getLz(message) {
if (this.lz[message]) {
@ -332,7 +335,8 @@ const app = new Vue({
"name": app.getLz('term.sortBy.name'),
"genre": app.getLz('term.sortBy.genre'),
"releaseDate": app.getLz('term.sortBy.releaseDate'),
"durationInMillis": app.getLz('term.sortBy.duration')
"durationInMillis": app.getLz('term.sortBy.duration'),
"dateAdded": app.getLz('term.sortBy.dateAdded')
}
app.$data.library.albums.sortingOptions = {
@ -572,6 +576,8 @@ const app = new Vue({
this.mk._services.timing.mode = 0
this.platform = ipcRenderer.sendSync('cider-platform');
this.mklang = await this.MKJSLang()
try {
// Set profile name
this.chrome.userinfo = (await app.mk.api.v3.music(`/v1/me/social-profile`)).data.data[0]
@ -637,7 +643,8 @@ const app = new Vue({
let kind = lastItem.attributes.playParams.kind;
let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
app.mk.setQueue({
[truekind]: [lastItem.attributes.playParams.id]
[truekind]: [lastItem.attributes.playParams.id],
parameters : {l : app.mklang}
})
app.mk.mute()
setTimeout(() => {
@ -690,7 +697,7 @@ const app = new Vue({
ipcRenderer.on('play', function(_event, mode, id) {
if (mode !== 'url'){
self.mk.setQueue({[mode]: id}).then(() => {
self.mk.setQueue({[mode]: id , parameters : {l : self.mklang}}).then(() => {
app.mk.play()
})
@ -727,7 +734,7 @@ const app = new Vue({
} 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) => {
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem?._songId ?? (app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id)}`).then((response) => {
previewURL = response.data.data[0].attributes.previews[0].url
if (previewURL)
ipcRenderer.send('getPreviewURL', previewURL)
@ -796,6 +803,7 @@ const app = new Vue({
this.getBrowsePage();
this.$forceUpdate()
}, 500)
},
setTheme(theme = "") {
console.log(theme)
@ -1016,12 +1024,12 @@ 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}?l=${this.mklang}`, {}, {includeResponseMeta: !0})).data
console.log(response)
await this.showCollection(response, title, "artists")
},
async showRecordLabelView(label, title, view) {
let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/record-labels/${label}/view/${view}`)).data
let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/record-labels/${label}/view/${view}?l=${this.mklang}`)).data
await this.showCollection(response, title, "record-labels")
},
async showSearchView(term, group, title) {
@ -1051,7 +1059,8 @@ const app = new Vue({
omit: {
resource: ["autos"]
},
groups: group
groups: group,
l : this.mklang
}
let response = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${term}`, requestBody, {
includeResponseMeta: !0
@ -1102,7 +1111,8 @@ const app = new Vue({
"fields[playlists]": "curatorName,playlistType,name,artwork,url,playParams",
"include[library-songs]": "catalog,artists,albums,playParams,name,artwork,url",
"fields[catalog]": "artistUrl,albumUrl,url",
"fields[songs]": "artistUrl,albumUrl,playParams,name,artwork,url,artistName,albumName,durationInMillis"
"fields[songs]": "artistUrl,albumUrl,playParams,name,artwork,url,artistName,albumName,durationInMillis",
l : this.mklang
}
if (!transient) {
this.playlists.loadingState = 0;
@ -1130,7 +1140,8 @@ const app = new Vue({
"include[songs]": "albums",
"fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount",
"limit[artists:top-songs]": 20,
"art[url]": "f"
"art[url]": "f",
l : this.mklang
}, {includeResponseMeta: !0})
console.log(artistData.data.data[0])
this.artistPage.data = artistData.data.data[0]
@ -1325,7 +1336,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", l : app.mklang});
app.searchAndNavigate(u.data.data[0], target)
},
async searchAndNavigate(item, target) {
@ -1530,6 +1541,7 @@ const app = new Vue({
if (kind == "album" | kind == "albums") {
params["include"] = "tracks,artists,record-labels,catalog";
}
params['l'] = this.mklang;
try {
a = await this.mkapi(kind.toString(), isLibrary, id.toString(), params, params2);
} catch (e) {
@ -1558,17 +1570,24 @@ const app = new Vue({
searchLibrarySongs() {
let self = this
let prefs = this.cfg.libraryPrefs.songs
let albumAdded = self.library?.albums?.listing?.map(function(i){return {[i.id]: i.attributes?.dateAdded}})
let startTime = new Date().getTime()
function sortSongs() {
// sort this.library.songs.displayListing by song.attributes[self.library.songs.sorting] in descending or ascending order based on alphabetical order and numeric order
// check if song.attributes[self.library.songs.sorting] is a number and if so, sort by number if not, sort by alphabetical order ignoring case
self.library.songs.displayListing.sort((a, b) => {
let aa = a.attributes[prefs.sort]
let bb = b.attributes[prefs.sort]
if (self.library.songs.sorting == "genre") {
if (prefs.sort == "genre") {
aa = a.attributes.genreNames[0]
bb = b.attributes.genreNames[0]
}
if (prefs.sort == "dateAdded"){
let albumida = a.relationships?.albums?.data[0]?.id ?? '1970-01-01T00:01:01Z'
let albumidb = b.relationships?.albums?.data[0]?.id ?? '1970-01-01T00:01:01Z'
aa = startTime - new Date(((albumAdded.find(i => i[albumida]))?? [])[albumida] ?? '1970-01-01T00:01:01Z').getTime()
bb = startTime - new Date(((albumAdded.find(i => i[albumidb]))?? [])[albumidb] ?? '1970-01-01T00:01:01Z').getTime()
}
if (aa == null) {
aa = ""
}
@ -1820,10 +1839,11 @@ const app = new Vue({
"fields[catalog]": "artistUrl,albumUrl",
"fields[songs]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url",
limit: 100,
l: self.mklang
}
const safeparams = {
"platform": "web",
"limit": 80,
"limit": 80
}
self.library.songs.downloadState = 1
if (downloaded == null) {
@ -1923,6 +1943,7 @@ const app = new Vue({
"fields[catalog]": "artistUrl,albumUrl",
"fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url",
limit: 100,
l: self.mklang
}
const safeparams = {
platform: "web",
@ -2032,6 +2053,7 @@ const app = new Vue({
// "fields[catalog]": "artistUrl,albumUrl",
// "fields[artists]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url",
limit: 100,
l: self.mklang
}
const safeparams = {
include: "catalog",
@ -2122,12 +2144,12 @@ const app = new Vue({
}
},
async getLibrarySongs() {
let response = await this.mkapi("songs", true, "", {limit: 100}, {includeResponseMeta: !0})
let response = await this.mkapi("songs", true, "", {limit: 100, l : this.mklang}, {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, l : this.mklang}, {includeResponseMeta: !0})
this.library.albums.listing = response.data.data
this.library.albums.meta = response.data.meta
},
@ -2161,7 +2183,8 @@ const app = new Vue({
"extend[stations]": ["airDate", "supportsAirTimeUpdates"],
"meta[stations]": "inflectionPoints",
types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-upsells",
platform: "web"
platform: "web",
l: this.mklang
}, {
includeResponseMeta: !0,
reload: !0
@ -2190,7 +2213,8 @@ const app = new Vue({
"include[music-videos]": "artists",
extend: "editorialArtwork,artistUrl",
"fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes",
"art[url]": "f"
"art[url]": "f",
l: this.mklang
});
this.browsepage = browse.data.data[0];
this.browsepage.timestamp = Date.now()
@ -2207,7 +2231,8 @@ const app = new Vue({
try {
this.radio.personal = (await app.mk.api.v3.music(`/v1/me/recent/radio-stations`, {
"platform": "web",
"art[url]": "f"
"art[url]": "f",
l: this.mklang
})).data.data;
} catch (e) {
console.log(e)
@ -2273,12 +2298,12 @@ const app = new Vue({
}
},
loadAMLyrics() {
const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ?? -1 : -1;
const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ?? (this.mk.nowPlayingItem["songId"] ?? -1) : -1;
// this.getMXM( trackName, artistName, 'en', duration);
if (songID != -1) {
MusicKit.getInstance().api.lyric(songID)
this.mk.api.v3.music(`v1/catalog/${this.mk.storefrontId}/songs/${songID}/lyrics`)
.then((response) => {
this.lyricsMediaItem = response.attributes["ttml"]
this.lyricsMediaItem = response.data?.data[0]?.attributes["ttml"]
this.parseTTML()
})
}
@ -2304,7 +2329,7 @@ const app = new Vue({
},
async losslessBadge() {
const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ?? -1 : -1;
const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ?? (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')) {*/
@ -2389,7 +2414,7 @@ const app = new Vue({
const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : '');
const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : '');
const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1);
const id = encodeURIComponent((this.mk.nowPlayingItem != null) ? app.mk.nowPlayingItem._songId ?? '' : '');
const id = encodeURIComponent((this.mk.nowPlayingItem != null) ? app.mk.nowPlayingItem._songId ?? (app.mk.nowPlayingItem["songId"] ?? '') : '');
let lrcfile = "";
let richsync = [];
const lang = app.cfg.lyrics.mxm_language // translation language
@ -2698,7 +2723,8 @@ const app = new Vue({
});
} else {
this.mk.setQueue({
[truekind]: [id]
[truekind]: [id],
parameters : {l : this.mklang}
}).then(function (queue) {
MusicKit.getInstance().play()
})
@ -2738,7 +2764,8 @@ const app = new Vue({
app.mk.stop().then(() => {
if (item) {
app.mk.setQueue({
[item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id
[item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id,
parameters : {l : app.mklang}
}).then(function () {
app.mk.play().then(() => {
if (app.mk.shuffleMode == 1) {
@ -2772,7 +2799,8 @@ const app = new Vue({
app.mk.stop().then(() => {
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
[item.attributes.playParams.kind ?? item.type]: item.attributes.playParams.id ?? item.id,
parameters : {l : app.mklang}
}).then(function () {
app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ?? 1).then(function () {
if ((app.showingPlaylist && app.showingPlaylist.id == id)) {
@ -2811,7 +2839,8 @@ const app = new Vue({
})
} else {
this.mk.setQueue({
[truekind]: [id]
[truekind]: [id],
parameters : {l : this.mklang}
}).then(function (queue) {
if (item && ((queue._itemIDs[childIndex] != item.id))) {
childIndex = queue._itemIDs.indexOf(item.id)
@ -2910,7 +2939,8 @@ const app = new Vue({
"art[url]": "c,f",
"omit[resource]": "autos",
"platform": "web",
limit: 25
limit: 25,
l: this.mklang
}).then(function (results) {
results.data.results["meta"] = results.data.meta
self.search.results = results.data.results
@ -3126,7 +3156,7 @@ const app = new Vue({
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().setQueue({song: data["songs"]['data'][0]["id"], parameters : {l : app.mklang}}).then(function (queue) {
MusicKit.getInstance().play()
setTimeout(() => {
self.$forceUpdate()
@ -3383,7 +3413,7 @@ const app = new Vue({
"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.mkapi(app.mk.nowPlayingItem.attributes?.playParams?.kind ?? app.mk.nowPlayingItem.type ?? 'songs', false, app.mk.nowPlayingItem._songId ?? (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)
})
}
@ -3392,7 +3422,7 @@ const app = new Vue({
"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.mkapi(app.mk.nowPlayingItem.attributes?.playParams?.kind ?? app.mk.nowPlayingItem.type ?? 'songs', false, app.mk.nowPlayingItem._songId ?? (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)
})
}
@ -3572,6 +3602,13 @@ const app = new Vue({
darwinShare(url) {
ipcRenderer.send('share-menu', url)
},
arrayToChunk(arr, chunkSize) {
let R = [];
for (let i = 0, len = arr.length; i < len; i += chunkSize) {
R.push(arr.slice(i, i + chunkSize));
}
return R;
},
SpacePause() {
const elems = document.querySelectorAll('input');
for (elem of elems){
@ -3582,16 +3619,36 @@ const app = new Vue({
if (!this.isDev) // disable in dev mode to keep my sanity
MusicKitInterop.playPause();
},
MKJSLang(){
async MKJSLang(){
let u = this.cfg.general.language;
let langcodes = ['af', 'sq', 'ar', 'eu', 'bg', 'be', 'ca', 'zh', 'zh-tw', 'zh-cn', 'zh-hk', 'zh-sg', 'hr', 'cs', 'da', 'nl', 'nl-be', 'en', 'en-us', 'en-eg', 'en-au', 'en-gb', 'en-ca', 'en-nz', 'en-ie', 'en-za', 'en-jm', 'en-bz', 'en-tt', 'en-001', 'et', 'fo', 'fa', 'fi', 'fr', 'fr-ca', 'gd', 'de', 'de-ch', 'el', 'he', 'hi', 'hu', 'is', 'id', 'it', 'ja', 'ko', 'lv', 'lt', 'mk', 'mt', 'no', 'nb', 'nn', 'pl', 'pt-br', 'pt', 'rm', 'ro', 'ru', 'sr', 'sk', 'sl', 'es', 'es-mx', 'es-419', 'sv', 'th', 'ts', 'tn', 'tr', 'uk', 'ur', 've', 'vi', 'xh', 'yi', 'zu', 'ms', 'iw', 'lo', 'tl', 'kk', 'ta', 'te', 'bn', 'ga', 'ht', 'la', 'pa', 'sa'];
let sellang = "en"
if (u && langcodes.includes(u.toLowerCase().replace('_', "-"))) {
sellang = ((u.toLowerCase()).replace('_', "-"))
} else if (u && u.includes('_') && langcodes.includes(((u.toLowerCase()).replace('_', "-")).split("-")[0])) {
sellang = ((u.toLowerCase()).replace('_', "-")).split("-")[0]
// use MusicKit.getInstance or crash
try {
item = await MusicKit.getInstance().api.v3.music(`v1/storefronts/${app.mk.storefrontId}`)
let langcodes = item.data.data[0].attributes.supportedLanguageTags;
if (langcodes) langcodes = langcodes.map(function (u) { return u.toLowerCase() })
console.log(langcodes)
let sellang = ""
if (u && langcodes.includes(u.toLowerCase().replace('_', "-"))) {
sellang = ((u.toLowerCase()).replace('_', "-"))
} else if (u && u.includes('_') && langcodes.includes(((u.toLowerCase()).replace('_', "-")).split("-")[0])) {
sellang = ((u.toLowerCase()).replace('_', "-")).split("-")[0]
}
if (sellang == "") sellang = (item.data.data[0].attributes.defaultLanguageTag).toLowerCase()
console.log(sellang)
return await sellang
}
catch (err) {
console.log('locale err', err)
let langcodes = ['af', 'sq', 'ar', 'eu', 'bg', 'be', 'ca', 'zh', 'zh-tw', 'zh-cn', 'zh-hk', 'zh-sg', 'hr', 'cs', 'da', 'nl', 'nl-be', 'en', 'en-us', 'en-eg', 'en-au', 'en-gb', 'en-ca', 'en-nz', 'en-ie', 'en-za', 'en-jm', 'en-bz', 'en-tt', 'en-001', 'et', 'fo', 'fa', 'fi', 'fr', 'fr-ca', 'gd', 'de', 'de-ch', 'el', 'he', 'hi', 'hu', 'is', 'id', 'it', 'ja', 'ko', 'lv', 'lt', 'mk', 'mt', 'no', 'nb', 'nn', 'pl', 'pt-br', 'pt', 'rm', 'ro', 'ru', 'sr', 'sk', 'sl', 'es', 'es-mx', 'es-419', 'sv', 'th', 'ts', 'tn', 'tr', 'uk', 'ur', 've', 'vi', 'xh', 'yi', 'zu', 'ms', 'iw', 'lo', 'tl', 'kk', 'ta', 'te', 'bn', 'ga', 'ht', 'la', 'pa', 'sa'];
let sellang = "en"
if (u && langcodes.includes(u.toLowerCase().replace('_', "-"))) {
sellang = ((u.toLowerCase()).replace('_', "-"))
} else if (u && u.includes('_') && langcodes.includes(((u.toLowerCase()).replace('_', "-")).split("-")[0])) {
sellang = ((u.toLowerCase()).replace('_', "-")).split("-")[0]
}
if (sellang.startsWith("en") && this.mk.storefrontId != "en-us") sellang = "en-gb"
return await sellang
}
return sellang
}
}
})

View file

@ -81,14 +81,14 @@ const wsapi = {
},
playTrackById(id, kind = "song") {
MusicKit.getInstance().setQueue({ [kind]: id }).then(function (queue) {
MusicKit.getInstance().setQueue({ [kind]: id , parameters : {l : app.mklang}}).then(function (queue) {
MusicKit.getInstance().play()
})
},
quickPlay(term) {
// Quick play by song name
MusicKit.getInstance().api.search(term, { limit: 2, types: 'songs' }).then(function (data) {
MusicKit.getInstance().setQueue({ song: data["songs"][0]["id"] }).then(function (queue) {
MusicKit.getInstance().setQueue({ song: data["songs"][0]["id"],parameters : {l : app.mklang} }).then(function (queue) {
MusicKit.getInstance().play()
})
})

File diff suppressed because it is too large Load diff

View file

@ -663,6 +663,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
.usermenu-container {
top: 0px;
z-index: 200001 !important;
#cmenu.container();
.usermenu-body {
@ -2977,7 +2978,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
padding-top: var(--navigationBarHeight);
.playlist-body {
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
padding: var(--contentInnerPadding) 2em;
margin-top: -75px;
}
@ -3445,7 +3446,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.artist-body {
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
margin-top: -140px;
margin: -140px 20px;
}
&.animated > .artist-body {
@ -3566,7 +3567,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
position: fixed;
top: 0;
left: 0;
z-index: 1001;
z-index: 100001;
display: flex;
justify-content: center;
align-items: center;
@ -4271,7 +4272,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
/* mediaitem-square */
.cd-mediaitem-square {
width: 220px;
height: 260px;
height: 238px;
display: inline-flex;
flex: 0 0 auto;
flex-direction: column;
@ -5410,26 +5411,19 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
// Cider App
.listitem-horizontal {
.cd-mediaitem-list-item {
width: 350px;
height: 60px;
}
}
.mediaitem-list-item__grid {
overflow-x: overlay;
overflow-y: hidden;
background: rgba(200, 200, 200, 0.05);
border-radius: 10px;
padding: var(--contentInnerPadding);
box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
height: 300px;
display: flex;
align-items: center;
.grid-body {
display: grid;
grid-auto-flow: column dense;
grid-template-rows: auto auto auto auto;
grid-gap: 0 6px;
padding: 2px 0;
justify-content: left;
width: 0;
}
width: 100%;
.cd-mediaitem-list-item {
width: 350px;

View file

@ -159,5 +159,11 @@
<cider-applecurator :data="appleCurator"></cider-applecurator>
</template>
</transition>
<!-- Library - Library Videos -->
<transition name="wpfade">
<template v-if="page == 'remote-pair'">
<remote-pair></remote-pair>
</template>
</transition>
</div>

View file

@ -93,12 +93,8 @@
</div>
</button>
<button class="usermenu-item" @click="appRoute('remote-pair')">
<div class="row nopadding">
<div class="col nopadding">
<span class="usermenu-item-icon"><%- include("../svg/smartphone.svg") %></span>
<span class="usermenu-item-name">{{$root.getLz('action.showWebRemoteQR')}}</span>
</div>
</div>
</button>
<button class="usermenu-item" v-if="cfg.advanced.AudioContext"
@click="modals.audioSettings = true">

View file

@ -0,0 +1,43 @@
<script type="text/x-template" id="listitem-horizontal">
<div class="listitem-horizontal">
<vue-horizontal>
<div v-for="items in itemPages">
<mediaitem-list-item
v-for="(song, index) in items"
:index="song.index"
:item="song"></mediaitem-list-item>
</div>
</vue-horizontal>
</div>
</script>
<script>
Vue.component('listitem-horizontal', {
template: '#listitem-horizontal',
name: "listitem-horizontal",
props: {
items: {
type: Array,
required: true
}
},
data: function () {
return {
itemPages: []
}
},
mounted() {
// give every item an id
this.items.forEach(function (item, index) {
item.id = index;
});
// split items into pages
this.itemPages = app.arrayToChunk(this.items, 4);
},
methods: {
sayHello: function () {
alert('Hello world!');
}
}
});
</script>

View file

@ -19,16 +19,16 @@
<button @click="addToLibrary()" v-if="!addedToLibrary && (showIndex == false ||(showIndex == true && showIndexPlaylist != false))">
<div class="svg-icon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/plus.svg)'}"></div>
</button>
<button v-else @click="playTrack()" style="width: 44px;margin-left: -11px;">
<button v-else-if='!(showArtwork == true && (showIndex == false ||(showIndex == true && showIndexPlaylist != false)))' @click="playTrack()" style="width: 44px;margin-left: -11px;">
<%- include("../svg/play.svg") %>
</button>
</div>
<div v-if="!(app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.id ) == item.attributes.playParams.id) || (app.mk.nowPlayingItem.id == item.id ))) && showIndex" :style="{display: ((showIndex && !showInLibrary) ? 'block' : 'none'), 'margin-left':'11px'}">
<div v-if="!(app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? (app.mk.nowPlayingItem.songId ?? app.mk.nowPlayingItem.id )) == item.attributes.playParams.id) || (app.mk.nowPlayingItem.id == item.id ))) && showIndex" :style="{display: ((showIndex && !showInLibrary) ? 'block' : 'none'), 'margin-left':'11px'}">
<div>
<div>{{ (item.attributes && !showIndexPlaylist) ? (item.attributes.trackNumber ?? '') : ((index * 1 + 1 ) ?? '')}}</div>
</div>
</div>
<div v-if="app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.id ) == item.attributes.playParams.id) || (app.mk.nowPlayingItem.id == item.id))" :style="{display: (showInLibrary ? 'none' : 'block')}">
<div v-if="app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? (app.mk.nowPlayingItem.songId ?? app.mk.nowPlayingItem.id )) == item.attributes.playParams.id) || (app.mk.nowPlayingItem.id == item.id))" :style="{display: (showInLibrary ? 'none' : 'block')}">
<div class="loadbar-sound"></div>
</div>
</div>
@ -531,7 +531,7 @@
array[j] = temp;
}
}
app.mk.setQueue({ [truekind]: [item.attributes.playParams.id ?? item.id] }).then(function () {
app.mk.setQueue({ [truekind]: [item.attributes.playParams.id ?? item.id] , parameters : {l : this.app.mklang} }).then(function () {
app.mk.play().then(function () {
var playlistId = id
function getPlaylist(id, isLibrary) {

View file

@ -66,7 +66,7 @@
},
methods: {
async getHistory() {
let history = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`)
let history = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`, { l : this.$root.mklang})
this.history = history.data.data
},
select(e, position) {

View file

@ -78,7 +78,7 @@
let self = this
this.artists = []
this.artistFeed = []
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=latest-release&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=2&art[url]=f`).then(artistData => {
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=latest-release&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=2&art[url]=f`,{ l : this.$root.mklang}).then(artistData => {
artistData.data.data.forEach(item => {
self.artists.push(item)
if (item.views["latest-release"].data.length != 0) {

View file

@ -57,35 +57,32 @@
</div>
<div class="artist-body">
<div class="row well">
<div class="col">
<div class="col-sm-3" v-if="data.views['latest-release'].data.length != 0">
<h3>{{app.getLz('term.latestReleases')}}</h3>
<div style="width: auto;margin: 0 auto;">
<mediaitem-square kind="card" v-for="song in data.views['latest-release'].data"
:item="song">
</mediaitem-square>
</div>
</div>
<div class="col-sm-9" v-if="data.views['top-songs']">
<div class="row">
<div class="col-auto" v-if="data.views['latest-release'].data.length != 0">
<h3>{{app.getLz('term.latestReleases')}}</h3>
<div style="width: auto;margin: 0 auto;">
<mediaitem-square kind="card" v-for="song in data.views['latest-release'].data"
:item="song">
</mediaitem-square>
</div>
<div class="col" style="padding:0;">
<h3>{{app.getLz('term.topSongs')}}</h3>
</div>
<div class="col" v-if="data.views['top-songs']">
<div class="row">
<div class="col" style="padding:0;">
<h3>{{app.getLz('term.topSongs')}}</h3>
</div>
<div class="col-auto flex-center" v-if="data.views['top-songs'].data.length >= 16" style="padding:0;">
<button class="cd-btn-seeall" @click="app.showArtistView(data.id, data.attributes.name + ' - Top Songs', 'top-songs')">{{app.getLz('term.seeAll')}}</button>
</div>
</div>
<div class="col-auto flex-center" v-if="data.views['top-songs'].data.length >= 16" style="padding:0;">
<button class="cd-btn-seeall" @click="app.showArtistView(data.id, data.attributes.name + ' - Top Songs', 'top-songs')">{{app.getLz('term.seeAll')}}</button>
</div>
</div>
<div class="row">
<div class="col flex-center" style="padding:0;">
<div class="mediaitem-list-item__grid">
<div class="grid-body">
<mediaitem-list-item
v-for="(song, index) in data.views['top-songs'].data.limit(16)"
:index="index"
:item="song"></mediaitem-list-item>
</div>
<listitem-horizontal :items="data.views['top-songs'].data.limit(16)">
</listitem-horizontal>
</div>
</div>
</div>
</div>
</div>
<div class="row well">

View file

@ -289,7 +289,7 @@
this.confirm = false
},
async removeFromLibrary(id) {
const params = {"fields[somgs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library"};
const params = {"fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library"};
var id = this.data.id ?? this.data.attributes.playParams.id
const res = await app.mkapi(this.data.attributes.playParams.kind ?? this.data.type, this.data.attributes.playParams.isLibrary ?? false, this.data.attributes.playParams.id ?? this.data.id, params);
if (res.data.data[0] && res.data.data[0].relationships && res.data.data[0].relationships.library && res.data.data[0].relationships.library.data && res.data.data[0].relationships.library.data.length > 0) {
@ -480,7 +480,7 @@
let query = (this.data ?? app.showingPlaylist).relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
app.mk.stop().then(function () {
app.mk.setQueue({[truekind]: [id]}).then(function () {
app.mk.setQueue({[truekind]: [id] , parameters : {l : app.mklang}}).then(function () {
app.mk.play().then(function () {
if (query.length > 100) {
let u = query.slice(100);

View file

@ -3,12 +3,12 @@
<div v-if="page == 'main'">
<div class="row">
<div class="col">
<div class="row nopadding">
<div class="row">
<div class="col nopadding">
<h3>{{app.getLz('home.recentlyPlayed')}}</h3>
</div>
<div class="col-auto nopadding flex-center">
<button class="cd-btn-seeall" @click="seeAllHistory()">{{app.getLz('term.seeAll')}}</button>
<button class="cd-btn-seeall" @click="seeAllHistory()">{{app.getLz('term.history')}}</button>
</div>
</div>
<div class="well artistfeed-well">
@ -20,7 +20,7 @@
</div>
</div>
<div class="col">
<div class="row nopadding">
<div class="row">
<div class="col nopadding">
<h3>{{app.getLz('home.artistsFeed')}}</h3>
</div>
@ -54,7 +54,7 @@
<h3>{{app.getLz('home.madeForYou')}}</h3>
<div class="well">
<vue-horizontal v-if="isSectionReady('madeForYou')">
<mediaitem-square kind="small" v-for="item in madeForYou" :item="item"></mediaitem-square>
<mediaitem-square kind="small" v-for="item in madeForYou" :item="item"></mediaitem-square>
</vue-horizontal>
<div class="spinner" v-else></div>
</div>
@ -72,9 +72,8 @@
</div>
<div class="well">
<vue-horizontal v-if="isSectionReady('friendsListeningTo')">
<mediaitem-square kind="small" v-for="item in friendsListeningTo"
:item="item"></mediaitem-square>
</vue-horizontal>
<mediaitem-square kind="small" v-for="item in friendsListeningTo" :item="item"></mediaitem-square>
</vue-horizontal>
<div class="spinner" v-else></div>
</div>
</div>
@ -86,7 +85,7 @@
<script>
Vue.component('cider-home', {
template: '#cider-home',
data: function () {
data: function() {
return {
app: this.$root,
followedArtists: this.$root.cfg.home.followedArtists,
@ -112,7 +111,9 @@
},
methods: {
async seeAllHistory() {
let hist = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`)
let hist = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`, {
l: this.$root.mklang
})
app.showCollection(hist.data, app.getLz('term.history'))
},
isSectionReady(section) {
@ -122,7 +123,7 @@
let self = this
return {
name: "Remove from Favorites",
action: function (item) {
action: function(item) {
let index = self.favoriteItems.findIndex(x => x.id == item.id)
if (index > -1) {
self.favoriteItems.splice(index, 1)
@ -143,12 +144,16 @@
}
}
if (playlists.length != 0) {
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${playlists.toString()}`).then(playlistsData => {
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${playlists.toString()}`, {
l: this.$root.mklang
}).then(playlistsData => {
self.favorites.push(...playlistsData.data)
})
}
if (libraryPlaylists.length != 0) {
this.app.mk.api.v3.music(`v1/me/library/playlists/${playlists.toString()}`).then(playlistsData => {
this.app.mk.api.v3.music(`v1/me/library/playlists/${playlists.toString()}`, {
l: this.$root.mklang
}).then(playlistsData => {
self.favorites.push(...playlistsData.data)
})
}
@ -156,13 +161,13 @@
async getArtistFeed() {
let artists = this.followedArtists
let self = this
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=latest-release&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=2&art[url]=f`).then(artistData => {
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=latest-release&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=2&art[url]=f&l=${this.$root.mklang}`).then(artistData => {
artistData.data.data.forEach(item => {
if (item.views["latest-release"].data.length != 0) {
self.artistFeed.push(item.views["latest-release"].data[0])
}
})
// sort artistFeed by attributes.releaseDate descending, date is formatted as "YYYY-MM-DD"
if (item.views["latest-release"].data.length != 0) {
self.artistFeed.push(item.views["latest-release"].data[0])
}
})
// sort artistFeed by attributes.releaseDate descending, date is formatted as "YYYY-MM-DD"
this.artistFeed.sort((a, b) => {
let dateA = new Date(a.attributes.releaseDate)
let dateB = new Date(b.attributes.releaseDate)
@ -177,7 +182,7 @@
},
async getListenNowData() {
let self = this
this.app.mk.api.v3.music(`/v1/me/recommendations?timezone=${encodeURIComponent(app.formatTimezoneOffset())}&name=listen-now&with=friendsMix,library,social&art[social-profiles:url]=c&art[url]=c,f&omit[resource]=autos&relate[editorial-items]=contents&extend=editorialCard,editorialVideo&extend[albums]=artistUrl&extend[library-albums]=artistUrl,editorialVideo&extend[playlists]=artistNames,editorialArtwork,editorialVideo&extend[library-playlists]=artistNames,editorialArtwork,editorialVideo&extend[social-profiles]=topGenreNames&include[albums]=artists&include[songs]=artists&include[music-videos]=artists&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url&fields[artists]=name,url&extend[stations]=airDate,supportsAirTimeUpdates&meta[stations]=inflectionPoints&types=artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-upsells&platform=web`).then((data) => {
this.app.mk.api.v3.music(`/v1/me/recommendations?timezone=${encodeURIComponent(app.formatTimezoneOffset())}&name=listen-now&with=friendsMix,library,social&art[social-profiles:url]=c&art[url]=c,f&omit[resource]=autos&relate[editorial-items]=contents&extend=editorialCard,editorialVideo&extend[albums]=artistUrl&extend[library-albums]=artistUrl,editorialVideo&extend[playlists]=artistNames,editorialArtwork,editorialVideo&extend[library-playlists]=artistNames,editorialArtwork,editorialVideo&extend[social-profiles]=topGenreNames&include[albums]=artists&include[songs]=artists&include[music-videos]=artists&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url&fields[artists]=name,url&extend[stations]=airDate,supportsAirTimeUpdates&meta[stations]=inflectionPoints&types=artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-upsells&platform=web&l=${this.$root.mklang}`).then((data) => {
console.log(data.data.data[1])
try {
self.madeForYou = data.data.data.filter(section => {
@ -185,7 +190,7 @@
return section
};
})[0].relationships.contents.data
} catch (err) { }
} catch (err) {}
self.sectionsReady.push("madeForYou")
try {
@ -195,7 +200,7 @@
return section
};
})[0].relationships.contents.data
} catch (err) { }
} catch (err) {}
self.sectionsReady.push("recentlyPlayed")
self.sectionsReady.push("friendsListeningTo")
});

View file

@ -534,7 +534,7 @@
let query = (this.data ?? app.showingPlaylist).relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
app.mk.stop().then(function () {
app.mk.setQueue({[truekind]: [id]}).then(function () {
app.mk.setQueue({[truekind]: [id] , parameters : {l : app.mklang}}).then(function () {
app.mk.play().then(function () {
if (query.length > 100) {
let u = query.slice(100);

View file

@ -204,7 +204,7 @@
return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
},
playEpisode(episode) {
app.mk.setQueue({'episode': episode.id}).then(() => {app.mk.play()})
app.mk.setQueue({'episode': episode.id, parameters : {l : app.mklang}}).then(() => {app.mk.play()})
},
selectPodcast(podcast) {
this.podcastSelected = podcast

View file

@ -4,8 +4,8 @@
</div>
</script>
<script>
Vue.component('apple-account-settings', {
template: '#apple-account-settings',
Vue.component('remote-pair', {
template: '#remote-pair',
async mounted() {
ipcRenderer.send('get-remote-pair-url')
ipcRenderer.on('send-remote-pair-url', (event, url) => {

View file

@ -1,13 +1,10 @@
<script type="text/x-template" id="cider-search">
<div class="content-inner">
<div v-if="search != null && search != [] && search.term != ''">
<h3>{{app.getLz('term.topResult')}}</h3>
<mediaitem-scroller-horizontal
:items="search.results[search.results.meta.results.order[0]]['data']"></mediaitem-scroller-horizontal>
<div class="row">
<div class="col-sm" style="width: auto;" v-if="getTopResult()">
<template>
<h3>{{app.getLz('term.topResult')}}</h3>
<mediaitem-square :item="getTopResult()"></mediaitem-square>
</template>
</div>
<div v-else style="text-align: center">
<h3>{{app.getLz('error.noResults')}}</h3>
<p>{{app.getLz('error.noResults.description')}}</p>
@ -24,10 +21,8 @@
</div>
</div>
<div class="mediaitem-list-item__grid">
<div class="grid-body">
<mediaitem-list-item :item="item" :index="index"
v-for="(item, index) in search.results.song.data.limit(12)"></mediaitem-list-item>
</div>
<listitem-horizontal :items="search.results.song.data.limit(12)">
</listitem-horizontal>
</div>
</div>
</div>
@ -121,7 +116,7 @@
},
async getCategories() {
if (this.categoriesView != [] && this.categoriesView.length > 0) { this.categoriesReady = true; return await true; } else {
let response = await this.app.mk.api.v3.music(`/v1/recommendations/${this.app.mk.storefrontId}?timezone=${encodeURIComponent(this.app.formatTimezoneOffset())}&name=search-landing&platform=web&extend=editorialArtwork&art%5Burl%5D=f%2Cc&types=editorial-items%2Capple-curators%2Cactivities`);
let response = await this.app.mk.api.v3.music(`/v1/recommendations/${this.app.mk.storefrontId}?timezone=${encodeURIComponent(this.app.formatTimezoneOffset())}&name=search-landing&platform=web&extend=editorialArtwork&art%5Burl%5D=f%2Cc&types=editorial-items%2Capple-curators%2Cactivities&l=${this.$root.mklang}`);
this.categoriesView = response.data.data;
console.log(this.categoriesView)
this.categoriesReady = true;