Merge branch 'develop' into update-owo

This commit is contained in:
GamingLiamStudios 2022-03-08 01:33:12 +11:00
commit 0fa505e60b
No known key found for this signature in database
GPG key ID: 3650DE4EAFF62ADD
71 changed files with 14964 additions and 10541 deletions

View file

@ -4,8 +4,9 @@
<img src="https://img.shields.io/github/forks/ciderapp/Cider?label=Forks" alt="GitHub Forks"/> <img src="https://img.shields.io/github/forks/ciderapp/Cider?label=Forks" alt="GitHub Forks"/>
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/cider-music"><img src="https://badges.crowdin.net/cider-music/localized.svg"></a> <a title="Crowdin" target="_blank" href="https://crowdin.com/project/cider-music"><img src="https://badges.crowdin.net/cider-music/localized.svg"></a>
<br> <br>
<a target="_blank" href="https://ko-fi.com/cryptofyre"><img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-donate-B48C69" alt="Buy Me A Coffee"/></a> <a target="_blank" href="https://ko-fi.com/cryptofyre"><img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-donate-B48C69?logo=Ko-fi&logoColor=FFFFFF" alt="Buy Me A Coffee"/></a>
<a target="_blank" href="https://opencollective.com/ciderapp"><img src="https://img.shields.io/opencollective/all/ciderapp?color=%237FADF2&label=Backers%20and%20Sponsors&logo=opencollective" alt="Open Collective"/></a> <a target="_blank" href="https://opencollective.com/ciderapp"><img src="https://img.shields.io/opencollective/all/ciderapp?color=%237FADF2&label=Backers%20and%20Sponsors&logo=opencollective" alt="Open Collective"/></a>
<a target="_blank" href="https://github.com/sponsors/ciderapp"><img src="https://img.shields.io/github/sponsors/ciderapp?color=C96198&label=GitHub%20Sponsors&logo=GitHub" alt="GitHub Sponsor"/></a>
<br> <br>
<a target="_blank" href="https://discord.gg/applemusic"><img src="https://img.shields.io/discord/843954443845238864?label=Discord&color=5865F2&logo=discord&logoColor=white&style=flat" alt="Discord"/></a> <a target="_blank" href="https://discord.gg/applemusic"><img src="https://img.shields.io/discord/843954443845238864?label=Discord&color=5865F2&logo=discord&logoColor=white&style=flat" alt="Discord"/></a>
<a target="_blank" href="https://twitter.com/UseCider"><img src="https://img.shields.io/twitter/follow/UseCider?label=Twitter&color=%231DA1F2&logo=twitter&style=flat" alt="Twitter"/></a> <a target="_blank" href="https://twitter.com/UseCider"><img src="https://img.shields.io/twitter/follow/UseCider?label=Twitter&color=%231DA1F2&logo=twitter&style=flat" alt="Twitter"/></a>

View file

@ -2,7 +2,7 @@
"name": "cider", "name": "cider",
"applicationId": "Cider", "applicationId": "Cider",
"productName": "Cider", "productName": "Cider",
"version": "1.2.1", "version": "1.3.0",
"description": "A new look into listening and enjoying music in style and performance.", "description": "A new look into listening and enjoying music in style and performance.",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "./build/index.js", "main": "./build/index.js",
@ -48,6 +48,7 @@
"electron-notarize": "^1.1.1", "electron-notarize": "^1.1.1",
"electron-store": "^8.0.1", "electron-store": "^8.0.1",
"electron-updater": "^4.6.5", "electron-updater": "^4.6.5",
"electron-vibrancy-updated": "git+https://github.com/ciderapp/electron-vibrancy-updated",
"electron-window-state": "^5.0.3", "electron-window-state": "^5.0.3",
"express": "^4.17.3", "express": "^4.17.3",
"get-port": "^5.1.1", "get-port": "^5.1.1",
@ -75,7 +76,7 @@
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/qrcode-terminal": "^0.12.0", "@types/qrcode-terminal": "^0.12.0",
"@types/ws": "^8.5.1", "@types/ws": "^8.5.1",
"electron": "git+https://github.com/castlabs/electron-releases.git", "electron": "git+https://github.com/castlabs/electron-releases.git#16-x-y",
"electron-builder": "^22.14.13", "electron-builder": "^22.14.13",
"electron-builder-notarize-pkg": "^1.2.0", "electron-builder-notarize-pkg": "^1.2.0",
"electron-webpack": "^2.8.2", "electron-webpack": "^2.8.2",

View file

@ -164,8 +164,8 @@
"action.addToLibrary": "obtain piss", "action.addToLibrary": "obtain piss",
"action.addToLibrary.success": "piss obtained", "action.addToLibrary.success": "piss obtained",
"action.addToLibrary.error": "error obtaining piss", "action.addToLibrary.error": "error obtaining piss",
"action.removeFromLibrary": "dump piss", "action.removeFromLibrary": "unobtain piss",
"action.removeFromLibrary.success": "piss dumped", "action.removeFromLibrary.success": "piss unobtained",
"action.addToQueue": "add to toilet", "action.addToQueue": "add to toilet",
"action.addToQueue.success": "added to toilet", "action.addToQueue.success": "added to toilet",
"action.addToQueue.error": "error adding to toilet", "action.addToQueue.error": "error adding to toilet",

View file

@ -19,11 +19,10 @@
"term.learnMore": "|:ᒷᖋ∷リ ᒲᒍ∷ᒷ", "term.learnMore": "|:ᒷᖋ∷リ ᒲᒍ∷ᒷ",
"term.accountSettings": "ᖋᔮᔮᒍ⚍リᒣ ϟᒷᒣᒣ╎リ┤ϟ", "term.accountSettings": "ᖋᔮᔮᒍ⚍リᒣ ϟᒷᒣᒣ╎リ┤ϟ",
"term.logout": "|:ᒍ┤ᒍ⚍ᒣ", "term.logout": "|:ᒍ┤ᒍ⚍ᒣ",
"term.login": "|:ᒍ┤ ╎リ", "term.login": "|:ᒍ┤╎リ",
"term.about": "ᖋᕊᒍ⚍ᒣ", "term.about": "ᖋᕊᒍ⚍ᒣ",
"term.privateSession": "I!∷╎⍊ᖋᒣᒷ ϟᒷϟϟ╎ᒍリ", "term.privateSession": "I!∷╎⍊ᖋᒣᒷ ϟᒷϟϟ╎ᒍリ",
"term.queue": "ᑑ⚍ᒷ⚍ᒷ", "term.queue": "ᑑ⚍ᒷ⚍ᒷ",
"term.history": "⍑╎ϟᒣᒍ∷॥",
"term.search": "ϟᒷᖋ∷ᔮ⍑", "term.search": "ϟᒷᖋ∷ᔮ⍑",
"term.library": "|:╎ᕊ∷ᖋ∷॥", "term.library": "|:╎ᕊ∷ᖋ∷॥",
"term.listenNow": "|:╎ϟᒣᒷリ", "term.listenNow": "|:╎ϟᒣᒷリ",
@ -36,11 +35,6 @@
"term.podcasts": "I!ᒍ↸ᔮᖋϟᒣϟ", "term.podcasts": "I!ᒍ↸ᔮᖋϟᒣϟ",
"term.playlists": "i!|:ᖋ॥|:╎ϟᒣϟ", "term.playlists": "i!|:ᖋ॥|:╎ϟᒣϟ",
"term.playlist": "i!|:ᖋ॥|:╎ϟᒣ", "term.playlist": "i!|:ᖋ॥|:╎ϟᒣ",
"term.newPlaylist": "リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ",
"term.newPlaylistFolder": "リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ ⎓ᒍ|:↸ᒷ∷",
"term.createNewPlaylist": "ᔮ∷ᒷᖋᒣᒷ リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ",
"term.createNewPlaylistFolder": "ᔮ∷ᒷᖋᒣᒷ リᒷ∴ i!|:ᖋ॥|:╎ϟᒣ ⎓ᒍ|:↸ᒷ∷",
"term.deletePlaylist": "ᖋ∷ᒷ ॥ᒍ⚍ ϟ⚍∷ᒷ ॥ᒍ⚍ ∴ᖋリᒣ ᒣᒍ ↸ᒷ|:ᒷᒣᒷ ᒣ⍑╎ϟ i!|:ᖋ॥|:╎ϟᒣ?",
"term.play": "i!|:ᖋ॥", "term.play": "i!|:ᖋ॥",
"term.pause": "I!ᖋ⚍ϟᒷ", "term.pause": "I!ᖋ⚍ϟᒷ",
"term.previous": "I!∷ᒷ⍊╎ᒍ⚍ϟ", "term.previous": "I!∷ᒷ⍊╎ᒍ⚍ϟ",
@ -51,7 +45,6 @@
"term.mute": "ᒲ⚍ᒣᒷ", "term.mute": "ᒲ⚍ᒣᒷ",
"term.unmute": "⚍リᒲ⚍ᒣᒷ", "term.unmute": "⚍リᒲ⚍ᒣᒷ",
"term.share": "ϟ⍑ᖋ∷ᒷ", "term.share": "ϟ⍑ᖋ∷ᒷ",
"term.share.success": "ᔮi!╎ᒷ↸ ᒣᒍ ᔮ|:╎i!ᕊᒍᖋ∷↸",
"term.settings": "ϟᒷᒣᒣ╎リ┤ϟ", "term.settings": "ϟᒷᒣᒣ╎リ┤ϟ",
"term.seeAll": "ϟᒷᒷ ᖋ|:|:", "term.seeAll": "ϟᒷᒷ ᖋ|:|:",
"term.sortBy": "ϟᒍ∷ᒣ ᕊ॥", "term.sortBy": "ϟᒍ∷ᒣ ᕊ॥",

View file

@ -2,7 +2,7 @@
"i18n.languageName": "English (US)", "i18n.languageName": "English (US)",
"i18n.languageNameEnglish": "English (US)", "i18n.languageNameEnglish": "English (US)",
"i18n.category": "main", "i18n.category": "main",
"i18n.authors": "@maikirakiwi @kyw504100 nosh118", "i18n.authors": "@maikirakiwi @kyw504100 @nosh118",
"app.name": "Cider", "app.name": "Cider",
"date.format": "${m} ${d}, ${y}", "date.format": "${m} ${d}, ${y}",
"dialog.cancel": "Cancel", "dialog.cancel": "Cancel",
@ -148,6 +148,7 @@
"term.noVideos": "No videos found.", "term.noVideos": "No videos found.",
"term.plugin": "Plug-in", "term.plugin": "Plug-in",
"term.pluginMenu": "Plug-in Menu", "term.pluginMenu": "Plug-in Menu",
"term.pluginMenu.none": "No interactive plugins",
"term.replay": "Replay", "term.replay": "Replay",
"term.uniqueAlbums": "Unique Albums", "term.uniqueAlbums": "Unique Albums",
"term.uniqueArtists": "Unique Artists", "term.uniqueArtists": "Unique Artists",
@ -200,11 +201,13 @@
"action.unfollow": "Unfollow", "action.unfollow": "Unfollow",
"action.unfollow.success": "Unfollowed", "action.unfollow.success": "Unfollowed",
"action.unfollow.error": "Error Unfollowing", "action.unfollow.error": "Error Unfollowing",
"action.relaunch.confirm": "Do you want to relaunch Cider?",
"action.playNext": "Play Next", "action.playNext": "Play Next",
"action.playLater": "Play Later", "action.playLater": "Play Later",
"action.startRadio": "Start Radio", "action.startRadio": "Start Radio",
"action.goToArtist": "Go to Artist", "action.goToArtist": "Go to Artist",
"action.goToAlbum": "Go to Album", "action.goToAlbum": "Go to Album",
"action.showInPlaylist": "Show in Playlist",
"action.moveToTop": "Move out of Folder", "action.moveToTop": "Move out of Folder",
"action.share": "Share", "action.share": "Share",
"action.rename": "Rename", "action.rename": "Rename",
@ -313,6 +316,8 @@
"settings.option.visual.hardwareAcceleration.description": "Requires relaunch", "settings.option.visual.hardwareAcceleration.description": "Requires relaunch",
"settings.header.visual.hardwareAcceleration.default": "Default", "settings.header.visual.hardwareAcceleration.default": "Default",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.option.visual.transparent": "Transparent frame",
"settings.option.visual.transparent.description": "Transparent frame (needs Theme Support , requires relaunch)",
"settings.header.visual.theme": "Theme", "settings.header.visual.theme": "Theme",
"settings.option.visual.theme.github.download": "Install from GitHub URL", "settings.option.visual.theme.github.download": "Install from GitHub URL",
"settings.option.visual.theme.github.explore": "Explore GitHub Themes", "settings.option.visual.theme.github.explore": "Explore GitHub Themes",
@ -353,7 +358,7 @@
"settings.option.experimental.close_button_hide": "Close Button Should Hide the Application", "settings.option.experimental.close_button_hide": "Close Button Should Hide the Application",
"settings.option.experimental.inline_playlists": "Inline Playlists and Albums", "settings.option.experimental.inline_playlists": "Inline Playlists and Albums",
"settings.option.advanced.playlistTrackMapping": "Playlist Track Mapping", "settings.option.advanced.playlistTrackMapping": "Playlist Track Mapping",
"settings.option.advanced.playlistTrackMapping.description": "Enables deep scanning of playlists to determine which tracks are in which playlists.", "settings.option.advanced.playlistTrackMapping.description": "Enables deep scanning of playlists to determine which tracks are in which playlists. Playlist cache build times can increase significantly.",
"spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.", "spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.",
"spatial.spatialProperties": "Spatial Properties", "spatial.spatialProperties": "Spatial Properties",
"spatial.width": "Width", "spatial.width": "Width",

View file

@ -365,4 +365,4 @@
"remote.web.title": "Cider 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.", "remote.web.description": "Olvasd be ezt a QR-kódot a telefonoddal, hogy tudd vezérelni a lejátszót.",
"about.thanks": "Köszönet a Cider Collective csapatának és minden hozzájárulónak." "about.thanks": "Köszönet a Cider Collective csapatának és minden hozzájárulónak."
} }

View file

@ -23,9 +23,8 @@
"term.about": "정보", "term.about": "정보",
"term.privateSession": "개인 세션", "term.privateSession": "개인 세션",
"term.queue": "대기열", "term.queue": "대기열",
"term.history": "청취 기록",
"term.search": "검색", "term.search": "검색",
"term.library": "보관함", "term.library": "라이브러리",
"term.listenNow": "지금 듣기", "term.listenNow": "지금 듣기",
"term.browse": "둘러보기", "term.browse": "둘러보기",
"term.radio": "라디오", "term.radio": "라디오",
@ -34,77 +33,76 @@
"term.albums": "앨범", "term.albums": "앨범",
"term.artists": "아티스트", "term.artists": "아티스트",
"term.podcasts": "팟캐스트", "term.podcasts": "팟캐스트",
"term.playlists": "재생 목록", "term.playlists": "플레이리스트",
"term.playlist": "재생 목록", "term.playlist": "플레이리스트",
"term.newPlaylist": "새 재생 목록", "term.newPlaylist": "새 플레이리스트",
"term.newPlaylistFolder": "새 재생 목록 폴더", "term.newPlaylistFolder": "새 플레이리스트 폴더",
"term.createNewPlaylist": "새 재생 목록 만들기", "term.createNewPlaylist": "새 플레이리스트 만들기",
"term.createNewPlaylistFolder": "새 재생 목록 폴더 만들기", "term.createNewPlaylistFolder": "새 플레이리스트 폴더 만들기",
"term.deletePlaylist": "정말로 이 재생 목록을 삭제하시겠습니까?", "term.deletePlaylist": "정말 플레이리스트를 삭제하시겠습니까?",
"term.play": "재생", "term.play": "재생",
"term.pause": "일시 정지", "term.pause": "정지",
"term.previous": "이전", "term.previous": "이전",
"term.next": "다음", "term.next": "다음",
"term.shuffle": "셔플", "term.shuffle": "셔플",
"term.repeat": "반복", "term.repeat": "반복재생",
"term.volume": "볼륨", "term.volume": "볼륨",
"term.mute": "음소거", "term.mute": "음소거",
"term.unmute": "음소거 해제", "term.unmute": "음소거 해제",
"term.share": "공유", "term.share": "공유",
"term.share.success": "클립보드에 복사됨",
"term.settings": "설정", "term.settings": "설정",
"term.seeAll": "모두 보기", "term.seeAll": "모두 보기",
"term.sortBy": "정렬", "term.sortBy": "정렬방식",
"term.sortBy.album": "앨범", "term.sortBy.album": "앨범",
"term.sortBy.artist": "아티스트 이름", "term.sortBy.artist": "아티스트",
"term.sortBy.name": "제목", "term.sortBy.name": "이름",
"term.sortBy.genre": "장르", "term.sortBy.genre": "장르",
"term.sortBy.releaseDate": "발매일", "term.sortBy.releaseDate": "출시일",
"term.sortBy.duration": "길이", "term.sortBy.duration": "재생시간",
"term.sortOrder": "A-Z", "term.sortOrder": "ㄱ-ㅎ",
"term.sortOrder.ascending": "오름차순", "term.sortOrder.ascending": "오름차순",
"term.sortOrder.descending": "내림차순", "term.sortOrder.descending": "내림차순",
"term.viewAs": "표시", "term.viewAs": "표시방식",
"term.viewAs.coverArt": "커버 아트", "term.viewAs.coverArt": "커버아트",
"term.viewAs.list": "리스트", "term.viewAs.list": "리스트",
"term.size": "크기", "term.size": "크기",
"term.size.normal": "표준", "term.size.normal": "일반",
"term.size.compact": "컴팩트", "term.size.compact": "컴팩트",
"term.enable": "켜기", "term.enable": "활성화",
"term.disable": "끄기", "term.disable": "비활성화",
"term.enabled": "켜짐", "term.enabled": "활성화",
"term.disabled": "꺼짐", "term.disabled": "비활성화",
"term.connect": "연결", "term.connect": "연결",
"term.connecting": "연결 중", "term.connecting": "연결 중",
"term.disconnect": "연결 해제", "term.disconnect": "연결 끊김",
"term.authed": "인증됨", "term.authed": "인증됨",
"term.confirm": "진행하시겠습니까?", "term.confirm": "확인하시겠습니까 ?",
"term.more": "추가", "term.more": "",
"term.less": "줄이기", "term.less": "적게",
"term.showMore": "더 보기", "term.showMore": "더 보기",
"term.showLess": " 보기", "term.showLess": "적게 보기",
"term.topSongs": "많이 듣는 노래", "term.topSongs" : "인기곡",
"term.latestReleases": "최근 발매된 노래", "term.latestReleases": "최신곡",
"term.time.added": "추가", "term.time.added": "추가",
"term.time.released": "발매됨", "term.time.released": "발매일",
"term.time.updated": "업데이트", "term.time.updated": "업데이트",
"term.time.hours": "시간", "term.time.hours": "시간",
"term.time.hour": "시간", "term.time.hour": "시간",
"term.time.minutes": "분", "term.time.minutes": "분",
"term.time.minute": "분", "term.time.minute": "분",
"term.time.seconds": "초", "term.time.seconds": "초",
"term.time.second": "초", "term.time.second": "초",
"term.fullscreenView": "전체 화면 보기", "term.fullscreenView": "전체화면",
"term.defaultView": "윈도우 보기", "term.defaultView": "본화면",
"term.audioSettings": "오디오 설정", "term.audioSettings": "오디오 설정",
"term.clearAll": "모두 지우기", "term.clearAll": "우기",
"term.recentStations": "최근 스테이션", "term.recentStations": "최근 스테이션",
"term.language": "언어", "term.language": "언어",
"term.funLanguages": "재미를 위한 언어", "term.funLanguages": "재미있는",
"term.noLyrics": "로딩 중... / 가사를 찾지 못했습니다. / Instrumental 곡일 수 있습니다.", "term.noLyrics": "불러오는 중... / 가사를 찾을 수 없습니다/ 연주곡",
"term.copyright": "저작권", "term.copyright": "Copyright",
"term.rightsReserved": "All Rights Reserved.", "term.rightsReserved": "All Rights Reserved.",
"term.sponsor": "이 프로젝트를 후원하", "term.sponsor": "이 프로젝트를 후원하세요",
"term.ciderTeam": "Cider 팀", "term.ciderTeam": "Cider 팀",
"term.developer": "개발자", "term.developer": "개발자",
"term.socialTeam": "소셜 팀", "term.socialTeam": "소셜 팀",
@ -133,12 +131,12 @@
"term.videoExtras": "추가 비디오", "term.videoExtras": "추가 비디오",
"term.top": "Top", "term.top": "Top",
"home.title": "홈", "home.title": "홈",
"home.recentlyPlayed": "최근 재생 항목", "home.recentlyPlayed": "최근 재생 항목",
"home.recentlyAdded": "최근 추가된 항목", "home.recentlyAdded": "최근 추가된 항목",
"home.artistsFeed": "아티스트 피드", "home.artistsFeed": "아티스트 피드",
"home.artistsFeed.noArtist": "좋아하는 아티스트를 팔로우해보세요.", "home.artistsFeed.noArtist": "아티스트를 팔로우하면 최근 발매곡이 표시됩니다",
"home.madeForYou": "나만을 위한 추천", "home.madeForYou": "나만을 위한 추천",
"home.friendsListeningTo": "친구가 듣는 음악", "home.friendsListeningTo": "친구들이 듣는",
"home.followedArtists": "팔로우한 아티스트", "home.followedArtists": "팔로우한 아티스트",
"error.appleMusicSubRequired": "Apple Music은 구독을 필요로 합니다.", "error.appleMusicSubRequired": "Apple Music은 구독을 필요로 합니다.",
"error.connectionError": "Apple Music에 연결하지 못했습니다.", "error.connectionError": "Apple Music에 연결하지 못했습니다.",
@ -154,21 +152,21 @@
"podcast.website": "팟캐스트 사이트", "podcast.website": "팟캐스트 사이트",
"action.addToLibrary": "보관함에 추가", "action.addToLibrary": "보관함에 추가",
"action.addToLibrary.success": "보관함에 추가됨", "action.addToLibrary.success": "보관함에 추가됨",
"action.addToLibrary.error": "보관함에 추가하는데 실패", "action.addToLibrary.error": "보관함에 추가 실패",
"action.removeFromLibrary": "보관함에서 삭제", "action.removeFromLibrary": "보관함에서 삭제",
"action.removeFromLibrary.success": "보관함에서 삭제됨", "action.removeFromLibrary.success": "보관함에서 삭제됨",
"action.addToQueue": "대기열에 추가", "action.addToQueue": "대기열에 추가",
"action.addToQueue.success": "대기열에 추가됨", "action.addToQueue.success": "대기열에 추가됨",
"action.addToQueue.error": "대기열에 추가하는데 실패", "action.addToQueue.error": "대기열에 추가 실패",
"action.removeFromQueue": "대기열에서 삭제", "action.removeFromQueue": "대기열에서 삭제",
"action.removeFromQueue.success": "대기열에서 삭제됨", "action.removeFromQueue.success": "대기열에서 삭제됨",
"action.removeFromQueue.error": "대기열에서 삭제하는데 실패", "action.removeFromQueue.error": "대기열에서 삭제 실패",
"action.createPlaylist": "새 재생 목록 만들기", "action.createPlaylist": "새 플레이리스트",
"action.addToPlaylist": "재생 목록에 추가", "action.addToPlaylist": "플레이리스트에 추가...",
"action.removeFromPlaylist": "재생 목록에서 삭제", "action.removeFromPlaylist": "플레이리스트에서 삭제",
"action.addToFavorites": "즐겨찾기에 추가", "action.addToFavorites": "선호항목에 추가",
"action.follow": "팔로우", "action.follow": "팔로우",
"action.follow.success": "팔로우", "action.follow.success": "팔로우",
"action.follow.error": "팔로우 실패", "action.follow.error": "팔로우 실패",
"action.unfollow": "언팔로우", "action.unfollow": "언팔로우",
"action.unfollow.success": "언팔로우됨", "action.unfollow.success": "언팔로우됨",
@ -178,23 +176,23 @@
"action.startRadio": "스테이션 생성", "action.startRadio": "스테이션 생성",
"action.goToArtist": "아티스트 보기", "action.goToArtist": "아티스트 보기",
"action.goToAlbum": "앨범 보기", "action.goToAlbum": "앨범 보기",
"action.moveToTop": "위로 가기", "action.moveToTop": "맨 위로 이동",
"action.share": "공유", "action.share": "공유하기",
"action.rename": "편집", "action.rename": "이름 편집하기",
"action.love": "좋아요", "action.love": "좋아요",
"action.unlove": "좋아요 취소", "action.unlove": "좋아요 취소",
"action.dislike": "싫어요", "action.dislike": "비슷한 항목의 제안 줄이기",
"action.undoDislike": "싫어요 취소", "action.undoDislike": "비슷한 항목의 제안 줄이기 실행 취소",
"action.showWebRemoteQR": "웹 리모트", "action.showWebRemoteQR": "웹 리모트",
"action.playTracksNext": "다음 ${app.selectedMediaItems.length}곡 재생", "action.playTracksNext": "${app.selectedMediaItems.length} 바로 다음에 재생",
"action.playTracksLater": "나중에 ${app.selectedMediaItems.length}곡 재생", "action.playTracksLater": "${app.selectedMediaItems.length} 맨 나중에 재생",
"action.removeTracks": "${self.selectedItems.length}곡을 대기열에서 삭제", "action.removeTracks": "${self.selectedItems.length} 대기열에서 삭제",
"action.import": "불러오기", "action.import": "가져오기",
"action.export": "내보내기", "action.export": "내보내기",
"action.showAlbum": "전체 앨범 보기", "action.showAlbum": "전체 앨범 보기",
"action.tray.minimize": "트레이 최소화", "action.tray.minimize": "트레이 최소화",
"action.tray.quit": "종료", "action.tray.quit": "종료",
"action.tray.show": "보기", "action.tray.show": "",
"action.update": "업데이트", "action.update": "업데이트",
"action.copy": "복사", "action.copy": "복사",
"action.newpreset": "새 프리셋", "action.newpreset": "새 프리셋",
@ -223,7 +221,7 @@
"settings.header.visual.description": "Cider의 시각 기능을 설정합니다.", "settings.header.visual.description": "Cider의 시각 기능을 설정합니다.",
"settings.option.visual.windowBackgroundStyle": "윈도우 배경 스타일", "settings.option.visual.windowBackgroundStyle": "윈도우 배경 스타일",
"settings.header.visual.windowBackgroundStyle.none": "없음", "settings.header.visual.windowBackgroundStyle.none": "없음",
"settings.header.visual.windowBackgroundStyle.artwork": "앨범 아트", "settings.header.visual.windowBackgroundStyle.artwork": "아트워크",
"settings.header.visual.windowBackgroundStyle.image": "이미지", "settings.header.visual.windowBackgroundStyle.image": "이미지",
"settings.option.visual.animatedArtwork": "애니메이션 앨범 표지", "settings.option.visual.animatedArtwork": "애니메이션 앨범 표지",
"settings.header.visual.animatedArtwork.always": "항상 활성화", "settings.header.visual.animatedArtwork.always": "항상 활성화",
@ -273,7 +271,7 @@
"spatial.width": "길이", "spatial.width": "길이",
"spatial.height": "높이", "spatial.height": "높이",
"spatial.depth": "깊이", "spatial.depth": "깊이",
"spatial.gain": "출력", "spatial.gain": "게인",
"spatial.roomMaterials": "방 재질", "spatial.roomMaterials": "방 재질",
"spatial.roomDimensions": "방 차원", "spatial.roomDimensions": "방 차원",
"spatial.roomPositions": "방 위치", "spatial.roomPositions": "방 위치",
@ -281,8 +279,8 @@
"spatial.setPositions": "위치 설정", "spatial.setPositions": "위치 설정",
"spatial.up": "위", "spatial.up": "위",
"spatial.front": "앞", "spatial.front": "앞",
"spatial.left": "", "spatial.left": "왼쪽",
"spatial.right": "", "spatial.right": "오른쪽",
"spatial.back": "뒤", "spatial.back": "뒤",
"spatial.down": "아래", "spatial.down": "아래",
"spatial.listener": "사용자", "spatial.listener": "사용자",
@ -291,4 +289,4 @@
"remote.web.title": "Cider 리모트", "remote.web.title": "Cider 리모트",
"remote.web.description": "QR 코드를 스캔해서 Cider와 스마트폰을 연결하기", "remote.web.description": "QR 코드를 스캔해서 Cider와 스마트폰을 연결하기",
"about.thanks": "Cider Collective Team과 모든 기여자들에게 감사합니다." "about.thanks": "Cider Collective Team과 모든 기여자들에게 감사합니다."
} }

View file

@ -1,14 +1,270 @@
{ {
"i18n.languageName": "Română", "i18n.languageName": "Română",
"i18n.languageNameEnglish": "Romanian", "i18n.languageNameEnglish": "Romanian",
"i18n.category": "main", "i18n.category": "main",
"i18n.authors": "georgechrc, ", "i18n.authors": "@SubZeroNexii georgechrc",
"app.name": "Cider",
"date.format": "${d} ${m}, ${y}", "date.format": "${d} ${m}, ${y}",
"dialog.cancel": "Anulare",
"dialog.ok": "OK",
"notification.updatingLibrarySongs": "Actualizare bibliotecă muzică...",
"notification.updatingLibraryAlbums": "Actualizare bibliotecă albume...",
"notification.updatingLibraryArtists": "Actualizare bibliotecă artiști...",
"term.appleInc": "Apple Inc.",
"term.appleMusic": "Apple Music",
"term.applePodcasts": "Apple Podcasts",
"term.itunes": "iTunes",
"term.github": "GitHub",
"term.discord": "Discord",
"term.learnMore": "Află mai multe",
"term.accountSettings": "Setări cont",
"term.logout": "Deconectare",
"term.login": "Autentificare",
"term.about": "Despre",
"term.privateSession": "Sesiune Privată",
"term.queue": "în Coadă",
"term.search": "Căutare",
"term.library": "Bibliotecă",
"term.listenNow": "Ascultă acum",
"term.browse": "Navigați",
"term.radio": "Radio",
"term.recentlyAdded": "Recent Adăugate",
"term.songs": "Muzică",
"term.albums": "Albume",
"term.artists": "Artiști",
"term.podcasts": "Podcast-uri",
"term.playlists": "Playlist-uri",
"term.playlist": "Playlist",
"term.newPlaylist": "Playlist Nou",
"term.newPlaylistFolder": "Dosar Playlist Nou",
"term.createNewPlaylist": "Creează un Playlist Nou",
"term.createNewPlaylistFolder": "Creează un Dosar Playlist Nou",
"term.deletePlaylist": "Sunteți siguri că vreți să ștergeți acest Playlist?",
"term.play": "Redă",
"term.pause": "Pauză",
"term.previous": "Înapoi",
"term.next": "Înainte",
"term.shuffle": "Aleator",
"term.repeat": "Repetă",
"term.volume": "Volum",
"term.mute": "Fară sunet",
"term.unmute": "Activare sunet",
"term.share": "Partajează",
"term.settings": "Setări",
"term.seeAll": "Vedeți tot",
"term.sortBy": "Sortare după",
"term.sortBy.album": "Album",
"term.sortBy.artist": "Artist",
"term.sortBy.name": "Nume",
"term.sortBy.genre": "Gen",
"term.sortBy.releaseDate": "Data Lansării",
"term.sortBy.duration": "Durată",
"term.sortOrder": "A-Z",
"term.sortOrder.ascending": "Ascendent",
"term.sortOrder.descending": "Descendent",
"term.viewAs": "Vizualizare ca",
"term.viewAs.coverArt": "Artă Copertă",
"term.viewAs.list": "Listă",
"term.size": "Mărime",
"term.size.normal": "Normal",
"term.size.compact": "Compact",
"term.enable": "Activare",
"term.disable": "Dezactivare",
"term.enabled": "Activat",
"term.disabled": "Dezactivat",
"term.connect": "Conectare",
"term.connecting": "Se conectează",
"term.disconnect": "Deconectare",
"term.authed": "Autentificat",
"term.confirm": "Confirmați ?",
"term.more": "Mai mult",
"term.less": "Mai puțin",
"term.showMore": "Arată mai mult",
"term.showLess": "Arată mai puțin",
"term.topSongs" : "Top Muzică",
"term.latestReleases": "Ultimele Lansări",
"term.time.added": "Adăugate",
"term.time.released": "Lansate",
"term.time.updated": "Actualizate",
"term.time.hours": "ore",
"term.time.hour": "oră",
"term.time.minutes": "minute",
"term.time.minute": "minut",
"term.time.seconds": "secunde",
"term.time.second": "secundă",
"term.fullscreenView": "Vizualizare Ecran Complet",
"term.defaultView": "Vizualizare Standard",
"term.audioSettings": "Setări Audio",
"term.clearAll": "Ștergere toate",
"term.recentStations": "Stații Recente",
"term.language": "Limbă",
"term.funLanguages": "Amuzament",
"term.noLyrics": "Incărcare... / Versurile nu au fost găsite./ Instrumental.",
"term.copyright": "Copyright",
"term.rightsReserved": "Toate drepturile rezervate.",
"term.sponsor": "Sponsorizați acest proiect",
"term.ciderTeam": "Echipa Cider",
"term.developer": "Dezvoltatori",
"term.socialTeam": "Echipa de relații publice",
"term.socials": "Rețele Sociale",
"term.contributors": "Contribuitori",
"term.equalizer": "Egalizator", "term.equalizer": "Egalizator",
"settings.option.audio.enableAdvancedFunctionality.description": "Pornirea funcționalităților AudioContext va permite folosirea funcțiilor audio avansate precum Normalizare Volum , Egalizator și Vizualizator, pe unele sisteme mai slabe poate cauza probleme precum întreruperi în redare.", "term.reset": "Reset",
"term.tracks": "melodii",
"term.videos": "Videoclipuri",
"term.menu": "Meniu",
"term.check": "Verificare",
"term.aboutArtist": "Despre {{artistName}}",
"term.updateCider": "Actualizare Cider",
"home.title": "Acasă",
"home.recentlyPlayed": "Asculate Recent",
"home.recentlyAdded": "Adăugate Recent",
"home.artistsFeed": "Fluxul Artiștilor tăi",
"home.artistsFeed.noArtist": "Urmărește prima oară cațiva artiști și ultimele lor lansări vor apărea aici",
"home.madeForYou": "Pentru tine",
"home.friendsListeningTo": "Prietenii tăi ascultă",
"home.followedArtists": "Artiști Urmăriți",
"error.appleMusicSubRequired": "Apple Music necesită un abonament.",
"error.connectionError": "A apărut o problemă în conectarea la Apple Music.",
"error.noResults": "Nici un rezultat.",
"error.noResults.description": "încearcă o nouă căutare.",
"podcast.followOnCider": "Urmărește pe Cider",
"podcast.followedOnCider": "Urmărit pe Cider",
"podcast.subscribeOnItunes": "Abonează-te pe iTunes",
"podcast.subscribedOnItunes": "Abonat pe iTunes",
"podcast.itunesStore": "Magazin iTunes",
"podcast.episodes": "Episoade",
"podcast.playEpisode": "Începe Episodul",
"podcast.website": "Pagină Podcast",
"action.addToLibrary": "Adaugă în Librărie",
"action.addToLibrary.success": "Adăugat în Librărie",
"action.addToLibrary.error": "Eroare la adăugarea în Librărie",
"action.removeFromLibrary": "Ștergere din Librărie",
"action.removeFromLibrary.success": "Șters din Librărie",
"action.addToQueue": "Adăugare la Coadă",
"action.addToQueue.success": "Adăugat la Coadă",
"action.addToQueue.error": "Eroare adăugare la Coadă",
"action.removeFromQueue": "Ștergere din Coadă",
"action.removeFromQueue.success": "Șters din Coadă",
"action.removeFromQueue.error": "Eroare Ștergere din Coadă",
"action.createPlaylist": "Creează un nou Playlist",
"action.addToPlaylist": "Adaugă la Playlist",
"action.removeFromPlaylist": "Ștergere din Playlist",
"action.addToFavorites": "Adaugă la Favorite",
"action.follow": "Urmărește",
"action.follow.success": "Urmărit",
"action.follow.error": "Eroare Urmărire",
"action.unfollow": "Nu mai urmăriți",
"action.unfollow.success": "Urmărire încetată",
"action.unfollow.error": "Eroare încetare Urmărire",
"action.playNext": "Ascultă în Continuare",
"action.playLater": "Ascultă Mai Târziu",
"action.startRadio": "Pornește Radio",
"action.goToArtist": "Du-te la Artist",
"action.goToAlbum": "Du-te la Album",
"action.moveToTop": "Mută în vârf",
"action.share": "Partajează",
"action.rename": "Redenumire",
"action.love": "Apreciază",
"action.unlove": "Elimină Apreciere",
"action.dislike": "Dislike",
"action.undoDislike": "Elimină dislike",
"action.showWebRemoteQR": "Telecomandă Web",
"action.playTracksNext": "Redă ${app.selectedMediaItems.length} de melodii în continuare",
"action.playTracksLater": "Redă ${app.selectedMediaItems.length} de melodii mai târziu",
"action.removeTracks": "Șterge ${self.selectedItems.length} de melodii din Coadă",
"action.import": "Import",
"action.export": "Export",
"action.showAlbum": "Arată Albumul Complet",
"action.tray.minimize": "Minimizează în Tray",
"action.tray.quit": "Ieșire",
"action.tray.show": "Arată",
"action.update": "Actualizează",
"settings.header.general": "General",
"settings.header.general.description": "Ajustează setările generale pentru Cider.",
"settings.option.general.language": "Limbă",
"settings.option.general.language.main": "Limbi",
"settings.option.general.language.fun": "Amuzant",
"settings.option.general.language.unsorted": "Nesortate",
"settings.header.audio": "Audio",
"settings.header.audio.description": "Ajustează setările audio pentru Cider.",
"settings.option.audio.quality": "Calitate Audio",
"settings.header.audio.quality.high": "Ridicată",
"settings.header.audio.quality.low": "Redusă",
"settings.header.audio.quality.auto": "Auto",
"settings.option.audio.seamlessTransition": "Tranziție Audio Neîntreruptă",
"settings.option.audio.enableAdvancedFunctionality": "Activează Funcționalitate Avansată",
"settings.option.audio.enableAdvancedFunctionality.description": "Pornirea funcționalității AudioContext va permite folosirea funcțiilor audio avansate precum Normalizare Volum , Egalizator și Vizualizator, dar pe unele sisteme poate cauza probleme precum întreruperi în redare.",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizare Volum", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalizare Volum",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizează volumul maxim al melodiilor pentru a genera o experiență audio optimă.", "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalizează volumul maxim al melodiilor pentru a genera o experiență audio optimă.",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spațializare Sunet", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "Spațializare Audio",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Efect de spațializare tri-dimensională a sunetului(Atenție, nu e Dolby Atmos!)", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "Spațializează sunetul și face sunetul 3-dimensional (notă: Nu este Dolby Atmos)",
"spatial.notTurnedOn": "Spațializarea Sunetului e dezactivată, pentru a o utiliza pornește-o." "settings.header.visual": "Vizual",
} "settings.header.visual.description": "Ajustează setările vizuale pentru Cider.",
"settings.option.visual.windowBackgroundStyle": "Stil Fundal Fereastră",
"settings.header.visual.windowBackgroundStyle.none": "Niciunul",
"settings.header.visual.windowBackgroundStyle.artwork": "Copertă Melodie",
"settings.header.visual.windowBackgroundStyle.image": "Imagine",
"settings.option.visual.animatedArtwork": "Copertă Animată",
"settings.header.visual.animatedArtwork.always": "Întotdeauna",
"settings.header.visual.animatedArtwork.limited": "Limitat la pagini și Albume speciale",
"settings.header.visual.animatedArtwork.disable": "Dezactivează peste tot",
"settings.option.visual.animatedArtworkQuality": "Calitate Copertă Animată",
"settings.header.visual.animatedArtworkQuality.low": "Redusă",
"settings.header.visual.animatedArtworkQuality.medium": "Medie",
"settings.header.visual.animatedArtworkQuality.high": "Ridicată",
"settings.header.visual.animatedArtworkQuality.veryHigh": "Foarte Ridicată",
"settings.header.visual.animatedArtworkQuality.extreme": "Extremă",
"settings.option.visual.animatedWindowBackground": "Fundal Fereastră Animat",
"settings.option.visual.hardwareAcceleration": "Accelerare Hardware",
"settings.option.visual.hardwareAcceleration.description": "Necesită Repornire",
"settings.header.visual.hardwareAcceleration.default": "Implitcit",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.option.visual.showPersonalInfo": "Arată informații personale",
"settings.header.lyrics": "Versuri",
"settings.header.lyrics.description": "Ajustează setările versurilor pentru Cider.",
"settings.option.lyrics.enableMusixmatch": "Activează Versuri Musixmatch",
"settings.option.lyrics.enableMusixmatchKaraoke": "Activează Mod Karaoke (numai Musixmatch)",
"settings.option.lyrics.musixmatchPreferredLanguage": "Limbă Preferată Traducere Musixmatch",
"settings.option.lyrics.enableYoutubeLyrics": "Activează Versuri Youtube pentru Videoclipuri Muzică",
"settings.header.connectivity": "Conectivitate",
"settings.header.connectivity.description": "Ajustează setările de conectivitate pentru Cider.",
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
"settings.option.connectivity.playbackNotifications": "Notificări Redare",
"settings.header.connectivity.discordRPC.cider": "Afișează ca 'Cider'",
"settings.header.connectivity.discordRPC.appleMusic": "Afișează ca 'Apple Music'",
"settings.option.connectivity.discordRPC.clearOnPause": "Curăță Discord Rich Presence la Pauză",
"settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling",
"settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble Delay (%)",
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Activează Last.fm Now Playing",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Ștergeți artiștii invitat din titlul melodiei (Last.fm)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrează melodii repetate (Last.fm)",
"settings.header.experimental": "Experimental",
"settings.header.experimental.description": "Ajustează setările experimentale pentru Cider.",
"settings.option.experimental.compactUI": "UI Compact",
"settings.option.experimental.close_button_hide": "Butonul de închidere ar trebui să ascundă aplicația",
"spatial.notTurnedOn": "Spațializarea Audio este dezactivată. Pentru a folosi opțiunea aceasta, activați-o mai întâi.",
"spatial.spatialProperties": "Proprietăți Spațiale",
"spatial.width": "Lățime",
"spatial.height": "Înălțime",
"spatial.depth": "Adâncime",
"spatial.gain": "Gain",
"spatial.roomMaterials": "Materiale Cameră",
"spatial.roomDimensions": "Dimensiuni Cameră",
"spatial.roomPositions": "Poziții Cameră",
"spatial.setDimensions": "Setează Dimensiunile",
"spatial.setPositions": "Setează Pozițiile",
"spatial.up": "Sus",
"spatial.front": "În Față",
"spatial.left": "Stânga",
"spatial.right": "Dreapta",
"spatial.back": "În Spate",
"spatial.down": "Jos",
"spatial.listener": "Ascultător",
"spatial.audioSource": "Sursă Audio",
"settings.header.unfinished": "Neterminat",
"remote.web.title": "Telecomandă Cider",
"remote.web.description": "Scanează codul QR pentru a împerechea telefonul tău cu această instanță Cider",
"about.thanks": "Multe Mulțumiri Echipei Colectiv Cider și a tuturor contribuitorilor."
}

View file

@ -2,7 +2,7 @@
"i18n.languageName": "English (US)", "i18n.languageName": "English (US)",
"i18n.languageNameEnglish": "English (US)", "i18n.languageNameEnglish": "English (US)",
"i18n.category": "main", "i18n.category": "main",
"i18n.authors": "@maikirakiwi @kyw504100 nosh118", "i18n.authors": "@maikirakiwi @kyw504100 @nosh118",
"app.name": "Cider", "app.name": "Cider",
"date.format": "${m} ${d}, ${y}", "date.format": "${m} ${d}, ${y}",
"dialog.cancel": "Cancel", "dialog.cancel": "Cancel",
@ -148,6 +148,7 @@
"term.noVideos": "No videos found.", "term.noVideos": "No videos found.",
"term.plugin": "Plug-in", "term.plugin": "Plug-in",
"term.pluginMenu": "Plug-in Menu", "term.pluginMenu": "Plug-in Menu",
"term.pluginMenu.none": "No interactive plugins",
"term.replay": "Replay", "term.replay": "Replay",
"term.uniqueAlbums": "Unique Albums", "term.uniqueAlbums": "Unique Albums",
"term.uniqueArtists": "Unique Artists", "term.uniqueArtists": "Unique Artists",
@ -205,6 +206,7 @@
"action.startRadio": "Start Radio", "action.startRadio": "Start Radio",
"action.goToArtist": "Go to Artist", "action.goToArtist": "Go to Artist",
"action.goToAlbum": "Go to Album", "action.goToAlbum": "Go to Album",
"action.showInPlaylist": "Show in Playlist",
"action.moveToTop": "Move out of Folder", "action.moveToTop": "Move out of Folder",
"action.share": "Share", "action.share": "Share",
"action.rename": "Rename", "action.rename": "Rename",
@ -353,7 +355,7 @@
"settings.option.experimental.close_button_hide": "Close Button Should Hide the Application", "settings.option.experimental.close_button_hide": "Close Button Should Hide the Application",
"settings.option.experimental.inline_playlists": "Inline Playlists and Albums", "settings.option.experimental.inline_playlists": "Inline Playlists and Albums",
"settings.option.advanced.playlistTrackMapping": "Playlist Track Mapping", "settings.option.advanced.playlistTrackMapping": "Playlist Track Mapping",
"settings.option.advanced.playlistTrackMapping.description": "Enables deep scanning of playlists to determine which tracks are in which playlists.", "settings.option.advanced.playlistTrackMapping.description": "Enables deep scanning of playlists to determine which tracks are in which playlists. Playlist cache build times can increase significantly.",
"spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.", "spatial.notTurnedOn": "Audio Spatialization is disabled. To use, please enable it first.",
"spatial.spatialProperties": "Spatial Properties", "spatial.spatialProperties": "Spatial Properties",
"spatial.width": "Width", "spatial.width": "Width",

View file

@ -146,7 +146,7 @@
"home.followedArtists": "关注的艺人", "home.followedArtists": "关注的艺人",
"error.appleMusicSubRequired": "需要订阅 Apple Music 以使用 Cider", "error.appleMusicSubRequired": "需要订阅 Apple Music 以使用 Cider",
"error.connectionError": "无法连接到 Apple Music。", "error.connectionError": "无法连接到 Apple Music。",
"error.noResults": "没有结果", "error.noResults": "没有结果",
"error.noResults.description": "尝试更改搜索条件。", "error.noResults.description": "尝试更改搜索条件。",
"podcast.followOnCider": "在 Cider 中关注", "podcast.followOnCider": "在 Cider 中关注",
"podcast.followedOnCider": "已关注", "podcast.followedOnCider": "已关注",
@ -192,7 +192,7 @@
"action.showWebRemoteQR": "显示远程控制的二维码", "action.showWebRemoteQR": "显示远程控制的二维码",
"action.playTracksNext": "插播 ${app.selectedMediaItems.length} 首歌曲", "action.playTracksNext": "插播 ${app.selectedMediaItems.length} 首歌曲",
"action.playTracksLater": "最后播放 ${app.selectedMediaItems.length} 首歌曲", "action.playTracksLater": "最后播放 ${app.selectedMediaItems.length} 首歌曲",
"action.removeTracks": "从队列中移除 ${self.selectedItems.length} 首歌曲", "action.removeTracks": "从待播清单中移除 ${self.selectedItems.length} 首歌曲",
"action.import": "导入", "action.import": "导入",
"action.export": "导出", "action.export": "导出",
"action.showAlbum": "显示专辑", "action.showAlbum": "显示专辑",

View file

@ -23,7 +23,6 @@
"term.about": "關於", "term.about": "關於",
"term.privateSession": "私人模式", "term.privateSession": "私人模式",
"term.queue": "待播清單", "term.queue": "待播清單",
"term.history": "歷史紀錄",
"term.search": "搜尋", "term.search": "搜尋",
"term.library": "資料庫", "term.library": "資料庫",
"term.listenNow": "立即聆聽", "term.listenNow": "立即聆聽",
@ -51,7 +50,6 @@
"term.mute": "靜音", "term.mute": "靜音",
"term.unmute": "取消靜音", "term.unmute": "取消靜音",
"term.share": "分享", "term.share": "分享",
"term.share.success": "已複製至剪貼簿",
"term.settings": "設定", "term.settings": "設定",
"term.seeAll": "顯示全部", "term.seeAll": "顯示全部",
"term.sortBy": "排序", "term.sortBy": "排序",
@ -191,7 +189,7 @@
"action.love": "喜愛", "action.love": "喜愛",
"action.unlove": "取消喜愛", "action.unlove": "取消喜愛",
"action.dislike": "減少此類建議", "action.dislike": "減少此類建議",
"action.undoDislike": "還原減此類建議", "action.undoDislike": "還原減此類建議",
"action.showWebRemoteQR": "遙距控制", "action.showWebRemoteQR": "遙距控制",
"action.playTracksNext": "插播 ${app.selectedMediaItems.length} 首歌曲", "action.playTracksNext": "插播 ${app.selectedMediaItems.length} 首歌曲",
"action.playTracksLater": "稍後播放 ${app.selectedMediaItems.length} 首歌曲", "action.playTracksLater": "稍後播放 ${app.selectedMediaItems.length} 首歌曲",

View file

@ -1,290 +1,290 @@
{ {
"i18n.languageName": "廣東話(香港)", "i18n.languageName": "廣東話(香港)",
"i18n.languageNameEnglish": "Cantonese (Hong Kong)", "i18n.languageNameEnglish": "Cantonese (Hong Kong)",
"i18n.category": "main", "i18n.category": "main",
"i18n.authors": "@tszngaiyip @strikesnc", "i18n.authors": "@tszngaiyip @strikesnc",
"app.name": "Cider", "app.name": "Cider",
"date.format": "${y}年${m}月${d}日", "date.format": "${y}年${m}月${d}日",
"dialog.cancel": "取消", "dialog.cancel": "取消",
"dialog.ok": "確認", "dialog.ok": "確認",
"notification.updatingLibrarySongs": "更新緊資料庫嘅歌曲...", "notification.updatingLibrarySongs": "更新緊資料庫嘅歌曲...",
"notification.updatingLibraryAlbums": "更新緊資料庫嘅專輯...", "notification.updatingLibraryAlbums": "更新緊資料庫嘅專輯...",
"notification.updatingLibraryArtists": "更新緊資料庫嘅藝人...", "notification.updatingLibraryArtists": "更新緊資料庫嘅藝人...",
"term.appleInc": "Apple Inc.", "term.appleInc": "Apple Inc.",
"term.appleMusic": "Apple Music", "term.appleMusic": "Apple Music",
"term.applePodcasts": "Apple Podcasts", "term.applePodcasts": "Apple Podcasts",
"term.itunes": "iTunes", "term.itunes": "iTunes",
"term.github": "GitHub", "term.github": "GitHub",
"term.discord": "Discord", "term.discord": "Discord",
"term.learnMore": "想知更多", "term.learnMore": "想知更多",
"term.accountSettings": "帳號設定", "term.accountSettings": "帳號設定",
"term.logout": "登出", "term.logout": "登出",
"term.login": "登入", "term.login": "登入",
"term.about": "關於", "term.about": "關於",
"term.privateSession": "無痕模式", "term.privateSession": "無痕模式",
"term.queue": "待播清單", "term.queue": "待播清單",
"term.history": "播放歷史", "term.history": "播放歷史",
"term.search": "搵野", "term.search": "搵野",
"term.library": "資料庫", "term.library": "資料庫",
"term.listenNow": "即刻聽", "term.listenNow": "即刻聽",
"term.browse": "瀏覽", "term.browse": "瀏覽",
"term.radio": "電台", "term.radio": "電台",
"term.recentlyAdded": "最近加入", "term.recentlyAdded": "最近加入",
"term.songs": "歌曲", "term.songs": "歌曲",
"term.albums": "專輯", "term.albums": "專輯",
"term.artists": "藝人", "term.artists": "藝人",
"term.podcasts": "Podcasts", "term.podcasts": "Podcasts",
"term.playlists": "播放清單", "term.playlists": "播放清單",
"term.playlist": "播放清單", "term.playlist": "播放清單",
"term.newPlaylist": "新播放清單", "term.newPlaylist": "新播放清單",
"term.newPlaylistFolder": "新資料夾", "term.newPlaylistFolder": "新資料夾",
"term.createNewPlaylist": "新增播放清單", "term.createNewPlaylist": "新增播放清單",
"term.createNewPlaylistFolder": "新增資料夾", "term.createNewPlaylistFolder": "新增資料夾",
"term.deletePlaylist": "你係咪要刪除呢個播放清單?", "term.deletePlaylist": "你係咪要刪除呢個播放清單?",
"term.play": "播放", "term.play": "播放",
"term.pause": "暫停", "term.pause": "暫停",
"term.previous": "前一首", "term.previous": "前一首",
"term.next": "下一首", "term.next": "下一首",
"term.shuffle": "隨機播放", "term.shuffle": "隨機播放",
"term.repeat": "重複播放", "term.repeat": "重複播放",
"term.volume": "音量", "term.volume": "音量",
"term.mute": "靜音", "term.mute": "靜音",
"term.unmute": "取消靜音", "term.unmute": "取消靜音",
"term.share": "分享", "term.share": "分享",
"term.share.success": "複製咗喺剪貼簿", "term.share.success": "複製咗喺剪貼簿",
"term.settings": "設定", "term.settings": "設定",
"term.seeAll": "睇哂全部", "term.seeAll": "睇哂全部",
"term.sortBy": "排序", "term.sortBy": "排序",
"term.sortBy.album": "專輯", "term.sortBy.album": "專輯",
"term.sortBy.artist": "藝人", "term.sortBy.artist": "藝人",
"term.sortBy.name": "歌名", "term.sortBy.name": "歌名",
"term.sortBy.genre": "音樂風格", "term.sortBy.genre": "音樂風格",
"term.sortBy.releaseDate": "幾時出", "term.sortBy.releaseDate": "幾時出",
"term.sortBy.duration": "幾長", "term.sortBy.duration": "幾長",
"term.sortOrder": "點排", "term.sortOrder": "點排",
"term.sortOrder.ascending": "順序", "term.sortOrder.ascending": "順序",
"term.sortOrder.descending": "倒序", "term.sortOrder.descending": "倒序",
"term.viewAs": "想點樣顯示", "term.viewAs": "想點樣顯示",
"term.viewAs.coverArt": "專輯封面", "term.viewAs.coverArt": "專輯封面",
"term.viewAs.list": "列表", "term.viewAs.list": "列表",
"term.size": "大細", "term.size": "大細",
"term.size.normal": "正常", "term.size.normal": "正常",
"term.size.compact": "迫啲", "term.size.compact": "迫啲",
"term.enable": "開", "term.enable": "開",
"term.disable": "熄", "term.disable": "熄",
"term.enabled": "開左", "term.enabled": "開左",
"term.disabled": "熄左", "term.disabled": "熄左",
"term.connect": "連結", "term.connect": "連結",
"term.connecting": "連緊", "term.connecting": "連緊",
"term.disconnect": "取消連結", "term.disconnect": "取消連結",
"term.authed": "授權咗", "term.authed": "授權咗",
"term.confirm": "確認?", "term.confirm": "確認?",
"term.more": "多啲", "term.more": "多啲",
"term.less": "少啲", "term.less": "少啲",
"term.showMore": "顯示多啲", "term.showMore": "顯示多啲",
"term.showLess": "顯示少啲", "term.showLess": "顯示少啲",
"term.topSongs": "熱門歌曲", "term.topSongs": "熱門歌曲",
"term.latestReleases": "最新出嘅", "term.latestReleases": "最新出嘅",
"term.time.added": "加入於", "term.time.added": "加入於",
"term.time.released": "發行於", "term.time.released": "發行於",
"term.time.updated": "更新於", "term.time.updated": "更新於",
"term.time.hours": "粒鐘", "term.time.hours": "粒鐘",
"term.time.hour": "粒鐘", "term.time.hour": "粒鐘",
"term.time.minutes": "分鐘", "term.time.minutes": "分鐘",
"term.time.minute": "分鐘", "term.time.minute": "分鐘",
"term.time.seconds": "秒", "term.time.seconds": "秒",
"term.time.second": "秒", "term.time.second": "秒",
"term.fullscreenView": "用全螢幕睇", "term.fullscreenView": "用全螢幕睇",
"term.defaultView": "平時咁睇", "term.defaultView": "平時咁睇",
"term.audioSettings": "音訊設定", "term.audioSettings": "音訊設定",
"term.clearAll": "清除", "term.clearAll": "清除",
"term.recentStations": "呢排聽緊嘅", "term.recentStations": "呢排聽緊嘅",
"term.language": "語言", "term.language": "語言",
"term.funLanguages": "惡搞", "term.funLanguages": "惡搞",
"term.noLyrics": "搵緊... / 搵唔到歌詞。 / 純音樂黎。", "term.noLyrics": "搵緊... / 搵唔到歌詞。 / 純音樂黎。",
"term.copyright": "版權", "term.copyright": "版權",
"term.rightsReserved": "保留一切權利", "term.rightsReserved": "保留一切權利",
"term.sponsor": "課金俾呢個Project", "term.sponsor": "課金俾呢個Project",
"term.ciderTeam": "Cider 團隊", "term.ciderTeam": "Cider 團隊",
"term.developer": "開發者", "term.developer": "開發者",
"term.socialTeam": "PR", "term.socialTeam": "PR",
"term.socials": "我哋嘅社群", "term.socials": "我哋嘅社群",
"term.contributors": "合作人", "term.contributors": "合作人",
"term.equalizer": "均衡器 (EQ)", "term.equalizer": "均衡器 (EQ)",
"term.reset": "重設", "term.reset": "重設",
"term.tracks": "首歌", "term.tracks": "首歌",
"term.videos": "影片", "term.videos": "影片",
"term.menu": "選項", "term.menu": "選項",
"term.check": "檢查", "term.check": "檢查",
"term.aboutArtist": "關於 {{artistName}}", "term.aboutArtist": "關於 {{artistName}}",
"term.topResult": "熱門搜尋結果", "term.topResult": "熱門搜尋結果",
"term.sharedPlaylists": "播放清單", "term.sharedPlaylists": "播放清單",
"term.people": "個人檔案", "term.people": "個人檔案",
"term.newpreset.name": "新EQ範本嘅名", "term.newpreset.name": "新EQ範本嘅名",
"term.addedpreset": "新增咗", "term.addedpreset": "新增咗",
"term.deletepreset.warn": "你係咪要刪除呢個範本?", "term.deletepreset.warn": "你係咪要刪除呢個範本?",
"term.deletedpreset": "刪除咗", "term.deletedpreset": "刪除咗",
"term.musicVideos": "MV", "term.musicVideos": "MV",
"term.stations": "電台", "term.stations": "電台",
"term.radioShows": "電台單集", "term.radioShows": "電台單集",
"term.recordLabels": "唱片公司", "term.recordLabels": "唱片公司",
"term.videoExtras": "相關嘅片", "term.videoExtras": "相關嘅片",
"home.title": "主頁", "home.title": "主頁",
"home.recentlyPlayed": "呢排播左", "home.recentlyPlayed": "呢排播左",
"home.recentlyAdded": "呢排加嘅", "home.recentlyAdded": "呢排加嘅",
"home.artistsFeed": "藝人動態", "home.artistsFeed": "藝人動態",
"home.artistsFeed.noArtist": "Follow 一啲藝人嚟獲得佢哋嘅最新歌曲資訊。 ", "home.artistsFeed.noArtist": "Follow 一啲藝人嚟獲得佢哋嘅最新歌曲資訊。 ",
"home.madeForYou": "為你而整", "home.madeForYou": "為你而整",
"home.friendsListeningTo": "你啲Friend聽緊", "home.friendsListeningTo": "你啲Friend聽緊",
"home.followedArtists": "Follow左嘅藝人", "home.followedArtists": "Follow左嘅藝人",
"error.appleMusicSubRequired": "需要訂閱Apple Music先可以用Cider。", "error.appleMusicSubRequired": "需要訂閱Apple Music先可以用Cider。",
"error.connectionError": "連接唔到Apple Music。", "error.connectionError": "連接唔到Apple Music。",
"error.noResults": "冇結果。", "error.noResults": "冇結果。",
"error.noResults.description": "重新搵過啦。", "error.noResults.description": "重新搵過啦。",
"podcast.followOnCider": "喺Cider上Follow", "podcast.followOnCider": "喺Cider上Follow",
"podcast.followedOnCider": "喺Cider上Follow左", "podcast.followedOnCider": "喺Cider上Follow左",
"podcast.subscribeOnItunes": "喺iTunes上訂閱", "podcast.subscribeOnItunes": "喺iTunes上訂閱",
"podcast.subscribedOnItunes": "喺iTunes上訂閱左", "podcast.subscribedOnItunes": "喺iTunes上訂閱左",
"podcast.itunesStore": "iTunes Store", "podcast.itunesStore": "iTunes Store",
"podcast.episodes": "單集", "podcast.episodes": "單集",
"podcast.playEpisode": "播呢集", "podcast.playEpisode": "播呢集",
"podcast.website": "Podcast 網頁", "podcast.website": "Podcast 網頁",
"action.addToLibrary": "加入資料庫", "action.addToLibrary": "加入資料庫",
"action.addToLibrary.success": "加入咗資料庫", "action.addToLibrary.success": "加入咗資料庫",
"action.addToLibrary.error": "加入唔到資料庫", "action.addToLibrary.error": "加入唔到資料庫",
"action.removeFromLibrary": "喺資料庫到刪除", "action.removeFromLibrary": "喺資料庫到刪除",
"action.removeFromLibrary.success": "已經喺資料庫到刪除咗", "action.removeFromLibrary.success": "已經喺資料庫到刪除咗",
"action.addToQueue": "加入待播清單", "action.addToQueue": "加入待播清單",
"action.addToQueue.success": "加入咗待播清單", "action.addToQueue.success": "加入咗待播清單",
"action.addToQueue.error": "加入唔到待播清單", "action.addToQueue.error": "加入唔到待播清單",
"action.removeFromQueue": "喺待播清單刪除", "action.removeFromQueue": "喺待播清單刪除",
"action.removeFromQueue.success": "已經喺待播清單到刪除咗", "action.removeFromQueue.success": "已經喺待播清單到刪除咗",
"action.removeFromQueue.error": "喺待播清單到刪除唔到", "action.removeFromQueue.error": "喺待播清單到刪除唔到",
"action.createPlaylist": "建立新嘅播放清單", "action.createPlaylist": "建立新嘅播放清單",
"action.addToPlaylist": "加入播放清單", "action.addToPlaylist": "加入播放清單",
"action.removeFromPlaylist": "喺播放清單到刪除", "action.removeFromPlaylist": "喺播放清單到刪除",
"action.addToFavorites": "加至收藏", "action.addToFavorites": "加至收藏",
"action.follow": "Follow", "action.follow": "Follow",
"action.follow.success": "Follow緊", "action.follow.success": "Follow緊",
"action.follow.error": "Follow唔到", "action.follow.error": "Follow唔到",
"action.unfollow": "Unfollow", "action.unfollow": "Unfollow",
"action.unfollow.success": "Unfollow咗", "action.unfollow.success": "Unfollow咗",
"action.unfollow.error": "Unfollow唔到", "action.unfollow.error": "Unfollow唔到",
"action.playNext": "下首即刻播", "action.playNext": "下首即刻播",
"action.playLater": "陣間先再播", "action.playLater": "陣間先再播",
"action.startRadio": "建立電台", "action.startRadio": "建立電台",
"action.goToArtist": "前往藝人", "action.goToArtist": "前往藝人",
"action.goToAlbum": "前往專輯", "action.goToAlbum": "前往專輯",
"action.moveToTop": "返最頂", "action.moveToTop": "返最頂",
"action.share": "分享歌曲", "action.share": "分享歌曲",
"action.rename": "重新命名", "action.rename": "重新命名",
"action.love": "鐘意", "action.love": "鐘意",
"action.unlove": "唔鐘意", "action.unlove": "唔鐘意",
"action.dislike": "唔想再睇到", "action.dislike": "唔想再睇到",
"action.undoDislike": "還原唔想再睇到", "action.undoDislike": "還原唔想再睇到",
"action.showWebRemoteQR": "遙距控制", "action.showWebRemoteQR": "遙距控制",
"action.playTracksNext": "插播 ${app.selectedMediaItems.length} 首歌曲", "action.playTracksNext": "插播 ${app.selectedMediaItems.length} 首歌曲",
"action.playTracksLater": "陣間播放 ${app.selectedMediaItems.length} 首歌曲", "action.playTracksLater": "陣間播放 ${app.selectedMediaItems.length} 首歌曲",
"action.removeTracks": "喺待播清單到刪除 ${self.selectedItems.length} 首歌曲", "action.removeTracks": "喺待播清單到刪除 ${self.selectedItems.length} 首歌曲",
"action.import": "匯入", "action.import": "匯入",
"action.export": "匯出", "action.export": "匯出",
"action.showAlbum": "顯示完整嘅專輯", "action.showAlbum": "顯示完整嘅專輯",
"action.tray.minimize": "收埋喺系統托盤", "action.tray.minimize": "收埋喺系統托盤",
"action.tray.quit": "結束", "action.tray.quit": "結束",
"action.tray.show": "顯示", "action.tray.show": "顯示",
"action.update": "更新", "action.update": "更新",
"action.copy": "複製", "action.copy": "複製",
"action.newpreset": "新增範本", "action.newpreset": "新增範本",
"action.deletepreset": "刪除範本", "action.deletepreset": "刪除範本",
"settings.header.general": "一般", "settings.header.general": "一般",
"settings.header.general.description": "調整Cider嘅一般設定", "settings.header.general.description": "調整Cider嘅一般設定",
"settings.option.general.language": "語言", "settings.option.general.language": "語言",
"settings.option.general.language.main": "語言", "settings.option.general.language.main": "語言",
"settings.option.general.language.fun": "惡搞語言", "settings.option.general.language.fun": "惡搞語言",
"settings.option.general.language.unsorted": "未分類", "settings.option.general.language.unsorted": "未分類",
"settings.option.general.updateCider": "更新 Cider", "settings.option.general.updateCider": "更新 Cider",
"settings.header.audio": "音訊", "settings.header.audio": "音訊",
"settings.header.audio.description": "調整Cider嘅音訊設定", "settings.header.audio.description": "調整Cider嘅音訊設定",
"settings.option.audio.quality": "音質", "settings.option.audio.quality": "音質",
"settings.header.audio.quality.high": "質素優先", "settings.header.audio.quality.high": "質素優先",
"settings.header.audio.quality.low": "流暢度優先", "settings.header.audio.quality.low": "流暢度優先",
"settings.header.audio.quality.auto": "自動", "settings.header.audio.quality.auto": "自動",
"settings.option.audio.seamlessTransition": "無縫播放", "settings.option.audio.seamlessTransition": "無縫播放",
"settings.option.audio.enableAdvancedFunctionality": "進階功能", "settings.option.audio.enableAdvancedFunctionality": "進階功能",
"settings.option.audio.enableAdvancedFunctionality.description": "啟用AudioContext解鎖類似音量平衡和均衡器嘅進階功能但係會喺部分電腦造成音樂Lag機。", "settings.option.audio.enableAdvancedFunctionality.description": "啟用AudioContext解鎖類似音量平衡和均衡器嘅進階功能但係會喺部分電腦造成音樂Lag機。",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量平衡", "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量平衡",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "平衡輕柔同響亮嘅歌曲,令你有統一嘅聆聽體驗。", "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "平衡輕柔同響亮嘅歌曲,令你有統一嘅聆聽體驗。",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空間音訊", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "空間音訊",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "空間化音訊,製造一個更立體嘅聆聽體驗(注意:呢個功能唔係官方嘅杜比全景聲)", "settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description": "空間化音訊,製造一個更立體嘅聆聽體驗(注意:呢個功能唔係官方嘅杜比全景聲)",
"settings.header.visual": "外觀", "settings.header.visual": "外觀",
"settings.header.visual.description": "調整Cider嘅外觀", "settings.header.visual.description": "調整Cider嘅外觀",
"settings.option.visual.windowBackgroundStyle": "視窗背景樣式", "settings.option.visual.windowBackgroundStyle": "視窗背景樣式",
"settings.header.visual.windowBackgroundStyle.none": "空白", "settings.header.visual.windowBackgroundStyle.none": "空白",
"settings.header.visual.windowBackgroundStyle.artwork": "專輯封面", "settings.header.visual.windowBackgroundStyle.artwork": "專輯封面",
"settings.header.visual.windowBackgroundStyle.image": "圖片", "settings.header.visual.windowBackgroundStyle.image": "圖片",
"settings.option.visual.animatedArtwork": "動態專輯封面", "settings.option.visual.animatedArtwork": "動態專輯封面",
"settings.header.visual.animatedArtwork.always": "總是顯示", "settings.header.visual.animatedArtwork.always": "總是顯示",
"settings.header.visual.animatedArtwork.limited": "淨係喺藝人頁面同專輯封面顯示", "settings.header.visual.animatedArtwork.limited": "淨係喺藝人頁面同專輯封面顯示",
"settings.header.visual.animatedArtwork.disable": "熄左佢", "settings.header.visual.animatedArtwork.disable": "熄左佢",
"settings.option.visual.animatedArtworkQuality": "動態專輯封面品質", "settings.option.visual.animatedArtworkQuality": "動態專輯封面品質",
"settings.header.visual.animatedArtworkQuality.low": "低", "settings.header.visual.animatedArtworkQuality.low": "低",
"settings.header.visual.animatedArtworkQuality.medium": "中", "settings.header.visual.animatedArtworkQuality.medium": "中",
"settings.header.visual.animatedArtworkQuality.high": "高", "settings.header.visual.animatedArtworkQuality.high": "高",
"settings.header.visual.animatedArtworkQuality.veryHigh": "非常高", "settings.header.visual.animatedArtworkQuality.veryHigh": "非常高",
"settings.header.visual.animatedArtworkQuality.extreme": "極高", "settings.header.visual.animatedArtworkQuality.extreme": "極高",
"settings.option.visual.animatedWindowBackground": "動態視窗背景", "settings.option.visual.animatedWindowBackground": "動態視窗背景",
"settings.option.visual.hardwareAcceleration": "硬體加速", "settings.option.visual.hardwareAcceleration": "硬體加速",
"settings.option.visual.hardwareAcceleration.description": "需要重開Cider先會生效", "settings.option.visual.hardwareAcceleration.description": "需要重開Cider先會生效",
"settings.header.visual.hardwareAcceleration.default": "預設", "settings.header.visual.hardwareAcceleration.default": "預設",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.header.visual.theme": "主題", "settings.header.visual.theme": "主題",
"settings.option.visual.theme.default": "預設", "settings.option.visual.theme.default": "預設",
"settings.option.visual.theme.dark": "黑色", "settings.option.visual.theme.dark": "黑色",
"settings.option.visual.showPersonalInfo": "顯示個人檔案", "settings.option.visual.showPersonalInfo": "顯示個人檔案",
"settings.header.lyrics": "歌詞", "settings.header.lyrics": "歌詞",
"settings.header.lyrics.description": "調整Cider嘅歌詞設定", "settings.header.lyrics.description": "調整Cider嘅歌詞設定",
"settings.option.lyrics.enableMusixmatch": "啟用 Musixmatch 歌詞", "settings.option.lyrics.enableMusixmatch": "啟用 Musixmatch 歌詞",
"settings.option.lyrics.enableMusixmatchKaraoke": "開啟唱K模式僅限Musixmatch)", "settings.option.lyrics.enableMusixmatchKaraoke": "開啟唱K模式僅限Musixmatch)",
"settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好",
"settings.option.lyrics.enableYoutubeLyrics": "播放MV嘅時候用YouTube字幕", "settings.option.lyrics.enableYoutubeLyrics": "播放MV嘅時候用YouTube字幕",
"settings.header.connectivity": "外部連結", "settings.header.connectivity": "外部連結",
"settings.header.connectivity.description": "調整Cider同外部嘅連結", "settings.header.connectivity.description": "調整Cider同外部嘅連結",
"settings.option.connectivity.discordRPC": "Discord 狀態", "settings.option.connectivity.discordRPC": "Discord 狀態",
"settings.option.connectivity.playbackNotifications": "喺播歌嘅時候通知你", "settings.option.connectivity.playbackNotifications": "喺播歌嘅時候通知你",
"settings.header.connectivity.discordRPC.cider": "顯示為'Cider'", "settings.header.connectivity.discordRPC.cider": "顯示為'Cider'",
"settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'", "settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'",
"settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態",
"settings.option.connectivity.lastfmScrobble": "Last.FM Scrobbling 記錄", "settings.option.connectivity.lastfmScrobble": "Last.FM Scrobbling 記錄",
"settings.option.connectivity.lastfmScrobble.delay": "Last.FM Scrobble 延遲 (%)", "settings.option.connectivity.lastfmScrobble.delay": "Last.FM Scrobble 延遲 (%)",
"settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 Last.FM 正在播放", "settings.option.connectivity.lastfmScrobble.nowPlaying": "啟用 Last.FM 正在播放",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (Last.FM)", "settings.option.connectivity.lastfmScrobble.removeFeatured": "從歌名中移除藝人推薦 (Last.FM)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.FM)", "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.FM)",
"settings.header.experimental": "實驗性功能", "settings.header.experimental": "實驗性功能",
"settings.header.experimental.description": "調整Cider嘅實驗性功能", "settings.header.experimental.description": "調整Cider嘅實驗性功能",
"settings.option.experimental.compactUI": "逼啲既 UI", "settings.option.experimental.compactUI": "逼啲既 UI",
"settings.option.experimental.close_button_hide": "㩒交叉制嚟隱藏 Cider", "settings.option.experimental.close_button_hide": "㩒交叉制嚟隱藏 Cider",
"settings.option.experimental.copy_log": "將log複製喺剪貼簿", "settings.option.experimental.copy_log": "將log複製喺剪貼簿",
"spatial.notTurnedOn": "唔該喺設定入面啟用左空間音訊先。", "spatial.notTurnedOn": "唔該喺設定入面啟用左空間音訊先。",
"spatial.spatialProperties": "空間音訊屬性", "spatial.spatialProperties": "空間音訊屬性",
"spatial.width": "幾闊", "spatial.width": "幾闊",
"spatial.height": "幾高", "spatial.height": "幾高",
"spatial.depth": "幾深", "spatial.depth": "幾深",
"spatial.gain": "增益", "spatial.gain": "增益",
"spatial.roomMaterials": "空間材質", "spatial.roomMaterials": "空間材質",
"spatial.roomDimensions": "空間大小", "spatial.roomDimensions": "空間大小",
"spatial.roomPositions": "空間位置", "spatial.roomPositions": "空間位置",
"spatial.setDimensions": "大小設定", "spatial.setDimensions": "大小設定",
"spatial.setPositions": "位置設定", "spatial.setPositions": "位置設定",
"spatial.up": "上面", "spatial.up": "上面",
"spatial.front": "前面", "spatial.front": "前面",
"spatial.left": "左邊", "spatial.left": "左邊",
"spatial.right": "右邊", "spatial.right": "右邊",
"spatial.back": "後面", "spatial.back": "後面",
"spatial.down": "下面", "spatial.down": "下面",
"spatial.listener": "觀眾", "spatial.listener": "觀眾",
"spatial.audioSource": "音源", "spatial.audioSource": "音源",
"settings.header.unfinished": "未搞掂", "settings.header.unfinished": "未搞掂",
"remote.web.title": "遙距控制 Cider", "remote.web.title": "遙距控制 Cider",
"remote.web.description": "Scan 呢個 QR Code 去控制 Cider", "remote.web.description": "Scan 呢個 QR Code 去控制 Cider",
"about.thanks": "多謝 Cider Collective 同埋所有合作人作出嘅貢獻。" "about.thanks": "多謝 Cider Collective 同埋所有合作人作出嘅貢獻。"
} }

View file

@ -4,6 +4,12 @@ import * as path from 'path';
import * as log from 'electron-log'; import * as log from 'electron-log';
import {utils} from './utils'; import {utils} from './utils';
/**
* @file Creates App instance
* @author CiderCollective
*/
/** @namespace */
export class AppEvents { export class AppEvents {
private protocols: string[] = [ private protocols: string[] = [
"ame", "ame",
@ -17,6 +23,7 @@ export class AppEvents {
private tray: any = undefined; private tray: any = undefined;
private i18n: any = undefined; private i18n: any = undefined;
/** @constructor */
constructor() { constructor() {
this.start(); this.start();
} }
@ -90,6 +97,7 @@ export class AppEvents {
/*********************************************************************************************************************** /***********************************************************************************************************************
* Protocols * Protocols
**********************************************************************************************************************/ **********************************************************************************************************************/
/** */
if (process.defaultApp) { if (process.defaultApp) {
if (process.argv.length >= 2) { if (process.argv.length >= 2) {
this.protocols.forEach((protocol: string) => { this.protocols.forEach((protocol: string) => {

View file

@ -16,7 +16,12 @@ import {utils} from './utils';
const fileWatcher = require('chokidar'); const fileWatcher = require('chokidar');
const AdmZip = require("adm-zip"); const AdmZip = require("adm-zip");
/**
* @file Creates the BrowserWindow
* @author CiderCollective
*/
/** @namespace */
export class BrowserWindow { export class BrowserWindow {
public static win: any | undefined = null; public static win: any | undefined = null;
private devMode: boolean = !app.isPackaged; private devMode: boolean = !app.isPackaged;
@ -273,6 +278,9 @@ export class BrowserWindow {
/** /**
* Creates the browser window * Creates the browser window
* @generator
* @function createWindow
* @yields {object} Electron browser window
*/ */
async createWindow(): Promise<Electron.BrowserWindow> { async createWindow(): Promise<Electron.BrowserWindow> {
this.clientPort = await getPort({port: 9000}); this.clientPort = await getPort({port: 9000});
@ -283,6 +291,7 @@ export class BrowserWindow {
const windowState = windowStateKeeper({ const windowState = windowStateKeeper({
defaultWidth: 1024, defaultWidth: 1024,
defaultHeight: 600, defaultHeight: 600,
fullScreen: false
}); });
this.options.width = windowState.width; this.options.width = windowState.width;
this.options.height = windowState.height; this.options.height = windowState.height;
@ -292,8 +301,9 @@ export class BrowserWindow {
break; break;
case "win32": case "win32":
this.options.backgroundColor = "#1E1E1E"; if (!(utils.getStoreValue('visual.transparent') ?? false)){
this.options.transparent = false; this.options.backgroundColor = "#1E1E1E";} else {
this.options.transparent = true;}
break; break;
case "linux": case "linux":
this.options.backgroundColor = "#1E1E1E"; this.options.backgroundColor = "#1E1E1E";
@ -312,6 +322,12 @@ export class BrowserWindow {
this.startWebServer(); this.startWebServer();
BrowserWindow.win = new bw(this.options); BrowserWindow.win = new bw(this.options);
// cant be built in CI
// if (process.platform === "win32" && (utils.getStoreValue('visual.transparent') ?? false)) {
// var electronVibrancy = require('electron-vibrancy-updated');
// electronVibrancy.SetVibrancy(BrowserWindow.win, 0);
// }
const ws = new wsapi(BrowserWindow.win) const ws = new wsapi(BrowserWindow.win)
ws.InitWebSockets() ws.InitWebSockets()
// and load the renderer. // and load the renderer.
@ -427,9 +443,8 @@ export class BrowserWindow {
} }
}); });
app.get("/themes/:theme/*", (req, res) => { app.get("/themes/:theme/*", (req: {params: {theme: string, 0: string}}, res) => {
const theme = req.params.theme; const theme = req.params.theme;
// @ts-ignore
const file = req.params[0]; const file = req.params[0];
const themePath = join(utils.getPath('srcPath'), "./renderer/themes/", theme); const themePath = join(utils.getPath('srcPath'), "./renderer/themes/", theme);
const userThemePath = join(utils.getPath('themes'), theme); const userThemePath = join(utils.getPath('themes'), theme);
@ -442,9 +457,8 @@ export class BrowserWindow {
} }
}); });
app.get("/plugins/:plugin/*", (req, res) => { app.get("/plugins/:plugin/*", (req: {params: {plugin: string, 0: string}}, res) => {
const plugin = req.params.plugin; const plugin = req.params.plugin;
// @ts-ignore
const file = req.params[0]; const file = req.params[0];
const pluginPath = join(utils.getPath('plugins'), plugin); const pluginPath = join(utils.getPath('plugins'), plugin);
console.log(pluginPath) console.log(pluginPath)
@ -790,9 +804,15 @@ export class BrowserWindow {
ipcMain.on('setFullScreen', (_event, flag) => { ipcMain.on('setFullScreen', (_event, flag) => {
BrowserWindow.win.setFullScreen(flag) BrowserWindow.win.setFullScreen(flag)
}) })
//Fullscreen //Fullscreen
ipcMain.on('detachDT', (_event, _) => { ipcMain.on('detachDT', (_event, _) => {
BrowserWindow.win.webContents.openDevTools({mode: 'detach'}); BrowserWindow.win.webContents.openDevTools({mode: 'detach'});
})
ipcMain.on('relaunchApp',(_event, _) => {
app.relaunch()
app.exit()
}) })
@ -927,11 +947,11 @@ export class BrowserWindow {
ipcMain.on('get-remote-pair-url', (_event, _) => { ipcMain.on('get-remote-pair-url', (_event, _) => {
let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`; let url = `http://${BrowserWindow.getIP()}:${this.remotePort}`;
if (app.isPackaged) { //if (app.isPackaged) {
BrowserWindow.win.webContents.send('send-remote-pair-url', (`https://cider.sh/pair-remote?url=${Buffer.from(encodeURI(url)).toString('base64')}`).toString()); BrowserWindow.win.webContents.send('send-remote-pair-url', (`https://cider.sh/pair-remote?url=${Buffer.from(encodeURI(url)).toString('base64')}`).toString());
} else { //} else {
BrowserWindow.win.webContents.send('send-remote-pair-url', (`http://127.0.0.1:5500/pair-remote.html?url=${Buffer.from(encodeURI(url)).toString('base64')}`).toString()); // BrowserWindow.win.webContents.send('send-remote-pair-url', (`http://127.0.0.1:5500/pair-remote.html?url=${Buffer.from(encodeURI(url)).toString('base64')}`).toString());
} //}
}); });
if (process.platform === "darwin") { if (process.platform === "darwin") {
@ -958,6 +978,7 @@ export class BrowserWindow {
await utils.checkForUpdate(); await utils.checkForUpdate();
}); });
ipcMain.on('disable-update', (event) => { ipcMain.on('disable-update', (event) => {
// Check if using app store builds so people don't get pissy wen button go bonk // Check if using app store builds so people don't get pissy wen button go bonk
if (app.isPackaged && !process.mas || !process.windowsStore) { if (app.isPackaged && !process.mas || !process.windowsStore) {
@ -967,6 +988,8 @@ export class BrowserWindow {
} }
}) })
ipcMain.on('share-menu', async (_event, url) => { ipcMain.on('share-menu', async (_event, url) => {
if (process.platform != 'darwin') return; if (process.platform != 'darwin') return;
//https://www.electronjs.org/docs/latest/api/share-menu //https://www.electronjs.org/docs/latest/api/share-menu
@ -975,7 +998,6 @@ export class BrowserWindow {
title: 'Share', title: 'Share',
urls: [url] urls: [url]
}; };
// @ts-ignore
const shareMenu = new ShareMenu(options); const shareMenu = new ShareMenu(options);
shareMenu.popup(); shareMenu.popup();
}) })

View file

@ -3,6 +3,18 @@ import * as path from 'path';
import * as electron from 'electron' import * as electron from 'electron'
import {utils} from './utils'; import {utils} from './utils';
//
// Hello, this our loader for the various plugins that the Cider Development Team built for our
// numerous plugins internally and ones made by the community
//
// To learn how to make your own, visit https://github.com/ciderapp/Cider/wiki/Plugins
//
/**
* @class
* Plugin Loading
* @author booploops#7139
* @see {@link https://github.com/ciderapp/Cider/wiki/Plugins|Documentation}
*/
export class Plugins { export class Plugins {
private basePluginsPath = path.join(__dirname, '../plugins'); private basePluginsPath = path.join(__dirname, '../plugins');
private userPluginsPath = path.join(electron.app.getPath('userData'), 'Plugins'); private userPluginsPath = path.join(electron.app.getPath('userData'), 'Plugins');

View file

@ -15,7 +15,15 @@ export class Store {
"update_branch": "main", "update_branch": "main",
"resumeOnStartupBehavior": "local", "resumeOnStartupBehavior": "local",
"privateEnabled": false, "privateEnabled": false,
"themeUpdateNotification": true "themeUpdateNotification": true,
"sidebarItems": {
"recentlyAdded": true,
"songs": true,
"albums": true,
"artists": true,
"videos": true,
"podcasts": true
}
}, },
"home": { "home": {
"followedArtists": [], "followedArtists": [],
@ -97,6 +105,7 @@ export class Store {
"bg_artwork_rotation": false, "bg_artwork_rotation": false,
"hw_acceleration": "default", // default, webgpu, disabled "hw_acceleration": "default", // default, webgpu, disabled
"showuserinfo": true, "showuserinfo": true,
"transparent": false,
"miniplayer_top_toggle": true, "miniplayer_top_toggle": true,
"directives": { "directives": {
"windowLayout": "default" "windowLayout": "default"

View file

@ -2,7 +2,7 @@ import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import {Store} from "./store"; import {Store} from "./store";
import {BrowserWindow as bw} from "./browserwindow"; import {BrowserWindow as bw} from "./browserwindow";
import {app} from "electron"; import {app, dialog, ipcMain, Notification, shell } from "electron";
import fetch from "electron-fetch"; import fetch from "electron-fetch";
import {AppImageUpdater, NsisUpdater} from "electron-updater"; import {AppImageUpdater, NsisUpdater} from "electron-updater";
import * as log from "electron-log"; import * as log from "electron-log";
@ -115,7 +115,13 @@ export class utils {
* Checks the application for updates * Checks the application for updates
*/ */
static async checkForUpdate(): Promise<void> { static async checkForUpdate(): Promise<void> {
if (!app.isPackaged) {
new Notification({ title: "Application Update", body: "Can't update as app is in DEV mode. Please build or grab a copy by clicking me"})
.on('click', () => {shell.openExternal('https://download.cider.sh/?utm_source=app&utm_medium=dev-mode-warning')})
.show()
bw.win.webContents.send('update-response', "update-error")
return;
}
// Get the artifacts // Get the artifacts
const response = await fetch(`https://circleci.com/api/v1.1/project/gh/ciderapp/Cider/latest/artifacts?branch=${utils.getStoreValue('general.update_branch')}&filter=successful`) const response = await fetch(`https://circleci.com/api/v1.1/project/gh/ciderapp/Cider/latest/artifacts?branch=${utils.getStoreValue('general.update_branch')}&filter=successful`)
if (response.status != 200) { if (response.status != 200) {
@ -141,6 +147,10 @@ export class utils {
autoUpdater = await new AppImageUpdater(options) //Linux and Mac (AppImages work on macOS btw) autoUpdater = await new AppImageUpdater(options) //Linux and Mac (AppImages work on macOS btw)
} }
autoUpdater.on('checking-for-update', () => {
new Notification({ title: "Cider Update", body: "Cider is currently checking for updates."}).show()
})
autoUpdater.on('error', (error: any) => { autoUpdater.on('error', (error: any) => {
console.error(`[AutoUpdater] Error: ${error}`) console.error(`[AutoUpdater] Error: ${error}`)
bw.win.webContents.send('update-response', "update-error") bw.win.webContents.send('update-response', "update-error")
@ -150,10 +160,27 @@ export class utils {
console.log('[AutoUpdater] Update not available.') console.log('[AutoUpdater] Update not available.')
bw.win.webContents.send('update-response', "update-not-available"); bw.win.webContents.send('update-response', "update-not-available");
}) })
autoUpdater.on('download-progress', (event: any, progress: any) => {
bw.win.setProgressBar(progress.percent / 100)
})
autoUpdater.on('update-downloaded', () => { autoUpdater.on('update-downloaded', (info: any) => {
console.log('[AutoUpdater] Update downloaded.') console.log('[AutoUpdater] Update downloaded.')
bw.win.webContents.send('update-response', "update-downloaded"); bw.win.webContents.send('update-response', "update-downloaded");
const dialogOpts = {
type: 'info',
buttons: ['Restart', 'Later'],
title: 'Application Update',
message: info,
detail: 'A new version has been downloaded. Restart the application to apply the updates.'
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall()
})
new Notification({ title: "Application Update", body: info}).on('click', () => {
bw.win.show()
}).show()
}) })
log.transports.file.level = "debug" log.transports.file.level = "debug"

View file

@ -41,7 +41,7 @@ export default class ChromecastPlugin {
browser.on('ready', browser.discover); browser.on('ready', browser.discover);
browser.on('update', (service :any) => { browser.on('update', (service :any) => {
if (service.addresses && service.fullname) { if (service.addresses && service.fullname && service.fullname.includes('_googlecast._tcp')) {
this.ondeviceup(service.addresses[0], service.fullname.substring(0, service.fullname.indexOf("._googlecast")) + " " + (service.type[0].description ?? ""), '', 'googlecast'); this.ondeviceup(service.addresses[0], service.fullname.substring(0, service.fullname.indexOf("._googlecast")) + " " + (service.type[0].description ?? ""), '', 'googlecast');
} }
}); });

View file

@ -1,4 +1,4 @@
var CiderAudio = { const CiderAudio = {
context : null, context : null,
source : null, source : null,
audioNodes : { audioNodes : {
@ -304,7 +304,7 @@ var CiderAudio = {
CiderAudio.audioNodes.analogWarmth = [] CiderAudio.audioNodes.analogWarmth = []
for (i = 0; i < WARMTH_FREQUENCIES.length; i++) { for (let i = 0; i < WARMTH_FREQUENCIES.length; i++) {
CiderAudio.audioNodes.analogWarmth[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.analogWarmth[i] = CiderAudio.context.createBiquadFilter();
CiderAudio.audioNodes.analogWarmth[i].type = 'peaking'; // 'peaking'; CiderAudio.audioNodes.analogWarmth[i].type = 'peaking'; // 'peaking';
CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i]; CiderAudio.audioNodes.analogWarmth[i].frequency.value = WARMTH_FREQUENCIES[i];
@ -312,7 +312,7 @@ var CiderAudio = {
CiderAudio.audioNodes.analogWarmth[i].gain.value = WARMTH_GAIN[i] * app.cfg.audio.maikiwiAudio.analogWarmth_value; CiderAudio.audioNodes.analogWarmth[i].gain.value = WARMTH_GAIN[i] * app.cfg.audio.maikiwiAudio.analogWarmth_value;
} }
for (i = 1; i < WARMTH_FREQUENCIES.length; i ++) { for (let i = 1; i < WARMTH_FREQUENCIES.length; i ++) {
CiderAudio.audioNodes.analogWarmth[i-1].connect(CiderAudio.audioNodes.analogWarmth[i]); CiderAudio.audioNodes.analogWarmth[i-1].connect(CiderAudio.audioNodes.analogWarmth[i]);
} }
@ -345,7 +345,7 @@ var CiderAudio = {
CiderAudio.audioNodes.llpw = [] CiderAudio.audioNodes.llpw = []
if (app.cfg.audio.maikiwiAudio.ciderPPE_value === 0.55) { if (app.cfg.audio.maikiwiAudio.ciderPPE_value === 0.55) {
for (i = 0; i < c_LLPW_FREQUENCIES.length; i++) { for (let i = 0; i < c_LLPW_FREQUENCIES.length; i++) {
CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter();
CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking'; CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking';
CiderAudio.audioNodes.llpw[i].frequency.value = c_LLPW_FREQUENCIES[i]; CiderAudio.audioNodes.llpw[i].frequency.value = c_LLPW_FREQUENCIES[i];
@ -354,7 +354,7 @@ var CiderAudio = {
} }
for (i = 1; i < c_LLPW_FREQUENCIES.length; i ++) { for (let i = 1; i < c_LLPW_FREQUENCIES.length; i ++) {
CiderAudio.audioNodes.llpw[i-1].connect(CiderAudio.audioNodes.llpw[i]); CiderAudio.audioNodes.llpw[i-1].connect(CiderAudio.audioNodes.llpw[i]);
} }
@ -373,7 +373,7 @@ var CiderAudio = {
} }
else if (app.cfg.audio.maikiwiAudio.ciderPPE_value === 0.5) { else if (app.cfg.audio.maikiwiAudio.ciderPPE_value === 0.5) {
for (i = 0; i < LLPW_FREQUENCIES.length; i++) { for (let i = 0; i < LLPW_FREQUENCIES.length; i++) {
CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter();
CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking'; CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking';
CiderAudio.audioNodes.llpw[i].frequency.value = LLPW_FREQUENCIES[i]; CiderAudio.audioNodes.llpw[i].frequency.value = LLPW_FREQUENCIES[i];
@ -382,7 +382,7 @@ var CiderAudio = {
} }
for (i = 1; i < LLPW_FREQUENCIES.length; i ++) { for (let i = 1; i < LLPW_FREQUENCIES.length; i ++) {
CiderAudio.audioNodes.llpw[i-1].connect(CiderAudio.audioNodes.llpw[i]); CiderAudio.audioNodes.llpw[i-1].connect(CiderAudio.audioNodes.llpw[i]);
} }
@ -408,7 +408,7 @@ var CiderAudio = {
let VIBRANTBASSQ = app.cfg.audio.maikiwiAudio.vibrantBass.Q; let VIBRANTBASSQ = app.cfg.audio.maikiwiAudio.vibrantBass.Q;
CiderAudio.audioNodes.vibrantbassNode = [] CiderAudio.audioNodes.vibrantbassNode = []
for (i = 0; i < VIBRANTBASSBANDS.length; i++) { for (let i = 0; i < VIBRANTBASSBANDS.length; i++) {
CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter();
CiderAudio.audioNodes.vibrantbassNode[i].type = 'peaking'; // 'peaking'; CiderAudio.audioNodes.vibrantbassNode[i].type = 'peaking'; // 'peaking';
CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i]; CiderAudio.audioNodes.vibrantbassNode[i].frequency.value = VIBRANTBASSBANDS[i];
@ -416,7 +416,7 @@ var CiderAudio = {
CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * app.cfg.audio.maikiwiAudio.vibrantBass.multiplier; CiderAudio.audioNodes.vibrantbassNode[i].gain.value = VIBRANTBASSGAIN[i] * app.cfg.audio.maikiwiAudio.vibrantBass.multiplier;
} }
for (i = 1; i < VIBRANTBASSBANDS.length; i ++) { for (let i = 1; i < VIBRANTBASSBANDS.length; i ++) {
CiderAudio.audioNodes.vibrantbassNode[i-1].connect(CiderAudio.audioNodes.vibrantbassNode[i]); CiderAudio.audioNodes.vibrantbassNode[i-1].connect(CiderAudio.audioNodes.vibrantbassNode[i]);
} }
@ -683,7 +683,7 @@ var CiderAudio = {
CiderAudio.audioNodes.audioBands = []; CiderAudio.audioNodes.audioBands = [];
for (i = 0; i < BANDS.length; i++) { for (let i = 0; i < BANDS.length; i++) {
CiderAudio.audioNodes.audioBands[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.audioBands[i] = CiderAudio.context.createBiquadFilter();
CiderAudio.audioNodes.audioBands[i].type = 'peaking'; // 'peaking'; CiderAudio.audioNodes.audioBands[i].type = 'peaking'; // 'peaking';
CiderAudio.audioNodes.audioBands[i].frequency.value = BANDS[i]; CiderAudio.audioNodes.audioBands[i].frequency.value = BANDS[i];
@ -694,14 +694,11 @@ var CiderAudio = {
// Dynamic-ish loading // Dynamic-ish loading
CiderAudio.hierarchical_loading(); CiderAudio.hierarchical_loading();
for (i = 1; i < BANDS.length; i ++) { for (let i = 1; i < BANDS.length; i ++) {
CiderAudio.audioNodes.audioBands[i-1].connect(CiderAudio.audioNodes.audioBands[i]); CiderAudio.audioNodes.audioBands[i-1].connect(CiderAudio.audioNodes.audioBands[i]);
} }
CiderAudio.audioNodes.audioBands[BANDS.length-1].connect(CiderAudio.context.destination); CiderAudio.audioNodes.audioBands[BANDS.length-1].connect(CiderAudio.context.destination);
} }
} }
if (app.cfg.advanced.AudioContext){ export {CiderAudio}
CiderAudio.init()
}

File diff suppressed because it is too large Load diff

2637
src/renderer/less/bootstrap-vue.min.css vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -174,4 +174,9 @@
flex: 0 0 auto; flex: 0 0 auto;
} }
} }
.collection-page {
.top-fab {
bottom:96px;
}
}
} }

View file

@ -305,19 +305,19 @@
.menu-panel-body { .menu-panel-body {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
background: rgb(38 38 38); background: #262626;
position: relative; position: relative;
min-width: 200px; min-width: 200px;
box-shadow: var(--ciderShadow-Generic); box-shadow: var(--ciderShadow-Generic);
border-radius: var(--mediaItemRadius); border-radius: var(--mediaItemRadius);
overflow: hidden; overflow: hidden;
font-size: 14px; font-size: 13px;
.menu-option { .menu-option {
text-align: left; text-align: left;
display: flex; display: flex;
width: 100%; width: 100%;
padding: 10px 16px; padding: 9px 16px;
appearance: none; appearance: none;
border: 0px; border: 0px;
font: inherit; font: inherit;

11
src/renderer/lib/bootstrap-vue.min.js vendored Normal file

File diff suppressed because one or more lines are too long

181
src/renderer/lib/resonance-audio.min.js vendored Normal file

File diff suppressed because one or more lines are too long

30
src/renderer/main/app.js Normal file
View file

@ -0,0 +1,30 @@
import { app } from "./vueapp.js"
import {CiderCache} from './cidercache.js'
import {CiderFrontAPI} from './ciderfrontapi.js'
import {simulateGamepad} from './gamepad.js'
import {CiderAudio} from '../audio/audio.js'
import {Events} from './events.js'
import { wsapi } from "./wsapi_interop.js"
import { MusicKitTools } from "./musickittools.js"
// Define window objects
window.app = app
window.MusicKitTools = MusicKitTools
window.CiderAudio = CiderAudio
window.CiderCache = CiderCache
window.CiderFrontAPI = CiderFrontAPI
window.wsapi = wsapi
// Mount Vue to #app
app.$mount("#app")
// Init CiderAudio
if (app.cfg.advanced.AudioContext){
CiderAudio.init()
}
// Import gamepad support
app.simulateGamepad = simulateGamepad
Events.InitEvents()

View file

@ -0,0 +1,24 @@
const CiderCache = {
async getCache(file) {
let cache = await ipcRenderer.sendSync("get-cache", file)
if (isJson(cache)) {
cache = JSON.parse(cache)
if (Object.keys(cache).length === 0) {
cache = false
}
} else {
cache = false
}
return cache
},
async putCache(file, data) {
console.log(`Caching ${file}`)
ipcRenderer.invoke("put-cache", {
file: file,
data: JSON.stringify(data)
})
return true
}
}
export {CiderCache}

View file

@ -0,0 +1,16 @@
const CiderFrontAPI = {
Objects: {
MenuEntry: function () {
this.id = ""
this.name = ""
this.onClick = () => {
}
}
},
AddMenuEntry(entry) {
app.pluginMenuEntries.push(entry)
app.pluginInstalled = true
}
}
export {CiderFrontAPI}

View file

@ -0,0 +1,74 @@
const Events = {
InitEvents() {
const app = window.app
// Key binds
document.addEventListener('keydown', function (e) {
if (e.keyCode === 70 && e.ctrlKey) {
app.$refs.searchInput.focus()
app.$refs.searchInput.select()
}
});
// add event listener for when window.location.hash changes
window.addEventListener("hashchange", function () {
app.appRoute(window.location.hash)
});
// Key bind to unjam MusicKit in case it fails: CTRL+F10
document.addEventListener('keydown', function (event) {
if (event.ctrlKey && event.keyCode == 121) {
try {
app.mk._services.mediaItemPlayback._currentPlayer.stop()
} catch (e) {
}
try {
app.mk._services.mediaItemPlayback._currentPlayer.destroy()
} catch (e) {
}
}
});
window.addEventListener("mouseup", (e) => {
if (e.button === 3) {
e.preventDefault()
app.navigateBack()
} else if (e.button === 4) {
e.preventDefault()
app.navigateForward()
}
});
document.addEventListener('keydown', function (event) {
if (event.ctrlKey && event.keyCode == 122) {
try {
ipcRenderer.send('detachDT', '')
} catch (e) {
}
}
});
// Hang Timer
app.hangtimer = setTimeout(() => {
if (confirm("Cider is not responding. Reload the app?")) {
window.location.reload()
}
}, 10000)
// Refresh Focus
function refreshFocus() {
if (document.hasFocus() == false) {
app.windowFocus(false)
} else {
app.windowFocus(true)
}
setTimeout(refreshFocus, 200);
}
app.getHTMLStyle()
refreshFocus();
}
}
export {Events}

View file

@ -0,0 +1,327 @@
function simulateGamepad () {
const app = window.app
app.chrome.showCursor = true
let cursorPos = [0, 0];
let intTabIndex = 0
const cursorSpeedPvt = 8
const cursorSize = 16
let scrollSpeed = 8
let buttonPressDelay = 500
let stickDeadZone = 0.2
let scrollGroup = null
let scrollGroupY = null
let elementFocusEnabled = true
let start;
let cursorSpeed = cursorSpeedPvt
let lastButtonPress = {
}
var sounds = {
Confirm: new Audio("./sounds/confirm.ogg"),
Menu: new Audio("./sounds/btn1.ogg"),
Hover: new Audio("./sounds/hover.ogg")
}
let element = document.elementFromPoint(0, 0)
let elementType = 0
function appLoop() {
var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
if (!gamepads) {
return;
}
var gp = gamepads[0];
// LEFT STICK
if (gp.axes[0] > stickDeadZone) {
cursorPos[0] += (gp.axes[0] * cursorSpeed)
} else if (gp.axes[0] < -stickDeadZone) {
cursorPos[0] += (gp.axes[0] * cursorSpeed)
}
if (gp.axes[1] > stickDeadZone) {
cursorPos[1] += (gp.axes[1] * cursorSpeed)
} else if (gp.axes[1] < -stickDeadZone) {
cursorPos[1] += (gp.axes[1] * cursorSpeed)
}
if (cursorPos[0] < cursorSize) {
cursorPos[0] = cursorSize
}
if (cursorPos[1] < cursorSize) {
cursorPos[1] = cursorSize
}
if (cursorPos[0] > window.innerWidth - cursorSize) {
cursorPos[0] = window.innerWidth - cursorSize
}
if (cursorPos[1] > window.innerHeight - cursorSize) {
cursorPos[1] = window.innerHeight - cursorSize
}
// RIGHT STICK.
if (scrollGroupY) {
if (gp.axes[3] > stickDeadZone) {
$(scrollGroupY).scrollTop($(scrollGroupY).scrollTop() + (gp.axes[3] * scrollSpeed))
elementFocusEnabled = false
} else if (gp.axes[3] < -stickDeadZone) {
$(scrollGroupY).scrollTop($(scrollGroupY).scrollTop() + (gp.axes[3] * scrollSpeed))
elementFocusEnabled = false
} else {
elementFocusEnabled = true
}
}
if (scrollGroup) {
if (gp.axes[2] > stickDeadZone) {
$(scrollGroup).scrollLeft($(scrollGroup).scrollLeft() + (gp.axes[2] * scrollSpeed))
elementFocusEnabled = false
} else if (gp.axes[2] < -stickDeadZone) {
$(scrollGroup).scrollLeft($(scrollGroup).scrollLeft() + (gp.axes[2] * scrollSpeed))
elementFocusEnabled = false
} else {
elementFocusEnabled = true
}
}
$(".cursor").css({
top: cursorPos[1] + "px",
left: cursorPos[0] + "px",
display: "block"
})
// A BUTTON
if (gp.buttons[0].pressed) {
if (!lastButtonPress["A"]) {
lastButtonPress["A"] = 0
}
if (Date.now() - lastButtonPress["A"] > buttonPressDelay) {
lastButtonPress["A"] = Date.now()
sounds.Confirm.play()
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("click"))
document.activeElement.dispatchEvent(new Event("controller-click"))
} else {
element.dispatchEvent(new Event("click"))
element.dispatchEvent(new Event("controller-click"))
}
}
}
// B BUTTON
if (gp.buttons[1].pressed) {
if (!lastButtonPress["B"]) {
lastButtonPress["B"] = 0
}
if (Date.now() - lastButtonPress["B"] > buttonPressDelay) {
lastButtonPress["B"] = Date.now()
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("contextmenu"))
setTimeout(() => {
if ($(".menu-option").length > 0) {
let bounds = $(".menu-option")[0].getBoundingClientRect()
cursorPos[0] = bounds.left + (bounds.width / 2)
cursorPos[1] = bounds.top + (bounds.height / 2)
}
}, 100)
} else {
element.dispatchEvent(new Event("contextmenu"))
}
}
}
// right bumper
if (gp.buttons[5].pressed) {
if (!lastButtonPress["RB"]) {
lastButtonPress["RB"] = 0
}
if (Date.now() - lastButtonPress["RB"] > buttonPressDelay) {
lastButtonPress["RB"] = Date.now()
app.navigateForward()
}
}
// left bumper
if (gp.buttons[4].pressed) {
if (!lastButtonPress["LB"]) {
lastButtonPress["LB"] = 0
}
if (Date.now() - lastButtonPress["LB"] > buttonPressDelay) {
lastButtonPress["LB"] = Date.now()
app.navigateBack()
}
}
// cursor hover
if (elementFocusEnabled) {
element = document.elementFromPoint(cursorPos[0], cursorPos[1])
}
if (element) {
let closest = element.closest("[tabindex], input, button, a")
// VERT SCROLL
let scrollGroupCloY = element.closest(`[scrollaxis="y"]`)
if (scrollGroupCloY) {
scrollGroupY = scrollGroupCloY
}
// HOZ SCROLL
let scrollGroupClo = element.closest(".v-hl-container")
if (scrollGroupClo) {
if (scrollGroupClo.classList.contains("v-hl-container")) {
scrollGroup = scrollGroupClo
scrollGroup.style["scroll-snap-type"] = "unset"
} else {
scrollGroup.style["scroll-snap-type"] = ""
scrollGroup = null
}
}
if (closest) {
elementType = 0
closest.focus()
} else {
if (closest) {
closest.blur()
}
elementType = 1
element.focus()
}
cursorSpeed = cursorSpeedPvt
if (!element.classList.contains("app-chrome")
&& !element.classList.contains("app-content")) {
cursorSpeed = cursorSpeedPvt
}
// console.log($._data($(element), "events"))
} else {
cursorSpeed = 12
}
// console.log(gp.axes[0], gp.axes[1])
start = requestAnimationFrame(appLoop);
}
// controller pairing
notyf.error("Press the button on your controller to pair it to Cider.")
window.addEventListener("gamepadconnected", function (e) {
console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.",
e.gamepad.index, e.gamepad.id,
e.gamepad.buttons.length, e.gamepad.axes.length);
notyf.success("Pairing successful!")
appLoop()
}, { once: true });
document.addEventListener("keydown", (e) => {
sounds.Confirm.currentTime = 0
sounds.Menu.currentTime = 0
sounds.Hover.currentTime = 0
let tabbable = $("[tabindex]")
console.log(e.key)
switch (e.key) {
default:
break;
case "ArrowLeft":
e.preventDefault()
cursorPos[0] -= cursorSpeed
break;
case "ArrowRight":
e.preventDefault()
cursorPos[0] += cursorSpeed
break;
case "ArrowUp":
e.preventDefault()
cursorPos[1] -= cursorSpeed
// sounds.Hover.play()
// if(intTabIndex <= 0) {
// intTabIndex = 0
// }else{
// intTabIndex--
// }
// $(tabbable[intTabIndex]).focus()
// $("#app-content").scrollTop($(document.activeElement).offset().top)
break;
case "ArrowDown":
e.preventDefault()
cursorPos[1] += cursorSpeed
// if(intTabIndex < tabbable.length) {
// intTabIndex++
// }else{
// intTabIndex = tabbable.length
// }
// $(tabbable[intTabIndex]).focus()
// $("#app-content").scrollTop($(document.activeElement).offset().top)
break;
case "c":
app.resetState()
break;
case "x":
// set cursorPos to the top right of the screen
// sounds.Menu.play()
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("contextmenu"))
} else {
element.dispatchEvent(new Event("contextmenu"))
}
e.preventDefault()
break;
case "z":
sounds.Confirm.play()
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("click"))
document.activeElement.dispatchEvent(new Event("controller-click"))
} else {
element.dispatchEvent(new Event("click"))
element.dispatchEvent(new Event("controller-click"))
}
e.preventDefault()
break;
}
$(".cursor").css({
top: cursorPos[1] + "px",
left: cursorPos[0] + "px"
})
function lerp(a, b, n) {
return (1 - n) * a + n * b
}
element = document.elementFromPoint(cursorPos[0], cursorPos[1])
if (element) {
let closest = element.closest("[tabindex], input, button, a")
if (closest) {
elementType = 0
closest.focus()
} else {
elementType = 1
element.focus()
}
}
console.log(element)
});
}
export {simulateGamepad}

View file

@ -0,0 +1,27 @@
const MusicKitTools = {
async v3Continuous (href, options = {}, reqOptions = {}) {
let returnData = []
async function sendReq(href, options) {
const response = await app.mk.api.v3.music(href, options)
returnData = returnData.concat(response.data.data)
if(response.data.next) {
await sendReq(response.data.next, options)
}
}
await sendReq(href, options)
return returnData
},
getHeader() {
return new Headers({
Authorization: 'Bearer ' + MusicKit.getInstance().developerToken,
Accept: 'application/json',
'Content-Type': 'application/json',
'Music-User-Token': '' + MusicKit.getInstance().musicUserToken
});
}
}
export { MusicKitTools }

4033
src/renderer/main/vueapp.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
const store = new Vuex.Store({
state: {
library: {
// songs: ipcRenderer.sendSync("get-library-songs"),
// albums: ipcRenderer.sendSync("get-library-albums"),
// recentlyAdded: ipcRenderer.sendSync("get-library-recentlyAdded"),
// playlists: ipcRenderer.sendSync("get-library-playlists")
},
artwork: {
playerLCD: ""
}
},
mutations: {
setLCDArtwork(state, artwork) {
state.artwork.playerLCD = artwork
}
}
})
export {store}

View file

@ -49,13 +49,13 @@ const wsapi = {
}, },
musickitApi(method, id, params, library = false) { musickitApi(method, id, params, library = false) {
if (library) { if (library) {
MusicKit.getInstance().api.library[method](id, params).then((results)=>{ MusicKit.getInstance().api.library[method](id, params).then((results)=>{
ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method) ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method)
}) })
} else { } else {
MusicKit.getInstance().api[method](id, params).then((results)=>{ MusicKit.getInstance().api[method](id, params).then((results)=>{
ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method) ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method)
}) })
} }
}, },
getPlaybackState () { getPlaybackState () {
@ -111,4 +111,6 @@ const wsapi = {
getmaxVolume() { getmaxVolume() {
ipcRenderer.send('wsapi-returnvolumeMax',JSON.stringify(app.cfg.audio.maxVolume)); ipcRenderer.send('wsapi-returnvolumeMax',JSON.stringify(app.cfg.audio.maxVolume));
} }
} }
export {wsapi}

View file

@ -4,6 +4,7 @@
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap");
@import url("less/bootstrap-vue.min.css");
@import url("less/ameframework.less"); @import url("less/ameframework.less");
@import url("less/codicon.css"); @import url("less/codicon.css");
@import url("less/bootstrap.less"); @import url("less/bootstrap.less");
@ -777,18 +778,26 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
font-weight: 400; font-weight: 400;
font-family: inherit; font-family: inherit;
font-size: 14px; font-size: 14px;
margin: 6px 0px; margin: 3px 0px;
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 6px; border-radius: 6px;
background: transparent; background: transparent;
color: #eee; color: #eee;
transition: transform .1s; transition: transform 0.1s;
text-align: left; text-align: left;
&.app-sidebar-item-playlist { &.app-sidebar-item-playlist {
-webkit-user-drag: element; -webkit-user-drag: element;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
.presentNotice {
align-self: center;
margin-left: 8px;
text-transform: uppercase;
font-size: 0.7em;
opacity: 0.6;
}
} }
} }
@ -1829,6 +1838,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
.no-animation {
animation: unset !important;
}
.fullscreen-view-container { .fullscreen-view-container {
position: absolute; position: absolute;
@ -1868,6 +1880,10 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
height: 50vh; height: 50vh;
} }
.bg-artwork-container {
display: block !important;
}
@media only screen and (max-width: 1121px) { @media only screen and (max-width: 1121px) {
.display--large { .display--large {
display: flex !important; display: flex !important;
@ -1970,13 +1986,10 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9); filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9);
} }
.no-animation {
animation: unset;
}
} }
} }
.lyrics-col { .lyrics-col {
height: 62vh; height: 62vh;
@ -2653,6 +2666,10 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
width: 200VH; width: 200VH;
height: 200VH; height: 200VH;
} }
.bg-artwork-container{
display: block !important;
}
} }
.lyric-body { .lyric-body {
@ -2661,22 +2678,15 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
overflow: hidden; overflow: hidden;
filter: drop-shadow(0px 4px 6px rgb(0 0 0 / 70%));
.lyric-line { .lyric-line {
pointer-events: none; pointer-events: none;
font-weight: 500; font-weight: 600;
font-size: 2em; font-size: 2em;
transform-origin: center; transform-origin: center;
animation: fsLyricIn var(--appleEase) .2s; animation: fsLyricIn var(--appleEase) .2s;
opacity: 0.9; opacity: 0.9;
text-shadow: -1px -1px 0 #000,
0 -1px 0 #000,
1px -1px 0 #000,
1px 0 0 #000,
1px 1px 0 #000,
0 1px 0 #000,
-1px 1px 0 #000,
-1px 0 0 #000;
&:not(.active) { &:not(.active) {
display: none; display: none;
@ -2962,6 +2972,10 @@ body.no-gpu {
.bg-artwork-container { .bg-artwork-container {
display: none; display: none;
animation: none !important;
.bg-artwork{
animation: none !important;
}
} }
#navigation-bar { #navigation-bar {
@ -3002,6 +3016,10 @@ body.no-gpu {
.drawertransition-leave-to { .drawertransition-leave-to {
right: -300px; right: -300px;
} }
.lyric-line:hover::after {
display: none;
}
} }
.qrimg { .qrimg {

View file

@ -6,8 +6,9 @@
v-if="drawer.open && drawer.panel == 'lyrics' && lyrics && lyrics != [] && lyrics.length > 0"> v-if="drawer.open && drawer.panel == 'lyrics' && lyrics && lyrics != [] && lyrics.length > 0">
<div class="bgArtworkMaterial"> <div class="bgArtworkMaterial">
<div class="bg-artwork-container"> <div class="bg-artwork-container">
<img class="bg-artwork a" :src="$store.state.artwork.playerLCD"> <img v-if="(cfg.visual.bg_artwork_rotation && animateBackground)" class="bg-artwork a" :src="$store.state.artwork.playerLCD">
<img class="bg-artwork b" :src="$store.state.artwork.playerLCD"> <img v-if="(cfg.visual.bg_artwork_rotation && animateBackground)" class="bg-artwork b" :src="$store.state.artwork.playerLCD">
<img v-if="!(cfg.visual.bg_artwork_rotation && animateBackground)" class="bg-artwork no-animation" :src="$store.state.artwork.playerLCD">
</div> </div>
</div> </div>
<lyrics-view v-if="drawer.panel == 'lyrics'" :time="lyriccurrenttime" :lyrics="lyrics" <lyrics-view v-if="drawer.panel == 'lyrics'" :time="lyriccurrenttime" :lyrics="lyrics"

View file

@ -96,7 +96,8 @@
<button class="volume-button--small volume" @click="muteButtonPressed()" <button class="volume-button--small volume" @click="muteButtonPressed()"
:class="{'active': this.cfg.audio.volume == 0}"></button> :class="{'active': this.cfg.audio.volume == 0}"></button>
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume" <input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"> v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
v-b-tooltip.hover :title="`${(Math.log10(mk.volume) * 20).toFixed(2)} dB`">
</div> </div>
<div class="app-chrome-item generic"> <div class="app-chrome-item generic">
<button class="playback-button--small miniplayer" <button class="playback-button--small miniplayer"

View file

@ -112,7 +112,8 @@
<button class="volume-button--small volume" @click="muteButtonPressed()" <button class="volume-button--small volume" @click="muteButtonPressed()"
:class="{'active': this.cfg.audio.volume == 0}"></button> :class="{'active': this.cfg.audio.volume == 0}"></button>
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume" <input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"> v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()"
v-b-tooltip.hover :title="`${(Math.log10(mk.volume) * 20).toFixed(2)} dB`">
</div> </div>
<div class="app-chrome-item generic"> <div class="app-chrome-item generic">
<button class="playback-button--small miniplayer" <button class="playback-button--small miniplayer"

View file

@ -55,6 +55,13 @@
<sidebar-library-item :name="$root.getLz('term.podcasts')" svg-icon="./assets/feather/mic.svg" <sidebar-library-item :name="$root.getLz('term.podcasts')" svg-icon="./assets/feather/mic.svg"
page="podcasts"> page="podcasts">
</sidebar-library-item> </sidebar-library-item>
<template v-if="getPlaylistFolderChildren('p.applemusic').length != 0">
<div class="app-sidebar-header-text" @contextmenu="playlistHeaderContextMenu">
{{ $root.getLz('term.appleMusic') }} {{ $root.getLz('term.playlists') }}
</div>
<sidebar-playlist v-for="item in getPlaylistFolderChildren('p.applemusic')" :item="item">
</sidebar-playlist>
</template>
<div class="app-sidebar-header-text" @contextmenu="playlistHeaderContextMenu"> <div class="app-sidebar-header-text" @contextmenu="playlistHeaderContextMenu">
{{ $root.getLz('term.playlists') }} {{ $root.getLz('term.playlists') }}
</div> </div>
@ -164,7 +171,8 @@
<input type="range" class="" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" <input type="range" class="" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0"
:max="cfg.audio.maxVolume" :max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" v-model="mk.volume" v-if="typeof mk.volume != 'undefined'"
@change="checkMuteChange()"> @change="checkMuteChange()"
v-b-tooltip.hover :title="`${(Math.log10(mk.volume) * 20).toFixed(2)} dB`">
</div> </div>
</div> </div>
</div> </div>

View file

@ -12,7 +12,7 @@
<div class="icon"><%- include("../svg/plus.svg") %></div> <div class="icon"><%- include("../svg/plus.svg") %></div>
<div class="name">{{app.getLz('action.createPlaylist')}}</div> <div class="name">{{app.getLz('action.createPlaylist')}}</div>
</button> </button>
<sidebar-playlist :playlist-select="playlistSelect" v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')" :item="item"> <sidebar-playlist :playlist-select="playlistSelect" :relate-media-items="relateItems" v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')" :item="item">
</sidebar-playlist> </sidebar-playlist>
</div> </div>
<div class="modal-search"> <div class="modal-search">
@ -42,6 +42,7 @@
searchQuery: "", searchQuery: "",
focused: "", focused: "",
app: this.$root, app: this.$root,
relateItems: []
} }
}, },
props: { props: {
@ -51,6 +52,7 @@
} }
}, },
mounted() { mounted() {
this.relateItems = [this.$root.selectedMediaItems[0].id]
this.search() this.search()
this.$refs.searchInput.focus() this.$refs.searchInput.focus()
this.$refs.searchInput.addEventListener('keydown', (e) => { this.$refs.searchInput.addEventListener('keydown', (e) => {

View file

@ -59,7 +59,29 @@
} }
this.hls.attachMedia(this.$refs.video); this.hls.attachMedia(this.$refs.video);
this.hls.loadSource(this.video); this.hls.loadSource(this.video);
this.hls.loadLevel = parseInt(app.cfg.visual.animated_artwork_qualityLevel || 1); let u = this.hls;
var quality = app.cfg.visual.animated_artwork_qualityLevel;
setTimeout(() => {
let levelsnum = u.levels.map((level)=>{return level.width})
if (levelsnum.length > 0) {
let qualities = []
let qualities2 = []
for (let i = 0; i < levelsnum.length; i++) {
if (qualities2.indexOf(levelsnum[i]) == -1) {
qualities.push({level: i, quality: levelsnum[i]})
qualities2.push(levelsnum[i])
}
}
let actualnum = Math.floor(qualities[qualities.length -1 ].level * (quality / 4))
if (quality != 0 ){
quality = qualities[Math.min(actualnum,qualities.length -1 )].level
}
if (quality == 4 ){
quality = qualities[qualities.length - 1].level
}
}
this.hls.loadLevel = parseInt( quality || 1);},200)
} }
}) })
} }

View file

@ -237,15 +237,15 @@
"import": { "import": {
"icon": "./assets/feather/share.svg", "icon": "./assets/feather/share.svg",
"name": app.getLz('action.import'), "name": app.getLz('action.import'),
"action": function () { action: () => {
this.importPreset() notyf.error("Not implemented yet")
} }
}, },
"export": { "export": {
"icon": "./assets/feather/share.svg", "icon": "./assets/feather/share.svg",
"name": app.getLz('action.export'), "name": app.getLz('action.export'),
"action": function () { action: () => {
this.exportPreset() notyf.error("Not implemented yet")
} }
}, },
} }

View file

@ -3,9 +3,9 @@
<div class="background"> <div class="background">
<div class="bgArtworkMaterial"> <div class="bgArtworkMaterial">
<div class="bg-artwork-container"> <div class="bg-artwork-container">
<img v-if="(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork a" :src="image.replace('600x600','30x30') ?? ''"> <img v-if="(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork a" :src="(image ?? '').replace('{w}','30').replace('{h}','30')">
<img v-if="(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork b" :src="image.replace('600x600','30x30') ?? ''"> <img v-if="(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork b" :src="(image ?? '').replace('{w}','30').replace('{h}','30')">
<img v-if="!(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork no-animation" :src="image.replace('600x600','30x30') ?? ''"> <img v-if="!(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork no-animation" :src="(image ?? '').replace('{w}','30').replace('{h}','30')">
</div> </div>
</div> </div>
</div> </div>
@ -14,7 +14,7 @@
<div class="artwork" @click="app.fullscreen(false)"> <div class="artwork" @click="app.fullscreen(false)">
<mediaitem-artwork <mediaitem-artwork
:size="600" :size="600"
:url="image ?? ''" :url="(image ?? '').replace('{w}','600').replace('{h}','600') "
></mediaitem-artwork> ></mediaitem-artwork>
</div> </div>
<div class="controls-parents"> <div class="controls-parents">
@ -81,7 +81,8 @@
<div class="input-container"> <div class="input-container">
<button class="volume-button--small volume" @click="app.muteButtonPressed()" :class="{'active': app.cfg.audio.volume == 0}"></button> <button class="volume-button--small volume" @click="app.muteButtonPressed()" :class="{'active': app.cfg.audio.volume == 0}"></button>
<input type="range" class="slider" @wheel="app.volumeWheel" :step="app.cfg.audio.volumeStep" min="0" :max="app.cfg.audio.maxVolume" v-model="app.mk.volume" <input type="range" class="slider" @wheel="app.volumeWheel" :step="app.cfg.audio.volumeStep" min="0" :max="app.cfg.audio.maxVolume" v-model="app.mk.volume"
v-if="typeof app.mk.volume != 'undefined'" @change="app.checkMuteChange()"> v-if="typeof app.mk.volume != 'undefined'" @change="app.checkMuteChange()"
v-b-tooltip.hover :title="`${(Math.log10(app.mk.volume) * 20).toFixed(2)} dB`">
</div> </div>
</div> </div>
</div> </div>

View file

@ -2,13 +2,13 @@
<vue-horizontal> <vue-horizontal>
<template v-if="browsesp"> <template v-if="browsesp">
<mediaitem-mvview-sp <mediaitem-mvview-sp
:item="item ? (item.attributes.kind ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []" :item="item ? ((item.attributes?.kind != null || item.attributes?.type == 'editorial-elements') ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
:imagesize="imagesize" :imagesize="imagesize"
:badge="item.attributes" v-for="item in items"></mediaitem-mvview-sp> :badge="item.attributes" v-for="item in items"></mediaitem-mvview-sp>
</template> </template>
<template v-else> <template v-else>
<mediaitem-square :kind="kind" size="600" <mediaitem-square :kind="kind" size="600"
:item="item ? (item.attributes.kind ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []" :item="item ? ((item.attributes?.kind != null || item.type == 'editorial-elements') ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
:imagesize="imagesize" :imagesize="imagesize"
v-for="item in items"></mediaitem-square> v-for="item in items"></mediaitem-square>
</template> </template>
@ -43,6 +43,8 @@
app: this.$root, app: this.$root,
} }
}, },
methods: {} // mounted(){
// console.log('hes',this.items)
// }
}); });
</script> </script>

View file

@ -36,7 +36,7 @@
</div> </div>
<div class="info-rect" :class="{'info-rect-card': kind == 'card'}" :style="{'--bgartwork': getArtworkUrl(size, true)}"> <div class="info-rect" :class="{'info-rect-card': kind == 'card'}" :style="{'--bgartwork': getArtworkUrl(size, true)}">
<div class="title" v-if="item.attributes.artistNames == null || kind!= 'card'" @click='app.routeView(item)'> <div class="title" v-if="item.attributes.artistNames == null || kind!= 'card'" @click='app.routeView(item)'>
<div class="item-navigate text-overflow-elipsis">{{ item.attributes.name }}</div> <div class="item-navigate text-overflow-elipsis">{{ item.attributes?.name ?? (item.relationships?.contents?.data[0]?.attributes?.name ?? '') }}</div>
<div class="explicit-icon" v-if="item.attributes && item.attributes.contentRating == 'explicit'" style= "background-image: url(./assets/explicit.svg);height: 12px;width: 12px;filter: contrast(0);background-repeat: no-repeat;margin-top: 2.63px;margin-left: 4px;"></div> <div class="explicit-icon" v-if="item.attributes && item.attributes.contentRating == 'explicit'" style= "background-image: url(./assets/explicit.svg);height: 12px;width: 12px;filter: contrast(0);background-repeat: no-repeat;margin-top: 2.63px;margin-left: 4px;"></div>
</div> </div>
<div class="subtitle item-navigate text-overflow-elipsis" @click="getSubtitleNavigation()" <div class="subtitle item-navigate text-overflow-elipsis" @click="getSubtitleNavigation()"
@ -76,8 +76,8 @@
isVisible: false, isVisible: false,
addedToLibrary: false, addedToLibrary: false,
guid: this.uuidv4(), guid: this.uuidv4(),
noplay: ["apple-curators"], noplay: ["apple-curators", "editorial-elements"],
nomenu: ["artists", "stations", "apple-curators"], nomenu: ["artists", "stations", "apple-curators", "editorial-elements"],
app: this.$root, app: this.$root,
badges: this.$root.socialBadges.badgeMap, badges: this.$root.socialBadges.badgeMap,
itemBadges: [], itemBadges: [],
@ -149,7 +149,7 @@
}, },
async getBadges() { async getBadges() {
const self = this const self = this
const id = (this.item.attributes.playParams ? this.item.attributes.playParams.id : null) || this.item.id const id = ((this.item.attributes?.playParams ?? false) ? this.item.attributes?.playParams.id : null) || this.item.id
if (id && this.badges[id]) { if (id && this.badges[id]) {
let friends = this.badges[id] let friends = this.badges[id]
if (friends) { if (friends) {
@ -215,7 +215,7 @@
} }
switch (this.kind) { switch (this.kind) {
case "385": case "385":
artwork = this.item.attributes.editorialArtwork.subscriptionHero.url artwork = this.item.attributes.editorialArtwork?.subscriptionHero?.url ?? (this.item.attributes.artwork?.url ?? (this.item.relationships?.contents?.data[0]?.attributes?.editorialArtwork?.subscriptionHero?.url ?? ''))
break; break;
} }
if(!includeUrl) { if(!includeUrl) {
@ -225,7 +225,12 @@
} }
}, },
getClasses() { getClasses() {
let type = this.item.type let type = []
try{
type = this.item.type
}catch(e) {console.log('sd',this.item)}
if (this.kind != "") { if (this.kind != "") {
type = this.kind type = this.kind
} }
@ -233,6 +238,7 @@
default: default:
return [] return []
break; break;
case "editorial-elements":
case "card": case "card":
return ["mediaitem-card"] return ["mediaitem-card"]
break; break;

View file

@ -11,7 +11,7 @@
</div> </div>
<div class="menu-header-body" v-if="Object.keys(content.headerItems).length != 0"> <div class="menu-header-body" v-if="Object.keys(content.headerItems).length != 0">
<template v-for="item in content.headerItems"> <template v-for="item in content.headerItems">
<button class="menu-option-header" :class="getClasses(item)" :title="item.name" <button class="menu-option-header" :class="getClasses(item)" v-b-tooltip.hover :title="item.name"
v-if="canDisplay(item)" :style="getItemStyle(item)" @click="action(item)"> v-if="canDisplay(item)" :style="getItemStyle(item)" @click="action(item)">
<div class="sidebar-icon" style="margin: 0;" v-if="item.icon"> <div class="sidebar-icon" style="margin: 0;" v-if="item.icon">
<div class="svg-icon" :style="{'--url': 'url(' + item.icon + ')'}"></div> <div class="svg-icon" :style="{'--url': 'url(' + item.icon + ')'}"></div>

View file

@ -155,6 +155,9 @@
beforeDestroy() { beforeDestroy() {
window.removeEventListener('keyup', this.onEscapeKeyUp) window.removeEventListener('keyup', this.onEscapeKeyUp)
}, },
mounted() {
app.pinMiniPlayer(true)
},
methods: { methods: {
onEscapeKeyUp(event) { onEscapeKeyUp(event) {
if (event.which === 27) { if (event.which === 27) {

View file

@ -9,13 +9,14 @@
:href="item.href" :href="item.href"
@click='clickEvent()'> @click='clickEvent()'>
<template v-if="!renaming"> <template v-if="!renaming">
<div class="sidebar-icon" v-html="icon"></div> {{ item.attributes.name }} <div class="sidebar-icon" :key="item.id" v-html="icon"></div> {{ item.attributes.name }}
<small class="presentNotice" v-if="hasRelatedMediaItems">(Track present)</small>
</template> </template>
<input type="text" v-model="item.attributes.name" class="pl-rename-field" @blur="rename()" @keydown.enter="rename()" v-else> <input type="text" v-model="item.attributes.name" class="pl-rename-field" @blur="rename()" @keydown.enter="rename()" v-else>
</button> </button>
<div class="folder-body" v-if="item.type === 'library-playlist-folders' && folderOpened"> <div class="folder-body" v-if="item.type === 'library-playlist-folders' && folderOpened">
<template v-if="children.length != 0"> <template v-if="children.length != 0">
<sidebar-playlist v-for="item in children" :playlist-select="playlistSelect" :item="item" :key="item.id"></sidebar-playlist> <sidebar-playlist v-for="item in children" :relate-media-items="relateMediaItems" :playlist-select="playlistSelect" :item="item" :key="item.id"></sidebar-playlist>
</template> </template>
<template v-else> <template v-else>
<div class="spinner"></div> <div class="spinner"></div>
@ -35,6 +36,13 @@
playlistSelect: { playlistSelect: {
type: Function, type: Function,
required: false required: false
},
relateMediaItems: {
type: Array,
required: false,
default () {
return []
}
} }
}, },
data: function () { data: function () {
@ -43,7 +51,8 @@
children: [], children: [],
playlistRoot: "p.playlistsroot", playlistRoot: "p.playlistsroot",
renaming: false, renaming: false,
icon: "" icon: "",
hasRelatedMediaItems: false
} }
}, },
async mounted() { async mounted() {
@ -52,6 +61,12 @@
} else { } else {
this.icon = await this.$root.getSvgIcon("./assets/feather/folder.svg") this.icon = await this.$root.getSvgIcon("./assets/feather/folder.svg")
} }
let playlistMap = this.$root.playlists.trackMapping
if(this.relateMediaItems.length != 0) {
if(playlistMap[this.relateMediaItems[0]].includes(this.item.id)) {
this.hasRelatedMediaItems = true
}
}
}, },
methods: { methods: {
clickEvent() { clickEvent() {

View file

@ -2,39 +2,44 @@
<html lang="en"> <html lang="en">
<head> <head>
<link rel="preconnect" href="https://amp-api.music.apple.com/" crossorigin/> <link rel="preconnect" href="https://amp-api.music.apple.com/" crossorigin />
<link rel="preconnect" href="https://api.music.apple.com/" crossorigin/> <link rel="preconnect" href="https://api.music.apple.com/" crossorigin />
<link rel="preconnect" href="https://is1-ssl.mzstatic.com/" crossorigin/> <link rel="preconnect" href="https://is1-ssl.mzstatic.com/" crossorigin />
<link rel="preconnect" href="https://is2-ssl.mzstatic.com/" crossorigin/> <link rel="preconnect" href="https://is2-ssl.mzstatic.com/" crossorigin />
<link rel="preconnect" href="https://is3-ssl.mzstatic.com/" crossorigin/> <link rel="preconnect" href="https://is3-ssl.mzstatic.com/" crossorigin />
<link rel="preconnect" href="https://is4-ssl.mzstatic.com/" crossorigin/> <link rel="preconnect" href="https://is4-ssl.mzstatic.com/" crossorigin />
<link rel="preconnect" href="https://is5-ssl.mzstatic.com/" crossorigin/> <link rel="preconnect" href="https://is5-ssl.mzstatic.com/" crossorigin />
<link rel="preconnect" href="https://play.itunes.apple.com/" crossorigin/> <link rel="preconnect" href="https://play.itunes.apple.com/" crossorigin />
<link rel="preconnect" href="https://aod-ssl.itunes.apple.com/" crossorigin/> <link rel="preconnect" href="https://aod-ssl.itunes.apple.com/" crossorigin />
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Cider</title> <title>Cider</title>
<link rel="stylesheet/less" type="text/css" href="style.less"/> <link rel="stylesheet/less" type="text/css" href="style.less" />
<link rel="stylesheet/less" type="text/css" id="userTheme" href="themes/default.less"/> <link rel="stylesheet/less" type="text/css" id="userTheme" href="themes/default.less" />
<script src="./js/less.js"></script> <script src="./lib/less.js"></script>
<script src="<%- (env.dev ? "./js/vue.js" : "./js/vue.dev.js") %>"></script> <script src="<%- (env.dev ? " ./lib/vue.js" : "./lib/vue.dev.js" ) %>"></script>
<script src="./js/vue-horizontal.js"></script> <script src="./lib/vue-horizontal.js"></script>
<script src="./js/smoothscroll.js"></script> <script src="./lib/smoothscroll.js"></script>
<script src="./js/vuex.min.js"></script> <script src="./lib/vuex.min.js"></script>
<script src="./js/sortable.min.js"></script> <script src="./lib/sortable.min.js"></script>
<script src="./js/vue-observe-visibility.min.js"></script> <script src="./lib/vue-observe-visibility.min.js"></script>
<script src="./js/vuedraggable.umd.min.js"></script> <script src="./lib/vuedraggable.umd.min.js"></script>
<link rel="manifest" href="./manifest.json?v=2"> <link rel="manifest" href="./manifest.json?v=2">
<script src="https://js-cdn.music.apple.com/hls.js/2.141.0/hls.js/hls.js"></script> <script src="https://js-cdn.music.apple.com/hls.js/2.141.0/hls.js/hls.js"></script>
<script src="hlscider.js"></script> <script src="hlscider.js"></script>
<script src="./js/jquery-3.2.1.slim.min.js"></script> <script src="./lib/jquery-3.2.1.slim.min.js"></script>
<script src="./js/popper.min.js"></script> <script src="./lib/popper.min.js"></script>
<script src="./js/bootstrap.min.js"></script> <script src="./lib/bootstrap-vue.min.js"></script>
<script src="./js/bootbox.min.js"></script> <script src="./lib/bootstrap.min.js"></script>
<script src="./js/notyf.min.js"></script> <script src="./lib/bootbox.min.js"></script>
<script src="./js/showdown.min.js"></script> <script src="./lib/notyf.min.js"></script>
<script src="./js/velocity.min.js"></script> <script src="./lib/showdown.min.js"></script>
<script src="./lib/velocity.min.js"></script>
<script src="./lib/fast-plural-rules.js"></script>
<script src="./lib/resonance-audio.min.js"></script>
<script type="module" src="./main/app.js"></script>
<style> <style>
#LOADER { #LOADER {
position: fixed; position: fixed;
@ -48,54 +53,55 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
#LOADER > svg { #LOADER>svg {
width: 128px; width: 128px;
} }
</style> </style>
</head> </head>
<body oncontextmenu="return false;" loading="1" platform="<%= env.platform %>"> <body oncontextmenu="return false;" loading="1" platform="<%= env.platform %>">
<div id="LOADER"> <div id="LOADER">
<%- include("../assets/cider-round.svg") %> <%- include("../assets/cider-round.svg") %>
</div> </div>
<div id="app" :class="getAppClasses()"> <div id="app" :class="getAppClasses()">
<transition name="fsModeSwitch"> <transition name="fsModeSwitch">
<div id="app-main" v-show="appMode == 'player'"> <div id="app-main" v-show="appMode == 'player'">
<%- include('app/chrome-top'); %> <%- include('app/chrome-top'); %>
<%- include('app/app-navigation'); %> <%- include('app/app-navigation'); %>
<%- include('app/chrome-bottom'); %> <%- include('app/chrome-bottom'); %>
</div> </div>
</transition> </transition>
<transition name="fsModeSwitch"> <transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'fullscreen'"> <div class="fullscreen-view-container" v-if="appMode == 'fullscreen'">
<fullscreen-view :image="currentArtUrlRaw" :time="lyriccurrenttime" <fullscreen-view :image="currentArtUrlRaw" :time="lyriccurrenttime" :lyrics="lyrics"
:lyrics="lyrics" :richlyrics="richlyrics"></fullscreen-view> :richlyrics="richlyrics"></fullscreen-view>
</div> </div>
</transition> </transition>
<transition name="fsModeSwitch"> <transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'mini'"> <div class="fullscreen-view-container" v-if="appMode == 'mini'">
<mini-view :image="currentArtUrlRaw" :time="lyriccurrenttime" <mini-view :image="currentArtUrlRaw" :time="lyriccurrenttime" :lyrics="lyrics" :richlyrics="richlyrics">
:lyrics="lyrics" :richlyrics="richlyrics"></mini-view> </mini-view>
</div> </div>
</transition> </transition>
<%- include('app/panels'); %> <%- include('app/panels'); %>
<div class="cursor" v-if="chrome.showCursor"></div> <div class="cursor" v-if="chrome.showCursor"></div>
</div> </div>
<% for(var i=0; i < Object.keys(env.components).length ; i++) {%> <% for(var i=0; i < Object.keys(env.components).length ; i++) {%>
<%- include(env.components[i]); %> <%- include(env.components[i]); %>
<% } %> <% } %>
<script type="text/x-template" <script async src="https://js-cdn.music.apple.com/musickit/v2/amp/musickit.js"></script>
id="am-musiccovershelf"> <script src="index.js?v=1"></script>
<script type="text/x-template" id="am-musiccovershelf">
<h1>{{ component.attributes.title.stringForDisplay }}</h1> <h1>{{ component.attributes.title.stringForDisplay }}</h1>
</script> </script>
<!-- Sidebar Item --> <!-- Sidebar Item -->
<script type="text/x-template" <script type="text/x-template" id="sidebar-library-item">
id="sidebar-library-item">
<button class="app-sidebar-item" <button class="app-sidebar-item"
:class="$parent.getSidebarItemClass(page)" @click="$root.appRoute(page)"> :class="$parent.getSidebarItemClass(page)" @click="$root.appRoute(page)">
<div class="sidebar-icon" v-html="svgIconData" v-if="svgIconData != ''"></div> <div class="sidebar-icon" v-html="svgIconData" v-if="svgIconData != ''"></div>
@ -103,22 +109,6 @@
</button> </button>
</script> </script>
<script
src="musickit.js?v=1"></script>
<script>
if (typeof MusicKit == 'undefined') {
document.write(unescape("%3Cscript src='https://js-cdn.music.apple.com/musickit/v2/amp/musickit.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
<script src="./js/fast-plural-rules.js"></script>
<script
src="index.js?v=1"></script>
<script
src="https://cdn.jsdelivr.net/npm/resonance-audio/build/resonance-audio.min.js"></script>
<script
src="/audio/audio.js?v=1"></script>
<script
src="./js/WSAPI_Interop.js"></script>
</body> </body>
</html> </html>

View file

@ -12,6 +12,7 @@
{{$root.getLz('term.rightsReserved')}}</p> {{$root.getLz('term.rightsReserved')}}</p>
<hr> <hr>
<h3>{{$root.getLz('term.sponsor')}}</h3> <h3>{{$root.getLz('term.sponsor')}}</h3>
<button onclick="window.open('https://github.com/sponsors/ciderapp')" class="md-btn sponsorBtn"><img src="./assets/github.svg"/>GitHub Sponsors</button>
<button onclick="window.open('https://ko-fi.com/cryptofyre')" class="md-btn sponsorBtn"><img src="./assets/ko_fi.svg"/>Ko-fi</button> <button onclick="window.open('https://ko-fi.com/cryptofyre')" class="md-btn sponsorBtn"><img src="./assets/ko_fi.svg"/>Ko-fi</button>
<button onclick="window.open('https://opencollective.com/ciderapp')" class="md-btn sponsorBtn"><img src="./assets/open_collective.svg"/>Open Collective</button> <button onclick="window.open('https://opencollective.com/ciderapp')" class="md-btn sponsorBtn"><img src="./assets/open_collective.svg"/>Open Collective</button>
<h3>{{$root.getLz('term.socials')}}</h3> <h3>{{$root.getLz('term.socials')}}</h3>

View file

@ -21,7 +21,7 @@
:video-priority="true" :video-priority="true"
:url="(data.attributes != null && data.attributes.artwork != null) ? data.attributes.artwork.url : ((data.relationships != null && data.relationships.tracks.data.length > 0 && data.relationships.tracks.data[0].attributes != null) ? ((data.relationships.tracks.data[0].attributes.artwork != null)? data.relationships.tracks.data[0].attributes.artwork.url : ''):'')" :url="(data.attributes != null && data.attributes.artwork != null) ? data.attributes.artwork.url : ((data.relationships != null && data.relationships.tracks.data.length > 0 && data.relationships.tracks.data[0].attributes != null) ? ((data.relationships.tracks.data[0].attributes.artwork != null)? data.relationships.tracks.data[0].attributes.artwork.url : ''):'')"
:video="(data.attributes != null && data.attributes.editorialVideo != null) ? (data.attributes.editorialVideo.motionDetailSquare ? data.attributes.editorialVideo.motionDetailSquare.video : (data.attributes.editorialVideo.motionSquareVideo1x1 ? data.attributes.editorialVideo.motionSquareVideo1x1.video : '')) : '' " :video="(data.attributes != null && data.attributes.editorialVideo != null) ? (data.attributes.editorialVideo.motionDetailSquare ? data.attributes.editorialVideo.motionDetailSquare.video : (data.attributes.editorialVideo.motionSquareVideo1x1 ? data.attributes.editorialVideo.motionSquareVideo1x1.video : '')) : '' "
size="260" size="500"
></mediaitem-artwork> ></mediaitem-artwork>
</div> </div>
</div> </div>

View file

@ -119,7 +119,7 @@
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.audioNormalization.description')}}</small> <small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.audioNormalization.description')}}</small>
</div> </div>
<div class="md-option-segment md-option-segment_auto"> <div class="md-option-segment md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.audio.normalization" v-on:change="toggleNormalization" :disabled="app.cfg.audio.equalizer.vibrantBass !== 0 || app.cfg.audio.maikiwiAudio.spatial === true" switch/> <input type="checkbox" v-model="app.cfg.audio.normalization" v-on:change="toggleNormalization" :disabled="app.cfg.audio.equalizer.vibrantBass !== 0 || app.cfg.audio.maikiwiAudio.spatial === true || app.cfg.audio.maikiwiAudio.ciderPPE === true" switch/>
</div> </div>
</div> </div>
</div> </div>
@ -731,7 +731,7 @@
{{$root.getLz('settings.option.general.updateCider')}} {{$root.getLz('settings.option.general.updateCider')}}
</div> </div>
<div class="md-option-segment md-option-segment_auto"> <div class="md-option-segment md-option-segment_auto">
<button class="md-btn" @click="app.checkForUpdate()"> <button class="md-btn" id='settings.option.general.updateCider.check' @click="app.checkForUpdate()">
{{$root.getLz('term.check')}} {{$root.getLz('term.check')}}
</button> </button>
</div> </div>
@ -752,6 +752,15 @@
</select> </select>
</div> </div>
</div> </div>
<div class="md-option-line update-check" v-if="app.platform === 'win32'">
<div class="md-option-segment">
{{$root.getLz('settings.option.visual.transparent')}}<br>
<small>({{$root.getLz('settings.option.visual.transparent.description')}})</small>
</div>
<div class="md-option-segment md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.visual.transparent" switch @change="promptForRelaunch()"/>
</div>
</div>
</div> </div>
<div style="opacity: 0.5; pointer-events: none"> <div style="opacity: 0.5; pointer-events: none">
<div class="md-option-header"> <div class="md-option-header">
@ -909,6 +918,13 @@
updateFields[i].title = "Not available on this type of build"; updateFields[i].title = "Not available on this type of build";
} }
} }
},
promptForRelaunch(){
bootbox.confirm(app.getLz('action.relaunch.confirm'), function (result) {
if (result) {
ipcRenderer.send('relaunchApp','');
}
});
} }
} }
}) })

View file

@ -10,6 +10,7 @@
v-model="$root.cfg.visual.theme"> v-model="$root.cfg.visual.theme">
<option value="default.less">{{$root.getLz('settings.option.visual.theme.default')}}</option> <option value="default.less">{{$root.getLz('settings.option.visual.theme.default')}}</option>
<option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}</option> <option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}</option>
<option value="sweetener.less">Sweetener</option>
<option v-for="theme in themes" :value="theme.file">{{ theme.name }}</option> <option v-for="theme in themes" :value="theme.file">{{ theme.name }}</option>
</select> </select>
</div> </div>