diff --git a/.circleci/config.yml b/.circleci/config.yml
index e02b98b2..1ac3ccfd 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -30,6 +30,9 @@ jobs:
key: yarn-packages-{{ checksum "cider.lock" }}
paths:
- ~/.cache/yarn
+ - run:
+ name: Clear Yarn Cache
+ command: yarn cache clean
- run:
name: TypeScript Compile
command: yarn build
@@ -80,6 +83,12 @@ jobs:
sudo dpkg --add-architecture i386
sudo apt-get update -y
sudo apt-get install -y wine32
+ - run:
+ name: Reinstall proper rust node module
+ command: |
+ cd ./node_modules/cider_utils
+ yarn run prebuild-downloads --platform=win32 --verbose
+ cd ../..
- run:
name: Generate Builds (Windows)
command: yarn electron-builder -w --x64 -p never
@@ -105,6 +114,12 @@ jobs:
sudo dpkg --add-architecture i386
sudo apt-get update -y
sudo apt-get install -y wine32
+ - run:
+ name: Reinstall proper rust node module
+ command: |
+ cd ./node_modules/cider_utils
+ yarn run prebuild-downloads --platform=win32 --verbose
+ cd ../..
- run:
name: Generate Builds (Winget)
command: yarn electron-builder --win -c winget.json -p never
@@ -147,6 +162,7 @@ jobs:
- run:
name: Publish Release
command: |
+ echo "Creating release for Cider v${APP_VERSION} on the ${CIRCLE_BRANCH} branch."
gh release create "v${APP_VERSION}" --title "Cider Version ${APP_VERSION} (${CIRCLE_BRANCH})" --generate-notes -R ciderapp/cider-releases ~/Cider/dist/artifacts/*.deb ~/Cider/dist/artifacts/*.AppImage ~/Cider/dist/artifacts/*.snap ~/Cider/dist/artifacts/*.exe ~/Cider/dist/artifacts/*.yml ~/Cider/dist/artifacts/*.blockmap
# Orchestrate our job run sequence
diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml
index a9a2fa0f..f47f1d37 100644
--- a/.github/workflows/build-macos.yml
+++ b/.github/workflows/build-macos.yml
@@ -94,6 +94,9 @@ jobs:
yarn install
cp resources/verror-types node_modules/@types/verror/index.d.ts
cp resources/macPackager.js node_modules/app-builder-lib/out/macPackager.js
+ rm -r node_modules/pouchdb-node/node_modules/leveldown
+ rm -r node_modules/pouchdb-adapter-leveldb/node_modules/leveldown
+ rm -r /node_modules/leveldown/node_modules/node-gyp-build || true
yarn dist:universalNotWorking -p never
# - name: Perform CodeQL Analysis
# uses: github/codeql-action/analyze@v1
diff --git a/.gitignore b/.gitignore
index e6413018..fc8bf102 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ dist
build
.flatpak*
yarn-cache
+src/renderer/style.css
# Misc
.idea
@@ -328,3 +329,5 @@ savedconfig/cider-config.json
savedconfig/config.json
savedconfig/session.json
savedconfig/window-state.json
+src/main/base/sample.json
+
diff --git a/README.md b/README.md
index ee3b5fd1..b3e20bbd 100644
--- a/README.md
+++ b/README.md
@@ -21,10 +21,10 @@
* [Documentation](https://docs.cider.sh)
* [Request Feature](https://github.com/ciderapp/Cider/discussions/new?category=feature-request)
* [Report Bug](https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug&template=bug_report.md&title=%5BBUG%5D+)
-* [**View The Releases**](https://github.com/ciderapp/Cider/releases/latest)
+* [**View The Releases**](https://github.com/ciderapp/cider-releases/releases/latest)
### Install Sources
-[](https://github.com/ciderapp/cider/releases/latest)
+[](https://github.com/ciderapp/cider-releases/releases/latest)
[](https://www.microsoft.com/store/apps/9P21XJ9D9G66)
diff --git a/package.json b/package.json
index 5ca5c12b..9926ed56 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,8 @@
"homepage": "https://cider.sh/",
"buildResources": "resources",
"scripts": {
- "build": "tsc",
+ "build": "tsc && yarn compile-less",
+ "compile-less": "lessc ./src/renderer/style.less ./src/renderer/style.css",
"watch": "tsc --watch",
"start": "run-script-os",
"start:win32": "yarn build && set ELECTRON_ENABLE_LOGGING=true && electron ./build/index.js --enable-accelerated-mjpeg-decode --enable-accelerated-video --disable-gpu-driver-bug-workarounds --ignore-gpu-blacklist --enable-native-gpu-memory-buffers",
@@ -39,10 +40,13 @@
"dependencies": {
"@sentry/electron": "^3.0.7",
"@sentry/integrations": "^6.19.6",
+ "@types/pouchdb": "^6.4.0",
+ "@types/pouchdb-node": "^6.1.4",
"adm-zip": "0.4.10",
- "airtunes2": "git+https://github.com/ciderapp/node_airtunes2",
+ "airtunes2": "git+https://github.com/ciderapp/node_airtunes2.git",
"castv2-client": "^1.2.0",
"chokidar": "^3.5.3",
+ "cider_utils": "git+https://github.com/ciderapp/cider_utils.git",
"discord-auto-rpc": "^1.0.16",
"dns-js": "git+https://github.com/ciderapp/node-dns-js.git",
"ejs": "^3.1.6",
@@ -57,16 +61,22 @@
"jimp": "^0.16.1",
"jsonc": "^2.0.0",
"lastfmapi": "^0.1.1",
+ "level": "^8.0.0",
+ "leveldown": "^6.1.1",
"mdns-js": "git+https://github.com/ciderapp/node-mdns-js.git",
"mpris-service": "^2.1.2",
- "music-metadata": "^7.12.3",
+ "music-metadata": "^7.12.4",
"node-gyp": "^9.0.0",
"node-ssdp": "^4.0.1",
+ "pouchdb-adapter-leveldb": "^7.3.0",
+ "pouchdb-node": "^7.3.0",
+ "pouchdb-upsert": "^2.2.0",
"qrcode": "^1.5.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"run-script-os": "^1.1.6",
"source-map-support": "^0.5.21",
+ "ts-md5": "^1.2.11",
"v8-compile-cache": "^2.3.0",
"wallpaper": "5.0.1",
"ws": "^8.5.0",
@@ -83,6 +93,7 @@
"electron-builder": "^23.0.3",
"electron-builder-notarize-pkg": "^1.2.0",
"electron-webpack": "^2.8.2",
+ "less": "^4.1.3",
"musickit-typescript": "^1.2.4",
"typescript": "^4.6.4",
"vue-devtools": "^5.1.4",
@@ -111,9 +122,9 @@
}
],
"build": {
- "electronVersion": "18.3.3",
+ "electronVersion": "18.3.5",
"electronDownload": {
- "version": "18.3.3+wvcus",
+ "version": "18.3.5+wvcus",
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
},
"appId": "cider",
diff --git a/resources/afterPack.js b/resources/afterPack.js
index dd9eda0d..8e3ff50f 100644
--- a/resources/afterPack.js
+++ b/resources/afterPack.js
@@ -24,9 +24,10 @@ exports.default = function(context) {
// execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac',{stdio: 'inherit'})
// if (fs.existsSync('dist/mac-arm64'))
// execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac-arm64 -z',{stdio: 'inherit'})
- // if (fs.existsSync('dist/mac-x64'))
- // execSync('python3 -m castlabs_evs.vmp -n sign-pkg dist/mac-x64',{stdio: 'inherit'})
+
+ if (fs.existsSync('dist/mac-x64') || fs.existsSync('dist/mac-universal--x64') )
+ execSync('cd ./node_modules/cider_utils; yarn run prebuild-downloads --platform=darwin --arch=arm64 --verbose; cd ../..',{stdio: 'inherit'})
// console.log('VMP signing complete')
-}
\ No newline at end of file
+}
diff --git a/resources/version.sh b/resources/version.sh
index 2d174625..deb492ca 100755
--- a/resources/version.sh
+++ b/resources/version.sh
@@ -3,7 +3,6 @@
LATEST_SHA=$(curl -s https://api.github.com/repos/ciderapp/Cider/branches/stable | grep sha | cut -d '"' -f 4 | sed 's/v//' | xargs)
COMMITSINCESTABLE=$(git rev-list $LATEST_SHA..HEAD --count)
CURRENT_VERSION=$(node -p -e "require('./package.json').version")
-CIRCLE_BRANCH="main"
if [[ $CIRCLE_BRANCH == "main" && $COMMITSINCESTABLE -gt 0 ]]; then
NEW_VERSION="${CURRENT_VERSION}-beta.${COMMITSINCESTABLE}"
else
diff --git a/src/i18n/README.md b/src/i18n/README.md
index cd00b4c0..cf5f1de4 100644
--- a/src/i18n/README.md
+++ b/src/i18n/README.md
@@ -423,10 +423,10 @@ Update 24/05/2022 20:30 UTC
Update 24/05/2022 21:15 UTC
-* `settings.option.general.updateCider`: Deleted for all language files
-* `settings.option.general.updateCider.branch`: Deleted for all language files
+* `settings.option.general.updateCider`: Deleted for all language files
+* `settings.option.general.updateCider.branch`: Deleted for all language files
* `settings.option.general.updateCider.branch.description`: Deleted for all language files
-* `settings.option.general.updateCider.branch.main`: Deleted for all language files
+* `settings.option.general.updateCider.branch.main`: Deleted for all language files
* `settings.option.general.updateCider.branch.develop`: Deleted for all language files
* `settings.notyf.updateCider.update-error`: Deleted for all language files
@@ -497,3 +497,27 @@ Update 14/06/2022 14:10 UTC
* `term.themeManaged`: Added to `en_US`
+Update 15/06/2022 20:00 UTC
+
+* `settings.notyf.connectivity.lastfmScrobble.connectError`: Added to `en_US`
+* `settings.notyf.connectivity.lastfmScrobble.connectSuccess`: Added to `en_US`
+* `settings.notyf.connectivity.lastfmScrobble.connecting`: Added to `en_US`
+
+Update 19/06/2022 12:00 UTC
+
+* `settings.option.connectivity.lastfmScrobble.filterLoop.description`: Added to `en_US`
+
+Update 21/06/2022 20:39 UTC
+
+* `term.showSearch`: Added to `en_US`
+* `term.hideSearch`: Added to `en_US`
+
+Update 23/06/2022 04:00 UTC
+
+* `settings.option.connectivity.lastfmScrobble.filterTypes`: Added to `en_US`
+
+
+Update 03/07/2022 20:00 UTC
+
+* `term.plugins`: Added to `en_US`
+* `settings.header.visual.styles`: Added to `en_US`
\ No newline at end of file
diff --git a/src/i18n/de_DE.json b/src/i18n/de_DE.json
index 071d18eb..8f86cdf6 100644
--- a/src/i18n/de_DE.json
+++ b/src/i18n/de_DE.json
@@ -386,5 +386,18 @@
"term.track": {
"one": "Titel",
"other": "Titel"
- }
+ },
+ "settings.option.visual.customAccentColor": "Benutzerdefinierte Akzentfarbe",
+ "settings.option.visual.accentColor": "Akzentfarbe",
+ "settings.option.visual.purplePodcastPlaybackBar": "Lila Wiedergabeleiste für Podcasts",
+ "settings.option.visual.windowColor": "Fenstertönung Farbe",
+ "action.cut": "Ausschneiden",
+ "action.paste": "Einfügen",
+ "action.selectAll": "Alles auswählen",
+ "action.delete": "Löschen",
+ "home.syncFavorites": "Sync Favoriten",
+ "term.quit" : "Beenden",
+ "settings.option.connectivity.lastfmScrobble.filterLoop.description": "Verhindert, dass geloopte Titel gescrobbelt oder in der (Hört Gerade)-Liste auf Last.fm angezeigt werden",
+ "settings.option.connectivity.lastfmScrobble.filterTypes": "Medientypen filtern (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.manualToken": "Last.fm-Token manuell eingeben"
}
diff --git a/src/i18n/en_OWO.json b/src/i18n/en_OWO.json
index b46d1673..eb147a67 100644
--- a/src/i18n/en_OWO.json
+++ b/src/i18n/en_OWO.json
@@ -22,7 +22,6 @@
"term.logout": "Wogout",
"term.login": "Wog In",
"term.quickNav": "Quick Nyav",
- "term.cast": "Cast",
"term.about": "About",
"term.privateSession": "Pwivate Session",
"term.disablePrivateSession": "Disabwe Pwivate Session",
@@ -42,6 +41,7 @@
"term.artists": "Awtists",
"term.podcasts": "Podcasts",
"term.playlists": "Pwaywists",
+ "term.charts": "Chawts",
"term.playlist": "Pwaywist",
"term.newPlaylist": "Nyew Pwaywist",
"term.newPlaylistFolder": "Nyew Pwaywist Fowdew",
@@ -51,6 +51,7 @@
"term.navigateBack": "Nyavigate back",
"term.navigateForward": "Nyavigate fowwawd",
"term.play": "Pway",
+ "term.playpause": "Pway/Pause",
"term.pause": "Pause",
"term.stop": "Stop",
"term.previous": "Pwevious",
@@ -135,7 +136,7 @@
"term.amLive": "Appwe Music Wive",
"term.language": "Wanguage",
"term.funLanguages": "Fun",
- "term.noLyrics": "Woading... / Wywics nyot found./ Instwumentaw.",
+ "term.noLyrics": ">w< Sowwy Wowwy.. N-Nyo Wywics Avaiwabwe",
"term.copyright": "Copywight",
"term.rightsReserved": "Aww Wights Wesewved.",
"term.sponsor": "Sponsow this pwoject",
@@ -153,6 +154,7 @@
},
"term.videos": "Videos",
"term.menu": "Menyu",
+ "term.themeManaged": "Manyaged by a theme",
"term.check": "Check",
"term.aboutArtist": "About {{artistName}}",
"term.topResult": "Top Wesuwt",
@@ -192,6 +194,16 @@
"term.confirmLogout": "Awe you suwe you want to wogout?",
"term.creditDesignedBy": "Designyed by ${authorUsername}",
"term.discNumber": "Disc ${discNumber}",
+ "term.reload": "Wewoad Cidew ?",
+ "term.toggleprivate": "Toggwe Pwivate Session",
+ "term.webremote": "Web Wemote",
+ "term.cast": "Cast",
+ "term.cast2": "Cast to Devices",
+ "term.quit": "Quit",
+ "term.zoomin": "Zoom In",
+ "term.zoomout": "Zoom Out",
+ "term.zoomreset": "Weset Zoom",
+ "term.fullscreen": "Fuwwscween",
"home.title": "Home",
"home.recentlyPlayed": "Wecentwy Pwayed",
"home.recentlyAdded": "Wecentwy Added",
@@ -264,11 +276,7 @@
"action.export": "Expowt",
"action.showAlbum": "Show Compwete Awbum",
"action.tray.minimize": "Minyimize to Tway",
- "action.tray.quit": "Quit",
"action.tray.show": "Show Cidew",
- "action.tray.playpause": "Pway/Pause",
- "action.tray.next": "Nyext",
- "action.tray.previous": "Pwevious",
"action.tray.listento": "Wisten To:",
"action.update": "Update",
"action.install": "Instaww",
@@ -288,45 +296,26 @@
"action.createNew": "Cweate Nyew...",
"action.openArtworkInBrowser": "Open awtwowk in bwowsew",
"action.scrollToTop": "Scwoww to top",
- "menubar.options.about": "About",
- "menubar.options.settings": "Settings",
- "menubar.options.quit": "Quit Cidew",
- "menubar.options.view": "View ",
+ "menubar.options.view": "View",
"menubar.options.reload": "Wewoad",
"menubar.options.forcereload": "Fowce Wewoad",
"menubar.options.toggledevtools": "Toggwe Devewopew Toows",
"menubar.options.window": "Window",
"menubar.options.minimize": "Minyimize",
- "menubar.options.toggleprivate": "Toggwe Pwivate Session",
- "menubar.options.webremote": "Web Wemote",
- "menubar.options.audio": "Audio Settings",
"menubar.options.plugins": "Pwu-gins Menyu",
"menubar.options.controls": "Contwows",
- "menubar.options.next": "Nyext",
- "menubar.options.playpause": "Pway/Pause",
- "menubar.options.previous": "Pwevious",
"menubar.options.volumeup": "Vowume Up",
"menubar.options.volumedown": "Vowume Down",
- "menubar.options.browse": "Bwowse",
- "menubar.options.artists": "Awtists",
- "menubar.options.search": "Seawch",
- "menubar.options.albums": "Awbums",
- "menubar.options.cast": "Cast To Devices",
"menubar.options.account": "Account",
- "menubar.options.accountsettings": "Account Settings",
"menubar.options.signout": "Sign Out",
"menubar.options.support": "Suppowt",
- "menubar.options.discord": "Discowd",
- "menubar.options.github": "GitHub Wiki",
"menubar.options.report": "Wepowt a...",
"menubar.options.bug": "Bug",
"menubar.options.feature": "Featuwe Wequest",
"menubar.options.trans": "Twanswation Wepowt/Wequest",
"menubar.options.license": "View Wicense",
"menubar.options.conf": "Open Configuwation Fiwe in Editow",
- "menubar.options.listennow": "Wisten Nyow",
- "menubar.options.recentlyAdded": "Wecentwy Added",
- "menubar.options.songs": "Songs",
+ "menubar.options.zoom": "Zoom",
"settings.header.general": "Genyewaw",
"settings.header.general.description": "Adjust the genyewaw settings fow Cidew.",
"settings.option.general.language": "Wanguage",
@@ -346,11 +335,15 @@
"settings.option.general.customizeSidebar": "Customize Sidebaw Items",
"settings.option.general.customizeSidebar.customize": "Customize",
"settings.option.general.keybindings": "Keybindings",
+ "settings.option.general.keybindings.library": "Wibwawy",
+ "settings.option.general.keybindings.session": "Session",
+ "settings.option.general.keybindings.control": "Contwows",
+ "settings.option.general.keybindings.interface": "Intewface",
+ "settings.option.general.keybindings.advanced": "Advanced",
"settings.option.general.keybindings.pressCombination": "Pwess a combinyation of two keys to update keybind.",
"settings.option.general.keybindings.pressEscape": "Pwess Escape key to go back.",
"settings.notyf.general.keybindings.update.success": "Keybind updated successfuwwy",
"settings.prompt.general.keybindings.update.success": "Keybind updated successfuwwy. Pwess OK to wewaunch Cidew",
- "settings.option.general.keybindings.open": "Open",
"settings.option.general.themeUpdateNotification": "Automaticawwy check fow theme updates",
"settings.option.general.showLovedTracksInline": "Show wuvd twacks inwinye",
"settings.description.search": "Seawch",
diff --git a/src/i18n/en_PISS.json b/src/i18n/en_PISS.json
index 3047cac2..692c8ebc 100644
--- a/src/i18n/en_PISS.json
+++ b/src/i18n/en_PISS.json
@@ -103,7 +103,7 @@
"term.recentStations": "recent pisses",
"term.language": "piss around the world",
"term.funLanguages": "piss languages",
- "term.noLyrics": "piss…",
+ "term.noLyrics": "out of piss...",
"term.copyright": "copypiss",
"term.rightsReserved": "all piss reserved.",
"term.sponsor": "piss on Cider",
diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json
index c948da74..b01419a5 100644
--- a/src/i18n/en_US.json
+++ b/src/i18n/en_US.json
@@ -31,6 +31,12 @@
"term.miniplayer": "MiniPlayer",
"term.history": "History",
"term.search": "Search",
+ "term.scroll": "Scroll Mode",
+ "term.scroll.infinite": "Infinite",
+ "term.scroll.paged": "${songsPerPage} per page",
+ "term.live": "LIVE",
+ "term.showSearch": "Show search bar",
+ "term.hideSearch": "Hide search bar",
"term.library": "Library",
"term.listenNow": "Listen Now",
"term.browse": "Browse",
@@ -134,10 +140,9 @@
"term.recentStations": "Recent Stations",
"term.personalStations": "Personal Stations",
"term.amLive": "Apple Music Live",
- "term.live": "LIVE",
"term.language": "Language",
"term.funLanguages": "Fun",
- "term.noLyrics": "Loading... / Lyrics not found./ Instrumental.",
+ "term.noLyrics": "Instrumental Track / No Lyrics.",
"term.copyright": "Copyright",
"term.rightsReserved": "All Rights Reserved.",
"term.sponsor": "Sponsor this project",
@@ -179,8 +184,9 @@
"term.top": "Top",
"term.version": "Version",
"term.noVideos": "No videos found.",
- "term.plugin": "Plug-in",
- "term.pluginMenu": "Plug-in Menu",
+ "term.plugins": "Plugins",
+ "term.plugin": "Plugin",
+ "term.pluginMenu": "Plugins Menu",
"term.pluginMenu.none": "No interactive plugins",
"term.replay": "Replay",
"term.uniqueAlbums": "Unique Albums",
@@ -195,7 +201,7 @@
"term.confirmLogout": "Are you sure you want to logout?",
"term.creditDesignedBy": "Designed by ${authorUsername}",
"term.discNumber": "Disc ${discNumber}",
- "term.reload" : "Reload Cider ?",
+ "term.reload" : "Reload Cider?",
"term.toggleprivate" : "Toggle Private Session",
"term.webremote" : "Web Remote",
"term.cast" : "Cast",
@@ -205,8 +211,12 @@
"term.zoomout" : "Zoom Out",
"term.zoomreset" : "Reset Zoom",
"term.fullscreen" : "Fullscreen",
+ "term.nowPlaying": "Now Playing",
"home.syncFavorites": "Sync Favorites",
"home.syncFavorites.gettingArtists": "Getting Favorited Artists...",
+ "action.favorite": "Favorite",
+ "action.removeFavorite": "Remove Favorite",
+ "action.refresh": "Refresh",
"home.title": "Home",
"home.recentlyPlayed": "Recently Played",
"home.recentlyAdded": "Recently Added",
@@ -227,8 +237,6 @@
"podcast.episodes": "Episodes",
"podcast.playEpisode": "Play Episode",
"podcast.website": "Podcast Website",
- "action.favorite": "Favorite",
- "action.removeFavorite": "Remove Favorite",
"action.hideLibrary": "Hide Library",
"action.showLibrary": "Show Library",
"action.cut": "Cut",
@@ -237,6 +245,7 @@
"action.delete": "Delete",
"action.edit": "Edit",
"action.done": "Done",
+ "action.submit": "Submit",
"action.editTracklist": "Edit Tracklist",
"action.addToLibrary": "Add to Library",
"action.addToLibrary.success": "Added to Library",
@@ -411,9 +420,9 @@
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500A": "Moonlight Softcake",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500B": "Clafoutis aux Cerises",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500C": "Uji Matcha Mochi",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Enhances the perceived audio quality of AAC encoded audio by using a real-time algorithm that takes advantage of both psychoacoustic models of human hearing and AAC encoding characteristics.",
@@ -447,15 +456,10 @@
"settings.header.visual": "Visual",
"settings.header.visual.description": "Adjust the visual settings for Cider.",
"settings.option.visual.windowStyle": "Window Style",
- "settings.option.visual.customAccentColor": "Custom Accent Color",
- "settings.option.visual.accentColor": "Accent Color",
- "settings.option.visual.purplePodcastPlaybackBar": "Purple Playback Bar for Podcasts",
- "settings.option.visual.windowColor": "Window Tint Color",
"settings.option.visual.windowBackgroundStyle": "Window Background Style",
"settings.header.visual.windowBackgroundStyle.none": "None",
"settings.header.visual.windowBackgroundStyle.artwork": "Artwork",
"settings.header.visual.windowBackgroundStyle.image": "Image",
- "settings.header.visual.windowBackgroundStyle.color": "Color Tint",
"settings.option.visual.animatedArtwork": "Animated Artwork",
"settings.header.visual.animatedArtwork.always": "Always",
"settings.header.visual.animatedArtwork.limited": "Limited to pages and special entries",
@@ -481,6 +485,7 @@
"settings.prompt.visual.theme.github.URL": "Enter the URL of the theme you want to install",
"settings.prompt.visual.theme.uninstallTheme": "Are you sure you want to uninstall {{ theme }}?",
"settings.option.visual.theme.checkForUpdates": "Check for updates",
+ "settings.header.visual.styles": "Styles",
"settings.option.visual.theme.manageStyles": "Manage Styles",
"settings.option.visual.theme.uninstall": "Uninstall",
"settings.option.visual.theme.viewInfo": "View Info",
@@ -532,6 +537,12 @@
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable Last.fm Now Playing",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (Last.fm)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.filterLoop.description": "Prevent looped tracks from being scrobbled or displayed in the Now Playing list on Last.fm.",
+ "settings.option.connectivity.lastfmScrobble.filterTypes": "Filter Media Types (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.manualToken": "Enter Last.fm Token Manually",
+ "settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection Timed Out",
+ "settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.fm Connection Successful",
+ "settings.notyf.connectivity.lastfmScrobble.connecting": "Connecting to Last.fm...",
"settings.header.debug": "Debug",
"settings.option.debug.copy_log": "Copy logs to clipboard",
"settings.option.debug.openAppData": "Open Cider Folder",
@@ -543,11 +554,17 @@
"settings.option.experimental.unknownPlugin.description": "Allow installation of plugins from repos other than the Cider Plugin Repository",
"settings.option.experimental.compactUI": "Compact UI",
"settings.option.window.close_button_hide": "Close Button Should Hide the Application",
+ "settings.option.window.maxElementScale": "Maximum Element Scale",
"settings.option.experimental.inline_playlists": "Inline Playlists and Albums",
"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. Playlist cache build times can increase significantly.",
"settings.option.visual.transparent": "Transparent frame",
"settings.option.visual.transparent.description": "needs Theme Support, requires relaunch",
+ "settings.option.visual.customAccentColor": "Custom Accent Color",
+ "settings.option.visual.accentColor": "Accent Color",
+ "settings.option.visual.purplePodcastPlaybackBar": "Purple Playback Bar for Podcasts",
+ "settings.option.visual.windowColor": "Window Tint Color",
+ "settings.header.visual.windowBackgroundStyle.color": "Color Tint",
"settings.header.advanced": "Advanced",
"settings.header.connect": "Sync",
"settings.option.connect.link_account": "Enable Sync with Cider Connect",
@@ -624,4 +641,4 @@
"oobe.visual.suggestingThemes.community3": "Dracula",
"oobe.visual.suggestingThemes.community3.text": "The iconic Dracula color scheme.",
"oobe.amsignin.title": ""
-}
+}
\ No newline at end of file
diff --git a/src/i18n/fr_FR.json b/src/i18n/fr_FR.json
index 3886fd0e..720ee97c 100644
--- a/src/i18n/fr_FR.json
+++ b/src/i18n/fr_FR.json
@@ -22,7 +22,6 @@
"term.logout": "Déconnexion",
"term.login": "Connexion",
"term.quickNav": "Navigation rapide",
- "term.cast": "Diffuser",
"term.about": "À propos",
"term.privateSession": "Session privée",
"term.disablePrivateSession": "Désactiver la session privée",
@@ -33,7 +32,7 @@
"term.history": "Historique",
"term.search": "Recherche",
"term.library": "Bibliothèque",
- "term.listenNow": "Écoutez maintenant",
+ "term.listenNow": "Écouter",
"term.browse": "Explorer",
"term.radio": "Radio",
"term.recentlyAdded": "Ajouté récemment",
@@ -42,6 +41,7 @@
"term.artists": "Artistes",
"term.podcasts": "Podcasts",
"term.playlists": "Playlists",
+ "term.charts": "Classements",
"term.playlist": "Playlist",
"term.newPlaylist": "Nouvelle Playlist",
"term.newPlaylistFolder": "Nouveau dossier de playlist",
@@ -51,7 +51,9 @@
"term.navigateBack": "Naviguer en arrière",
"term.navigateForward": "Naviguer en avant",
"term.play": "Lecture",
+ "term.playpause": "Lecture/Pause",
"term.pause": "Pause",
+ "term.stop": "Stop",
"term.previous": "Précédent",
"term.next": "Suivant",
"term.shuffle": "Aléatoire",
@@ -130,6 +132,8 @@
"term.audioControls": "Contrôles du volume",
"term.clearAll": "Tout effacer",
"term.recentStations": "Stations récentes",
+ "term.personalStations": "Stations personnelles",
+ "term.amLive": "Apple Music Live",
"term.language": "Langue",
"term.funLanguages": "Amusant",
"term.noLyrics": "Chargement... / Paroles non trouvé./ Instrumental.",
@@ -150,6 +154,7 @@
},
"term.videos": "Vidéos",
"term.menu": "Menu",
+ "term.themeManaged": "Géré par un thème",
"term.check": "Vérifier",
"term.aboutArtist": "À propos de {{artistName}}",
"term.topResult": "Meilleurs résultats",
@@ -174,7 +179,7 @@
"term.version": "Version",
"term.noVideos": "Aucune vidéo trouvée.",
"term.plugin": "Plugin",
- "term.pluginMenu": "Plug-in Menu",
+ "term.pluginMenu": "Menu des plugins",
"term.pluginMenu.none": "Aucun plugin interactif",
"term.replay": "Replay",
"term.uniqueAlbums": "Albums uniques",
@@ -189,6 +194,16 @@
"term.confirmLogout": "Êtes-vous sûr de vouloir vous déconnecter ?",
"term.creditDesignedBy": "Conçu par ${authorUsername}",
"term.discNumber": "Disque ${discNumber}",
+ "term.reload": "Recharger Cider ?",
+ "term.toggleprivate": "Activer/désactiver la session privée",
+ "term.webremote": "Télécommande Web",
+ "term.cast": "Diffuser",
+ "term.cast2": "Diffuser sur des appareils",
+ "term.quit": "Quitter",
+ "term.zoomin": "Zoom avant",
+ "term.zoomout": "Zoom Out",
+ "term.zoomreset": "Zoom arrière",
+ "term.fullscreen": "Plein écran",
"home.title": "Accueil",
"home.recentlyPlayed": "Joué récemment",
"home.recentlyAdded": "Ajouté récemment",
@@ -209,9 +224,16 @@
"podcast.episodes": "Épisodes",
"podcast.playEpisode": "Lire l'épisode",
"podcast.website": "Site du podcast",
+ "action.hideLibrary": "Cacher la bibliothèque",
+ "action.showLibrary": "Afficher la bibliothèque",
+ "action.cut": "Couper",
+ "action.paste": "Coller",
+ "action.selectAll": "Tout sélectionner",
+ "action.delete": "Supprimer",
"action.edit": "Modifier",
"action.done": "Terminé",
- "action.editTracklist": "Edit Tracklist",
+ "action.submit": "Soumettre",
+ "action.editTracklist": "Modifier la liste de morceaux",
"action.addToLibrary": "Ajouter à la bibliothèque",
"action.addToLibrary.success": "Ajouté à la bibliothèque",
"action.addToLibrary.error": "Erreur lors de l'ajout à la bibliothèque",
@@ -275,45 +297,26 @@
"action.createNew": "Créer un nouveau...",
"action.openArtworkInBrowser": "Ouvrir la pochette d'album dans le navigateur",
"action.scrollToTop": "Défiler vers le haut",
- "menubar.options.about": "À propos",
- "menubar.options.settings": "Paramètres",
- "menubar.options.quit": "Quitter Cider",
"menubar.options.view": "Afficher ",
"menubar.options.reload": "Recharger",
"menubar.options.forcereload": "Rechargement forcé",
"menubar.options.toggledevtools": "Activer les outils de développement",
"menubar.options.window": "Fenêtre",
"menubar.options.minimize": "Minimiser",
- "menubar.options.toggleprivate": "Activer la session privée",
- "menubar.options.webremote": "Télécommande Web",
- "menubar.options.audio": "Paramètres audio",
"menubar.options.plugins": "Menu des plugins",
"menubar.options.controls": "Contrôles",
- "menubar.options.next": "Suivant",
- "menubar.options.playpause": "Lecture/Pause",
- "menubar.options.previous": "Précédent",
"menubar.options.volumeup": "Augmenter le volume",
"menubar.options.volumedown": "Réduire le volume",
- "menubar.options.browse": "Parcourir",
- "menubar.options.artists": "Artistes",
- "menubar.options.search": "Search",
- "menubar.options.albums": "Albums",
- "menubar.options.cast": "Diffuser sur des appareils",
"menubar.options.account": "Compte",
- "menubar.options.accountsettings": "Paramètres du compte",
"menubar.options.signout": "Se déconnecter",
"menubar.options.support": "Support",
- "menubar.options.discord": "Discord",
- "menubar.options.github": "Documentation GitHub",
"menubar.options.report": "Remonter un(e)...",
"menubar.options.bug": "Bug",
"menubar.options.feature": "Demande de fonctionnalité",
"menubar.options.trans": "Erreur/Demande de traduction",
"menubar.options.license": "Voir la license",
"menubar.options.conf": "Ouvrir le fichier de configuration dans l'éditeur",
- "menubar.options.listennow": "Écoutez maintenant",
- "menubar.options.recentlyAdded": "Ajouté récemment",
- "menubar.options.songs": "Musiques",
+ "menubar.options.zoom": "Zoom",
"settings.header.general": "Général",
"settings.header.general.description": "Ajuster les paramètres généraux de Cider.",
"settings.option.general.language": "Langue",
@@ -333,11 +336,15 @@
"settings.option.general.customizeSidebar": "Personnaliser les éléments de la barre latérale",
"settings.option.general.customizeSidebar.customize": "Personnalisez",
"settings.option.general.keybindings": "Raccourcis clavier",
+ "settings.option.general.keybindings.library": "Bibliothèque",
+ "settings.option.general.keybindings.session": "Session",
+ "settings.option.general.keybindings.control": "Contrôles",
+ "settings.option.general.keybindings.interface": "Interface",
+ "settings.option.general.keybindings.advanced": "Avancé",
"settings.option.general.keybindings.pressCombination": "Appuyez sur une combinaison de deux touches pour mettre à jour la combinaison de touches.",
"settings.option.general.keybindings.pressEscape": "Appuyez sur la touche Échap pour revenir en arrière.",
"settings.notyf.general.keybindings.update.success": "Le raccourci clavier a bien été mis à jour",
"settings.prompt.general.keybindings.update.success": "Le raccourci clavier a bien été mis à jour. Appuyez sur OK pour relancer Cider",
- "settings.option.general.keybindings.open": "Ouvrir",
"settings.option.general.themeUpdateNotification": "Vérifier automatiquement les mises à jour des thèmes",
"settings.option.general.showLovedTracksInline": "Afficher les pistes aimées en ligne",
"settings.description.search": "Rechercher",
@@ -360,6 +367,7 @@
"settings.header.audio": "Audio",
"settings.header.audio.description": "Ajuster les paramètres audio de Cider.",
"settings.option.audio.volumeStep": "Étape du volume",
+ "settings.option.audio.advanced": "Contrôle avancé du volume",
"settings.option.audio.maxVolume": "Volume maximum",
"settings.option.audio.changePlaybackRate": "Changer la vitesse de lecture",
"settings.option.audio.playbackRate": "Vitesse de lecture",
@@ -394,12 +402,21 @@
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Changes the mode of operation of the Atmosphere Realizer module.",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Naturelle (Standard)",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Naturelle (Plus)",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_1": "Fromage au sel de roche et thé mousseux",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_2": "Thé au lait Uji Matcha",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Macchiato au jasmin",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Thé au lait Hokkaido",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500A": "Gâteau au clair de lune",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Lait crème brûlée au sucre brun",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Chaleur des câlins",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Moteur de traitement psycho-acoustique Cider",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Améliore la qualité audio perçue de l'audio AAC 256 kbps en utilisant un algorithme en temps réel qui tire parti à la fois des modèles psychoacoustiques de l'audition humaine et des caractéristiques de codage AAC.",
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "Le moteur de traitement psycho-acoustique n'est pas compatible avec la spatialisation. Veuillez désactiver la spatialisation pour continuer.",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Force du moteur de traitement psycho-acoustique",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Modifie l'intensité du traitement effectué sur l'audio. (Un traitement agressif peut donner des résultats indésirables).",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standard",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "Adaptive",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "Ancien",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Agressive",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalisation du son",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normalise le volume maximal des pistes individuelles pour créer une expérience d'écoute plus uniforme.",
@@ -413,6 +430,9 @@
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Séparation",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimale",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffusé",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Encore élargi",
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "La spatialisation n'est pas compatible avec le moteur de traitement psycho-acoustique. Veuillez le désactiver pour continuer.",
"settings.option.audio.dbspl.display": "Affichage dB SPL",
"settings.option.audio.dbspl.description": "(Utilisateurs avancés uniquement) Affichez dB SPL au lieu de dBFS sur le curseur de volume.",
@@ -494,11 +514,19 @@
"settings.option.connectivity.discordRPC.hideTimestamp": "Cacher le temps restant sur le Discord Rich Presence",
"settings.option.connectivity.discordRPC.detailsFormat": "Format des détails",
"settings.option.connectivity.discordRPC.stateFormat": "Format de l'état",
+ "settings.option.connectivity.discordRPC.reload": "Recharger DiscordRPC",
+ "settings.option.connectivity.discordRPC.reconnectedToUser": "DiscordRPC Reconnecté à l'utilisateur: {{user}} ({{userid}})",
"settings.option.connectivity.lastfmScrobble": "Scrobble LastFM",
"settings.option.connectivity.lastfmScrobble.delay": "Délai de Scrobble LastFM (%)",
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Activer la lecture en cours sur LastFM",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Supprimer les artistes en vedette du titre de la chanson (LastFM)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrer les titres en boucle (LastFM)",
+ "settings.option.connectivity.lastfmScrobble.filterLoop.description": "Empêcher les pistes en boucle d'être scrobbulées ou affichées dans la liste En cours de lecture sur Last.fm.",
+ "settings.option.connectivity.lastfmScrobble.filterTypes": "Types de médias filtrés (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.manualToken": "Entrer manuellement le jeton Last.fm",
+ "settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection échouée",
+ "settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.fm Connection réussie",
+ "settings.notyf.connectivity.lastfmScrobble.connecting": "Connexion à Last.fm...",
"settings.header.debug": "Débogage",
"settings.option.debug.copy_log": "Copier les logs dans le presse-papiers",
"settings.option.debug.openAppData": "Ouvrir le dossier de Cider",
@@ -551,5 +579,44 @@
"share.platform.email": "Email",
"share.platform.songLink": "Copier avec song.link",
"share.platform.clipboard": "Copier le lien",
- "about.thanks": "Un grand merci à l'équipe de la Cider Collective et à tous nos contributeurs."
+ "about.thanks": "Un grand merci à l'équipe de la Cider Collective et à tous nos contributeurs.",
+ "oobe.yes": "Oui",
+ "oobe.no": "Non",
+ "oobe.next": "Suivant",
+ "oobe.previous": "Précédent",
+ "oobe.done": "Terminé",
+ "oobe.amupsell.title": "Avant de commencer",
+ "oobe.amupsell.text": "Cider nécessite un abonnement Apple Music actif et payant.\nCider ne fonctionne pas avec l'offre Apple Music Voice ou certains abonnements d'essai promotionnels. Si vous avez déjà un abonnement Apple Music qualifié, cliquez sur Suivant pour continuer.",
+ "oobe.amupsell.subscribeBtn": "S'abonner à Apple Music",
+ "oobe.amupsell.explainBtn": "Expliquer",
+ "oobe.amupsell.subscribeUrl": "https://apple.co/3MdqJVQ",
+ "oobe.amupsell.amWebUrl": "https://beta.music.apple.com/",
+ "oobe.amupsell.promoExplained": "Certains abonnements d'essai Apple Music promotionnels et non américains n'ont pas accès aux API du lecteur web Apple Music nécessaires au fonctionnement de Cider. Pour vérifier si votre version d'essai active fonctionnera avec Cider, rendez-vous à l'adresse suivante {{ amWebUrl }} connectez-vous et essayez de jouer de la musique. Si cela fonctionne, tant mieux ! Vous êtes prêt à utiliser Cider, mais si ce n'est pas le cas, abonnez-vous à Apple Music ici : {{ subscribeUrl }} ",
+ "oobe.intro.title": "Bienvenue sur Cider",
+ "oobe.intro.subtitle": "",
+ "oobe.intro.text": "Nous allons mettre en place quelques éléments pour que vous puissiez utiliser Cider comme vous le souhaitez. Vous pourrez toujours modifier ces paramètres plus tard.",
+ "oobe.general.title": "Général",
+ "oobe.general.subtitle": "",
+ "oobe.general.text": "",
+ "oobe.audio.title": "Audio",
+ "oobe.audio.subtitle": "",
+ "oobe.audio.text": "Cider dispose d'une pile audio personnalisée et conçue pour offrir une expérience audio riche et de haute qualité.\nIl comprend le moteur de traitement psycho-acoustique Cider, le réalisateur d'atmosphère et la spatialisation de l'audio.\nPour activer cette fonctionnalité, la fonction \"Fonctionnalité audio avancée\" doit être activée.\nL'activation de la fonctionnalité audio avancée vous donnera accès à ces améliorations dans les laboratoires audio de Cider, qui se trouvent dans les paramètres de l'application.",
+ "oobe.audio.advancedFunctionality": "",
+ "oobe.visual.title": "Visuel",
+ "oobe.visual.subtitle": "",
+ "oobe.visual.text": "",
+ "oobe.visual.layout.text": "Cider présente deux agencements de fenêtres différents.\nMaverick est une mise en page semblable à celle d'iTunes, avec le lecteur en haut de la fenêtre.\nMojave est une nouvelle agencement créé par la Cider Collective.\n\nVous pouvez modifier la mise en page à tout moment dans les paramètres.",
+ "oobe.visual.suggestingThemes": "Les thèmes sont un excellent moyen de personnaliser votre expérience. En voici quelques-uns que nous vous suggérons : ",
+ "oobe.visual.suggestingThemes.subtext": "(Ces thèmes seront téléchargés à partir de GitHub)",
+ "oobe.visual.suggestingThemes.default": "Cider",
+ "oobe.visual.suggestingThemes.default.text": "Le thème classique de Cider.",
+ "oobe.visual.suggestingThemes.dark": "Sombre",
+ "oobe.visual.suggestingThemes.dark.text": "L'obscurité.",
+ "oobe.visual.suggestingThemes.community1": "Groovy",
+ "oobe.visual.suggestingThemes.community1.text": "Un thème influencé par WinUI",
+ "oobe.visual.suggestingThemes.community2": "iTheme",
+ "oobe.visual.suggestingThemes.community2.text": "La disposition classique des gros fruits.",
+ "oobe.visual.suggestingThemes.community3": "Dracula",
+ "oobe.visual.suggestingThemes.community3.text": "L'emblématique combinaison de couleurs de Dracula.",
+ "oobe.amsignin.title": ""
}
diff --git a/src/i18n/hi_IN.json b/src/i18n/hi_IN.json
index d941bf5d..c09c0b66 100644
--- a/src/i18n/hi_IN.json
+++ b/src/i18n/hi_IN.json
@@ -101,7 +101,7 @@
"term.recentStations": "Recent Stations",
"term.language": "Language",
"term.funLanguages": "Fun",
- "term.noLyrics": "Loading... / Lyrics not found./ Instrumental.",
+ "term.noLyrics": "Instrumental Track / No Lyrics.",
"term.copyright": "Copyright",
"term.rightsReserved": "All Rights Reserved.",
"term.sponsor": "Sponsor this project",
diff --git a/src/i18n/in_ID.json b/src/i18n/in_ID.json
index 24acf48f..aa1e9a1c 100644
--- a/src/i18n/in_ID.json
+++ b/src/i18n/in_ID.json
@@ -10,6 +10,7 @@
"notification.updatingLibrarySongs": "Memperbarui Pustaka lagu...",
"notification.updatingLibraryAlbums": "Memperbarui Pustaka album...",
"notification.updatingLibraryArtists": "Memperbarui Pustaka artis...",
+ "term.variables": "Variabel",
"term.appleInc": "Apple Inc.",
"term.appleMusic": "Apple Music",
"term.applePodcasts": "Apple Podcasts",
@@ -20,9 +21,12 @@
"term.accountSettings": "Pengaturan Akun",
"term.logout": "Keluar",
"term.login": "Masuk",
+ "term.quickNav": "Navigasi Cepat",
"term.about": "Tentang",
"term.privateSession": "Sesi Pribadi",
+ "term.disablePrivateSession": "Matikan Mode Pribadi",
"term.queue": "Antrian",
+ "term.autoplay": "Pemutar Otomatis",
"term.lyrics": "Lirik",
"term.miniplayer": "Pemutar Kecil",
"term.history": "Riwayat",
@@ -37,18 +41,28 @@
"term.artists": "Artis",
"term.podcasts": "Podcasts",
"term.playlists": "Playlist",
+ "term.charts": "Tangga Lagu",
"term.playlist": "Playlist",
"term.newPlaylist": "Playlist Baru",
"term.newPlaylistFolder": "Folder Playlist Baru",
"term.createNewPlaylist": "Buat Playlist Baru",
"term.createNewPlaylistFolder": "Buat Folder Playlist Baru",
"term.deletePlaylist": "Yakin ingin menghapus playlist ini?",
+ "term.navigateBack": "Navigasi kembali",
+ "term.navigateForward": "Navigasi kedepan",
"term.play": "Mainkan",
+ "term.playpause": "Mainkan/Jeda",
"term.pause": "Jeda",
+ "term.stop": "Berhenti",
"term.previous": "Sebelumnya",
"term.next": "Selanjutnya",
"term.shuffle": "Acak",
+ "term.enableShuffle": "Nyalakan pemutaran acak",
+ "term.disableShuffle": "Matikan pemutaran acak",
"term.repeat": "Ulangi",
+ "term.enableRepeatOne": "Aktifkan ulangi sekali",
+ "term.disableRepeatOne": "Matikan ulangi sekali",
+ "term.disableRepeat": "Matikan ulangi",
"term.volume": "Volume",
"term.mute": "Bisu",
"term.unmute": "Bunyikan",
@@ -70,6 +84,7 @@
"term.viewAs": "Lihat Sebagai",
"term.viewAs.coverArt": "Cover Art",
"term.viewAs.list": "Daftar",
+ "term.dynamic": "Dinamis",
"term.size": "Ukuran",
"term.size.normal": "Normal",
"term.size.compact": "Kompak",
@@ -117,6 +132,9 @@
"term.audioControls": "Kontrol Volume",
"term.clearAll": "Bersihkan Semua",
"term.recentStations": "Stasiun Terbaru",
+ "term.personalStations": "Stasiun Pribadi",
+ "term.amLive": "Apple Music Live",
+ "term.live": "LIVE",
"term.language": "Bahasa",
"term.funLanguages": "Senang-senang",
"term.noLyrics": "Memuat... / Lirik tidak ditermukan./ Instrumental.",
@@ -137,6 +155,7 @@
},
"term.videos": "Video",
"term.menu": "Menu",
+ "term.themeManaged": "Diatur oleh tema",
"term.check": "Cek",
"term.aboutArtist": "Tentang {{artistName}}",
"term.topResult": "Hasil Teratas",
@@ -175,6 +194,19 @@
"term.topGenres": "Genre Teratas",
"term.confirmLogout": "Apakah Anda yakin ingin keluar??",
"term.creditDesignedBy": "Dirancang oleh ${authorUsername}",
+ "term.discNumber": "Kaset ${discNumber}",
+ "term.reload" : "Muat ulang Cider?",
+ "term.toggleprivate" : "Nyalakan Sesi Pribadi",
+ "term.webremote" : "Remot Web",
+ "term.cast" : "Transmisi",
+ "term.cast2" : "Transmisikan ke Perangkat",
+ "term.quit" : "Keluar",
+ "term.zoomin" : "Perbesar",
+ "term.zoomout" : "Perkecil",
+ "term.zoomreset" : "Atur Ulang",
+ "term.fullscreen" : "Layar Penuh",
+ "home.syncFavorites": "Sinkronkan Favorit",
+ "home.syncFavorites.gettingArtists": "Mendapatkan artis favorit",
"home.title": "Beranda",
"home.recentlyPlayed": "Baru Dimainkan",
"home.recentlyAdded": "Baru Ditambahkan",
@@ -187,14 +219,25 @@
"error.connectionError": "Terjadi masalah saat menyambungkan ke Apple Music.",
"error.noResults": "Tidak ada hasil.",
"error.noResults.description": "Coba pencarian baru.",
- "podcast.followOnCider": "Ikuti Di Cider",
- "podcast.followedOnCider": "Mengikuti Di Cider",
- "podcast.subscribeOnItunes": "Langganan Di iTunes",
- "podcast.subscribedOnItunes": "Berlangganan Di iTunes",
+ "podcast.followOnCider": "Ikuti di Cider",
+ "podcast.followedOnCider": "Mengikuti di Cider",
+ "podcast.subscribeOnItunes": "Langganan di iTunes",
+ "podcast.subscribedOnItunes": "Telah Berlangganan di iTunes",
"podcast.itunesStore": "iTunes Store",
"podcast.episodes": "Episode",
"podcast.playEpisode": "Mainkan Episode",
"podcast.website": "Website Podcast",
+ "action.favorite": "Favorit",
+ "action.removeFavorite": "Hapus Favorit",
+ "action.hideLibrary": "Sembunyikan Pustaka",
+ "action.showLibrary": "Tampilkan Pustaka",
+ "action.cut": "Cut",
+ "action.paste": "Paste",
+ "action.selectAll": "Pilih Semua",
+ "action.delete": "Hapus",
+ "action.edit": "Ubah",
+ "action.done": "Selesai",
+ "action.editTracklist": "Edit Daftar Lagu",
"action.addToLibrary": "Tambahkan ke Pustaka",
"action.addToLibrary.success": "Ditambahkan ke Pustaka",
"action.addToLibrary.error": "Terjadi Kesalahan Saat Menambahkan Pustaka",
@@ -240,12 +283,45 @@
"action.tray.minimize": "Sembunyikan ke Tray",
"action.tray.quit": "Keluar",
"action.update": "Perbarui",
+ "action.tray.listento": "Dengarkan:",
"action.install": "Pasang",
"action.copy": "Salin",
"action.newpreset": "Preset Baru...",
"action.deletepreset": "Hapus Preset",
"action.open": "Buka",
+ "action.close": "Close",
"action.relaunch.confirm": "Apakah Anda ingin memulai ulang Cider?",
+ "action.cast.chromecast": "Chromecast",
+ "action.cast.todevices": "Transmisi ke Perangkat",
+ "action.cast.stop": "Stop transmisi ke semua perangkat",
+ "action.cast.airplay": "AirPlay",
+ "action.cast.airplay.underdevelopment": "AirPlay masih dalam tahap pengembangan",
+ "action.cast.scan": "Pindai",
+ "action.cast.scanning": "Pindai...",
+ "action.createNew": "Buat Baru...",
+ "action.openArtworkInBrowser": "Buka artwork di browser",
+ "action.scrollToTop": "Gulir ke atas",
+ "action.refresh": "Muat ulang",
+ "menubar.options.view": "Tampilan",
+ "menubar.options.reload": "Muat Ulang",
+ "menubar.options.forcereload": "Paksa Muat Ulang",
+ "menubar.options.toggledevtools": "Aktfikan Alat Developer",
+ "menubar.options.window": "Jendela",
+ "menubar.options.minimize": "Perkecil",
+ "menubar.options.plugins": "Menu Plu-gins",
+ "menubar.options.controls": "Kontrol",
+ "menubar.options.volumeup": "Keraskan Volume",
+ "menubar.options.volumedown": "Kecilkan Volume",
+ "menubar.options.account": "Akun",
+ "menubar.options.signout": "Keluar",
+ "menubar.options.support": "Bantuan",
+ "menubar.options.report": "Laporkan...",
+ "menubar.options.bug": "Bug",
+ "menubar.options.feature": "Permintaan Fitur",
+ "menubar.options.trans": "Laporkan/Minta Terjemahan",
+ "menubar.options.license": "Lihat Lisensi",
+ "menubar.options.conf": "Bukan File Konfigurasi pada Editor",
+ "menubar.options.zoom": "Zoom",
"settings.header.general": "Umum",
"settings.header.general.description": "Sesuaikan pengaturan umum untuk Cider.",
"settings.option.general.language": "Bahasa",
@@ -254,17 +330,53 @@
"settings.option.general.resumebehavior.locally": "Lokal",
"settings.option.general.resumebehavior.locally.description": "Cider akan melanjutkan sesi terakhir Anda di perangkat ini.",
"settings.option.general.resumebehavior.history": "Riwayat",
- "settings.option.general.resumebehavior.history.description": "Cider akan menambahkan lagu terakhir dari keseluruhan riwayat Apple Music Anda ke dalam antrian di seluruh perangkat.",
+ "settings.option.general.resumebehavior.history.description": "Cider akan melanjutkan lagu terakhir dari riwayat Apple Music di seluruh perangkat Anda.",
+ "settings.option.general.resumetabs" : "Buka Tab ketika Diluncurkan",
+ "settings.option.general.resumetabs.description" : "Anda dapat memilih tab apa yang akan dibuka ketika Anda membuka Cider.",
+ "settings.option.general.resumetabs.dynamic" : "Dinamis",
+ "settings.option.general.resumetabs.dynamic.description" : "Cider akan membuka tab yang terakhir digunakan",
"settings.option.general.language.main": "Bahasa",
"settings.option.general.language.fun": "Bahasa Candaan",
"settings.option.general.language.unsorted": "Tidak disortir",
+ "settings.option.general.customizeSidebar": "Sesuaikan Item Sidebar",
+ "settings.option.general.customizeSidebar.customize": "Sesuaikan",
+ "settings.option.general.keybindings": "Kombinasi Keyboard",
+ "settings.option.general.keybindings.library": "Pustaka",
+ "settings.option.general.keybindings.session": "Sesi",
+ "settings.option.general.keybindings.control": "Kontrol",
+ "settings.option.general.keybindings.interface": "Tampilan",
+ "settings.option.general.keybindings.advanced": "Lebih Lanjut",
+ "settings.option.general.keybindings.pressCombination": "Tekan kombinasi dua tombol untuk memperbarui",
+ "settings.option.general.keybindings.pressEscape": "Tekan ESC untuk kembali",
+ "settings.notyf.general.keybindings.update.success": "Kombinasi Keyboard telah diperbarui",
+ "settings.prompt.general.keybindings.update.success": "Kombinasi keyboard telah diperbarui",
+ "settings.option.general.themeUpdateNotification": "Perbarui tema secara otomatis",
+ "settings.option.general.showLovedTracksInline": "Tampilkan lagu yang di-love sejajar",
+ "settings.description.search": "Cari",
+ "settings.description.albums": "Pustaka Album",
+ "settings.description.artists": "Pustaka Artis",
+ "settings.description.browse": "Jelajahi",
+ "settings.description.private": "Nyalakan Sesi Pribadi",
+ "settings.description.remote": "Remote Web",
+ "settings.description.audio": "Peraturan Audio",
+ "settings.description.plugins": "Menu Plugins",
+ "settings.description.cast": "Transmisikan ke Perangkat",
+ "settings.description.settings": "Pengaturan",
+ "settings.description.developer": "Alat Developer",
+ "settings.description.listnow": "Dengarkan Sekarang",
+ "settings.description.recentAdd": "Baru Ditambahkan",
+ "settings.description.songs": "Lagu",
"settings.notyf.updateCider.update-not-available": "Tidak ada pembaruan tersedia",
"settings.notyf.updateCider.update-downloaded": "Pembaruan sudah didownload, mulai ulang untuk menginstall pembaruan",
"settings.notyf.updateCider.update-timeout": "Waktu pembaruan habis",
"settings.header.audio": "Audio",
"settings.header.audio.description": "Sesuaikan pengaturan audio untuk Cider.",
"settings.option.audio.volumeStep": "Jangkah Volume",
+ "settings.option.audio.advanced": "Kontrol Volume Lanjut",
"settings.option.audio.maxVolume": "Volume Maksimal",
+ "settings.option.audio.changePlaybackRate": "Ubah Tingkat Pemutaran",
+ "settings.option.audio.playbackRate": "Tingkat Pemutaran",
+ "settings.option.audio.playbackRate.change": "Ganti",
"settings.option.audio.quality": "Kualitas Audio",
"settings.header.audio.quality.hireslossless": "Hi-Res Lossless",
"settings.header.audio.quality.hireslossless.description": "sampai dari 24-bit/192 kHz",
@@ -277,20 +389,41 @@
"settings.option.audio.seamlessTransition": "Transisi Audio Mulus",
"settings.option.audio.enableAdvancedFunctionality": "Aktifkan Fungsi Lanjutan",
"settings.option.audio.enableAdvancedFunctionality.description": "Mengaktifkan fungsionalitas AudioContext memungkinkan fitur audio lanjutan seperti Normalisasi Audio, Equalizer dan Visualizer. Namun pada beberapa perangkat dapat menyebabkan tersendatnya audio.",
+ "settings.warn.audio.enableAdvancedFunctionality.lowcores": "Cider memperkirakan bahwa PC Anda tidak dapat menggunakan fitur ini. Apakah Anda yakin ingin melanjutkan?",
"settings.option.audio.audioLab": "Lab Audio Cider",
"settings.option.audio.audioLab.description": "Macam-macam efek audio yang dikembangkan sendiri untuk Cider.",
+ "settings.option.audio.audioLab.subheader": "Dibuat oleh Cider Acoustic Technologies di California",
"settings.warn.audioLab.withoutAF": "AudioContext (Fungsi Lanjutan) perlu diaktifkan untuk menggunakan Lab Audio Cider.",
+ "settings.warn.enableAdvancedFunctionality": "AudioContext (Advanced Functionality) dibutuhkan untuk menyalakan fitur ini.",
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Analog Warmth",
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Mensimulasikan kehangatan analog yang dimodelkan setelah Korg Nutube 6P1",
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Analog Warmth intensity",
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Mengubah intensitas pemrosesan modul Analog Warmth.",
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "Halus",
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "Hangat",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider Atmosphere Realizer™️",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Membuat atmosfir musik yang berbeda setelah penyesuaian audio tingkat modern dan terbaru",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Cider Atmosphere Realizer™️ Mode",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Ubah mode operasi dari modul Atmosphere Realizer.",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Hōjicha Cheese Foam Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Genmaicha Tapioca Milk Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_1": "Rock Salt Cheese Foam Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_2": "Uji Matcha Milk Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500A": "Moonlight Softcake",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500B": "Clafoutis aux Cerises",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500C": "Uji Matcha Mochi",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Meningkatkan kualitas audio AAC secara 'realtime' dengan algoritma yang memanfaatkan model psychoacoustic manusia dan karakteristik encoding AAC",
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "CAP tidak cocok dengan Spatialisasi. Matikan Spasialisasi untuk menggunakan.",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Kekuatan CAP",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Mengubah kekuatan pemrosesan yang dilakukan pada audio. (Agresif dapat menghasilkan hasil yang tidak diinginkan)",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Standar",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "Adaptif",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "Legacy",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Agresif",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalisasi Audio",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Menormalkan puncak volume untuk masing-masing lagu demi menciptakan pengalaman mendengarkan yang lebih seragam.",
@@ -300,14 +433,30 @@
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Profil Spasialisasi Cider",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Mengubah Profil Tuning Spasialisasi. (Memerlukan Restart Aplikasi)",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Standar",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "Soundstage",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Separation",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffused",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Expanded Encore",
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "Spatialization tidak cocok dengan CAP. Matikan CAP untuk menggunakan.",
+ "settings.option.audio.dbspl.display": "dB SPL Display",
+ "settings.option.audio.dbspl.description": "(Untuk pengguna ahli) Tampilkan dB SPL daripada dBFS pada penggeser volume.",
+ "settings.option.audio.dbfs.calibration": "0 dBFS Calibration",
+ "settings.option.audio.dbfs.description": "Masukkan puncak Z-weighted dB SPL saat Cider berada pada 0 dBFS.",
"settings.header.visual": "Visual",
"settings.header.visual.description": "Sesuaikan pengaturan visual untuk Cider.",
+ "settings.option.visual.windowStyle": "Gaya Jendela",
+ "settings.option.visual.customAccentColor": "Warna Pilihan",
+ "settings.option.visual.accentColor": "Warna",
+ "settings.option.visual.purplePodcastPlaybackBar": "Bilah Pemutaran Ungu untuk Podcast",
+ "settings.option.visual.windowColor": "Warna Jendela",
"settings.option.visual.windowBackgroundStyle": "Gaya Latar Belakang Jendela",
"settings.header.visual.windowBackgroundStyle.none": "Tidak Ada",
"settings.header.visual.windowBackgroundStyle.artwork": "Artwork",
"settings.header.visual.windowBackgroundStyle.image": "Gambar",
+ "settings.header.visual.windowBackgroundStyle.color": "Warna-warna",
"settings.option.visual.animatedArtwork": "Artwork Bergerak",
"settings.header.visual.animatedArtwork.always": "Selalu",
"settings.header.visual.animatedArtwork.limited": "Terbatas untuk halaman dan entri khusus",
@@ -323,12 +472,21 @@
"settings.option.visual.hardwareAcceleration.description": "Membutuhkan dibuka ulang",
"settings.header.visual.hardwareAcceleration.default": "Default",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
+ "settings.option.visual.uiscale": "Skala UI",
"settings.header.visual.theme": "Tema",
"settings.option.visual.theme.github.download": "Pasang dari URL GitHub",
+ "settings.option.visual.theme.github.openfolder": "Buka Folder Tema",
"settings.option.visual.theme.github.explore": "Jelajahi Tema di GitHub",
"settings.header.visual.theme.github.page": "Tema dari GitHub",
"settings.option.visual.theme.github.install.confirm": "Apakah anda yakin untuk memasang {{ repo }}?",
"settings.prompt.visual.theme.github.URL": "Masukan URL tema yang ingin Anda pasang",
+ "settings.prompt.visual.theme.uninstallTheme": "Apakah Anda yakin untuk untuk mencopot {{ theme }}?",
+ "settings.option.visual.theme.checkForUpdates": "Cek Pembaruan",
+ "settings.option.visual.theme.manageStyles": "Kelola Gaya",
+ "settings.option.visual.theme.uninstall": "Copot",
+ "settings.option.visual.theme.viewInfo": "Lihat Info",
+ "settings.option.visual.theme.github.available": "Tersedia",
+ "settings.option.visual.theme.github.applied": "Diterapkan",
"settings.notyf.visual.theme.install.success": "Tema berhasil dipasang",
"settings.notyf.visual.theme.install.error": "Pemasangan tema gagal",
"settings.header.visual.plugin": "Plugin",
@@ -347,17 +505,29 @@
"settings.header.window.description": "Atur pengaturan jendela pada Cider.",
"settings.option.window.openOnStartup": "Buka Cider Ketika Perangkat Dinyalakan",
"settings.option.window.openOnStartup.hidden": "Buka dalam mode tersembunyi",
+ "settings.option.window.useNativeTitleBar": "Gunakan Title Bar Native",
+ "settings.option.window.windowControlStyle": "Pengontrol Style Jendela",
+ "settings.option.window.windowControlStyle.right": "Kanan",
+ "settings.option.window.windowControlStyle.left": "Kiri",
"settings.header.lyrics": "Lirik",
"settings.header.lyrics.description": "Sesuaikan pengaturan lirik untuk Cider.",
"settings.option.lyrics.enableMusixmatch": "Aktifkan Lirik Musixmatch",
"settings.option.lyrics.enableMusixmatchKaraoke": "Aktifkan Mode Karaoke (khusus Musixmatch)",
"settings.option.lyrics.musixmatchPreferredLanguage": "Bahasa Terjemahan Musixmatch",
"settings.option.lyrics.enableYoutubeLyrics": "Aktifkan Lirik Youtube untuk Video Musik",
+ "settings.option.lyrics.enableQQLyrics": "Aktifkan QQ Lyrics",
"settings.header.connectivity": "Konektivitas",
"settings.header.connectivity.description": "Sesuaikan pengaturan konektivitas untuk Cider.",
- "settings.option.connectivity.discordRPC": "Discord Rich Presence",
"settings.option.connectivity.playbackNotifications": "Pemberitahuan Pemutaran",
+ "settings.option.connectivity.discordRPC": "Discord Rich Presence",
+ "settings.option.connectivity.discordRPC.clientName": "Nama Client",
"settings.option.connectivity.discordRPC.clearOnPause": "Sembunyikan Discord Rich Presence Saat Dijeda",
+ "settings.option.connectivity.discordRPC.hideButtons": "Sembunyikan tombol pada Discord Rich Presence",
+ "settings.option.connectivity.discordRPC.hideTimestamp": "Sembunyikan tanda waktu pada Discord Rich Presence",
+ "settings.option.connectivity.discordRPC.detailsFormat": "Format Detail",
+ "settings.option.connectivity.discordRPC.stateFormat": "Format State",
+ "settings.option.connectivity.discordRPC.reload": "Muat Ulang DiscordRPC",
+ "settings.option.connectivity.discordRPC.reconnectedToUser": "DiscordRPC terhubung ke pengguna: {{user}} ({{userid}})",
"settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling",
"settings.option.connectivity.lastfmScrobble.delay": "Delay Last.fm Scrobble (%)",
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Aktifkan Last.fm Now Playing",
@@ -368,6 +538,8 @@
"settings.option.debug.openAppData": "Buka Folder Cider",
"settings.header.experimental": "Eksperimental",
"settings.header.experimental.description": "Sesuaikan pengaturan eksperimental untuk Cider.",
+ "settings.option.experimental.reinstallwidevine": "Pasang Ulang WidevineCDM",
+ "settings.option.experimental.reinstallwidevine.confirm": "Apakah Anda yakin untuk memasang ulang Widevine?",
"settings.option.experimental.unknownPlugin": "Sumber Tidak Diketahui",
"settings.option.experimental.unknownPlugin.description": "Izinkan pemasangan plugin dari repo selain Cider Plugin Repository",
"settings.option.experimental.compactUI": "UI Kompak",
@@ -377,6 +549,10 @@
"settings.option.advanced.playlistTrackMapping.description": "Mengaktifkan pemindaian daftar putar yang mendalam untuk menentukan trek mana yang ada di daftar putar. Waktu pembuatan cache daftar putar dapat meningkat secara signifikan.",
"settings.option.visual.transparent": "Frame transparan",
"settings.option.visual.transparent.description": "membutuhkan tema yang mendukung, membutuhkan dibuka ulang",
+ "settings.header.advanced": "Lanjutan",
+ "settings.header.connect": "Sinkron",
+ "settings.option.connect.link_account": "Sikronisasikan dengan Cider Connect",
+ "settings.option.connect.link_account.description": "Menghubungkan akun Discord Anda dengan Cider Connect memungkinkan Anda untuk menyimpan data pengguna termasuk Pengaturan, EQ, dan lebih banyak lagi setelah selesai. (Pekerjaan Dalam Proses)",
"spatial.notTurnedOn": "Spasialisasi Audio dinonaktifkan. Untuk menggunakan, aktifkan terlebih dahulu.",
"spatial.spatialProperties": "Spatial Properties",
"spatial.width": "Lebar",
@@ -399,5 +575,54 @@
"settings.header.unfinished": "Belum Diselesaikan",
"remote.web.title": "Remote Cider",
"remote.web.description": "Pindai kode QR untuk memasangkan ponsel Anda dengan Cider.",
- "about.thanks": "Terima kasih yang sebesar-besarnya kepada Cider Collective Team dan semua kontributor kami."
+ "share.platform.twitter.tweet": "Dengarkan {{song}} di Apple Music.\n\n{{url}}\n\n#AppleMusic #Cider",
+ "share.platform.twitter": "Twitter",
+ "share.platform.facebook": "Facebook",
+ "share.platform.reddit": "Reddit",
+ "share.platform.telegram": "Telegram",
+ "share.platform.whatsapp": "WhatsApp",
+ "share.platform.messenger": "Messenger",
+ "share.platform.email": "Email",
+ "share.platform.songLink": "Salin dengan song.link",
+ "share.platform.clipboard": "Salin Link",
+ "about.thanks": "Terima kasih yang sebesar-besarnya kepada Cider Collective Team dan semua kontributor kami.",
+ "oobe.yes": "Ya",
+ "oobe.no": "Tidak",
+ "oobe.next": "Berikutnya",
+ "oobe.previous": "Sebelumnya",
+ "oobe.done": "Selesai",
+ "oobe.amupsell.title": "Sebelum kita mulai",
+ "oobe.amupsell.text": "Cider memerlukan langganan Apple Music yang aktif\nCider tidak akan berfungsi dengan Apple Music Voice Plan atau beberapa langganan uji coba promosi. Jika Anda sudah berlangganan Apple Music yang memenuhi syarat, klik Berikutnya untuk melanjutkan.",
+ "oobe.amupsell.subscribeBtn": "Berlangganan Apple Music",
+ "oobe.amupsell.explainBtn": "Jelaskan",
+ "oobe.amupsell.subscribeUrl": "https://apple.co/3MdqJVQ",
+ "oobe.amupsell.amWebUrl": "https://beta.music.apple.com/",
+ "oobe.amupsell.promoExplained": "Beberapa promosi uji coba Apple Music dan akun non AS tidak memiliki akses ke Apple Music Web Player API yang diperlukan agar Cider berfungsi. Untuk memverifikasi apakah uji coba aktif Anda akan berfungsi dengan Cider, buka {{ amWebUrl }} masuk dan coba putar musik. Jika berhasil, bagus! Anda siap menggunakan Cider, namun jika tidak mempertimbangkan untuk berlangganan Apple Music di sini: {{ subscribeUrl }} ",
+ "oobe.intro.title": "Selamat Datang di Cider",
+ "oobe.intro.subtitle": "",
+ "oobe.intro.text": "Mari kita siapkan beberapa hal agar Anda dapat menggunakan Cider sesuai keinginan Anda. Anda selalu dapat mengubah setelan ini nanti.",
+ "oobe.general.title": "Umum",
+ "oobe.general.subtitle": "",
+ "oobe.general.text": "",
+ "oobe.audio.title": "Audio",
+ "oobe.audio.subtitle": "",
+ "oobe.audio.text": "Cider menghadirkan tumpukan audio yang disesuaikan dan dirancang khusus. Serta menghadirkan pengalaman audio berkualitas tinggi yang baik.\nDengan fitur seperti Cider Adrenaline, Atmosphere Realizer, dan Spatialized Audio.\nUntuk mengaktifkan fungsi ini \"Pengaturan Audio Tingkat Lanjut\" harus dinyalakan.\nMengaktifkan Pengaturan Audio Tingkat Lanjut akan memberi Anda akses ke peningkatan ini di Lab Audio Cider, yang ditemukan di pengaturan aplikasi",
+ "oobe.audio.advancedFunctionality": "",
+ "oobe.visual.title": "Visual",
+ "oobe.visual.subtitle": "",
+ "oobe.visual.text": "",
+ "oobe.visual.layout.text": "Cider menampilkan dua jendela tata letak yang berbeda.\nMaverick adalah tata letak seperti iTunes dengan pemutar di bagian atas jendela.\nMojave adalah putaran baru yang dibuat oleh tim Cider Collective.\n\nAnda dapat mengubah tata letak kapan saja di setelan.",
+ "oobe.visual.suggestingThemes": "Tema adalah cara terbaik untuk mempersonalisasi pengalaman Anda. Berikut adalah beberapa yang kami sarankan:",
+ "oobe.visual.suggestingThemes.subtext": "(Tema-tema ini akan diunduh dari GitHub)",
+ "oobe.visual.suggestingThemes.default": "Cider",
+ "oobe.visual.suggestingThemes.default.text": "Tema classic Cider.",
+ "oobe.visual.suggestingThemes.dark": "Gelap",
+ "oobe.visual.suggestingThemes.dark.text": "Kegelapan.",
+ "oobe.visual.suggestingThemes.community1": "Groovy",
+ "oobe.visual.suggestingThemes.community1.text": "A WinUI influenced theme",
+ "oobe.visual.suggestingThemes.community2": "iTheme",
+ "oobe.visual.suggestingThemes.community2.text": "The classic big fruit layout.",
+ "oobe.visual.suggestingThemes.community3": "Dracula",
+ "oobe.visual.suggestingThemes.community3.text": "The iconic Dracula color scheme.",
+ "oobe.amsignin.title": ""
}
diff --git a/src/i18n/pt_PT.json b/src/i18n/pt_PT.json
index 5cac376a..54496abe 100644
--- a/src/i18n/pt_PT.json
+++ b/src/i18n/pt_PT.json
@@ -1,584 +1,590 @@
{
- "i18n.languageName": "Português (Portugal)",
- "i18n.languageNameEnglish": "Portuguese (Portugal)",
- "i18n.category": "main",
- "i18n.authors": "@pgalhardo",
- "app.name": "Cider",
- "date.format": "${m} ${d}, ${y}",
- "dialog.cancel": "Cancelar",
- "dialog.ok": "OK",
- "notification.updatingLibrarySongs": "A atualizar biblioteca de músicas...",
- "notification.updatingLibraryAlbums": "A atualizar biblioteca de álbuns...",
- "notification.updatingLibraryArtists": "A atualizar biblioteca de artistas...",
- "term.variables": "Variáveis",
- "term.appleInc": "Apple Inc.",
- "term.appleMusic": "Apple Music",
- "term.applePodcasts": "Apple Podcasts",
- "term.itunes": "iTunes",
- "term.github": "GitHub",
- "term.discord": "Discord",
- "term.learnMore": "Saiba mais",
- "term.accountSettings": "Definições da conta",
- "term.logout": "Terminar sessão",
- "term.login": "Iniciar sessão",
- "term.quickNav": "Navegação rápida",
- "term.cast": "Transmitir",
- "term.about": "Sobre",
- "term.privateSession": "Sessão privada",
- "term.disablePrivateSession": "Desativar sessão privada",
- "term.queue": "Fila",
- "term.autoplay": "Reprodução automática",
- "term.lyrics": "Letra",
- "term.miniplayer": "Mini-leitor",
- "term.history": "Histórico",
- "term.search": "Pesquisa",
- "term.library": "Biblioteca",
- "term.listenNow": "Ouvir agora",
- "term.browse": "Explorar",
- "term.radio": "Rádio",
- "term.recentlyAdded": "Adições recentes",
- "term.songs": "Músicas",
- "term.albums": "Álbuns",
- "term.artists": "Intérpretes",
- "term.podcasts": "Podcasts",
- "term.playlists": "Listas de reprodução",
- "term.charts": "Gráficos",
- "term.playlist": "Lista de reprodução",
- "term.newPlaylist": "Nova lista de reprodução",
- "term.newPlaylistFolder": "Nova pasta de listas de reprodução",
- "term.createNewPlaylist": "Criar nova lista de reprodução",
- "term.createNewPlaylistFolder": "Criar nova pasta de listas de reprodução",
- "term.deletePlaylist": "Tem a certeza de que pretende apagar esta lista de reprodução?",
- "term.navigateBack": "Retroceder uma página",
- "term.navigateForward": "Avançar uma página",
- "term.play": "Reproduzir",
- "term.pause": "Pausa",
- "term.stop": "Parar",
- "term.previous": "Anterior",
- "term.next": "Seguinte",
- "term.shuffle": "Modo aleatório",
- "term.enableShuffle": "Ativar modo aleatório",
- "term.disableShuffle": "Desativar modo aleatório",
- "term.repeat": "Repetir",
- "term.enableRepeatOne": "Ativar repetir uma",
- "term.disableRepeatOne": "Desativar repetir uma",
- "term.disableRepeat": "Não repetir",
- "term.volume": "Volume",
- "term.mute": "Mudo",
- "term.unmute": "Com som",
- "term.share": "Partilhar",
- "term.share.success": "Copiado para a área de transferência",
- "term.settings": "Definições",
- "term.seeAll": "Ver tudo",
- "term.sortBy": "Ordenar por",
- "term.sortBy.album": "Álbum",
- "term.sortBy.artist": "Intérprete",
- "term.sortBy.name": "Nome",
- "term.sortBy.genre": "Género",
- "term.sortBy.releaseDate": "Data de lançamento",
- "term.sortBy.duration": "Duração",
- "term.sortBy.dateAdded": "Data de adição",
- "term.sortOrder": "A-Z",
- "term.sortOrder.ascending": "Ascendente",
- "term.sortOrder.descending": "Descendente",
- "term.viewAs": "Ver como",
- "term.viewAs.coverArt": "Grafismos",
- "term.viewAs.list": "Lista",
- "term.dynamic": "Dinâmico",
- "term.size": "Tamanho",
- "term.size.normal": "Normal",
- "term.size.compact": "Compacto",
- "term.enable": "Ativar",
- "term.disable": "Desativar",
- "term.enabled": "Ativado",
- "term.disabled": "Desativado",
- "term.connect": "Ligar",
- "term.connecting": "A ligar",
- "term.disconnect": "Desligar",
- "term.authed": "Autenticado",
- "term.confirm": "Confirmar?",
- "term.more": "Mais",
- "term.less": "Menos",
- "term.showMore": "Mostrar mais",
- "term.showLess": "Mostrar menos",
- "term.topSongs": "Músicas populares",
- "term.latestReleases": "Últimos lançamentos",
- "term.time.added": "Adicionado",
- "term.time.released": "Lançado",
- "term.time.updated": "Atualizado",
- "term.time.days": "dias",
- "term.time.day": {
- "one": "dia",
- "other": "dias"
- },
- "term.time.hours": "horas",
- "term.time.hour": {
- "one": "hora",
- "other": "horas"
- },
- "term.time.minutes": "minutos",
- "term.time.minute": {
- "one": "minuto",
- "other": "minutos"
- },
- "term.time.seconds": "segundos",
- "term.time.second": {
- "one": "segundo",
- "other": "segundos"
- },
- "term.fullscreenView": "Vista de ecrã inteiro",
- "term.defaultView": "Vista normal",
- "term.audioSettings": "Definições de áudio",
- "term.audioControls": "Controlos de volume",
- "term.clearAll": "Limpar tudo",
- "term.recentStations": "Estações recentes",
- "term.personalStations": "Estações pessoais",
- "term.amLive": "Apple Music Live",
- "term.language": "Idioma",
- "term.funLanguages": "Divertido",
- "term.noLyrics": "A carregar... / Letra não encontrada. / Instrumental.",
- "term.copyright": "Copyright",
- "term.rightsReserved": "Todos os direitos reservados.",
- "term.sponsor": "Patrocine este projecto",
- "term.ciderTeam": "Equipa do Cider",
- "term.developer": "Programador",
- "term.socialTeam": "Equipa social",
- "term.socials": "Redes sociais",
- "term.contributors": "Contribuidores",
- "term.equalizer": "Equalizador",
- "term.reset": "Repor",
- "term.tracks": "músicas",
- "term.track": {
- "one": "música",
- "other": "músicas"
- },
- "term.videos": "Vídeos",
- "term.menu": "Menu",
- "term.check": "Verificar",
- "term.aboutArtist": "Sobre {{artistName}}",
- "term.topResult": "Melhor resultado",
- "term.sharedPlaylists": "Listas de reprodução partilhadas",
- "term.people": "Pessoas",
- "term.newpreset.name": "Nome da nova predefinição do EQ",
- "term.addedpreset": "Predefinição adicionada",
- "term.deletepreset.warn": "Tem a certeza de que pretende apagar esta predefinição?",
- "term.deletedpreset": "Predefinição eliminada",
- "term.defaultPresets": "Predefinições por omissão",
- "term.userPresets": "Predefinições do utilizador",
- "term.requestError": "Ocorreu um problema ao processar o pedido.",
- "term.song.link.generate": "A obter o URL de partilha song.link...",
- "term.musicVideos": "Videoclipes",
- "term.stations": "Estações",
- "term.curators": "Curadores",
- "term.appleCurators": "Curadores da Apple",
- "term.radioShows": "Programas de rádio",
- "term.recordLabels": "Gravadoras",
- "term.videoExtras": "Vídeos extra",
- "term.top": "Top",
- "term.version": "Versão",
- "term.noVideos": "Não foram encontrados vídeos.",
- "term.plugin": "Plug-in",
- "term.pluginMenu": "Menu de plug-ins",
- "term.pluginMenu.none": "Sem plug-ins interactivos",
- "term.replay": "Repetir",
- "term.uniqueAlbums": "Álbuns únicos",
- "term.uniqueArtists": "Intérpretes únicos",
- "term.uniqueSongs": "Músicas únicas",
- "term.topArtists": "Intérpretes populares",
- "term.listenedTo": "Reproduzido:",
- "term.times": "vezes",
- "term.topAlbums": "Álbuns populares",
- "term.plays": "Reproduções",
- "term.topGenres": "Géneros populares",
- "term.confirmLogout": "Tem a certeza de que pretende terminar sessão?",
- "term.creditDesignedBy": "Concebido por ${authorUsername}",
- "term.discNumber": "Disco ${discNumber}",
- "home.title": "Início",
- "home.recentlyPlayed": "Reproduzido recentemente",
- "home.recentlyAdded": "Adicionado recentemente",
- "home.artistsFeed": "Feed dos seus artistas",
- "home.artistsFeed.noArtist": "Siga alguns artistas para ver os seus últimos lançamentos",
- "home.madeForYou": "Feito para si",
- "home.friendsListeningTo": "O que os seus amigos estão a ouvir",
- "home.followedArtists": "Artistas seguidos",
- "error.appleMusicSubRequired": "A Apple Music requer uma subscrição.",
- "error.connectionError": "Ocorreu um problema ao estabelecer ligação à Apple Music.",
- "error.noResults": "Sem resultados.",
- "error.noResults.description": "Tente uma nova pesquisa.",
- "podcast.followOnCider": "Siga no Cider",
- "podcast.followedOnCider": "A seguir no Cider",
- "podcast.subscribeOnItunes": "Subscreva no iTunes",
- "podcast.subscribedOnItunes": "Subscrito no iTunes",
- "podcast.itunesStore": "iTunes Store",
- "podcast.episodes": "Episódios",
- "podcast.playEpisode": "Reproduzir episódio",
- "podcast.website": "Website do Podcast",
- "action.hideLibrary": "Ocultar biblioteca",
- "action.showLibrary": "Mostrar biblioteca",
- "action.cut": "Cortar",
- "action.paste": "Colar",
- "action.selectAll": "Seleccionar tudo",
- "action.delete": "Apagar",
- "action.edit": "Editar",
- "action.done": "Concluído",
- "action.editTracklist": "Editar lista de reprodução",
- "action.addToLibrary": "Adicionar à biblioteca",
- "action.addToLibrary.success": "Adicionado à biblioteca",
- "action.addToLibrary.error": "Erro ao adicionar à biblioteca",
- "action.removeFromLibrary": "Remover da biblioteca",
- "action.removeFromLibrary.success": "Removido da biblioteca",
- "action.addToQueue": "Adicionar à fila",
- "action.addToQueue.success": "Adicionado à fila",
- "action.addToQueue.error": "Erro ao adicionar à fila",
- "action.removeFromQueue": "Remover da fila",
- "action.removeFromQueue.success": "Removido da fila",
- "action.removeFromQueue.error": "Erro ao remover da fila",
- "action.createPlaylist": "Criar uma nova lista de reprodução",
- "action.addToPlaylist": "Adicionar à lista de reprodução",
- "action.removeFromPlaylist": "Removar da lista de reprodução",
- "action.addToFavorites": "Adicionar aos favoritos",
- "action.follow": "Seguir",
- "action.follow.success": "Seguido",
- "action.follow.error": "Erro ao seguir",
- "action.unfollow": "Não seguir",
- "action.unfollow.success": "Não seguido",
- "action.unfollow.error": "Erro ao deixar de seguir",
- "action.playNext": "Reproduzir a seguir",
- "action.playLater": "Reproduzir mais tarde",
- "action.startRadio": "Criar estação",
- "action.goToArtist": "Ir para intérprete",
- "action.goToAlbum": "Ir para álbum",
- "action.showInPlaylist": "Mostrar na lista de reprodução",
- "action.showInAppleMusic": "Mostrar na Apple Music",
- "action.moveToTop": "Mover para fora da pasta",
- "action.share": "Partilhar",
- "action.rename": "Renomear",
- "action.love": "Gostar",
- "action.unlove": "Desfazer gostar",
- "action.dislike": "Não gostar",
- "action.undoDislike": "Desfazer não gostar",
- "action.showWebRemoteQR": "Web Remote",
- "action.playTracksNext": "Reproduzir ${app.selectedMediaItems.length} músicas a seguir",
- "action.playTracksLater": "Reproduzir ${app.selectedMediaItems.length} músicas mais tarde",
- "action.removeTracks": "Remover ${self.selectedItems.length} músicas da fila",
- "action.import": "Importar",
- "action.export": "Exportar",
- "action.showAlbum": "Mostrar álbum completo",
- "action.tray.minimize": "Minimizar para a bandeja",
- "action.tray.quit": "Fechar",
- "action.tray.show": "Mostrar o Cider",
- "action.tray.playpause": "Reproduzir/Pausa",
- "action.tray.next": "Seguinte",
- "action.tray.previous": "Anterior",
- "action.tray.listento": "Ouvir:",
- "action.update": "Atualizar",
- "action.install": "Instalar",
- "action.copy": "Copiar",
- "action.newpreset": "Nova predefinição...",
- "action.deletepreset": "Eliminar predefinição",
- "action.open": "Abrir",
- "action.close": "Fechar",
- "action.relaunch.confirm": "Pretende reiniciar o Cider?",
- "action.cast.chromecast": "Chromecast",
- "action.cast.todevices": "Transmitir para dispositivos",
- "action.cast.stop": "Parar a transmissão para todos os dispositivos",
- "action.cast.airplay": "AirPlay",
- "action.cast.airplay.underdevelopment": "AirPlay ainda está em desenvolvimento",
- "action.cast.scan": "Procurar",
- "action.cast.scanning": "A procurar...",
- "action.createNew": "Criar nova...",
- "action.openArtworkInBrowser": "Abrir grafismo no navegador",
- "action.scrollToTop": "Voltar ao topo",
- "menubar.options.about": "Sobre",
- "menubar.options.settings": "Definições",
- "menubar.options.quit": "Fechar o Cider",
- "menubar.options.view": "Ver",
- "menubar.options.reload": "Atualizar",
- "menubar.options.forcereload": "Forçar atualização",
- "menubar.options.toggledevtools": "Alternar ferramentas do programador",
- "menubar.options.window": "Janela",
- "menubar.options.minimize": "Minimizar",
- "menubar.options.toggleprivate": "Alternar sessão privada",
- "menubar.options.webremote": "Web Remote",
- "menubar.options.audio": "Definições de áudio",
- "menubar.options.plugins": "Menu de plug-ins",
- "menubar.options.controls": "Controlos",
- "menubar.options.next": "Seguinte",
- "menubar.options.playpause": "Reproduzir/Pausa",
- "menubar.options.previous": "Anterior",
- "menubar.options.volumeup": "Aumentar o volume",
- "menubar.options.volumedown": "Diminuir o volume",
- "menubar.options.browse": "Explorar",
- "menubar.options.artists": "Intérpretes",
- "menubar.options.search": "Pesquisa",
- "menubar.options.albums": "Álbuns",
- "menubar.options.cast": "Transmitir para dispositivos",
- "menubar.options.account": "Conta",
- "menubar.options.accountsettings": "Definições da conta",
- "menubar.options.signout": "Terminar sessão",
- "menubar.options.support": "Suporte",
- "menubar.options.discord": "Discord",
- "menubar.options.github": "GitHub Wiki",
- "menubar.options.report": "Reportar um...",
- "menubar.options.bug": "Problema",
- "menubar.options.feature": "Pedido de funcionalidade",
- "menubar.options.trans": "Pedido de tradução",
- "menubar.options.license": "Ver licença",
- "menubar.options.conf": "Abrir ficheiro de configuração no editor",
- "menubar.options.listennow": "Ouvir agora",
- "menubar.options.recentlyAdded": "Adições recentes",
- "menubar.options.songs": "Músicas",
- "settings.header.general": "Geral",
- "settings.header.general.description": "Ajustar as definições gerais do Cider.",
- "settings.option.general.language": "Idioma",
- "settings.option.general.resumebehavior": "Comportamento de retoma",
- "settings.option.general.resumebehavior.description": "Define a forma como o Cider irá retomar a sua sessão quando regressar à aplicação.",
- "settings.option.general.resumebehavior.locally": "Localmente",
- "settings.option.general.resumebehavior.locally.description": "O Cider irá retomar a sua última sessão nesta máquina.",
- "settings.option.general.resumebehavior.history": "Histórico",
- "settings.option.general.resumebehavior.history.description": "O Cider irá colocar na fila a última música do seu histórico da Apple Music, através de todos os seus dispositivos.",
- "settings.option.general.resumetabs": "Abrir separador no arranque",
- "settings.option.general.resumetabs.description": "Pode escolher que separador quer abrir quando abre o Cider.",
- "settings.option.general.resumetabs.dynamic": "Dinâmico",
- "settings.option.general.resumetabs.dynamic.description": "O Cider abrirá o separador que utilizou pela última vez.",
- "settings.option.general.language.main": "Idiomas",
- "settings.option.general.language.fun": "Idiomas divertidos",
- "settings.option.general.language.unsorted": "Indiferenciado",
- "settings.option.general.customizeSidebar": "Personalizar os itens da barra lateral",
- "settings.option.general.customizeSidebar.customize": "Personalizar",
- "settings.option.general.keybindings": "Atalhos do teclado",
- "settings.option.general.keybindings.pressCombination": "Prima uma combinação de duas teclas para atualizar o atalho.",
- "settings.option.general.keybindings.pressEscape": "Prima a tecla Escape para voltar atrás.",
- "settings.notyf.general.keybindings.update.success": "Atalho atualizado com sucesso",
- "settings.prompt.general.keybindings.update.success": "Atalho atualizado com sucesso. Prima OK para reiniciar o Cider",
- "settings.option.general.keybindings.open": "Abrir",
- "settings.option.general.themeUpdateNotification": "Verificação automática de atualizações de temas",
- "settings.option.general.showLovedTracksInline": "Mostrar músicas que gosta \"inline\"",
- "settings.description.search": "Pesquisa",
- "settings.description.albums": "Álbuns da biblioteca",
- "settings.description.artists": "Intérpretes da biblioteca",
- "settings.description.browse": "Explorar",
- "settings.description.private": "Alternar sessão privada",
- "settings.description.remote": "Web Remote",
- "settings.description.audio": "Definições de áudio",
- "settings.description.plugins": "Menu de plug-ins",
- "settings.description.cast": "Transmitir para dispositivos",
- "settings.description.settings": "Definições",
- "settings.description.developer": "Ferramentas do programador",
- "settings.description.listnow": "Ouvir agora",
- "settings.description.recentAdd": "Adições recentes",
- "settings.description.songs": "Músicas",
- "settings.notyf.updateCider.update-not-available": "Nenhuma atualização disponível",
- "settings.notyf.updateCider.update-downloaded": "A atualização foi descarregada, reinicie para aplicar",
- "settings.notyf.updateCider.update-timeout": "O pedido de atualização estou o tempo limite",
- "settings.header.audio": "Áudio",
- "settings.header.audio.description": "Ajustar as definições de áudio para o Cider.",
- "settings.option.audio.volumeStep": "Nível de incremento de volume",
- "settings.option.audio.advanced": "Controlo avançado de volume",
- "settings.option.audio.maxVolume": "Volume máximo",
- "settings.option.audio.changePlaybackRate": "Alterar velocidade de reprodução",
- "settings.option.audio.playbackRate": "Velocidade de reprodução",
- "settings.option.audio.playbackRate.change": "Alterar",
- "settings.option.audio.quality": "Qualidade do áudio",
- "settings.header.audio.quality.hireslossless": "Alta resolução sem perdas",
- "settings.header.audio.quality.hireslossless.description": "até 24-bit/192 kHz",
- "settings.header.audio.quality.lossless": "Sem perdas",
- "settings.header.audio.quality.lossless.description": "até 24-bit/48 kHz",
- "settings.header.audio.quality.high": "Alta",
- "settings.header.audio.quality.high.description": "256 kbps",
- "settings.header.audio.quality.standard": "Padrão",
- "settings.header.audio.quality.standard.description": "64 kbps",
- "settings.option.audio.seamlessTransition": "Transição gradual do áudio",
- "settings.option.audio.enableAdvancedFunctionality": "Ativar funcionalidades avançadas",
- "settings.option.audio.enableAdvancedFunctionality.description": "Ativar o AudioContext dá acesso a funcionalidades alargadas como Normalização de Áudio, Equalizadores e Visualizadores - contudo, isto pode causar dificuldades em alguns sistemas.",
- "settings.warn.audio.enableAdvancedFunctionality.lowcores": "O Cider pensa que o seu PC não é capaz de lidar com estas funcionalidades. Tem a certeza de que pretende continuar?",
- "settings.option.audio.audioLab": "Cider Audio Lab",
- "settings.option.audio.audioLab.description": "Efeitos de áudio desenvolvidos internamente para o Cider.",
- "settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California",
- "settings.warn.audioLab.withoutAF": "AudioContext (funcionalidade avançada) é necessário para suportar o Cider Audio Lab.",
- "settings.warn.enableAdvancedFunctionality": "AudioContext (funcionalidade avançada) é necessário para suportar esta funcionalidade.",
- "settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Calor Analógico",
- "settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simula o calor analógico inspirado no Korg Nutube 6P1",
- "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Intensidade do calor analógico",
- "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Altera a intensidade do processamento do módulo de calor analógico.",
- "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "Suave",
- "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "Quente",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider Atmosphere Realizer™️",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Cria uma atmosfera musical diferente inspirada nas mais modernas aparelhagens.",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Modo do Cider Atmosphere Realizer™️",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Altera o modo de funcionamento do módulo Atmosphere Realizer.",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Hōjicha Cheese Foam Tea",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Genmaicha Tapioca Milk Tea",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_1": "Rock Salt Cheese Foam Tea",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_2": "Uji Matcha Milk Tea",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "Moonlight Softcake",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Melhora a qualidade de áudio percecionada do áudio codificado em AAC, utilizando um algoritmo de tempo real que tira partido tanto dos modelos psicoacústicos da audição humana como das características de codificação do AAC.",
- "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "O CAP não é compatível com a espacialização. Por favor, desative a espacialização para continuar.",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Intensidade do CAP",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Muda a intensidade do processamento feito ao áudio (a agressividade pode produzir resultados indesejáveis).",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Padrão",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "Adaptativo",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "Antigo",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Agressivo",
- "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalização de áudio",
- "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza o volume de pico das músicas para criar uma experiência de audição mais uniforme (não funciona em músicas carregadas pelo utilizador).",
- "settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Gerido pelo Audio Lab",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Espacialização ajustada pelo Cider",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Efeito de espacialização pré-ajustado, desactiva as configurações personalizáveis de espacialização de áudio.",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Perfil de espacialização do Cider",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Altera o perfil de ajuste da espacialização.",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Padrão",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "Palco",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Separação",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Mínimo",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiófilo",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Difundido",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Encore expandido",
- "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "A espacialização não é compatível com o CAP. Por favor, desative o CAP para continuar.",
- "settings.option.audio.dbspl.display": "Mostrar dB SPL",
- "settings.option.audio.dbspl.description": "(Apenas para utilizadores avançados) Mostrar dB SPL em vez de dBFS no controlo de volume.",
- "settings.option.audio.dbfs.calibration": "Calibração de 0 dBFS",
- "settings.option.audio.dbfs.description": "Introduza o pico de SPL com ponderação Z quando o Cider está a 0 dBFS.",
- "settings.header.visual": "Aparência",
- "settings.header.visual.description": "Ajustar as definições visuais do Cider.",
- "settings.option.visual.windowStyle": "Estilo da janela",
- "settings.option.visual.windowBackgroundStyle": "Estilo do fundo da janela",
- "settings.header.visual.windowBackgroundStyle.none": "Nenhum",
- "settings.header.visual.windowBackgroundStyle.artwork": "Grafismo",
- "settings.header.visual.windowBackgroundStyle.image": "Imagem",
- "settings.option.visual.animatedArtwork": "Grafismo animado",
- "settings.header.visual.animatedArtwork.always": "Sempre",
- "settings.header.visual.animatedArtwork.limited": "Limitado a páginas e entradas especiais",
- "settings.header.visual.animatedArtwork.disable": "Desativar em todo o lado",
- "settings.option.visual.animatedArtworkQuality": "Qualidade dos grafismos animados",
- "settings.header.visual.animatedArtworkQuality.low": "Baixa",
- "settings.header.visual.animatedArtworkQuality.medium": "Média",
- "settings.header.visual.animatedArtworkQuality.high": "Alta",
- "settings.header.visual.animatedArtworkQuality.veryHigh": "Muito alta",
- "settings.header.visual.animatedArtworkQuality.extreme": "Extrema",
- "settings.option.visual.animatedWindowBackground": "Fundo da janela animado",
- "settings.option.visual.hardwareAcceleration": "Aceleração de hardware",
- "settings.option.visual.hardwareAcceleration.description": "Requer reinício",
- "settings.header.visual.hardwareAcceleration.default": "Padrão",
- "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
- "settings.option.visual.uiscale": "Escala da UI",
- "settings.header.visual.theme": "Tema",
- "settings.option.visual.theme.github.download": "Instalar a partir de um URL do GitHub",
- "settings.option.visual.theme.github.openfolder": "Abrir pasta de temas",
- "settings.option.visual.theme.github.explore": "Explorar temas do GitHub",
- "settings.header.visual.theme.github.page": "Temas do GitHub",
- "settings.option.visual.theme.github.install.confirm": "Tem a certeza de que pretende instalar {{ repo }}?",
- "settings.prompt.visual.theme.github.URL": "Introduza o URL do tema que pretende instalar",
- "settings.prompt.visual.theme.uninstallTheme": "Tem a certeza de que pretende desinstalar {{ theme }}?",
- "settings.option.visual.theme.checkForUpdates": "Procurar por atualizações",
- "settings.option.visual.theme.manageStyles": "Gerir estilos",
- "settings.option.visual.theme.uninstall": "Desinstalar",
- "settings.option.visual.theme.viewInfo": "Ver informação",
- "settings.option.visual.theme.github.available": "Disponível",
- "settings.option.visual.theme.github.applied": "Aplicado",
- "settings.notyf.visual.theme.install.success": "Tema instalado com sucesso",
- "settings.notyf.visual.theme.install.error": "A instalação do tema falhou",
- "settings.header.visual.plugin": "Plug-in",
- "settings.option.visual.plugin.github.download": "Instalar a partir de um URL do GitHub",
- "settings.option.visual.plugin.github.explore": "Explorar plug-ins do GitHub",
- "settings.header.visual.plugin.github.page": "Plug-ins do GitHub",
- "settings.option.visual.plugin.github.install.confirm": "Tem a certeza de que pretende instalar {{ repo }}?",
- "settings.prompt.visual.plugin.github.URL": "Introduza o URL do plug-in que pretende instalar",
- "settings.prompt.visual.plugin.github.success": "Plug-in instalado com sucesso. Pressione OK para reiniciar o Cider",
- "settings.notyf.visual.plugin.install.success": "Plug-in instalado com sucesso",
- "settings.notyf.visual.plugin.install.error": "A instalação do plug-in falhou",
- "settings.option.visual.theme.default": "Cider",
- "settings.option.visual.theme.dark": "Escuro",
- "settings.option.visual.showPersonalInfo": "Mostrar informação pessoal",
- "settings.header.window": "Janela",
- "settings.header.window.description": "Ajustar as definições da janela para o Cider.",
- "settings.option.window.openOnStartup": "Abrir o Cider no arranque",
- "settings.option.window.openOnStartup.hidden": "Abrir escondido",
- "settings.option.window.useNativeTitleBar": "Usar barra de título nativa",
- "settings.option.window.windowControlStyle": "Estilo de controlo da janela",
- "settings.option.window.windowControlStyle.right": "Direita",
- "settings.option.window.windowControlStyle.left": "Esquerda",
- "settings.header.lyrics": "Letras",
- "settings.header.lyrics.description": "Ajustar as definições de letras para o Cider.",
- "settings.option.lyrics.enableMusixmatch": "Ativar letras do Musixmatch",
- "settings.option.lyrics.enableMusixmatchKaraoke": "Ativar o modo Karaoke (apenas para o Musixmatch)",
- "settings.option.lyrics.musixmatchPreferredLanguage": "Língua preferida para traduções do Musixmatch",
- "settings.option.lyrics.enableYoutubeLyrics": "Ativar letras do Youtube para videoclipes",
- "settings.option.lyrics.enableQQLyrics": "Ativar letras do QQ",
- "settings.header.connectivity": "Conectividade",
- "settings.header.connectivity.description": "Ajustar as definições de conectividade para o Cider.",
- "settings.option.connectivity.playbackNotifications": "Notificações de reprodução",
- "settings.option.connectivity.discordRPC": "Discord Rich Presence",
- "settings.option.connectivity.discordRPC.clientName": "Nome do cliente",
- "settings.option.connectivity.discordRPC.clearOnPause": "Limpar o Discord Rich Presence ao colocar em pausa",
- "settings.option.connectivity.discordRPC.hideButtons": "Esconder botões no Discord Rich Presence",
- "settings.option.connectivity.discordRPC.hideTimestamp": "Esconder timestamp no Discord Rich Presence",
- "settings.option.connectivity.discordRPC.detailsFormat": "Formato dos detalhes",
- "settings.option.connectivity.discordRPC.stateFormat": "Formato do estado",
- "settings.option.connectivity.discordRPC.reload": "Reiniciar o DiscordRPC",
- "settings.option.connectivity.discordRPC.reconnectedToUser": "DiscordRPC ligação restabelecida ao utilizador: {{user}} ({{userid}})",
- "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling",
- "settings.option.connectivity.lastfmScrobble.delay": "Last.fm atraso do scrobble (%)",
- "settings.option.connectivity.lastfmScrobble.nowPlaying": "Ativar Last.fm Now Playing",
- "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remover artistas do título da música (Last.fm)",
- "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrar música em loop (Last.fm)",
- "settings.header.debug": "Debug",
- "settings.option.debug.copy_log": "Copiar logs para a área de transferência",
- "settings.option.debug.openAppData": "Abrir pasta do Cider",
- "settings.header.experimental": "Experimental",
- "settings.header.experimental.description": "Ajustar as definições experimentais para o Cider.",
- "settings.option.experimental.reinstallwidevine": "Reinstalar WidevineCDM",
- "settings.option.experimental.reinstallwidevine.confirm": "Tem a certeza de que pretende reinstalar o Widevine?",
- "settings.option.experimental.unknownPlugin": "Fontes desconhecidas",
- "settings.option.experimental.unknownPlugin.description": "Permitir a instalação de plug-ins de outros repositórios que não o repositório de plug-ins do Cider",
- "settings.option.experimental.compactUI": "UI compacta",
- "settings.option.window.close_button_hide": "Botão fechar oculta a aplicação",
- "settings.option.experimental.inline_playlists": "Listas de reprodução e álbuns \"inline\"",
- "settings.option.advanced.playlistTrackMapping": "Mapeamento de músicas de listas de reprodução",
- "settings.option.advanced.playlistTrackMapping.description": "Ativa uma análise profunda das listas de reprodução para determinar que músicas estão em que listas de reprodução. O tempo de construção da cache das listas de reprodução pode aumentar significativamente.",
- "settings.option.visual.transparent": "Moldura transparente",
- "settings.option.visual.transparent.description": "Necessita de suporte do tema, requer reinício",
- "settings.header.advanced": "Avançado",
- "settings.header.connect": "Sincronização",
- "settings.option.connect.link_account": "Ativar a sincronização com o Cider Connect",
- "settings.option.connect.link_account.description": "Ligar a sua conta Discord ao Cider Connect permite-lhe armazenar dados de utilizador incluindo definições, EQ's, e eventualmente mais uma vez terminado (trabalho em curso).",
- "spatial.notTurnedOn": "A espacialização de áudio está desativada. Para utilizar, por favor, ative-a primeiro.",
- "spatial.spatialProperties": "Propriedades espaciais",
- "spatial.width": "Largura",
- "spatial.height": "Altura",
- "spatial.depth": "Profundidade",
- "spatial.gain": "Ganho",
- "spatial.roomMaterials": "Materiais da sala",
- "spatial.roomDimensions": "Dimensões da sala",
- "spatial.roomPositions": "Posições na sala",
- "spatial.setDimensions": "Definir dimensões",
- "spatial.setPositions": "Definir posições",
- "spatial.up": "Acima",
- "spatial.front": "Frente",
- "spatial.left": "Esquerda",
- "spatial.right": "Direita",
- "spatial.back": "Atrás",
- "spatial.down": "Em baixo",
- "spatial.listener": "Ouvinte",
- "spatial.audioSource": "Fonte de áudio",
- "settings.header.unfinished": "Inacabado",
- "remote.web.title": "Cider Remote",
- "remote.web.description": "Digitalize o código QR para emparelhar o seu telemóvel com esta instância do Cider",
- "share.platform.twitter.tweet": "Ouça {{song}} na Apple Music.\n\n{{url}}\n\n#AppleMusic #Cider",
- "share.platform.twitter": "Twitter",
- "share.platform.facebook": "Facebook",
- "share.platform.reddit": "Reddit",
- "share.platform.telegram": "Telegram",
- "share.platform.whatsapp": "WhatsApp",
- "share.platform.messenger": "Messenger",
- "share.platform.email": "Email",
- "share.platform.songLink": "Copiar com song.link",
- "share.platform.clipboard": "Copiar ligação",
- "about.thanks": "Um grande obrigado à equipa da Cider Collective e a todos os nossos contribuidores."
+ "i18n.languageName": "Português (Portugal)",
+ "i18n.languageNameEnglish": "Portuguese (Portugal)",
+ "i18n.category": "main",
+ "i18n.authors": "@pgalhardo",
+ "app.name": "Cider",
+ "date.format": "${m} ${d}, ${y}",
+ "dialog.cancel": "Cancelar",
+ "dialog.ok": "OK",
+ "notification.updatingLibrarySongs": "A atualizar biblioteca de músicas...",
+ "notification.updatingLibraryAlbums": "A atualizar biblioteca de álbuns...",
+ "notification.updatingLibraryArtists": "A atualizar biblioteca de artistas...",
+ "term.variables": "Variáveis",
+ "term.appleInc": "Apple Inc.",
+ "term.appleMusic": "Apple Music",
+ "term.applePodcasts": "Apple Podcasts",
+ "term.itunes": "iTunes",
+ "term.github": "GitHub",
+ "term.discord": "Discord",
+ "term.learnMore": "Saiba mais",
+ "term.accountSettings": "Definições da conta",
+ "term.logout": "Terminar sessão",
+ "term.login": "Iniciar sessão",
+ "term.quickNav": "Navegação rápida",
+ "term.about": "Sobre",
+ "term.privateSession": "Sessão privada",
+ "term.disablePrivateSession": "Desativar sessão privada",
+ "term.queue": "Fila",
+ "term.autoplay": "Reprodução automática",
+ "term.lyrics": "Letra",
+ "term.miniplayer": "Mini-leitor",
+ "term.history": "Histórico",
+ "term.search": "Pesquisa",
+ "term.showSearch": "Mostrar a barra de pesquisa",
+ "term.hideSearch": "Esconder a barar de pesquisa",
+ "term.library": "Biblioteca",
+ "term.listenNow": "Ouvir agora",
+ "term.browse": "Explorar",
+ "term.radio": "Rádio",
+ "term.recentlyAdded": "Adições recentes",
+ "term.songs": "Músicas",
+ "term.albums": "Álbuns",
+ "term.artists": "Intérpretes",
+ "term.podcasts": "Podcasts",
+ "term.playlists": "Listas de reprodução",
+ "term.charts": "Gráficos",
+ "term.playlist": "Lista de reprodução",
+ "term.newPlaylist": "Nova lista de reprodução",
+ "term.newPlaylistFolder": "Nova pasta de listas de reprodução",
+ "term.createNewPlaylist": "Criar nova lista de reprodução",
+ "term.createNewPlaylistFolder": "Criar nova pasta de listas de reprodução",
+ "term.deletePlaylist": "Tem a certeza de que pretende apagar esta lista de reprodução?",
+ "term.navigateBack": "Retroceder uma página",
+ "term.navigateForward": "Avançar uma página",
+ "term.play": "Reproduzir",
+ "term.playpause": "Reproduzir/Pausa",
+ "term.pause": "Pausa",
+ "term.stop": "Parar",
+ "term.previous": "Anterior",
+ "term.next": "Seguinte",
+ "term.shuffle": "Modo aleatório",
+ "term.enableShuffle": "Ativar modo aleatório",
+ "term.disableShuffle": "Desativar modo aleatório",
+ "term.repeat": "Repetir",
+ "term.enableRepeatOne": "Ativar repetir uma",
+ "term.disableRepeatOne": "Desativar repetir uma",
+ "term.disableRepeat": "Não repetir",
+ "term.volume": "Volume",
+ "term.mute": "Mudo",
+ "term.unmute": "Com som",
+ "term.share": "Partilhar",
+ "term.share.success": "Copiado para a área de transferência",
+ "term.settings": "Definições",
+ "term.seeAll": "Ver tudo",
+ "term.sortBy": "Ordenar por",
+ "term.sortBy.album": "Álbum",
+ "term.sortBy.artist": "Intérprete",
+ "term.sortBy.name": "Nome",
+ "term.sortBy.genre": "Género",
+ "term.sortBy.releaseDate": "Data de lançamento",
+ "term.sortBy.duration": "Duração",
+ "term.sortBy.dateAdded": "Data de adição",
+ "term.sortOrder": "A-Z",
+ "term.sortOrder.ascending": "Ascendente",
+ "term.sortOrder.descending": "Descendente",
+ "term.viewAs": "Ver como",
+ "term.viewAs.coverArt": "Grafismos",
+ "term.viewAs.list": "Lista",
+ "term.dynamic": "Dinâmico",
+ "term.size": "Tamanho",
+ "term.size.normal": "Normal",
+ "term.size.compact": "Compacto",
+ "term.enable": "Ativar",
+ "term.disable": "Desativar",
+ "term.enabled": "Ativado",
+ "term.disabled": "Desativado",
+ "term.connect": "Ligar",
+ "term.connecting": "A ligar",
+ "term.disconnect": "Desligar",
+ "term.authed": "Autenticado",
+ "term.confirm": "Confirmar?",
+ "term.more": "Mais",
+ "term.less": "Menos",
+ "term.showMore": "Mostrar mais",
+ "term.showLess": "Mostrar menos",
+ "term.topSongs": "Top de músicas",
+ "term.latestReleases": "Últimos lançamentos",
+ "term.time.added": "Adicionado",
+ "term.time.released": "Lançado",
+ "term.time.updated": "Atualizado",
+ "term.time.days": "dias",
+ "term.time.day": {
+ "one": "dia",
+ "other": "dias"
+ },
+ "term.time.hours": "horas",
+ "term.time.hour": {
+ "one": "hora",
+ "other": "horas"
+ },
+ "term.time.minutes": "minutos",
+ "term.time.minute": {
+ "one": "minuto",
+ "other": "minutos"
+ },
+ "term.time.seconds": "segundos",
+ "term.time.second": {
+ "one": "segundo",
+ "other": "segundos"
+ },
+ "term.fullscreenView": "Vista de ecrã inteiro",
+ "term.defaultView": "Vista normal",
+ "term.audioSettings": "Definições de áudio",
+ "term.audioControls": "Controlos de volume",
+ "term.clearAll": "Limpar tudo",
+ "term.recentStations": "Estações recentes",
+ "term.personalStations": "Estações pessoais",
+ "term.amLive": "Apple Music Live",
+ "term.live": "AO VIVO",
+ "term.language": "Idioma",
+ "term.funLanguages": "Divertido",
+ "term.noLyrics": "A carregar... / Letra não encontrada. / Instrumental.",
+ "term.copyright": "Copyright",
+ "term.rightsReserved": "Todos os direitos reservados.",
+ "term.sponsor": "Patrocine este projecto",
+ "term.ciderTeam": "Equipa do Cider",
+ "term.developer": "Programador",
+ "term.socialTeam": "Equipa social",
+ "term.socials": "Redes sociais",
+ "term.contributors": "Contribuidores",
+ "term.equalizer": "Equalizador",
+ "term.reset": "Repor",
+ "term.tracks": "músicas",
+ "term.track": {
+ "one": "música",
+ "other": "músicas"
+ },
+ "term.videos": "Vídeos",
+ "term.menu": "Menu",
+ "term.themeManaged": "Gerido por um tema",
+ "term.check": "Verificar",
+ "term.aboutArtist": "Sobre {{artistName}}",
+ "term.topResult": "Melhor resultado",
+ "term.sharedPlaylists": "Listas de reprodução partilhadas",
+ "term.people": "Pessoas",
+ "term.newpreset.name": "Nome da nova predefinição do EQ",
+ "term.addedpreset": "Predefinição adicionada",
+ "term.deletepreset.warn": "Tem a certeza de que pretende apagar esta predefinição?",
+ "term.deletedpreset": "Predefinição eliminada",
+ "term.defaultPresets": "Predefinições por omissão",
+ "term.userPresets": "Predefinições do utilizador",
+ "term.requestError": "Ocorreu um problema ao processar o pedido.",
+ "term.song.link.generate": "A obter o URL de partilha song.link...",
+ "term.musicVideos": "Videoclipes",
+ "term.stations": "Estações",
+ "term.curators": "Curadores",
+ "term.appleCurators": "Curadores da Apple",
+ "term.radioShows": "Programas de rádio",
+ "term.recordLabels": "Gravadoras",
+ "term.videoExtras": "Vídeos extra",
+ "term.top": "Top",
+ "term.version": "Versão",
+ "term.noVideos": "Não foram encontrados vídeos.",
+ "term.plugin": "Plug-in",
+ "term.pluginMenu": "Menu de plug-ins",
+ "term.pluginMenu.none": "Sem plug-ins interactivos",
+ "term.replay": "Repetir",
+ "term.uniqueAlbums": "Álbuns únicos",
+ "term.uniqueArtists": "Intérpretes únicos",
+ "term.uniqueSongs": "Músicas únicas",
+ "term.topArtists": "Top de intérpretes",
+ "term.listenedTo": "Reproduzido:",
+ "term.times": "vezes",
+ "term.topAlbums": "Top de álbuns",
+ "term.plays": "Reproduções",
+ "term.topGenres": "Top de géneros",
+ "term.confirmLogout": "Tem a certeza de que pretende terminar sessão?",
+ "term.creditDesignedBy": "Concebido por ${authorUsername}",
+ "term.discNumber": "Disco ${discNumber}",
+ "term.reload": "Reiniciar o Cider ?",
+ "term.toggleprivate": "Alternar sessão privada",
+ "term.webremote": "Web Remote",
+ "term.cast": "Transmitir",
+ "term.cast2": "Transmitir para dispositivos",
+ "term.quit": "Fechar",
+ "term.zoomin": "Aumentar o zoom",
+ "term.zoomout": "Diminuir o zoom",
+ "term.zoomreset": "Repor zoom",
+ "term.fullscreen": "Ecrã inteiro",
+ "home.syncFavorites": "Sincronizar favoritos",
+ "home.syncFavorites.gettingArtists": "A obter os artistas favoritos...",
+ "home.title": "Início",
+ "home.recentlyPlayed": "Reproduzido recentemente",
+ "home.recentlyAdded": "Adicionado recentemente",
+ "home.artistsFeed": "Feed dos seus artistas",
+ "home.artistsFeed.noArtist": "Siga alguns artistas para ver os seus últimos lançamentos",
+ "home.madeForYou": "Feito para si",
+ "home.friendsListeningTo": "O que os seus amigos estão a ouvir",
+ "home.followedArtists": "Artistas seguidos",
+ "error.appleMusicSubRequired": "A Apple Music requer uma subscrição.",
+ "error.connectionError": "Ocorreu um problema ao estabelecer ligação à Apple Music.",
+ "error.noResults": "Sem resultados.",
+ "error.noResults.description": "Tente uma nova pesquisa.",
+ "podcast.followOnCider": "Siga no Cider",
+ "podcast.followedOnCider": "A seguir no Cider",
+ "podcast.subscribeOnItunes": "Subscreva no iTunes",
+ "podcast.subscribedOnItunes": "Subscrito no iTunes",
+ "podcast.itunesStore": "iTunes Store",
+ "podcast.episodes": "Episódios",
+ "podcast.playEpisode": "Reproduzir episódio",
+ "podcast.website": "Website do Podcast",
+ "action.favorite": "Adicionar favorito",
+ "action.removeFavorite": "Remover favorito",
+ "action.hideLibrary": "Ocultar biblioteca",
+ "action.showLibrary": "Mostrar biblioteca",
+ "action.cut": "Cortar",
+ "action.paste": "Colar",
+ "action.selectAll": "Seleccionar tudo",
+ "action.delete": "Apagar",
+ "action.edit": "Editar",
+ "action.done": "Concluído",
+ "action.editTracklist": "Editar lista de reprodução",
+ "action.addToLibrary": "Adicionar à biblioteca",
+ "action.addToLibrary.success": "Adicionado à biblioteca",
+ "action.addToLibrary.error": "Erro ao adicionar à biblioteca",
+ "action.removeFromLibrary": "Remover da biblioteca",
+ "action.removeFromLibrary.success": "Removido da biblioteca",
+ "action.addToQueue": "Adicionar à fila",
+ "action.addToQueue.success": "Adicionado à fila",
+ "action.addToQueue.error": "Erro ao adicionar à fila",
+ "action.removeFromQueue": "Remover da fila",
+ "action.removeFromQueue.success": "Removido da fila",
+ "action.removeFromQueue.error": "Erro ao remover da fila",
+ "action.createPlaylist": "Criar uma nova lista de reprodução",
+ "action.addToPlaylist": "Adicionar à lista de reprodução",
+ "action.removeFromPlaylist": "Removar da lista de reprodução",
+ "action.addToFavorites": "Adicionar aos favoritos",
+ "action.follow": "Seguir",
+ "action.follow.success": "Seguido",
+ "action.follow.error": "Erro ao seguir",
+ "action.unfollow": "Não seguir",
+ "action.unfollow.success": "Não seguido",
+ "action.unfollow.error": "Erro ao deixar de seguir",
+ "action.playNext": "Reproduzir a seguir",
+ "action.playLater": "Reproduzir mais tarde",
+ "action.startRadio": "Criar estação",
+ "action.goToArtist": "Ir para intérprete",
+ "action.goToAlbum": "Ir para álbum",
+ "action.showInPlaylist": "Mostrar na lista de reprodução",
+ "action.showInAppleMusic": "Mostrar na Apple Music",
+ "action.moveToTop": "Mover para fora da pasta",
+ "action.share": "Partilhar",
+ "action.rename": "Renomear",
+ "action.love": "Gostar",
+ "action.unlove": "Desfazer gostar",
+ "action.dislike": "Não gostar",
+ "action.undoDislike": "Desfazer não gostar",
+ "action.showWebRemoteQR": "Web Remote",
+ "action.playTracksNext": "Reproduzir ${app.selectedMediaItems.length} músicas a seguir",
+ "action.playTracksLater": "Reproduzir ${app.selectedMediaItems.length} músicas mais tarde",
+ "action.removeTracks": "Remover ${self.selectedItems.length} músicas da fila",
+ "action.import": "Importar",
+ "action.export": "Exportar",
+ "action.showAlbum": "Mostrar álbum completo",
+ "action.tray.minimize": "Minimizar para a bandeja",
+ "action.tray.show": "Mostrar o Cider",
+ "action.tray.listento": "Ouvir:",
+ "action.update": "Atualizar",
+ "action.install": "Instalar",
+ "action.copy": "Copiar",
+ "action.newpreset": "Nova predefinição...",
+ "action.deletepreset": "Eliminar predefinição",
+ "action.open": "Abrir",
+ "action.close": "Fechar",
+ "action.relaunch.confirm": "Pretende reiniciar o Cider?",
+ "action.cast.chromecast": "Chromecast",
+ "action.cast.todevices": "Transmitir para dispositivos",
+ "action.cast.stop": "Parar a transmissão para todos os dispositivos",
+ "action.cast.airplay": "AirPlay",
+ "action.cast.airplay.underdevelopment": "AirPlay ainda está em desenvolvimento",
+ "action.cast.scan": "Procurar",
+ "action.cast.scanning": "A procurar...",
+ "action.createNew": "Criar nova...",
+ "action.openArtworkInBrowser": "Abrir grafismo no navegador",
+ "action.scrollToTop": "Voltar ao topo",
+ "menubar.options.view": "Ver",
+ "menubar.options.reload": "Atualizar",
+ "menubar.options.forcereload": "Forçar atualização",
+ "menubar.options.toggledevtools": "Alternar ferramentas do programador",
+ "menubar.options.window": "Janela",
+ "menubar.options.minimize": "Minimizar",
+ "menubar.options.plugins": "Menu de plug-ins",
+ "menubar.options.controls": "Controlos",
+ "menubar.options.volumeup": "Aumentar o volume",
+ "menubar.options.volumedown": "Diminuir o volume",
+ "menubar.options.account": "Conta",
+ "menubar.options.signout": "Terminar sessão",
+ "menubar.options.support": "Suporte",
+ "menubar.options.report": "Reportar um...",
+ "menubar.options.bug": "Problema",
+ "menubar.options.feature": "Pedido de funcionalidade",
+ "menubar.options.trans": "Pedido de tradução",
+ "menubar.options.license": "Ver licença",
+ "menubar.options.conf": "Abrir ficheiro de configuração no editor",
+ "menubar.options.zoom": "Zoom",
+ "settings.header.general": "Geral",
+ "settings.header.general.description": "Ajustar as definições gerais do Cider.",
+ "settings.option.general.language": "Idioma",
+ "settings.option.general.resumebehavior": "Comportamento de retoma",
+ "settings.option.general.resumebehavior.description": "Define a forma como o Cider irá retomar a sua sessão quando regressar à aplicação.",
+ "settings.option.general.resumebehavior.locally": "Localmente",
+ "settings.option.general.resumebehavior.locally.description": "O Cider irá retomar a sua última sessão nesta máquina.",
+ "settings.option.general.resumebehavior.history": "Histórico",
+ "settings.option.general.resumebehavior.history.description": "O Cider irá colocar na fila a última música do seu histórico da Apple Music, através de todos os seus dispositivos.",
+ "settings.option.general.resumetabs": "Abrir separador no arranque",
+ "settings.option.general.resumetabs.description": "Pode escolher que separador quer abrir quando abre o Cider.",
+ "settings.option.general.resumetabs.dynamic": "Dinâmico",
+ "settings.option.general.resumetabs.dynamic.description": "O Cider abrirá o separador que utilizou pela última vez.",
+ "settings.option.general.language.main": "Idiomas",
+ "settings.option.general.language.fun": "Idiomas divertidos",
+ "settings.option.general.language.unsorted": "Indiferenciado",
+ "settings.option.general.customizeSidebar": "Personalizar os itens da barra lateral",
+ "settings.option.general.customizeSidebar.customize": "Personalizar",
+ "settings.option.general.keybindings": "Atalhos do teclado",
+ "settings.option.general.keybindings.library": "Biblioteca",
+ "settings.option.general.keybindings.session": "Sessão",
+ "settings.option.general.keybindings.control": "Controlos",
+ "settings.option.general.keybindings.interface": "Interface",
+ "settings.option.general.keybindings.advanced": "Avançado",
+ "settings.option.general.keybindings.pressCombination": "Prima uma combinação de duas teclas para atualizar o atalho.",
+ "settings.option.general.keybindings.pressEscape": "Prima a tecla Escape para voltar atrás.",
+ "settings.notyf.general.keybindings.update.success": "Atalho atualizado com sucesso",
+ "settings.prompt.general.keybindings.update.success": "Atalho atualizado com sucesso. Prima OK para reiniciar o Cider",
+ "settings.option.general.themeUpdateNotification": "Verificação automática de atualizações de temas",
+ "settings.option.general.showLovedTracksInline": "Mostrar músicas que gosta \"inline\"",
+ "settings.description.search": "Pesquisa",
+ "settings.description.albums": "Álbuns da biblioteca",
+ "settings.description.artists": "Intérpretes da biblioteca",
+ "settings.description.browse": "Explorar",
+ "settings.description.private": "Alternar sessão privada",
+ "settings.description.remote": "Web Remote",
+ "settings.description.audio": "Definições de áudio",
+ "settings.description.plugins": "Menu de plug-ins",
+ "settings.description.cast": "Transmitir para dispositivos",
+ "settings.description.settings": "Definições",
+ "settings.description.developer": "Ferramentas do programador",
+ "settings.description.listnow": "Ouvir agora",
+ "settings.description.recentAdd": "Adições recentes",
+ "settings.description.songs": "Músicas",
+ "settings.notyf.updateCider.update-not-available": "Nenhuma atualização disponível",
+ "settings.notyf.updateCider.update-downloaded": "A atualização foi descarregada, reinicie para aplicar",
+ "settings.notyf.updateCider.update-timeout": "O pedido de atualização estou o tempo limite",
+ "settings.header.audio": "Áudio",
+ "settings.header.audio.description": "Ajustar as definições de áudio para o Cider.",
+ "settings.option.audio.volumeStep": "Nível de incremento de volume",
+ "settings.option.audio.advanced": "Controlo avançado de volume",
+ "settings.option.audio.maxVolume": "Volume máximo",
+ "settings.option.audio.changePlaybackRate": "Alterar velocidade de reprodução",
+ "settings.option.audio.playbackRate": "Velocidade de reprodução",
+ "settings.option.audio.playbackRate.change": "Alterar",
+ "settings.option.audio.quality": "Qualidade do áudio",
+ "settings.header.audio.quality.hireslossless": "Alta resolução sem perdas",
+ "settings.header.audio.quality.hireslossless.description": "até 24-bit/192 kHz",
+ "settings.header.audio.quality.lossless": "Sem perdas",
+ "settings.header.audio.quality.lossless.description": "até 24-bit/48 kHz",
+ "settings.header.audio.quality.high": "Alta",
+ "settings.header.audio.quality.high.description": "256 kbps",
+ "settings.header.audio.quality.standard": "Padrão",
+ "settings.header.audio.quality.standard.description": "64 kbps",
+ "settings.option.audio.seamlessTransition": "Transição gradual do áudio",
+ "settings.option.audio.enableAdvancedFunctionality": "Ativar funcionalidades avançadas",
+ "settings.option.audio.enableAdvancedFunctionality.description": "Ativar o AudioContext dá acesso a funcionalidades alargadas como Normalização de Áudio, Equalizadores e Visualizadores - contudo, isto pode causar dificuldades em alguns sistemas.",
+ "settings.warn.audio.enableAdvancedFunctionality.lowcores": "O Cider pensa que o seu PC não é capaz de lidar com estas funcionalidades. Tem a certeza de que pretende continuar?",
+ "settings.option.audio.audioLab": "Cider Audio Lab",
+ "settings.option.audio.audioLab.description": "Efeitos de áudio desenvolvidos internamente para o Cider.",
+ "settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California",
+ "settings.warn.audioLab.withoutAF": "AudioContext (funcionalidade avançada) é necessário para suportar o Cider Audio Lab.",
+ "settings.warn.enableAdvancedFunctionality": "AudioContext (funcionalidade avançada) é necessário para suportar esta funcionalidade.",
+ "settings.option.audio.enableAdvancedFunctionality.analogWarmth": "Calor Analógico",
+ "settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "Simula o calor analógico inspirado no Korg Nutube 6P1",
+ "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "Intensidade do calor analógico",
+ "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.description": "Altera a intensidade do processamento do módulo de calor analógico.",
+ "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.smooth": "Suave",
+ "settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity.warm": "Quente",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer": "Cider Atmosphere Realizer™️",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer.description": "Cria uma atmosfera musical diferente inspirada nas mais modernas aparelhagens.",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode": "Modo do Cider Atmosphere Realizer™️",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Altera o modo de funcionamento do módulo Atmosphere Realizer.",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Hōjicha Cheese Foam Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Genmaicha Tapioca Milk Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_1": "Rock Salt Cheese Foam Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_2": "Uji Matcha Milk Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "Jasmine Macchiato",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500A": "Moonwight Softcake",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500B": "Clafoutis aux Cerises",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500C": "Uji Matcha Mochi",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Melhora a qualidade de áudio percecionada do áudio codificado em AAC, utilizando um algoritmo de tempo real que tira partido tanto dos modelos psicoacústicos da audição humana como das características de codificação do AAC.",
+ "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "O CAP não é compatível com a espacialização. Por favor, desative a espacialização para continuar.",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "Intensidade do CAP",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "Muda a intensidade do processamento feito ao áudio (a agressividade pode produzir resultados indesejáveis).",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "Padrão",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "Adaptativo",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "Antigo",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "Agressivo",
+ "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "Normalização de áudio",
+ "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "Normaliza o volume de pico das músicas para criar uma experiência de audição mais uniforme (não funciona em músicas carregadas pelo utilizador).",
+ "settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "Gerido pelo Audio Lab",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization": "Espacialização ajustada pelo Cider",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Efeito de espacialização pré-ajustado, desactiva as configurações personalizáveis de espacialização de áudio.",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Perfil de espacialização do Cider",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Altera o perfil de ajuste da espacialização.",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Padrão",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "Palco",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Separação",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Mínimo",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiófilo",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Difundido",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Encore expandido",
+ "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "A espacialização não é compatível com o CAP. Por favor, desative o CAP para continuar.",
+ "settings.option.audio.dbspl.display": "Mostrar dB SPL",
+ "settings.option.audio.dbspl.description": "(Apenas para utilizadores avançados) Mostrar dB SPL em vez de dBFS no controlo de volume.",
+ "settings.option.audio.dbfs.calibration": "Calibração de 0 dBFS",
+ "settings.option.audio.dbfs.description": "Introduza o pico de SPL com ponderação Z quando o Cider está a 0 dBFS.",
+ "settings.header.visual": "Aparência",
+ "settings.header.visual.description": "Ajustar as definições visuais do Cider.",
+ "settings.option.visual.windowStyle": "Estilo da janela",
+ "settings.option.visual.customAccentColor": "Cor de destaque personalizada",
+ "settings.option.visual.accentColor": "Cor de destaque",
+ "settings.option.visual.purplePodcastPlaybackBar": "Barra de reprodução roxa para Podcasts",
+ "settings.option.visual.windowColor": "Tonalidade da cor da janela",
+ "settings.header.visual.windowBackgroundStyle.color": "Tonalidade da cor",
+ "settings.option.visual.windowBackgroundStyle": "Estilo do fundo da janela",
+ "settings.header.visual.windowBackgroundStyle.none": "Nenhum",
+ "settings.header.visual.windowBackgroundStyle.artwork": "Grafismo",
+ "settings.header.visual.windowBackgroundStyle.image": "Imagem",
+ "settings.option.visual.animatedArtwork": "Grafismo animado",
+ "settings.header.visual.animatedArtwork.always": "Sempre",
+ "settings.header.visual.animatedArtwork.limited": "Limitado a páginas e entradas especiais",
+ "settings.header.visual.animatedArtwork.disable": "Desativar em todo o lado",
+ "settings.option.visual.animatedArtworkQuality": "Qualidade dos grafismos animados",
+ "settings.header.visual.animatedArtworkQuality.low": "Baixa",
+ "settings.header.visual.animatedArtworkQuality.medium": "Média",
+ "settings.header.visual.animatedArtworkQuality.high": "Alta",
+ "settings.header.visual.animatedArtworkQuality.veryHigh": "Muito alta",
+ "settings.header.visual.animatedArtworkQuality.extreme": "Extrema",
+ "settings.option.visual.animatedWindowBackground": "Fundo da janela animado",
+ "settings.option.visual.hardwareAcceleration": "Aceleração de hardware",
+ "settings.option.visual.hardwareAcceleration.description": "Requer reinício",
+ "settings.header.visual.hardwareAcceleration.default": "Padrão",
+ "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
+ "settings.option.visual.uiscale": "Escala da UI",
+ "settings.header.visual.theme": "Tema",
+ "settings.option.visual.theme.github.download": "Instalar a partir de um URL do GitHub",
+ "settings.option.visual.theme.github.openfolder": "Abrir pasta de temas",
+ "settings.option.visual.theme.github.explore": "Explorar temas do GitHub",
+ "settings.header.visual.theme.github.page": "Temas do GitHub",
+ "settings.option.visual.theme.github.install.confirm": "Tem a certeza de que pretende instalar {{ repo }}?",
+ "settings.prompt.visual.theme.github.URL": "Introduza o URL do tema que pretende instalar",
+ "settings.prompt.visual.theme.uninstallTheme": "Tem a certeza de que pretende desinstalar {{ theme }}?",
+ "settings.option.visual.theme.checkForUpdates": "Procurar por atualizações",
+ "settings.option.visual.theme.manageStyles": "Gerir estilos",
+ "settings.option.visual.theme.uninstall": "Desinstalar",
+ "settings.option.visual.theme.viewInfo": "Ver informação",
+ "settings.option.visual.theme.github.available": "Disponível",
+ "settings.option.visual.theme.github.applied": "Aplicado",
+ "settings.notyf.visual.theme.install.success": "Tema instalado com sucesso",
+ "settings.notyf.visual.theme.install.error": "A instalação do tema falhou",
+ "settings.header.visual.plugin": "Plug-in",
+ "settings.option.visual.plugin.github.download": "Instalar a partir de um URL do GitHub",
+ "settings.option.visual.plugin.github.explore": "Explorar plug-ins do GitHub",
+ "settings.header.visual.plugin.github.page": "Plug-ins do GitHub",
+ "settings.option.visual.plugin.github.install.confirm": "Tem a certeza de que pretende instalar {{ repo }}?",
+ "settings.prompt.visual.plugin.github.URL": "Introduza o URL do plug-in que pretende instalar",
+ "settings.prompt.visual.plugin.github.success": "Plug-in instalado com sucesso. Pressione OK para reiniciar o Cider",
+ "settings.notyf.visual.plugin.install.success": "Plug-in instalado com sucesso",
+ "settings.notyf.visual.plugin.install.error": "A instalação do plug-in falhou",
+ "settings.option.visual.theme.default": "Cider",
+ "settings.option.visual.theme.dark": "Escuro",
+ "settings.option.visual.showPersonalInfo": "Mostrar informação pessoal",
+ "settings.header.window": "Janela",
+ "settings.header.window.description": "Ajustar as definições da janela para o Cider.",
+ "settings.option.window.openOnStartup": "Abrir o Cider no arranque",
+ "settings.option.window.openOnStartup.hidden": "Abrir escondido",
+ "settings.option.window.useNativeTitleBar": "Usar barra de título nativa",
+ "settings.option.window.windowControlStyle": "Estilo de controlo da janela",
+ "settings.option.window.windowControlStyle.right": "Direita",
+ "settings.option.window.windowControlStyle.left": "Esquerda",
+ "settings.header.lyrics": "Letras",
+ "settings.header.lyrics.description": "Ajustar as definições de letras para o Cider.",
+ "settings.option.lyrics.enableMusixmatch": "Ativar letras do Musixmatch",
+ "settings.option.lyrics.enableMusixmatchKaraoke": "Ativar o modo Karaoke (apenas para o Musixmatch)",
+ "settings.option.lyrics.musixmatchPreferredLanguage": "Língua preferida para traduções do Musixmatch",
+ "settings.option.lyrics.enableYoutubeLyrics": "Ativar letras do Youtube para videoclipes",
+ "settings.option.lyrics.enableQQLyrics": "Ativar letras do QQ",
+ "settings.header.connectivity": "Conectividade",
+ "settings.header.connectivity.description": "Ajustar as definições de conectividade para o Cider.",
+ "settings.option.connectivity.playbackNotifications": "Notificações de reprodução",
+ "settings.option.connectivity.discordRPC": "Discord Rich Presence",
+ "settings.option.connectivity.discordRPC.clientName": "Nome do cliente",
+ "settings.option.connectivity.discordRPC.clearOnPause": "Limpar o Discord Rich Presence ao colocar em pausa",
+ "settings.option.connectivity.discordRPC.hideButtons": "Esconder botões no Discord Rich Presence",
+ "settings.option.connectivity.discordRPC.hideTimestamp": "Esconder timestamp no Discord Rich Presence",
+ "settings.option.connectivity.discordRPC.detailsFormat": "Formato dos detalhes",
+ "settings.option.connectivity.discordRPC.stateFormat": "Formato do estado",
+ "settings.option.connectivity.discordRPC.reload": "Reiniciar o DiscordRPC",
+ "settings.option.connectivity.discordRPC.reconnectedToUser": "DiscordRPC ligação restabelecida ao utilizador: {{user}} ({{userid}})",
+ "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling",
+ "settings.option.connectivity.lastfmScrobble.delay": "Last.fm atraso do scrobble (%)",
+ "settings.option.connectivity.lastfmScrobble.nowPlaying": "Ativar Last.fm Now Playing",
+ "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remover artistas do título da música (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.filterLoop": "Filtrar música em loop (Last.fm)",
+ "settings.header.debug": "Debug",
+ "settings.option.debug.copy_log": "Copiar logs para a área de transferência",
+ "settings.option.debug.openAppData": "Abrir pasta do Cider",
+ "settings.header.experimental": "Experimental",
+ "settings.header.experimental.description": "Ajustar as definições experimentais para o Cider.",
+ "settings.option.experimental.reinstallwidevine": "Reinstalar WidevineCDM",
+ "settings.option.experimental.reinstallwidevine.confirm": "Tem a certeza de que pretende reinstalar o Widevine?",
+ "settings.option.experimental.unknownPlugin": "Fontes desconhecidas",
+ "settings.option.experimental.unknownPlugin.description": "Permitir a instalação de plug-ins de outros repositórios que não o repositório de plug-ins do Cider",
+ "settings.option.experimental.compactUI": "UI compacta",
+ "settings.option.window.close_button_hide": "Botão fechar oculta a aplicação",
+ "settings.option.experimental.inline_playlists": "Listas de reprodução e álbuns \"inline\"",
+ "settings.option.advanced.playlistTrackMapping": "Mapeamento de músicas de listas de reprodução",
+ "settings.option.advanced.playlistTrackMapping.description": "Ativa uma análise profunda das listas de reprodução para determinar que músicas estão em que listas de reprodução. O tempo de construção da cache das listas de reprodução pode aumentar significativamente.",
+ "settings.option.visual.transparent": "Moldura transparente",
+ "settings.option.visual.transparent.description": "Necessita de suporte do tema, requer reinício",
+ "settings.header.advanced": "Avançado",
+ "settings.header.connect": "Sincronização",
+ "settings.option.connect.link_account": "Ativar a sincronização com o Cider Connect",
+ "settings.option.connect.link_account.description": "Ligar a sua conta Discord ao Cider Connect permite-lhe armazenar dados de utilizador incluindo definições, EQ's, e eventualmente mais uma vez terminado (trabalho em curso).",
+ "spatial.notTurnedOn": "A espacialização de áudio está desativada. Para utilizar, por favor, ative-a primeiro.",
+ "spatial.spatialProperties": "Propriedades espaciais",
+ "spatial.width": "Largura",
+ "spatial.height": "Altura",
+ "spatial.depth": "Profundidade",
+ "spatial.gain": "Ganho",
+ "spatial.roomMaterials": "Materiais da sala",
+ "spatial.roomDimensions": "Dimensões da sala",
+ "spatial.roomPositions": "Posições na sala",
+ "spatial.setDimensions": "Definir dimensões",
+ "spatial.setPositions": "Definir posições",
+ "spatial.up": "Acima",
+ "spatial.front": "Frente",
+ "spatial.left": "Esquerda",
+ "spatial.right": "Direita",
+ "spatial.back": "Atrás",
+ "spatial.down": "Em baixo",
+ "spatial.listener": "Ouvinte",
+ "spatial.audioSource": "Fonte de áudio",
+ "settings.header.unfinished": "Inacabado",
+ "remote.web.title": "Cider Remote",
+ "remote.web.description": "Digitalize o código QR para emparelhar o seu telemóvel com esta instância do Cider",
+ "share.platform.twitter.tweet": "Ouça {{song}} na Apple Music.\n\n{{url}}\n\n#AppleMusic #Cider",
+ "share.platform.twitter": "Twitter",
+ "share.platform.facebook": "Facebook",
+ "share.platform.reddit": "Reddit",
+ "share.platform.telegram": "Telegram",
+ "share.platform.whatsapp": "WhatsApp",
+ "share.platform.messenger": "Messenger",
+ "share.platform.email": "Email",
+ "share.platform.songLink": "Copiar com song.link",
+ "share.platform.clipboard": "Copiar ligação",
+ "about.thanks": "Um grande obrigado à equipa da Cider Collective e a todos os nossos contribuidores."
}
diff --git a/src/i18n/source/en_US.json b/src/i18n/source/en_US.json
index 7c9a36cb..b01419a5 100644
--- a/src/i18n/source/en_US.json
+++ b/src/i18n/source/en_US.json
@@ -31,6 +31,12 @@
"term.miniplayer": "MiniPlayer",
"term.history": "History",
"term.search": "Search",
+ "term.scroll": "Scroll Mode",
+ "term.scroll.infinite": "Infinite",
+ "term.scroll.paged": "${songsPerPage} per page",
+ "term.live": "LIVE",
+ "term.showSearch": "Show search bar",
+ "term.hideSearch": "Hide search bar",
"term.library": "Library",
"term.listenNow": "Listen Now",
"term.browse": "Browse",
@@ -136,7 +142,7 @@
"term.amLive": "Apple Music Live",
"term.language": "Language",
"term.funLanguages": "Fun",
- "term.noLyrics": "Loading... / Lyrics not found./ Instrumental.",
+ "term.noLyrics": "Instrumental Track / No Lyrics.",
"term.copyright": "Copyright",
"term.rightsReserved": "All Rights Reserved.",
"term.sponsor": "Sponsor this project",
@@ -178,8 +184,9 @@
"term.top": "Top",
"term.version": "Version",
"term.noVideos": "No videos found.",
- "term.plugin": "Plug-in",
- "term.pluginMenu": "Plug-in Menu",
+ "term.plugins": "Plugins",
+ "term.plugin": "Plugin",
+ "term.pluginMenu": "Plugins Menu",
"term.pluginMenu.none": "No interactive plugins",
"term.replay": "Replay",
"term.uniqueAlbums": "Unique Albums",
@@ -194,7 +201,7 @@
"term.confirmLogout": "Are you sure you want to logout?",
"term.creditDesignedBy": "Designed by ${authorUsername}",
"term.discNumber": "Disc ${discNumber}",
- "term.reload" : "Reload Cider ?",
+ "term.reload" : "Reload Cider?",
"term.toggleprivate" : "Toggle Private Session",
"term.webremote" : "Web Remote",
"term.cast" : "Cast",
@@ -204,6 +211,12 @@
"term.zoomout" : "Zoom Out",
"term.zoomreset" : "Reset Zoom",
"term.fullscreen" : "Fullscreen",
+ "term.nowPlaying": "Now Playing",
+ "home.syncFavorites": "Sync Favorites",
+ "home.syncFavorites.gettingArtists": "Getting Favorited Artists...",
+ "action.favorite": "Favorite",
+ "action.removeFavorite": "Remove Favorite",
+ "action.refresh": "Refresh",
"home.title": "Home",
"home.recentlyPlayed": "Recently Played",
"home.recentlyAdded": "Recently Added",
@@ -232,6 +245,7 @@
"action.delete": "Delete",
"action.edit": "Edit",
"action.done": "Done",
+ "action.submit": "Submit",
"action.editTracklist": "Edit Tracklist",
"action.addToLibrary": "Add to Library",
"action.addToLibrary.success": "Added to Library",
@@ -407,6 +421,8 @@
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "Hokkaido Milk Tea",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500A": "Moonlight Softcake",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "Brown Sugar Creme Brûlée Milk",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500B": "Clafoutis aux Cerises",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500C": "Uji Matcha Mochi",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "Cuddle Warmth",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider Adrenaline Processor™️",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Enhances the perceived audio quality of AAC encoded audio by using a real-time algorithm that takes advantage of both psychoacoustic models of human hearing and AAC encoding characteristics.",
@@ -469,6 +485,7 @@
"settings.prompt.visual.theme.github.URL": "Enter the URL of the theme you want to install",
"settings.prompt.visual.theme.uninstallTheme": "Are you sure you want to uninstall {{ theme }}?",
"settings.option.visual.theme.checkForUpdates": "Check for updates",
+ "settings.header.visual.styles": "Styles",
"settings.option.visual.theme.manageStyles": "Manage Styles",
"settings.option.visual.theme.uninstall": "Uninstall",
"settings.option.visual.theme.viewInfo": "View Info",
@@ -520,6 +537,12 @@
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Enable Last.fm Now Playing",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (Last.fm)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.filterLoop.description": "Prevent looped tracks from being scrobbled or displayed in the Now Playing list on Last.fm.",
+ "settings.option.connectivity.lastfmScrobble.filterTypes": "Filter Media Types (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.manualToken": "Enter Last.fm Token Manually",
+ "settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection Timed Out",
+ "settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.fm Connection Successful",
+ "settings.notyf.connectivity.lastfmScrobble.connecting": "Connecting to Last.fm...",
"settings.header.debug": "Debug",
"settings.option.debug.copy_log": "Copy logs to clipboard",
"settings.option.debug.openAppData": "Open Cider Folder",
@@ -531,11 +554,17 @@
"settings.option.experimental.unknownPlugin.description": "Allow installation of plugins from repos other than the Cider Plugin Repository",
"settings.option.experimental.compactUI": "Compact UI",
"settings.option.window.close_button_hide": "Close Button Should Hide the Application",
+ "settings.option.window.maxElementScale": "Maximum Element Scale",
"settings.option.experimental.inline_playlists": "Inline Playlists and Albums",
"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. Playlist cache build times can increase significantly.",
"settings.option.visual.transparent": "Transparent frame",
"settings.option.visual.transparent.description": "needs Theme Support, requires relaunch",
+ "settings.option.visual.customAccentColor": "Custom Accent Color",
+ "settings.option.visual.accentColor": "Accent Color",
+ "settings.option.visual.purplePodcastPlaybackBar": "Purple Playback Bar for Podcasts",
+ "settings.option.visual.windowColor": "Window Tint Color",
+ "settings.header.visual.windowBackgroundStyle.color": "Color Tint",
"settings.header.advanced": "Advanced",
"settings.header.connect": "Sync",
"settings.option.connect.link_account": "Enable Sync with Cider Connect",
@@ -612,4 +641,4 @@
"oobe.visual.suggestingThemes.community3": "Dracula",
"oobe.visual.suggestingThemes.community3.text": "The iconic Dracula color scheme.",
"oobe.amsignin.title": ""
-}
+}
\ No newline at end of file
diff --git a/src/i18n/zh_CN.json b/src/i18n/zh_CN.json
index 9e726cb9..100546db 100644
--- a/src/i18n/zh_CN.json
+++ b/src/i18n/zh_CN.json
@@ -2,7 +2,7 @@
"i18n.languageName": "简体中文(中国)",
"i18n.languageNameEnglish": "Simp. Chinese (China)",
"i18n.category": "main",
- "i18n.authors": "@notmaikiwi @BillKerman @jay900604",
+ "i18n.authors": "@notmaikiwi @BillKerman @jay900604 @sakura0224",
"app.name": "Cider",
"date.format": "${y}年${m}月${d}日",
"dialog.cancel": "取消",
@@ -21,17 +21,22 @@
"term.accountSettings": "账户设置",
"term.logout": "退出登录",
"term.login": "登录",
- "term.quickNav":"快速导航",
- "term.cast":"投射",
+ "term.quickNav": "快速导航",
"term.about": "关于",
"term.privateSession": "隐身聆听",
- "term.disablePrivateSession":"停止隐身聆听",
- "term.autoplay":"自动播放",
- "term.lyrics": "歌词",
+ "term.disablePrivateSession": "停止隐身聆听",
"term.queue": "待播清单",
- "term.history": "历史记录",
+ "term.autoplay": "自动播放",
+ "term.lyrics": "歌词",
"term.miniplayer": "迷你播放器",
+ "term.history": "历史记录",
"term.search": "搜索",
+ "term.scroll": "滚动模式",
+ "term.scroll.infinite": "无限制",
+ "term.scroll.paged": "每页${songsPerPage}首",
+ "term.live": "LIVE",
+ "term.showSearch": "显示搜索栏",
+ "term.hideSearch": "隐藏搜索栏",
"term.library": "资料库",
"term.listenNow": "现在就听",
"term.browse": "浏览",
@@ -42,23 +47,24 @@
"term.artists": "艺人",
"term.podcasts": "播客",
"term.playlists": "播放列表",
- "term.charts":"排行榜",
+ "term.charts": "排行榜",
"term.playlist": "播放列表",
"term.newPlaylist": "新播放列表",
"term.newPlaylistFolder": "新播放列表文件夹",
"term.createNewPlaylist": "新建播放列表",
"term.createNewPlaylistFolder": "新建播放列表文件夹",
"term.deletePlaylist": "您确定要删除该播放列表吗?",
- "term.navigateBack":"上一页",
- "term.navigateForward":"下一页",
+ "term.navigateBack": "上一页",
+ "term.navigateForward": "下一页",
"term.play": "播放",
+ "term.playpause": "播放/暂停",
"term.pause": "暂停",
"term.stop": "停止",
"term.previous": "上一首",
"term.next": "下一首",
"term.shuffle": "随机播放",
- "term.enableShuffle":"开启随机播放",
- "term.disableShuffle":"关闭随机播放",
+ "term.enableShuffle": "开启随机播放",
+ "term.disableShuffle": "关闭随机播放",
"term.repeat": "循环播放",
"term.enableRepeatOne": "开启单曲循环",
"term.disableRepeatOne": "关闭单曲循环",
@@ -67,7 +73,7 @@
"term.mute": "静音",
"term.unmute": "解除静音",
"term.share": "分享",
- "term.share.success": "已拷貝到剪贴板",
+ "term.share.success": "已拷贝到剪贴板",
"term.settings": "设置",
"term.seeAll": "查看全部",
"term.sortBy": "排序",
@@ -77,14 +83,14 @@
"term.sortBy.genre": "类型",
"term.sortBy.releaseDate": "发行日期",
"term.sortBy.duration": "时长",
- "term.sortBy.dateAdded":"加入日期",
+ "term.sortBy.dateAdded": "加入日期",
"term.sortOrder": "字母排序",
"term.sortOrder.ascending": "升序",
"term.sortOrder.descending": "倒序",
"term.viewAs": "显示模式",
"term.viewAs.coverArt": "专辑封面",
"term.viewAs.list": "列表",
- "term.dynamic":"动态",
+ "term.dynamic": "动态",
"term.size": "大小",
"term.size.normal": "正常",
"term.size.compact": "紧凑",
@@ -106,6 +112,8 @@
"term.time.added": "添加于",
"term.time.released": "发行于",
"term.time.updated": "更新于",
+ "term.time.days": "天",
+ "term.time.day": "天",
"term.time.hours": "小时",
"term.time.hour": "小时",
"term.time.minutes": "分钟",
@@ -118,8 +126,8 @@
"term.audioSettings": "音频设置",
"term.clearAll": "清空",
"term.recentStations": "最近播放的广播",
- "term.personalStations":"最近播放的个人广播",
- "term.amLive":"amLive",
+ "term.personalStations": "最近播放的个人广播",
+ "term.amLive": "Apple Music Live",
"term.language": "语言",
"term.funLanguages": "恶搞",
"term.noLyrics": "加载中... / 无搜索结果 / 纯音乐",
@@ -133,13 +141,11 @@
"term.contributors": "贡献者",
"term.equalizer": "均衡器",
"term.reset": "重置",
- "term.track": {
- "one": "首歌曲",
- "other": "首歌曲"
- },
"term.tracks": "歌曲",
+ "term.track": "首歌曲",
"term.videos": "音乐视频",
"term.menu": "菜单",
+ "term.themeManaged": "由主题所管理",
"term.check": "检查",
"term.aboutArtist": "关于{{artistName}}",
"term.topResult": "热门搜索结果",
@@ -155,30 +161,47 @@
"term.song.link.generate": "获取 song.link 共享链接...",
"term.musicVideos": "音乐视频",
"term.stations": "电台",
+ "term.curators": "策展人",
+ "term.appleCurators": "Apple 策展人",
"term.radioShows": "广播单集",
"term.recordLabels": "唱片公司",
"term.videoExtras": "视频特辑",
- "term.top":"顶部",
+ "term.top": "顶部",
"term.version": "版本",
- "term.noVideos":"无视频",
+ "term.noVideos": "无视频",
+ "term.plugins": "插件",
"term.plugin": "插件",
"term.pluginMenu": "插件菜单",
"term.pluginMenu.none": "沒有交互式插件",
- "term.replay":"音乐回忆",
- "term.uniqueAlbums":"Unique Albums",
- "term.uniqueArtists":"Unique Artists",
- "term.uniqueSongs":"Unique Songs",
- "term.topArtists":"热门艺人",
- "term.listenedTo":"听过",
- "term.times":"次",
- "term.topAlbums":"热门专辑",
- "term.plays":"次",
- "term.topGenres":"热门类型",
- "term.confirmLogout":"你确定要退出登录吗?",
- "term.creditDesignedBy":"由 ${authorUsername} 设计",
- "term.discNumber":"碟 ${discNumber}",
+ "term.replay": "音乐回忆",
+ "term.uniqueAlbums": "独特专辑",
+ "term.uniqueArtists": "超绝艺人",
+ "term.uniqueSongs": "别致单曲",
+ "term.topArtists": "热门艺人",
+ "term.listenedTo": "听过",
+ "term.times": "次",
+ "term.topAlbums": "热门专辑",
+ "term.plays": "次",
+ "term.topGenres": "热门类型",
+ "term.confirmLogout": "你确定要退出登录吗?",
+ "term.creditDesignedBy": "由 ${authorUsername} 设计",
+ "term.discNumber": "碟 ${discNumber}",
+ "term.reload" : "重新载入 Cider?",
+ "term.toggleprivate": "切换隐身聆听",
+ "term.webremote": "远程控制",
+ "term.cast": "投射",
+ "term.cast2" : "投射到设备",
+ "term.quit" : "退出应用",
+ "term.zoomin" : "放大",
+ "term.zoomout" : "缩小",
+ "term.zoomreset" : "重置缩放",
+ "term.fullscreen" : "全屏模式",
+ "term.nowPlaying": "正在播放",
"home.syncFavorites": "同步喜爱艺人",
"home.syncFavorites.gettingArtists": "获取喜爱艺人...",
+ "action.favorite": "喜爱",
+ "action.removeFavorite": "取消喜爱",
+ "action.refresh": "刷新",
"home.title": "主页",
"home.recentlyPlayed": "最近播放",
"home.recentlyAdded": "最近添加",
@@ -199,16 +222,15 @@
"podcast.episodes": "单集",
"podcast.playEpisode": "播放单集",
"podcast.website": "Podcast 网站",
- "action.favorite":"喜爱",
- "action.removeFavorite":"取消喜爱",
- "action.hideLibrary":"隐藏资料库",
- "action.showLibrary":"显示资料可查",
- "action.cut":"剪切",
- "action.paste":"粘贴",
- "action.selectAll":"全选",
- "action.delete":"删除",
+ "action.hideLibrary": "隐藏资料库",
+ "action.showLibrary": "显示资料库",
+ "action.cut": "剪切",
+ "action.paste": "粘贴",
+ "action.selectAll": "全选",
+ "action.delete": "删除",
"action.edit": "编辑",
"action.done": "完成",
+ "action.submit": "提交",
"action.editTracklist": "编辑歌曲清单",
"action.addToLibrary": "加入资料库",
"action.addToLibrary.success": "成功加入资料库",
@@ -224,7 +246,7 @@
"action.createPlaylist": "新建播放列表",
"action.addToPlaylist": "添加到播放列表",
"action.removeFromPlaylist": "从播放列表移除",
- "action.addToFavorites": "加至收藏",
+ "action.addToFavorites": "添加至收藏",
"action.follow": "关注",
"action.follow.success": "已关注",
"action.follow.error": "尝试关注的过程发生了错误",
@@ -236,7 +258,7 @@
"action.startRadio": "开始电台",
"action.goToArtist": "前往艺人",
"action.goToAlbum": "前往专辑",
- "action.showInPlaylist":"在播放列表中显示",
+ "action.showInPlaylist": "在播放列表中显示",
"action.showInAppleMusic": "在 Apple Music 中显示",
"action.moveToTop": "移到顶部",
"action.share": "分享歌曲",
@@ -253,11 +275,7 @@
"action.export": "导出",
"action.showAlbum": "显示专辑",
"action.tray.minimize": "最小化",
- "action.tray.quit": "退出",
"action.tray.show": "显示 Cider",
- "action.tray.playpause": "播放/暂停",
- "action.tray.next": "下一首",
- "action.tray.previous": "上一首",
"action.tray.listento": "Listen To:",
"action.update": "更新",
"action.install": "安装",
@@ -266,7 +284,7 @@
"action.deletepreset": "删除默认",
"action.open": "打开",
"action.close": "关闭",
- "action.relaunch.confirm":"你想重新启动 Cider 吗?",
+ "action.relaunch.confirm": "你想重新启动 Cider 吗?",
"action.cast.chromecast": "Chromecast",
"action.cast.todevices": "投射到设备",
"action.cast.stop": "停止投射到所有设备",
@@ -277,49 +295,29 @@
"action.createNew": "添加...",
"action.openArtworkInBrowser": "在浏览器中打开专辑封面",
"action.scrollToTop": "回到顶部",
- "menubar.options.about": "关于",
- "menubar.options.settings": "设置",
- "menubar.options.quit": "退出 Cider",
"menubar.options.view": "查看 ",
"menubar.options.reload": "重新载入",
"menubar.options.forcereload": "强制重新载入",
"menubar.options.toggledevtools": "切换开发人员工具",
"menubar.options.window": "窗口",
"menubar.options.minimize": "最小化",
- "menubar.options.toggleprivate": "切换隐身聆听",
- "menubar.options.webremote": "远程控制",
- "menubar.options.audio": "音频设定",
"menubar.options.plugins": "插件目录",
"menubar.options.controls": "控制",
- "menubar.options.next": "下一首",
- "menubar.options.playpause": "播放/暂停",
- "menubar.options.previous": "上一首",
"menubar.options.volumeup": "增大音量",
"menubar.options.volumedown": "减小音量",
- "menubar.options.browse": "浏览",
- "menubar.options.artists": "艺人",
- "menubar.options.search": "搜索",
- "menubar.options.albums": "专辑",
- "menubar.options.cast": "投射至设备",
"menubar.options.account": "账户",
- "menubar.options.accountsettings": "账户设置",
"menubar.options.signout": "注销",
"menubar.options.support": "支持",
- "menubar.options.discord": "Discord",
- "menubar.options.github": "GitHub Wiki",
"menubar.options.report": "报告...",
"menubar.options.bug": "Bug",
"menubar.options.feature": "功能请求",
"menubar.options.trans": "翻译报告/请求",
"menubar.options.license": "查看授权",
"menubar.options.conf": "在编辑器打开配置文件",
- "menubar.options.listennow": "现在就听",
- "menubar.options.recentlyAdded": "最近添加",
- "menubar.options.songs": "歌曲",
+ "menubar.options.zoom": "缩放",
"settings.header.general": "通用",
"settings.header.general.description": "调整 Cider 的通用设置",
- "settings.option.audio.volumeStep": "音量改变量",
- "settings.option.audio.maxVolume": "最大音量",
+ "settings.option.general.language": "语言",
"settings.option.general.resumebehavior": "恢复行为",
"settings.option.general.resumebehavior.description": "会影响你回到 Cider 应用程序时,恢复歌曲的方式。",
"settings.option.general.resumebehavior.locally": "本地",
@@ -330,61 +328,66 @@
"settings.option.general.resumetabs.description": "你可以选择启动 Cider 时要默认打开的页面。",
"settings.option.general.resumetabs.dynamic": "动态",
"settings.option.general.resumetabs.dynamic.description": "Cider 将自动打开你上次停留的页面。",
- "settings.option.general.language": "语言",
"settings.option.general.language.main": "语言",
"settings.option.general.language.fun": "恶搞语言",
"settings.option.general.language.unsorted": "未分类",
"settings.option.general.customizeSidebar": "自定义侧边栏的功能",
"settings.option.general.customizeSidebar.customize": "自定义",
"settings.option.general.keybindings": "快捷操作键",
- "settings.option.general.keybindings.pressCombination":"按下两个键组合来更新操作设定。",
+ "settings.option.general.keybindings.library": "资料库",
+ "settings.option.general.keybindings.session": "聆听",
+ "settings.option.general.keybindings.control": "控制",
+ "settings.option.general.keybindings.interface": "界面",
+ "settings.option.general.keybindings.advanced": "高级",
+ "settings.option.general.keybindings.pressCombination": "按下两个键组合来更新操作设定。",
"settings.option.general.keybindings.pressEscape": "按下 Esc 键返回。",
- "settings.notyf.general.keybindings.update.success":"快捷键更新成功。",
- "settings.prompt.general.keybindings.update.success":"快捷键更新成功,按下 OK 重新启动 Cider.",
- "settings.option.general.keybindings.open": "打开",
- "settings.option.general.themeUpdateNotification":"自动检查主题更新",
- "settings.option.general.showLovedTracksInline":"行内显示喜爱曲目",
- "settings.description.search":"搜索",
- "settings.description.albums":"资料库专辑",
- "settings.description.artists":"资料库艺人",
- "settings.description.browse":"浏览",
- "settings.description.private":"隐身聆听",
- "settings.description.remote":"远程控制",
- "settings.description.audio":"音频设定",
- "settings.description.plugins":"插件目录",
- "settings.description.cast":"投射到装置",
- "settings.description.settings":"设置",
- "settings.description.developer":"开发者",
- "settings.description.listnow":"现在就听",
- "settings.description.recentAdd":"最近加入",
- "settings.description.songs":"歌曲",
+ "settings.notyf.general.keybindings.update.success": "快捷键更新成功。",
+ "settings.prompt.general.keybindings.update.success": "快捷键更新成功,按下 OK 重新启动 Cider。",
+ "settings.option.general.themeUpdateNotification": "自动检查主题更新",
+ "settings.option.general.showLovedTracksInline": "行内显示喜爱曲目",
+ "settings.description.search": "搜索",
+ "settings.description.albums": "资料库专辑",
+ "settings.description.artists": "资料库艺人",
+ "settings.description.browse": "浏览",
+ "settings.description.private": "隐身聆听",
+ "settings.description.remote": "远程控制",
+ "settings.description.audio": "音频设定",
+ "settings.description.plugins": "插件目录",
+ "settings.description.cast": "投射到装置",
+ "settings.description.settings": "设置",
+ "settings.description.developer": "开发者",
+ "settings.description.listnow": "现在就听",
+ "settings.description.recentAdd": "最近加入",
+ "settings.description.songs": "歌曲",
"settings.notyf.updateCider.update-not-available": "没有可用的更新",
"settings.notyf.updateCider.update-downloaded": "更新已成功下载,重启后进行更新",
"settings.notyf.updateCider.update-timeout": "更新超时",
"settings.header.audio": "音频",
"settings.header.audio.description": "调整 Cider 的音频设置",
- "settings.option.audio.advanced":"高级功能",
- "settings.option.audio.changePlaybackRate":"修改播放速度",
- "settings.option.audio.playbackRate":"播放速度",
- "settings.option.audio.playbackRate.change":"修改",
+ "settings.option.audio.volumeStep": "音量改变量",
+ "settings.option.audio.advanced": "高级功能",
+ "settings.option.audio.maxVolume": "最大音量",
+ "settings.option.audio.changePlaybackRate": "修改播放速度",
+ "settings.option.audio.playbackRate": "播放速度",
+ "settings.option.audio.playbackRate.change": "修改",
"settings.option.audio.quality": "音质",
"settings.header.audio.quality.hireslossless": "高解析度无损",
"settings.header.audio.quality.hireslossless.description": "(最高 24 位/192 kHz)",
"settings.header.audio.quality.lossless": "无损",
"settings.header.audio.quality.lossless.description": "(最高 24 位/48 kHz)",
"settings.header.audio.quality.high": "高音质",
- "settings.header.audio.quality.high.description":"256 kbps",
+ "settings.header.audio.quality.high.description": "256 kbps",
"settings.header.audio.quality.standard": "高效率",
- "settings.header.audio.quality.standard.description":"64 kbps",
+ "settings.header.audio.quality.standard.description": "64 kbps",
"settings.option.audio.seamlessTransition": "无缝播放",
"settings.option.audio.enableAdvancedFunctionality": "高级音频功能",
"settings.option.audio.enableAdvancedFunctionality.description": "打开 AudioContext 将启用类似音量平衡和等化器的高级设置。但这并不一定适合每部电脑,可能会发生音乐卡顿。",
- "settings.warn.audio.enableAdvancedFunctionality.lowcores":"您的电脑可能无法处理这些功能, 您确定要继续?",
+ "settings.warn.audio.enableAdvancedFunctionality.lowcores": "您的电脑可能无法处理这些功能, 您确定要继续?",
"settings.option.audio.audioLab": "Cider 音频实验室",
"settings.option.audio.audioLab.description": "包含由 Cider 开发团队进行的各种音频优化功能。",
- "settings.option.audio.audioLab.subheader":"Designed by Cider Acoustic Technologies in California",
+ "settings.option.audio.audioLab.subheader": "Designed by Cider Acoustic Technologies in California",
"settings.warn.audioLab.withoutAF": "使用 Cider 音频实验室需要打开进阶音频功能才可使用。",
- "settings.warn.enableAdvancedFunctionality":"此功能需要开启高级音频功能才可使用。",
+ "settings.warn.enableAdvancedFunctionality": "此功能需要开启高级音频功能才可使用。",
"settings.option.audio.enableAdvancedFunctionality.analogWarmth": "模拟温暖",
"settings.option.audio.enableAdvancedFunctionality.analogWarmth.description": "以 Korg Nutube 6P1 为蓝本的模拟温暖。",
"settings.option.audio.enableAdvancedFunctionality.analogWarmthIntensity": "模拟温暖强度",
@@ -401,18 +404,20 @@
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E68_2": "宇治抹茶奶茶",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.E168_1": "春毫茉莉玛琪雅朵",
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z3600": "北海道奶茶",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500": "月光软饼干",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM":"布蕾黑糖鲜奶",
- "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE":"温暖抱抱",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500A": "月光软饼干",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.BSCBM": "布蕾黑糖鲜奶",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500B": "樱桃克拉芙缇",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.Z8500C": "宇治抹茶麻糬",
+ "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.CUDDLE": "温暖抱抱",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 数码增强音频处理™️",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "通过人类的听力心理学模型和 AAC 编码特色的即时算法,强化 AAC 音频的感知音频质量。",
+ "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "数码增强音频处理与空间音频不兼容,请先停用空间音频。",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "数码增强音频处理设置",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "将更改音频处理的激进/振奋程度(增强选项有可能会引起杂讯)。",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard": "标准",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive":"自适应",
- "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy":"传统",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive": "自适应",
+ "settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy": "传统",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive": "增强",
- "settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility":"数码增强音频处理与空间音频不兼容,请先停用空间音频。",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量平衡",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "自动将歌曲播放音量调整到相同水平,享受更舒适的聆听体验。",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.disabled": "此功能由音频实验室管理",
@@ -421,28 +426,25 @@
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider 音频空间配置档",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "变更音频空间的配置档,需重新启动应用程序。",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "标准",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage":"声场",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation":"分离感",
- "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal":"微调",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "声场",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "分离感",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "微调",
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "发烧友",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "扩散",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "安可",
+ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "延长版安可",
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "音频空间无法与 CAP 相容,请关闭 CAP 在进行操作。",
- "settings.option.audio.dbspl.display":"显示 dB SPL(声压)",
- "settings.option.audio.dbspl.description":"(专业用户选项) 音量滑动条显示 dB SPL 而非 dBFS.",
- "settings.option.audio.dbfs.calibration":"0 dBFS 校正",
- "settings.option.audio.dbfs.description":"Enter the peak Z-weighted dB SPL when Cider is at 0 dBFS.",
- "settings.option.visual.uiscale": "UI界面大小",
+ "settings.option.audio.dbspl.display": "显示 dB SPL(声压)",
+ "settings.option.audio.dbspl.description": "(专业用户选项) 音量滑动条显示 dB SPL 而非 dBFS。",
+ "settings.option.audio.dbfs.calibration": "0 dBFS 校正",
+ "settings.option.audio.dbfs.description": "输入当 Cider 为 0 dBFS 时的峰值 Z 加权 dB SPL。",
"settings.header.visual": "外观",
"settings.header.visual.description": "调整 Cider 的外观",
- "settings.option.visual.windowStyle":"窗口风格",
- "settings.option.visual.customAccentColor": "自定义强调色",
- "settings.option.visual.accentColor": "强调色",
- "settings.option.visual.purplePodcastPlaybackBar": "播放播客时使用紫色进度条",
- "settings.option.visual.windowColor": "窗口色调",
+ "settings.option.visual.windowStyle": "窗口风格",
"settings.option.visual.windowBackgroundStyle": "窗口背景样式",
"settings.header.visual.windowBackgroundStyle.none": "无",
"settings.header.visual.windowBackgroundStyle.artwork": "专辑插图",
"settings.header.visual.windowBackgroundStyle.image": "图像",
- "settings.header.visual.windowBackgroundStyle.color":"色调",
"settings.option.visual.animatedArtwork": "动态专辑插图",
"settings.header.visual.animatedArtwork.always": "总是显示",
"settings.header.visual.animatedArtwork.limited": "只在艺人页面和专辑插图显示",
@@ -458,20 +460,22 @@
"settings.option.visual.hardwareAcceleration.description": "需要重启 Cider 才会生效",
"settings.header.visual.hardwareAcceleration.default": "默认",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
+ "settings.option.visual.uiscale": "UI界面大小",
"settings.header.visual.theme": "主题",
"settings.option.visual.theme.github.download": "从 GitHub 链接安装",
- "settings.option.visual.theme.github.openfolder":"开启主题文件夹",
+ "settings.option.visual.theme.github.openfolder": "开启主题文件夹",
"settings.option.visual.theme.github.explore": "浏览 GitHub 上的主题",
- "settings.header.visual.theme.github.page":"GitHub 上的主题",
- "settings.option.visual.theme.github.install.confirm":"你确定要安装 {{ repo }}",
+ "settings.header.visual.theme.github.page": "GitHub 上的主题",
+ "settings.option.visual.theme.github.install.confirm": "你确定要安装 {{ repo }}",
"settings.prompt.visual.theme.github.URL": "输入您要安装的窗口主题链接",
- "settings.prompt.visual.theme.uninstallTheme":"你确定要删除 {{ theme }}",
- "settings.option.visual.theme.checkForUpdates":"检查更新",
- "settings.option.visual.theme.manageStyles":"管理风格",
- "settings.option.visual.theme.uninstall":"卸载",
- "settings.option.visual.theme.viewInfo":"查看信息",
- "settings.option.visual.theme.github.available":"可使用的主题",
- "settings.option.visual.theme.github.applied":"已应用",
+ "settings.prompt.visual.theme.uninstallTheme": "你确定要删除 {{ theme }}",
+ "settings.option.visual.theme.checkForUpdates": "检查更新",
+ "settings.header.visual.styles": "主题",
+ "settings.option.visual.theme.manageStyles": "管理主题",
+ "settings.option.visual.theme.uninstall": "卸载",
+ "settings.option.visual.theme.viewInfo": "查看信息",
+ "settings.option.visual.theme.github.available": "可使用的主题",
+ "settings.option.visual.theme.github.applied": "已应用",
"settings.notyf.visual.theme.install.success": "主题成功安装",
"settings.notyf.visual.theme.install.error": "主题安装失败",
"settings.header.visual.plugin": "插件",
@@ -503,21 +507,27 @@
"settings.option.lyrics.enableQQLyrics": "启用 QQ 音乐的歌词",
"settings.header.connectivity": "外部连接",
"settings.header.connectivity.description": "调整 Cider 与外部应用的交互设置",
- "settings.option.connectivity.discordRPC": "Discord 动态",
"settings.option.connectivity.playbackNotifications": "歌曲播放通知",
+ "settings.option.connectivity.discordRPC": "Discord 动态",
"settings.option.connectivity.discordRPC.clientName": "应用程序名称",
"settings.option.connectivity.discordRPC.clearOnPause": "暂停时清除 Discord 动态",
"settings.option.connectivity.discordRPC.hideButtons": "隐藏 Discord 动态上的按钮",
- "settings.option.connectivity.discordRPC.hideTimestamp":"隐藏 Discord 动态上的时间戳",
+ "settings.option.connectivity.discordRPC.hideTimestamp": "隐藏 Discord 动态上的时间戳",
"settings.option.connectivity.discordRPC.detailsFormat": "详细信息格式",
"settings.option.connectivity.discordRPC.stateFormat": "动态格式",
- "settings.option.connectivity.discordRPC.reload":"重新加载 DiscordRPC",
- "settings.option.connectivity.discordRPC.reconnectedToUser":"DiscordRPC 重新连接至用户: {{user}} ({{userid}})",
+ "settings.option.connectivity.discordRPC.reload": "重新加载 DiscordRPC",
+ "settings.option.connectivity.discordRPC.reconnectedToUser": "DiscordRPC 重新连接至用户: {{user}} ({{userid}})",
"settings.option.connectivity.lastfmScrobble": "Last.FM 音乐记录",
"settings.option.connectivity.lastfmScrobble.delay": "Last.FM 歌曲追踪延迟 (%)",
"settings.option.connectivity.lastfmScrobble.nowPlaying": "打开 Last.FM 正在聆听",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除合作者 (Last.FM)",
"settings.option.connectivity.lastfmScrobble.filterLoop": "不记录单曲循环 (Last.FM)",
+ "settings.option.connectivity.lastfmScrobble.filterLoop.description": "防止循环单曲被记录或展示在Last.FM 的正在播放列表中。",
+ "settings.option.connectivity.lastfmScrobble.filterTypes": "过滤媒体类型 (Last.fm)",
+ "settings.option.connectivity.lastfmScrobble.manualToken": "手动输入 Last.fm 验证码",
+ "settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm 连接超时",
+ "settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.fm 连接成功",
+ "settings.notyf.connectivity.lastfmScrobble.connecting": "正在连接至 Last.fm...",
"settings.header.debug": "Debug",
"settings.option.debug.copy_log": "拷贝日志至剪贴板",
"settings.option.debug.openAppData": "打开 Cider 程序文件夹",
@@ -529,15 +539,21 @@
"settings.option.experimental.unknownPlugin.description": "允许从 Cider 来源以外的 repo 安装插件",
"settings.option.experimental.compactUI": "紧凑型 UI",
"settings.option.window.close_button_hide": "关闭按钮将 Cider 隐藏至系统栏",
+ "settings.option.window.maxElementScale": "最大元素比例",
"settings.option.experimental.inline_playlists": "将播放列表做为行内元素显示",
"settings.option.advanced.playlistTrackMapping": "播放列表追踪映射",
"settings.option.advanced.playlistTrackMapping.description": "打开对播放列表的深度扫描,以确认歌曲在哪些播放列表中。但播放列表加载时间会显著增加。",
"settings.option.visual.transparent": "透明窗口框架",
"settings.option.visual.transparent.description": "需主题有支持透明框架,且须重新启动才会生效。",
+ "settings.option.visual.customAccentColor": "自定义强调色",
+ "settings.option.visual.accentColor": "强调色",
+ "settings.option.visual.purplePodcastPlaybackBar": "播放播客时使用紫色进度条",
+ "settings.option.visual.windowColor": "窗口色调",
+ "settings.header.visual.windowBackgroundStyle.color": "色调",
"settings.header.advanced": "高级",
- "settings.header.connect":"同步",
- "settings.option.connect.link_account":"开启 Cider Connect 同步",
- "settings.option.connect.link_account.description":"将您的 Discord 帐户与 Cider Connect 关联后,您可以储存用户资料,包括设定、均衡器,并在后续版本中加入更多可同步选项。(正在更新中)",
+ "settings.header.connect": "同步",
+ "settings.option.connect.link_account": "开启 Cider Connect 同步",
+ "settings.option.connect.link_account.description": "将您的 Discord 帐户与 Cider Connect 关联后,您可以储存用户资料,包括设定、均衡器,并在后续版本中加入更多可同步选项。(正在更新中)",
"spatial.notTurnedOn": "请在设置中开启空间音频。",
"spatial.spatialProperties": "空间属性",
"spatial.width": "宽度",
@@ -560,54 +576,54 @@
"settings.header.unfinished": "未完成",
"remote.web.title": "Cider 远程控制",
"remote.web.description": "扫描以下的二维码以控制 Cider",
+ "share.platform.twitter.tweet": "在 Apple Music 上聆听 {{song}}。 \n\n{{url}}\n\n#AppleMusic #Cider",
+ "share.platform.twitter": "Twitter",
+ "share.platform.facebook": "Facebook",
+ "share.platform.reddit": "Reddit",
+ "share.platform.telegram": "Telegram",
+ "share.platform.whatsapp": "WhatsApp",
+ "share.platform.messenger": "Messenger",
+ "share.platform.email": "电子邮件",
+ "share.platform.songLink": "复制 song.link 链接",
+ "share.platform.clipboard": "复制到剪贴板",
"about.thanks": "郑重感谢 Cider Collective 以及为这个项目提供支持的贡献者。",
- "share.platform.twitter.tweet":"在 Apple Music 上聆听 {{song}}。 \n\n{{url}}\n\n#AppleMusic #Cider",
- "share.platform.twitter":"Twitter",
- "share.platform.facebook":"Facebook",
- "share.platform.reddit":"Reddit",
- "share.platform.telegram":"Telegram",
- "share.platform.whatsapp":"WhatsApp",
- "share.platform.messenger":"Messenger",
- "share.platform.email":"电子邮件",
- "share.platform.songLink":"复制 song.link 链接",
- "share.platform.clipboard":"复制到剪贴板",
- "oobe.yes":"好的",
- "oobe.no":"不",
- "oobe.next":"下一步",
- "oobe.previous":"上一步",
- "oobe.done":"完成",
- "oobe.amupsell.title":"在我们开始之前",
- "oobe.amupsell.text":"使用 Cider 需要付费的 Apple Music 订阅。\nCider 不能在 Apple Music Voice 计划或某些促销试用订阅状态下使用。 如果您已经订阅 Apple Music,请点击下一步继续。",
- "oobe.amupsell.subscribeBtn":"订阅 Apple Music",
- "oobe.amupsell.explainBtn":"这是什么?",
- "oobe.amupsell.subscribeUrl":"https://apple.co/3MdqJVQ",
- "oobe.amupsell.amWebUrl":"https://beta.music.apple.com/",
- "oobe.amupsell.promoExplained":"Cider 无法获取部分促销活动与非美区 Apple Muisc 试用状态下的网络播放器API. 要验证您的试用订阅是否能够在Cider内使用, 点击{{ amWebUrl }} , 登陆后尝试播放音乐。如果能够播放,您就可以使用 Cider 了!否则请考虑订阅 Apple Music 服务: {{ subscribeUrl }} 。",
- "oobe.intro.title":"欢迎使用 Cider",
- "oobe.intro.subtitle":"",
- "oobe.intro.text":"为了按您喜欢的方式使用 Cider ,请先完成一些设置。您之后可以随时改变这些设置。",
- "oobe.general.title":"通用设置",
- "oobe.general.subtitle":"",
- "oobe.general.text":"",
- "oobe.audio.title":"音频设置",
- "oobe.audio.subtitle":"",
- "oobe.audio.text":"Cider 能够自定义调整和设置的音频属性,提供丰富的高品质音频体验,包括Cider Adrenaline Processor,气氛实现器和空间音频。要启用这些功能,必须启用 \"高级音频功能\"。",
- "oobe.audio.advancedFunctionality":"",
- "oobe.visual.title":"外观设置",
- "oobe.visual.subtitle":"",
- "oobe.visual.text":"",
- "oobe.visual.layout.text":"Cider 拥有两种不同的窗口布局。Maverick 是一个类似 iTunes 的布局,播放器在窗口的顶部。Mojave 是由 Cider 团队设计的一种新的布局。您可以在设置中随时改变布局。",
- "oobe.visual.suggestingThemes":"主题能够个性化您的播放器。以下是推荐的几个主题:",
- "oobe.visual.suggestingThemes.subtext":"(主题会从 GitHub 上下载)",
- "oobe.visual.suggestingThemes.default":"Cider",
- "oobe.visual.suggestingThemes.default.text":"传统的 Cider 主题。",
- "oobe.visual.suggestingThemes.dark":"Dark",
- "oobe.visual.suggestingThemes.dark.text":"暗黑模式。",
- "oobe.visual.suggestingThemes.community1":"Groovy",
- "oobe.visual.suggestingThemes.community1.text":"类 WinUI 主题。",
- "oobe.visual.suggestingThemes.community2":"iTheme",
- "oobe.visual.suggestingThemes.community2.text":"基于 MacOS Monterey 的 Apple Music bata 主题。",
- "oobe.visual.suggestingThemes.community3":"Dracula",
- "oobe.visual.suggestingThemes.community3.text":"著名的德古拉吸血鬼主题。",
+ "oobe.yes": "好的",
+ "oobe.no": "不",
+ "oobe.next": "下一步",
+ "oobe.previous": "上一步",
+ "oobe.done": "完成",
+ "oobe.amupsell.title": "在我们开始之前",
+ "oobe.amupsell.text": "使用 Cider 需要付费的 Apple Music 订阅。\nCider 不能在 Apple Music Voice 计划或某些促销试用订阅状态下使用。 如果您已经订阅 Apple Music,请点击下一步继续。",
+ "oobe.amupsell.subscribeBtn": "订阅 Apple Music",
+ "oobe.amupsell.explainBtn": "这是什么?",
+ "oobe.amupsell.subscribeUrl": "https://apple.co/3MdqJVQ",
+ "oobe.amupsell.amWebUrl": "https://beta.music.apple.com/",
+ "oobe.amupsell.promoExplained": "Cider 无法获取部分促销活动与非美区 Apple Muisc 试用状态下的网络播放器API. 要验证您的试用订阅是否能够在Cider内使用, 点击{{ amWebUrl }} , 登陆后尝试播放音乐。如果能够播放,您就可以使用 Cider 了!否则请考虑订阅 Apple Music 服务: {{ subscribeUrl }} 。",
+ "oobe.intro.title": "欢迎使用 Cider",
+ "oobe.intro.subtitle": "",
+ "oobe.intro.text": "为了按您喜欢的方式使用 Cider ,请先完成一些设置。您之后可以随时改变这些设置。",
+ "oobe.general.title": "通用设置",
+ "oobe.general.subtitle": "",
+ "oobe.general.text": "",
+ "oobe.audio.title": "音频设置",
+ "oobe.audio.subtitle": "",
+ "oobe.audio.text": "Cider 能够自定义调整和设置的音频属性,提供丰富的高品质音频体验,包括Cider Adrenaline Processor,气氛实现器和空间音频。要启用这些功能,必须启用 \"高级音频功能\"。",
+ "oobe.audio.advancedFunctionality": "",
+ "oobe.visual.title": "外观设置",
+ "oobe.visual.subtitle": "",
+ "oobe.visual.text": "",
+ "oobe.visual.layout.text": "Cider 拥有两种不同的窗口布局。Maverick 是一个类似 iTunes 的布局,播放器在窗口的顶部。Mojave 是由 Cider 团队设计的一种新的布局。您可以在设置中随时改变布局。",
+ "oobe.visual.suggestingThemes": "主题能够个性化您的播放器。以下是推荐的几个主题:",
+ "oobe.visual.suggestingThemes.subtext": "(主题会从 GitHub 上下载)",
+ "oobe.visual.suggestingThemes.default": "Cider",
+ "oobe.visual.suggestingThemes.default.text": "经典的 Cider 主题。",
+ "oobe.visual.suggestingThemes.dark": "Dark",
+ "oobe.visual.suggestingThemes.dark.text": "暗黑模式。",
+ "oobe.visual.suggestingThemes.community1": "Groovy",
+ "oobe.visual.suggestingThemes.community1.text": "类 WinUI 主题。",
+ "oobe.visual.suggestingThemes.community2": "iTheme",
+ "oobe.visual.suggestingThemes.community2.text": "经典的苹果风主题。",
+ "oobe.visual.suggestingThemes.community3": "Dracula",
+ "oobe.visual.suggestingThemes.community3.text": "著名的德古拉吸血鬼主题。",
"oobe.amsignin.title": ""
}
diff --git a/src/i18n/zh_TW.json b/src/i18n/zh_TW.json
index 456bbf46..6d30e581 100644
--- a/src/i18n/zh_TW.json
+++ b/src/i18n/zh_TW.json
@@ -19,7 +19,10 @@
"term.accountSettings": "帳戶設定",
"term.logout": "登出",
"term.login": "登入",
+ "term.quit" : "結束",
"term.about": "關於",
+ "term.cast" : "投影",
+ "term.cast2" : "投影到裝置",
"term.privateSession": "私人時間",
"term.queue": "待播清單",
"term.lyrics": "歌詞",
@@ -46,6 +49,7 @@
"term.navigateBack": "回上一頁",
"term.navigateForward": "到下一頁",
"term.play": "播放",
+ "term.playpause": "播放/暫停",
"term.pause": "暫停",
"term.stop": "停止",
"term.previous": "上一首",
@@ -131,19 +135,25 @@
"term.videos": "音樂錄影帶",
"term.menu": "選單",
"term.check": "檢查",
+ "term.themeManaged": "此功能現在由主題管理。",
"term.aboutArtist": "關於{{artistName}}",
"term.requestError": "請求發生錯誤。",
"term.song.link.generate": "正在取得 song.link 的分享網址...",
+ "term.musicVideos": "音樂錄影帶",
"term.version": "版本",
"term.creditDesignedBy": "由 ${authorUsername} 設計",
"term.plugin": "模組",
+ "term.plugins": "模組",
"term.pluginMenu": "模組選單",
"term.pluginMenu.none": "沒有交互式模組",
+ "term.fullscreen" : "全螢幕模式",
"home.title": "首頁",
"home.recentlyPlayed": "最近播放",
"home.recentlyAdded": "最近加入",
"home.artistsFeed": "藝人追蹤",
"home.artistsFeed.noArtist": "追蹤你喜愛的藝人來取得他們的最新發行歌曲。",
+ "home.syncFavorites" : "同步追蹤" ,
+ "home.syncFavorites.gettingArtists" : "取得追蹤的藝人歌手列表... " ,
"home.madeForYou": "為您推薦",
"home.friendsListeningTo": "朋友正在聆聽",
"home.followedArtists": "追蹤的藝人",
@@ -217,13 +227,15 @@
"action.deletepreset": "刪除預設",
"action.open": "開啟",
"action.cast.chromecast": "Chromecast",
- "action.cast.todevices": "投射到裝置",
- "action.cast.stop": "停止投射到所有裝置",
+ "action.cast.todevices": "投影到裝置",
+ "action.cast.stop": "停止投影到所有裝置",
"action.cast.airplay": "AirPlay",
"action.cast.airplay.underdevelopment": "AirPlay 仍處於開發階段中,敬請期待。",
"action.cast.scan": "尋找",
"action.cast.scanning": "尋找中...",
"action.createNew": "新增...",
+ "action.refresh": "重新整理",
+ "menubar.options.reload": "重新載入",
"settings.header.general": "一般",
"settings.header.general.description": "調整 Cider 的一般設定",
"settings.option.general.resumebehavior": "還原行為",
@@ -256,6 +268,9 @@
"settings.header.audio.description": "調整 Cider 的音訊設定",
"settings.option.audio.volumeStep": "音量改變量",
"settings.option.audio.maxVolume": "最大音量",
+ "settings.option.audio.changePlaybackRate": "更改播放速率",
+ "settings.option.audio.playbackRate": "播放速率",
+ "settings.option.audio.playbackRate.change": "更改",
"settings.option.audio.quality": "音訊品質",
"settings.header.audio.quality.hireslossless": "高品質無損壓縮",
"settings.header.audio.quality.hireslossless.description": "(最高24位元/192 kHz)",
@@ -304,6 +319,11 @@
"settings.option.visual.uiscale": "介面顯示大小",
"settings.header.visual": "外觀",
"settings.header.visual.description": "調整 Cider 的外觀",
+ "settings.option.visual.windowStyle": "視窗布局風格",
+ "settings.option.visual.customAccentColor": "自訂強調色",
+ "settings.option.visual.accentColor": "強調色",
+ "settings.option.visual.purplePodcastPlaybackBar": "Podcasts 功能的紫色播放列",
+ "settings.option.visual.windowColor": "視窗色調顏色",
"settings.option.visual.windowBackgroundStyle": "視窗背景樣式",
"settings.header.visual.windowBackgroundStyle.none": "空白",
"settings.header.visual.windowBackgroundStyle.artwork": "專輯插圖",
@@ -328,6 +348,8 @@
"settings.option.visual.theme.github.openfolder": "開啟主題存放位置",
"settings.option.visual.theme.github.explore": "探索 GitHub 上的主題",
"settings.prompt.visual.theme.github.URL": "輸入你要安裝的主題網址",
+ "settings.option.visual.theme.checkForUpdates": "檢查更新",
+ "settings.header.visual.styles": "主題",
"settings.option.visual.theme.manageStyles": "管理主題",
"settings.option.visual.theme.uninstall": "移除",
"settings.option.visual.theme.viewInfo": "查看資訊",
@@ -349,6 +371,7 @@
"settings.option.visual.showPersonalInfo": "顯示個人檔案",
"settings.header.window": "視窗",
"settings.header.window.description": "調整 Cider 的視窗設定",
+ "settings.option.window.maxElementScale": "最大元素比例",
"settings.option.window.openOnStartup": "開機時,啟動 Cider ",
"settings.option.window.openOnStartup.hidden": "啟動時,自動隱藏至系統列",
"settings.option.window.useNativeTitleBar": "使用原生視窗標題列",
@@ -362,7 +385,7 @@
"settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞優先語言偏好選項",
"settings.option.lyrics.enableYoutubeLyrics": "播放 MV 時,使用 YouTube 歌詞",
"settings.option.lyrics.enableQQLyrics": "開啟 QQ 音樂的歌詞",
- "settings.header.connectivity": "外部連接",
+ "settings.header.connectivity": "連接",
"settings.header.connectivity.description": "調整 Cider 與外部的連接",
"settings.option.connectivity.playbackNotifications": "歌曲播放通知",
"settings.option.connectivity.discordRPC": "Discord 動態",
@@ -379,6 +402,12 @@
"settings.option.connectivity.lastfmScrobble.nowPlaying": "開啟 Last.FM 正在聆聽",
"settings.option.connectivity.lastfmScrobble.removeFeatured": "從 Last.FM 的歌名中移除客串藝人",
"settings.option.connectivity.lastfmScrobble.filterLoop": "讓 Last.FM 不記錄單曲循環",
+ "settings.option.connectivity.lastfmScrobble.filterLoop.description": "防止循環單曲被打亂或顯示在 Last.FM 的正在播放列表中。",
+ "settings.option.connectivity.lastfmScrobble.filterTypes": "過濾媒體類型 (Last.FM)",
+ "settings.option.connectivity.lastfmScrobble.manualToken": "手動輸入 Last.FM 驗證碼",
+ "settings.notyf.connectivity.lastfmScrobble.connectError": "Last.FM 連線超時",
+ "settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.FM 連線成功",
+ "settings.notyf.connectivity.lastfmScrobble.connecting": "正在連線到 Last.FM...",
"settings.header.debug": "除錯",
"settings.option.debug.copy_log": "複製執行紀錄檔至剪貼簿",
"settings.option.debug.openAppData": "打開 Cider 資料夾",
diff --git a/src/main/base/app.ts b/src/main/base/app.ts
index ea81d8f6..fe54b158 100644
--- a/src/main/base/app.ts
+++ b/src/main/base/app.ts
@@ -162,13 +162,10 @@ export class AppEvents {
// LastFM Auth URL
if (arg.includes('auth')) {
- let authURI = arg.split('/auth/')[1]
+ const authURI = arg.split('/auth/')[1]
if (authURI.startsWith('lastfm')) { // If we wanted more auth options
- const authKey = authURI.split('lastfm?token=')[1];
- utils.setStoreValue('lastfm.enabled', true);
- utils.setStoreValue('lastfm.auth_token', authKey);
- utils.getWindow().webContents.send('LastfmAuthenticated', authKey);
- this.plugin.callPlugin('lastfm', 'authenticate', authKey);
+ console.log('token: ', authURI.split('lastfm?token=')[1])
+ utils.getWindow().webContents.executeJavaScript(`ipcRenderer.send('lastfm:auth', "${authURI.split('lastfm?token=')[1]}")`).catch(console.error)
}
}
// Play
diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts
index e0d646d3..20addc89 100644
--- a/src/main/base/browserwindow.ts
+++ b/src/main/base/browserwindow.ts
@@ -1,9 +1,9 @@
-import {join} from "path";
-import {app, BrowserWindow as bw, ipcMain, ShareMenu, shell, screen} from "electron";
+import { join } from "path";
+import { app, BrowserWindow as bw, ipcMain, ShareMenu, shell, screen, dialog } from "electron";
import * as windowStateKeeper from "electron-window-state";
import * as express from "express";
import * as getPort from "get-port";
-import {search} from "youtube-search-without-api-key";
+import { search } from "youtube-search-without-api-key";
import {
existsSync,
rmSync,
@@ -16,19 +16,18 @@ import {
rmdirSync,
lstatSync,
} from "fs";
-import {Stream} from "stream";
-import {networkInterfaces} from "os";
+import { Stream } from "stream";
+import { networkInterfaces } from "os";
import * as mm from 'music-metadata';
import fetch from 'electron-fetch'
-import {wsapi} from "./wsapi";
-import {utils} from './utils';
-import {Plugins} from "./plugins";
-import {watch} from "chokidar";
+import { wsapi } from "./wsapi";
+import { utils } from './utils';
+import { Plugins } from "./plugins";
+import { watch } from "chokidar";
import * as os from "os";
import wallpaper from "wallpaper";
import * as AdmZip from "adm-zip";
-import * as path from 'path';
-const { readdir } = require('fs').promises;
+import { LocalFiles } from "../providers/local/";
/**
@@ -40,11 +39,11 @@ const { readdir } = require('fs').promises;
export class BrowserWindow {
public static win: any | undefined = null;
private devMode: boolean = !app.isPackaged;
+ public static express: any | undefined = null;
private audioStream: any = new Stream.PassThrough();
private headerSent: any = false;
private chromecastIP: any = [];
- private localSongs: any = [];
private clientPort: number = 0;
private remotePort: number = 6942;
private EnvironmentVariables: object = {
@@ -64,8 +63,7 @@ export class BrowserWindow {
"pages/browse",
"pages/groupings",
"pages/charts",
- "pages/settings",
- "pages/installed-themes",
+ //"pages/installed-themes",
"pages/listen_now",
"pages/radio",
"pages/home",
@@ -81,14 +79,16 @@ export class BrowserWindow {
"pages/about",
"pages/library-videos",
"pages/remote-pair",
- "pages/themes-github",
- "pages/plugins-github",
+ //"pages/themes-github",
+ //"pages/plugins-github",
"pages/replay",
"pages/audiolabs",
"pages/zoo",
"pages/plugin-renderer",
- "pages/keybinds",
"pages/oobe",
+ "pages/cider-profile",
+ "components/app-content",
+ "components/sidebar",
"components/mediaitem-artwork",
"components/artwork-material",
"components/menu-panel",
@@ -119,159 +119,173 @@ export class BrowserWindow {
"components/fullscreen",
"components/miniplayer",
"components/castmenu",
+ "components/pathmenu",
"components/airplay-modal",
"components/artist-chip",
"components/hello-world",
"components/inline-collection-list",
+ "components/settings-window",
+ "components/settings-keybinds",
+ "components/settings-themes",
+ "components/settings-themes-github",
+ "components/settings-plugins-github",
],
appRoutes: [
{
page: "library-recentlyadded",
component: ` `,
- condition: "page == 'library-recentlyadded'"
+ condition: "$root.page == 'library-recentlyadded'"
},
{
page: "plugin-renderer",
component: ` `,
- condition: "page == 'plugin-renderer'"
+ condition: "$root.page == 'plugin-renderer'"
},
{
page: "zoo",
component: " ",
- condition: "page == 'zoo'"
+ condition: "$root.page == 'zoo'"
},
{
page: "podcasts",
component: ` `,
- condition: `page == 'podcasts'`
+ condition: `$root.page == 'podcasts'`
}, {
page: "library-videos",
component: ` `,
- condition: `page == 'library-videos'`
+ condition: `$root.page == 'library-videos'`
}, {
page: "apple-account-settings",
component: ` `,
- condition: `page == 'apple-account-settings'`
+ condition: `$root.page == 'apple-account-settings'`
}, {
page: "about",
component: ` `,
- condition: `page == 'about'`
+ condition: `$root.page == 'about'`
}, {
page: "cider-artist",
- component: ` `,
- condition: `page == 'artist-page' && artistPage.data.attributes`
+ component: ` `,
+ condition: `$root.page == 'artist-page' && $root.artistPage.data.attributes`
}, {
page: "collection-list",
- component: ` `,
- condition: `page == 'collection-list'`
+ component: ` `,
+ condition: `$root.page == 'collection-list'`
}, {
page: "home",
component: ` `,
- condition: `page == 'home'`
+ condition: `$root.page == 'home'`
}, {
page: "artist-feed",
component: ` `,
- condition: `page == 'artist-feed'`
+ condition: `$root.page == 'artist-feed'`
}, {
page: "playlist-inline",
- component: ` `,
- condition: `modals.showPlaylist`
+ component: ` `,
+ condition: `$root.modals.showPlaylist`
}, {
page: "playlist_",
- component: ` `,
- condition: `page.includes('playlist_')`
+ component: ` `,
+ condition: `$root.page.includes('playlist_')`
}, {
page: "album_",
- component: ` `,
- condition: `page.includes('album_')`
+ component: ` `,
+ condition: `$root.page.includes('album_')`
}, {
page: "recordLabel_",
- component: ` `,
- condition: `page.includes('recordLabel_')`
+ component: ` `,
+ condition: `$root.page.includes('recordLabel_')`
+ }, {
+ page: "social-profiles_",
+ component: ` `,
+ condition: `$root.page.includes('social-profiles_')`
}, {
page: "multiroom",
- component: ` `,
- condition: `page.includes('multiroom')`
+ component: ` `,
+ condition: `$root.page.includes('multiroom')`
}, {
page: "curator_",
- component: ` `,
- condition: `page.includes('curator_')`
+ component: ` `,
+ condition: `$root.page.includes('curator_')`
}, {
page: "browsepage",
- component: ` `,
- condition: `page == 'browse'`,
+ component: ` `,
+ condition: `$root.page == 'browse'`,
onEnter: ``
- },{
+ }, {
page: "groupings",
- component: ` `,
- condition: `page == 'groupings'`,
+ component: ` `,
+ condition: `$root.page == 'groupings'`,
onEnter: ``
- },{
+ }, {
page: "charts",
- component: ` `,
- condition: `page == 'charts'`,
+ component: ` `,
+ condition: `$root.page == 'charts'`,
onEnter: ``
}, {
page: "listen_now",
- component: ` `,
- condition: `page == 'listen_now'`,
+ component: ` `,
+ condition: `$root.page == 'listen_now'`,
onEnter: ``
}, {
page: "radio",
- component: ` `,
- condition: `page == 'radio'`,
+ component: ` `,
+ condition: `$root.page == 'radio'`,
onEnter: ``
}, {
page: "settings",
component: ` `,
- condition: `page == 'settings'`
+ condition: `$root.page == 'settings'`
}, {
page: "installed-themes",
component: ` `,
- condition: `page == 'installed-themes'`
+ condition: `$root.page == 'installed-themes'`
}, {
page: "search",
- component: ` `,
- condition: `page == 'search'`
+ component: ` `,
+ condition: `$root.page == 'search'`
}, {
page: "library-songs",
- component: ` `,
- condition: `page == 'library-songs'`,
+ component: ` `,
+ condition: `$root.page == 'library-songs'`,
onEnter: ``
}, {
page: "library-albums",
- component: ` `,
- condition: `page == 'library-albums'`,
+ component: ` `,
+ condition: `$root.page == 'library-albums'`,
onEnter: ``
}, {
page: "library-artists",
component: ` `,
- condition: `page == 'library-artists'`,
+ condition: `$root.page == 'library-artists'`,
onEnter: ``
}, {
page: "appleCurator",
- component: ` `,
- condition: `page.includes('appleCurator')`
+ component: ` `,
+ condition: `$root.page.includes('appleCurator')`
}, {
page: "themes-github",
component: ` `,
- condition: `page == 'themes-github'`
+ condition: `$root.page == 'themes-github'`
}, {
page: "plugins-github",
component: ` `,
- condition: `page == 'plugins-github'`
+ condition: `$root.page == 'plugins-github'`
}, {
page: "remote-pair",
component: ` `,
- condition: `page == 'remote-pair'`
+ condition: `$root.page == 'remote-pair'`
}, {
page: "audiolabs",
component: ` `,
- condition: `page == 'audiolabs'`
+ condition: `$root.page == 'audiolabs'`
}, {
page: "replay",
component: ` `,
- condition: `page == 'replay'`
+ condition: `$root.page == 'replay'`
+ }, {
+ page: "keydinds",
+ component: ` `,
+ condition: `$root.page == 'keybinds-settings'`
}
]
},
@@ -292,7 +306,7 @@ export class BrowserWindow {
show: false,
// backgroundColor: "#1E1E1E",
titleBarStyle: 'hidden',
- trafficLightPosition: {x: 15, y: 20},
+ trafficLightPosition: { x: 15, y: 20 },
webPreferences: {
experimentalFeatures: true,
nodeIntegration: true,
@@ -358,7 +372,8 @@ export class BrowserWindow {
* @yields {object} Electron browser window
*/
async createWindow(): Promise {
- this.clientPort = await getPort({port: 9000});
+ const envPort = process.env?.CIDER_PORT || '9000'
+ this.clientPort = await getPort({ port: parseInt(envPort, 10) || 9000 });
BrowserWindow.verifyFiles();
this.StartWatcher(utils.getPath('themes'));
@@ -405,9 +420,10 @@ export class BrowserWindow {
}
// Start the webserver for the browser window to load
-
+ // LocalFiles.DB.init()
this.startWebServer();
+
BrowserWindow.win = new bw(this.options);
// cant be built in CI
// if (process.platform === "win32" && (utils.getStoreValue('visual.transparent') ?? false)) {
@@ -463,7 +479,7 @@ export class BrowserWindow {
*/
private startWebServer(): void {
const app = express();
-
+ BrowserWindow.express = app;
app.use(express.static(join(utils.getPath('srcPath'), "./renderer/")));
app.set("views", join(utils.getPath('srcPath'), "./renderer/views"));
app.set("view engine", "ejs");
@@ -495,9 +511,9 @@ export class BrowserWindow {
app.get("/cideraudio/impulses/:file", (req, res) => {
const impulseExternals = join(utils.getPath("externals"), "/impulses/")
const impulseFile = join(impulseExternals, req.params.file)
- if(existsSync(impulseFile)) {
+ if (existsSync(impulseFile)) {
res.sendFile(impulseFile)
- }else{
+ } else {
res.sendFile(join(utils.getPath('srcPath'), "./renderer/audio/impulses/" + req.params.file))
}
})
@@ -547,14 +563,6 @@ export class BrowserWindow {
res.send(`// Theme not found - ${userThemePath}`);
}
});
- app.get("/ciderlocal/:songs", (req, res) => {
- const audio = atob(req.params.songs.replace(/_/g, '/').replace(/-/g, '+'));
- console.log('auss', audio)
- let data = {data:
- this.localSongs.filter((f: any) => audio.split(',').includes(f.id))};
- res.send(data);
- });
-
app.get("/themes/:theme/*", (req: { params: { theme: string, 0: string } }, res) => {
const theme = req.params.theme;
@@ -615,10 +623,12 @@ export class BrowserWindow {
//region Connect Integration
app.get("/connect/set-cc-user/:data", (req, res) => {
//utils.getStoreValue('connectUser', JSON.parse()) // [Connect] Save user in store
- utils.setStoreValue('connectUser', JSON.parse(req.params.data))
- utils.getWindow().reload()
+ utils.getWindow().webContents.send('setStoreValue', 'connectUser', JSON.parse(req.params.data))
res.redirect(`https://connect.cidercollective.dev/linked.html`)
});
+
+ LocalFiles.setupHandlers()
+
// [Connect] Set auth URL in store for `shell.openExternal`
utils.setStoreValue('cc_authURL', `https://connect.cidercollective.dev/callback/discord?app=cider&appPort=${this.clientPort}`)
console.log(`[Connect] Auth URL: ${utils.getStoreValue('cc_authURL')}`)
@@ -638,7 +648,7 @@ export class BrowserWindow {
remote.use(express.static(join(utils.getPath('srcPath'), "./web-remote/")))
remote.set("views", join(utils.getPath('srcPath'), "./web-remote/views"));
remote.set("view engine", "ejs");
- getPort({port: 6942}).then((port: number) => {
+ getPort({ port: 6942 }).then((port: number) => {
this.remotePort = port;
// Start Remote Discovery
this.broadcastRemote()
@@ -669,13 +679,13 @@ export class BrowserWindow {
callback({
redirectURL: `http://localhost:${this.clientPort}/apple-hls.js`,
});
- } else if (details.url.includes("ciderlocal")) {
+ } else if (details.url.includes("ciderlocal") && !details.url.includes("https://apic-desktop.musixmatch.com") ) {
let text = details.url.toString().includes('ids=') ? decodeURIComponent(details.url.toString()).split("?ids=")[1] : decodeURIComponent(details.url.toString().substring(details.url.toString().lastIndexOf('/') + 1));
- console.log('localurl',text)
+ //console.log('localurl',text)
callback({
redirectURL: `http://localhost:${this.clientPort}/ciderlocal/${Buffer.from(text).toString('base64url')}`,
});
- }else {
+ } else {
callback({
cancel: false,
});
@@ -717,7 +727,7 @@ export class BrowserWindow {
'KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3) '
details.requestHeaders['Referer'] = "https://y.qq.com/portal/player.html"
}
- callback({requestHeaders: details.requestHeaders});
+ callback({ requestHeaders: details.requestHeaders });
}
);
@@ -774,7 +784,7 @@ export class BrowserWindow {
const Jimp = require("jimp")
const img = await Jimp.read(wpPath)
const blurAmount = args.blurAmount ?? 256
- if(blurAmount) {
+ if (blurAmount) {
img.blur(blurAmount)
}
const screens = await screen.getAllDisplays()
@@ -811,7 +821,7 @@ export class BrowserWindow {
}
// if path is directory, delete it
if (lstatSync(path).isDirectory()) {
- await rmdirSync(path, {recursive: true});
+ await rmdirSync(path, { recursive: true });
} else {
// if path is file, delete it
await unlinkSync(path);
@@ -842,7 +852,7 @@ export class BrowserWindow {
// remove WidevineCDM from appdata folder
const widevineCdmPath = join(app.getPath("userData"), "./WidevineCdm");
if (existsSync(widevineCdmPath)) {
- rmSync(widevineCdmPath, {recursive: true, force: true})
+ rmSync(widevineCdmPath, { recursive: true, force: true })
}
// reinstall WidevineCDM
app.relaunch()
@@ -1134,7 +1144,7 @@ export class BrowserWindow {
// Move window
ipcMain.on("windowmove", (_event, x, y) => {
- BrowserWindow.win.setBounds({x, y});
+ BrowserWindow.win.setBounds({ x, y });
});
//Fullscreen
@@ -1149,7 +1159,7 @@ export class BrowserWindow {
//Fullscreen
ipcMain.on('detachDT', (_event, _) => {
- BrowserWindow.win.webContents.openDevTools({mode: 'detach'});
+ BrowserWindow.win.webContents.openDevTools({ mode: 'detach' });
})
ipcMain.handle('relaunchApp', (_event, _) => {
@@ -1168,6 +1178,10 @@ export class BrowserWindow {
app.quit();
})
+ ipcMain.handle("quit-app", (_event, _) => {
+ app.quit();
+ })
+
app.on('before-quit', () => {
})
@@ -1182,102 +1196,17 @@ export class BrowserWindow {
});
- ipcMain.on("scanLibrary", async (event, folders) => {
- async function getFiles(dir : any) {
- const dirents = await readdir(dir, { withFileTypes: true });
- const files = await Promise.all(dirents.map((dirent: any) => {
- const res = path.resolve(dir, dirent.name);
- return dirent.isDirectory() ? getFiles(res) : res;
- }));
- return Array.prototype.concat(...files);
- }
- if (folders == null || folders.length == null || folders.length == 0) folders = ["D:\\Music"]
- console.log('folders', folders)
- let files: any[] = []
- for (var folder of folders){
- // get files from the Music folder
- files = files.concat(await getFiles(folder))
- }
-
- //console.log("cider.files", files2);
- let supporttedformats = ["mp3", "aac", "webm", "flac", "m4a", "ogg", "wav", "opus"]
- let audiofiles = files.filter(f => supporttedformats.includes(f.substring(f.lastIndexOf('.') + 1)));
- // console.log("cider.files2", audiofiles, audiofiles.length);
- let metadatalist = []
- let numid = 0;
- for (var audio of audiofiles) {
- try{
- const metadata = await mm.parseFile(audio);
- if (metadata != null){
- let form = {
- "id": "ciderlocal" + numid,
- "type": "podcast-episodes",
- "href": audio,
- "attributes": {
- "artwork": {
- "width": 3000,
- "height": 3000,
- "url": metadata.common.picture != undefined ? "data:image/png;base64,"+metadata.common.picture[0].data.toString('base64')+"" : "",
- },
- "topics": [],
- "url": "",
- "subscribable": true,
- "mediaKind": "audio",
- "genreNames": [
- ""
- ],
- // "playParams": {
- // "id": "ciderlocal" + numid,
- // "kind": "podcast",
- // "isLibrary": true,
- // "reporting": false },
- "trackNumber": metadata.common.track?.no ?? 0,
- "discNumber": metadata.common.disk?.no ?? 0,
- "name": metadata.common.title ?? audio.substring(audio.lastIndexOf('\\') + 1),
- "albumName": metadata.common.album,
- "artistName": metadata.common.artist,
- "copyright": metadata.common.copyright ?? "",
- "assetUrl": "file:///" +audio,
- "contentAdvisory": "",
- "releaseDateTime": "2022-05-13T00:23:00Z",
- "durationInMilliseconds": Math.floor((metadata.format.duration?? 0) * 1000),
-
- "offers": [
- {
- "kind": "get",
- "type": "STDQ"
- }
- ],
- "contentRating": "clean"
- }
- };
- numid += 1;
-
- // let form = {"id": "/ciderlocal?" + audio,
- // "type": "library-songs",
- // "href": "/ciderlocal?" + audio,
- // "artwork": {
- // "url": metadata.common.picture != undefined ? "data:image/png;base64,"+metadata.common.picture[0].data.toString('base64')+"" : "",
- // },
- // "attributes":
- // { "durationInMillis": Math.floor((metadata.format.duration?? 0) * 1000),
- // "hasLyrics": false,
- // "playParams": { "id": "/ciderlocal?" + audio, "kind": "song", "isLibrary": true, "reporting": false },
- // "trackNumber": 0,
- // "discNumber": 0,
- // "genreNames": [""],
- // "name": metadata.common.title,
- // "albumName": metadata.common.album,
- // "artistName": metadata.common.artist}}
- metadatalist.push(form)}
- } catch (e){}
- }
- // console.log('metadatalist', metadatalist);
- this.localSongs = metadatalist;
- BrowserWindow.win.webContents.send('getUpdatedLocalList', metadatalist);
- }
+ ipcMain.handle("scanLibrary", async (event, folders) => {
+ const oldmetadatalist = await LocalFiles.sendOldLibrary()
+ BrowserWindow.win.webContents.send('getUpdatedLocalList', oldmetadatalist);
+ const metadatalist = await LocalFiles.scanLibrary()
+ BrowserWindow.win.webContents.send('getUpdatedLocalList', metadatalist);
+ LocalFiles.cleanUpDB()
+ })
- )
+ LocalFiles.eventEmitter.on('newtracks', (data) => {
+ BrowserWindow.win.webContents.send('getUpdatedLocalList', data);
+ });
ipcMain.on('writeWAV', (event, leftpcm, rightpcm, bufferlength) => {
@@ -1445,13 +1374,13 @@ export class BrowserWindow {
console.log('sc', SoundCheckTag)
BrowserWindow.win.webContents.send('SoundCheckTag', SoundCheckTag)
}).catch(err => {
- console.log(err)
- });
+ console.log(err)
+ });
});
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
console.log('[Share Sheet - App.ts]', url)
const options = {
@@ -1470,10 +1399,17 @@ export class BrowserWindow {
}
});
+
ipcMain.on('open-appdata', (_event) => {
shell.openPath(app.getPath('userData'));
});
+ ipcMain.handle('folderSelector', async (_event) => {
+ let u = await dialog.showOpenDialog({
+ properties: ['openDirectory', 'multiSelections']
+ });
+ return u.filePaths
+ });
//#region Cider Connect
ipcMain.on('cc-auth', (_event) => {
@@ -1498,35 +1434,38 @@ export class BrowserWindow {
/* *********************************************************************************************
* Window Events
* **********************************************************************************************/
- if (process.platform === "win32") {
- let WND_STATE = {
- MINIMIZED: 0,
- NORMAL: 1,
- MAXIMIZED: 2,
- FULL_SCREEN: 3,
- };
- let wndState = WND_STATE.NORMAL;
+ let WND_STATE = {
+ MINIMIZED: 0,
+ NORMAL: 1,
+ MAXIMIZED: 2,
+ FULL_SCREEN: 3,
+ };
+ let wndState = WND_STATE.NORMAL;
+
+ BrowserWindow.win.on("resize", (_: any) => {
+ const isMaximized = BrowserWindow.win.isMaximized();
+ const isMinimized = BrowserWindow.win.isMinimized();
+ const isFullScreen = BrowserWindow.win.isFullScreen();
+ const state = wndState;
+ if (isMinimized && state !== WND_STATE.MINIMIZED) {
+ wndState = WND_STATE.MINIMIZED;
+ BrowserWindow.win.webContents.send('window-state-changed', 'minimized');
+ } else if (isFullScreen && state !== WND_STATE.FULL_SCREEN) {
+ wndState = WND_STATE.FULL_SCREEN;
+ BrowserWindow.win.webContents.send('window-state-changed', 'fullscreen')
+ } else if (isMaximized && state !== WND_STATE.MAXIMIZED) {
+ wndState = WND_STATE.MAXIMIZED;
+ BrowserWindow.win.webContents.send('window-state-changed', 'maximized')
+ BrowserWindow.win.webContents.executeJavaScript(`app.chrome.maximized = true`);
+ } else if (state !== WND_STATE.NORMAL) {
+ wndState = WND_STATE.NORMAL;
+ BrowserWindow.win.webContents.send('window-state-changed', 'normal')
+ BrowserWindow.win.webContents.executeJavaScript(
+ `app.chrome.maximized = false`
+ );
+ }
+ });
- BrowserWindow.win.on("resize", (_: any) => {
- const isMaximized = BrowserWindow.win.isMaximized();
- const isMinimized = BrowserWindow.win.isMinimized();
- const isFullScreen = BrowserWindow.win.isFullScreen();
- const state = wndState;
- if (isMinimized && state !== WND_STATE.MINIMIZED) {
- wndState = WND_STATE.MINIMIZED;
- } else if (isFullScreen && state !== WND_STATE.FULL_SCREEN) {
- wndState = WND_STATE.FULL_SCREEN;
- } else if (isMaximized && state !== WND_STATE.MAXIMIZED) {
- wndState = WND_STATE.MAXIMIZED;
- BrowserWindow.win.webContents.executeJavaScript(`app.chrome.maximized = true`);
- } else if (state !== WND_STATE.NORMAL) {
- wndState = WND_STATE.NORMAL;
- BrowserWindow.win.webContents.executeJavaScript(
- `app.chrome.maximized = false`
- );
- }
- });
- }
let isQuiting = false
@@ -1569,10 +1508,10 @@ export class BrowserWindow {
// Set window Handler
BrowserWindow.win.webContents.setWindowOpenHandler((x: any) => {
if (x.url.includes("apple") || x.url.includes("localhost")) {
- return {action: "allow"};
+ return { action: "allow" };
}
shell.openExternal(x.url).catch(console.error);
- return {action: "deny"};
+ return { action: "deny" };
});
}
@@ -1628,7 +1567,7 @@ export class BrowserWindow {
"CtlN": "Cider",
"iV": "196623"
};
- let server2 = mdns.createAdvertisement(x, `${await getPort({port: 3839})}`, {
+ let server2 = mdns.createAdvertisement(x, `${await getPort({ port: 3839 })}`, {
name: encoded,
txt: txt_record
});
diff --git a/src/main/base/plugins.ts b/src/main/base/plugins.ts
index d51e8a85..5873af4c 100644
--- a/src/main/base/plugins.ts
+++ b/src/main/base/plugins.ts
@@ -16,10 +16,10 @@ import {utils} from './utils';
* @see {@link https://github.com/ciderapp/Cider/wiki/Plugins|Documentation}
*/
export class Plugins {
+ private static PluginMap: any = {};
private basePluginsPath = path.join(__dirname, '../plugins');
private userPluginsPath = path.join(electron.app.getPath('userData'), 'Plugins');
private readonly pluginsList: any = {};
- private static PluginMap: any = {};
constructor() {
this.pluginsList = this.getPlugins();
@@ -35,8 +35,8 @@ export class Plugins {
public getPlugins(): any {
let plugins: any = {};
-
-
+
+
if (fs.existsSync(this.basePluginsPath)) {
fs.readdirSync(this.basePluginsPath).forEach(file => {
if (file.endsWith('.ts') || file.endsWith('.js')) {
@@ -49,8 +49,8 @@ export class Plugins {
}
});
}
-
-
+
+
if (fs.existsSync(this.userPluginsPath)) {
fs.readdirSync(this.userPluginsPath).forEach(file => {
// Plugins V1
@@ -104,10 +104,11 @@ export class Plugins {
public callPlugins(event: string, ...args: any[]) {
for (const plugin in this.pluginsList) {
if (this.pluginsList[plugin][event]) {
- try{
+ try {
this.pluginsList[plugin][event](...args);
- }catch(e) {
- console.log(`[${plugin}] Plugin error: ${e}`);
+ } catch (e) {
+ console.error(`[${plugin}] An error was encountered: ${e}`);
+ console.error(e)
}
}
}
diff --git a/src/main/base/store.ts b/src/main/base/store.ts
index 0e82df80..2debe3ca 100644
--- a/src/main/base/store.ts
+++ b/src/main/base/store.ts
@@ -2,6 +2,7 @@ import * as ElectronStore from 'electron-store';
import * as electron from "electron";
import {app} from "electron";
import fetch from "electron-fetch";
+
export class Store {
static cfg: ElectronStore;
@@ -12,15 +13,6 @@ export class Store {
},
"general": {
"close_button_hide": false,
- "discordrpc": {
- "enabled": true,
- "client": "Cider",
- "clear_on_pause": true,
- "hide_buttons": false,
- "hide_timestamp": false,
- "state_format": "by {artist}",
- "details_format": "{title}",
- },
"language": "en_US", // electron.app.getLocale().replace('-', '_') this can be used in future
"playbackNotifications": true,
"resumeOnStartupBehavior": "local",
@@ -39,7 +31,8 @@ export class Store {
"applemusic": false,
"library": false,
"amplaylists": false,
- "playlists": false
+ "playlists": false,
+ "localLibrary": false
},
"onStartup": {
"enabled": false,
@@ -66,7 +59,7 @@ export class Store {
"CommandOrControl",
"G"
],
- "songs" : [
+ "songs": [
"CommandOrControl",
"J"
],
@@ -89,17 +82,17 @@ export class Store {
],
"audioSettings": [
"CommandOrControl",
- process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift": "Alt"),
+ process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift" : "Alt"),
"A"
],
"pluginMenu": [
"CommandOrControl",
- process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift": "Alt"),
+ process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift" : "Alt"),
"P"
],
"castToDevices": [
"CommandOrControl",
- process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift": "Alt"),
+ process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift" : "Alt"),
"C"
],
"settings": [
@@ -126,12 +119,35 @@ export class Store {
},
"showLovedTracksInline": true
},
+ "connectivity": {
+ "discord_rpc": {
+ "enabled": true,
+ "client": "Cider",
+ "clear_on_pause": true,
+ "hide_buttons": false,
+ "hide_timestamp": false,
+ "state_format": "by {artist}",
+ "details_format": "{title}",
+ },
+ "lastfm": {
+ "enabled": false,
+ "scrobble_after": 50,
+ "filter_loop": false,
+ "filter_types": {},
+ "secrets": {
+ "username": "",
+ "key": ""
+ }
+
+ },
+ },
"home": {
"followedArtists": [],
"favoriteItems": []
},
"libraryPrefs": {
"songs": {
+ "scroll": "infinite",
"sort": "name",
"sortOrder": "asc",
"size": "normal"
@@ -141,6 +157,7 @@ export class Store {
"sortOrder": "asc",
"viewAs": "covers"
},
+ "localPaths": []
},
"audio": {
"volume": 1,
@@ -151,18 +168,19 @@ export class Store {
"playbackRate": 1,
"quality": "HIGH",
"seamless_audio": true,
- "normalization": false,
+ "normalization": true,
"dBSPL": false,
"dBSPLcalibration": 90,
"maikiwiAudio": {
- "ciderPPE": false,
+ "ciderPPE": true,
"ciderPPE_value": "MAIKIWI",
+ "opportunisticCorrection_state": "OFF",
"atmosphereRealizer1": false,
"atmosphereRealizer1_value": "NATURAL_STANDARD",
"atmosphereRealizer2": false,
"atmosphereRealizer2_value": "NATURAL_STANDARD",
"spatial": false,
- "spatialProfile": "71_420maikiwi",
+ "spatialProfile": "BPLK",
"vibrantBass": { // Hard coded into the app. Don't include any of this config into exporting presets in store.ts
'frequencies': [17.182, 42.169, 53.763, 112.69, 119.65, 264.59, 336.57, 400.65, 505.48, 612.7, 838.7, 1155.3, 1175.6, 3406.8, 5158.6, 5968.1, 6999.9, 7468.6, 8862.9, 9666, 10109],
'Q': [2.5, 0.388, 5, 5, 2.5, 7.071, 14.14, 10, 7.071, 14.14, 8.409, 0.372, 7.071, 10, 16.82, 7.071, 28.28, 20, 8.409, 40, 40],
@@ -221,28 +239,22 @@ export class Store {
"windowColor": "#000000",
"customAccentColor": false,
"accentColor": "#fc3c44",
- "purplePodcastPlaybackBar": false
+ "purplePodcastPlaybackBar": false,
+ "maxElementScale": -1 // -1 default, anything else is a custom scale
},
"lyrics": {
- "enable_mxm": false,
+ "enable_mxm": true,
"mxm_karaoke": false,
- "mxm_language": "en",
+ "mxm_language": "disabled",
"enable_qq": false,
"enable_yt": false,
},
- "lastfm": {
- "enabled": false,
- "scrobble_after": 30,
- "auth_token": "",
- "enabledRemoveFeaturingArtists": true,
- "filterLoop": true,
- "NowPlaying": "true"
- },
"advanced": {
- "AudioContext": false,
+ "AudioContext": true,
"experiments": [],
"playlistTrackMapping": true,
- "ffmpegLocation": ""
+ "ffmpegLocation": "",
+ "disableLogging": true
},
"connectUser": {
"auth": null,
@@ -253,15 +265,9 @@ export class Store {
}
},
}
- private migrations: any = {
- '>=1.4.3': (store: ElectronStore) => {
- if (typeof store.get('general.discordrpc') == 'number' || typeof store.get('general.discordrpc') == 'string') {
- store.delete('general.discordrpc');
- }
- },
- }
+ private migrations: any = {}
private schema: ElectronStore.Schema = {
- "general.discordrpc": {
+ "connectivity.discord_rpc": {
type: 'object'
},
}
@@ -272,57 +278,13 @@ export class Store {
defaults: this.defaults,
schema: this.schema,
migrations: this.migrations,
- clearInvalidConfig: true
+ clearInvalidConfig: false //disabled for now
});
Store.cfg.set(this.mergeStore(this.defaults, Store.cfg.store))
this.ipcHandler();
}
- /**
- * Merge Configurations
- * @param target The target configuration
- * @param source The source configuration
- */
- private mergeStore = (target: { [x: string]: any; }, source: { [x: string]: any; }) => {
- // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties
- for (const key of Object.keys(source)) {
- if (key.includes('migrations')) {
- continue;
- }
- if (source[key] instanceof Array) {
- continue
- }
- if (source[key] instanceof Object) Object.assign(source[key], this.mergeStore(target[key], source[key]))
- }
- // Join `target` and modified `source`
- Object.assign(target || {}, source)
- return target
- }
-
-
- /**
- * IPC Handler
- */
- private ipcHandler(): void {
- electron.ipcMain.handle('getStoreValue', (_event, key, defaultValue) => {
- return (defaultValue ? Store.cfg.get(key, true) : Store.cfg.get(key));
- });
-
- electron.ipcMain.handle('setStoreValue', (_event, key, value) => {
- Store.cfg.set(key, value);
- });
-
- electron.ipcMain.on('getStore', (event) => {
- event.returnValue = Store.cfg.store
- })
-
- electron.ipcMain.on('setStore', (_event, store) => {
- Store.cfg.store = store
- })
- }
-
-
static pushToCloud(): void {
if (Store.cfg.get('connectUser.auth') === null) return;
var syncData = Object();
@@ -336,7 +298,7 @@ export class Store {
plugins: Store.cfg.store.plugins
})
}
-
+
if (Store.cfg.get('connectUser.sync.settings')) {
syncData.push({
general: Store.cfg.get('general'),
@@ -360,4 +322,46 @@ export class Store {
body: JSON.stringify(postBody)
})
}
+
+ /**
+ * Merge Configurations
+ * @param target The target configuration
+ * @param source The source configuration
+ */
+ private mergeStore = (target: { [x: string]: any; }, source: { [x: string]: any; }) => {
+ // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties
+ for (const key of Object.keys(source)) {
+ if (key.includes('migrations')) {
+ continue;
+ }
+ if (source[key] instanceof Array) {
+ continue
+ }
+ if (source[key] instanceof Object) Object.assign(source[key], this.mergeStore(target[key], source[key]))
+ }
+ // Join `target` and modified `source`
+ Object.assign(target || {}, source)
+ return target
+ }
+
+ /**
+ * IPC Handler
+ */
+ private ipcHandler(): void {
+ electron.ipcMain.handle('getStoreValue', (_event, key, defaultValue) => {
+ return (defaultValue ? Store.cfg.get(key, true) : Store.cfg.get(key));
+ });
+
+ electron.ipcMain.handle('setStoreValue', (_event, key, value) => {
+ Store.cfg.set(key, value);
+ });
+
+ electron.ipcMain.on('getStore', (event) => {
+ event.returnValue = Store.cfg.store
+ })
+
+ electron.ipcMain.on('setStore', (_event, store) => {
+ Store.cfg.store = store
+ })
+ }
}
diff --git a/src/main/base/utils.ts b/src/main/base/utils.ts
index b0f1b513..da47e917 100644
--- a/src/main/base/utils.ts
+++ b/src/main/base/utils.ts
@@ -2,18 +2,39 @@ import * as fs from "fs";
import * as path from "path";
import {Store} from "./store";
import {BrowserWindow as bw} from "./browserwindow";
-import {app, dialog, ipcMain, Notification, shell, BrowserWindow} from "electron";
+import {app, BrowserWindow, ipcMain} from "electron";
import fetch from "electron-fetch";
-import {AppImageUpdater, NsisUpdater} from "electron-updater";
-import * as log from "electron-log";
import ElectronStore from "electron-store";
export class utils {
+ /**
+ * Playback Functions
+ */
+ static playback = {
+ pause: () => {
+ bw.win.webContents.executeJavaScript("MusicKitInterop.pause()")
+ },
+ play: () => {
+ bw.win.webContents.executeJavaScript("MusicKitInterop.play()")
+ },
+ playPause: () => {
+ bw.win.webContents.executeJavaScript("MusicKitInterop.playPause()")
+ },
+ next: () => {
+ bw.win.webContents.executeJavaScript("MusicKitInterop.next()")
+ },
+ previous: () => {
+ bw.win.webContents.executeJavaScript("MusicKitInterop.previous()")
+ },
+ seek: (seconds: number) => {
+ bw.win.webContents.executeJavaScript(`MusicKit.getInstance().seekToTime(${seconds})`)
+ }
+ }
/**
* Paths for the application to use
*/
- private static paths: any = {
+ static paths: any = {
srcPath: path.join(__dirname, "../../src"),
rendererPath: path.join(__dirname, "../../src/renderer"),
mainPath: path.join(__dirname, "../../src/main"),
@@ -43,6 +64,21 @@ export class utils {
return app;
}
+ /**
+ * Get the IPCMain
+ */
+ static getIPCMain(): Electron.IpcMain {
+ return ipcMain
+ }
+
+ /*
+ * Get the Express instance
+ * @returns {any}
+ */
+ static getExpress(): any {
+ return bw.express
+ }
+
/**
* Fetches the i18n locale for the given language.
* @param language {string} The language to fetch the locale for.
@@ -64,7 +100,7 @@ export class utils {
} else {
i18n = Object.assign(i18n, JSON.parse(fs.readFileSync(path.join(this.paths.i18nPath, `en_US.json`), "utf8")));
}
- })
+ })
}
if (key) {
return i18n[key]
@@ -90,7 +126,6 @@ export class utils {
return Store.cfg.store
}
-
/**
* Get the store instance
* @returns {Store}
@@ -116,10 +151,6 @@ export class utils {
return Store.pushToCloud
}
-
-
-
-
/**
* Gets the browser window
*/
@@ -138,25 +169,4 @@ export class utils {
static loadJSFrontend(path: string): void {
bw.win.webContents.executeJavaScript(fs.readFileSync(path, "utf8"));
}
-
- /**
- * Playback Functions
- */
- static playback = {
- pause: () => {
- bw.win.webContents.executeJavaScript("MusicKitInterop.pause()")
- },
- play: () => {
- bw.win.webContents.executeJavaScript("MusicKitInterop.play()")
- },
- playPause: () => {
- bw.win.webContents.executeJavaScript("MusicKitInterop.playPause()")
- },
- next: () => {
- bw.win.webContents.executeJavaScript("MusicKitInterop.next()")
- },
- previous: () => {
- bw.win.webContents.executeJavaScript("MusicKitInterop.previous()")
- }
- }
}
diff --git a/src/main/base/vcomponents.json b/src/main/base/vcomponents.json
index 42f86c68..fcbc115c 100644
--- a/src/main/base/vcomponents.json
+++ b/src/main/base/vcomponents.json
@@ -6,7 +6,6 @@
"pages/library-artists",
"pages/browse",
"pages/groupings",
- "pages/settings",
"pages/installed-themes",
"pages/listen_now",
"pages/radio",
@@ -60,6 +59,7 @@
"components/fullscreen",
"components/miniplayer",
"components/castmenu",
+ "components/pathmenu",
"components/airplay-modal",
"components/artist-chip",
"components/hello-world",
diff --git a/src/main/base/vrouting.json b/src/main/base/vrouting.json
index 6d69582c..613103d1 100644
--- a/src/main/base/vrouting.json
+++ b/src/main/base/vrouting.json
@@ -69,6 +69,11 @@
"component": " ",
"condition": "page.includes('album_')"
},
+ {
+ "page": "social-profiles_",
+ "component": " ",
+ "condition": "$root.page.includes('social-profiles_')"
+ },
{
"page": "recordLabel_",
"component": " ",
diff --git a/src/main/index.ts b/src/main/index.ts
index ce2d043d..dcb407c2 100644
--- a/src/main/index.ts
+++ b/src/main/index.ts
@@ -1,18 +1,18 @@
-require('v8-compile-cache');
-
-const {app, components, ipcMain} = require('electron');
-import {join} from 'path';
+require("v8-compile-cache");
+import {join} from "path";
+import {app} from "electron"
if (!app.isPackaged) {
- app.setPath('userData', join(app.getPath('appData'), 'Cider'));
+ app.setPath("userData", join(app.getPath("appData"), "Cider"));
}
import {Store} from "./base/store";
import {AppEvents} from "./base/app";
import {Plugins} from "./base/plugins";
import {BrowserWindow} from "./base/browserwindow";
-import {init as Sentry} from '@sentry/electron';
+import {init as Sentry} from "@sentry/electron";
import {RewriteFrames} from "@sentry/integrations";
+import {components, ipcMain} from "electron"
// Analytics for debugging fun yeah.
Sentry({
@@ -32,13 +32,13 @@ const CiderPlug = new Plugins();
* App Event Handlers
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-app.on('ready', () => {
+app.on("ready", () => {
Cider.ready(CiderPlug);
- console.log('[Cider] Application is Ready. Creating Window.')
+ console.log("[Cider] Application is Ready. Creating Window.")
if (!app.isPackaged) {
- console.info('[Cider] Running in development mode.')
- require('vue-devtools').install()
+ console.info("[Cider] Running in development mode.")
+ require("vue-devtools").install()
}
components.whenReady().then(async () => {
@@ -49,11 +49,11 @@ app.on('ready', () => {
console.log(gpuInfo)
})
- console.log('[Cider][Widevine] Status:', components.status());
+ console.log("[Cider][Widevine] Status:", components.status());
Cider.bwCreated();
win.on("ready-to-show", () => {
- console.debug('[Cider] Window is Ready.')
- CiderPlug.callPlugins('onReady', win);
+ console.debug("[Cider] Window is Ready.")
+ CiderPlug.callPlugins("onReady", win);
win.show();
});
});
@@ -68,20 +68,16 @@ ipcMain.handle("renderer-ready", (event) => {
CiderPlug.callPlugins("onRendererReady", event);
})
-ipcMain.on('playbackStateDidChange', (_event, attributes) => {
- CiderPlug.callPlugins('onPlaybackStateDidChange', attributes);
+ipcMain.on("playbackStateDidChange", (_event, attributes) => {
+ CiderPlug.callPlugins("onPlaybackStateDidChange", attributes);
});
-ipcMain.on('nowPlayingItemDidChange', (_event, attributes) => {
- CiderPlug.callPlugins('onNowPlayingItemDidChange', attributes);
+ipcMain.on("nowPlayingItemDidChange", (_event, attributes) => {
+ CiderPlug.callPlugins("onNowPlayingItemDidChange", attributes);
});
-ipcMain.on('nowPlayingItemDidChangeLastFM', (_event, attributes) => {
- CiderPlug.callPlugin('lastfm.js', 'nowPlayingItemDidChangeLastFM', attributes);
-})
-
-app.on('before-quit', () => {
- CiderPlug.callPlugins('onBeforeQuit');
+app.on("before-quit", () => {
+ CiderPlug.callPlugins("onBeforeQuit");
console.warn(`${app.getName()} exited.`);
});
@@ -90,21 +86,21 @@ app.on('before-quit', () => {
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// @ts-ignore
-app.on('widevine-ready', (version, lastVersion) => {
+app.on("widevine-ready", (version, lastVersion) => {
if (null !== lastVersion) {
- console.log('[Cider][Widevine] Widevine ' + version + ', upgraded from ' + lastVersion + ', is ready to be used!')
+ console.log("[Cider][Widevine] Widevine " + version + ", upgraded from " + lastVersion + ", is ready to be used!")
} else {
- console.log('[Cider][Widevine] Widevine ' + version + ' is ready to be used!')
+ console.log("[Cider][Widevine] Widevine " + version + " is ready to be used!")
}
})
// @ts-ignore
-app.on('widevine-update-pending', (currentVersion, pendingVersion) => {
- console.log('[Cider][Widevine] Widevine ' + currentVersion + ' is ready to be upgraded to ' + pendingVersion + '!')
+app.on("widevine-update-pending", (currentVersion, pendingVersion) => {
+ console.log("[Cider][Widevine] Widevine " + currentVersion + " is ready to be upgraded to " + pendingVersion + "!")
})
// @ts-ignore
-app.on('widevine-error', (error) => {
- console.log('[Cider][Widevine] Widevine installation encountered an error: ' + error)
+app.on("widevine-error", (error) => {
+ console.log("[Cider][Widevine] Widevine installation encountered an error: " + error)
app.exit()
})
diff --git a/src/main/plugins/discordrpc.ts b/src/main/plugins/discordrpc.ts
index 9cc7baf1..9c606d17 100644
--- a/src/main/plugins/discordrpc.ts
+++ b/src/main/plugins/discordrpc.ts
@@ -52,29 +52,57 @@ export default class DiscordRPC {
const self = this
this.connect();
console.debug(`[Plugin][${this.name}] Ready.`);
- ipcMain.on('updateRPCImage', (_event, imageurl) => {
+ ipcMain.on('updateRPCImage', async (_event, imageurl) => {
if (!this._utils.getStoreValue("general.privateEnabled")) {
- fetch('https://api.cider.sh/v1/images', {
+ let b64data = ""
+ let postbody = ""
+ if (imageurl.startsWith("/ciderlocalart")){
+ let port = await _win.webContents.executeJavaScript(
+ `app.clientPort`
+ );
+ console.log("http://localhost:"+port+imageurl)
+ const response = await fetch("http://localhost:"+port+imageurl)
+ b64data = (await response.buffer()).toString('base64');
+ postbody = JSON.stringify({data: b64data})
+ fetch('https://api.cider.sh/v1/images', {
- method: 'POST',
- body: JSON.stringify({url: imageurl}),
- headers: {
- 'Content-Type': 'application/json',
- 'User-Agent': _win.webContents.getUserAgent()
- },
- })
- .then(res => res.json())
- .then(function (json) {
- self._attributes["artwork"]["url"] = json.url
- self.setActivity(self._attributes)
+ method: 'POST',
+ body: postbody,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'User-Agent': _win.webContents.getUserAgent()
+ },
})
+ .then(res => res.json())
+ .then(function (json) {
+ self._attributes["artwork"]["url"] = json.url
+ self.setActivity(self._attributes)
+ })
+ } else {
+ postbody = JSON.stringify({url: imageurl})
+ fetch('https://api.cider.sh/v1/images', {
+
+ method: 'POST',
+ body: postbody,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'User-Agent': _win.webContents.getUserAgent()
+ },
+ })
+ .then(res => res.json())
+ .then(function (json) {
+ self._attributes["artwork"]["url"] = json.url
+ self.setActivity(self._attributes)
+ })
+ }
+
}
})
ipcMain.on("reloadRPC", () => {
console.log(`[DiscordRPC][reload] Reloading DiscordRPC.`);
this._client.destroy()
- this._client.endlessLogin({clientId: this._utils.getStoreValue("general.discordrpc.client") === "Cider" ? '911790844204437504' : '886578863147192350'})
+ this._client.endlessLogin({clientId: this._utils.getStoreValue("connectivity.discord_rpc.client") === "Cider" ? '911790844204437504' : '886578863147192350'})
.then(() => {
this.ready = true
this._utils.getWindow().webContents.send("rpcReloaded", this._client.user)
@@ -88,6 +116,7 @@ export default class DiscordRPC {
})
}
+
/**
* Runs on app stop
*/
@@ -125,7 +154,7 @@ export default class DiscordRPC {
* @private
*/
private connect() {
- if (!this._utils.getStoreValue("general.discordrpc.enabled")) {
+ if (!this._utils.getStoreValue("connectivity.discord_rpc.enabled")) {
return;
}
@@ -143,7 +172,7 @@ export default class DiscordRPC {
})
// Login to Discord
- this._client.endlessLogin({clientId: this._utils.getStoreValue("general.discordrpc.client") === "Cider" ? '911790844204437504' : '886578863147192350'})
+ this._client.endlessLogin({clientId: this._utils.getStoreValue("connectivity.discord_rpc.client") === "Cider" ? '911790844204437504' : '886578863147192350'})
.then(() => {
this.ready = true
})
@@ -161,8 +190,8 @@ export default class DiscordRPC {
// Check if show buttons is (true) or (false)
let activity: Object = {
- details: this._utils.getStoreValue("general.discordrpc.details_format"),
- state: this._utils.getStoreValue("general.discordrpc.state_format"),
+ details: this._utils.getStoreValue("connectivity.discord_rpc.details_format"),
+ state: this._utils.getStoreValue("connectivity.discord_rpc.state_format"),
largeImageKey: attributes?.artwork?.url?.replace('{w}', '1024').replace('{h}', '1024'),
largeImageText: attributes.albumName,
instance: false // Whether the activity is in a game session
@@ -177,7 +206,7 @@ export default class DiscordRPC {
}
// Set the activity
- if (!attributes.status && this._utils.getStoreValue("general.discordrpc.clear_on_pause")) {
+ if (!attributes.status && this._utils.getStoreValue("connectivity.discord_rpc.clear_on_pause")) {
this._client.clearActivity()
} else if (activity && this._activityCache !== activity) {
this._client.setActivity(activity)
@@ -191,7 +220,7 @@ export default class DiscordRPC {
private filterActivity(activity: any, attributes: any): Object {
// Add the buttons if people want them
- if (!this._utils.getStoreValue("general.discordrpc.hide_buttons")) {
+ if (!this._utils.getStoreValue("connectivity.discord_rpc.hide_buttons")) {
activity.buttons = [
{label: 'Listen on Cider', url: attributes.url.cider},
{label: 'View on Apple Music', url: attributes.url.appleMusic}
@@ -199,13 +228,13 @@ export default class DiscordRPC {
}
// Add the timestamp if its playing and people want them
- if (!this._utils.getStoreValue("general.discordrpc.hide_timestamp") && attributes.status) {
+ if (!this._utils.getStoreValue("connectivity.discord_rpc.hide_timestamp") && attributes.status) {
activity.startTimestamp = Date.now() - (attributes?.durationInMillis - attributes?.remainingTime)
activity.endTimestamp = attributes.endTime
}
// If the user wants to keep the activity when paused
- if (!this._utils.getStoreValue("general.discordrpc.clear_on_pause")) {
+ if (!this._utils.getStoreValue("connectivity.discord_rpc.clear_on_pause")) {
activity.smallImageKey = attributes.status ? 'play' : 'pause';
activity.smallImageText = attributes.status ? 'Playing' : 'Paused';
}
diff --git a/src/main/plugins/lastfm.ts b/src/main/plugins/lastfm.ts
index 5018c01b..027f997c 100644
--- a/src/main/plugins/lastfm.ts
+++ b/src/main/plugins/lastfm.ts
@@ -1,278 +1,236 @@
-import * as electron from 'electron';
-import * as fs from 'fs';
-import {resolve} from 'path';
+export default class lastfm {
-export default class LastFMPlugin {
- private sessionPath = resolve(electron.app.getPath('userData'), 'session.json');
- private apiCredentials = {
+ /**
+ * Base Plugin Information
+ */
+ public name: string = 'LastFM Plugin';
+ public version: string = '2.0.0';
+ public author: string = 'Core (Cider Collective)';
+
+
+ private _apiCredentials = {
key: "f9986d12aab5a0fe66193c559435ede3",
secret: "acba3c29bd5973efa38cc2f0b63cc625"
}
/**
- * Private variables for interaction in plugins
+ * Plugin Initialization
*/
- private _win: any;
- private _app: any;
- private _lastfm: any;
- private _store: any;
- private _timer: any;
-
- private authenticateFromFile() {
- let sessionData = require(this.sessionPath)
- console.log("[LastFM][authenticateFromFile] Logging in with Session Info.")
- this._lastfm.setSessionCredentials(sessionData.username, sessionData.key)
- console.log("[LastFM][authenticateFromFile] Logged in.", sessionData.username, sessionData.key)
- }
-
-
- authenticate() {
- try {
- if (this._store.lastfm.auth_token) {
- this._store.lastfm.enabled = true;
- }
-
- if (!this._store.lastfm.enabled || !this._store.lastfm.auth_token) {
- this._store.lastfm.enabled = false;
- return
- }
- /// dont move this require to top , app wont load
- const LastfmAPI = require('lastfmapi');
- const lfmAPI = new LastfmAPI({
- 'api_key': this.apiCredentials.key,
- 'secret': this.apiCredentials.secret
- });
-
- this._lastfm = Object.assign(lfmAPI, {cachedAttributes: false, cachedNowPlayingAttributes: false});
-
- fs.stat(this.sessionPath, (err: any) => {
- if (err) {
- console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err)
- console.log("[LastFM][Auth] Beginning authentication from configuration")
- console.log("[LastFM][tk]", this._store.lastfm.auth_token)
- this._lastfm.authenticate(this._store.lastfm.auth_token, (err: any, session: any) => {
- if (err) {
- throw err;
- }
- console.log("[LastFM] Successfully obtained LastFM session info,", session); // {"name": "LASTFM_USERNAME", "key": "THE_USER_SESSION_KEY"}
- console.log("[LastFM] Saving session info to disk.")
- let tempData = JSON.stringify(session)
- fs.writeFile(this.sessionPath, tempData, (err: any) => {
- if (err)
- console.log("[LastFM][fs]", err)
- else {
- console.log("[LastFM][fs] File was written successfully.")
- this.authenticateFromFile()
- new electron.Notification({
- title: electron.app.getName(),
- body: "Successfully logged into LastFM using Authentication Key."
- }).show()
- }
- })
- });
- } else {
- this.authenticateFromFile()
- }
- })
- } catch (err) {
- console.log(err)
- }
- }
-
- private scrobbleSong(attributes: any) {
- if (this._timer) clearTimeout(this._timer);
- var self = this;
- this._timer = setTimeout(async () => {
- const currentAttributes = attributes;
-
- if (!self._lastfm || self._lastfm.cachedAttributes === attributes) {
- return
- }
-
- if (self._lastfm.cachedAttributes) {
- if (self._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return;
- }
-
- const artist = await this.getPrimaryArtist(attributes)
- const album = this.getAlbumName(attributes)
-
- if (currentAttributes.status && currentAttributes === attributes) {
- if (fs.existsSync(this.sessionPath)) {
- // Scrobble playing song.
- if (attributes.status === true) {
- self._lastfm.track.scrobble({
- 'artist': artist,
- 'track': attributes.name,
- 'album': album,
- 'albumArtist': artist,
- 'timestamp': new Date().getTime() / 1000
- }, function (err: any, scrobbled: any) {
- if (err) {
- return console.error('[LastFM] An error occurred while scrobbling', err);
- }
-
- console.log('[LastFM] Successfully scrobbled: ', scrobbled);
- });
- self._lastfm.cachedAttributes = attributes
- }
- } else {
- self.authenticate();
- }
- } else {
- return console.log('[LastFM] Did not add ', attributes.name, '—', artist, 'because now playing a other song.');
- }
- }, Math.round(attributes.durationInMillis * Math.min((self._store.lastfm.scrobble_after / 100), 0.8)));
- }
-
- private async updateNowPlayingSong(attributes: any) {
- if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._store.lastfm.NowPlaying) {
- return
- }
-
- if (this._lastfm.cachedNowPlayingAttributes) {
- if (this._lastfm.cachedNowPlayingAttributes.playParams.id === attributes.playParams.id) return;
- }
-
- if (fs.existsSync(this.sessionPath)) {
- const artist = await this.getPrimaryArtist(attributes)
- const album = this.getAlbumName(attributes)
-
- // update Now Playing
- if (attributes.status === true) {
- this._lastfm.track.updateNowPlaying({
- 'artist': artist,
- 'track': attributes.name,
- 'album': album,
- 'albumArtist': artist
- }, function (err: any, nowPlaying: any) {
- if (err) {
- return console.error('[LastFM] An error occurred while updating nowPlayingSong', err);
- }
-
- console.log('[LastFM] Successfully updated nowPlayingSong', nowPlaying);
- });
- this._lastfm.cachedNowPlayingAttributes = attributes
- }
-
- } else {
- this.authenticate()
- }
- }
-
- private getAlbumName(attributes: any): string {
- return attributes.albumName.replace(/ - Single| - EP/g, '');
- }
-
- private async getPrimaryArtist(attributes: any) {
- const songId = attributes.playParams.catalogId || attributes.playParams.id
-
- if (!this._store.lastfm.enabledRemoveFeaturingArtists || !songId) return attributes.artistName;
-
- const res = await this._win.webContents.executeJavaScript(`
- (async () => {
- const subMk = await MusicKit.getInstance().api.v3.music("/v1/catalog/" + MusicKit.getInstance().storefrontId + "/songs/${songId}", {
- include: {
- songs: ["artists"]
- }
- })
- if (!subMk) console.error('[LastFM] Request failed: /v1/catalog/us/songs/${songId}')
- return subMk.data
- })()
- `).catch(console.error)
- if (!res) return attributes.artistName
-
- const data = res.data
- if (!data.length) {
- console.error(`[LastFM] Unable to locate song with id of ${songId}`)
- return attributes.artistName;
- }
-
- const artists = res.data[0].relationships.artists.data
- if (!artists.length) {
- console.error(`[LastFM] Unable to find artists related to the song with id of ${songId}`)
- return attributes.artistName;
- }
-
- const primaryArtist = artists[0]
- return primaryArtist.attributes.name
- }
+ private _lfm: any = null;
+ private _authenticated: boolean = false;
+ private _scrobbleDelay: any = null;
+ private _utils: any = null;
+ private _scrobbleCache: any = {};
+ private _nowPlayingCache: any = {};
/**
- * Base Plugin Details (Eventually implemented into a GUI in settings)
+ * Public Methods
*/
- public name: string = 'LastFMPlugin';
- public description: string = 'LastFM plugin for Cider';
- public version: string = '0.0.1';
- public author: string = 'vapormusic / Cider Collective';
- /**
- * Runs on plugin load (Currently run on application start)
- */
- constructor(utils: { getApp: () => any; getStore: () => any; }) {
- this._app = utils.getApp();
- this._store = utils.getStore()
- utils.getApp().on('second-instance', (_e: any, argv: any) => {
- // Checks if first instance is authorized and if second instance has protocol args
- argv.forEach((value: any) => {
- if (value.includes('auth')) {
- console.log('[LastFMPlugin ok]')
- let authURI = String(argv).split('/auth/')[1];
- if (authURI.startsWith('lastfm')) { // If we wanted more auth options
- const authKey = authURI.split('lastfm?token=')[1];
- this._store.lastfm.enabled = true;
- this._store.lastfm.auth_token = authKey;
- console.log(authKey);
- this._win.webContents.send('LastfmAuthenticated', authKey);
- this.authenticate();
- }
- }
- })
+ constructor(utils: any) {
+ this._utils = utils;
+ }
+
+ onReady(_win: Electron.BrowserWindow): void {
+ this.initializeLastFM("", this._apiCredentials)
+
+ // Register the ipcMain handlers
+ this._utils.getIPCMain().handle('lastfm:url', (event: any) => {
+ console.debug(`[${lastfm.name}:url] Called.`)
+ return this._lfm.getAuthenticationUrl({"cb": "cider://auth/lastfm"})
})
- electron.app.on('open-url', (event: any, arg: any) => {
- console.log('[LastFMPlugin] yes')
- event.preventDefault();
- if (arg.includes('auth')) {
- let authURI = String(arg).split('/auth/')[1];
- if (authURI.startsWith('lastfm')) { // If we wanted more auth options
- const authKey = authURI.split('lastfm?token=')[1];
- this._store.lastfm.enabled = true;
- this._store.lastfm.auth_token = authKey;
- this._win.webContents.send('LastfmAuthenticated', authKey);
- console.log(authKey);
- this.authenticate();
- }
- }
+
+ this._utils.getIPCMain().on('lastfm:auth', (event: any, token: string) => {
+ console.debug(`[${lastfm.name}:auth] Token: `, token)
+ this.authenticateLastFM(token)
+ })
+
+ this._utils.getIPCMain().on('lastfm:disconnect', (_event: any) => {
+ this._lfm.setSessionCredentials(null, null);
+ this._authenticated = false;
+ console.debug(`[${lastfm.name}:disconnect] Disconnected`)
+ })
+
+ this._utils.getIPCMain().on('lastfm:nowPlayingChange', (event: any, attributes: any) => {
+ if (this._utils.getStoreValue("connectivity.lastfm.filter_loop") || this._utils.getStoreValue("general.privateEnabled")) return;
+ this.updateNowPlayingTrack(attributes)
+ })
+
+ this._utils.getIPCMain().on('lastfm:scrobbleTrack', (event: any, attributes: any) => {
+ if (this._utils.getStoreValue("general.privateEnabled")) return;
+ this.scrobbleTrack(attributes)
})
}
/**
- * Runs on app ready
+ * Runs on playback State Change
+ * @param attributes Music Attributes (attributes.status = current state)
*/
- onReady(win: any): void {
- this._win = win;
- this.authenticate();
- }
-
- /**
- * Runs on app stop
- */
- onBeforeQuit(): void {
- console.log('Example plugin stopped');
+ onPlaybackStateDidChange(attributes: object): void {
}
/**
* Runs on song change
* @param attributes Music Attributes
+ * @param scrobble
*/
- nowPlayingItemDidChangeLastFM(attributes: any): void {
- if (!this._store.general.privateEnabled) {
- attributes.status = true
- if (!this._store.lastfm.filterLoop) {
- this._lastfm.cachedNowPlayingAttributes = false;
- this._lastfm.cachedAttributes = false
- }
- this.updateNowPlayingSong(attributes)
- this.scrobbleSong(attributes)
+ onNowPlayingItemDidChange(attributes: any, scrobble = false): void {
+ if (this._utils.getStoreValue("general.privateEnabled")) return;
+ this.updateNowPlayingTrack(attributes)
+ }
+
+ /**
+ * Initialize LastFM
+ * @param token
+ * @param api
+ * @private
+ */
+ private initializeLastFM(token: string, api: { key: string, secret: string }): void {
+ console.debug(`[${lastfm.name}:initialize] Initializing LastFM`)
+ const LastfmAPI = require("lastfmapi")
+ this._lfm = new LastfmAPI({
+ 'api_key': api.key,
+ 'secret': api.secret,
+ });
+
+ if (this._utils.getStoreValue("connectivity.lastfm.secrets.username") && this._utils.getStoreValue("connectivity.lastfm.secrets.key")) {
+ this._lfm.setSessionCredentials(this._utils.getStoreValue("connectivity.lastfm.secrets.username"), this._utils.getStoreValue("connectivity.lastfm.secrets.key"));
+ this._authenticated = true;
+ } else {
+ this.authenticateLastFM(token)
}
}
-}
+ /**
+ * Authenticate the user with the given token
+ * @param token
+ * @private
+ */
+ private authenticateLastFM(token: string): void {
+ if (!token) return;
+ this._lfm.authenticate(token, (err: any, session: any) => {
+ if (err) {
+ console.error(`[${lastfm.name}:authenticate] Error: ${typeof err === "string" ? err : err.message}`);
+
+ this._utils.getWindow().webContents.executeJavaScript(`app.notyf.error("${err.message}");`)
+ return;
+ }
+ this._utils.getWindow().webContents.send('lastfm:authenticated', session)
+ this._authenticated = true;
+ console.debug(`[${lastfm.name}:authenticate] Authenticated as ${session.username}`)
+ });
+ }
+
+ /**
+ * Verifies the track information with lastfm
+ * @param attributes
+ * @param callback
+ * @private
+ */
+ private verifyTrack(attributes: any, callback: Function): void {
+ if (!attributes) return attributes;
+
+ if (!attributes.lfmAlbum) {
+ this._lfm.album.getInfo({
+ "artist": attributes.artistName,
+ "album": attributes.albumName
+ }, (err: any, data: any) => {
+ if (err) {
+ console.error(`[${lastfm.name}] [album.getInfo] Error: ${typeof err === "string" ? err : err.message}`)
+ return {};
+ }
+ if (data) {
+ attributes.lfmAlbum = data
+ callback(attributes)
+ }
+ })
+ } else {
+ this._lfm.track.getCorrection(attributes.artistName, attributes.name, (err: any, data: any) => {
+ if (err) {
+ console.error(`[${lastfm.name}] [track.getCorrection] Error: ${typeof err === "string" ? err : err.message}`)
+ return {};
+ }
+ if (data) {
+ attributes.lfmTrack = data.correction.track
+ callback(attributes)
+ }
+ })
+ }
+
+
+ }
+
+ /**
+ * Scrobbles the track to lastfm
+ * @param attributes
+ * @private
+ */
+ private scrobbleTrack(attributes: any): void {
+ if (!attributes?.lfmTrack || !attributes?.lfmAlbum) {
+ this.verifyTrack(attributes, (a: any) => {
+ this.scrobbleTrack(a)
+ })
+ return
+ }
+
+ if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._scrobbleCache.track === attributes.lfmTrack.name)) return;
+
+ // Scrobble
+ const scrobble = {
+ 'artist': attributes.lfmTrack.artist.name,
+ 'track': attributes.lfmTrack.name,
+ 'album': attributes.lfmAlbum.name,
+ 'albumArtist': attributes.lfmAlbum.artist,
+ 'timestamp': new Date().getTime() / 1000,
+ 'trackNumber': attributes.trackNumber,
+ 'duration': attributes.durationInMillis / 1000,
+ }
+
+ // Easy Debugging
+ console.debug(`[${lastfm.name}:scrobble] Scrobbling ${scrobble.artist} - ${scrobble.track}`)
+
+ // Scrobble the track
+ this._lfm.track.scrobble(scrobble, (err: any, _res: any) => {
+ if (err) {
+ console.error(`[${lastfm.name}:scrobble] Scrobble failed: ${err.message}`);
+ } else {
+ console.debug(`[${lastfm.name}:scrobble] Track scrobbled: ${scrobble.artist} - ${scrobble.track}`);
+ this._scrobbleCache = scrobble
+ }
+ });
+ }
+
+ /**
+ * Updates the now playing track
+ * @param attributes
+ * @private
+ */
+ private updateNowPlayingTrack(attributes: any): void {
+ if (!attributes?.lfmTrack || !attributes?.lfmAlbum) {
+ this.verifyTrack(attributes, (a: any) => {
+ this.updateNowPlayingTrack(a)
+ })
+ return
+ }
+
+ if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._nowPlayingCache.track === attributes.lfmTrack.name)) return;
+
+ const nowPlaying = {
+ 'artist': attributes.lfmTrack.artist.name,
+ 'track': attributes.lfmTrack.name,
+ 'album': attributes.lfmAlbum.name,
+ 'trackNumber': attributes.trackNumber,
+ 'duration': attributes.durationInMillis / 1000,
+ 'albumArtist': attributes.lfmAlbum.artist,
+ }
+
+ this._lfm.track.updateNowPlaying(nowPlaying, (err: any, res: any) => {
+ if (err) {
+ console.error(`[${lastfm.name}:updateNowPlaying] Now Playing Update failed: ${err.message}`);
+ } else {
+ console.debug(`[${lastfm.name}:updateNowPlaying] Now Playing Updated: ${nowPlaying.artist} - ${nowPlaying.track}`);
+ this._nowPlayingCache = nowPlaying
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/plugins/menubar.ts b/src/main/plugins/menubar.ts
index 9546e5d8..a51b6b05 100644
--- a/src/main/plugins/menubar.ts
+++ b/src/main/plugins/menubar.ts
@@ -37,7 +37,7 @@ export default class Thumbar {
{
label: utils.getLocale(utils.getStoreValue('general.language'), 'term.settings'),
accelerator: utils.getStoreValue("general.keybindings.settings").join('+'),
- click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('settings')`)
+ click: () => utils.getWindow().webContents.executeJavaScript(`app.openSettingsPage()`)
},
...(this.isMac ? [
{type: 'separator'},
diff --git a/src/main/plugins/mpris.ts b/src/main/plugins/mpris.ts
index 25730ee9..2dcfa64d 100644
--- a/src/main/plugins/mpris.ts
+++ b/src/main/plugins/mpris.ts
@@ -6,7 +6,10 @@ export default class mpris {
* Private variables for interaction in plugins
*/
private static utils: any;
-
+ /**
+ * MPRIS Service
+ */
+ private static player: Player.Player;
/**
* Base Plugin Details (Eventually implemented into a GUI in settings)
*/
@@ -15,30 +18,17 @@ export default class mpris {
public version: string = '1.0.0';
public author: string = 'Core';
- /**
- * MPRIS Service
- */
- private static player: Player.Player;
- private static mprisEvents: Object = {
- "playpause": "playPause",
- "play": "play",
- "pause": "pause",
- "next": "next",
- "previous": "previous",
- }
-
/*******************************************************************************************
* Private Methods
* ****************************************************************************************/
/**
- * Runs a media event
- * @param type - pausePlay, next, previous
- * @private
+ * Runs on plugin load (Currently run on application start)
*/
- private static runMediaEvent(type: string) {
- console.debug(`[Plugin][${this.name}] ${type}.`);
- mpris.utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.${type}()`).catch(console.error)
+ constructor(utils: any) {
+ mpris.utils = utils
+
+ console.debug(`[Plugin][${mpris.name}] Loading Complete.`);
}
/**
@@ -54,7 +44,6 @@ export default class mpris {
}
}
-
/**
* Connects to MPRIS Service
*/
@@ -63,29 +52,49 @@ export default class mpris {
const player = Player({
name: 'cider',
identity: 'Cider',
- supportedUriSchemes: [],
- supportedMimeTypes: [],
supportedInterfaces: ['player']
});
- console.debug(`[Plugin][${mpris.name}] Successfully connected.`);
+ console.debug(`[${mpris.name}:connect] Successfully connected.`);
- const pos_atr = {durationInMillis: 0};
- player.getPosition = function () {
- const durationInMicro = pos_atr.durationInMillis * 1000;
- const percentage = parseFloat("0") || 0;
- return durationInMicro * percentage;
+ const renderer = mpris.utils.getWindow().webContents
+ const loopType: { [key: string]: number; } = {
+ 'none': 0,
+ 'track': 1,
+ 'playlist': 2,
}
- for (const [key, value] of Object.entries(mpris.mprisEvents)) {
- player.on(key, function () {
- mpris.runMediaEvent(value)
- });
- }
+ player.on('next', () => mpris.utils.playback.next())
+ player.on('previous', () => mpris.utils.playback.previous())
+ player.on('playpause', () => mpris.utils.playback.playPause())
+ player.on('play', () => mpris.utils.playback.play())
+ player.on('pause', () => mpris.utils.playback.pause())
+ player.on('quit', () => mpris.utils.getApp().exit())
+ player.on('position', (args: { position: any; }) => mpris.utils.playback.seek(args.position / 1000 / 1000))
+ player.on('loopStatus', (status: string) => renderer.executeJavaScript(`app.mk.repeatMode = ${loopType[status.toLowerCase()]}`))
+ player.on('shuffle', () => renderer.executeJavaScript('app.mk.shuffleMode = (app.mk.shuffleMode === 0) ? 1 : 0'))
- player.on('quit', function () {
- process.exit();
- });
+ mpris.utils.getIPCMain().on('mpris:playbackTimeDidChange', (event: any, time: number) => {
+ player.getPosition = () => time;
+ })
+
+ mpris.utils.getIPCMain().on('repeatModeDidChange', (_e: any, mode: number) => {
+ switch (mode) {
+ case 0:
+ player.loopStatus = Player.LOOP_STATUS_NONE;
+ break;
+ case 1:
+ player.loopStatus = Player.LOOP_STATUS_TRACK;
+ break;
+ case 2:
+ player.loopStatus = Player.LOOP_STATUS_PLAYLIST;
+ break;
+ }
+ })
+
+ mpris.utils.getIPCMain().on('shuffleModeDidChange', (_e: any, mode: number) => {
+ player.shuffle = mode === 1
+ })
mpris.player = player;
}
@@ -93,9 +102,9 @@ export default class mpris {
/**
* Update M.P.R.I.S Player Attributes
*/
- private static updatePlayer(attributes: any) {
+ private static updateMetaData(attributes: any) {
- const MetaData = {
+ mpris.player.metadata = {
'mpris:trackid': mpris.player.objectPath(`track/${attributes.playParams.id.replace(/[.]+/g, "")}`),
'mpris:length': attributes.durationInMillis * 1000, // In microseconds
'mpris:artUrl': (attributes.artwork.url.replace('/{w}x{h}bb', '/512x512bb')).replace('/2000x2000bb', '/35x35bb'),
@@ -103,33 +112,12 @@ export default class mpris {
'xesam:album': `${attributes.albumName}`,
'xesam:artist': [`${attributes.artistName}`],
'xesam:genre': attributes.genreNames
- }
-
- if (mpris.player.metadata["mpris:trackid"] === MetaData["mpris:trackid"]) {
- return
- }
-
- mpris.player.metadata = MetaData;
+ };
}
- /**
- * Update M.P.R.I.S Player State
- * @private
- * @param attributes
- */
- private static updatePlayerState(attributes: any) {
- switch (attributes.status) {
- case true: // Playing
- mpris.player.playbackStatus = Player.PLAYBACK_STATUS_PLAYING;
- break;
- case false: // Paused
- mpris.player.playbackStatus = Player.PLAYBACK_STATUS_PAUSED;
- break;
- default:
- mpris.player.playbackStatus = Player.PLAYBACK_STATUS_STOPPED;
- break
- }
- }
+ /*******************************************************************************************
+ * Public Methods
+ * ****************************************************************************************/
/**
* Clear state
@@ -143,26 +131,12 @@ export default class mpris {
mpris.player.playbackStatus = Player.PLAYBACK_STATUS_STOPPED;
}
-
- /*******************************************************************************************
- * Public Methods
- * ****************************************************************************************/
-
- /**
- * Runs on plugin load (Currently run on application start)
- */
- constructor(utils: any) {
- mpris.utils = utils
-
- console.debug(`[Plugin][${mpris.name}] Loading Complete.`);
- }
-
/**
* Runs on app ready
*/
@mpris.linuxOnly
onReady(_: any): void {
- console.debug(`[Plugin][${mpris.name}] Ready.`);
+ console.debug(`[${mpris.name}:onReady] Ready.`);
}
/**
@@ -187,9 +161,8 @@ export default class mpris {
* @param attributes Music Attributes (attributes.status = current state)
*/
@mpris.linuxOnly
- onPlaybackStateDidChange(attributes: object): void {
- console.debug(`[Plugin][${mpris.name}] onPlaybackStateDidChange.`);
- mpris.updatePlayerState(attributes)
+ onPlaybackStateDidChange(attributes: any): void {
+ mpris.player.playbackStatus = attributes?.status ? Player.PLAYBACK_STATUS_PLAYING : Player.PLAYBACK_STATUS_PAUSED
}
/**
@@ -198,8 +171,7 @@ export default class mpris {
*/
@mpris.linuxOnly
onNowPlayingItemDidChange(attributes: object): void {
- console.debug(`[Plugin][${mpris.name}] onMetadataDidChange.`);
- mpris.updatePlayer(attributes);
+ mpris.updateMetaData(attributes);
}
}
diff --git a/src/main/providers/local/db/index.ts b/src/main/providers/local/db/index.ts
new file mode 100644
index 00000000..89063d20
--- /dev/null
+++ b/src/main/providers/local/db/index.ts
@@ -0,0 +1,12 @@
+import * as PouchDB from 'pouchdb-node';
+import {join} from 'path';
+import {app} from "electron";
+PouchDB.plugin(require('pouchdb-upsert'));
+export class ProviderDB {
+ public static db: any = null
+ static init() {
+ if (ProviderDB.db == null){
+ ProviderDB.db = new PouchDB(join(app.getPath('userData'), 'tracksdb'))
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/providers/local/index.ts b/src/main/providers/local/index.ts
new file mode 100644
index 00000000..157ac85e
--- /dev/null
+++ b/src/main/providers/local/index.ts
@@ -0,0 +1,257 @@
+import { ProviderDB } from "./db";
+import * as path from 'path';
+const { readdir } = require('fs').promises;
+import { utils } from '../../base/utils';
+import * as mm from 'music-metadata';
+import {Md5} from 'ts-md5/dist/md5';
+import e from "express";
+import { EventEmitter } from 'events';
+import { parseFile, recursiveFolderSearch } from 'cider_utils';
+
+export class LocalFiles {
+ static localSongs: any = [];
+ static localSongsArts: any = [];
+ public static DB = ProviderDB.db;
+ static eventEmitter = new EventEmitter();
+
+ static getDataType(item_id : String | any){
+ if ((item_id ?? ('')).startsWith('ciderlocalart'))
+ return 'artwork'
+ else if ((item_id ?? ('')).startsWith('ciderlocal'))
+ return 'track'
+ }
+
+ static async sendOldLibrary() {
+ ProviderDB.init()
+ let rows = (await ProviderDB.db.allDocs({include_docs: true,
+ attachments: true})).rows.map((item: any)=>{return item.doc})
+ let tracks = rows.filter((item: any) => {return this.getDataType(item._id) == "track"})
+ let arts = rows.filter((item: any) => {return this.getDataType(item._id) == "artwork"})
+ this.localSongs = tracks;
+ this.localSongsArts = arts;
+ return tracks;
+ }
+
+ static async scanLibrary() {
+ ProviderDB.init()
+ let folders = utils.getStoreValue("libraryPrefs.localPaths")
+ if (folders == null || folders.length == null || folders.length == 0) folders = []
+ console.log('folders', folders)
+ let parseFileQueue: any[] = []; let mmQueue: any[] = []
+ for (var folder of folders) {
+ // Recursively search and add
+ let result = await recursiveFolderSearch(folder)
+ parseFileQueue = parseFileQueue.concat(result.parseFile)
+ mmQueue = mmQueue.concat(result.musicMetadata)
+ }
+ if (parseFileQueue.length !== 0 || mmQueue.length !== 0) {console.log('Recursive Folder Search in Cider Utils worki')}
+ let metadatalist = []
+ let metadatalistart = []
+ let numid = 0;
+
+ // Music Metadata fallback
+ for (var audio of mmQueue) {
+ try {
+ const metadata = await mm.parseFile(audio);
+ let lochash = Md5.hashStr(audio) ?? numid;
+ if (metadata != null) {
+ let form = {
+ "id": "ciderlocal" + lochash,
+ "_id": "ciderlocal" + lochash,
+ "type": "podcast-episodes",
+ "href": audio,
+ "attributes": {
+ "artwork": {
+ "width": 3000,
+ "height": 3000,
+ "url": "/ciderlocalart/" + "ciderlocal" + lochash,
+ },
+ "topics": [],
+ "url": "",
+ "subscribable": true,
+ "mediaKind": "audio",
+ "genreNames": [
+ ""
+ ],
+ // "playParams": {
+ // "id": "ciderlocal" + numid,
+ // "kind": "podcast",
+ // "isLibrary": true,
+ // "reporting": false },
+ "trackNumber": metadata.common.track?.no ?? 0,
+ "discNumber": metadata.common.disk?.no ?? 0,
+ "name": metadata.common.title ?? audio.substring(audio.lastIndexOf('\\') + 1),
+ "albumName": metadata.common.album,
+ "artistName": metadata.common.artist,
+ "copyright": metadata.common.copyright ?? "",
+ "assetUrl": "file:///" + audio,
+ "contentAdvisory": "",
+ "releaseDateTime": `${metadata?.common?.year ?? '2022'}-05-13T00:23:00Z`,
+ "durationInMillis": Math.floor((metadata.format.duration ?? 0) * 1000),
+ "bitrate": Math.floor((metadata.format?.bitrate ?? 0) / 1000),
+ "offers": [
+ {
+ "kind": "get",
+ "type": "STDQ"
+ }
+ ],
+ "contentRating": "clean"
+ },
+ flavor: Math.floor((metadata.format?.bitrate ?? 0) / 1000),
+ localFilesMetadata: {
+ lossless: metadata.format?.lossless,
+ container: metadata.format?.container,
+ bitDepth: metadata.format?.bitsPerSample ?? 0,
+ sampleRate: metadata.format?.sampleRate ?? 0,
+ },
+ };
+ let art = {
+ id: "ciderlocal" + lochash,
+ _id: "ciderlocalart" + lochash,
+ url: metadata.common.picture != undefined ? metadata.common.picture[0].data.toString('base64') : "",
+ }
+ metadatalistart.push(art)
+ numid += 1;
+ ProviderDB.db.putIfNotExists(form)
+ ProviderDB.db.putIfNotExists(art)
+ metadatalist.push(form)
+
+ if (this.localSongs.length === 0 && numid % 10 === 0) { // send updated chunks only if there is no previous database
+ this.eventEmitter.emit('newtracks', metadatalist)}
+ }
+ } catch (e) {console.error("error:", e)}
+ }
+
+ // Cider-Utils supported formats.
+ for (var audio of parseFileQueue) {
+ try {
+ const metadata = await parseFile(audio);
+ let lochash = Md5.hashStr(audio) ?? numid;
+ if (metadata != null) {
+ let form = {
+ "id": "ciderlocal" + lochash,
+ "_id": "ciderlocal" + lochash,
+ "type": "podcast-episodes",
+ "href": audio,
+ "attributes": {
+ "artwork": {
+ "width": 3000,
+ "height": 3000,
+ "url": "/ciderlocalart/" + "ciderlocal" + lochash,
+ },
+ "topics": [],
+ "url": "",
+ "subscribable": true,
+ "mediaKind": "audio",
+ "genreNames": [
+ ""
+ ],
+ // "playParams": {
+ // "id": "ciderlocal" + numid,
+ // "kind": "podcast",
+ // "isLibrary": true,
+ // "reporting": false },
+ "trackNumber": metadata.track_number ?? 0,
+ "discNumber": metadata.disc_number ?? 0,
+ "name": metadata.title ?? audio.substring(audio.lastIndexOf('\\') + 1),
+ "albumName": metadata.album,
+ "artistName": metadata.artist,
+ "copyright": metadata.copyright ?? "",
+ "assetUrl": "file:///" + audio,
+ "contentAdvisory": "",
+ "releaseDateTime": `${metadata.year ?? '2022'}-05-13T00:23:00Z`,
+ "durationInMillis": metadata.duration_in_ms ?? 0,
+ "bitrate": metadata.bitrate ?? 0,
+ "offers": [
+ {
+ "kind": "get",
+ "type": "STDQ"
+ }
+ ],
+ "contentRating": "clean"
+ },
+ flavor: metadata.bitrate,
+ localFilesMetadata: {
+ lossless: metadata.lossless,
+ container: metadata.container,
+ bitDepth: metadata.bit_depth,
+ sampleRate: metadata.sample_rate ?? 0,
+ },
+ };
+ let art = {
+ id: "ciderlocal" + lochash,
+ _id: "ciderlocalart" + lochash,
+ url: metadata.artwork != undefined ? metadata.artwork : "",
+ }
+ metadatalistart.push(art)
+ numid += 1;
+ ProviderDB.db.putIfNotExists(form)
+ ProviderDB.db.putIfNotExists(art)
+ metadatalist.push(form)
+
+ if (this.localSongs.length === 0 && numid % 10 === 0) { // send updated chunks only if there is no previous database
+ this.eventEmitter.emit('newtracks', metadatalist)}
+ }
+ } catch (e) {console.error("error:", e)}
+ }
+ this.localSongs = metadatalist;
+ this.localSongsArts = metadatalistart;
+ return metadatalist;
+ }
+
+ static async cleanUpDB(){
+ let folders = utils.getStoreValue("libraryPrefs.localPaths")
+ let rows = (await ProviderDB.db.allDocs({include_docs: true,
+ attachments: true})).rows.map((item: any)=>{return item.doc})
+ let tracks = rows.filter((item: any) => {return this.getDataType(item._id) == "track" && !folders.some((i: String) => {return item["attributes"]["assetUrl"].startsWith("file:///" + i)})})
+ let hashs = tracks.map((i: any) => {return i._id})
+ for (let hash of hashs){
+ try{
+ ProviderDB.db.get(hash).then(function (doc: any) {
+ return ProviderDB.db.remove(doc);
+ });} catch(e){}
+ try{
+ ProviderDB.db.get(hash.replace('ciderlocal','ciderlocalart')).then(function (doc: any) {
+ return ProviderDB.db.remove(doc);
+ });} catch(e){}
+ }
+ }
+
+ static async getFiles(dir: any) {
+ const dirents = await readdir(dir, { withFileTypes: true });
+ const files = await Promise.all(dirents.map((dirent: any) => {
+ const res = path.resolve(dir, dirent.name);
+ return dirent.isDirectory() ? this.getFiles(res) : res;
+ }));
+ return Array.prototype.concat(...files);
+ }
+
+ static setupHandlers () {
+ const app = utils.getExpress()
+ console.log("Setting up handlers for local files")
+ app.get("/ciderlocal/:songs", (req: any, res: any) => {
+ const audio = atob(req.params.songs.replace(/_/g, '/').replace(/-/g, '+'));
+ //console.log('auss', audio)
+ let data = {
+ data:
+ LocalFiles.localSongs.filter((f: any) => audio.split(',').includes(f.id))
+ };
+ res.send(data);
+ });
+
+ app.get("/ciderlocalart/:songs", (req: any, res: any) => {
+ const audio = req.params.songs;
+ // metadata.common.picture[0].data.toString('base64')
+
+ res.setHeader('Cache-Control', 'public, max-age=31536000');
+ res.setHeader('Expires', new Date(Date.now() + 31536000000).toUTCString());
+ res.setHeader('Content-Type', 'image/jpeg');
+
+ let data =
+ LocalFiles.localSongsArts.filter((f: any) => f.id == audio);
+ res.status(200).send(Buffer.from(data[0]?.url, 'base64'));
+ });
+
+ return app
+ }
+}
\ No newline at end of file
diff --git a/src/preload/cider-preload.js b/src/preload/cider-preload.js
index 44ba7589..8afae876 100644
--- a/src/preload/cider-preload.js
+++ b/src/preload/cider-preload.js
@@ -11,9 +11,6 @@ const MusicKitInterop = {
if (MusicKitInterop.filterTrack(attributes, true, false)) {
global.ipcRenderer.send('playbackStateDidChange', attributes)
global.ipcRenderer.send('wsapi-updatePlaybackState', attributes);
- // if (typeof _plugins != "undefined") {
- // _plugins.execute("OnPlaybackStateChanged", {Attributes: MusicKitInterop.getAttributes()})
- // }
}
});
@@ -23,19 +20,18 @@ const MusicKitInterop = {
});
/** wsapi */
+ MusicKit.getInstance().addEventListener(MusicKit.Events.playbackTimeDidChange, () => {
+ ipcRenderer.send('mpris:playbackTimeDidChange', (MusicKit.getInstance()?.currentPlaybackTime * 1000 * 1000 ) ?? 0);
+ })
+
MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, async () => {
- console.debug('nowPlayingItemDidChange')
+ console.debug('[cider:preload] nowPlayingItemDidChange')
const attributes = MusicKitInterop.getAttributes()
- const trackFilter = MusicKitInterop.filterTrack(attributes, false, true)
- if (trackFilter) {
+ if (MusicKitInterop.filterTrack(attributes, false, true)) {
global.ipcRenderer.send('nowPlayingItemDidChange', attributes);
- }
-
- // LastFM's Custom Call
- await MusicKitInterop.modifyNamesOnLocale();
- if (trackFilter || !app.cfg.lastfm.filterLoop) {
- global.ipcRenderer.send('nowPlayingItemDidChangeLastFM', attributes);
+ } else if (attributes.name !== 'no-title-found' && attributes.playParams.id !== "no-id-found") {
+ global.ipcRenderer.send('lastfm:nowPlayingChange', attributes);
}
if (MusicKit.getInstance().nowPlayingItem) {
@@ -46,41 +42,27 @@ const MusicKitInterop = {
MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, () => {
global.ipcRenderer.send('authorizationStatusDidChange', MusicKit.getInstance().authorizationStatus)
- })
+ });
MusicKit.getInstance().addEventListener(MusicKit.Events.mediaPlaybackError, (e) => {
- console.warn(`[mediaPlaybackError] ${e}`);
- })
+ console.warn(`[cider:preload] mediaPlaybackError] ${e}`);
+ });
+
+ MusicKit.getInstance().addEventListener(MusicKit.Events.shuffleModeDidChange, () => {
+ global.ipcRenderer.send('shuffleModeDidChange', MusicKit.getInstance().shuffleMode)
+ });
+
+ MusicKit.getInstance().addEventListener(MusicKit.Events.repeatModeDidChange, () => {
+ global.ipcRenderer.send('repeatModeDidChange', MusicKit.getInstance().repeatMode)
+ });
},
sleep(ms) {
return new Promise((resolve) => {
- setTimeout(resolve, ms);
+ setTimeout(resolve, ms);
});
},
- async modifyNamesOnLocale() {
- if (app.mklang === '' || app.mklang == null) {
- return;
- }
- const mk = MusicKit.getInstance()
- const nowPlayingItem = mk.nowPlayingItem;
- if ((nowPlayingItem?._songId ?? nowPlayingItem?.songId) == null){
- return;
- }
- const id = nowPlayingItem?._songId ?? (nowPlayingItem?.songId ?? nowPlayingItem?.id)
- if (id != null && id !== -1) {
- try{
- const query = await mk.api.v3.music(`/v1${(((nowPlayingItem?._songId ?? nowPlayingItem?.songId) != null) && ((nowPlayingItem?._songId ?? nowPlayingItem?.songId) !== -1)) ? `/catalog/${mk.storefrontId}/` : `/me/library/`}songs/${id}?l=${app.mklang}`);
- if (query?.data?.data[0]){
- let attrs = query?.data?.data[0]?.attributes;
- if (attrs?.name) { nowPlayingItem.attributes.name = attrs?.name ?? ''}
- if (attrs?.albumName) { nowPlayingItem.attributes.albumName = attrs?.albumName ?? ''}
- if (attrs?.artistName) { nowPlayingItem.attributes.artistName = attrs?.artistName ?? ''}
-
- }} catch (e) { }
- } else {}
- },
getAttributes: function () {
const mk = MusicKit.getInstance()
const nowPlayingItem = mk.nowPlayingItem;
@@ -96,8 +78,8 @@ const MusicKitInterop = {
attributes.playParams = attributes?.playParams ?? {id: 'no-id-found'};
attributes.playParams.id = attributes?.playParams?.id ?? 'no-id-found';
attributes.url = {
- cider: `https://cider.sh/link?play/s/${nowPlayingItem?._songId ?? (nowPlayingItem?.songId ??'no-id-found')}`,
- appleMusic: attributes.websiteUrl ? attributes.websiteUrl : `https://music.apple.com/${mk.storefrontId}/song/${nowPlayingItem?._songId ?? (nowPlayingItem?.songId ??'no-id-found')}`
+ cider: `https://cider.sh/link?play/s/${nowPlayingItem?._songId ?? (nowPlayingItem?.songId ?? 'no-id-found')}`,
+ appleMusic: attributes.websiteUrl ? attributes.websiteUrl : `https://music.apple.com/${mk.storefrontId}/song/${nowPlayingItem?._songId ?? (nowPlayingItem?.songId ?? 'no-id-found')}`
}
if (attributes.playParams.id === 'no-id-found') {
attributes.playParams.id = nowPlayingItem?.id ?? 'no-id-found';
@@ -109,13 +91,14 @@ const MusicKitInterop = {
? remainingTimeExport * 1000
: 0;
attributes.durationInMillis = attributes?.durationInMillis ?? 0;
+ attributes.currentPlaybackTime = mk?.currentPlaybackTime ?? 0;
attributes.currentPlaybackProgress = currentPlaybackProgress ?? 0;
attributes.startTime = Date.now();
attributes.endTime = Math.round(
attributes?.playParams?.id === cache.playParams.id
? Date.now() + attributes?.remainingTime
: attributes?.startTime + attributes?.durationInMillis
- );
+ );
return attributes;
},
@@ -156,19 +139,19 @@ const MusicKitInterop = {
// } catch (e) { }
// if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null)
// MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);
- MusicKit.getInstance().skipToNextItem().then(r => console.debug(`[MusicKitInterop.next] Skipping to Next ${r}`));
+ MusicKit.getInstance().skipToNextItem().then(r => console.debug(`[cider:preload] [next] Skipping to Next ${r}`));
},
previous: () => {
// if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null)
// MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex);
- MusicKit.getInstance().skipToPreviousItem().then(r => console.debug(`[MusicKitInterop.previous] Skipping to Previous ${r}`));
+ MusicKit.getInstance().skipToPreviousItem().then(r => console.debug(`[cider:preload] [previous] Skipping to Previous ${r}`));
}
}
process.once('loaded', () => {
- console.debug("Setting ipcRenderer")
+ console.debug("[cider:preload] IPC Listeners Created!")
global.MusicKitInterop = MusicKitInterop;
});
diff --git a/src/renderer/assets/angles-left.svg b/src/renderer/assets/angles-left.svg
new file mode 100644
index 00000000..cc38eb23
--- /dev/null
+++ b/src/renderer/assets/angles-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/assets/angles-right.svg b/src/renderer/assets/angles-right.svg
new file mode 100644
index 00000000..7bc040ed
--- /dev/null
+++ b/src/renderer/assets/angles-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/assets/chevron-right.svg b/src/renderer/assets/chevron-right.svg
new file mode 100644
index 00000000..538cc611
--- /dev/null
+++ b/src/renderer/assets/chevron-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/assets/discord.svg b/src/renderer/assets/discord.svg
index f905d235..3b0fa57f 100644
--- a/src/renderer/assets/discord.svg
+++ b/src/renderer/assets/discord.svg
@@ -1,10 +1,41 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/renderer/assets/feather/hard-drive.svg b/src/renderer/assets/feather/hard-drive.svg
new file mode 100644
index 00000000..30305b6c
--- /dev/null
+++ b/src/renderer/assets/feather/hard-drive.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/renderer/assets/feather/headphones.svg b/src/renderer/assets/feather/headphones.svg
new file mode 100644
index 00000000..6c197a70
--- /dev/null
+++ b/src/renderer/assets/feather/headphones.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/assets/feather/pen-tool.svg b/src/renderer/assets/feather/pen-tool.svg
new file mode 100644
index 00000000..304803a1
--- /dev/null
+++ b/src/renderer/assets/feather/pen-tool.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/renderer/assets/feather/plugins.svg b/src/renderer/assets/feather/plugins.svg
new file mode 100644
index 00000000..1ad5759a
--- /dev/null
+++ b/src/renderer/assets/feather/plugins.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/assets/feather/style.svg b/src/renderer/assets/feather/style.svg
new file mode 100644
index 00000000..e6eae9e2
--- /dev/null
+++ b/src/renderer/assets/feather/style.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
diff --git a/src/renderer/assets/feather/zap.svg b/src/renderer/assets/feather/zap.svg
new file mode 100644
index 00000000..8e71dd07
--- /dev/null
+++ b/src/renderer/assets/feather/zap.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/renderer/assets/github.svg b/src/renderer/assets/github.svg
index 2180f759..e84df9e7 100644
--- a/src/renderer/assets/github.svg
+++ b/src/renderer/assets/github.svg
@@ -1,3 +1,41 @@
-
-
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/src/renderer/assets/ko_fi.svg b/src/renderer/assets/ko_fi.svg
index 8630f586..dcd86131 100644
--- a/src/renderer/assets/ko_fi.svg
+++ b/src/renderer/assets/ko_fi.svg
@@ -1 +1,4 @@
-
\ No newline at end of file
+
+
+
+
diff --git a/src/renderer/assets/open_collective.svg b/src/renderer/assets/open_collective.svg
index ea86a543..59e09857 100644
--- a/src/renderer/assets/open_collective.svg
+++ b/src/renderer/assets/open_collective.svg
@@ -1 +1,50 @@
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/assets/search-alt.svg b/src/renderer/assets/search-alt.svg
new file mode 100644
index 00000000..d21e9b73
--- /dev/null
+++ b/src/renderer/assets/search-alt.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/renderer/assets/settings.svg b/src/renderer/assets/settings.svg
new file mode 100644
index 00000000..41f574c0
--- /dev/null
+++ b/src/renderer/assets/settings.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/assets/spatialization.svg b/src/renderer/assets/spatialization.svg
new file mode 100644
index 00000000..97c0ef77
--- /dev/null
+++ b/src/renderer/assets/spatialization.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/renderer/assets/twitter.svg b/src/renderer/assets/twitter.svg
index 1bbb2f50..ce724ef1 100644
--- a/src/renderer/assets/twitter.svg
+++ b/src/renderer/assets/twitter.svg
@@ -1,49 +1,41 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/renderer/audio/audio.js b/src/renderer/audio/audio.js
index eaf0860d..d40a261c 100644
--- a/src/renderer/audio/audio.js
+++ b/src/renderer/audio/audio.js
@@ -11,6 +11,7 @@ const CiderAudio = {
intelliGainComp: null,
atmosphereRealizer2: null,
atmosphereRealizer1: null,
+ opportunisticCorrection: null
},
ccON: false,
mediaRecorder: null,
@@ -23,7 +24,7 @@ const CiderAudio = {
CiderAudio.connectContext(document.getElementById("apple-music-player"), 0);
cb();
- clearInterval(searchInt);
+ clearInterval(searchInt);
}
}, 1000);
},
@@ -40,6 +41,7 @@ const CiderAudio = {
intelliGainComp: null,
atmosphereRealizer2: null,
atmosphereRealizer1: null,
+ opportunisticCorrection: null,
}
} catch (e) { }
CiderAudio.source.connect(CiderAudio.context.destination);
@@ -47,7 +49,8 @@ const CiderAudio = {
},
connectContext: function (mediaElem) {
if (!CiderAudio.context) {
- CiderAudio.context = new window.AudioContext({ sampleRate: 96000 }); // Don't ever remove the sample rate arg. Ask Maikiwi.
+ CiderAudio.context = new window.AudioContext({ sampleRate: 96000, latencyHint: "playback"}); // Don't ever remove the sample rate arg. Ask Maikiwi.
+ app.lyricOffset = CiderAudio.context.baseLatency
}
if (!CiderAudio.source) {
CiderAudio.source = CiderAudio.context.createMediaElementSource(mediaElem);
@@ -80,6 +83,7 @@ const CiderAudio = {
}
} catch (e) {
+ console.debug("[Cider][MaikiwiSoundCheck] normalizer func err: " + e)
}
},
normalizerOff: function () {
@@ -225,6 +229,14 @@ const CiderAudio = {
"description": "8500",
}
],
+ opportunisticCorrectionProfiles: [
+ {
+ "id": "CHU",
+ "file": './cideraudio/impulses/MoondropCHU_Cider.wav',
+ "name": "Moondrop CHU Specific",
+ "description": "",
+ }
+ ],
spatial_ninf: function () {
CiderAudio.audioNodes.spatialNode = null;
CiderAudio.audioNodes.spatialNode = CiderAudio.context.createConvolver();
@@ -385,7 +397,7 @@ const CiderAudio = {
if (this._isBufferFull()) {
this._flush();
}
- let dataLength = audioRawData[0].length;
+ let dataLength = audioRawData[0]?.length ?? 0;
for (let idx=0; idx Spatial");} catch (e) { }
+ try { CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> Spatial");} catch (e) { }
break;
- case "n5":
+ case "n6":
try {
CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] atmosphereRealizer2_n5 -> atmosphereRealizer2");
+ console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer2");
+ } catch (e) { }
+ break;
+ case 'n5':
+ try {
+ CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer1);
+ console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> atmosphereRealizer1");
} catch (e) { }
break;
case 'n4':
try {
- CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] atmosphereRealizer2_n5 -> atmosphereRealizer1");
+ CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
+ console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> vibrantbassNode");
} catch (e) { }
break;
case 'n3':
try {
- CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] atmosphereRealizer2_n5 -> vibrantbassNode");
+ CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.audioBands[0]);
+ console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> audioBands");
} catch (e) { }
break;
case 'n2':
try {
- CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.audioBands[0]);
- console.debug("[Cider][Audio] atmosphereRealizer2_n5 -> audioBands");
+ CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> opportunisticCorrection");
} catch (e) { }
break;
case 'n1':
try {
CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] atmosphereRealizer2_n5 -> llpw");
+ console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> llpw");
} catch (e) { }
break;
case 'n0':
- try { CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.context.destination); console.debug("[Cider][Audio] atmosphereRealizer2_n5 -> destination");} catch (e) { }
+ try { CiderAudio.audioNodes.atmosphereRealizer2.connect(CiderAudio.context.destination); console.debug("[Cider][Audio] atmosphereRealizer2_n6 -> destination");} catch (e) { }
break;
}
@@ -547,7 +565,7 @@ const CiderAudio = {
}
},
- atmosphereRealizer1_n4: function (status, destination) {
+ atmosphereRealizer1_n5: function (status, destination) {
if (status === true) {
CiderAudio.audioNodes.atmosphereRealizer1 = CiderAudio.context.createConvolver();
CiderAudio.audioNodes.atmosphereRealizer1.normalize = false;
@@ -565,40 +583,46 @@ const CiderAudio = {
switch (destination) {
case "spatial":
- try { CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> Spatial");} catch (e) { }
+ try { CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> Spatial");} catch (e) { }
break;
- case "n5":
+ case "n6":
try {
CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> atmosphereRealizer2");
+ console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer2");
+ } catch (e) { }
+ break;
+ case 'n5':
+ try {
+ CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer1);
+ console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> atmosphereRealizer1");
} catch (e) { }
break;
case 'n4':
try {
- CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> atmosphereRealizer1");
+ CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
+ console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> vibrantbassNode");
} catch (e) { }
break;
case 'n3':
try {
- CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> vibrantbassNode");
+ CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.audioBands[0]);
+ console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> audioBands");
} catch (e) { }
break;
case 'n2':
try {
- CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.audioBands[0]);
- console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> audioBands");
+ CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> opportunisticCorrection");
} catch (e) { }
break;
case 'n1':
try {
CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> llpw");
+ console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> llpw");
} catch (e) { }
break;
case 'n0':
- try { CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.context.destination); console.debug("[Cider][Audio] atmosphereRealizer1_n4 -> destination");} catch (e) { }
+ try { CiderAudio.audioNodes.atmosphereRealizer1.connect(CiderAudio.context.destination); console.debug("[Cider][Audio] atmosphereRealizer1_n5 -> destination");} catch (e) { }
break;
}
@@ -606,6 +630,64 @@ const CiderAudio = {
}
},
+ opportunisticCorrection_n2: function (status, destination) {
+ if (status === true) {
+ CiderAudio.audioNodes.opportunisticCorrection = CiderAudio.context.createConvolver();
+ CiderAudio.audioNodes.opportunisticCorrection.normalize = false;
+ let opportunisticCorrectionProfile = CiderAudio.opportunisticCorrectionProfiles.find(function (profile) {
+ return profile.id === app.cfg.audio.maikiwiAudio.opportunisticCorrection_state;
+ });
+
+ if (opportunisticCorrectionProfile === undefined) {
+ opportunisticCorrectionProfile = CiderAudio.opportunisticCorrectionProfiles[0];
+ }
+ fetch(opportunisticCorrectionProfile.file).then(async (impulseData) => {
+ let bufferedImpulse = await impulseData.arrayBuffer();
+ CiderAudio.audioNodes.opportunisticCorrection.buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
+ });
+
+ switch (destination) {
+ case "spatial":
+ try { CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] opportunisticCorrection_n2 -> Spatial");} catch (e) { }
+ break;
+ case "n6":
+ try {
+ CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.atmosphereRealizer2);
+ console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer2");
+ } catch (e) { }
+ break;
+ case 'n5':
+ try {
+ CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.atmosphereRealizer1);
+ console.debug("[Cider][Audio] opportunisticCorrection_n2 -> atmosphereRealizer1");
+ } catch (e) { }
+ break;
+ case 'n4':
+ try { CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
+ console.debug("[Cider][Audio] opportunisticCorrection_n2 -> vibrantbassNode");} catch (e) { }
+ break;
+ case 'n3':
+ try { CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] opportunisticCorrection_n2 -> audioBands");} catch (e) { }
+ break;
+ case 'n2':
+ try {
+ CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection");
+ } catch (e) { }
+ break;
+ case 'n1':
+ try {
+ CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.audioNodes.opportunisticCorrection[0]);
+ console.debug("[Cider][Audio] opportunisticCorrection_n2 -> opportunisticCorrection");
+ } catch (e) { }
+ break;
+ case 'n0':
+ try { CiderAudio.audioNodes.opportunisticCorrection.connect(CiderAudio.context.destination); console.debug("[Cider][Audio] opportunisticCorrection_n2 -> destination");} catch (e) { }
+ break;
+ }
+
+ }
+ },
llpw_n1: function (status, destination) {
if (status === true) {
let c_LLPW_Q = [1.250, 0.131, 10, 2.5, 2.293, 0.110, 14.14, 1.552, 28.28, 7.071, 2.847, 5, 0.625, 7.071, 3.856, 3.856, 20, 28.28, 20, 14.14, 2.102, 6.698, 3.536, 10];
@@ -619,89 +701,48 @@ const CiderAudio = {
switch (app.cfg.audio.maikiwiAudio.ciderPPE_value) {
case "MAIKIWI":
- try {
- switch (localStorage.getItem("playingBitrate")) {
- case "64":
- CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver();
- CiderAudio.audioNodes.llpw[0].normalize = false;
- fetch('./cideraudio/impulses/CAP_64.wav').then(async (impulseData) => {
- let bufferedImpulse = await impulseData.arrayBuffer();
- CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
- });
- console.debug("[Cider][Audio] CAP Adaptive - 64kbps");
-
- break;
- case "256":
- CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.llpw[0].normalize = false;
- CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); CiderAudio.audioNodes.llpw[1].gain.value = 2.37; // Post Gain Compensation
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]);
- fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => {
- let bufferedImpulse = await impulseData.arrayBuffer();
- CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
- });
- console.debug("[Cider][Audio] CAP Adaptive - 256kbps_2_48k");
-
- break;
- default:
- CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.llpw[0].normalize = false;
- CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); CiderAudio.audioNodes.llpw[1].gain.value = 2.37; // Post Gain Compensation
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]);
- fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => {
- let bufferedImpulse = await impulseData.arrayBuffer();
- CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
- });
- console.debug("[Cider][Audio] CAP Adaptive - CONFIG FALLBACK - 256kbps_2_48k");
+ try {
+ switch (localStorage.getItem("playingBitrate")) {
+ case "64":
+ CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver();
+ CiderAudio.audioNodes.llpw[0].normalize = false;
+ fetch('./cideraudio/impulses/CAP_64.wav').then(async (impulseData) => {
+ let bufferedImpulse = await impulseData.arrayBuffer();
+ CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
+ });
+ console.debug("[Cider][Audio] CAP Adaptive - 64kbps");
+
+ break;
+ case "256":
+ CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.llpw[0].normalize = false;
+ CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); CiderAudio.audioNodes.llpw[1].gain.value = 2.37; // Post Gain Compensation
+ CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]);
+ fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => {
+ let bufferedImpulse = await impulseData.arrayBuffer();
+ CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
+ });
+ console.debug("[Cider][Audio] CAP Adaptive - 256kbps");
+
+ break;
+ default:
+ CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createGain(); CiderAudio.audioNodes.llpw[0].gain.value = 1
+ console.debug("[Cider][Audio] CAP Disabled (Passthrough) : Non-Lossy Bitrate.");
- break;
- }
-
- } catch (e) {
- CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.llpw[0].normalize = false;
- CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); CiderAudio.audioNodes.llpw[1].gain.value = 2.37;
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]);
- fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => {
- let bufferedImpulse = await impulseData.arrayBuffer();
- CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
- });
- console.debug("[Cider][Audio] CAP Adaptive - (Error Fallback) 256kbps");
- }
-
- switch (destination) {
- case "spatial":
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { }
- break;
- case "n5":
- try {
- CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
- } catch (e) { }
- break;
- case 'n4':
- try {
- CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
- } catch (e) { }
- break;
-
- case 'n3':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { }
- break;
- case 'n2':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { }
- break;
- case 'n1':
- try {
- CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] llpw_n1 -> llpw");
- } catch (e) { }
- break;
- case 'n0':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { }
- break;
+ break;
}
-
- break;
+
+ } catch (e) {
+ CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver(); CiderAudio.audioNodes.llpw[0].normalize = false;
+ CiderAudio.audioNodes.llpw[1] = CiderAudio.context.createGain(); CiderAudio.audioNodes.llpw[1].gain.value = 2.37;
+ CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[1]);
+ fetch('./cideraudio/impulses/CAP_256_FINAL_48k.wav').then(async (impulseData) => {
+ let bufferedImpulse = await impulseData.arrayBuffer();
+ CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
+ });
+ console.debug("[Cider][Audio] CAP Adaptive - (Error Fallback) 256kbps");
+ }
+
+ break;
case "MAIKIWI_LEGACY":
CiderAudio.audioNodes.llpw[0] = CiderAudio.context.createConvolver();
CiderAudio.audioNodes.llpw[0].normalize = false;
@@ -709,41 +750,6 @@ const CiderAudio = {
let bufferedImpulse = await impulseData.arrayBuffer();
CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
});
-
- switch (destination) {
- case "spatial":
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { }
- break;
- case "n5":
- try {
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
- } catch (e) { }
- break;
- case 'n4':
- try {
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
- } catch (e) { }
- break;
- case 'n1':
- try {
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] llpw_n1 -> llpw");
- } catch (e) { }
- break;
- case 'n3':
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { }
- break;
- case 'n2':
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { }
- break;
- case 'n0':
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { }
- break;
- }
-
console.debug("[Cider][Audio] CAP - Maikiwi Signature Mode");
break;
case "NATURAL":
@@ -754,41 +760,6 @@ const CiderAudio = {
CiderAudio.audioNodes.llpw[0].buffer = await CiderAudio.context.decodeAudioData(bufferedImpulse);
});
- switch (destination) {
- case "spatial":
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { }
- break;
- case "n5":
- try {
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
- } catch (e) { }
- break;
- case 'n4':
- try {
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
- } catch (e) { }
- break;
- case 'n1':
- try {
- CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] llpw_n1 -> llpw");
- } catch (e) { }
- break;
- case 'n3':
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { }
- break;
- case 'n2':
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { }
- break;
- case 'n0':
- try { CiderAudio.audioNodes.llpw[0].connect(CiderAudio.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { }
- break;
-
- }
-
console.debug("[Cider][Audio] CAP - Natural Mode");
break;
@@ -803,41 +774,7 @@ const CiderAudio = {
for (let i = 1; i < LLPW_FREQUENCIES.length; i ++) {
CiderAudio.audioNodes.llpw[i-1].connect(CiderAudio.audioNodes.llpw[i]);
}
-
- switch (destination) {
- case "spatial":
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { }
- break;
- case "n5":
- try {
- CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
- } catch (e) { }
- break;
- case 'n4':
- try {
- CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
- } catch (e) { }
- break;
- case 'n1':
- try {
- CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] llpw_n1 -> llpw");
- } catch (e) { }
- break;
- case 'n3':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { }
- break;
- case 'n2':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { }
- break;
- case 'n0':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { }
- break;
- }
- console.debug("[Cider][Audio] CAP - Legacy Mode");
+ console.debug("[Cider][Audio] CAP - Legacy Mode");
break;
@@ -851,46 +788,53 @@ const CiderAudio = {
});
app.cfg.audio.maikiwiAudio.ciderPPE_value = "MAIKIWI";
- switch (destination) {
- case "spatial":
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { }
- break;
- case "n5":
- try {
- CiderAudio.audioNodes.llpw[1].connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
- } catch (e) { }
- break;
- case 'n4':
- try {
- CiderAudio.audioNodes.llpw[1].connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
- } catch (e) { }
- break;
- case 'n1':
- try {
- CiderAudio.audioNodes.llpw[1].connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] llpw_n1 -> llpw");
- } catch (e) { }
- break;
- case 'n3':
- try { CiderAudio.audioNodes.llpw[1].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { }
- break;
- case 'n2':
- try { CiderAudio.audioNodes.llpw[1].connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { }
- break;
- case 'n0':
- try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { }
- break;
- }
console.debug("[Cider][Audio] CAP - Maikiwi Adaptive Mode (Defaulted from broki config)");
break;
}
+
+ switch (destination) {
+ case "spatial":
+ try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] llpw_n1 -> Spatial");} catch (e) { }
+ break;
+ case "n6":
+ try {
+ CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
+ console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
+ } catch (e) { }
+ break;
+ case 'n5':
+ try {
+ CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
+ console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
+ } catch (e) { }
+ break;
+ case 'n4':
+ try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
+ console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");} catch (e) { }
+ break;
+ case 'n3':
+ try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.audioBands[0]); console.debug("[Cider][Audio] llpw_n1 -> audioBands");} catch (e) { }
+ break;
+ case 'n2':
+ try {
+ CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] llpw_n1 -> opportunisticCorrection");
+ } catch (e) { }
+ break;
+ case 'n1':
+ try {
+ CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
+ console.debug("[Cider][Audio] llpw_n1 -> llpw");
+ } catch (e) { }
+ break;
+ case 'n0':
+ try { CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.context.destination); console.debug("[Cider][Audio] llpw_n1 -> destination");} catch (e) { }
+ break;
+ }
}
},
- vibrantbass_n3: function (status, destination) {
+ vibrantbass_n4: function (status, destination) {
if (status === true) {
let VIBRANTBASSBANDS = app.cfg.audio.maikiwiAudio.vibrantBass.frequencies;
let VIBRANTBASSGAIN = app.cfg.audio.maikiwiAudio.vibrantBass.gain;
@@ -911,41 +855,47 @@ const CiderAudio = {
switch (destination) {
case "spatial":
- try { CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] vibrantbass_n3 -> Spatial");} catch (e) { }
+ try { CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.spatialNode); console.debug("[Cider][Audio] vibrantbass_n4 -> Spatial");} catch (e) { }
break;
- case "n5":
+ case "n6":
try {
- CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.audioNodes.atmosphereRealizer2);
- console.debug("[Cider][Audio] vibrantbass_n3 -> atmosphereRealizer2");
+ CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
+ console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer2");
+ } catch (e) { }
+ break;
+ case 'n5':
+ try {
+ CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
+ console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer1");
} catch (e) { }
break;
case 'n4':
try {
- CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] vibrantbass_n3 -> atmosphereRealizer1");
+ CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
+ console.debug("[Cider][Audio] vibrantbass_n4 -> vibrantbassNode");
} catch (e) { }
break;
case 'n3':
try {
- CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] vibrantbass_n3 -> vibrantbassNode");
+ CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.audioBands[0]);
+ console.debug("[Cider][Audio] vibrantbass_n4 -> audioBands");
} catch (e) { }
break;
case 'n2':
try {
- CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.audioNodes.audioBands[0]);
- console.debug("[Cider][Audio] vibrantbass_n3 -> audioBands");
+ CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] vibrantbass_n4 -> opportunisticCorrection");
} catch (e) { }
break;
case 'n1':
try {
- CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.audioNodes.llpw[0]);
- console.debug("[Cider][Audio] vibrantbass_n3 -> llpw");
+ CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
+ console.debug("[Cider][Audio] vibrantbass_n4 -> llpw");
} catch (e) { }
break;
case 'n0':
- try { CiderAudio.audioNodes.vibrantbassNode[0].connect(CiderAudio.context.destination); console.debug("[Cider][Audio] vibrantbass_n3 -> destination");} catch (e) { }
+ try { CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.context.destination); console.debug("[Cider][Audio] vibrantbass_n4 -> destination");} catch (e) { }
break;
}
}
@@ -958,15 +908,17 @@ const CiderAudio = {
try { for (var i of CiderAudio.audioNodes.llpw) { i.disconnect(); } CiderAudio.audioNodes.llpw = null } catch (e) { }
try { for (var i of CiderAudio.audioNodes.vibrantbassNode) { i.disconnect(); } CiderAudio.audioNodes.vibrantbassNode = null } catch (e) { }
try { for (var i of CiderAudio.audioNodes.audioBands) { i.disconnect(); } CiderAudio.audioNodes.vibrantbassNode = null} catch (e) { };
+ try {CiderAudio.audioNodes.opportunisticCorrection.disconnect(); CiderAudio.audioNodes.opportunisticCorrection = null } catch (e) { };
console.debug("[Cider][Audio] Finished hierarchical unloading")
},
hierarchical_loading: async function () {
const configMap = new Map([
['spatial', app.cfg.audio.maikiwiAudio.spatial === true],
- ['n5', app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true],
- ['n4', app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true],
- ['n3', app.cfg.audio.equalizer.vibrantBass != 0],
- ['n2', Math.max(...app.cfg.audio.equalizer.gain) != 0],
+ ['n6', app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true],
+ ['n5', app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true],
+ ['n4', app.cfg.audio.equalizer.vibrantBass != 0],
+ ['n3', Math.max(...app.cfg.audio.equalizer.gain) != 0],
+ ['n2', app.cfg.audio.maikiwiAudio.opportunisticCorrection_state !== "OFF"],
['n1', app.cfg.audio.maikiwiAudio.ciderPPE === true]
]);
@@ -979,22 +931,26 @@ const CiderAudio = {
CiderAudio.spatial_ninf();
lastNode = 'spatial';
break;
+ case 'n6':
+ app.cfg.audio.normalization = true;
+ CiderAudio.atmosphereRealizer2_n6(true, lastNode);
+ lastNode = 'n6';
+ break;
case 'n5':
app.cfg.audio.normalization = true;
- CiderAudio.atmosphereRealizer2_n5(true, lastNode);
+ CiderAudio.atmosphereRealizer1_n5(true, lastNode);
lastNode = 'n5';
- break;
- case 'n4':
- app.cfg.audio.normalization = true;
- CiderAudio.atmosphereRealizer1_n4(true, lastNode);
- lastNode = 'n4';
break;
- case 'n3':
- CiderAudio.vibrantbass_n3(true, lastNode);
- lastNode = 'n3';
+ case 'n4':
+ CiderAudio.vibrantbass_n4(true, lastNode);
+ lastNode = 'n4';
break;
- case 'n2':
+ case 'n3':
CiderAudio.equalizer(true, lastNode);
+ lastNode = 'n3';
+ break;
+ case 'n2':
+ CiderAudio.opportunisticCorrection_n2(true, lastNode);
lastNode = 'n2';
break;
case 'n1':
@@ -1011,22 +967,28 @@ const CiderAudio = {
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialNode);
console.debug("[Cider][Audio] gainNode -> Spatial");
break;
- case 'n5':
+ case 'n6':
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer2);
console.debug("[Cider][Audio] gainNode -> atmosphereRealizer2");
break;
- case 'n4':
+ case 'n5':
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.atmosphereRealizer1);
console.debug("[Cider][Audio] gainNode -> atmosphereRealizer1");
break;
- case 'n3':
+ case 'n4':
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
console.debug("[Cider][Audio] gainNode -> vibrantbass");
break;
- case 'n2':
+ case 'n3':
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.audioBands[0]);
console.debug("[Cider][Audio] gainNode -> audioBands");
+ break;
+ case 'n2':
+ try {
+ CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] gainNode -> opportunisticCorrection");
+ } catch (e) { }
break;
case 'n1':
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]);
@@ -1045,7 +1007,7 @@ const CiderAudio = {
},
- equalizer: function (status, destination) { // n2_1
+ equalizer: function (status, destination) { // n3_1
if (status === true) {
let BANDS = app.cfg.audio.equalizer.frequencies;
let GAIN = app.cfg.audio.equalizer.gain;
@@ -1066,41 +1028,47 @@ const CiderAudio = {
switch (destination) {
case 'spatial':
- CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.audioNodes.spatialNode);
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.spatialNode);
console.debug("[Cider][Audio] Equalizer -> Spatial");
break;
- case "n5":
+ case "n6":
try {
- CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2);
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer2");
} catch (e) { }
break;
+ case 'n5':
+ try {
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
+ console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1");
+ } catch (e) { }
+ break;
case 'n4':
try {
- CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1);
- console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1");
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
+ console.debug("[Cider][Audio] Equalizer -> vibrantbassNode");
} catch (e) { }
break;
case 'n3':
try {
- CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
- console.debug("[Cider][Audio] Equalizer -> vibrantbassNode");
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.audioBands[0]);
+ console.debug("[Cider][Audio] Equalizer -> audioBands");
} catch (e) { }
break;
case 'n2':
try {
- CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.audioNodes.audioBands[0]);
- console.debug("[Cider][Audio] Equalizer -> audioBands");
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.opportunisticCorrection);
+ console.debug("[Cider][Audio] Equalizer -> opportunisticCorrection");
} catch (e) { }
break;
case 'n1':
try {
- CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.audioNodes.llpw[0]);
+ CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
console.debug("[Cider][Audio] Equalizer -> llpw");
} catch (e) { }
break;
case 'n0':
- try { CiderAudio.audioNodes.audioBands[BANDS.length - 1].connect(CiderAudio.context.destination); console.debug("[Cider][Audio] Equalizer -> destination");} catch (e) { }
+ try { CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.context.destination); console.debug("[Cider][Audio] Equalizer -> destination");} catch (e) { }
break;
}
diff --git a/src/renderer/audio/impulses/CAP_64.wav b/src/renderer/audio/impulses/CAP_64.wav
index ed2f442b..ac60adcc 100644
Binary files a/src/renderer/audio/impulses/CAP_64.wav and b/src/renderer/audio/impulses/CAP_64.wav differ
diff --git a/src/renderer/audio/impulses/CiderSpatial_LIVE.wav b/src/renderer/audio/impulses/CiderSpatial_LIVE.wav
deleted file mode 100644
index ca707d66..00000000
Binary files a/src/renderer/audio/impulses/CiderSpatial_LIVE.wav and /dev/null differ
diff --git a/src/renderer/audio/impulses/MoondropCHU_Cider.wav b/src/renderer/audio/impulses/MoondropCHU_Cider.wav
new file mode 100644
index 00000000..ab57c636
Binary files /dev/null and b/src/renderer/audio/impulses/MoondropCHU_Cider.wav differ
diff --git a/src/renderer/index.js b/src/renderer/index.js
index 6868dd26..b9a7de0e 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -1,5 +1,9 @@
var notyf = new Notyf();
+function clamp(num, min, max) {
+ return Math.min(Math.max(num, min), max);
+}
+
const MusicKitObjects = {
LibraryPlaylist: function () {
this.id = "";
@@ -52,75 +56,15 @@ Vue.component("animated-number", {
},
});
-Vue.component("sidebar-library-item", {
- template: "#sidebar-library-item",
- props: {
- name: {
- type: String,
- required: true,
- },
- page: {
- type: String,
- required: true,
- },
- svgIcon: {
- type: String,
- required: false,
- default: "",
- },
- cdClick: {
- type: Function,
- required: false,
- },
- },
- data: function () {
- return {
- app: app,
- svgIconData: "",
- };
- },
- async mounted() {
- if (this.svgIcon) {
- this.svgIconData = await this.app.getSvgIcon(this.svgIcon);
- }
- },
- methods: {},
-});
-
-function fallbackinitMusicKit() {
- const request = new XMLHttpRequest();
-
- function loadAlternateKey() {
- let parsedJson = JSON.parse(this.responseText);
- MusicKit.configure({
- developerToken: parsedJson.developerToken,
- app: {
- name: "Apple Music",
- build: "1978.4.1",
- version: "1.0",
- },
- sourceType: 24,
- suppressErrorDialog: true,
- });
- setTimeout(() => {
- app.init();
- if (app.cfg.visual.window_background_style == "mica" && !app.isDev) {
- app.spawnMica();
- }
- }, 1000);
- }
-
- request.addEventListener("load", loadAlternateKey);
- request.open(
- "GET",
- "https://raw.githubusercontent.com/lujjjh/LitoMusic/main/token.json"
- );
- request.send();
-}
-
function initMusicKit() {
-
+ if(!this.responseText) {
+ console.log("Using stored token")
+ this.responseText = JSON.stringify({
+ token: localStorage.getItem("lastToken")
+ })
+ }
let parsedJson = JSON.parse(this.responseText);
+ localStorage.setItem("lastToken", parsedJson.token);
MusicKit.configure({
developerToken: parsedJson.token,
app: {
@@ -150,8 +94,12 @@ function capiInit() {
request.timeout = 5000;
request.addEventListener("load", initMusicKit);
request.onreadystatechange = function (aEvt) {
- if (request.readyState == 4) {
- if (request.status != 200) fallbackinitMusicKit();
+ if (request.readyState == 4 && request.status != 200) {
+ if(localStorage.getItem("lastToken") != null) {
+ initMusicKit()
+ } else {
+ console.error(`Failed to load capi, cannot get token [${request.status}]`)
+ }
}
};
request.open("GET", "https://api.cider.sh/v1/");
diff --git a/src/renderer/less/ameframework.less b/src/renderer/less/ameframework.less
index de057c2f..085aa08e 100644
--- a/src/renderer/less/ameframework.less
+++ b/src/renderer/less/ameframework.less
@@ -239,6 +239,14 @@ input[type=range].md-slider::-webkit-slider-runnable-track {
width: auto;
}
+@media only screen and (min-width: 1133px) and (max-width: 1233px) {
+ .about-page {
+ .row .col-auto {
+ display: none !important;
+ }
+ }
+}
+
.col-1 {
flex: 0 0 auto;
width: 8.33333333%;
diff --git a/src/renderer/less/bootstrap.less b/src/renderer/less/bootstrap.less
index a392294e..8fe8cd27 100644
--- a/src/renderer/less/bootstrap.less
+++ b/src/renderer/less/bootstrap.less
@@ -2432,10 +2432,9 @@ fieldset:disabled .btn {
.nav-pills .nav-link {
background-color: transparent;
border: 0;
- border-radius: 50px;
+ border-radius: 6px;
color: #eee;
-webkit-user-drag: none;
- // transition: transform .35s var(--appleEase), background-color .35s var(--appleEase);
font-weight: 500;
margin: 0px 4px;
&:hover {
@@ -2447,7 +2446,7 @@ fieldset:disabled .btn {
.nav-pills .show > .nav-link {
color: #fff;
background-color: var(--selected);
- outline:2px solid var(--keyColor);
+ // outline:2px solid var(--keyColor);
}
.nav-fill > .nav-link,
@@ -2643,6 +2642,14 @@ fieldset:disabled .btn {
width: auto;
}
+@media only screen and (min-width: 1133px) and (max-width: 1233px) {
+ .about-page {
+ .row .col-auto {
+ display: none !important;
+ }
+ }
+}
+
.col-1 {
flex : 0 0 auto;
width: 8.33333333%;
diff --git a/src/renderer/less/directives.less b/src/renderer/less/directives.less
index 978c0707..9af65a5d 100644
--- a/src/renderer/less/directives.less
+++ b/src/renderer/less/directives.less
@@ -35,6 +35,11 @@
margin : 0px;
height : 100%;
position : relative;
+ white-space: nowrap;
+
+ ._svg-icon {
+ flex: 0 0 auto;
+ }
&:before {
--dist : 1px;
@@ -338,7 +343,9 @@
#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item {
min-width: 110px;
- font-size: 0em;
+ .sidebar-item-text {
+ display: none;
+ }
.sidebar-icon {
margin: 0px;
@@ -353,7 +360,9 @@
#app.twopanel .app-chrome:not(.chrome-bottom) .app-chrome--center .top-nav-group .app-sidebar-item {
min-width: 60px;
- font-size: 0em;
+ .sidebar-item-text {
+ display: none;
+ }
.sidebar-icon {
margin: 0px;
diff --git a/src/renderer/less/elements.less b/src/renderer/less/elements.less
index e43e8a6c..975ac5b6 100644
--- a/src/renderer/less/elements.less
+++ b/src/renderer/less/elements.less
@@ -162,6 +162,32 @@
align-self: center;
}
+.page-btn {
+ align-self: center;
+ height: 32px;
+}
+
+.page-btn img {
+ height: 100%;
+ align-self: center;
+}
+
+.md-ico-first {
+ content: url('./assets/angles-left.svg');
+}
+
+.md-ico-prev {
+ content: url('./assets/chevron-left.svg');
+}
+
+.md-ico-next {
+ content: url('./assets/chevron-right.svg');
+}
+
+.md-ico-last {
+ content: url('./assets/angles-right.svg');
+}
+
.reload-btn {
background: rgb(86 86 86 / 52%);
border-radius: 100%;
@@ -958,11 +984,11 @@
/* mediaitem-square */
.cd-mediaitem-square {
- --transitionDuration: .25s;
+ --transitionDuration: .5s;
--scaleRate: 1.25;
--scaleRateArtwork: 1;
- width: 200px;
- height: 200px;
+ width: calc(160px * var(--windowRelativeScale));
+ height: calc(200px * var(--windowRelativeScale));
display: inline-flex;
flex: 0 0 auto;
flex-direction: column;
@@ -970,14 +996,13 @@
justify-content: center;
align-items: center;
border-radius: 6px;
- transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
.artwork-container {
position: relative;
.artwork {
- height: 150px;
- width: 150px;
+ height: calc(140px * var(--windowRelativeScale));
+ width: calc(140px * var(--windowRelativeScale));
background: blue;
border-radius: var(--mediaItemRadius);
background: var(--artwork);
@@ -985,7 +1010,6 @@
flex: 0 0 auto;
margin: 6px;
cursor: pointer;
- transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
.mediaitem-artwork {
box-shadow: unset;
@@ -1059,31 +1083,31 @@
}
}
- &:not(.mediaitem-card):not(.mediaitem-brick):not(.mediaitem-video):not(.noscale) {
- @media (min-width: 1460px) {
- --scaleRate: 1.1;
- --scaleRateArtwork: 0.9;
- width: calc(200px * var(--scaleRate));
- height: calc(200px * var(--scaleRate));
+ // &:not(.mediaitem-card):not(.mediaitem-brick):not(.mediaitem-video):not(.noscale) {
+ // @media (min-width: 1460px) {
+ // --scaleRate: 1.1;
+ // --scaleRateArtwork: 0.9;
+ // width: calc(200px * var(--scaleRate));
+ // height: calc(200px * var(--scaleRate));
- .artwork-container > .artwork {
- width: calc(190px * var(--scaleRateArtwork));
- height: calc(190px * var(--scaleRateArtwork));
- }
- }
+ // .artwork-container > .artwork {
+ // width: calc(190px * var(--scaleRateArtwork));
+ // height: calc(190px * var(--scaleRateArtwork));
+ // }
+ // }
- @media (min-width: 1550px) {
- --scaleRate: 1.25;
- --scaleRateArtwork: 1;
- width: calc(200px * var(--scaleRate));
- height: calc(200px * var(--scaleRate));
+ // @media (min-width: 1550px) {
+ // --scaleRate: 1.25;
+ // --scaleRateArtwork: 1;
+ // width: calc(200px * var(--scaleRate));
+ // height: calc(200px * var(--scaleRate));
- .artwork-container > .artwork {
- width: calc(190px * var(--scaleRateArtwork));
- height: calc(190px * var(--scaleRateArtwork));
- }
- }
- }
+ // .artwork-container > .artwork {
+ // width: calc(190px * var(--scaleRateArtwork));
+ // height: calc(190px * var(--scaleRateArtwork));
+ // }
+ // }
+ // }
.info-rect {
@@ -1135,10 +1159,12 @@
&.mediaitem-video {
height: 200px;
width: 240px;
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
.artwork {
height: 120px;
width: 212px;
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
}
&:not(.noscale) {
@@ -1171,10 +1197,12 @@
&.mediaitem-brick {
height: 200px;
width: 240px;
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
.artwork {
height: 123px;
width: 220px;
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
}
&:not(.noscale) {
@@ -1205,12 +1233,14 @@
}
&.mediaitem-small {
- width: 140px;
- height: 180px;
+ width: calc(140px, var(--windowRelativeScale));
+ height: calc(180px, var(--windowRelativeScale));
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
.artwork {
- height: 128px;
- width: 128px;
+ height: calc(128px, var(--windowRelativeScale));
+ width: calc(128px, var(--windowRelativeScale));
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
}
}
@@ -1223,6 +1253,7 @@
position: relative;
border-radius: calc(var(--mediaItemRadius) * 2);
box-shadow: var(--mediaItemShadow-ShadowSubtle);
+ transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
.artwork {
width: 230px;
@@ -1315,7 +1346,7 @@
}
&:not(.noscale) {
- @media (min-width: 1460px) {
+ @media (min-width: 1200px) {
width: calc(230px * 1.1);
height: calc(298px * 1.1);
.artwork-container > .artwork {
@@ -1324,7 +1355,7 @@
}
}
- @media (min-width: 1550px) {
+ @media (min-width: 1400px) {
width: calc(230px * 1.25);
height: calc(298px * 1.25);
.artwork-container > .artwork {
@@ -1873,7 +1904,7 @@ input[type=checkbox][switch]:checked:active::before {
align-items: center;
color: white;
- > svg {
+ > ._svg-icon {
height: 16px;
width: 16px;
pointer-events: none;
@@ -2064,6 +2095,7 @@ input[type=checkbox][switch]:checked:active::before {
font-size: 12px;
cursor: pointer;
flex: 0 0 32px;
+ box-shadow: var(--ciderShadow-Generic);
&:hover {
background: var(--selected);
@@ -2168,107 +2200,116 @@ input[type=checkbox][switch]:checked:active::before {
}
// fancy pills
-.nav-pills {
- position: relative;
-
- .nav-link {
- transition: transform .3s var(--appleEase);
+.fancy-pills {
+ .nav-pills {
position: relative;
-
-
- &:after {
- --dist: 1px;
- content: "";
- position: absolute;
- top: var(--dist);
- bottom: var(--dist);
- left: var(--dist);
- right: var(--dist);
- // width : 100%;
- // height : 100%;
+
+ .nav-link {
+ transition: transform .3s var(--appleEase);
+ position: relative;
background-color: transparent;
+ border: 0;
border-radius: 50px;
- z-index: -1;
- opacity: 0;
- transition: background-color .5s var(--appleEase), opacity 0.25s var(--appleEase), border-radius .32s var(--appleEase);
- }
-
-
- &:hover {
- outline: none;
- transform: scale(1.1);
- // background: #eee;
- background: transparent;
- color: #333;
-
- &:after {
- opacity: 1;
- background-color: #eee;
- transition: background-color .25s var(--appleEase),
- border-radius .25s var(--appleEase),
- color .0s var(--appleEase),
- opacity 0.0s var(--appleEase);
- }
- }
-
- &.active {
- outline: none;
- transform: scale(1.1);
- // background: #eee;
- background: transparent;
- color: #333;
- font-weight: 600;
-
- &:after {
- opacity: 1;
- background-color: #eee;
- }
- }
-
-
- }
-
- &:hover {
- .nav-link.active {
- outline: none;
- transform: scale(1.0);
- background: transparent;
color: #eee;
- transform: scale(1.0);
-
+ -webkit-user-drag: none;
+ font-weight: 500;
+ margin: 0px 4px;
+
+
&:after {
- background: rgb(200 200 200 / 15%);
- opacity: 1;
- transition: color 0s;
- // border-radius: 5px;
- --dist: 4px;
+ --dist: 1px;
+ content: "";
+ position: absolute;
+ top: var(--dist);
+ bottom: var(--dist);
+ left: var(--dist);
+ right: var(--dist);
+ // width : 100%;
+ // height : 100%;
+ background-color: transparent;
+ border-radius: 50px;
+ z-index: -1;
+ opacity: 0;
+ transition: background-color .5s var(--appleEase), opacity 0.25s var(--appleEase), border-radius .32s var(--appleEase);
}
-
+
+
&:hover {
+ outline: none;
transform: scale(1.1);
- z-index: 1;
+ // background: #eee;
+ background: transparent;
color: #333;
-
+
&:after {
- background: #eee;
- border-radius: inherit;
- --dist: 1px;
+ opacity: 1;
+ background-color: #eee;
+ transition: background-color .25s var(--appleEase),
+ border-radius .25s var(--appleEase),
+ color .0s var(--appleEase),
+ opacity 0.0s var(--appleEase);
+ }
+ }
+
+ &.active {
+ outline: none;
+ transform: scale(1.1);
+ // background: #eee;
+ background: transparent;
+ color: #333;
+ font-weight: 600;
+
+ &:after {
+ opacity: 1;
+ background-color: #eee;
+ }
+ }
+
+
+ }
+
+ &:hover {
+ .nav-link.active {
+ outline: none;
+ transform: scale(1.0);
+ background: transparent;
+ color: #eee;
+ transform: scale(1.0);
+
+ &:after {
+ background: rgb(200 200 200 / 15%);
+ opacity: 1;
+ transition: color 0s;
+ // border-radius: 5px;
+ --dist: 4px;
+ }
+
+ &:hover {
+ transform: scale(1.1);
+ z-index: 1;
+ color: #333;
+
+ &:after {
+ background: #eee;
+ border-radius: inherit;
+ --dist: 1px;
+ }
}
}
}
- }
-
- &:after {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- background: rgb(200 200 200 / 10%);
- border-radius: 50px;
- z-index: 0;
- pointer-events: none;
+
+ &:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ background: rgb(200 200 200 / 10%);
+ border-radius: 50px;
+ z-index: 0;
+ pointer-events: none;
+ }
}
}
diff --git a/src/renderer/less/fullscreen.less b/src/renderer/less/fullscreen.less
new file mode 100644
index 00000000..82c3bdd9
--- /dev/null
+++ b/src/renderer/less/fullscreen.less
@@ -0,0 +1,604 @@
+.fullscreen-view-container {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: black;
+ z-index: 99;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ opacity: 1;
+}
+
+.fullscreen-view {
+ width: 100%;
+ height: 100%;
+ background: black;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ --chromeHeight1: 70px;
+
+ .app-content-container {
+ width:100%;
+ height:100%;
+ #app-content {
+ width:100%;
+ height:100%;
+
+ .fs-search {
+
+ .search-input--icon {
+ width: 4em;
+ background-size: 40%;
+ background-position: center;
+ }
+ input {
+ padding-left: 2em;
+ font-size: 2em;
+ border-radius: var(--mediaItemRadius)
+ }
+ }
+ }
+ }
+
+ .fs-header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--chromeHeight1);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 9999;
+
+ .top-nav-group {
+ background : #1e1e1e99;
+ border : 1px solid lighten(@baseColor, 8);
+ border-radius: 12px;
+ display : flex;
+ height : 55px;
+ width: 90%;
+ backdrop-filter: var(--glassFilter);
+
+
+ .app-sidebar-item {
+ background-color: #1e1e1e00;
+ border-radius : 10px !important;
+ border : 0px;
+ min-width : 120px;
+ padding : 6px;
+ justify-content : center;
+ align-items : center;
+ margin : 0px;
+ height : 100%;
+ position : relative;
+ font-size: 1.1em;
+ font-weight: 500;
+
+ &:before {
+ --dist : 1px;
+ content : '';
+ position : absolute;
+ top : var(--dist);
+ left : var(--dist);
+ right : var(--dist);
+ bottom : var(--dist);
+ background-color: #fff;
+ opacity : 0;
+ border-radius : 10px;
+ transform : scale(0.5);
+ transition : transform 0.2s ease-in-out, opacity 0.2s ease-in-out;
+ }
+
+ &:after {
+ display: none;
+ }
+
+ &:hover {
+ background-color: transparent;
+
+ &:before {
+ transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
+ opacity : .1;
+ transform : scale(1);
+ }
+ }
+
+ &.active {
+ background-color: transparent;
+
+ &:before {
+ opacity : .2;
+ transform: scale(1);
+ }
+ }
+
+ &.md-btn-primary {
+ box-shadow : 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8);
+ background-color: lighten(@baseColor, @colorMixRate * 5);
+ z-index : 1;
+ }
+ }
+ }
+ }
+
+ .fs-row {
+ flex-grow: 0.5;
+ }
+
+ .playback-button--small.active {
+ background-color: rgb(200 200 200 / 25%);
+ }
+
+ .playback-button--small {
+ opacity: 0.7;
+ }
+
+ .right-col {
+ height: 50vh;
+ }
+
+ .bg-artwork-container {
+ display: block !important;
+ }
+
+ @media only screen and (max-width: 1121px) {
+ .display--large {
+ display: flex !important;
+ }
+ }
+
+ .display--large {
+ display: flex;
+
+ .slider {
+ width: 100%;
+ z-index: 1;
+ }
+
+ .input-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%
+ }
+
+ .volume-button--small {
+ border-radius: 6px;
+ color: inherit;
+ background-size: 16px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: transparent;
+ height: 15px;
+ width: 30px;
+ border: 0px;
+ box-shadow: unset;
+ opacity: 0.70;
+ background-image: url("./assets/feather/volume-2.svg");
+ }
+
+ .volume-button--small:active {
+ transform: scale(0.9);
+ }
+
+ .volume-button--small.active {
+ background-image: url("./assets/feather/volume.svg");
+ }
+
+ input[type=range] {
+ -webkit-appearance: none;
+ height: 4px;
+ background: rgba(255, 255, 255, 0.4);
+ border-radius: 5px;
+ background-size: 70% 100%;
+ background-repeat: no-repeat;
+
+ &::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ height: 14px;
+ width: 14px;
+ border-radius: 50%;
+ background: rgb(50 50 50);
+ cursor: default;
+ box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
+ transition: all var(--appleTransition);
+ }
+
+ &::-webkit-slider-thumb:hover {
+ background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px);
+ transform: scale(1.2);
+ }
+
+ &::-webkit-slider-thumb:active {
+ background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px);
+ transform: scale(1);
+ }
+
+ &::-webkit-slider-runnable-track {
+ -webkit-appearance: none;
+ box-shadow: none;
+ border: none;
+ background: transparent;
+ }
+ }
+ }
+
+
+ .background {
+ position: absolute;
+ background-size: cover;
+ width: 100%;
+ height: 100%;
+
+ .bgArtworkMaterial {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+
+ .bg-artwork-container {
+ z-index: unset;
+ }
+
+ .bg-artwork-container .bg-artwork {
+ filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9);
+ }
+
+
+ }
+ }
+
+ .lyrics-col {
+
+ height: 62vh;
+ display: flex;
+ justify-content: center;
+ align-content: center;
+ width: 80%;
+
+ ::-webkit-scrollbar-thumb {
+ box-shadow: unset;
+ }
+
+ &:hover ::-webkit-scrollbar-thumb {
+ box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
+ }
+
+ .no-lyrics {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ }
+
+ .lyric-line {
+ font-size: 35px;
+ }
+
+ }
+
+ .queue-col {
+
+ width: 60vh;
+ height: 62vh;
+
+ .queue-title {
+ opacity: 0.6;
+ }
+
+ .queue-panel > * {
+ z-index: 3;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ box-shadow: unset;
+ }
+
+ &:hover ::-webkit-scrollbar-thumb {
+ box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
+ }
+ }
+
+ .tab-toggles {
+ display: flex;
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ width: 15vh;
+ height: 5vh;
+ justify-content: space-evenly;
+
+ .volume {
+ background-image: url("./assets/feathers/volume.svg");
+ padding: 0.5vh;
+ width: 2vh;
+ height: 2vh;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ }
+
+ .queue {
+ background-image: url("./assets/list.svg");
+ padding: 0.5vh;
+ width: 2.5vh;
+ height: 2.5vh;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ }
+
+ .lyrics {
+ background-image: url("./assets/quote-right.svg");
+ padding: 0.5vh;
+ width: 2.5vh;
+ height: 2.5vh;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ }
+
+ .active {
+ background-color: rgba(200, 200, 200, 0.7);
+ border-radius: 3px;
+ }
+ }
+
+ .artwork-col {
+ justify-content: center;
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+
+ .artwork {
+ width: 50vh;
+ height: 50vh;
+ }
+
+ .controls-parents {
+ width: 50vh;
+ }
+
+ .app-playback-controls {
+ .song-artist, .song-name {
+ font-weight: 600;
+ text-align: center;
+ font-size: 0.9em;
+ height: 1.2em;
+ line-height: 0.9em;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 360px;
+
+ .song-name-normal {
+ height: inherit;
+ }
+
+ &.song-artist-marquee {
+ > marquee {
+ //margin-bottom: -3px;
+ }
+ }
+ }
+
+ .song-artist {
+ font-size: 0.875em;
+ font-weight: 400;
+ }
+
+ .song-name {
+ width: unset !important;
+ margin-top: 0.15vh;
+ display: -webkit-box;
+ line-height: 1.2;
+ text-overflow: ellipsis;
+ text-align: center;
+ }
+ }
+
+ .app-playback-controls .playback-info {
+ margin-top: 0.5vh;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ position: relative;
+
+ input[type="range"] {
+ width: 100%;
+ }
+
+ > div {
+ width: 100%;
+ text-align: center;
+ }
+
+
+ }
+
+ .app-playback-controls .song-progress {
+ @bgColor: transparent;
+ //height: 16px;
+ position: absolute;
+ bottom: -1.5vh;
+ left: 0px;
+ background: @bgColor;
+
+ .song-duration p {
+ font-weight: 400;
+ font-size: 10px;
+ height: 1.2em;
+ line-height: 1.3em;
+ overflow: hidden;
+ margin: 0 0 0 0.25em;
+ }
+
+ &:hover {
+ > input[type=range] {
+ &::-webkit-slider-thumb {
+ opacity: 1;
+ transform: scale(1);
+ z-index: 1;
+ }
+ }
+ }
+
+ input[type=range] {
+ appearance: none;
+ width: 100%;
+ height: 4px;
+ background-color: rgb(200 200 200 / 10%);
+ border-radius: 2px;
+
+ &::-webkit-slider-thumb {
+ opacity: 0;
+ transform: scale(0.5);
+ -webkit-appearance: none;
+ appearance: none;
+ width: 12px;
+ height: 12px;
+ border-radius: 100%;
+ background: var(--songProgressColor);
+ cursor: default;
+ transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
+ }
+
+ &::-moz-range-thumb {
+ width: 8px;
+ height: 8px;
+ border-radius: 100%;
+ background: var(--songProgressColor);
+ cursor: default;
+ }
+ }
+ }
+
+ .control-buttons {
+ margin-top: 2vh;
+ display: inline-flex;
+ width: 100%;
+ justify-content: center;
+ }
+
+ }
+
+ .cd-mediaitem-square {
+ font-size: 17px;
+ font-weight: 500;
+ }
+
+ .cd-mediaitem-square .artwork-container .artwork {
+ box-shadow: var(--mediaItemShadow-Shadow);
+ }
+
+ .cd-mediaitem-list-item {
+ height: 80px;
+ }
+
+ .cd-mediaitem-list-item .title {
+ font-size: 1.2em;
+ font-weight: 450;
+ }
+
+ .cd-mediaitem-list-item .subtitle {
+ font-size: 1.1em;
+ font-weight: 380;
+ }
+
+ .cd-mediaitem-list-item .duration {
+ font-size: 1.2em;
+ }
+
+ .cd-mediaitem-list-item .artwork {
+ width: 50px;
+ height: 50px;
+ }
+
+ .cd-btn-seeall {
+ font-size: 1.2em;
+ }
+
+ h1 {
+ font-size: 3em;
+ }
+
+ h3 {
+ font-size: 1.5rem;
+ }
+
+ .home-page .well.artistfeed-well {
+ height: 512px;
+ }
+
+ .header-text {
+ font-size: 3em;
+ height: 3em;
+ padding-left: 0.2em;
+ }
+
+ .grouping-container .grouping-btn {
+ font-size: 1.3em;
+ color: var(--textColor);
+ background-color: var(--sidebarColor);
+ font-weight: 600;
+ padding: 32px;
+ //box-shadow: var(--ciderShadow-Generic);
+ }
+
+ .content-inner.playlist-page {
+ display: flex;
+ flex-direction: row;
+ }
+
+ .playlist-page .playlist-display {
+ width: 100%;
+ max-width: 500px;
+ flex:1;
+ text-align: center;
+
+ .playlistInfo {
+ >.row {
+ justify-content: center;
+ }
+ }
+
+ .playlist-controls {
+ div {
+ width:100%;
+ }
+ }
+ }
+ .playlist-page .mediaContainer {
+ width: 30vh;
+ height: 30vh;
+ aspect-ratio: 1;
+ }
+ .playlist-page .playlist-display .playlistInfo .playlist-info {
+ gap: 16px;
+ margin-top: 40px;
+ }
+
+ .playlist-page .playlist-display .playlistInfo .playlist-hero {
+ transform: unset;
+ }
+
+ .artist-page .artist-header {
+ min-height: 60vh;
+ }
+
+ .artist-page .artist-image {
+ width: 20vh;
+ height: 20vh;
+ aspect-ratio: 1;
+ }
+
+ .artist-page.animated .artist-header {
+ min-height: 80vh;
+ }
+
+ .playlist-page .playlist-body {
+ flex: 1;
+ }
+}
diff --git a/src/renderer/less/helpers.less b/src/renderer/less/helpers.less
index 1350f7f0..7cd68bd3 100644
--- a/src/renderer/less/helpers.less
+++ b/src/renderer/less/helpers.less
@@ -1,6 +1,6 @@
.notyf__toast {
-webkit-app-region: no-drag;
- cursor : pointer;
+ cursor: pointer;
}
.notyf-info {
@@ -9,142 +9,145 @@
.tooltip-inner {
background: #2f2f2f;
- opacity : 1;
- border : 1px solid rgb(0 0 0 / 35%);
+ opacity: 1;
+ border: 1px solid rgb(0 0 0 / 35%);
transition: all 0.3s ease-in-out;
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
}
.modal-fullscreen {
- display : flex;
+ display: flex;
justify-content: center;
- align-items : center;
- position : fixed;
- top : 0;
- left : 0;
- width : 100%;
- height : 100%;
- background : rgba(0, 0, 0, 0.3);
- z-index : 1000;
+ align-items: center;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.3);
+ z-index: 1000;
.modal-window {
- background : #333;
+ background: #333;
border-radius: 10px;
- box-shadow : var(--mediaItemShadow-Shadow);
- display : flex;
- flex-flow : column;
- max-height : 500px;
- max-width : 360px;
- background : #121212;
- width : 100%;
- position : relative;
+ box-shadow: var(--mediaItemShadow-Shadow);
+ display: flex;
+ flex-flow: column;
+ max-height: 500px;
+ max-width: 360px;
+ background: #121212;
+ width: 100%;
+ position: relative;
&:after {
- content : "";
- position : absolute;
- top : 0;
- left : 0;
- width : 100%;
- height : 100%;
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
pointer-events: none;
- box-shadow : var(--mediaItemShadow);
- z-index : 1;
- border-radius : inherit;
+ box-shadow: var(--mediaItemShadow);
+ z-index: 1;
+ border-radius: inherit;
}
.modal-header {
- width : 100%;
+ width: 100%;
padding: 6px;
}
.modal-content {
- width : 100%;
- height : 100%;
- overflow : hidden;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
overflow-y: overlay;
}
- .modal-footer {}
+ .modal-footer {
+ }
}
}
.spatialproperties-panel {
.modal-window {
- &:not(.airplay-modal){
- height : 700px;
- max-height: 700px;
- width : 800px;
- max-width : 800px;}
- overflow : hidden;
+ &:not(.airplay-modal) {
+ height: 700px;
+ max-height: 700px;
+ width: 800px;
+ max-width: 800px;
+ }
+
+ overflow: hidden;
.info-header {
padding-left: 12px;
}
.visual-container {
- display : flex;
+ display: flex;
justify-content: center;
- align-items : center;
- overflow : hidden;
+ align-items: center;
+ overflow: hidden;
}
.visual {
- position : relative;
- height : 250px;
- width : 300px;
- display : inline-flex;
- align-items : flex-end;
+ position: relative;
+ height: 250px;
+ width: 300px;
+ display: inline-flex;
+ align-items: flex-end;
justify-content: center;
- filter : drop-shadow(2px 12px 6px rgb(0 0 0 / 25%));
- margin : 0 auto;
+ filter: drop-shadow(2px 12px 6px rgb(0 0 0 / 25%));
+ margin: 0 auto;
.face {
- position : absolute;
- width : calc(12px * 6);
- height : calc(12px * 6);
+ position: absolute;
+ width: calc(12px * 6);
+ height: calc(12px * 6);
border-radius: 6px;
- transform : rotateX(60deg) rotateZ(-45deg);
- transition : transform 0.2s linear, width 0.2s linear, height 0.2s linear;
+ transform: rotateX(60deg) rotateZ(-45deg);
+ transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
}
.listener {
- position : absolute;
- width : 32px;
- height : 32px;
+ position: absolute;
+ width: 32px;
+ height: 32px;
border-radius: 6px;
- transform : rotateX(60deg) rotateZ(-45deg);
- transition : transform 0.2s linear, width 0.2s linear, height 0.2s linear;
- background : white;
- color : black;
- z-index : 2;
+ transform: rotateX(60deg) rotateZ(-45deg);
+ transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
+ background: white;
+ color: black;
+ z-index: 2;
}
.audiosource {
- position : absolute;
- width : 32px;
- height : 32px;
+ position: absolute;
+ width: 32px;
+ height: 32px;
border-radius: 6px;
- transform : rotateX(60deg) rotateZ(-45deg);
- transition : transform 0.2s linear, width 0.2s linear, height 0.2s linear;
- background : yellow;
- z-index : 2;
+ transform: rotateX(60deg) rotateZ(-45deg);
+ transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
+ background: yellow;
+ z-index: 2;
}
.face:nth-of-type(1) {
background: linear-gradient(45deg, #28223a, #1f2038);
- z-index : 1;
+ z-index: 1;
}
.face:nth-of-type(2) {
background: linear-gradient(45deg, #7d53ad, #5763ff);
- transform : rotateX(60deg) rotateZ(-45deg) translateZ(30px);
- opacity : 0.7;
- z-index : 3;
+ transform: rotateX(60deg) rotateZ(-45deg) translateZ(30px);
+ opacity: 0.7;
+ z-index: 3;
}
}
.modal-header {
- padding : 16px;
+ padding: 16px;
position: relative;
overflow: hidden;
@@ -162,14 +165,14 @@
.addtoplaylist-panel {
.modal-window {
- max-height : 600px;
- max-width : 400px;
- background : rgb(18 18 18 / 90%);
- overflow : hidden;
+ max-height: 600px;
+ max-width: 400px;
+ background: rgb(18 18 18 / 90%);
+ overflow: hidden;
backdrop-filter: blur(16px) saturate(180%);
.modal-header {
- padding : 16px;
+ padding: 16px;
position: relative;
.modal-title {
@@ -182,34 +185,34 @@
}
.modal-search {
- width : 100%;
- padding : 0px 16px;
+ width: 100%;
+ padding: 0px 16px;
position: relative;
}
.playlist-item {
- appearance : none;
- border : 0px;
- text-align : left;
- width : 100%;
- margin : 0;
- display : flex;
- background : rgba(32, 32, 32, 0.46);
- color : #eee;
+ appearance: none;
+ border: 0px;
+ text-align: left;
+ width: 100%;
+ margin: 0;
+ display: flex;
+ background: rgba(32, 32, 32, 0.46);
+ color: #eee;
font-family: inherit;
- font-size : 0.98em;
- padding : 6px 12px;
+ font-size: 0.98em;
+ padding: 6px 12px;
align-items: center;
- flex-flow : row;
+ flex-flow: row;
.icon {
- pointer-events : none;
- width : 32px;
- height : 32px;
- display : flex;
+ pointer-events: none;
+ width: 32px;
+ height: 32px;
+ display: flex;
justify-content: center;
- align-items : center;
- margin-right : 6px;
+ align-items: center;
+ margin-right: 6px;
}
.name {
@@ -236,35 +239,35 @@
}
.menu-panel {
- width : 100%;
- height : 100%;
- position : fixed;
- top : 0;
- left : 0;
- z-index : 100001;
- display : flex;
- justify-content : center;
- align-items : center;
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 100001;
+ display: flex;
+ justify-content: center;
+ align-items: center;
-webkit-app-region: no-drag;
.menu-header-body {
- padding : 6px;
- display : flex;
+ padding: 6px;
+ display: flex;
background: rgb(200 200 200 / 10%);
.menu-option-header {
- width : 40px;
- height : 40px;
- display : flex;
+ width: 40px;
+ height: 40px;
+ display: flex;
justify-content: center;
- align-items : center;
- border-radius : var(--mediaItemRadius);
- appearance : none;
- border : 0;
- background : transparent;
+ align-items: center;
+ border-radius: var(--mediaItemRadius);
+ appearance: none;
+ border: 0;
+ background: transparent;
&.active {
- .sidebar-icon>.svg-icon {
+ .sidebar-icon > .svg-icon {
--color: var(--keyColor);
}
}
@@ -280,62 +283,62 @@
}
.menu-panel-body {
- display : flex;
- flex-flow : column;
- background : rgb(30 30 30 / 45%);
+ display: flex;
+ flex-flow: column;
+ background: rgb(30 30 30 / 45%);
backdrop-filter: blur(32px) saturate(180%);
- position : relative;
- min-width : 200px;
- box-shadow : var(--ciderShadow-Generic);
- border-radius : var(--panelRadius);
- overflow : hidden;
- font-size : 13px;
+ position: relative;
+ min-width: 200px;
+ box-shadow: var(--ciderShadow-Generic);
+ border-radius: var(--panelRadius);
+ overflow: hidden;
+ font-size: 13px;
.menu-option {
text-align: left;
- display : flex;
+ display: flex;
appearance: none;
- border : 0px;
- font : inherit;
+ border: 0px;
+ font: inherit;
background: transparent;
- color : inherit;
- margin : 0 auto;
- position : relative;
- width : 100%;
- padding : 9px 14px;
+ color: inherit;
+ margin: 0 auto;
+ position: relative;
+ width: 100%;
+ padding: 9px 14px;
align-items: center;
&::before {
- background : var(--hover);
+ background: var(--hover);
border-radius: 6px;
- content : "";
- --sizeY : 3px;
- --sizeX : 4px;
- top : var(--sizeY);
- left : var(--sizeX);
- bottom : var(--sizeY);
- right : var(--sizeX);
- position : absolute;
- opacity : 0;
- transform : scale(0.98);
- z-index : -1;
- transition : transform .25s ease-out, opacity .25s ease-out;
+ content: "";
+ --sizeY: 3px;
+ --sizeX: 4px;
+ top: var(--sizeY);
+ left: var(--sizeX);
+ bottom: var(--sizeY);
+ right: var(--sizeX);
+ position: absolute;
+ opacity: 0;
+ transform: scale(0.98);
+ z-index: -1;
+ transition: transform .25s ease-out, opacity .25s ease-out;
}
&:hover {
&::before {
transition: transform 0s ease-in, opacity 0s ease-in;
- opacity : 1;
- transform : scale(1);
+ opacity: 1;
+ transform: scale(1);
}
}
&:active {
&::before {
transition: transform .1s ease-in-out, opacity .1s ease-in-out;
- opacity : 1;
- transform : scale(0.98);
+ opacity: 1;
+ transform: scale(0.98);
background: var(--selected-click);
}
}
@@ -375,25 +378,25 @@
}
.menu-body {
- overflow : overlay;
- height : 100%;
- display : flex;
+ overflow: overlay;
+ height: 100%;
+ display: flex;
flex-flow: column;
- gap : 0px;
- padding : 0px;
- position : relative;
+ gap: 0px;
+ padding: 0px;
+ position: relative;
}
.menu-footer {
- width : 100%;
+ width: 100%;
padding: 12px;
}
}
.queue-panel {
- height : 100%;
- width : 100%;
- display : flex;
+ height: 100%;
+ width: 100%;
+ display: flex;
flex-flow: column;
.queue-header-text {
@@ -402,52 +405,52 @@
.queue-body {
overflow: overlay;
- height : 100%;
+ height: 100%;
}
.queue-footer {
- width : 100%;
+ width: 100%;
padding: 12px;
}
.autoplay {
- background : rgb(200 200 200 / 15%);
- display : flex;
+ background: rgb(200 200 200 / 15%);
+ display: flex;
justify-content: center;
- appearance : none;
- border : 0;
- border-radius : 6px;
- height : 32px;
- width : 32px;
+ appearance: none;
+ border: 0;
+ border-radius: 6px;
+ height: 32px;
+ width: 32px;
}
.infinity {
content: url("./assets/infinity.svg");
- margin : auto;
+ margin: auto;
}
}
.moreinfo-modal {
.modal-window {
- height : 70%;
- max-height : 100%;
- width : 45%;
- max-width : 100%;
- overflow : hidden;
+ height: 70%;
+ max-height: 100%;
+ width: 45%;
+ max-width: 100%;
+ overflow: hidden;
line-height: 1.25;
}
.modal-content {
- padding : 1em;
+ padding: 1em;
font-size: 0.8rem;
br {
- display : block;
+ display: block;
/* makes it have a width */
- content : "";
+ content: "";
/* clears default height */
- margin : 2em;
+ margin: 2em;
margin-bottom: -0.6rem;
}
}
@@ -457,7 +460,7 @@
.modal-title {
text-align: unset !important;
- width : 100%;
+ width: 100%;
&:not(.modal-subtitle) {
font-size: 25px;
@@ -479,8 +482,9 @@
top: 0;
left: 0;
z-index: -1;
- filter:blur(32px) brightness(50%) saturate(280%);
+ filter: blur(32px) brightness(50%) saturate(280%);
}
+
.popover-artwork {
width: 200px;
height: 200px;
@@ -491,7 +495,8 @@
.song-name {
font-weight: 600;
}
- .song-artist,.song-album {
+
+ .song-artist, .song-album {
opacity: 0.75;
cursor: pointer;
@@ -500,4 +505,20 @@
}
}
}
+}
+
+._svg-icon {
+ --icon: url("./assets/chevron-left.svg");
+ --size: 1em;
+ width: var(--size);
+ height: var(--size);
+ -webkit-mask-image: var(--icon);
+ -webkit-mask-position: center;
+ -webkit-mask-size: contain;
+ background: rgb(255 255 255 / 76%);
+ -webkit-mask-repeat: no-repeat;
+
+ &.md {
+ --size: 1.2em;
+ }
}
\ No newline at end of file
diff --git a/src/renderer/less/macos.less b/src/renderer/less/macos.less
index 80ae65c8..4819a263 100644
--- a/src/renderer/less/macos.less
+++ b/src/renderer/less/macos.less
@@ -1,15 +1,17 @@
body[platform="darwin"] {
html {
- background: transparent!important;
+ background: transparent !important;
}
&.notransparency::before {
display: none;
}
+
#app {
&.simplebg {
background: transparent;
}
+
&::before {
display: none;
}
@@ -25,6 +27,7 @@ body[platform="darwin"] {
.app-chrome .app-chrome-item.search {
margin-right: 12px;
}
+
.app-chrome .app-mainmenu {
width: 46px;
}
@@ -33,6 +36,21 @@ body[platform="darwin"] {
background-color: var(--macOSChromeColor);
}
}
+
+ &[window-state="normal"] {
+ &::after {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ box-shadow: inset 0px 0px .5px 1px rgb(200 200 200 / 40%);
+ border-radius: 10px;
+ content: " ";
+ z-index: 999999;
+ pointer-events: none;
+ }
+ }
}
#app-main {
@@ -43,7 +61,19 @@ body[platform="darwin"] {
}
#app-content {
- background-color: var(--baseColor);
+ background-color: #1e1e1e6b;
}
}
+
+ .settings-window.maxed {
+ .tabs>.col-auto {
+ transition: padding-top .3s linear;
+ padding-top: var(--chromeHeight1);
+ }
+ }
+
+ #apple-music-video-player-controls #player-exit {
+ margin-top: 18px;
+ left: 70px;
+ }
}
\ No newline at end of file
diff --git a/src/renderer/less/miniplayer.less b/src/renderer/less/miniplayer.less
new file mode 100644
index 00000000..795c2158
--- /dev/null
+++ b/src/renderer/less/miniplayer.less
@@ -0,0 +1,410 @@
+.mini-view {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ .fs-row {
+ flex-grow: 1;
+ }
+
+ .playback-button--small.active {
+ background-color: rgb(200 200 200 / 25%);
+ }
+
+ .player-exit {
+ z-index: 3;
+ position: absolute;
+ top: 5px;
+ right: 5px;
+ -webkit-app-region: no-drag;
+ }
+
+ .player-pin {
+ z-index: 3;
+ position: absolute;
+ min-width: 20px;
+ min-height: 20px;
+ top: 5px;
+ right: 30px;
+ -webkit-app-region: no-drag;
+ }
+
+ #mini-pin {
+ display: none;
+ }
+
+ .player-pin:hover #mini-pin {
+ display: block;
+ }
+
+ .playback-button--small {
+ opacity: 0.7;
+ }
+
+ .right-col {
+ height: 50vh;
+ }
+
+ @media only screen and (max-width: 1121px) {
+ .display--large {
+ display: flex !important;
+ }
+ }
+
+ .display--large {
+ display: flex;
+
+ .slider {
+ width: 100%;
+ z-index: 1;
+ }
+
+ .input-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%
+ }
+
+ .volume-button--small {
+ border-radius: 6px;
+ color: inherit;
+ background-size: 16px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: transparent;
+ height: 15px;
+ width: 30px;
+ border: 0px;
+ box-shadow: unset;
+ opacity: 0.70;
+ background-image: url("./assets/feather/volume-2.svg");
+ }
+
+ .volume-button--small:active {
+ transform: scale(0.9);
+ }
+
+ .volume-button--small.active {
+ background-image: url("./assets/feather/volume.svg");
+ }
+
+ input[type=range] {
+ -webkit-appearance: none;
+ height: 4px;
+ background: rgba(255, 255, 255, 0.4);
+ border-radius: 5px;
+ background-size: 70% 100%;
+ background-repeat: no-repeat;
+
+ &::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ height: 14px;
+ width: 14px;
+ border-radius: 50%;
+ background: rgb(50 50 50);
+ cursor: default;
+ box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
+ transition: all var(--appleTransition);
+ }
+
+ &::-webkit-slider-thumb:hover {
+ background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px);
+ transform: scale(1.2);
+ }
+
+ &::-webkit-slider-thumb:active {
+ background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px);
+ transform: scale(1);
+ }
+
+ &::-webkit-slider-runnable-track {
+ -webkit-appearance: none;
+ box-shadow: none;
+ border: none;
+ background: transparent;
+ }
+ }
+ }
+
+
+ .background {
+ position: absolute;
+ background-size: cover;
+ width: 100%;
+ height: 100%;
+ -webkit-user-select: none;
+ -webkit-app-region: drag;
+
+ .bgArtworkMaterial {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+
+ .bg-artwork-container {
+ z-index: unset;
+ }
+
+ .bg-artwork-container .bg-artwork {
+ filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9);
+ }
+
+ .no-animation {
+ animation: unset;
+ }
+ }
+ }
+
+
+ .lyrics-col {
+
+ height: 62vh;
+ display: flex;
+ justify-content: center;
+ align-content: center;
+ width: 80%;
+
+ ::-webkit-scrollbar-thumb {
+ box-shadow: unset;
+ }
+
+ &:hover ::-webkit-scrollbar-thumb {
+ box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
+ }
+
+ .no-lyrics {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ }
+
+ .lyric-line {
+ font-size: 35px;
+ }
+
+ }
+
+ .queue-col {
+
+ width: 60vh;
+ height: 50vh;
+
+ .queue-title {
+ opacity: 0.6;
+ }
+
+ .queue-panel > * {
+ z-index: 3;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ box-shadow: unset;
+ }
+
+ &:hover ::-webkit-scrollbar-thumb {
+ box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
+ }
+ }
+
+ .tab-toggles {
+ display: flex;
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ width: 15vh;
+ height: 5vh;
+ justify-content: space-evenly;
+
+ .volume {
+ background-image: url("./assets/feathers/volume.svg");
+ padding: 0.5vh;
+ width: 2vh;
+ height: 2vh;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ }
+
+ .queue {
+ background-image: url("./assets/list.svg");
+ padding: 0.5vh;
+ width: 2.5vh;
+ height: 2.5vh;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ }
+
+ .lyrics {
+ background-image: url("./assets/quote-right.svg");
+ padding: 0.5vh;
+ width: 2.5vh;
+ height: 2.5vh;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ }
+
+ .active {
+ background-color: rgba(200, 200, 200, 0.7);
+ border-radius: 3px;
+ }
+ }
+
+ .artwork-col {
+ justify-content: center;
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+
+ .artwork {
+ width: 100%;
+ height: 100%;
+
+ .mediaitem-artwork {
+ border-radius: unset;
+ }
+ }
+
+ .controls-parents {
+ width: 100%;
+ position: absolute;
+ background: #0000009e;
+ backdrop-filter: blur(10px);
+ bottom: 0px;
+ z-index: 3;
+ opacity: 0;
+ padding: 3%;
+
+ &:hover {
+ opacity: 1;
+ }
+ }
+
+
+ .app-playback-controls {
+ -webkit-app-region: no-drag;
+
+ .song-artist, .song-name {
+ font-weight: 600;
+ text-align: center;
+ font-size: 0.9em;
+ height: 1.2em;
+ line-height: 0.9em;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 360px;
+
+ .song-name-normal {
+ height: inherit;
+ }
+
+ &.song-artist-marquee {
+ > marquee {
+ //margin-bottom: -3px;
+ }
+ }
+ }
+
+ .song-artist {
+ font-size: 0.875em;
+ font-weight: 400;
+ }
+
+ .song-name {
+ width: unset !important;
+ margin-top: 0.15vh;
+ display: -webkit-box;
+ line-height: 1.2;
+ text-overflow: ellipsis;
+ text-align: center;
+ }
+ }
+
+ .app-playback-controls .playback-info {
+ margin-top: 0.5vh;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ position: relative;
+
+ input[type="range"] {
+ width: 100%;
+ }
+
+ > div {
+ width: 100%;
+ text-align: center;
+ }
+
+
+ }
+
+ .app-playback-controls .song-progress {
+ @bgColor: transparent;
+ //height: 16px;
+ position: absolute;
+ bottom: -3.5vh;
+ left: 0px;
+ background: @bgColor;
+
+ .song-duration p {
+ font-weight: 400;
+ font-size: 10px;
+ height: 1.2em;
+ line-height: 1.3em;
+ overflow: hidden;
+ margin: 0 0 0 0.25em;
+ }
+
+ &:hover {
+ > input[type=range] {
+ &::-webkit-slider-thumb {
+ opacity: 1;
+ transform: scale(1);
+ z-index: 1;
+ }
+ }
+ }
+
+ input[type=range] {
+ appearance: none;
+ width: 100%;
+ height: 4px;
+ background-color: rgb(200 200 200 / 10%);
+ border-radius: 2px;
+
+ &::-webkit-slider-thumb {
+ opacity: 0;
+ transform: scale(0.5);
+ -webkit-appearance: none;
+ appearance: none;
+ width: 12px;
+ height: 12px;
+ border-radius: 100%;
+ background: var(--songProgressColor);
+ cursor: default;
+ transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
+ }
+
+ &::-moz-range-thumb {
+ width: 8px;
+ height: 8px;
+ border-radius: 100%;
+ background: var(--songProgressColor);
+ cursor: default;
+ }
+ }
+ }
+
+ .control-buttons {
+ margin-top: 3.5vh;
+ display: inline-flex;
+ width: 100%;
+ justify-content: center;
+ }
+
+ }
+}
diff --git a/src/renderer/less/pages.less b/src/renderer/less/pages.less
index 859565b7..ebe641f8 100644
--- a/src/renderer/less/pages.less
+++ b/src/renderer/less/pages.less
@@ -1,48 +1,47 @@
// Helpers
.content-inner {
- position : absolute;
- top : var(--navigationBarHeight);
- left : 0;
- padding : 32px;
- width : 100%;
+ position: absolute;
+ top: var(--navigationBarHeight);
+ left: 0;
+ padding: 32px;
+ width: 100%;
transition: zoom 1s;
- zoom : 1;
+ zoom: 1;
}
.content-inner.centered {
- height : 100%;
- display : flex;
- flex-flow : column;
+ height: 100%;
+ display: flex;
+ flex-flow: column;
justify-content: center;
- align-items : center;
+ align-items: center;
}
// End Helpers
// GitHub Themes
.github-themes-page {
- display : flex;
+ display: flex;
flex-direction: column;
- padding : 0px;
- height : calc(100% - var(--navigationBarHeight));
+ height: 100%;
.github-avatar {
- height : 42px;
- width : 42px;
- margin : 6px;
+ height: 42px;
+ width: 42px;
+ margin: 6px;
border-radius: 32px;
}
.repo-name {
- margin : 0px;
- font-weight : 500;
- overflow : hidden;
+ margin: 0px;
+ font-weight: 500;
+ overflow: hidden;
text-overflow: ellipsis;
- white-space : break-spaces;
+ white-space: break-spaces;
}
.repo-url {
- color : var(--textColor);
+ color: var(--textColor);
font-size: 0.8em;
}
@@ -51,12 +50,14 @@
}
.repos-list {
- height : 100%;
- overflow-y: overlay;
- width : 320px;
- font-size : 14px;
+ height: 100%;
+ width: 320px;
+ font-size: 14px;
+ overflow: overlay;
+ padding-bottom: 16px;
+ flex: 0 0 auto;
- >.list-group {
+ > .list-group {
margin: 0px;
}
@@ -74,22 +75,198 @@
}
.github-preview {
- height : 100%;
- flex : 1;
- background: var(--color2);
- padding : 16px 32px;
- overflow-y: overlay;
+ height: 100%;
+ flex: 1;
+ padding: 16px 32px;
+ overflow: auto;
+ padding-bottom: 16px;
}
.gh-content {
- display : flex;
+ display: flex;
flex-direction: row;
- flex : 1;
- overflow : hidden;
+ flex: 1;
+ overflow: hidden;
}
.gh-header {
padding: 16px;
+ height: 64px;
+ display: grid;
+ align-content: center;
+ flex: 0 0 auto;
+
+ .header-text {
+ position: initial !important;
+ justify-content: left !important;
+ }
+ }
+
+ .installed-themes-page {
+ .style-editor-container {
+ height: 100%;
+ flex: 1;
+ background: var(--color2);
+ padding: 0px;
+ overflow-y: overlay;
+
+ .list-group-item {
+ border-radius: 0px;
+ }
+ }
+ }
+}
+
+//Styles Page
+.installed-themes-page {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+ .themeContextMenu {
+ background: transparent;
+ color: var(--keyColor);
+ border: 0px;
+ }
+
+ .list-group-item {
+ &.addon {
+ background: rgb(86 86 86 / 20%);
+ }
+
+ &.applied {
+ background: var(--keyColor-disabled);
+ pointer-events: none;
+ }
+ }
+
+ .repo-header {
+ font-size: 16px;
+ position: sticky;
+ top: 0;
+ left: 0;
+ right: 0;
+ width: 100%;
+ height: 50px;
+ z-index: 1;
+ background: rgba(36, 36, 36, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ backdrop-filter: var(--glassFilter);
+ overflow: hidden;
+ border-bottom: 1px solid rgb(0 0 0 / 18%);
+ border-top: 1px solid rgb(135 135 135 / 18%);
+ }
+
+ .gh-header {
+ z-index: 5;
+ padding: 16px;
+ flex: 0 0 auto;
+ height: 64px;
+ display: grid;
+ align-content: center;
+ .header-text {
+ position: initial !important;
+ justify-content: left !important;
+ }
+ }
+
+ .gh-content {
+ display: flex;
+ flex-direction: row;
+ padding: 0px;
+ height: 100%;
+ flex: 0 0 auto;
+
+ .repos-list {
+ width: 320px;
+ overflow: overlay;
+ height: 90%;
+ font-size: 14px;
+ white-space: nowrap;
+
+ > .list-group {
+ margin: 0px;
+ padding-bottom: 16px;
+ }
+
+ .list-group-item {
+ padding: 12px 6px;
+
+ &:hover {
+ filter: brightness(1.2);
+ }
+
+ &:active {
+ filter: brightness(0.8);
+ }
+ }
+ }
+
+ .style-editor-container {
+ height: 100%;
+ flex: 1;
+ padding: 0px;
+ width: 100%;
+ overflow: hidden;
+
+ .stylestack-editor {
+ padding-bottom: 16px;
+ }
+
+ .list-group-item {
+ border-radius: 0px;
+ }
+ }
+ }
+
+ .stylestack-editor {
+ width: 100%;
+
+ .btn,
+ .btn-group {
+ width: 100%;
+ }
+
+ .themeLabel {
+ display: flex;
+ align-items: center;
+ }
+
+ .handle {
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .list-group-item {
+
+ &:hover {
+ cursor: grab;
+ }
+
+ &:active {
+ cursor: grabbing;
+ }
+ }
+
+ .removeItem {
+ border: 0px;
+ background: transparent;
+ height: 32px;
+ font-weight: bold;
+ color: var(--textColor);
+ cursor: pointer;
+ }
+
+ .stylesDropdown {
+ > .dropdown-menu {
+ height: 300px;
+ overflow-y: overlay;
+ }
+ }
}
}
@@ -98,16 +275,16 @@
padding: 0px;
.library-header {
- position : sticky;
- top : 0;
- left : 0;
- border-bottom : 1px solid rgba(200, 200, 200, 0.05);
- z-index : 6;
- background : black;
- padding : 0px 2em;
+ position: sticky;
+ top: 0;
+ left: 0;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.05);
+ z-index: 6;
+ background: black;
+ padding: 0px 2em;
backdrop-filter: blur(32px);
- background : rgba(0, 0, 0, 0.25);
- top : var(--navigationBarHeight);
+ background: rgba(0, 0, 0, 0.25);
+ top: var(--navigationBarHeight);
}
.well {
@@ -121,7 +298,7 @@
.searchToggle {
float: right;
- >button {
+ > button {
min-width: 120px;
}
}
@@ -130,18 +307,18 @@
width: 530px !important;
.artwork-container .artwork {
- height : 168px !important;
- width : 507px !important;
+ height: 168px !important;
+ width: 507px !important;
z-index: 1;
}
.title {
- font-weight : bold;
+ font-weight: bold;
justify-content: left;
- font-size : 18px;
- margin-top : -40px;
- z-index : 5;
- pointer-events : none;
+ font-size: 18px;
+ margin-top: -40px;
+ z-index: 5;
+ pointer-events: none;
}
}
}
@@ -149,7 +326,7 @@
// Podcast Page
.content-inner.podcasts-page {
display: flex;
- height : calc(100% - var(--navigationBarHeight));
+ height: calc(100% - var(--navigationBarHeight));
padding: 0px;
.list-flat {
@@ -157,45 +334,45 @@
}
.podcast-artwork {
- width : 200px;
+ width: 200px;
margin: 16px auto;
height: 200px;
}
.podcasts-list {
- height : 100%;
- width : 280px;
- background : rgb(200 200 200 / 10%);
- overflow-y : overlay;
+ height: 100%;
+ width: 280px;
+ background: rgb(200 200 200 / 10%);
+ overflow-y: overlay;
border-right: 1px solid var(--color2);
- flex : none;
- overflow-x : hidden;
+ flex: none;
+ overflow-x: hidden;
.podcast-list-header {
- border-bottom : 1px solid var(--color2);
- font-size : 0.7em;
- padding : 6px;
- background : #ffffff17;
+ border-bottom: 1px solid var(--color2);
+ font-size: 0.7em;
+ padding: 6px;
+ background: #ffffff17;
text-transform: uppercase;
- font-weight : 600;
- opacity : 0.5;
+ font-weight: 600;
+ opacity: 0.5;
}
.podcasts-search {
- padding : 10px;
- position : sticky;
- top : 0;
- left : 0;
- width : 100%;
+ padding: 10px;
+ position: sticky;
+ top: 0;
+ left: 0;
+ width: 100%;
border-bottom: 1px solid var(--color2);
- z-index : 2;
- background : #303030;
+ z-index: 2;
+ background: #303030;
}
}
.episodes-list {
- height : 100%;
- width : 100%;
+ height: 100%;
+ width: 100%;
background: rgb(200 200 200 / 6%);
overflow-y: overlay;
overflow-x: hidden;
@@ -204,20 +381,20 @@
padding: 14px 14px 0px 14px;
.podcast-show-info {
- display : flex;
+ display: flex;
justify-content: center;
- flex-direction : column;
+ flex-direction: column;
}
.podcast-show-description {
- margin : 32px 6px;
- font-size : 0.8rem;
+ margin: 32px 6px;
+ font-size: 0.8rem;
white-space: pre-wrap;
- display : block;
+ display: block;
}
.podcast-artwork {
- width : 120px;
+ width: 120px;
margin: 0px auto;
height: 120px;
}
@@ -230,14 +407,14 @@
}
.podcasts-details {
- width : 300px;
- flex : none;
- background : rgb(255 255 255 / 5%);
- overflow-y : overlay;
- overflow-x : hidden;
- top : 2%;
- z-index : 2;
- border-left : 1px solid var(--color2);
+ width: 300px;
+ flex: none;
+ background: rgb(255 255 255 / 5%);
+ overflow-y: overlay;
+ overflow-x: hidden;
+ top: 2%;
+ z-index: 2;
+ border-left: 1px solid var(--color2);
padding-bottom: 1em;
.meta-btn {
@@ -245,27 +422,27 @@
}
.podcasts-details-header {
- display : flex;
+ display: flex;
justify-content: end;
- align-items : center;
- position : sticky;
- top : 0;
- z-index : 2;
+ align-items: center;
+ position: sticky;
+ top: 0;
+ z-index: 2;
}
.close-btn {
- width : 50px;
- height : 42px;
- background-image : var(--gfx-closeBtn);
+ width: 50px;
+ height: 42px;
+ background-image: var(--gfx-closeBtn);
background-position: center;
- background-repeat : no-repeat;
- -webkit-app-region : no-drag;
- appearance : none;
- border : 0;
- background-color : transparent;
- position : absolute;
- top : 0;
- right : 0;
+ background-repeat: no-repeat;
+ -webkit-app-region: no-drag;
+ appearance: none;
+ border: 0;
+ background-color: transparent;
+ position: absolute;
+ top: 0;
+ right: 0;
&:hover {
background-color: rgb(196, 43, 28)
@@ -273,17 +450,17 @@
}
.podcast-genre {
- text-align : center;
- margin : 6px;
- font-size : 0.8em;
+ text-align: center;
+ margin: 6px;
+ font-size: 0.8em;
font-weight: 500;
- opacity : 0.8;
+ opacity: 0.8;
}
.podcast-metainfo {
text-align: center;
- font-size : 0.7em;
- opacity : 0.8;
+ font-size: 0.7em;
+ opacity: 0.8;
}
.podcast-header {
@@ -292,17 +469,17 @@
}
.podcast-play-btn {
- width : 50%;
+ width: 50%;
display: block;
- margin : 0 auto;
+ margin: 0 auto;
}
.podcast-description {
- margin : 12px;
- font-size : 0.75em;
+ margin: 12px;
+ font-size: 0.75em;
white-space: pre-wrap;
- display : block;
- line-break : anywhere;
+ display: block;
+ line-break: anywhere;
}
@@ -313,59 +490,59 @@
// Podcast Page
.content-inner.library-artists-page {
// top: 0;
- height : calc(100% - 60px - var(--navigationBarHeight));
+ height: calc(100% - 60px - var(--navigationBarHeight));
padding: 0px;
.inner-container {
display: flex;
- height : calc(100% - var(--navigationBarHeight));
+ height: calc(100% - var(--navigationBarHeight));
padding: 0px;
- height : 100%;
+ height: 100%;
.list-flat {
border-radius: 0px;
}
.podcast-artwork {
- width : 200px;
+ width: 200px;
margin: 16px auto;
height: 200px;
}
.podcasts-list {
- height : 100%;
- width : 280px;
- background : rgb(200 200 200 / 10%);
- overflow-y : overlay;
+ height: 100%;
+ width: 280px;
+ background: rgb(200 200 200 / 10%);
+ overflow-y: overlay;
border-right: 1px solid var(--color2);
- flex : none;
- overflow-x : hidden;
+ flex: none;
+ overflow-x: hidden;
.podcast-list-header {
- border-bottom : 1px solid var(--color2);
- font-size : 0.7em;
- padding : 6px;
- background : #ffffff17;
+ border-bottom: 1px solid var(--color2);
+ font-size: 0.7em;
+ padding: 6px;
+ background: #ffffff17;
text-transform: uppercase;
- font-weight : 600;
- opacity : 0.5;
+ font-weight: 600;
+ opacity: 0.5;
}
.podcasts-search {
- padding : 10px;
- position : sticky;
- top : 0;
- left : 0;
- width : 100%;
+ padding: 10px;
+ position: sticky;
+ top: 0;
+ left: 0;
+ width: 100%;
border-bottom: 1px solid var(--color2);
- z-index : 2;
- background : #303030;
+ z-index: 2;
+ background: #303030;
}
}
.episodes-list {
- height : calc(100% + 60px);
- width : 100%;
+ height: calc(100% + 60px);
+ width: 100%;
background: rgb(200 200 200 / 6%);
overflow-y: overlay;
overflow-x: hidden;
@@ -374,20 +551,20 @@
padding: 14px 14px 0px 14px;
.podcast-show-info {
- display : flex;
+ display: flex;
justify-content: center;
- flex-direction : column;
+ flex-direction: column;
}
.podcast-show-description {
- margin : 32px 6px;
- font-size : 0.8rem;
+ margin: 32px 6px;
+ font-size: 0.8rem;
white-space: pre-wrap;
- display : block;
+ display: block;
}
.podcast-artwork {
- width : 120px;
+ width: 120px;
margin: 0px auto;
height: 120px;
}
@@ -400,14 +577,14 @@
}
.podcasts-details {
- width : 300px;
- flex : none;
- background : rgb(255 255 255 / 5%);
- overflow-y : overlay;
- overflow-x : hidden;
- top : 2%;
- z-index : 2;
- border-left : 1px solid var(--color2);
+ width: 300px;
+ flex: none;
+ background: rgb(255 255 255 / 5%);
+ overflow-y: overlay;
+ overflow-x: hidden;
+ top: 2%;
+ z-index: 2;
+ border-left: 1px solid var(--color2);
padding-bottom: 1em;
.meta-btn {
@@ -415,27 +592,27 @@
}
.podcasts-details-header {
- display : flex;
+ display: flex;
justify-content: end;
- align-items : center;
- position : sticky;
- top : 0;
- z-index : 2;
+ align-items: center;
+ position: sticky;
+ top: 0;
+ z-index: 2;
}
.close-btn {
- width : 50px;
- height : 42px;
- background-image : var(--gfx-closeBtn);
+ width: 50px;
+ height: 42px;
+ background-image: var(--gfx-closeBtn);
background-position: center;
- background-repeat : no-repeat;
- -webkit-app-region : no-drag;
- appearance : none;
- border : 0;
- background-color : transparent;
- position : absolute;
- top : 0;
- right : 0;
+ background-repeat: no-repeat;
+ -webkit-app-region: no-drag;
+ appearance: none;
+ border: 0;
+ background-color: transparent;
+ position: absolute;
+ top: 0;
+ right: 0;
&:hover {
background-color: rgb(196, 43, 28)
@@ -443,17 +620,17 @@
}
.podcast-genre {
- text-align : center;
- margin : 6px;
- font-size : 0.8em;
+ text-align: center;
+ margin: 6px;
+ font-size: 0.8em;
font-weight: 500;
- opacity : 0.8;
+ opacity: 0.8;
}
.podcast-metainfo {
text-align: center;
- font-size : 0.7em;
- opacity : 0.8;
+ font-size: 0.7em;
+ opacity: 0.8;
}
.podcast-header {
@@ -461,17 +638,17 @@
}
.podcast-play-btn {
- width : 50%;
+ width: 50%;
display: block;
- margin : 0 auto;
+ margin: 0 auto;
}
.podcast-description {
- margin : 12px;
- font-size : 0.75em;
+ margin: 12px;
+ font-size: 0.75em;
white-space: pre-wrap;
- display : block;
- line-break : anywhere;
+ display: block;
+ line-break: anywhere;
}
@@ -482,18 +659,18 @@
@media only screen and (max-width: 1230px) {
.content-inner.podcasts-page {
.podcasts-details {
- height : 96%;
- width : 300px;
- flex : none;
- background : rgb(20 20 20 / 97%);
- overflow-y : overlay;
- overflow-x : hidden;
- position : absolute;
- right : 2%;
- top : 2%;
+ height: 96%;
+ width: 300px;
+ flex: none;
+ background: rgb(20 20 20 / 97%);
+ overflow-y: overlay;
+ overflow-x: hidden;
+ position: absolute;
+ right: 2%;
+ top: 2%;
border-radius: 10px;
- box-shadow : var(--ciderShadow-Generic);
- z-index : 2;
+ box-shadow: var(--ciderShadow-Generic);
+ z-index: 2;
}
}
}
@@ -502,33 +679,33 @@
@media only screen and (max-width: 1230px) {
.content-inner.podcasts-page {
.podcasts-details {
- height : 96%;
- width : 300px;
- flex : none;
- background : rgb(20 20 20 / 97%);
- overflow-y : overlay;
- overflow-x : hidden;
- position : absolute;
- right : 2%;
- top : 2%;
+ height: 96%;
+ width: 300px;
+ flex: none;
+ background: rgb(20 20 20 / 97%);
+ overflow-y: overlay;
+ overflow-x: hidden;
+ position: absolute;
+ right: 2%;
+ top: 2%;
border-radius: 10px;
- box-shadow : var(--ciderShadow-Generic);
- z-index : 2;
+ box-shadow: var(--ciderShadow-Generic);
+ z-index: 2;
}
}
}
/* Album / Playlist Page */
.playlist-page {
- --bgColor : transparent;
- padding : 0px;
+ --bgColor: transparent;
+ padding: 0px;
//background: linear-gradient(180deg, var(--bgColor) 32px, var(--bgColor) 18px, transparent 60px, transparent 100%);
- top : 0;
- padding-top : var(--navigationBarHeight);
- display : flex;
+ top: 0;
+ padding-top: var(--navigationBarHeight);
+ display: flex;
flex-direction: column;
- height : 100%;
- overflow : hidden;
+ height: 100%;
+ overflow: hidden;
.cd-mediaitem-list-item {
&:hover {
@@ -544,51 +721,51 @@
.editTracksBtn {
position: absolute;
- top : 20px;
- right : 20px;
- z-index : 1;
+ top: 20px;
+ right: 20px;
+ z-index: 1;
- >span {
+ > span {
display: flex;
- gap : 8px;
+ gap: 8px;
}
}
.mediaContainer {
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
- width : 260px;
- height : 260px;
+ width: 260px;
+ height: 260px;
}
.playlist-body {
- padding : 32px;
+ padding: 32px;
// margin-top: -75px;
- overflow-y : overlay;
- height : 100%;
- padding : 0px;
+ overflow-y: overlay;
+ height: 100%;
+ padding: 0px;
background-color: var(--color3);
&.scrollbody {
.tabs {
- display : flex;
+ display: flex;
flex-flow: column;
- height : 100%;
+ height: 100%;
.nav-link {
text-transform: capitalize;
}
.tab-content {
- height : 100%;
+ height: 100%;
overflow: hidden;
- margin : 0px;
+ margin: 0px;
.tab-pane {
- height : 100%;
- overflow-y : overlay;
- overflow-x : hidden;
- padding : var(--contentInnerPadding);
- padding-inline : 40px;
+ height: 100%;
+ overflow-y: overlay;
+ overflow-x: hidden;
+ padding: var(--contentInnerPadding);
+ padding-inline: 40px;
-webkit-mask-image: linear-gradient(180deg, transparent, white 20px);
.well {
@@ -598,185 +775,263 @@
}
}
}
+
+ .search-input-container {
+ height: 2.5rem;
+ margin: 1rem;
+ margin-top: 0;
+ scroll-margin-top: 1rem;
+
+ .search-input {
+ width: 100%;
+ height: 100%;
+ }
+ }
}
.floating-header {
- position : sticky;
- top : 0;
- left : 0;
- border-bottom : 1px solid rgba(200, 200, 200, 0.05);
- z-index : 6;
- padding : 0px 1em;
+ position: sticky;
+ top: 0;
+ left: 0;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.05);
+ z-index: 6;
+ padding: 0px 1em;
backdrop-filter: blur(32px);
- background : rgba(0, 0, 0, 0.25);
- top : var(--navigationBarHeight);
- transition : opacity 0.1s var(--appleEase);
- display : none;
+ background: rgba(0, 0, 0, 0.25);
+ top: var(--navigationBarHeight);
+ transition: opacity 0.1s var(--appleEase);
+ display: none;
}
.playlist-display {
- padding : var(--contentInnerPadding);
+ padding: var(--contentInnerPadding);
min-height: 300px;
- position : relative;
+ position: relative;
box-shadow: 0px 4px 6px 3px rgb(0 0 0 / 10%);
transition: min-height 0.5s ease-in-out;
.artworkContainer {
- position : absolute;
- top : 0;
- left : 0;
- bottom : 0;
- right : 0;
- margin : 0;
- margin-top : calc(var(--navigationBarHeight) * -1);
- margin-bottom : -10px;
- padding : 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ margin: 0;
+ margin-top: calc(var(--navigationBarHeight) * -1);
+ margin-bottom: -10px;
+ padding: 0;
-webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%);
- opacity : .7;
- animation : playlistArtworkFadeIn 1s var(--appleEase);
+ opacity: .7;
+ animation: playlistArtworkFadeIn 1s var(--appleEase);
.artworkMaterial img {
- filter : brightness(100%) blur(80px) saturate(100%) contrast(1);
+ filter: brightness(100%) blur(80px) saturate(100%) contrast(1);
object-position: center;
- object-fit : cover;
- width : 100%;
- height : 100%;
- transform : unset;
+ object-fit: cover;
+ width: 100%;
+ height: 100%;
+ transform: unset;
}
}
.playlistInfo {
- z-index : 1;
- position : absolute;
- bottom : 0;
- left : 0;
- right : 0;
- top : 0;
- display : flex;
+ z-index: 1;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ top: 0;
+ display: flex;
justify-content: center;
- align-items : center;
- width : 100%;
- height : 100%;
+ align-items: center;
+ width: 100%;
+ height: 100%;
- >.row {
+ .playlist-hero {
+ width: 100%;
+ transform: translateX(+25%);
+ position: absolute;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ .mediaitem-artwork {
+ -webkit-mask-image: -webkit-radial-gradient(center, circle cover, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 75%);
+ border-radius: 0px;
+ }
+
+ .hero-tint {
+ position: absolute;
+ top: 0;
+ opacity: 0.6;
+ width: 100%;
+ height: 100%;
+ }
+ }
+
+ > .row {
width: calc(100% - 32px);
}
.playlist-info {
- flex-shrink : unset;
- display : flex;
- flex-flow : column;
+ flex-shrink: unset;
+ display: flex;
+ flex-flow: column;
justify-content: flex-end;
.playlist-name {
- font-weight : 700;
- font-size : 1.6rem;
+ font-weight: 700;
+ font-size: 1.6rem;
//margin-bottom: 6px;
- margin-right : 6px;
- margin-bottom : 6px;
- flex-shrink : unset;
+ margin-right: 6px;
+ margin-bottom: 6px;
+ flex-shrink: unset;
+ }
+
+ .search-input::placeholder {
+ color: var(--heroplaceholdercolor)
}
.nameEdit {
font-weight: 700;
- font-size : 1.6rem;
+ font-size: 1.6rem;
flex-shrink: unset;
- background : transparent;
- border : 0px;
- color : inherit;
+ background: transparent;
+ border: 0px;
+ color: inherit;
font-family: inherit;
}
.descriptionEdit {
- font-size : 14px;
+ font-size: 14px;
flex-shrink: unset;
- background : transparent;
- border : 0px;
- color : inherit;
+ background: transparent;
+ border: 0px;
+ color: inherit;
font-family: inherit;
- width : 60vw;
+ width: 60vw;
}
.descriptionEdit {
- font-size : 14px;
- flex-shrink : unset;
- background : transparent;
- border : 0px;
- color : inherit;
- font-family : inherit;
- width : 60vw;
+ font-size: 14px;
+ flex-shrink: unset;
+ background: transparent;
+ border: 0px;
+ color: inherit;
+ font-family: inherit;
+ width: 60vw;
}
.playlist-artist {
- font-size : 20px;
+ font-size: 20px;
margin-bottom: 6px;
- margin-right : 6px;
- flex-shrink : unset;
+ margin-right: 6px;
+ flex-shrink: unset;
}
.playlist-desc {
- transition : height .2s ease-in-out, opacity .2s ease-in-out;
- box-sizing : border-box;
- font-size : 14px;
- flex-shrink : unset;
+ transition: height .2s ease-in-out, opacity .2s ease-in-out;
+ box-sizing: border-box;
+ font-size: 14px;
+ flex-shrink: unset;
margin-right: 5px;
- max-height : 100px;
- position : relative;
- height : 4vh;
+ max-height: 100px;
+ position: relative;
+ height: 4vh;
.content {
- height : 4vh;
+ height: 4vh;
-webkit-mask-image: -webkit-gradient(linear, left 50%, left 90%, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
}
.more-btn {
- appearance : none;
- position : absolute;
- right : 0;
- bottom : 0;
- padding : 0 5px;
- font-size : 14px;
- color : var(--keyColor);
+ appearance: none;
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ padding: 0 5px;
+ font-size: 14px;
+ color: var(--keyColor);
background-color: transparent;
- border : 0px;
- cursor : pointer;
- width : 100%;
- height : 100%;
- overflow : hidden;
- display : flex;
- justify-content : flex-end;
- align-items : flex-end;
- font-weight : 600;
- font-family : inherit;
- text-transform : uppercase;
+ border: 0px;
+ cursor: pointer;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ display: flex;
+ justify-content: flex-end;
+ align-items: flex-end;
+ font-weight: 600;
+ font-family: inherit;
+ text-transform: uppercase;
}
}
.playlist-desc-expanded {
box-sizing: border-box;
- font-size : 14px;
- position : relative;
+ font-size: 14px;
+ position: relative;
.more-btn {
- appearance : none;
- position : absolute;
- right : 0;
- bottom : 0;
- padding : 0 5px;
- font-size : 14px;
- color : var(--keyColor);
+ appearance: none;
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ padding: 0 5px;
+ font-size: 14px;
+ color: var(--keyColor);
background-color: transparent;
- border : 0px;
- cursor : pointer;
- width : 100%;
- height : 100%;
- overflow : hidden;
- display : flex;
- justify-content : flex-end;
- align-items : flex-end;
- font-weight : 600;
- font-family : inherit;
- text-transform : uppercase;
+ border: 0px;
+ cursor: pointer;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ display: flex;
+ justify-content: flex-end;
+ align-items: flex-end;
+ font-weight: 600;
+ font-family: inherit;
+ text-transform: uppercase;
+ }
+ }
+
+ .search-btn {
+ display: flex;
+ width: 32px;
+ align-items: center;
+ margin-right: 1rem;
+ background: rgba(100, 100, 100, 0.5);
+ border: none;
+ cursor: pointer;
+ border-radius: 100vmax;
+ box-shadow: var(--ciderShadow-Generic);
+
+ > ._svg-icon {
+ width: 18px;
+ height: 18px;
+ margin: auto;
+ }
+ }
+
+ .search-btn.active {
+ animation: enlarge 0.5s ease-in-out;
+ }
+
+ .search-btn:hover {
+ filter: brightness(125%);
+ }
+
+ @keyframes enlarge {
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.2);
+ }
+ 100% {
+ transform: scale(1);
}
}
}
@@ -786,21 +1041,21 @@
}
.friends-info {
- display : flex;
+ display: flex;
flex-flow: column;
.badge-container {
- display : flex;
+ display: flex;
flex-flow: wrap;
.socialBadge {
- width : 40px;
- height : 40px;
+ width: 40px;
+ height: 40px;
border-radius: 100%;
- overflow : hidden;
- box-shadow : var(--mediaItemShadow-ShadowSubtle);
- transition : transform .2s var(--appleEase);
- margin : 6px;
+ overflow: hidden;
+ box-shadow: var(--mediaItemShadow-ShadowSubtle);
+ transition: transform .2s var(--appleEase);
+ margin: 6px;
&:hover {
transform: scale(1.2);
@@ -810,38 +1065,38 @@
.friends-name {
text-align: center;
- font-size : 0.9em;
- margin : 8px;
+ font-size: 0.9em;
+ margin: 8px;
}
}
.playlist-time {
- font-size : 0.9em;
- margin : 6px;
- opacity : 0.7;
+ font-size: 0.9em;
+ margin: 6px;
+ opacity: 0.7;
transition: height .2s ease-in-out, opacity .2s ease-in-out;
- height : 0.9em;
+ height: 0.9em;
}
&.inline-playlist {
- overflow : hidden;
- width : 100%;
- height : 100%;
- background : rgba(0, 0, 0, 0.5);
- display : flex;
+ overflow: hidden;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ display: flex;
justify-content: center;
- align-items : center;
- z-index : 10;
- position : sticky;
- margin-top : calc(var(--navigationBarHeight) * -1);
+ align-items: center;
+ z-index: 10;
+ position: sticky;
+ margin-top: calc(var(--navigationBarHeight) * -1);
.floating-header {
- opacity : 1;
- top : 0px;
- z-index : 6;
- padding : 1em;
+ opacity: 1;
+ top: 0px;
+ z-index: 6;
+ padding: 1em;
backdrop-filter: unset;
- background : black;
+ background: black;
h3 {
display: none;
@@ -849,27 +1104,27 @@
}
.playlist-inner {
- background : black;
- width : 80%;
- height : 100%;
- overflow : overlay;
- box-shadow : var(--ciderShadow-Generic);
+ background: black;
+ width: 80%;
+ height: 100%;
+ overflow: overlay;
+ box-shadow: var(--ciderShadow-Generic);
border-radius: var(--mediaItemRadius) var(--mediaItemRadius) 0px 0px;
.close-btn {
- position : sticky;
- top : 16px;
- left : 16px;
+ position: sticky;
+ top: 16px;
+ left: 16px;
margin-left: 16px;
- z-index : 7;
+ z-index: 7;
}
}
}
.pilldim {
.nav-pills {
- width : max-content;
- margin : 0 auto;
+ width: max-content;
+ margin: 0 auto;
margin-top: 16px;
}
}
@@ -879,24 +1134,25 @@
transition: min-height 0.5s ease-in-out;
min-height: 200px;
- .playlistInfo {}
+ .playlistInfo {
+ }
.mediaContainer {
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
- width : 128px !important;
- height : 128px !important;
+ width: 128px !important;
+ height: 128px !important;
}
.playlist-time {
transition: height .2s ease-in-out, opacity .2s ease-in-out;
- height : 0px;
- opacity : 0;
+ height: 0px;
+ opacity: 0;
}
.playlist-desc {
transition: height .2s ease-in-out, opacity .2s ease-in-out;
- height : 0px !important;
- opacity : 0;
+ height: 0px !important;
+ opacity: 0;
}
}
}
@@ -917,20 +1173,20 @@
padding-bottom: 128px;
.top-fab {
- height : 52px;
- width : 52px;
- position : fixed;
- bottom : 32px;
- right : 32px;
+ height: 52px;
+ width: 52px;
+ position: fixed;
+ bottom: 32px;
+ right: 32px;
border-radius: 100%;
- background : rgb(60 60 60);
- border : 0px;
- appearance : none;
- box-shadow : var(--ciderShadow-Generic);
+ background: rgb(60 60 60);
+ border: 0px;
+ appearance: none;
+ box-shadow: var(--ciderShadow-Generic);
- >svg {
- height : 50%;
- color : #eee;
+ > svg {
+ height: 50%;
+ color: #eee;
pointer-events: none;
}
@@ -952,53 +1208,53 @@
.artist-page {
padding: 0px;
- top : 0;
+ top: 0;
.floating-header {
- position : sticky;
- top : 0;
- left : 0;
- border-bottom : 1px solid rgba(200, 200, 200, 0.05);
- z-index : 6;
- padding : 0px 1em;
+ position: sticky;
+ top: 0;
+ left: 0;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.05);
+ z-index: 6;
+ padding: 0px 1em;
backdrop-filter: blur(32px);
- background : rgba(0, 0, 0, 0.25);
- top : var(--navigationBarHeight);
- transition : opacity 0.1s var(--appleEase);
+ background: rgba(0, 0, 0, 0.25);
+ top: var(--navigationBarHeight);
+ transition: opacity 0.1s var(--appleEase);
}
&.animated .artist-header .more-btn-round {
position: absolute;
- bottom : 22px !important;
- right : 28px;
+ bottom: 22px !important;
+ right: 28px;
}
&.animated .artist-header {
- min-height: 500px;
+ min-height: 80vh;
}
.artist-header {
//background: linear-gradient(45deg, var(--keyColor), #0e0e0e);
- color : white;
- display : flex;
- align-items : center;
+ color: white;
+ display: flex;
+ align-items: center;
justify-content: space-between;
- min-height : 400px;
- position : relative;
- pointer-events : none;
+ min-height: 400px;
+ position: relative;
+ pointer-events: none;
.header-content {
- z-index : 1;
+ z-index: 1;
// margin-top: -16px;
}
.artist-hero {
- height:100%;
+ height: 100%;
position: absolute;
- top:0;
- left:0;
- right:0;
- bottom:0;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
.mediaitem-artwork {
border-radius: 0px;
@@ -1007,51 +1263,72 @@
.artworkContainer {
- position : absolute;
- top : 0;
- left : 0;
- bottom : 0;
- right : 0;
- margin : 0;
- padding : 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ margin: 0;
+ padding: 0;
-webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%);
- opacity : .7;
- animation : playlistArtworkFadeIn 1s var(--appleEase);
+ opacity: .7;
+ animation: playlistArtworkFadeIn 1s var(--appleEase);
.artworkMaterial img {
- filter : brightness(100%) blur(80px) saturate(100%) contrast(1);
+ filter: brightness(100%) blur(80px) saturate(100%) contrast(1);
object-position: center;
- object-fit : cover;
- width : 100%;
- height : 100%;
- transform : unset;
+ object-fit: cover;
+ width: 100%;
+ height: 100%;
+ transform: unset;
}
}
.more-btn-round {
position: absolute;
- bottom : 82px;
- right : 28px;
+ bottom: 82px;
+ right: 28px;
+ }
+
+ .social-btn {
+ border-radius: 100%;
+ background: transparent;
+ height: 17px;
+ border: 0px;
+ cursor: pointer;
+ z-index: 69;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ float: right;
+ }
+ @media only screen and (min-width: 1133px) and (max-width: 1277px) {
+ .about-page {
+ .social-btn {
+ display: none !important;
+ }
+ }
}
.animated {
- width : 100%;
- height : 100%;
+ width: 100%;
+ height: 100%;
align-self: center;
- position : absolute;
- overflow : hidden;
+ position: absolute;
+ overflow: hidden;
box-shadow: rgb(0 0 0 / 50%) 0 0 0 1000000px inset;
z-index: 1;
video {
- overflow : hidden;
- height : 100%;
- width : 100%;
+ overflow: hidden;
+ height: 100%;
+ width: 100%;
min-height: 56.25vw;
- position : absolute;
- top : 50%;
- left : 50%;
- transform : translate(-50%, -50%);
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ object-fit: cover;
}
}
@@ -1061,29 +1338,29 @@
}
.artist-image {
- width : 200px;
- height : 200px;
- margin : 32px;
+ width: 200px;
+ height: 200px;
+ margin: 32px;
position: relative;
.overlay-play {
- position : absolute;
- top : 0;
- left : 0;
- width : 100%;
- height : 100%;
- opacity : 0;
- background : rgb(0 0 0 / 50%);
- transition : opacity 0.1s var(--appleEase);
- border-radius : 100%;
- z-index : 1;
- display : flex;
- align-items : center;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ background: rgb(0 0 0 / 50%);
+ transition: opacity 0.1s var(--appleEase);
+ border-radius: 100%;
+ z-index: 1;
+ display: flex;
+ align-items: center;
justify-content: center;
- cursor : pointer;
- appearance : none;
- border : 0px;
- padding : 0px;
+ cursor: pointer;
+ appearance: none;
+ border: 0px;
+ padding: 0px;
&:hover {
opacity: 1;
@@ -1093,32 +1370,32 @@
background: var(--selected-click);
}
- >svg {
+ > svg {
width: 70%;
}
}
}
.artist-play {
- width : 32px;
- height : 32px;
- background : rgba(100, 100, 100, 0.5);
- box-shadow : var(--ciderShadow-Generic);
+ width: 32px;
+ height: 32px;
+ background: rgba(100, 100, 100, 0.5);
+ box-shadow: var(--ciderShadow-Generic);
border-radius: 100%;
- box-shadow : var(--mediaItemShadow);
- display : none;
- cursor : pointer;
- appearance : none;
- border : 0px;
- padding : 0px;
+ box-shadow: var(--mediaItemShadow);
+ display: none;
+ cursor: pointer;
+ appearance: none;
+ border: 0px;
+ padding: 0px;
&:hover {
filter: brightness(125%);
}
&:active {
- filter : brightness(75%);
- transform : scale(0.98);
+ filter: brightness(75%);
+ transform: scale(0.98);
transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase);
}
}
@@ -1127,16 +1404,16 @@
.artist-play {
transform: translateY(3px);
- margin : 14px;
+ margin: 14px;
}
&.artist-animation-on {
- width : 100%;
- flex : unset;
+ width: 100%;
+ flex: unset;
margin-left: 0.5em;
- color : whitesmoke;
- position : absolute;
- bottom : 0;
+ color: whitesmoke;
+ position: absolute;
+ bottom: 0;
.artist-play {
display: block;
@@ -1146,45 +1423,45 @@
.artist-body {
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
- margin : -64px 20px;
+ margin: -64px 20px;
.arow {
- display : flex;
+ display: flex;
overflow: hidden;
- padding : 16px 32px;
+ padding: 16px 32px;
- >.latestRelease {
+ > .latestRelease {
width: 250px;
}
- >.topSongs {
+ > .topSongs {
width: calc(100% - 250px);
}
- &.arowb>.topSongs {
+ &.arowb > .topSongs {
width: 100%;
}
}
}
- &.animated>.artist-body {
- padding : 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
+ &.animated > .artist-body {
+ padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
margin-top: -57px;
}
.showmoreless {
- font-family : inherit;
- font-size : 16px;
- font-weight : 500;
- background : transparent;
- border : 0px;
+ font-family: inherit;
+ font-size: 16px;
+ font-weight: 500;
+ background: transparent;
+ border: 0px;
border-radius: 6px;
- appearance : none;
- color : var(--keyColor);
- padding : 8px 12px;
- cursor : pointer;
- margin-top : 12px;
- float : right;
+ appearance: none;
+ color: var(--keyColor);
+ padding: 8px 12px;
+ cursor: pointer;
+ margin-top: 12px;
+ float: right;
}
.showmoreless:hover {
@@ -1194,133 +1471,15 @@
/* Artist Page End */
-
-.installed-themes-page {
-
- .themeContextMenu {
- background: transparent;
- color : var(--keyColor);
- border : 0px;
- }
-
- .list-group-item {
- &.addon {
- background: rgb(86 86 86 / 20%);
- }
-
- &.applied {
- background : var(--keyColor-disabled);
- pointer-events: none;
- }
- }
-
- .repo-header {
- font-size : 16px;
- position : sticky;
- top : 0;
- left : 0;
- right : 0;
- width : 100%;
- height : 50px;
- z-index : 1;
- background : rgba(36, 36, 36, 0.5);
- display : flex;
- justify-content: center;
- align-items : center;
- backdrop-filter: var(--glassFilter);
- overflow : hidden;
- border-bottom : 1px solid rgb(0 0 0 / 18%);
- border-top : 1px solid rgb(135 135 135 / 18%);
- }
-
- .style-editor-container {
- height : 100%;
- flex : 1;
- background: var(--color2);
- padding : 0px;
- overflow-y: overlay;
-
- .list-group-item {
- border-radius: 0px;
- }
- }
-
-
- .stylestack-editor {
- width: 100%;
-
- .btn,
- .btn-group {
- width: 100%;
- }
-
- .themeLabel {
- display : flex;
- align-items: center;
- }
-
- .handle {
- height : 100%;
- display : flex;
- justify-content: center;
- align-items : center;
- }
-
- .list-group-item {
-
- &:hover {
- cursor: grab;
- }
-
- &:active {
- cursor: grabbing;
- }
- }
-
- .removeItem {
- border : 0px;
- background : transparent;
- height : 32px;
- font-weight: bold;
- color : var(--textColor);
- cursor : pointer;
- }
-
- .stylesDropdown {
- >.dropdown-menu {
- height : 300px;
- overflow-y: overlay;
- }
- }
- }
-}
-
// Settings page
.settings-page {
padding: 0px;
.nav {
- width : 90%;
+ width: 90%;
margin: 16px auto 0px;
}
- .md-option-header {
- padding : 0px 26px;
- border-bottom: unset;
- border-top : unset;
- font-weight : 600;
- background : rgb(255 255 255 / 0%);
- font-size : 2em;
- }
-
- .settings-option-body-webview {
- height: 100%;
- width : 100%;
- }
-
- .settings-option-body {
- margin: 16px;
- }
}
// AudioLabs page
@@ -1328,48 +1487,48 @@
padding: 0px;
.md-option-header {
- padding : 1.25em 1.25em;
+ padding: 1.25em 1.25em;
border-bottom: unset;
- border-top : unset;
- font-weight : 600;
- font-size : 1.0em;
- background : rgb(255 255 255 / 3%);
+ border-top: unset;
+ font-weight: 600;
+ font-size: 1.0em;
+ background: rgb(255 255 255 / 3%);
}
- .carousel-item>img {
+ .carousel-item > img {
object-fit: cover;
- width : 100%;
+ width: 100%;
}
.spprofile-line {
- height : 300px;
- width : 100%;
+ height: 300px;
+ width: 100%;
max-width: 1024px;
- padding : 16px;
- margin : 0 auto;
+ padding: 16px;
+ margin: 0 auto;
.spprofile-viewport {
- height : 100%;
- position : relative;
+ height: 100%;
+ position: relative;
border-radius: var(--mediaItemRadius);
- overflow : hidden;
- box-shadow : var(--mediaItemShadow-Shadow);
- background : black;
+ overflow: hidden;
+ box-shadow: var(--mediaItemShadow-Shadow);
+ background: black;
.spprev,
.nextprev {
- position : absolute;
- height : 100%;
- width : 64px;
- top : 0;
+ position: absolute;
+ height: 100%;
+ width: 64px;
+ top: 0;
background: rgb(0 0 0 / 20%);
- z-index : 1;
- border : 0px;
+ z-index: 1;
+ border: 0px;
transition: background 0.2s var(--appleEase), transform 0.2s var(--appleEase);
&:hover {
background: var(--selected);
- transform : scale(1.1);
+ transform: scale(1.1);
}
&:active {
@@ -1378,17 +1537,17 @@
}
&:before {
- content : '';
- position : absolute;
- top : 0;
- left : 0;
- width : 100%;
- height : 100%;
- background : #eee;
- opacity : 1;
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: #eee;
+ opacity: 1;
-webkit-mask-position: center;
- -webkit-mask-repeat : no-repeat;
- -webkit-mask-size : 1em;
+ -webkit-mask-repeat: no-repeat;
+ -webkit-mask-size: 1em;
}
}
@@ -1411,25 +1570,25 @@
}
.spslide {
- position : absolute;
- width : 100%;
- height : 100%;
- overflow : hidden;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
background: black;
- >img {
- WIDTH : 100%;
- height : 100%;
+ > img {
+ WIDTH: 100%;
+ height: 100%;
object-fit: cover;
}
.sptitle {
- position : absolute;
- bottom : 0px;
- left : 0;
- width : 100%;
- text-align : center;
- font-size : 18px;
+ position: absolute;
+ bottom: 0px;
+ left: 0;
+ width: 100%;
+ text-align: center;
+ font-size: 18px;
text-shadow: 0px 2px 4px #00000033;
}
}
@@ -1437,19 +1596,19 @@
.spfade-enter-active,
.spfade-leave-active {
--transitionTime: 0.2s;
- transition : opacity var(--transitionTime) var(--appleEase), transform var(--transitionTime) var(--appleEase);
- will-change : opacity, transform;
+ transition: opacity var(--transitionTime) var(--appleEase), transform var(--transitionTime) var(--appleEase);
+ will-change: opacity, transform;
}
.spfade-enter {
- opacity : 0;
- transform : scale(1.2) translate3d(0, 0, 0);
+ opacity: 0;
+ transform: scale(1.2) translate3d(0, 0, 0);
will-change: opacity, transform;
}
.spfade-leave-to {
- opacity : 1;
- transform : scale(1) translate3d(0, 0, 0);
+ opacity: 1;
+ transform: scale(1) translate3d(0, 0, 0);
will-change: opacity, transform;
}
}
@@ -1479,79 +1638,79 @@
.md-btn-replay {
background-image: linear-gradient(-45deg, #2e2173, #925042);
- animation : gradient-animation 5s ease-in-out infinite;
- background-size : 400% 400%;
- border : 0px;
- box-shadow : inset 0px 0px 0px 1px rgba(200, 200, 200, 0.2);
- text-transform : uppercase;
- font-weight : bold;
+ animation: gradient-animation 5s ease-in-out infinite;
+ background-size: 400% 400%;
+ border: 0px;
+ box-shadow: inset 0px 0px 0px 1px rgba(200, 200, 200, 0.2);
+ text-transform: uppercase;
+ font-weight: bold;
}
.md-btn-replay--hero {
- font-size : 1em;
- padding : 16px;
+ font-size: 1em;
+ padding: 16px;
background-image: linear-gradient(-45deg, #2e2173, #925042);
- animation : gradient-animation 5s ease-in-out infinite;
- background-size : 400% 400%;
- border : 0px;
- box-shadow : inset 0px 0px 0px 1px rgb(200 200 200 / 20%);
- margin-top : 1em;
- font-size : 0.9em;
- text-transform : uppercase;
- font-weight : bold;
+ animation: gradient-animation 5s ease-in-out infinite;
+ background-size: 400% 400%;
+ border: 0px;
+ box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 20%);
+ margin-top: 1em;
+ font-size: 0.9em;
+ text-transform: uppercase;
+ font-weight: bold;
}
.artist-feed-card {
- position : absolute;
- bottom : 0;
- left : 10%;
- z-index : 1;
- background : black;
- width : 80%;
- height : 96%;
- overflow : scroll;
+ position: absolute;
+ bottom: 0;
+ left: 10%;
+ z-index: 1;
+ background: black;
+ width: 80%;
+ height: 96%;
+ overflow: scroll;
border-radius: 10px;
}
.col.madeforyou-col {
- width : 420px;
+ width: 420px;
min-width: 0px;
max-width: 420px;
}
.well.artistfeed-well {
- margin-top : 0px;
- height : 392px;
+ margin-top: 0px;
+ height: 392px;
align-content: flex-start;
}
.hint-text {
font-size: 0.9rem;
- color : rgb(200 200 200 / 70%);
+ color: rgb(200 200 200 / 70%);
}
.user-icon {
border-radius: 100%;
- width : 128px;
- height : 128px;
- overflow : hidden;
- box-shadow : var(--mediaItemShadow-Shadow);
- margin : 16px;
+ width: 128px;
+ height: 128px;
+ overflow: hidden;
+ box-shadow: var(--mediaItemShadow-Shadow);
+ margin: 16px;
}
.well.profile-well {
- flex-direction : column;
+ flex-direction: column;
justify-content: center;
- align-items : center;
+ align-items: center;
.name {
- margin : 4px;
+ margin: 4px;
font-weight: 500;
}
.handle {
- margin : 4px;
- opacity : 0.7;
+ margin: 4px;
+ opacity: 0.7;
font-weight: 500;
}
}
@@ -1562,31 +1721,31 @@
--replayTextShadow: 0px 3px 2px #6f3f52;
.replay-period {
- height : 200px;
- width : 200px;
- margin : 6px;
- border-radius : var(--mediaItemRadius);
- overflow : hidden;
- cursor : pointer;
- transition : transform .2s var(--appleEase);
+ height: 200px;
+ width: 200px;
+ margin: 6px;
+ border-radius: var(--mediaItemRadius);
+ overflow: hidden;
+ cursor: pointer;
+ transition: transform .2s var(--appleEase);
transition-delay: .1s;
- align-self : center;
+ align-self: center;
&:hover {
- transform : translateY(-6px);
+ transform: translateY(-6px);
transition-delay: 0s;
}
.artwork-container {
height: 200px;
- width : 200px;
+ width: 200px;
}
}
.replay-playlist-container {
.cd-mediaitem-square {
height: 230px;
- width : 230px;
+ width: 230px;
.info-rect {
display: none;
@@ -1596,12 +1755,12 @@
.replay-video {
max-height: 300px;
- max-width : 800px;
- margin : 0 auto;
+ max-width: 800px;
+ margin: 0 auto;
.mediaitem-artwork {
max-height: 300px;
- max-width : 800px;
+ max-width: 800px;
}
.mediaitem-artwork .animatedartwork-view-box .animated video {
@@ -1612,28 +1771,28 @@
.top-genres-container {
.genre-name {
- font-size : 0.9em;
- margin : 6px 0px;
+ font-size: 0.9em;
+ margin: 6px 0px;
font-weight: 500;
}
.genre-count {
- width : 100%;
- height : 32px;
- background : #ffffff14;
+ width: 100%;
+ height: 32px;
+ background: #ffffff14;
border-radius: 10px;
- overflow : hidden;
+ overflow: hidden;
.genre-count-bar {
- height : 100%;
- width : 0%;
- background : var(--keyColor);
- display : flex;
+ height: 100%;
+ width: 0%;
+ background: var(--keyColor);
+ display: flex;
justify-content: center;
- align-items : center;
- min-width : 32px;
- font-size : 0.9em;
- font-weight : 500;
+ align-items: center;
+ min-width: 32px;
+ font-size: 0.9em;
+ font-weight: 500;
}
}
}
@@ -1643,11 +1802,11 @@
animation: replayFadeIn .5s var(--appleEase);
}
- transition : transform .2s var(--appleEase);
+ transition: transform .2s var(--appleEase);
transition-delay: .1s;
&:hover {
- transform : scale(1.1);
+ transform: scale(1.1);
transition-delay: 0s;
}
}
@@ -1656,78 +1815,78 @@
0% {
//border-radius: 100%;
transform: translateY(10px) scale(0.9);
- opacity : 0;
+ opacity: 0;
}
100% {
//border-radius: var(--mediaItemRadius);
transform: scale(1);
- opacity : 1;
+ opacity: 1;
}
}
.replay-viewport {
background-image: linear-gradient(-45deg, #2e2173, #925042);
- animation : gradient-animation 5s ease-in-out infinite;
- background-size : 400% 400%;
- padding : 16px 40px;
- border-radius : 10px;
- box-shadow : var(--mediaItemShadow), var(--mediaItemShadow-Shadow);
- color : rgb(238 238 238 / 86%);
+ animation: gradient-animation 5s ease-in-out infinite;
+ background-size: 400% 400%;
+ padding: 16px 40px;
+ border-radius: 10px;
+ box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-Shadow);
+ color: rgb(238 238 238 / 86%);
.replay-header {
- text-align : center;
- font-size : 3em;
+ text-align: center;
+ font-size: 3em;
text-shadow: var(--replayTextShadow);
}
}
.replay-card {
background: transparent;
- border : 0px;
+ border: 0px;
}
}
.content-inner.oobe {
- position : absolute;
- overflow : hidden;
- top : 0;
- left : 0;
- bottom : 0;
- right : 0;
- display : grid;
+ position: absolute;
+ overflow: hidden;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ display: grid;
place-items: center;
- width : 100%;
- background : #1e1e1e;
+ width: 100%;
+ background: #1e1e1e;
.oobe-view {
- display : flex;
- flex-direction : column;
+ display: flex;
+ flex-direction: column;
justify-content: center;
- align-items : center;
- gap : 32px;
- max-width : 1280px;
- max-height : 720px;
- align-self : center;
- justify-self : center;
- height : 100%;
- width : 100%;
+ align-items: center;
+ gap: 32px;
+ max-width: 1280px;
+ max-height: 720px;
+ align-self: center;
+ justify-self: center;
+ height: 100%;
+ width: 100%;
.oobe-header {
- font-size : 3em;
+ font-size: 3em;
text-shadow: var(--replayTextShadow);
font-weight: 600;
}
.oobe-body {
- flex : 1;
- width : 100%;
- background : #ffffff0d;
+ flex: 1;
+ width: 100%;
+ background: #ffffff0d;
border-radius: 20px;
- padding : 3em;
- overflow-y : scroll;
- overflow-x : hidden;
+ padding: 3em;
+ overflow-y: scroll;
+ overflow-x: hidden;
@media screen and (max-width: 1161px) {
font-size: 13px;
@@ -1739,7 +1898,7 @@
.blurb {
white-space: pre-wrap;
- margin : 16px;
+ margin: 16px;
line-height: 1.5em;
}
@@ -1748,34 +1907,34 @@
.stylePicker {
border-radius: 10px;
- overflow : hidden;
- cursor : pointer;
- transition : 0.25s all;
- box-shadow : 0px 2px 6px rgba(0, 0, 0, 0.25);
- width : 450px;
- margin : 0 auto;
+ overflow: hidden;
+ cursor: pointer;
+ transition: 0.25s all;
+ box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
+ width: 450px;
+ margin: 0 auto;
.visualPreview {
pointer-events: none;
- transition : .25s all;
- width : 100%;
+ transition: .25s all;
+ width: 100%;
}
.card-body {
- padding : 0;
- display : flex;
+ padding: 0;
+ display: flex;
justify-content: center;
- align-items : center;
+ align-items: center;
}
.card-footer {
- font-size : 1.25em;
+ font-size: 1.25em;
font-weight: 500;
- position : absolute;
- bottom : 0;
- left : 0;
- width : 100%;
- border : 0px;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ border: 0px;
text-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
font-weight: bold;
}
@@ -1785,10 +1944,9 @@
}
-
&:hover {
- transform : scale(1.10) translateZ(-1px) translateY(10px);
- z-index : 1;
+ transform: scale(1.10) translateZ(-1px) translateY(10px);
+ z-index: 1;
box-shadow: 0px 12px 16px rgb(0 0 0 / 25%);
}
@@ -1800,15 +1958,15 @@
}
.oobe-footer {
- display : flex;
- flex-direction : row;
+ display: flex;
+ flex-direction: row;
justify-content: center;
- align-items : center;
- padding : 16px;
+ align-items: center;
+ padding: 16px;
.md-btn {
- font-size : 18px;
- min-width : 128px;
+ font-size: 18px;
+ min-width: 128px;
text-align: center;
}
}
@@ -1817,41 +1975,42 @@
.oobe-titlebar {
- position : absolute;
- top : 0;
- left : 0;
- height : 46px;
- width : 100%;
- align-items : center;
- justify-content : right;
- display : flex;
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 46px;
+ width: 100%;
+ align-items: center;
+ justify-content: right;
+ display: flex;
-webkit-app-region: drag;
.button-group {
-webkit-app-region: no-drag;
- display : flex;
- flex-direction : row;
- width : 100px;
- height : 100%;
- justify-content : center;
- align-items : center;
- gap : 16px;
+ display: flex;
+ flex-direction: row;
+ width: 100px;
+ height: 100%;
+ justify-content: center;
+ align-items: center;
+ gap: 16px;
- >button {
- height : 32px;
- width : 32px;
- font-size : 16px;
- border-radius : 0px;
- border : 0;
- appearance : none;
- position : relative;
- display : flex;
+ > button {
+ height: 32px;
+ width: 32px;
+ font-size: 16px;
+ border-radius: 0px;
+ border: 0;
+ appearance: none;
+ position: relative;
+ display: flex;
justify-content: center;
- align-items : center;
- border-radius : 100%;
+ align-items: center;
+ border-radius: 100%;
&.close {
background-color: #fc3c44aa;
+
&:hover {
background-color: #fc3c44;
}
@@ -1859,6 +2018,7 @@
&.min {
background-color: rgb(200 200 200 / 5%);
+
&:hover {
background-color: rgb(200 200 200 / 10%);
}
@@ -1866,14 +2026,14 @@
&.close::before {
font-family: "codicon";
- content : "";
- color : white;
+ content: "";
+ color: white;
}
&.min::before {
font-family: "codicon";
- content : "";
- color : white;
+ content: "";
+ color: white;
}
}
}
@@ -1888,20 +2048,20 @@
}
.header-desc {
- font-size : 1em;
+ font-size: 1em;
font-weight: 400;
}
.artworkContainer {
height: 300px;
- width : 100%;
+ width: 100%;
img {
- height : 100%;
- width : 100%;
- overflow : hidden;
+ height: 100%;
+ width: 100%;
+ overflow: hidden;
object-fit: cover;
- filter : unset;
+ filter: unset;
&:last-child {
transform: unset;
@@ -1909,3 +2069,214 @@
}
}
}
+
+.settings-panel {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgb(0 0 0 / 0);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 16;
+
+ .settings-window {
+ background: var(--baseColorMix);
+ max-width: 90%;
+ max-height: 90%;
+ width: 100%;
+ height: 100%;
+ border-radius: 10px;
+ box-shadow: var(--ciderShadow-Generic);
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ flex: 1;
+ backdrop-filter: var(--glassFilterHeavy);
+ transition: width 0.25s ease-in-out, height 0.25s ease-in-out, max-width 0.25s ease-in-out, max-height 0.25s ease-in-out;
+
+ .header-text {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 600;
+ opacity: 0.9;
+ }
+
+ .nav-pills {
+ gap: 6px;
+
+ }
+
+ .nav-pills .nav-link {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ height: 35px;
+
+ :nth-child(2) {
+ white-space: nowrap;
+ }
+ }
+
+
+ .md-option-header {
+ padding: 0px 26px;
+ border-bottom: unset;
+ border-top: unset;
+ font-weight: 600;
+ background: rgb(255 255 255 / 0%);
+ font-size: 2em;
+ }
+
+ .settings-option-body-webview {
+ height: 100%;
+ width: 100%;
+ }
+
+ .settings-option-body {
+ margin: 16px;
+ }
+
+ &.maxed {
+ width: 100%;
+ height: 100%;
+ max-height: 100%;
+ max-width: 100%;
+ border-radius: 0px;
+ box-shadow: unset;
+ }
+
+ .close-btn {
+ width: 36px;
+ height: 36px;
+ background-position: center;
+ background-repeat: no-repeat;
+ -webkit-app-region: no-drag;
+ appearance: none;
+ border: 0;
+ background-color: transparent;
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ border-radius: 50px;
+ display: grid;
+ align-content: center;
+ z-index: 9;
+
+ &:before {
+ content: "";
+ font-family: "codicon";
+ color: var(--textColor);
+ font-size: 20px;
+ }
+
+ &:hover {
+ background-color: rgb(196, 43, 28)
+ }
+
+ &.back-btn {
+ left: 10px;
+ right: unset;
+ }
+
+ &.minmax-btn {
+ right: 52px;
+
+ &:before {
+ content: "";
+ }
+
+ &.min {
+ &:before {
+ content: "";
+ }
+ }
+
+ &:hover {
+ background-color: var(--selected);
+ }
+ }
+ }
+
+ .tabs {
+ height: 100%;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+
+ > .col-auto {
+ width: 230px;
+ overflow-x: hidden;
+ overflow-y: overlay;
+ transition: width 0.25s ease-in-out;
+ }
+
+ .tab-content {
+ margin: 0 !important;
+ }
+ }
+
+ .tab-content {
+ overflow-y: overlay;
+ height: 100%;
+ background-color: var(--panelColor2);
+ padding:0px;
+ padding-top: 48px;
+ border-left: 1px solid var(--borderColor);
+ }
+
+ .github-themes-page, .installed-themes-page {
+ .header-text {
+ font-size: 1.25em;
+ }
+ }
+
+ .tab-pane {
+ height:100%;
+ }
+
+ .settings-tab-content {
+ height:100%;
+ }
+
+ &.no-sidebar {
+ .gh-header {
+ >.row {
+ &:last-child {
+ padding-right: 90px;
+ }
+ }
+ }
+ .tab-content {
+ padding-top:0px;
+ }
+
+ .tabs {
+ .nav-pills .nav-link {
+ width: 50px;
+ :nth-child(2) {
+ // font-size: 0px;
+ opacity:0;
+ }
+ }
+ >.col-auto {
+ width: 80px;
+ }
+ }
+ }
+ }
+}
+
+#hid___BV_tab_button__ {
+ display: none;
+}
\ No newline at end of file
diff --git a/src/renderer/main/app.js b/src/renderer/main/app.js
index 476dfa47..5698d739 100644
--- a/src/renderer/main/app.js
+++ b/src/renderer/main/app.js
@@ -7,6 +7,8 @@ import {Events} from './events.js'
import { wsapi } from "./wsapi_interop.js"
import { MusicKitTools } from "./musickittools.js"
import { spawnMica } from "./mica.js"
+import { svgIcon } from './components/svg-icon.js'
+import { sidebarLibraryItem } from './components/sidebar-library-item.js'
// Define window objects
@@ -17,11 +19,22 @@ window.CiderCache = CiderCache
window.CiderFrontAPI = CiderFrontAPI
window.wsapi = wsapi
+if (app.cfg.advanced.disableLogging === true) {
+ window.console = {
+ log: function() {},
+ error: function() {},
+ warn: function() {},
+ assert: function() {},
+ debug: function() {}
+ }
+}
+
+
// Mount Vue to #app
app.$mount("#app")
// Init CiderAudio
-if (app.cfg.advanced.AudioContext){
+if (app.cfg.advanced.AudioContext === true) {
CiderAudio.init()
}
diff --git a/src/renderer/main/components/sidebar-library-item.js b/src/renderer/main/components/sidebar-library-item.js
new file mode 100644
index 00000000..adf31689
--- /dev/null
+++ b/src/renderer/main/components/sidebar-library-item.js
@@ -0,0 +1,46 @@
+import {html} from "../html.js"
+
+export const sidebarLibraryItem = Vue.component("sidebar-library-item", {
+ template: html`
+
+ `,
+ props: {
+ name: {
+ type: String,
+ required: true,
+ },
+ page: {
+ type: String,
+ required: true,
+ },
+ svgIcon: {
+ type: String,
+ required: false,
+ default: "",
+ },
+ svgIconName: {
+ type: String,
+ required: false
+ },
+ cdClick: {
+ type: Function,
+ required: false,
+ },
+ },
+ data: function () {
+ return {
+ app: app,
+ svgIconData: "",
+ };
+ },
+ async mounted() {
+ if (this.svgIcon) {
+ this.svgIconData = this.svgIcon;
+ }
+ },
+ methods: {},
+})
\ No newline at end of file
diff --git a/src/renderer/main/components/svg-icon.js b/src/renderer/main/components/svg-icon.js
new file mode 100644
index 00000000..71ddd29c
--- /dev/null
+++ b/src/renderer/main/components/svg-icon.js
@@ -0,0 +1,22 @@
+import {html} from "../html.js"
+
+export const svgIcon = Vue.component("svg-icon", {
+ template: html`
+
+ `,
+ props: {
+ name: {
+ type: String,
+ required: false
+ },
+ classes: {
+ type: String,
+ required: false
+ },
+ url: {
+ type: String,
+ required: true,
+ default: "./assets/repeat.svg"
+ }
+ }
+})
\ No newline at end of file
diff --git a/src/renderer/main/events.js b/src/renderer/main/events.js
index 52191c5d..e0a3c45c 100644
--- a/src/renderer/main/events.js
+++ b/src/renderer/main/events.js
@@ -24,7 +24,7 @@ const Events = {
// CTRL + R
if (event.keyCode === 82 && event.ctrlKey) {
event.preventDefault()
- bootbox.confirm(app.getLz('term.reload'), (res)=>{
+ app.confirm(app.getLz('term.reload'), (res)=>{
if (res) {
window.location.reload()
}
@@ -69,8 +69,8 @@ const Events = {
// Prevent Scrolling on spacebar
if (event.keyCode === 32 && event.target === document.body) {
event.preventDefault()
- app.SpacePause()
-
+ app.SpacePause()
+
}
});
diff --git a/src/renderer/main/html.js b/src/renderer/main/html.js
new file mode 100644
index 00000000..2b4d140c
--- /dev/null
+++ b/src/renderer/main/html.js
@@ -0,0 +1,3 @@
+export function html (str) {
+ return str[0]
+}
\ No newline at end of file
diff --git a/src/renderer/main/mica.js b/src/renderer/main/mica.js
index cbd346bc..052a1c24 100644
--- a/src/renderer/main/mica.js
+++ b/src/renderer/main/mica.js
@@ -21,22 +21,22 @@ async function spawnMica() {
let lastScreenWidth;
let lastScreenHeight;
- let regen = true;
- let imgSrc = await ipcRenderer.sendSync("get-wallpaper", {
+ let imgSrc = "";
+ let micaCache = await CiderCache.getCache("mica-cache");
+ if (!micaCache) {
+ micaCache = {
+ path: "",
+ data: "",
+ };
+ }
+ if (micaCache.path == imgSrc.path) {
+ imgSrc = micaCache;
+ }else{
+ imgSrc = await ipcRenderer.sendSync("get-wallpaper", {
blurAmount: 256
- });
-
-// let micaCache = await CiderCache.getCache("mica-cache");
-// if (!micaCache) {
-// micaCache = {
-// path: "",
-// data: "",
-// };
-// }
-// if (micaCache.path == imgSrc.path) {
-// regen = false;
-// imgSrc = micaCache;
-// }
+ });
+ CiderCache.putCache("mica-cache", imgSrc);
+ }
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
let img = new Image();
diff --git a/src/renderer/main/vueapp.js b/src/renderer/main/vueapp.js
index 7a8d8922..86dedaa2 100644
--- a/src/renderer/main/vueapp.js
+++ b/src/renderer/main/vueapp.js
@@ -12,6 +12,7 @@ const app = new Vue({
ipcRenderer: ipcRenderer,
cfg: ipcRenderer.sendSync("getStore"),
isDev: ipcRenderer.sendSync("is-dev"),
+ clientPort: ipcRenderer.sendSync("get-port"),
drawertest: false,
platform: "",
mk: {},
@@ -147,6 +148,7 @@ const app = new Vue({
start: 0,
end: 0
},
+ lyricOffset: 0,
v3: {
requestBody: {
platform: "web"
@@ -168,6 +170,7 @@ const app = new Vue({
location: "",
info: {}
},
+ windowState: "normal",
desiredPageTransition: "wpfade_transform",
hideUserInfo: ipcRenderer.sendSync("is-dev") || false,
artworkReady: false,
@@ -215,8 +218,10 @@ const app = new Vue({
audioPlaybackRate: false,
showPlaylist: false,
castMenu: false,
+ pathMenu: false,
moreInfo: false,
airplayPW: false,
+ settings: false
},
socialBadges: {
badgeMap: {},
@@ -243,6 +248,7 @@ const app = new Vue({
notyf: notyf,
idleTimer: null,
idleState: false,
+ appVisible: true
},
watch: {
cfg: {
@@ -274,6 +280,12 @@ const app = new Vue({
}, false)
},
methods: {
+ hotReload() {
+ this.appVisible = false
+ setTimeout(() => {
+ this.appVisible = true
+ }, 1000)
+ },
setWindowHash(route = "") {
window.location.hash = `#${route}`;
},
@@ -325,11 +337,7 @@ const app = new Vue({
let advancedTooltip = this.cfg.audio.dBSPL ? (Number(this.cfg.audio.dBSPLcalibration) + (Math.log10(this.mk.volume) * 20)).toFixed(2) + ' dB SPL' : (Math.log10(this.mk.volume) * 20).toFixed(2) + ' dBFS'
return this.cfg.audio.advanced ? advancedTooltip : (this.mk.volume * 100).toFixed(0) + '%'
},
- mainMenuVisibility(val, isContextMenu) {
- if (this.chrome.sidebarCollapsed && !isContextMenu) {
- this.chrome.sidebarCollapsed = false
- return
- }
+ mainMenuVisibility(val) {
if (val) {
(this.mk.isAuthorized) ? this.chrome.menuOpened = !this.chrome.menuOpened : false;
if (!this.mk.isAuthorized) {
@@ -392,6 +400,46 @@ const app = new Vue({
return message
}
},
+ getProfileLz(type, name) { // For Spatial and CAR.
+ let result = "";
+
+ // Hard-coded shiz
+ switch (name) {
+ case "Maikiwi":
+ return "Maikiwi";
+ break;
+
+ case "Maikiwi+":
+ return "Maikiwi+";
+ break;
+
+ case "Minimal+":
+ return this.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal') + "+";
+ break;
+
+ case "live":
+ return "LIVE";
+ break;
+ }
+ switch (type) {
+ case "CAR":
+ result = this.getLz('settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.' + name);
+ if (result === "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode." + name) {
+ return name;
+ }
+ else {return result;}
+ break;
+ case "CTS":
+ result = this.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.' + name.toLowerCase());
+ if (result === "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile." + name.toLowerCase()) {
+ return name;
+ }
+ else {return result;}
+ break;
+ default:
+ return name;
+ }
+ },
setLzManual() {
app.$data.library.songs.sortingOptions = {
"albumName": app.getLz('term.sortBy.album'),
@@ -440,6 +488,9 @@ const app = new Vue({
}
})
},
+ quit() {
+ ipcRenderer.invoke("quit-app")
+ },
async openAppleMusicURL(url) {
let properties = MusicKit.formattedMediaURL(url)
let item = {
@@ -695,6 +746,9 @@ const app = new Vue({
} catch (err) {
}
+ // Used to get a scale factor for the window for CSS scaling
+ window.addEventListener("resize", e => this.setWindowScaleFactor())
+ this.setWindowScaleFactor()
this.mk._bag.features['seamless-audio-transitions'] = this.cfg.audio.seamless_audio
this.mk._bag.features["broadcast-radio"] = true
this.mk._services.apiManager.store.storekit._restrictedEnabled = false
@@ -824,6 +878,10 @@ const app = new Vue({
MusicKit.getInstance().videoContainerElement = document.getElementById("apple-music-video-player")
+ ipcRenderer.on('setStoreValue', (e, key, value) => {
+ app.cfg[key] = value
+ })
+
ipcRenderer.on('theme-update', async (event, arg) => {
await less.refresh(true, true, true)
self.setTheme(self.cfg.visual.theme, true)
@@ -846,10 +904,14 @@ const app = new Vue({
})
ipcRenderer.on('getUpdatedLocalList', (event, data) => {
- console.log("cider-local", data);
+ // console.log("cider-local", data);
this.library.localsongs = data;
})
+ ipcRenderer.on('window-state-changed', (event, data) => {
+ this.chrome.windowState = data
+ })
+
ipcRenderer.on('SoundCheckTag', (event, tag) => {
// let replaygain = self.parseSCTagToRG(tag)
try {
@@ -869,6 +931,7 @@ const app = new Vue({
try {
//CiderAudio.audioNodes.gainNode.gain.value = (Math.min(Math.pow(10, (replaygain.gain / 20)), (1 / replaygain.peak)))
CiderAudio.audioNodes.gainNode.gain.value = gain
+ CiderAudio.hierarchical_loading();
} catch (e) {
}
}
@@ -896,13 +959,19 @@ const app = new Vue({
}
});
+ this.mk.addEventListener(MusicKit.Events.playbackProgressDidChange, () => {
+ if (self.mk.currentPlaybackProgress === (app.cfg.connectivity.lastfm.scrobble_after / 100)) {
+ ipcRenderer.send('lastfm:scrobbleTrack', MusicKitInterop.getAttributes());
+ }
+ })
+
this.mk.addEventListener(MusicKit.Events.playbackStateDidChange, (event) => {
ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes());
document.body.setAttribute("playback-state", event.state == 2 ? "playing" : "paused")
})
this.mk.addEventListener(MusicKit.Events.playbackTimeDidChange, (a) => {
- self.lyriccurrenttime = self.mk.currentPlaybackTime
+ // self.lyriccurrenttime = self.mk.currentPlaybackTime - app.lyricOffset
this.currentSongInfo = a
self.playerLCD.playbackDuration = (self.mk.currentPlaybackTime)
// wsapi
@@ -922,10 +991,10 @@ const app = new Vue({
app.mk.nowPlayingItem.attributes.name = e.title
app.mk.nowPlayingItem.attributes.artistName = e.performer
app.mk.nowPlayingItem.attributes.albumName = e.album
- if(e.links[1]) {
+ if (e.links[1]) {
app.currentArtUrl = e.links[1].url
app.currentArtUrlRaw = e.links[1].url
- }else{
+ } else {
app.currentArtUrl = e.links[0].url
app.currentArtUrlRaw = e.links[0].url
}
@@ -937,50 +1006,63 @@ const app = new Vue({
if (self.$refs.queue) {
self.$refs.queue.updateQueue();
}
- this.currentSongInfo = a
-
- if (app.cfg.advanced.AudioContext) {
- try {
- if (app.mk.nowPlayingItem.flavor.includes("64")) {
- if (localStorage.getItem("playingBitrate") !== "64") {
- localStorage.setItem("playingBitrate", "64")
- CiderAudio.hierarchical_loading();
- }
- } else if (app.mk.nowPlayingItem.flavor.includes("256")) {
- if (localStorage.getItem("playingBitrate") !== "256") {
- localStorage.setItem("playingBitrate", "256")
- CiderAudio.hierarchical_loading();
- }
- } else {
- localStorage.setItem("playingBitrate", "256")
- CiderAudio.hierarchical_loading();
- }
- } catch (e) {
+ this.currentSongInfo = a;
+ if (this.currentSongInfo === null || this.currentSongInfo === undefined) { return; } // EVIL EMPTY OBJECTS BE GONE
+ let localFiles = false;
+ try {
+ if (app.mk.nowPlayingItem.flavor.includes("64") && app.mk.nowPlayingItem.flavor.includes(":")) {
+ localStorage.setItem("playingBitrate", "64")
+ } else if (app.mk.nowPlayingItem.flavor.includes("256") && app.mk.nowPlayingItem.flavor.includes(":")) {
localStorage.setItem("playingBitrate", "256")
- CiderAudio.hierarchical_loading();
+ } else {
+ localFiles = true;
+ localStorage.setItem("playingBitrate", app.mk.nowPlayingItem.flavor)
}
+ } catch (e) {
+ localFiles = true;
+ try {localStorage.setItem("playingBitrate", app.mk.nowPlayingItem.flavor)}
+ catch(e) {}
}
-
- if (app.cfg.audio.normalization) {
+ if (!app.cfg.audio.normalization || app.cfg.advanced.AudioContext === true) { CiderAudio.hierarchical_loading(); }
+
+ else {
// get unencrypted audio previews to get SoundCheck's normalization tag
try {
let previewURL = null
try {
previewURL = app.mk.nowPlayingItem.previewURL
} catch (e) {
+ if (e instanceof TypeError === false) { console.debug("[Cider][MaikiwiSoundCheck] normalizer function err: " + e) }
+ else {
+ if (localFiles === true) {CiderAudio.audioNodes.gainNode.gain.value = 0.8222426499470}
+ }
}
if (previewURL == null && ((app.mk.nowPlayingItem?._songId ?? (app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id)) != -1)) {
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem?._songId ?? (app.mk.nowPlayingItem["songId"] ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id)}`).then((response) => {
- previewURL = response.data.data[0].attributes.previews[0].url
- if (previewURL)
+ try {previewURL = response.data.data[0].attributes.previews[0].url;} catch(e) {
+ if (e instanceof TypeError === false) { console.debug("[Cider][MaikiwiSoundCheck] normalizer function err: " + e) }
+ else {
+ if (localFiles === true) {CiderAudio.audioNodes.gainNode.gain.value = 0.8222426499470}}
+ }
+ if (previewURL) {
+ console.debug("[Cider][MaikiwiSoundCheck] previewURL response.data.data[0].attributes.previews[0].url: " + previewURL)
ipcRenderer.send('getPreviewURL', previewURL)
+ }
+ else {
+ if (localFiles === true) {CiderAudio.audioNodes.gainNode.gain.value = 0.8222426499470}
+ }
})
} else {
- if (previewURL)
- ipcRenderer.send('getPreviewURL', previewURL)
- }
+ if (previewURL) {
+ console.debug("[Cider][MaikiwiSoundCheck] previewURL in app.mk.nowPlayingItem.previewURL: " + previewURL)
+ ipcRenderer.send('getPreviewURL', previewURL)}
+ }
} catch (e) {
+ if (e instanceof TypeError === false) { console.debug("[Cider][MaikiwiSoundCheck] normalizer function err: " + e) }
+ else {
+ if (localFiles === true) {CiderAudio.audioNodes.gainNode.gain.value = 0.8222426499470}
+ }
}
}
@@ -1056,6 +1138,20 @@ const app = new Vue({
if (this.cfg.general.themeUpdateNotification && !this.isDev) {
this.checkForThemeUpdates()
}
+
+ ipcRenderer.invoke("scanLibrary")
+ },
+ setWindowScaleFactor() {
+ let scale = window.devicePixelRatio * window.innerWidth / 1280 * window.innerHeight / 720
+ let desiredScale = clamp(parseFloat(app.cfg.visual.maxElementScale == -1 ? 1.5 : app.cfg.visual.maxElementScale), 1, 1.5)
+ app.$store.state.windowRelativeScale = scale
+ if(scale <= 1) {
+ scale = 1
+ }else if(scale >= desiredScale) {
+ scale = desiredScale
+ }
+ document.documentElement.style
+ .setProperty('--windowRelativeScale', scale);
},
showFoo(querySelector, time) {
clearTimeout(this.idleTimer);
@@ -1086,7 +1182,7 @@ const app = new Vue({
message: `[Themes] ${theme.name} has an update available.`
})
notify.on("click", () => {
- app.appRoute("themes-github")
+ app.openSettingsPage("github-themes")
notyf.dismiss(notify)
})
}
@@ -1170,11 +1266,11 @@ const app = new Vue({
} else if (this.cfg.visual.directives[directive]) {
return this.cfg.visual.directives[directive]
} else {
- return ""
+ return false
}
},
unauthorize() {
- bootbox.confirm(app.getLz('term.confirmLogout'), function (result) {
+ this.confirm(app.getLz('term.confirmLogout'), function (result) {
if (result) {
app.mk.unauthorize()
document.location.reload()
@@ -1295,7 +1391,7 @@ const app = new Vue({
results.forEach(result => {
try {
if (result.relationships?.catalog?.data[0]?.attributes?.inFavorites) {
- if(!favs.includes(result.relationships?.catalog?.data[0].id)) {
+ if (!favs.includes(result.relationships?.catalog?.data[0].id)) {
favs.push(result.relationships?.catalog?.data[0].id)
}
}
@@ -1308,8 +1404,8 @@ const app = new Vue({
return favs
},
async setArtistFavorite(id, val = true) {
- if(val) {
- if(!app.cfg.home.followedArtists.includes(id)) {
+ if (val) {
+ if (!app.cfg.home.followedArtists.includes(id)) {
app.cfg.home.followedArtists.push(id)
}
await app.mk.api.v3.music(`/v1/me/favorites`, {
@@ -1322,8 +1418,8 @@ const app = new Vue({
method: "POST"
}
})
- }else{
- if(app.cfg.home.followedArtists.includes(id)) {
+ } else {
+ if (app.cfg.home.followedArtists.includes(id)) {
app.cfg.home.followedArtists.splice(app.cfg.home.followedArtists.indexOf(id), 1)
}
await app.mk.api.v3.music(`/v1/me/favorites`, {
@@ -1452,6 +1548,12 @@ const app = new Vue({
action: () => {
this.newPlaylistFolder()
}
+ },
+ {
+ name: app.getLz("action.refresh"),
+ action: () => {
+ this.refreshPlaylists()
+ }
}
]
}
@@ -1549,22 +1651,24 @@ const app = new Vue({
},
deletePlaylist(id) {
let self = this
- if (confirm(app.getLz('term.deletePlaylist'))) {
- app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, {}, {
- fetchOptions: {
- method: "DELETE"
- }
- }).then(res => {
- // remove this playlist from playlists.listing if it exists
- let found = self.playlists.listing.find(item => item.id == id)
- if (found) {
- self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1)
- }
- setTimeout(() => {
- app.refreshPlaylists(false, false);
- }, 8000);
- })
- }
+ this.confirm(app.getLz('term.deletePlaylist'), (ok) => {
+ if (ok) {
+ app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, {}, {
+ fetchOptions: {
+ method: "DELETE"
+ }
+ }).then(res => {
+ // remove this playlist from playlists.listing if it exists
+ let found = self.playlists.listing.find(item => item.id == id)
+ if (found) {
+ self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1)
+ }
+ setTimeout(() => {
+ app.refreshPlaylists(false, false);
+ }, 8000);
+ })
+ }
+ });
},
/**
* @param {string} url, href for the initial request
@@ -1888,7 +1992,7 @@ const app = new Vue({
this.routeView(item.relationships.contents.data[0])
} else if (item.attributes?.link?.url != null) {
if (item.attributes.link.url.includes("viewMultiRoom")) {
- const params = new Proxy(new URLSearchParams(item.attributes.link.url), {
+ const params = new Proxy(new URLSearchParams(new URL(item.attributes.link.url).search), {
get: (searchParams, prop) => searchParams.get(prop),
});
id = params.fcId
@@ -1902,12 +2006,30 @@ const app = new Vue({
})
return;
+ } else if (item.attributes.link.url.includes("viewFeature")) {
+ const params = new Proxy(new URLSearchParams(new URL(item.attributes.link.url).search), {
+ get: (searchParams, prop) => searchParams.get(prop),
+ });
+ id = params.id
+ app.mk.api.v3.music(`/v1/editorial/vn/multiplex/${id}?art%5Burl%5D=f&format%5Bresources%5D=map&platform=web`).then(
+ (data) => {
+ let item = data.data.results?.target ?? []
+ app.routeView(item)
+ }
+ )
} else {
window.open(item.attributes.link.url)
}
}
- } else if (kind == "multirooms") {
+ } else if (kind == "multiplex") {
+ app.mk.api.v3.music(`/v1/editorial/vn/multiplex/${id}?art%5Burl%5D=f&format%5Bresources%5D=map&platform=web`).then(
+ (data) => {
+ let item = data.data.results?.target ?? []
+ app.routeView(item)
+ }
+ )
+ }if (kind == "multirooms") {
app.getTypeFromID("multiroom", id, false, {
platform: "web",
extend: "editorialArtwork,uber,lockupStyle"
@@ -1935,7 +2057,26 @@ const app = new Vue({
});
window.location.hash = `${kind}/${id}`
document.querySelector("#app-content").scrollTop = 0
- } else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) {
+ } else if (kind.toString().includes("social-profiles")) {
+ app.page = (kind) + "_" + (id);
+ app.mk.api.v3.music(
+ `/v1/social/${app.mk.storefrontId}/social-profiles/${id}`,
+ {include:"shared-playlists"}).then(
+ (data) => {
+ console.log(data)
+ app.showingPlaylist = data.data?.data[0]
+ window.location.hash = `${kind}/${id}`
+ document.querySelector("#app-content").scrollTop = 0
+ }
+ )
+ // app.getTypeFromID((kind), (id), (isLibrary), {
+ // extend: "editorialVideo",
+ // include: 'grouping,playlists',
+ // views: 'top-releases,latest-releases,top-artists'
+ // });
+
+ }
+ else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) {
let params = {
extend: "offers,editorialVideo",
"views": "appears-on,more-by-artist,related-videos,other-versions,you-might-also-like,video-extras,audio-extras",
@@ -1948,7 +2089,7 @@ const app = new Vue({
params["fields[artists]"] = "name,url"
params["omit[resource]"] = "autos"
params["meta[albums:tracks]"] = 'popularity'
- params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright"
+ params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright,genreNames"
}
if (kind.includes("playlist") || kind.includes("album")) {
app.page = (kind) + "_" + (id);
@@ -2005,8 +2146,8 @@ const app = new Vue({
async getNowPlayingItemDetailed(target) {
let nowPlayingItem = JSON.parse(JSON.stringify(this.mk.nowPlayingItem))
- if(nowPlayingItem.type === "radioStation" && app.mk.nowPlayingItem.id !== -1) {
- nowPlayingItem.playParams = {kind: "songs"}
+ if (nowPlayingItem.type === "radioStation" && app.mk.nowPlayingItem.id !== -1) {
+ nowPlayingItem.playParams = { kind: "songs" }
nowPlayingItem.attributes.playParams.catalogId = app.mk.nowPlayingItem.id
nowPlayingItem.attributes.playParams.id = app.mk.nowPlayingItem.id
nowPlayingItem.id = app.mk.nowPlayingItem.id
@@ -2193,9 +2334,13 @@ const app = new Vue({
searchLibrarySongs() {
let self = this
let prefs = this.cfg.libraryPrefs.songs
- let albumAdded = self.library?.albums?.listing?.map(function (i) {
- return { [i.id]: i.attributes?.dateAdded }
- })
+
+ const albumAdded = {}
+
+ for (const listing of self.library?.albums?.listing ?? []) {
+ albumAdded[listing.id] = listing.attributes?.dateAdded
+ }
+
let startTime = new Date().getTime()
function sortSongs() {
@@ -2207,12 +2352,11 @@ const app = new Vue({
if (prefs.sort == "genre") {
aa = a.attributes.genreNames[0]
bb = b.attributes.genreNames[0]
- }
- if (prefs.sort == "dateAdded") {
- let albumida = a.relationships?.albums?.data[0]?.id ?? '1970-01-01T00:01:01Z'
- let albumidb = b.relationships?.albums?.data[0]?.id ?? '1970-01-01T00:01:01Z'
- aa = startTime - new Date(((albumAdded.find(i => i[albumida])) ?? [])[albumida] ?? '1970-01-01T00:01:01Z').getTime()
- bb = startTime - new Date(((albumAdded.find(i => i[albumidb])) ?? [])[albumidb] ?? '1970-01-01T00:01:01Z').getTime()
+ } else if (prefs.sort == "dateAdded") {
+ let albumida = a.relationships?.albums?.data[0]?.id
+ let albumidb = b.relationships?.albums?.data[0]?.id
+ aa = startTime - new Date(albumAdded[albumida] ?? '1970-01-01T00:01:01Z').getTime()
+ bb = startTime - new Date(albumAdded[albumidb] ?? '1970-01-01T00:01:01Z').getTime()
}
if (aa == null) {
aa = ""
@@ -2974,7 +3118,10 @@ const app = new Vue({
const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : '');
const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : '');
const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1);
- const id = encodeURIComponent((this.mk.nowPlayingItem != null) ? app.mk.nowPlayingItem._songId ?? (app.mk.nowPlayingItem["songId"] ?? '') : '');
+ let id = null; let vanity_id = null;
+ if (this.mk.nowPlayingItem != null && app.mk.nowPlayingItem.localFilesMetadata != null) {const id = encodeURIComponent('')}
+ else {id = encodeURIComponent((this.mk.nowPlayingItem != null) ? (app.mk.nowPlayingItem._songId) ?? (app.mk.nowPlayingItem["songId"] ?? '') : '');}
+
let lrcfile = "";
let richsync = [];
const lang = app.cfg.lyrics.mxm_language // translation language
@@ -2982,67 +3129,13 @@ const app = new Vue({
return Math.random().toString(36).replace(/[^a-z]+/g, '').slice(2, 10);
}
- /* get token */
- function getToken(mode, track, artist, songid, lang, time, id) {
- if (attempt > 2) {
- app.loadNeteaseLyrics();
- // app.loadAMLyrics();
- } else {
- attempt = attempt + 1;
- let url = "https://apic-desktop.musixmatch.com/ws/1.1/token.get?app_id=web-desktop-app-v1.0&t=" + revisedRandId();
- let req = new XMLHttpRequest();
- req.overrideMimeType("application/json");
- req.open('GET', url, true);
- req.setRequestHeader("authority", "apic-desktop.musixmatch.com");
- req.onload = function () {
- try {
- let jsonResponse = JSON.parse(this.responseText);
- let status2 = jsonResponse["message"]["header"]["status_code"];
- if (status2 == 200) {
- let token = jsonResponse["message"]["body"]["user_token"] ?? '';
- if (token != "" && token != "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") {
- console.debug('200 token', mode);
- // token good
- app.mxmtoken = token;
- if (mode == 1) {
- getMXMSubs(track, artist, app.mxmtoken, lang, time, id);
- } else {
- getMXMTrans(songid, lang, app.mxmtoken);
- }
- } else {
- console.debug('fake 200 token');
- getToken(mode, track, artist, songid, lang, time)
- }
- } else {
- // console.log('token 4xx');
- getToken(mode, track, artist, songid, lang, time)
- }
- } catch (e) {
- console.log('error');
- app.loadQQLyrics();
- //app.loadAMLyrics();
- }
- };
- req.onerror = function () {
- console.log('error');
- app.loadQQLyrics();
- // app.loadAMLyrics();
- };
- req.send();
- }
- }
-
- function getMXMSubs(track, artist, token, lang, time, id) {
- let usertoken = encodeURIComponent(token);
- let richsyncQuery = (app.cfg.lyrics.mxm_karaoke) ? "&optional_calls=track.richsync" : ""
- let timecustom = (!time || (time && time < 0)) ? '' : `&f_subtitle_length=${time}&q_duration=${time}&f_subtitle_length_max_deviation=40`;
- let itunesid = (id && id != "") ? `&track_itunes_id=${id}` : '';
- let url = "https://apic-desktop.musixmatch.com/ws/1.1/macro.subtitles.get?format=json&namespace=lyrics_richsynched" + richsyncQuery + "&subtitle_format=lrc&q_artist=" + artist + "&q_track=" + track + itunesid + "&usertoken=" + usertoken + timecustom + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId();
+ function getMXMSubs(track, artist, lang, time, id) {
+ let richsyncQuery = app.cfg.lyrics.mxm_karaoke
+ let itunesid = (id && id != "") ? id : ''; // Mode 1 -> Subs
+ let url = "https://api.cider.sh/v1/lyrics?" + "mode=1" + "&richsyncQuery=" + richsyncQuery + "&track=" + track + "&artist=" + artist + "&songID=" + itunesid + "&source=mxm" + "&lang=" + lang + "&time=" + time;
let req = new XMLHttpRequest();
req.overrideMimeType("application/json");
- req.open('GET', url, true);
- req.setRequestHeader("authority", "apic-desktop.musixmatch.com");
req.onload = function () {
try {
let jsonResponse = JSON.parse(this.responseText);
@@ -3050,11 +3143,13 @@ const app = new Vue({
let status1 = jsonResponse["message"]["header"]["status_code"];
if (status1 == 200) {
- let id = '';
+ let id, songLang = '';
try {
if (jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["header"]["status_code"] == 200 && jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["header"]["status_code"] == 200) {
id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] ?? '';
lrcfile = jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["body"]["subtitle_list"][0]["subtitle"]["subtitle_body"];
+ vanity_id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["commontrack_vanity_id"];
+ songLang = jsonResponse["message"]["body"]["macro_calls"]["track.lyrics.get"]["message"]["body"]["lyrics"]["lyrics_language_description"];
try {
let lrcrich = jsonResponse["message"]["body"]["macro_calls"]["track.richsync.get"]["message"]["body"]["richsync"]["richsync_body"];
@@ -3069,7 +3164,7 @@ const app = new Vue({
// app.loadAMLyrics()
} else {
if (richsync == [] || richsync.length == 0) {
- console.log("ok");
+ console.log("musixmatch worki");
// process lrcfile to json here
app.lyricsMediaItem = lrcfile
let u = app.lyricsMediaItem.split(/[\r\n]/);
@@ -3110,24 +3205,21 @@ const app = new Vue({
});
app.lyrics = preLrc;
}
- if (lrcfile != null && lrcfile != '') {
- // load translation
- getMXMTrans(id, lang, token);
- } else {
- // app.loadAMLyrics()
- app.loadQQLyrics();
+
+ // Load translation
+ if (songLang.toLowerCase() !== lang){
+ getMXMTrans(lang, vanity_id);
}
+
}
} catch (e) {
console.log(e);
app.loadQQLyrics();
// app.loadAMLyrics()
}
- } else { //4xx rejected
- getToken(1, track, artist, '', lang, time);
- }
+ }
} catch (e) {
- console.log(e);
+ console.error(e);
app.loadQQLyrics();
//app.loadAMLyrics()
}
@@ -3137,59 +3229,57 @@ const app = new Vue({
console.log('error');
// app.loadAMLyrics();
};
+ req.open('POST', url, true);
req.send();
}
- function getMXMTrans(id, lang, token) {
- if (lang != "disabled" && id != '') {
- let usertoken = encodeURIComponent(token);
- let url2 = "https://apic-desktop.musixmatch.com/ws/1.1/crowd.track.translations.get?translation_fields_set=minimal&selected_language=" + lang + "&track_id=" + id + "&comment_format=text&part=user&format=json&usertoken=" + usertoken + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId();
- let req2 = new XMLHttpRequest();
- req2.overrideMimeType("application/json");
- req2.open('GET', url2, true);
- req2.setRequestHeader("authority", "apic-desktop.musixmatch.com");
- req2.onload = function () {
- try {
- let jsonResponse2 = JSON.parse(this.responseText);
- console.log(jsonResponse2);
- let status2 = jsonResponse2["message"]["header"]["status_code"];
- if (status2 == 200) {
- try {
- let preTrans = []
- let u = app.lyrics;
- let translation_list = jsonResponse2["message"]["body"]["translations_list"];
- if (translation_list.length > 0) {
- for (var i = 0; i < u.length - 1; i++) {
- preTrans[i] = ""
- for (var trans_line of translation_list) {
- if (u[i].line == " " + trans_line["translation"]["matched_line"] || u[i].line == trans_line["translation"]["matched_line"]) {
- u[i].translation = trans_line["translation"]["description"];
- break;
- }
- }
- }
- app.lyrics = u;
+ function getMXMTrans(lang, vanity_id) {
+ try {
+ if (lang !== "disabled" && vanity_id !== '') { // Mode 2 -> Trans
+ let url = "https://api.cider.sh/v1/lyrics?mode=2&vanityID=" + vanity_id +'&source=mxm&lang=' + lang;
+ let req = new XMLHttpRequest();
+ req.overrideMimeType("application/json");
+ req.onload = function () {
+ if (req.status == 200) { // If it's not 200, 237890127389012 things could go wrong and I don't really care what those things are.
+ let jsonResponse = JSON.parse(this.responseText);
+ let applied = 0;
+ for (let i = 0; applied < app.lyrics.length; i++) {
+ if (app.lyrics[applied].line.trim() === "") {applied+=1;}
+ if (app.lyrics[applied].line.trim() === jsonResponse[i]) {
+ // Do Nothing
+ applied +=1;
}
- } catch (e) {
- /// not found trans -> ignore
+ else {
+ if (app.lyrics[applied].line === "lrcInstrumental") {
+ if (app.lyrics[applied+1].line.trim() === jsonResponse[i]) {
+ // Do Nothing
+ applied +=2;
+ }
+ else {
+ app.lyrics[applied+1].translation = jsonResponse[i];
+ applied +=2;
+ }
+ }
+ else {
+ app.lyrics[applied].translation = jsonResponse[i];
+ applied +=1;
+ }
+ }
}
- } else { //4xx rejected
- getToken(2, '', '', id, lang, '');
}
- } catch (e) {
}
+ req.onerror = function () {
+ console.log("MXM Translation somehow died. Don't need to know why.")
+ };
+ req.open('POST', url, true);
+ req.send();
}
- req2.send();
- }
+ } catch (e) {console.debug("Error while parsing MXM Trans: " + e)}
}
if (track != "" & track != "No Title Found") {
- if (app.mxmtoken != null && app.mxmtoken != '') {
- getMXMSubs(track, artist, app.mxmtoken, lang, time, id)
- } else {
- getToken(1, track, artist, '', lang, time);
- }
+ getMXMSubs(track, artist, lang, time, id);
}
},
loadNeteaseLyrics() {
@@ -3308,6 +3398,7 @@ const app = new Vue({
translation: ''
});
app.lyrics = preLrc.reverse();
+ if (app.lyrics[5].line == "") {app.loadNeteaseLyrics();} // Detect incomplete QQ lyrics.
} catch (e) {
console.log(e)
app.loadNeteaseLyrics();
@@ -3473,7 +3564,15 @@ const app = new Vue({
console.log(truekind, id)
try {
- if (app.library.songs.displayListing.length > childIndex && parent == "librarysongs") {
+ if (parent == 'playlist:ciderlocal'){
+ let u = app.library.localsongs.map(i => {return i.id})
+ app.mk.setQueue({"episodes" : u}).then(()=>{
+ let id = app.mk.queue._itemIDs.findIndex(element => element == item.id);
+ app.mk.changeToMediaAtIndex(id)
+ })
+
+ }
+ else if (app.library.songs.displayListing.length > childIndex && parent == "librarysongs") {
console.log(item)
if (item && ((app.library.songs.displayListing[childIndex].id != item.id))) {
childIndex = app.library.songs.displayListing.indexOf(item)
@@ -3777,7 +3876,7 @@ const app = new Vue({
type += "s"
}
type = type.replace("library-", "")
- let id = item.attributes.playParams.catalogId ?? item.attributes.playParams.id ?? item.id
+ let id = item.attributes.playParams?.catalogId ?? item.attributes.playParams.id ?? item.id
let index = types.findIndex(function (type) {
return type.type == this
@@ -3923,9 +4022,8 @@ const app = new Vue({
this.currentArtUrl = this.mk.nowPlayingItem._assets[0].artworkURL
}
try {
- document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
- } catch (e) {
- }
+ // document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
+ } catch (e) {}
} else {
let data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`);
data = data.data.data[0];
@@ -3937,14 +4035,14 @@ const app = new Vue({
}
ipcRenderer.send('updateRPCImage', this.currentArtUrl ?? '');
try {
- document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
+ // document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
} catch (e) {
}
} else {
this.currentArtUrlRaw = ''
this.currentArtUrl = '';
try {
- document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
+ // document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
} catch (e) {
}
}
@@ -4318,7 +4416,7 @@ const app = new Vue({
"name": app.getLz('settings.option.audio.audioLab'),
"hidden": true,
"action": function () {
- app.appRoute('audiolabs')
+ app.openSettingsPage('audiolabs')
}
},
]
@@ -4344,7 +4442,7 @@ const app = new Vue({
try {
// if its a radio station, then change the attributes to match a song
const nowPlayingItem = JSON.parse(JSON.stringify(this.mk.nowPlayingItem))
- if(nowPlayingItem.type == "radioStation" && app.mk.nowPlayingItem.id != -1) {
+ if (nowPlayingItem.type == "radioStation" && app.mk.nowPlayingItem.id != -1) {
nowPlayingItem.type = "song"
nowPlayingItem.attributes.playParams.catalogId = app.mk.nowPlayingItem.id
nowPlayingItem.attributes.playParams.id = app.mk.nowPlayingItem.id
@@ -4377,36 +4475,43 @@ const app = new Vue({
}
},
- LastFMDeauthorize() {
- ipcRenderer.invoke('setStoreValue', 'lastfm.enabled', false).catch((e) => console.error(e));
- ipcRenderer.invoke('setStoreValue', 'lastfm.auth_token', '').catch((e) => console.error(e));
- app.cfg.lastfm.auth_token = "";
- app.cfg.lastfm.enabled = false;
- const element = document.getElementById('lfmConnect');
- element.innerHTML = app.getLz('term.connect');
- element.onclick = app.LastFMAuthenticate;
- },
- LastFMAuthenticate() {
- console.log("[LastFM] Received LastFM authentication callback")
- const element = document.getElementById('lfmConnect');
- // new key : f9986d12aab5a0fe66193c559435ede3
- window.open('https://www.last.fm/api/auth?api_key=f9986d12aab5a0fe66193c559435ede3&cb=cider://auth/lastfm');
- element.innerText = app.getLz('term.connecting') + '...';
-
- /* Just a timeout for the button */
- setTimeout(() => {
- if (element.innerText === app.getLz('term.connecting') + '...') {
- element.innerText = app.getLz('term.connect');
- console.warn('[LastFM] Attempted connection timed out.');
- }
- }, 20000);
-
- ipcRenderer.on('LastfmAuthenticated', function (_event, lfmAuthKey) {
- app.cfg.lastfm.auth_token = lfmAuthKey;
- app.cfg.lastfm.enabled = true;
- element.innerHTML = `${app.getLz('term.disconnect')}\n(${app.getLz('term.authed')}: ${lfmAuthKey})
`;
- element.onclick = app.LastFMDeauthorize;
- });
+ openSettingsPage(page) {
+ switch (page) {
+ case "general":
+ this.$store.state.pageState.settings.currentTabIndex = 0
+ break;
+ case "audio":
+ this.$store.state.pageState.settings.currentTabIndex = 1
+ break;
+ case "audiolabs":
+ this.$store.state.pageState.settings.currentTabIndex = 2
+ break;
+ case "styles":
+ this.$store.state.pageState.settings.currentTabIndex = 3
+ break;
+ case "visual":
+ this.$store.state.pageState.settings.currentTabIndex = 4
+ break;
+ case "github-plugins":
+ this.$store.state.pageState.settings.currentTabIndex = 5
+ break;
+ case "lyrics":
+ this.$store.state.pageState.settings.currentTabIndex = 6
+ break;
+ case "connectivity":
+ this.$store.state.pageState.settings.currentTabIndex = 7
+ break;
+ case "advanced":
+ this.$store.state.pageState.settings.currentTabIndex = 8
+ break;
+ case "keybindings":
+ this.$store.state.pageState.settings.currentTabIndex = 9
+ break;
+ case "github-themes":
+ this.$store.state.pageState.settings.currentTabIndex = 10
+ break;
+ }
+ app.modals.settings = true
},
fullscreen(flag) {
this.fullscreenState = flag;
@@ -4619,6 +4724,29 @@ const app = new Vue({
app.mk._services.mediaItemPlayback._currentPlayer._playAssetURL(src, false)
}
}
+ },
+ confirm(message, callback) {
+ bootbox.confirm(this.getBootboxParams(null, message, callback));
+ },
+ prompt(title, callback) {
+ bootbox.prompt(this.getBootboxParams(title, null, callback));
+ },
+ getBootboxParams(title, message, callback) {
+ return {
+ title: title,
+ message: message,
+ buttons: {
+ confirm: {
+ label: app.getLz('dialog.ok'),
+ },
+ cancel: {
+ label: app.getLz('dialog.cancel'),
+ },
+ },
+ callback: function (result) {
+ if (callback) callback(result);
+ },
+ }
}
}
})
diff --git a/src/renderer/main/vuex-store.js b/src/renderer/main/vuex-store.js
index f7c0b0be..8263f065 100644
--- a/src/renderer/main/vuex-store.js
+++ b/src/renderer/main/vuex-store.js
@@ -1,5 +1,6 @@
const store = new Vuex.Store({
state: {
+ windowRelativeScale: 1,
library: {
// songs: ipcRenderer.sendSync("get-library-songs"),
// albums: ipcRenderer.sendSync("get-library-albums"),
@@ -12,6 +13,10 @@ const store = new Vuex.Store({
nextUrl: null,
items: [],
size: "normal"
+ },
+ settings: {
+ currentTabIndex: 0,
+ fullscreen: false
}
},
artwork: {
diff --git a/src/renderer/style.less b/src/renderer/style.less
index 5d45481c..0a8cfb71 100644
--- a/src/renderer/style.less
+++ b/src/renderer/style.less
@@ -14,62 +14,65 @@
@import url("less/pages.less");
:root {
- --appleEase: cubic-bezier(0.42, 0, 0.58, 1);
- --mediaItemShadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%);
- --mediaItemShadow-Shadow: 0 8px 40px rgb(0 0 0 / 0.55);
+ --windowRelativeScale : 1;
+ --appleEase : cubic-bezier(0.42, 0, 0.58, 1);
+ --borderColor : rgb(200 200 200 / 16%);
+ --mediaItemShadow : inset 0px 0px 0px 1px rgb(200 200 200 / 16%);
+ --mediaItemShadow-Shadow : 0 8px 40px rgb(0 0 0 / 0.55);
--mediaItemShadow-ShadowSubtle: 0 4px 14px rgb(0 0 0 / 10%);
- --ciderShadow-Generic: var(--mediaItemShadow), 0 8px 40px rgb(0 0 0 / 0.55);
- --mediaItemRadius: 8px;
- --mediaItemRadiusSmall: 6px;
- --mediaItemRadiusMedium: 8px;
- --mediaItemRadiusRound: 100%;
- --panelRadius: 10px;
- --contentInnerPadding: 16px;
- --navbarHeight1: 48px;
- --navbarHeight2: 0px;
- --navbarHeight: calc(var(--navbarHeight1) + var(--navbarHeight2));
- --selected: rgb(130 130 130 / 30%);
- --selected-click: rgb(80 80 80 / 30%);
- --hover: rgb(200 200 200 / 10%);
+ --ciderShadow-Generic : var(--mediaItemShadow), 0 8px 40px rgb(0 0 0 / 0.55);
+ --mediaItemRadius : 8px;
+ --mediaItemRadiusSmall : 6px;
+ --mediaItemRadiusMedium : 8px;
+ --mediaItemRadiusRound : 100%;
+ --panelRadius : 10px;
+ --contentInnerPadding : 16px;
+ --navbarHeight1 : 48px;
+ --navbarHeight2 : 0px;
+ --navbarHeight : calc(var(--navbarHeight1) + var(--navbarHeight2));
+ --selected : rgb(130 130 130 / 30%);
+ --selected-click : rgb(80 80 80 / 30%);
+ --hover : rgb(200 200 200 / 10%);
// --keyColor: #fa586a;
- --keyColorDefault: @keyColor;
- --keyColor: @keyColor;
- --keyColor-rgb: 250, 88, 106;
- --keyColor-rollover: #ff8a9c;
- --keyColor-rollover-rgb: 255, 138, 156;
- --keyColor-pressed: #ff7183;
- --keyColor-pressed-rgb: 255, 113, 131;
- --keyColor-deepPressed: #ff8a9c;
- --keyColor-deepPressed-rgb: 255, 138, 156;
- --keyColor-disabled: rgba(250, 88, 106, 0.35);
- --keyColor-primary: #ff2b52a6;
- --navigationBarHeight: 0px;
- --modalBackground: #262626;
- --songProgressColor: var(--keyColor);
- --songProgressBackground: #333;
- --textColor: #eee;
- --replayGradient: linear-gradient(45deg, hsl(248deg 58% 29%), hsl(13deg 41% 42%));
- --glassFilter: blur(16px) saturate(180%);
- --sidebarWidth: 260px;
+ --keyColorDefault : @keyColor;
+ --keyColor : @keyColor;
+ --keyColor-rgb : 250, 88, 106;
+ --keyColor-rollover : #ff8a9c;
+ --keyColor-rollover-rgb : 255, 138, 156;
+ --keyColor-pressed : #ff7183;
+ --keyColor-pressed-rgb : 255, 113, 131;
+ --keyColor-deepPressed : #ff8a9c;
+ --keyColor-deepPressed-rgb : 255, 138, 156;
+ --keyColor-disabled : rgba(250, 88, 106, 0.35);
+ --keyColor-primary : #ff2b52a6;
+ --navigationBarHeight : 0px;
+ --modalBackground : #262626;
+ --songProgressColor : var(--keyColor);
+ --songProgressBackground : #333;
+ --textColor : #eee;
+ --replayGradient : linear-gradient(45deg, hsl(248deg 58% 29%), hsl(13deg 41% 42%));
+ --glassFilter : blur(16px) saturate(180%);
+ --glassFilterHeavy : blur(64px) saturate(280%);
+ --sidebarWidth : 260px;
}
*:focus-visible {
- outline:2px solid var(--keyColor);
+ outline: 2px solid var(--keyColor);
}
html,
body {
- margin: 0;
- padding: 0;
- overflow: hidden;
- width: 100%;
- height: 100%;
- box-sizing: border-box;
- background-size: cover;
+ margin : 0;
+ padding : 0;
+ overflow : hidden;
+ width : 100%;
+ height : 100%;
+ box-sizing : border-box;
+ background-size : cover;
background-position: center;
- background: #0000;
- font-family: "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
- transition: opacity .10s var(--appleEase);
+ background : #0000;
+ font-family : "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ transition : opacity .10s var(--appleEase);
}
@@ -78,9 +81,9 @@ a:-webkit-any-link {
}
hr {
- appearance: none;
- border: none;
- height: 1px;
+ appearance : none;
+ border : none;
+ height : 1px;
background-color: rgb(255 255 255 / 20%);
}
@@ -99,14 +102,14 @@ body.stopanimation * {
}
body.notransparency::before {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- opacity: 0.5;
- display: none;
+ content : "";
+ position : absolute;
+ top : 0;
+ left : 0;
+ right : 0;
+ bottom : 0;
+ opacity : 0.5;
+ display : none;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==);
}
@@ -119,7 +122,7 @@ body.notransparency::before {
/* Modern style overlay scrollbars */
::-webkit-scrollbar {
- width: 16px;
+ width : 16px;
height: 24px;
}
@@ -132,54 +135,54 @@ body.notransparency::before {
}
::-webkit-scrollbar-thumb {
- background: transparent;
- border: 6px solid transparent;
- box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
+ background : transparent;
+ border : 6px solid transparent;
+ box-shadow : inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
border-radius: 16px;
- min-height: 64px;
- transition: border 1s;
+ min-height : 64px;
+ transition : border 1s;
}
::-webkit-scrollbar-thumb:hover {
- border: 5px solid transparent;
+ border : 5px solid transparent;
box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 80%);
}
[disabled] {
pointer-events: none;
- opacity: 0.5;
+ opacity : 0.5;
}
#app {
@panelBrightness : 0%;
@panelTransparency: 50%;
- @msColor1 : #202020;
- @msColor2 : #272727;
- @msColor3 : #2b2b2b;
+ @msColor1 : #202020;
+ @msColor2 : #272727;
+ @msColor3 : #2b2b2b;
--panelColor1 : darken(mix(@msColor1, transparent, @panelTransparency), @panelBrightness);
--panelColor2 : darken(mix(@msColor2, transparent, @panelTransparency), @panelBrightness);
- --color1 : var(--panelColor2);
- --color2 : var(--panelColor1);
- --color3 : rgb(0 0 0 / 20%);
- --bgColor: transparent;
- --bgWidth: 0px;
- --bgHeight: 0px;
- --chromeHeight1: 55px;
- --chromeHeight2: 0px;
- --chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2));
- width: 100%;
- height: 100%;
- background: transparent;
- color: var(--textColor);
- user-select: none;
- margin: 0 auto;
- position: relative;
- overflow: hidden;
- background-size: 400% 400%;
+ --color1 : var(--panelColor2);
+ --color2 : var(--panelColor1);
+ --color3 : rgb(0 0 0 / 20%);
+ --bgColor : transparent;
+ --bgWidth : 0px;
+ --bgHeight : 0px;
+ --chromeHeight1 : 55px;
+ --chromeHeight2 : 0px;
+ --chromeHeight : calc(var(--chromeHeight1) + var(--chromeHeight2));
+ width : 100%;
+ height : 100%;
+ background : transparent;
+ color : var(--textColor);
+ user-select : none;
+ margin : 0 auto;
+ position : relative;
+ overflow : hidden;
+ background-size : 400% 400%;
&.simplebg {
background: #0e0e0e;
- }
+ }
}
.bgGradientMaterial-base {
@@ -187,24 +190,25 @@ body.notransparency::before {
}
.bgGradientMaterial-base::before {
- position: absolute;
- top: -50%;
- left: -50%;
- width: 200%;
- height: 250%;
+ position : absolute;
+ top : -50%;
+ left : -50%;
+ width : 200%;
+ height : 250%;
background-image: var(--bgColor);
- content: "";
- z-index: -1;
- transform: rotateZ(0deg);
+ content : "";
+ z-index : -1;
+ transform : rotateZ(0deg);
transform-origin: center;
- animation: bgRotate 10s linear infinite;
- filter: brightness(100%) saturate(200%) contrast(1.5);
+ animation : bgRotate 10s linear infinite;
+ filter : brightness(100%) saturate(200%) contrast(1.5);
}
@keyframes bgRotate {
0% {
transform: rotateZ(0deg);
}
+
100% {
transform: rotateZ(360deg);
}
@@ -214,28 +218,29 @@ body.notransparency::before {
display: none !important;
}
-input[type="text"], input[type="number"] {
- background: #1c1c1c;
+input[type="text"],
+input[type="number"] {
+ background : #1c1c1c;
border-radius: 3px;
- border: 1px solid rgb(200 200 200 / 25%);
- color: #eee;
- padding: 6px;
- font-size: 1em;
- font-family: inherit;
+ border : 1px solid rgb(200 200 200 / 25%);
+ color : #eee;
+ padding : 6px;
+ font-size : 1em;
+ font-family : inherit;
}
.bg-artwork--placeholder {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: #222;
- z-index: -1;
- background-size: cover;
+ position : absolute;
+ top : 0;
+ left : 0;
+ width : 100%;
+ height : 100%;
+ background : #222;
+ z-index : -1;
+ background-size : cover;
background-position: center;
- opacity: 0.70;
+ opacity : 0.70;
}
a.dropdown-item {
@@ -243,23 +248,24 @@ a.dropdown-item {
&:hover {
background-color: var(--selected);
- color: var(--textColor);
+ color : var(--textColor);
}
+
&:active {
background-color: var(--selected-click);
}
}
.bg-artwork {
- position: absolute;
- width: 200%;
- background: var(--artwork);
- filter: brightness(200%) blur(180px) saturate(280%) contrast(2);
- opacity: 1;
- transition: opacity 0.25s var(--appleEase);
- pointer-events: none;
- transform: translateZ(0px);
- animation: rotateBg 35s linear infinite;
+ position : absolute;
+ width : 200%;
+ background : var(--artwork);
+ filter : brightness(200%) blur(180px) saturate(280%) contrast(2);
+ opacity : 1;
+ transition : opacity 0.25s var(--appleEase);
+ pointer-events : none;
+ transform : translateZ(0px);
+ animation : rotateBg 35s linear infinite;
backface-visibility: hidden;
}
@@ -267,6 +273,7 @@ a.dropdown-item {
0% {
transform: rotate(0deg);
}
+
100% {
transform: rotate(360deg);
}
@@ -274,26 +281,26 @@ a.dropdown-item {
.bg-artwork-container {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
+ position : absolute;
+ top : 0;
+ left : 0;
+ bottom : 0;
+ right : 0;
pointer-events: none;
- transform: translateZ(0px);
- z-index: -1;
+ transform : translateZ(0px);
+ z-index : -1;
.bg-artwork.a {
- top: 0;
- left: 0;
+ top : 0;
+ left : 0;
//mix-blend-mode: luminosity;
}
.bg-artwork.b {
- bottom: 0;
- right: 0;
+ bottom : 0;
+ right : 0;
animation-direction: reverse;
- animation-delay: 10s;
+ animation-delay : 10s;
}
&.noanimation {
@@ -304,27 +311,27 @@ a.dropdown-item {
}
.artworkMaterial {
- position: relative;
- height: 100%;
- width: 100%;
- overflow: hidden;
+ position : relative;
+ height : 100%;
+ width : 100%;
+ overflow : hidden;
pointer-events: none;
img {
position: absolute;
- width: 200%;
- opacity: 0.5;
- filter: brightness(200%) blur(180px) saturate(280%) contrast(2);
+ width : 200%;
+ opacity : 0.5;
+ filter : brightness(200%) blur(180px) saturate(280%) contrast(2);
}
img:first-child {
- top: 0;
+ top : 0;
left: 0;
}
img:last-child {
- bottom: 0;
- right: 0;
+ bottom : 0;
+ right : 0;
transform: rotate(180deg);
}
}
@@ -332,33 +339,33 @@ a.dropdown-item {
[artwork-hidden] {
transition: opacity .25s var(--appleEase);
- opacity: 0;
+ opacity : 0;
}
input[type="range"].web-slider {
-webkit-appearance: none;
- height: 4px;
- background: rgba(255, 255, 255, 0.6);
- border-radius: 5px;
- background-size: 70% 100%;
- background-repeat: no-repeat;
+ height : 4px;
+ background : rgba(255, 255, 255, 0.6);
+ border-radius : 5px;
+ background-size : 70% 100%;
+ background-repeat : no-repeat;
}
input[type="range"].web-slider::-webkit-slider-thumb {
-webkit-appearance: none;
- height: 20px;
- width: 20px;
- border-radius: 50%;
- background: rgb(255 255 255);
- cursor: ew-resize;
- box-shadow: 0 0 2px 0 #555;
+ height : 20px;
+ width : 20px;
+ border-radius : 50%;
+ background : rgb(255 255 255);
+ cursor : ew-resize;
+ box-shadow : 0 0 2px 0 #555;
}
input[type=range].web-slider::-webkit-slider-runnable-track {
-webkit-appearance: none;
- box-shadow: none;
- border: none;
- background: transparent;
+ box-shadow : none;
+ border : none;
+ background : transparent;
}
.nopadding {
@@ -366,50 +373,50 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
#app-main {
- display: flex;
- width: 100%;
- height: 100%;
- flex-direction: column;
- opacity: 1;
- overflow: hidden;
+ display : flex;
+ width : 100%;
+ height : 100%;
+ flex-direction : column;
+ opacity : 1;
+ overflow : hidden;
background-color: rgba(20 20 20 / .7);
}
#app-sidebar {
- height: 100%;
- width: var(--sidebarWidth);
- display: flex;
+ height : 100%;
+ width : var(--sidebarWidth);
+ display : flex;
flex-direction: column;
- flex: 0 0 auto;
- position: relative;
- background: linear-gradient(180deg, var(--baseColorMix) calc(var(--chromeHeight1) + 1px), var(--sidebarColorMix) calc(var(--chromeHeight1) + 1px));
- max-width: var(--sidebarWidth);
- padding-top: var(--chromeHeight1);
+ flex : 0 0 auto;
+ position : relative;
+ background : linear-gradient(180deg, var(--baseColorMix) calc(var(--chromeHeight1) + 1px), var(--sidebarColorMix) calc(var(--chromeHeight1) + 1px));
+ max-width : var(--sidebarWidth);
+ padding-top : var(--chromeHeight1);
}
#app-navbar {
- height: 40px;
- width: 100%;
- background: rgb(30 30 30 / 85%);
- position: sticky;
- top: 0px;
- left: 0;
- z-index: 2;
+ height : 40px;
+ width : 100%;
+ background : rgb(30 30 30 / 85%);
+ position : sticky;
+ top : 0px;
+ left : 0;
+ z-index : 2;
backdrop-filter: blur(16px) saturate(180%);
}
#app-content {
--navigationBarHeight: var(--chromeHeight1);
- background-color: var(--baseColorMix);
- height: 100%;
- width: 100%;
- overflow-y: scroll;
- overflow-y: overlay;
- overflow-x: hidden;
- border-radius: 0;
- border-left: 1px solid var(--baseColorMix);
+ background-color : var(--baseColorMix);
+ height : 100%;
+ width : 100%;
+ overflow-y : scroll;
+ overflow-y : overlay;
+ overflow-x : hidden;
+ border-radius : 0;
+ border-left : 1px solid var(--baseColorMix);
// border-top: 1px solid rgb(0 0 0 / 25%);
- position: relative;
+ position : relative;
&::-webkit-scrollbar-track-piece {
margin-top: var(--chromeHeight1);
@@ -417,29 +424,31 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.app-drawer {
- width: 300px;
- flex: 0 0 auto;
- position: absolute;
- right: 16px;
- background: var(--color2);
- border-radius: 12px;
- z-index: 10;
+ width : 300px;
+ flex : 0 0 auto;
+ position : absolute;
+ right : 16px;
+ background : var(--color2);
+ border-radius : 12px;
+ z-index : 10;
backdrop-filter: blur(40px) saturate(180%);
- box-shadow: var(--ciderShadow-Generic);
- overflow: hidden;
- height: calc(calc(100% - 6%) - var(--chromeHeight1));
- top: calc(var(--chromeHeight1) + 3%);
+ box-shadow : var(--ciderShadow-Generic);
+ overflow : hidden;
+ height : calc(calc(100% - 6%) - var(--chromeHeight1));
+ top : calc(var(--chromeHeight1) + 3%);
.bgArtworkMaterial {
- display: none;
+ display : none;
position: absolute;
- width: 100%;
- height: 100%;
+ width : 100%;
+ height : 100%;
.bg-artwork-container .bg-artwork {
filter: brightness(80%) blur(180px) saturate(180%) contrast(1);
}
}
+
+ transition: .3s var(--appleEase);
}
.search-input-container {
@@ -447,58 +456,58 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.search-input {
- width: 100%;
- padding: 6px;
+ width : 100%;
+ padding : 6px;
border-radius: 6px;
- border: 1px solid rgba(100, 100, 100, 0.35);
- border-top: 1px solid rgba(100, 100, 100, 0.5);
+ border : 1px solid rgba(100, 100, 100, 0.35);
+ border-top : 1px solid rgba(100, 100, 100, 0.5);
border-bottom: 1px solid rgb(60 60 60 / 62%);
- font-family: inherit;
- font-size: 14px;
- background: #1e1e1e99;
- color: #c8c8c8;
- font-weight: 500;
- padding-left: 32px;
- position: relative;
+ font-family : inherit;
+ font-size : 14px;
+ background : #1e1e1e99;
+ color : #c8c8c8;
+ font-weight : 500;
+ padding-left : 32px;
+ position : relative;
}
.search-input:focus {
- outline: none;
+ outline : none;
border-bottom: 1px solid var(--keyColor);
}
.search-input--icon {
- content: '';
- width: 100%;
- height: 100%;
- display: block;
- position: absolute;
- top: 0px;
- left: 0px;
- background-image: url('assets/search.svg');
+ content : '';
+ width : 100%;
+ height : 100%;
+ display : block;
+ position : absolute;
+ top : 0px;
+ left : 0px;
+ background-image : url('assets/search.svg');
background-position: 10px;
- background-repeat: no-repeat;
- background-size: 12px;
- pointer-events: none;
- opacity: 0.55;
+ background-repeat : no-repeat;
+ background-size : 12px;
+ pointer-events : none;
+ opacity : 0.55;
}
.app-sidebar-header {
- font-size: 14px;
- padding: 11px;
+ font-size : 14px;
+ padding : 11px;
font-weight: 600;
}
.app-sidebar-header-text {
- font-size: 11px;
- padding: 6px 6px;
- font-weight: 600;
- opacity: 0.5;
- background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iNDYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBkPSJtNiA5IDYgNiA2LTYiPjwvcGF0aD4KPC9zdmc+");
- background-size: 16px;
- background-repeat: no-repeat;
+ font-size : 11px;
+ padding : 6px 6px;
+ font-weight : 600;
+ opacity : 0.5;
+ background-image : url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iNDYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBkPSJtNiA5IDYgNiA2LTYiPjwvcGF0aD4KPC9zdmc+");
+ background-size : 16px;
+ background-repeat : no-repeat;
background-position: 98%;
- border-radius: 3px;
+ border-radius : 3px;
&.collapsed {
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iNDYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBkPSJtOSAxOCA2LTYtNi02Ij48L3BhdGg+Cjwvc3ZnPg==");
@@ -515,14 +524,15 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
.app-sidebar-footer {
border-top: 1px solid rgba(200, 200, 200, 0.15);
- padding: 11px;
+ padding : 11px;
.app-playback-controls {
margin: 0 auto;
+
.control-buttons {
- display: flex;
+ display : flex;
justify-content: center;
- align-content: center;
+ align-content : center;
}
.volume {
@@ -531,55 +541,59 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
&.collapseTab {
- display:flex;
- padding:6px;
- border:0;
+ display: flex;
+ padding: 6px;
+ border : 0;
+
>button {
- appearance: none;
- width: 100%;
- position: relative;
+ appearance : none;
+ width : 100%;
+ position : relative;
padding-left: 40px;
- text-align: left;
- font-family: inherit;
+ text-align : left;
+ font-family : inherit;
+
&:hover {
background-color: var(--selected);
}
+
&:active {
background-color: var(--selected-click);
}
+
&:after {
- content: '';
- display: flex;
+ content : '';
+ display : flex;
justify-content: center;
- align-items: center;
- width: 46px;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- font-weight: bold;
- font-size: 1em;
- font-family: "codicon";
+ align-items : center;
+ width : 46px;
+ height : 100%;
+ position : absolute;
+ top : 0;
+ left : 0;
+ font-weight : bold;
+ font-size : 1em;
+ font-family : "codicon";
}
}
}
}
.app-sidebar-button {
- width: 100%;
- padding: 0px;
- font-family: inherit;
- display: flex;
+ width : 100%;
+ padding : 0px;
+ font-family : inherit;
+ display : flex;
border-radius: 6px;
- border: 1px solid rgb(200 200 200 / 5%);
- background: rgb(100 100 100 / 25%);
- color: #eee;
- font-weight: 500;
- align-items: center;
+ border : 1px solid rgb(200 200 200 / 5%);
+ background : rgb(100 100 100 / 25%);
+ color : #eee;
+ font-weight : 500;
+ align-items : center;
&.active {
background: rgb(200 200 200 / 15%);
- animation: usermenuBtnClick .30s cubic-bezier(0.36, 0, 0.66, -0.56);
+ animation : usermenuBtnClick .30s cubic-bezier(0.36, 0, 0.66, -0.56);
}
}
@@ -597,93 +611,95 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
}
-.app-sidebar-button > .sidebar-user-icon {
- width: 32px;
- height: 32px;
- border-radius: 100%;
+.app-sidebar-button>.sidebar-user-icon {
+ width : 32px;
+ height : 32px;
+ border-radius : 100%;
background-image: var(--artwork);
- margin: 10px;
- flex: 0 0 auto;
- box-shadow: var(--mediaItemShadow);
- background-size: contain;
+ margin : 10px;
+ flex : 0 0 auto;
+ box-shadow : var(--mediaItemShadow);
+ background-size : contain;
}
-.app-sidebar-button > .sidebar-user-text {
- width: 100%;
- display: flex;
- font-size: 14px;
+.app-sidebar-button>.sidebar-user-text {
+ width : 100%;
+ display : flex;
+ font-size : 14px;
flex-direction: column;
- text-align: center;
- margin-right: 35px;
+ text-align : center;
+ margin-right : 35px;
}
-.app-sidebar-button > .sidebar-user-text .fullname {
+.app-sidebar-button>.sidebar-user-text .fullname {
text-align: left;
}
-.app-sidebar-button > .sidebar-user-text .handle-text {
- font-size: 12px;
- opacity: 0.7;
+.app-sidebar-button>.sidebar-user-text .handle-text {
+ font-size : 12px;
+ opacity : 0.7;
text-align: left;
}
.app-sidebar-notification {
- text-align: center;
- font-size: 12px;
- min-height: 36px;
- display: flex;
+ text-align : center;
+ font-size : 12px;
+ min-height : 36px;
+ display : flex;
justify-content: center;
- align-items: center;
- border-top: 1px solid rgb(200 200 200 / 15%);
- background: rgb(0 0 0 / 15%);
- flex-direction: column;
- padding: 10px 0px;
+ align-items : center;
+ border-top : 1px solid rgb(200 200 200 / 15%);
+ background : rgb(0 0 0 / 15%);
+ flex-direction : column;
+ padding : 10px 0px;
&.libraryNotification {
flex-direction: row;
- padding: 0px;
+ padding : 0px;
.message {
flex-grow: 1;
}
.spinner {
- width: 46px;
- height: 30px;
+ width : 46px;
+ height : 30px;
margin-left: 1em;
}
}
}
.app-sidebar-content {
- padding: 8px;
+ padding : 8px;
overflow-y: scroll;
overflow-y: overlay;
- height: 100%;
+ height : 100%;
}
#cmenu() {
.container {
- position: absolute;
- left: 0px;
- width: var(--sidebarWidth);
+ position : absolute;
+ left : 0px;
+ width : var(--sidebarWidth);
max-width: var(--sidebarWidth);
- padding: 10px;
- z-index: 1;
+ padding : 10px;
+ z-index : 1;
}
.body {
- background: rgb(30 30 30 / 45%);
- padding: 6px;
- border-radius: var(--panelRadius);
- width: 100%;
- box-shadow: var(--ciderShadow-Generic);
+ background : rgb(30 30 30 / 45%);
+ padding : 6px;
+ border-radius : var(--panelRadius);
+ width : 100%;
+ box-shadow : var(--ciderShadow-Generic);
backdrop-filter: var(--glassFilter);
- animation: cmenuBodyIn .5s var(--appleEase);
+ animation : cmenuBodyIn .5s var(--appleEase);
+
@keyframes cmenuBodyIn {
0% {
background: rgb(30 30 30);
}
+
100% {
background: rgb(30 30 30 / 45%);
}
@@ -691,18 +707,18 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.item {
- background: transparent;
- display: block;
- width: 100%;
- text-align: left;
- color: #eee;
- font-family: inherit;
- font-size: 15px;
- padding: 8px 12px;
- border: 0px;
- appearance: none;
+ background : transparent;
+ display : block;
+ width : 100%;
+ text-align : left;
+ color : #eee;
+ font-family : inherit;
+ font-size : 15px;
+ padding : 8px 12px;
+ border : 0px;
+ appearance : none;
border-radius: 6px;
- margin: 2px 0px;
+ margin : 2px 0px;
&:hover {
background: var(--selected);
@@ -724,7 +740,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.usermenu-container {
- top: var(--chromeHeight1);
+ top : var(--chromeHeight1);
z-index: 200001 !important;
#cmenu.container();
@@ -736,47 +752,47 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
.usermenu-item-icon {
position: relative;
- top: 1.5px;
- right: 3px;
- display: table-cell;
+ top : 1.5px;
+ right : 3px;
+ display : table-cell;
}
.usermenu-item-name {
- position: relative;
- bottom: 2px;
+ position : relative;
+ bottom : 2px;
padding-left: 5px;
- display: table-cell;
+ display : table-cell;
}
}
}
}
.context-menu {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
+ position : absolute;
+ top : 0;
+ left : 0;
+ width : 100%;
+ height : 100%;
background: rgba(0, 0, 0, 0.0);
- z-index: 100;
+ z-index : 100;
.context-menu-item {
- background: transparent;
- display: flex;
- width: 100%;
- text-align: left;
- color: #eee;
- font-family: inherit;
- font-size: 14px;
- padding: 6px 12px;
- border: 0px;
- appearance: none;
+ background : transparent;
+ display : flex;
+ width : 100%;
+ text-align : left;
+ color : #eee;
+ font-family : inherit;
+ font-size : 14px;
+ padding : 6px 12px;
+ border : 0px;
+ appearance : none;
border-radius: 6px;
- margin: 2px 0px;
+ margin : 2px 0px;
&:hover {
background: var(--selected);
- cursor: pointer;
+ cursor : pointer;
}
&:active {
@@ -785,23 +801,23 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.context-menu-body {
- background: #242424;
- padding: 6px;
+ background : #242424;
+ padding : 6px;
border-radius: 6px;
- box-shadow: var(--ciderShadow-Generic);
+ box-shadow : var(--ciderShadow-Generic);
&.context-menu-open {
- animation-duration: .10s;
- animation-name: contextMenuIn;
+ animation-duration : .10s;
+ animation-name : contextMenuIn;
animation-iteration-count: 1;
- animation-easings: var(--appleEase);
+ animation-easings : var(--appleEase);
}
&.context-menu-close {
- animation-duration: .10s;
- animation-name: contextMenuOut;
+ animation-duration : .10s;
+ animation-name : contextMenuOut;
animation-iteration-count: 1;
- animation-easings: var(--appleEase);
+ animation-easings : var(--appleEase);
}
}
}
@@ -809,42 +825,42 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
@keyframes contextMenuIn {
0% {
transform: scale(0.9);
- opacity: 0;
+ opacity : 0;
}
100% {
transform: scale(1);
- opacity: 1;
+ opacity : 1;
}
}
@keyframes contextMenuOut {
0% {
transform: scale(1);
- opacity: 1;
+ opacity : 1;
}
100% {
transform: scale(0.9);
- opacity: 0;
+ opacity : 0;
}
}
.hidden-opacity {
opacity: 0;
- height: 0px;
- width: 0px;
- margin: 0px;
+ height : 0px;
+ width : 0px;
+ margin : 0px;
}
.spinner {
- background-image: url("assets/spinner.svg");
+ background-image : url("assets/spinner.svg");
background-position: center;
- background-repeat: no-repeat;
- background-size: contain;
- width: 50px;
- height: 50px;
- display: inline-block;
+ background-repeat : no-repeat;
+ background-size : contain;
+ width : 50px;
+ height : 50px;
+ display : inline-block;
}
.app-sidebar-content::-webkit-scrollbar {
@@ -856,149 +872,156 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.app-sidebar-item {
- display: flex;
- width: 100%;
- padding: 8px 12px;
- font-weight: 400;
- font-family: inherit;
- font-size: 14px;
- margin: 3px 0px;
- border: 1px solid transparent;
+ --iconSize : 18px;
+ display : flex;
+ width : 100%;
+ padding : 8px 12px;
+ font-weight : 400;
+ font-family : inherit;
+ font-size : 14px;
+ margin : 3px 0px;
+ border : 1px solid transparent;
border-radius: 6px;
- background: transparent;
- color: #eee;
- transition: transform 0.1s;
- text-align: left;
- align-items: center;
+ background : transparent;
+ color : #eee;
+ transition : transform 0.1s;
+ text-align : left;
+ align-items : center;
+ gap : 12px;
&.app-sidebar-item-playlist {
-webkit-user-drag: element;
- overflow: hidden;
- text-overflow: ellipsis;
+ overflow : hidden;
+ text-overflow : ellipsis;
.presentNotice {
- align-self: center;
- margin-left: 8px;
+ align-self : center;
+ margin-left : 8px;
text-transform: uppercase;
- font-size: 0.7em;
- opacity: 0.6;
+ font-size : 0.7em;
+ opacity : 0.6;
}
}
+ >._svg-icon {
+ --size: var(--iconSize);
+ }
+
}
.app-sidebar-item:hover {
- border: 1px solid rgb(200 200 200 / 0%);
+ border : 1px solid rgb(200 200 200 / 0%);
background: rgb(180 180 180 / 15%);
// cursor: pointer;
}
.app-sidebar-item:active {
- border: 1px solid rgb(200 200 200 / 0%);
- background: rgb(150 150 150 / 15%);
+ border : 1px solid rgb(200 200 200 / 0%);
+ background : rgb(150 150 150 / 15%);
// transform: scale(0.98);
- transition: transform 0s;
+ transition : transform 0s;
}
.app-sidebar-item.active {
- border: 1px solid rgb(200 200 200 / 0%);
+ border : 1px solid rgb(200 200 200 / 0%);
background: rgb(200 200 200 / 15%);
- transform: scale(1);
+ transform : scale(1);
transition: transform 0s;
- cursor: default;
+ cursor : default;
}
.app-chrome {
background-color: var(--baseColorMix);
- box-shadow: 0px 3px 6px rgb(20 20 20 / 12%),
+ box-shadow : 0px 3px 6px rgb(20 20 20 / 12%),
0px 1px 0px 0px rgb(200 200 200 / 12%);
- width: 100%;
- height: var(--chromeHeight1);
- display: flex;
- flex-direction: row;
+ width : 100%;
+ height : var(--chromeHeight1);
+ display : flex;
+ flex-direction : row;
-webkit-app-region: drag;
- z-index: 4;
+ z-index : 4;
&:not(.chrome-bottom) {
// box-shadow: 0px 0px
- z-index: 16;
- position: fixed;
+ z-index : 16;
+ position : fixed;
backdrop-filter: var(--glassFilter);
.app-chrome--center {
- flex:1;
+ flex: 1;
}
-}
+ }
-.top-nav-group {
- background: var(--baseColor);
- border: 1px solid lighten(@baseColor, 8);
+ .top-nav-group {
+ background : var(--baseColor);
+ border : 1px solid lighten(@baseColor, 8);
border-radius: 10px;
- display: flex;
- height: 32px;
+ display : flex;
+ height : 32px;
.app-sidebar-item {
- background-color: var(--baseColor);
- border-radius: 10px!important;
- border:0px;
- min-width: 120px;
- padding:6px;
- justify-content: center;
- align-items: center;
- margin: 0px;
- height: 100%;
+ background-color: var(--baseColor);
+ border-radius : 10px !important;
+ border : 0px;
+ min-width : 120px;
+ padding : 6px;
+ justify-content : center;
+ align-items : center;
+ margin : 0px;
+ height : 100%;
- &:hover {
- background-color: lighten(@baseColor, @colorMixRate * 5);
- }
+ &:hover {
+ background-color: lighten(@baseColor, @colorMixRate * 5);
+ }
- &.active {
- background-color: lighten(@baseColor, @colorMixRate * 5);
- }
+ &.active {
+ background-color: lighten(@baseColor, @colorMixRate * 5);
+ }
- &.md-btn-primary {
- box-shadow: 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8);
- background-color: lighten(@baseColor, @colorMixRate * 5);
- z-index: 1;
- }
+ &.md-btn-primary {
+ box-shadow : 0px 0px 0px 1px lighten(@baseColor, @colorMixRate * 8);
+ background-color: lighten(@baseColor, @colorMixRate * 5);
+ z-index : 1;
+ }
}
-}
+ }
.vdiv {
- width: 1px;
+ width : 1px;
background: white;
- opacity: 0.25;
- height: 50%;
- margin: 6px;
+ opacity : 0.25;
+ height : 50%;
+ margin : 6px;
}
}
.mv-chrome {
- position: absolute;
- top: 0;
- right: 0;
- width: 90%;
- height: 55px;
+ position : absolute;
+ top : 0;
+ right : 0;
+ width : 90%;
+ height : 55px;
-webkit-app-region: drag;
}
.app-chrome .app-chrome--left,
.app-chrome .app-chrome--center,
.app-chrome .app-chrome--right {
- height: 100%;
- width: 100%;
- display: flex;
+ height : 100%;
+ width : 100%;
+ display : flex;
justify-content: center;
- align-items: center;
+ align-items : center;
}
.app-chrome .app-chrome--left {
- width: 30%;
- justify-content: left;
+ width : 30%;
+ justify-content : left;
-webkit-app-region: drag;
}
.app-chrome .app-chrome--center {
+
//width: 40%;
.app-title-text {
font-size: 0.8em;
@@ -1006,27 +1029,27 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.app-chrome .app-chrome--right {
- width: 30%;
+ width : 30%;
justify-content: right;
}
.app-chrome .app-chrome-item {
- height: 100%;
- width: auto;
- display: flex;
- justify-content: center;
- align-items: center;
+ height : 100%;
+ width : auto;
+ display : flex;
+ justify-content : center;
+ align-items : center;
-webkit-app-region: no-drag;
- height: auto;
+ height : auto;
&.generic {
- width: 50px;
+ width : 50px;
opacity: 0.70;
}
&.volume {
- width: 100px;
+ width : 100px;
margin-right: 6px;
}
@@ -1036,96 +1059,98 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
.volume-button {
- background-image: url("./assets/feather/volume-2.svg");
- height: 15px;
- width: 30px;
- padding: 0px;
- background: transparent;
- border: 0px;
- border-radius: 0px;
- box-shadow: unset;
- background-size: 12px;
+ background-image : url("./assets/feather/volume-2.svg");
+ height : 15px;
+ width : 30px;
+ padding : 0px;
+ background : transparent;
+ border : 0px;
+ border-radius : 0px;
+ box-shadow : unset;
+ background-size : 12px;
background-position: center;
- background-repeat: no-repeat;
- opacity: 0.70;
- border-radius: 6px;
+ background-repeat : no-repeat;
+ opacity : 0.70;
+ border-radius : 6px;
}
-.volume-button:active, .volume-button--small:active {
+.volume-button:active,
+.volume-button--small:active {
transform: scale(0.9);
}
-.volume-button.active, .volume-button--small.active {
+.volume-button.active,
+.volume-button--small.active {
background-image: url("./assets/feather/volume.svg");
}
.volume-button--small {
- border-radius: 6px;
- color: inherit;
- background-size: 16px;
- background-repeat: no-repeat;
+ border-radius : 6px;
+ color : inherit;
+ background-size : 16px;
+ background-repeat : no-repeat;
background-position: center;
- background-color: transparent;
- height: 15px;
- width: 30px;
- border: 0px;
- box-shadow: unset;
- opacity: 0.70;
- background-image: url("./assets/feather/volume-2.svg");
+ background-color : transparent;
+ height : 15px;
+ width : 30px;
+ border : 0px;
+ box-shadow : unset;
+ opacity : 0.70;
+ background-image : url("./assets/feather/volume-2.svg");
}
-.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb {
+.app-chrome .app-chrome-item.volume>input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
- height: 14px;
- width: 14px;
- border-radius: 50%;
- background: #A5A8BA;
- box-shadow: 0px 0px 0px 1px rgba(0 0 0 / 10%);
- cursor: default;
- transition: all var(--appleTransition);
+ height : 14px;
+ width : 14px;
+ border-radius : 50%;
+ background : #A5A8BA;
+ box-shadow : 0px 0px 0px 1px rgba(0 0 0 / 10%);
+ cursor : default;
+ transition : all var(--appleTransition);
}
-.app-chrome .app-chrome-item.volume > input[type=range] {
+.app-chrome .app-chrome-item.volume>input[type=range] {
-webkit-appearance: none;
- height: 4px;
- background: rgba(255, 255, 255, 0.4);
- border-radius: 5px;
- background-size: 70% 100%;
- background-repeat: no-repeat;
- width: 100%,
+ height : 4px;
+ background : rgba(255, 255, 255, 0.4);
+ border-radius : 5px;
+ background-size : 70% 100%;
+ background-repeat : no-repeat;
+ width : 100%,
}
-.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-runnable-track {
+.app-chrome .app-chrome-item.volume>input[type=range]::-webkit-slider-runnable-track {
-webkit-appearance: none;
- box-shadow: none;
- border: none;
- background: transparent;
+ box-shadow : none;
+ border : none;
+ background : transparent;
}
.app-chrome .back-button {
height: 100%;
- width: 60px;
+ width : 60px;
}
.app-chrome .app-chrome-item.full-height {
height: 100%;
}
-.app-chrome .app-chrome-item > .app-mainmenu {
- width: 34px;
- font-size: 13px;
- background: url("./assets/CiderMenu.svg");
- background-size: auto;
- background-repeat: no-repeat;
+.app-chrome .app-chrome-item>.app-mainmenu {
+ width : 34px;
+ font-size : 13px;
+ background : url("./assets/CiderMenu.svg");
+ background-size : auto;
+ background-repeat : no-repeat;
background-position: center;
- height: 34px;
- margin-right: 16px;
- margin-left: 16px;
- margin-top: 1.5px;
- border: 0px;
- border-radius: 6px;
- transition: transform .1s var(--appleEase);
- position: relative;
+ height : 34px;
+ margin-right : 16px;
+ margin-left : 16px;
+ margin-top : 1.5px;
+ border : 0px;
+ border-radius : 6px;
+ transition : transform .1s var(--appleEase);
+ position : relative;
// &:after {
// content: "";
@@ -1146,64 +1171,70 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
transform: scale(1.1);
}
- &:active, &.active {
+ &:active,
+ &.active {
border-radius: 100%;
- transform: scale(1.1);
- outline: 2px solid var(--keyColor);
+ transform : scale(1.1);
+ outline : 2px solid var(--keyColor);
}
}
-.app-chrome .app-chrome-item > .window-controls {
- width: 138px;
+.app-chrome .app-chrome-item>.window-controls {
+ width : 138px;
font-size: 13px;
- height: 100%;
- display: flex;
+ height : 100%;
+ display : flex;
&-macos {
width: 100px;
}
- > div {
+ >div {
height: 100%;
- width: 32px;
+ width : 32px;
+
&:hover {
background: rgb(200 200 200 / 10%);
}
+
&.close {
- width: 100%;
- height: 100%;
- background-image: var(--gfx-closeBtn);
+ width : 100%;
+ height : 100%;
+ background-image : var(--gfx-closeBtn);
background-position: center;
- background-repeat: no-repeat;
- -webkit-app-region: no-drag;
-
+ background-repeat : no-repeat;
+ -webkit-app-region : no-drag;
+
&:hover {
background-color: rgb(196, 43, 28)
}
}
+
&.minmax {
- background-image: var(--gfx-maxBtn);
+ background-image : var(--gfx-maxBtn);
background-position: center;
- background-repeat: no-repeat;
- -webkit-app-region: no-drag;
- width: 100%;
- height: 100%;
+ background-repeat : no-repeat;
+ -webkit-app-region : no-drag;
+ width : 100%;
+ height : 100%;
}
+
&.minmax.restore {
background-image: var(--gfx-restoreBtn);
}
+
&.minimize {
- background-image: var(--gfx-minBtn);
+ background-image : var(--gfx-minBtn);
background-position: center;
- background-repeat: no-repeat;
- -webkit-app-region: no-drag;
- width: 100%;
- height: 100%;
+ background-repeat : no-repeat;
+ -webkit-app-region : no-drag;
+ width : 100%;
+ height : 100%;
}
}
}
-body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minimize {
+body[platform="darwin"] .app-chrome .app-chrome-item>.window-controls>div.minimize {
display: none;
}
@@ -1211,130 +1242,140 @@ body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.mi
// display: none;
//}
-body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minmax {
+body[platform="darwin"] .app-chrome .app-chrome-item>.window-controls>div.minmax {
display: none;
}
-body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.close {
+body[platform="darwin"] .app-chrome .app-chrome-item>.window-controls>div.close {
display: none;
}
.app-chrome .app-chrome-item.playback-controls {
- width: 80%;
- height: 90%;
- display: flex;
- max-width: 500px;
- border-left: 1px solid rgb(200 200 200 / 8%);
- border-right: 1px solid rgb(200 200 200 / 8%);
+ width : 80%;
+ height : 90%;
+ display : flex;
+ max-width : 500px;
+ border-left : 1px solid rgb(200 200 200 / 8%);
+ border-right : 1px solid rgb(200 200 200 / 8%);
-webkit-app-region: drag;
}
-.app-chrome .app-chrome-item > .app-playback-controls {
- display: flex;
- justify-content: center;
- align-content: center;
- width: 100%;
+.app-chrome .app-chrome-item>.app-playback-controls {
+ display : flex;
+ justify-content : center;
+ align-content : center;
+ width : 100%;
-webkit-app-region: no-drag;
}
-.app-chrome .app-chrome-item > .app-playback-controls {
- .info-rect{
- mask-image: linear-gradient(-90deg, transparent 0%, black 10%, black 90%, transparent 100%);
+.app-chrome .app-chrome-item>.app-playback-controls {
+ .info-rect {
+ mask-image : linear-gradient(-90deg, transparent 0%, black 10%, black 90%, transparent 100%);
-webkit-mask-image: linear-gradient(-90deg, transparent 3%, black 10%, black 90%, transparent 100%);
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- width:100%;
+ display : flex;
+ flex-direction : column;
+ justify-content : center;
+ align-items : center;
+ width : 100%;
}
+
.song-name {
font-weight: 600;
- text-align: center;
- font-size: 13px;
- height: 1.3em;
+ text-align : center;
+ font-size : 13px;
+ height : 1.3em;
line-height: 1.3em;
white-space: nowrap;
- max-width: 360px;
+ max-width : 360px;
.song-name-normal {
height: inherit;
}
&.song-artist-marquee {
- > marquee {
+ >marquee {
//margin-bottom: -3px;
}
}
.explicit-icon {
- background-image: url("./assets/explicit.svg");
- height: 9px;
- width: 13px;
- filter: contrast(0);
+ background-image : url("./assets/explicit.svg");
+ height : 9px;
+ width : 13px;
+ filter : contrast(0);
background-repeat: no-repeat;
- margin-left: 3px;
+ margin-left : 3px;
}
.heart-icon {
- height: 9px;
- width: 13px;
- filter: contrast(0);
+ height : 9px;
+ width : 13px;
+ filter : contrast(0);
background-repeat: no-repeat;
- margin-left: 3px;
+ margin-left : 3px;
}
}
.lossless-icon {
background-image: url("./assets/lossless.svg") !important;
+ margin-left : 0.5em !important;
+ flex : 1;
}
.ppe-icon {
background-image: url("./assets/ppe.svg") !important;
- margin-left: 0.5em !important;
- flex: 1;
+ margin-left : 0.5em !important;
+ flex : 1;
+ }
+ .spatial-icon {
+ background-image: url("./assets/spatialization.svg") !important;
+ margin-left : 0.5em !important;
+ flex : 1;
}
.private-icon {
background-image: url("./assets/private.svg") !important;
- margin-left: 0.5em !important;
- flex: 1;
+ margin-left : 0.5em !important;
+ flex : 1;
}
.chrome-icon-container {
- display: flex;
+ display : flex;
position: absolute;
- right: 0px;
+ right : 0px;
}
.audio-type {
- filter: contrast(0);
+ filter : contrast(0);
background-repeat: no-repeat;
- background-size: contain;
- height: 15px;
- width: 15px;
- margin-bottom: 15px;
+ background-size : contain;
+ height : 15px;
+ width : 15px;
+ margin-bottom : 15px;
+ z-index : 1;
}
}
+
// Add Music Video Icons to Songs that are Music Videos
div[data-type="library-music-videos"] .info-rect .title::before,
div[data-type="musicVideo"] .info-rect .title::before {
- content: "";
- background-image: url(./assets/feather/video.svg);
- background-size: contain;
- filter:invert(0.6);
- display: inline-block;
- width: 20px;
- height: 20px;
- margin-bottom: -4px;
+ content : "";
+ background-image: url(./assets/feather/video.svg);
+ background-size : contain;
+ filter : invert(0.6);
+ display : inline-block;
+ width : 20px;
+ height : 20px;
+ margin-bottom : -4px;
}
-.app-chrome .app-chrome-item > .app-playback-controls .song-duration p {
+.app-chrome .app-chrome-item>.app-playback-controls .song-duration p {
font-weight: 400;
- font-size: 10px;
- height: 1.2em;
+ font-size : 10px;
+ height : 1.2em;
line-height: 1.3em;
- overflow: hidden;
- margin: 0 0 0 0.25em;
+ overflow : hidden;
+ margin : 0 0 0 0.25em;
}
.app-playback-controls:hover .marquee {
@@ -1360,7 +1401,7 @@ div[data-type="musicVideo"] .info-rect .title::before {
.marquee {
- animation: marquee 15s linear 2s infinite;
+ animation: marquee 15s linear 2s infinite;
&.song-artist {
overflow: unset;
@@ -1380,51 +1421,51 @@ div[data-type="musicVideo"] .info-rect .title::before {
}
-.app-chrome .app-chrome-item > .app-playback-controls .song-progress {
- @bgColor: transparent;
+.app-chrome .app-chrome-item>.app-playback-controls .song-progress {
+ @bgColor : transparent;
//height: 16px;
- position: absolute;
- bottom: 0px;
- left: 0px;
+ position : absolute;
+ bottom : 0px;
+ left : 0px;
background: @bgColor;
&:hover {
- > input[type=range] {
+ >input[type=range] {
&::-webkit-slider-thumb {
- opacity: 1;
+ opacity : 1;
transform: scale(1);
- z-index: 1;
+ z-index : 1;
}
}
}
- > input[type=range] {
- appearance: none;
- width: 100%;
- height: 4px;
+ >input[type=range] {
+ appearance : none;
+ width : 100%;
+ height : 4px;
background-color: rgb(200 200 200 / 10%);
- border-radius: 2px;
- margin: 0;
+ border-radius : 2px;
+ margin : 0;
&::-webkit-slider-thumb {
- opacity: 0;
- transform: scale(0.5);
+ opacity : 0;
+ transform : scale(0.5);
-webkit-appearance: none;
- appearance: none;
- width: 12px;
- height: 12px;
- border-radius: 100%;
- background: var(--songProgressColor);
- cursor: default;
- transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
+ appearance : none;
+ width : 12px;
+ height : 12px;
+ border-radius : 100%;
+ background : var(--songProgressColor);
+ cursor : default;
+ transition : opacity .10s var(--appleEase), transform .10s var(--appleEase);
}
&::-moz-range-thumb {
- width: 8px;
- height: 8px;
+ width : 8px;
+ height : 8px;
border-radius: 100%;
- background: var(--songProgressColor);
- cursor: default;
+ background : var(--songProgressColor);
+ cursor : default;
}
}
}
@@ -1439,45 +1480,46 @@ div[data-type="musicVideo"] .info-rect .title::before {
}
}
-.app-chrome .app-chrome-item > .app-playback-controls .artwork {
- width: 42px;
- height: 42px;
- background-image: var(--artwork);
+.app-chrome .app-chrome-item>.app-playback-controls .artwork {
+ width : 42px;
+ height : 42px;
+ background-image : var(--artwork);
background-position: center;
- background-size: contain;
- background-repeat: no-repeat;
- border-radius: var(--mediaItemRadiusSmall);
- flex: 0 0 auto;
- margin: 6px;
- image-rendering: -webkit-optimize-contrast;
+ background-size : contain;
+ background-repeat : no-repeat;
+ border-radius : var(--mediaItemRadiusSmall);
+ flex : 0 0 auto;
+ margin : 6px;
+ image-rendering : -webkit-optimize-contrast;
+
.mediaitem-artwork {
border-radius: var(--mediaItemRadiusSmall);
}
}
-.app-chrome .app-chrome-item > .app-playback-controls .actions {
- width: 42px;
- height: 42px;
- border-radius: 2px;
- flex: 0 0 auto;
- margin: 6px;
- display: flex;
+.app-chrome .app-chrome-item>.app-playback-controls .actions {
+ width : 42px;
+ height : 42px;
+ border-radius : 2px;
+ flex : 0 0 auto;
+ margin : 6px;
+ display : flex;
justify-content: center;
- align-items: center;
- filter: contrast(0.8);
+ align-items : center;
+ filter : contrast(0.8);
.lcdMenu {
- height: 100%;
- width: 100%;
- padding: 0px;
- margin: 0px;
- background: transparent;
- border: 0px;
- appearance: none;
- display: flex;
+ height : 100%;
+ width : 100%;
+ padding : 0px;
+ margin : 0px;
+ background : transparent;
+ border : 0px;
+ appearance : none;
+ display : flex;
justify-content: center;
- align-items: center;
- border-radius: 6px;
+ align-items : center;
+ border-radius : 6px;
&:focus {
outline: none;
@@ -1489,7 +1531,7 @@ div[data-type="musicVideo"] .info-rect .title::before {
&:active {
background: var(--selected-click);
- transform: scale(0.95);
+ transform : scale(0.95);
}
.svg-icon {
@@ -1498,17 +1540,17 @@ div[data-type="musicVideo"] .info-rect .title::before {
}
}
-.app-chrome .app-chrome-item > .app-playback-controls .playback-info {
- width: 100%;
- display: flex;
+.app-chrome .app-chrome-item>.app-playback-controls .playback-info {
+ width : 100%;
+ display : flex;
justify-content: center;
- align-items: center;
- flex-direction: column;
- position: relative;
- overflow: hidden;
+ align-items : center;
+ flex-direction : column;
+ position : relative;
+ overflow : hidden;
}
-.app-chrome .app-chrome-item > .app-playback-controls .playback-info > .song-progress {
+.app-chrome .app-chrome-item>.app-playback-controls .playback-info>.song-progress {
width: 100%;
}
@@ -1516,31 +1558,31 @@ div[data-type="musicVideo"] .info-rect .title::before {
background : transparent;
align-items : center;
justify-content: center;
- background: var(--color1);
- height: calc(100% - var(--chromeHeight2));
- width: 100%;
- display: flex;
- position: relative;
+ background : var(--color1);
+ height : calc(100% - var(--chromeHeight2));
+ width : 100%;
+ display : flex;
+ position : relative;
}
-.app-chrome .app-chrome-item > .app-playback-controls .song-artist-album {
- font-weight: 400;
- font-size: 12px;
- text-align: center;
- /*height: 1.2em;
- line-height: 1.2em;*/
- z-index: 1;
- align-items: center;
+.app-chrome .app-chrome-item>.app-playback-controls .song-artist-album {
+ font-weight : 400;
+ font-size : 12px;
+ text-align : center;
+ /*height : 1.2em;
+ line-height : 1.2em;*/
+ z-index : 1;
+ align-items : center;
justify-content: center;
- width: 80%;
- max-width: 340px;
- overflow: hidden;
+ width : 80%;
+ max-width : 340px;
+ overflow : hidden;
.song-artist-album-content {
font-weight: 400;
- font-size: 12px;
- text-align: center;
- width: 100%;
+ font-size : 12px;
+ text-align : center;
+ width : 100%;
&.song-artist-normal {
height: inherit;
@@ -1549,7 +1591,7 @@ div[data-type="musicVideo"] .info-rect .title::before {
&.song-artist-marquee {
- > marquee {
+ >marquee {
margin-bottom: -3px;
}
}
@@ -1565,66 +1607,67 @@ div[data-type="musicVideo"] .info-rect .title::before {
input[type="range"].web-slider.display--small::-webkit-slider-thumb {
-webkit-appearance: none;
- height: 14px;
- width: 14px;
- border-radius: 50%;
- background: rgb(50 50 50);
- cursor: default;
- box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
+ height : 14px;
+ width : 14px;
+ border-radius : 50%;
+ background : rgb(50 50 50);
+ cursor : default;
+ box-shadow : inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
}
/* Window is smaller <= 1023px width */
@media only screen and (max-width: 1120px) {
.display--small {
- display: inherit !important;;
+ display: inherit !important;
+ ;
.slider {
- width: 100%;
+ width : 100%;
z-index: 1;
}
.input-container {
- display: flex;
+ display : flex;
justify-content: center;
- align-items: center;
- width: 100%;
- padding-bottom: 10px;
+ align-items : center;
+ width : 100%;
+ padding-bottom : 10px;
}
input[type=range] {
-webkit-appearance: none;
- height: 4px;
- background: rgba(255, 255, 255, 0.4);
- border-radius: 5px;
- background-size: 70% 100%;
- background-repeat: no-repeat;
+ height : 4px;
+ background : rgba(255, 255, 255, 0.4);
+ border-radius : 5px;
+ background-size : 70% 100%;
+ background-repeat : no-repeat;
&::-webkit-slider-thumb {
-webkit-appearance: none;
- height: 14px;
- width: 14px;
- border-radius: 50%;
- background: rgb(50 50 50);
- cursor: default;
- box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
- transition: all var(--appleTransition);
+ height : 14px;
+ width : 14px;
+ border-radius : 50%;
+ background : rgb(50 50 50);
+ cursor : default;
+ box-shadow : inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
+ transition : all var(--appleTransition);
}
&::-webkit-slider-thumb:hover {
background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px);
- transform: scale(1.2);
+ transform : scale(1.2);
}
&::-webkit-slider-thumb:active {
background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px);
- transform: scale(1);
+ transform : scale(1);
}
&::-webkit-slider-runnable-track {
-webkit-appearance: none;
- box-shadow: none;
- border: none;
- background: transparent;
+ box-shadow : none;
+ border : none;
+ background : transparent;
}
}
}
@@ -1636,49 +1679,49 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
.flex-center {
- display: flex;
+ display : flex;
align-items: center;
- flex-wrap: wrap;
+ flex-wrap : wrap;
}
.md-container {
- width: 100%;
+ width : 100%;
position: relative;
}
.lyric-body {
-webkit-mask-image: -webkit-gradient(linear, left 95%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- overflow-y: scroll;
- overflow-x: hidden;
- display: flex;
- flex-flow: column;
- font-family: "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ overflow-y : scroll;
+ overflow-x : hidden;
+ display : flex;
+ flex-flow : column;
+ font-family : "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.lyric-body .no-lyrics {
- width: 100%;
+ width : 100%;
justify-content: center;
- align-items: center;
- font-weight: bold;
- font-size: 26px;
+ align-items : center;
+ font-weight : bold;
+ font-size : 26px;
}
.lyric-line {
- --bgSpeed: 1s;
- appearance: none;
- color: white;
- font-size: 26px;
- transform: scale(0.8);
+ --bgSpeed : 1s;
+ appearance : none;
+ color : white;
+ font-size : 26px;
+ transform : scale(0.8);
transform-origin: left center;
- transition: transform 0.5s var(--appleEase);
- opacity: 0.75;
- width: auto;
- display: inline-block;
- margin: 10px;
- margin-left: 5%;
- margin-right: 0px;
- overflow-wrap: break-word;
+ transition : transform 0.5s var(--appleEase);
+ opacity : 0.75;
+ width : auto;
+ display : inline-block;
+ margin : 10px;
+ margin-left : 5%;
+ margin-right : 0px;
+ overflow-wrap : break-word;
}
.lyric-line.active .verse {
@@ -1686,7 +1729,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
.lyric-line.active .verse.verse-active {
- opacity: 1;
+ opacity : 1;
transition: opacity 0.35s var(--appleEase);
}
@@ -1695,25 +1738,25 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
.lyric-line:hover::after {
- content: ' ';
- width: 100%;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- transform: scale(1.06);
- background: rgba(200, 200, 200, 0.1);
- pointer-events: none;
- border-radius: 10px;
+ content : ' ';
+ width : 100%;
+ height : 100%;
+ position : absolute;
+ top : 0;
+ left : 0;
+ transform : scale(1.06);
+ background : rgba(200, 200, 200, 0.1);
+ pointer-events : none;
+ border-radius : 10px;
-webkit-backface-visibility: hidden;
}
.lyric-line.active {
- --bgSpeed: 1s;
- opacity: 1;
- transform: scale(1);
+ --bgSpeed : 1s;
+ opacity : 1;
+ transform : scale(1);
/*background: var(--keyColor);*/
- transition: transform 0.2s var(--appleEase), opacity 0.35s var(--appleEase);
+ transition : transform 0.2s var(--appleEase), opacity 0.35s var(--appleEase);
}
.lyric-line:not(.active) {
@@ -1729,61 +1772,63 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
-.lyric-body:hover > .lyric-line:not(.active) {
+.lyric-body:hover>.lyric-line:not(.active) {
filter: none !important;
}
-.lyric-body > .lyric-line:not(.active) {
+
+.lyric-body>.lyric-line:not(.active) {
// transition: filter var(--appleEase) 0.5s ease;
}
.lyricWaiting {
- margin-bottom:10px;
- display: none;
+ margin-bottom: 10px;
+ display : none;
}
.lyric-line.active .lyricWaiting {
- display: inline-flex;
+ display : inline-flex;
animation: lyricWaitingLine 6s cubic-bezier(0.42, 0, 0.58, 1) infinite;
}
-.lyric-line.active .lyricWaiting > div {
- width: 10px;
- height: 10px;
- background: white;
+.lyric-line.active .lyricWaiting>div {
+ width : 10px;
+ height : 10px;
+ background : white;
border-radius: 50%;
- margin: 3px;
+ margin : 3px;
}
.lyrics-translation {
- font-size: 1.6rem;
+ font-size : 1.6rem;
font-weight: 450;
font-family: "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
- filter: contrast(0.5);
+ filter : contrast(0.5);
}
.lyric-footer {
- bottom: 0;
- height: 50px;
- width: 100%;
- position: absolute;
- z-index: 1000;
- opacity: 1;
- background: rgba(30, 30, 30, 0.8);
+ bottom : 0;
+ height : 50px;
+ width : 100%;
+ position : absolute;
+ z-index : 1000;
+ opacity : 1;
+ background : rgba(30, 30, 30, 0.8);
justify-content: center;
- align-items: center;
- display: none;
- transition: opacity 0.1s var(--appleEase);
+ align-items : center;
+ display : none;
+ transition : opacity 0.1s var(--appleEase);
}
-.lyric-body:hover + .lyric-footer, .lyric-footer:hover {
+.lyric-body:hover+.lyric-footer,
+.lyric-footer:hover {
display: flex;
}
.modular-fs .app-drawer .lyric-footer {
background: unset;
- display: flex;
- opacity: 0.3;
+ display : flex;
+ opacity : 0.3;
}
.modular-fs .app-drawer .lyric-footer:hover {
@@ -1791,23 +1836,23 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
.modular-fs .app-drawer .lyric-body .no-lyrics {
- height: 100%;
+ height : 100%;
display: flex;
}
@keyframes lyricWaitingLine {
0% {
- opacity: 0.25;
+ opacity : 0.25;
transform: scale(0.85);
}
50% {
- opacity: 1;
+ opacity : 1;
transform: scale(1);
}
100% {
- opacity: 0.25;
+ opacity : 0.25;
transform: scale(0.85);
}
}
@@ -1824,20 +1869,20 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.lyric-line2:before {
- background: var(--keyColor);
- content: '';
- width: 0%;
- height: 6px;
- position: absolute;
- bottom: -8px;
- left: 0;
+ background : var(--keyColor);
+ content : '';
+ width : 0%;
+ height : 6px;
+ position : absolute;
+ bottom : -8px;
+ left : 0;
border-radius: 10px;
- z-index: -1;
- transition: width var(--bgSpeed);
+ z-index : -1;
+ transition : width var(--bgSpeed);
}
.lyric-line2.active:before {
- width: 100%;
+ width : 100%;
transition: width var(--bgSpeed);
}
@@ -1848,64 +1893,105 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
/* Cider */
.more-btn-round {
- border-radius: 100%;
- background: rgba(100, 100, 100, 0.5);
- box-shadow: var(--ciderShadow-Generic);
- width: 32px;
- height: 32px;
- border: 0px;
- cursor: pointer;
- z-index: 5;
- display: flex;
+ border-radius : 100%;
+ background : rgba(100, 100, 100, 0.5);
+ box-shadow : var(--ciderShadow-Generic);
+ width : 32px;
+ height : 32px;
+ border : 0px;
+ cursor : pointer;
+ z-index : 5;
+ display : flex;
justify-content: center;
- align-items: center;
+ align-items : center;
&:hover {
filter: brightness(125%);
}
&:active {
- filter: brightness(75%);
- transform: scale(0.98);
+ filter : brightness(75%);
+ transform : scale(0.98);
transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase);
}
.svg-icon {
- width: 100%;
+ width : 100%;
background: #eee;
- --url: url("./views/svg/more.svg");
+ --url : url("./views/svg/more.svg");
+ }
+}
+
+.social-btn {
+ border-radius : 100%;
+ background : transparent;
+ height : 17px;
+ border : 0px;
+ cursor : pointer;
+ z-index : 69;
+ display : flex;
+ justify-content: center;
+ align-items : center;
+ float : right;
+}
+
+@media only screen and (min-width: 1133px) and (max-width: 1277px) {
+ .about-page {
+ .social-btn {
+ display: none !important;
+ }
}
}
.about-page {
.teamBtn {
- display: flex;
+ display : flex;
align-items: center;
- width: 100%;
- font-size: 14px;
- padding: 6px 16px;
- margin: 4px;
+ width : 100%;
+ font-size : 14px;
+ padding : 6px 16px;
+ margin : 4px;
- > img {
- width: 30px;
- margin: 0px 16px 0px 0px;
- pointer-events: none;
- border-radius: 100%;
- box-shadow: var(--mediaItemShadow);
+ >img {
+ width : 30px;
+ margin : 0px 16px 0px 0px;
+ pointer-events : none;
+ border-radius : 100%;
+ box-shadow : var(--mediaItemShadow);
image-rendering: -webkit-optimize-contrast;
}
}
.sponsorBtn {
- display: inline-flex;
+ display : inline-flex;
justify-content: center;
- align-items: center;
+ align-items : center;
- > img {
- width: 26px;
- margin: 0px 16px 0px 0px;
+ >img {
+ width : 26px;
+ margin : 0px 16px 0px 0px;
pointer-events: none;
}
+
+ &.githubBtn {
+ background-color: #211F1F;
+ }
+
+ &.kofiBtn {
+ background-color: #FBAA19;
+ }
+
+ &.opencollectiveBtn {
+ background-color: #7fadf2;
+ }
+
+ &.discordBtn {
+ background-color: #5865F2;
+ }
+
+ &.twitterBtn {
+ background-color: #1D9BF0;
+ }
}
}
@@ -1916,64 +2002,64 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
.folder-body {
- background: #ffffff0a;
+ background : #ffffff0a;
border-radius: 10px;
- padding: 1px 6px;
+ padding : 1px 6px;
.spinner {
- display: block;
- width: 100%;
- height: 32px;
+ display : block;
+ width : 100%;
+ height : 32px;
background-size: 16px;
}
}
}
#navigation-bar {
- width: 100%;
- background: rgba(0, 0, 0, 0.25);
- height: var(--navigationBarHeight);
- display: flex;
- align-items: center;
- padding: 0px 6px;
- z-index: 7;
- position: sticky;
- top: 0;
- left: 0;
+ width : 100%;
+ background : rgba(0, 0, 0, 0.25);
+ height : var(--navigationBarHeight);
+ display : flex;
+ align-items : center;
+ padding : 0px 6px;
+ z-index : 7;
+ position : sticky;
+ top : 0;
+ left : 0;
backdrop-filter: blur(32px);
//box-shadow: 0px 1px 0px rgba(185, 185, 185, 0.08);
- mix-blend-mode: hard-light;
+ mix-blend-mode : hard-light;
.nav-item {
- appearance: none;
- border: 0px;
- height: 32px;
- width: 40px;
- background: transparent;
- padding: 6px;
- display: flex;
+ appearance : none;
+ border : 0px;
+ height : 32px;
+ width : 40px;
+ background : transparent;
+ padding : 6px;
+ display : flex;
justify-content: center;
- align-items: center;
- color: rgba(200, 200, 200, 0.8);
- margin: 2px;
- border-radius: 6px;
- transition: transform .10s var(--appleEase);
+ align-items : center;
+ color : rgba(200, 200, 200, 0.8);
+ margin : 2px;
+ border-radius : 6px;
+ transition : transform .10s var(--appleEase);
&:active {
background: var(--selected-click);
- transform: scale(0.96);
+ transform : scale(0.96);
transition: transform 0s var(--appleEase);
}
- > svg {
- width: 8px;
+ >svg {
+ width : 8px;
pointer-events: none;
}
&:hover {
background: var(--selected);
- > svg {
+ >svg {
color: rgba(200, 200, 200, 1.0);
}
}
@@ -1981,41 +2067,44 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
.well {
- background: rgba(200, 200, 200, 0.05);
+ background : rgba(200, 200, 200, 0.05);
border-radius: 10px;
- padding: var(--contentInnerPadding);
- margin-top: 16px;
+ padding : var(--contentInnerPadding);
+ margin-top : 16px;
&.itemContainer {
- display: flex;
- flex-flow: wrap;
+ display : flex;
+ flex-flow : wrap;
justify-content: center;
- .cd-mediaitem-square-container{
+
+ .cd-mediaitem-square-container {
align-items: center;
}
+
.cd-mediaitem-square {
- width: 220px;
- height: 260px;
- display: inline-flex;
- flex: 0 0 auto;
- flex-direction: column;
- font-size: 14px;
+ width : 220px;
+ height : 260px;
+ display : inline-flex;
+ flex : 0 0 auto;
+ flex-direction : column;
+ font-size : 14px;
justify-content: center;
- align-items: center;
- border-radius: 6px;
- max-width: 240px;
- flex-grow: 1;
+ align-items : center;
+ border-radius : 6px;
+ max-width : 240px;
+ flex-grow : 1;
}
&.collection-list-square {
- display: grid;
+ display : grid;
grid-template-columns: repeat(4, minmax(200px, 1fr));
// screen size > 1200px
@media screen and (min-width: 1500px) {
- grid-template-columns: repeat(6, minmax(200px, 1fr));
+ grid-template-columns: repeat(5, minmax(200px, 1fr));
}
+
// less than 1100px
@media screen and (max-width: 1150px) {
grid-template-columns: repeat(3, minmax(200px, 1fr));
@@ -2024,24 +2113,24 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
}
}
-.cd-mediaitem-square-container{
- display: inline-flex;
- flex-direction: column;
+.cd-mediaitem-square-container {
+ display : inline-flex;
+ flex-direction : column;
justify-content: center;
}
-.reasonSP{
+.reasonSP {
// margin-left: 15px;
- color: rgb(167 163 163);
+ color : rgb(167 163 163);
font-weight: 500;
margin-left: 15px;
}
.text-overflow-elipsis {
- display: -webkit-box;
- min-width: 0px;
- overflow: hidden;
- text-overflow: ellipsis;
+ display : -webkit-box;
+ min-width : 0px;
+ overflow : hidden;
+ text-overflow : ellipsis;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
@@ -2050,811 +2139,24 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
animation: unset !important;
}
-.fullscreen-view-container {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: black;
- z-index: 99;
- display: flex;
- justify-content: center;
- align-items: center;
- opacity: 1;
-}
-
-.fullscreen-view {
- width: 100%;
- height: 100%;
- background: black;
- display: flex;
- justify-content: center;
- align-items: center;
-
- .fs-row {
- flex-grow: 1;
- }
-
- .playback-button--small.active {
- background-color: rgb(200 200 200 / 25%);
- }
-
- .playback-button--small {
- opacity: 0.7;
- }
-
- .right-col {
- height: 50vh;
- }
-
- .bg-artwork-container {
- display: block !important;
- }
-
- @media only screen and (max-width: 1121px) {
- .display--large {
- display: flex !important;
- }
- }
-
- .display--large {
- display: flex;
-
- .slider {
- width: 100%;
- z-index: 1;
- }
-
- .input-container {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%
- }
-
- .volume-button--small {
- border-radius: 6px;
- color: inherit;
- background-size: 16px;
- background-repeat: no-repeat;
- background-position: center;
- background-color: transparent;
- height: 15px;
- width: 30px;
- border: 0px;
- box-shadow: unset;
- opacity: 0.70;
- background-image: url("./assets/feather/volume-2.svg");
- }
-
- .volume-button--small:active {
- transform: scale(0.9);
- }
-
- .volume-button--small.active {
- background-image: url("./assets/feather/volume.svg");
- }
-
- input[type=range] {
- -webkit-appearance: none;
- height: 4px;
- background: rgba(255, 255, 255, 0.4);
- border-radius: 5px;
- background-size: 70% 100%;
- background-repeat: no-repeat;
-
- &::-webkit-slider-thumb {
- -webkit-appearance: none;
- height: 14px;
- width: 14px;
- border-radius: 50%;
- background: rgb(50 50 50);
- cursor: default;
- box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
- transition: all var(--appleTransition);
- }
-
- &::-webkit-slider-thumb:hover {
- background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px);
- transform: scale(1.2);
- }
-
- &::-webkit-slider-thumb:active {
- background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px);
- transform: scale(1);
- }
-
- &::-webkit-slider-runnable-track {
- -webkit-appearance: none;
- box-shadow: none;
- border: none;
- background: transparent;
- }
- }
- }
-
-
- .background {
- position: absolute;
- background-size: cover;
- width: 100%;
- height: 100%;
-
- .bgArtworkMaterial {
- position: absolute;
- width: 100%;
- height: 100%;
-
- .bg-artwork-container {
- z-index: unset;
- }
-
- .bg-artwork-container .bg-artwork {
- filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9);
- }
-
-
- }
- }
-
- .lyrics-col {
-
- height: 62vh;
- display: flex;
- justify-content: center;
- align-content: center;
- width: 80%;
-
- ::-webkit-scrollbar-thumb {
- box-shadow: unset;
- }
-
- &:hover ::-webkit-scrollbar-thumb {
- box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
- }
-
- .no-lyrics {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- }
-
- .lyric-line {
- font-size: 35px;
- }
-
- }
-
- .queue-col {
-
- width: 60vh;
- height: 62vh;
-
- .queue-title {
- opacity: 0.6;
- }
-
- .queue-panel > * {
- z-index: 3;
- }
-
- ::-webkit-scrollbar-thumb {
- box-shadow: unset;
- }
-
- &:hover ::-webkit-scrollbar-thumb {
- box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
- }
- }
-
- .tab-toggles {
- display: flex;
- position: absolute;
- bottom: 0;
- right: 0;
- width: 15vh;
- height: 5vh;
- justify-content: space-evenly;
-
- .volume {
- background-image: url("./assets/feathers/volume.svg");
- padding: 0.5vh;
- width: 2vh;
- height: 2vh;
- background-origin: content-box;
- background-repeat: no-repeat;
- }
-
- .queue {
- background-image: url("./assets/list.svg");
- padding: 0.5vh;
- width: 2.5vh;
- height: 2.5vh;
- background-origin: content-box;
- background-repeat: no-repeat;
- }
-
- .lyrics {
- background-image: url("./assets/quote-right.svg");
- padding: 0.5vh;
- width: 2.5vh;
- height: 2.5vh;
- background-origin: content-box;
- background-repeat: no-repeat;
- }
-
- .active {
- background-color: rgba(200, 200, 200, 0.7);
- border-radius: 3px;
- }
- }
-
- .artwork-col {
- justify-content: center;
- align-items: center;
- display: flex;
- flex-direction: column;
-
- .artwork {
- width: 50vh;
- height: 50vh;
- }
-
- .controls-parents {
- width: 50vh;
- }
-
- .app-playback-controls {
- .song-artist, .song-name {
- font-weight: 600;
- text-align: center;
- font-size: 0.9em;
- height: 1.2em;
- line-height: 0.9em;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 360px;
-
- .song-name-normal {
- height: inherit;
- }
-
- &.song-artist-marquee {
- > marquee {
- //margin-bottom: -3px;
- }
- }
- }
-
- .song-artist {
- font-size: 0.875em;
- font-weight: 400;
- }
-
- .song-name {
- width: unset !important;
- margin-top: 0.15vh;
- display: -webkit-box;
- line-height: 1.2;
- text-overflow: ellipsis;
- text-align: center;
- }
- }
-
- .app-playback-controls .playback-info {
- margin-top: 0.5vh;
- width: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- position: relative;
-
- input[type="range"] {
- width: 100%;
- }
-
- > div {
- width: 100%;
- text-align: center;
- }
-
-
- }
-
- .app-playback-controls .song-progress {
- @bgColor: transparent;
- //height: 16px;
- position: absolute;
- bottom: -1.5vh;
- left: 0px;
- background: @bgColor;
-
- .song-duration p {
- font-weight: 400;
- font-size: 10px;
- height: 1.2em;
- line-height: 1.3em;
- overflow: hidden;
- margin: 0 0 0 0.25em;
- }
-
- &:hover {
- > input[type=range] {
- &::-webkit-slider-thumb {
- opacity: 1;
- transform: scale(1);
- z-index: 1;
- }
- }
- }
-
- input[type=range] {
- appearance: none;
- width: 100%;
- height: 4px;
- background-color: rgb(200 200 200 / 10%);
- border-radius: 2px;
-
- &::-webkit-slider-thumb {
- opacity: 0;
- transform: scale(0.5);
- -webkit-appearance: none;
- appearance: none;
- width: 12px;
- height: 12px;
- border-radius: 100%;
- background: var(--songProgressColor);
- cursor: default;
- transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
- }
-
- &::-moz-range-thumb {
- width: 8px;
- height: 8px;
- border-radius: 100%;
- background: var(--songProgressColor);
- cursor: default;
- }
- }
- }
-
- .control-buttons {
- margin-top: 2vh;
- display: inline-flex;
- width: 100%;
- justify-content: center;
- }
-
- }
-}
-
-.mini-view {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
-
- .fs-row {
- flex-grow: 1;
- }
-
- .playback-button--small.active {
- background-color: rgb(200 200 200 / 25%);
- }
-
- .player-exit {
- z-index: 3;
- position: absolute;
- top: 5px;
- right: 5px;
- -webkit-app-region: no-drag;
- }
-
- .player-pin {
- z-index: 3;
- position: absolute;
- min-width: 20px;
- min-height: 20px;
- top: 5px;
- right: 30px;
- -webkit-app-region: no-drag;
- }
-
- #mini-pin {
- display: none;
- }
-
- .player-pin:hover #mini-pin {
- display: block;
- }
-
- .playback-button--small {
- opacity: 0.7;
- }
-
- .right-col {
- height: 50vh;
- }
-
- @media only screen and (max-width: 1121px) {
- .display--large {
- display: flex !important;
- }
- }
-
- .display--large {
- display: flex;
-
- .slider {
- width: 100%;
- z-index: 1;
- }
-
- .input-container {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%
- }
-
- .volume-button--small {
- border-radius: 6px;
- color: inherit;
- background-size: 16px;
- background-repeat: no-repeat;
- background-position: center;
- background-color: transparent;
- height: 15px;
- width: 30px;
- border: 0px;
- box-shadow: unset;
- opacity: 0.70;
- background-image: url("./assets/feather/volume-2.svg");
- }
-
- .volume-button--small:active {
- transform: scale(0.9);
- }
-
- .volume-button--small.active {
- background-image: url("./assets/feather/volume.svg");
- }
-
- input[type=range] {
- -webkit-appearance: none;
- height: 4px;
- background: rgba(255, 255, 255, 0.4);
- border-radius: 5px;
- background-size: 70% 100%;
- background-repeat: no-repeat;
-
- &::-webkit-slider-thumb {
- -webkit-appearance: none;
- height: 14px;
- width: 14px;
- border-radius: 50%;
- background: rgb(50 50 50);
- cursor: default;
- box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
- transition: all var(--appleTransition);
- }
-
- &::-webkit-slider-thumb:hover {
- background-image: radial-gradient(var(--songProgressColor) 2px, transparent 3px, transparent 10px);
- transform: scale(1.2);
- }
-
- &::-webkit-slider-thumb:active {
- background-image: radial-gradient(var(--songProgressColor) 3px, transparent 4px, transparent 10px);
- transform: scale(1);
- }
-
- &::-webkit-slider-runnable-track {
- -webkit-appearance: none;
- box-shadow: none;
- border: none;
- background: transparent;
- }
- }
- }
-
-
- .background {
- position: absolute;
- background-size: cover;
- width: 100%;
- height: 100%;
- -webkit-user-select: none;
- -webkit-app-region: drag;
-
- .bgArtworkMaterial {
- position: absolute;
- width: 100%;
- height: 100%;
-
- .bg-artwork-container {
- z-index: unset;
- }
-
- .bg-artwork-container .bg-artwork {
- filter: brightness(85%) saturate(95%) blur(180px) contrast(0.9) opacity(0.9);
- }
-
- .no-animation {
- animation: unset;
- }
- }
- }
-
-
- .lyrics-col {
-
- height: 62vh;
- display: flex;
- justify-content: center;
- align-content: center;
- width: 80%;
-
- ::-webkit-scrollbar-thumb {
- box-shadow: unset;
- }
-
- &:hover ::-webkit-scrollbar-thumb {
- box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
- }
-
- .no-lyrics {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- }
-
- .lyric-line {
- font-size: 35px;
- }
-
- }
-
- .queue-col {
-
- width: 60vh;
- height: 50vh;
-
- .queue-title {
- opacity: 0.6;
- }
-
- .queue-panel > * {
- z-index: 3;
- }
-
- ::-webkit-scrollbar-thumb {
- box-shadow: unset;
- }
-
- &:hover ::-webkit-scrollbar-thumb {
- box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
- }
- }
-
- .tab-toggles {
- display: flex;
- position: absolute;
- bottom: 0;
- right: 0;
- width: 15vh;
- height: 5vh;
- justify-content: space-evenly;
-
- .volume {
- background-image: url("./assets/feathers/volume.svg");
- padding: 0.5vh;
- width: 2vh;
- height: 2vh;
- background-origin: content-box;
- background-repeat: no-repeat;
- }
-
- .queue {
- background-image: url("./assets/list.svg");
- padding: 0.5vh;
- width: 2.5vh;
- height: 2.5vh;
- background-origin: content-box;
- background-repeat: no-repeat;
- }
-
- .lyrics {
- background-image: url("./assets/quote-right.svg");
- padding: 0.5vh;
- width: 2.5vh;
- height: 2.5vh;
- background-origin: content-box;
- background-repeat: no-repeat;
- }
-
- .active {
- background-color: rgba(200, 200, 200, 0.7);
- border-radius: 3px;
- }
- }
-
- .artwork-col {
- justify-content: center;
- align-items: center;
- display: flex;
- flex-direction: column;
-
- .artwork {
- width: 100%;
- height: 100%;
-
- .mediaitem-artwork {
- border-radius: unset;
- }
- }
-
- .controls-parents {
- width: 100%;
- position: absolute;
- background: #0000009e;
- backdrop-filter: blur(10px);
- bottom: 0px;
- z-index: 3;
- opacity: 0;
- padding: 3%;
-
- &:hover {
- opacity: 1;
- }
- }
-
-
- .app-playback-controls {
- -webkit-app-region: no-drag;
-
- .song-artist, .song-name {
- font-weight: 600;
- text-align: center;
- font-size: 0.9em;
- height: 1.2em;
- line-height: 0.9em;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 360px;
-
- .song-name-normal {
- height: inherit;
- }
-
- &.song-artist-marquee {
- > marquee {
- //margin-bottom: -3px;
- }
- }
- }
-
- .song-artist {
- font-size: 0.875em;
- font-weight: 400;
- }
-
- .song-name {
- width: unset !important;
- margin-top: 0.15vh;
- display: -webkit-box;
- line-height: 1.2;
- text-overflow: ellipsis;
- text-align: center;
- }
- }
-
- .app-playback-controls .playback-info {
- margin-top: 0.5vh;
- width: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- position: relative;
-
- input[type="range"] {
- width: 100%;
- }
-
- > div {
- width: 100%;
- text-align: center;
- }
-
-
- }
-
- .app-playback-controls .song-progress {
- @bgColor: transparent;
- //height: 16px;
- position: absolute;
- bottom: -3.5vh;
- left: 0px;
- background: @bgColor;
-
- .song-duration p {
- font-weight: 400;
- font-size: 10px;
- height: 1.2em;
- line-height: 1.3em;
- overflow: hidden;
- margin: 0 0 0 0.25em;
- }
-
- &:hover {
- > input[type=range] {
- &::-webkit-slider-thumb {
- opacity: 1;
- transform: scale(1);
- z-index: 1;
- }
- }
- }
-
- input[type=range] {
- appearance: none;
- width: 100%;
- height: 4px;
- background-color: rgb(200 200 200 / 10%);
- border-radius: 2px;
-
- &::-webkit-slider-thumb {
- opacity: 0;
- transform: scale(0.5);
- -webkit-appearance: none;
- appearance: none;
- width: 12px;
- height: 12px;
- border-radius: 100%;
- background: var(--songProgressColor);
- cursor: default;
- transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
- }
-
- &::-moz-range-thumb {
- width: 8px;
- height: 8px;
- border-radius: 100%;
- background: var(--songProgressColor);
- cursor: default;
- }
- }
- }
-
- .control-buttons {
- margin-top: 3.5vh;
- display: inline-flex;
- width: 100%;
- justify-content: center;
- }
-
- }
-}
+@import url("less/fullscreen.less");
+@import url("less/miniplayer.less");
// Cider App
#micaEffect {
- opacity:1;
+ opacity : 1;
// animation: micaEnter 1s ease-in-out forwards;
- filter: brightness(1) saturate(320%);
+ filter : brightness(1) saturate(320%);
+
@keyframes micaEnter {
0% {
- opacity: 0;
+ opacity : 0;
transform: translateY(10px);
}
+
100% {
- opacity: 1;
+ opacity : 1;
transform: translateY(0px);
}
}
@@ -2874,63 +2176,65 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
// Modular
.modular-fs {
.app-chrome.chrome-bottom {
- position: fixed;
- bottom: 0;
- left: 0;
- z-index: 14!important;
+ position : fixed;
+ bottom : 0;
+ left : 0;
+ z-index : 14 !important;
backdrop-filter: var(--glassFilter);
}
+
.app-navigation {
height: 100%;
}
+
.app-drawer {
- width: 100%;
- right: 0px;
- top: 0px;
- height: 100%;
+ width : 100%;
+ right : 0px;
+ top : 0px;
+ height : 100%;
border-radius: 0px;
- box-shadow: unset;
- background: black;
+ box-shadow : unset;
+ background : black;
.bgArtworkMaterial {
display: block;
&::before {
- top: -50%;
- left: -20%;
- width: 200VH;
+ top : -50%;
+ left : -20%;
+ width : 200VH;
height: 200VH;
}
- .bg-artwork-container{
+ .bg-artwork-container {
display: block !important;
}
}
.lyric-body {
justify-content: center;
- align-items: center;
- padding: 0px;
- margin: 0px;
- overflow: hidden;
- filter: drop-shadow(0px 4px 6px rgb(0 0 0 / 70%));
+ align-items : center;
+ padding : 0px;
+ margin : 0px;
+ overflow : hidden;
+ filter : drop-shadow(0px 4px 6px rgb(0 0 0 / 70%));
.lyric-line {
- pointer-events: none;
- font-weight: 600;
- font-size: 2em;
+ pointer-events : none;
+ font-weight : 600;
+ font-size : 2em;
transform-origin: center;
- animation: fsLyricIn var(--appleEase) .2s;
- opacity: 0.9;
+ animation : fsLyricIn var(--appleEase) .2s;
+ opacity : 0.9;
&:not(.active) {
- display: none;
- margin: 0;
+ display : none;
+ margin : 0;
transform: scale(1);
}
&.active {
- margin: 0;
+ margin : 0;
transform: scale(1);
}
}
@@ -2940,11 +2244,12 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
@keyframes fsLyricIn {
0% {
- opacity: 0;
+ opacity : 0;
transform: scale(0.98)
}
+
100% {
- opacity: 1;
+ opacity : 1;
transform: scale(1);
}
}
@@ -2960,7 +2265,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.replaycard-enter,
.replaycard-leave-to {
- opacity: 0;
+ opacity : 0;
transform: translateY(20px);
}
@@ -2981,7 +2286,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.modal-enter,
.modal-leave-to {
- opacity: 0;
+ opacity : 0;
transform: scale(1.10);
}
@@ -2997,40 +2302,40 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.wpfade_transform-enter-active,
.wpfade_transform-leave-active {
- --transitionTime: 0.2s;
- transition : opacity var(--transitionTime) var(--appleEase);
- will-change : opacity, transform;
+ --transitionTime: 0.2s;
+ transition : opacity var(--transitionTime) var(--appleEase);
+ will-change : opacity, transform;
}
.wpfade_transform-enter {
- opacity : 0;
- transform : unset;
- will-change: opacity;
+ opacity : 0;
+ transform : unset;
+ will-change: opacity;
}
.wpfade_transform-leave-to {
- opacity : 0;
- transform : unset;
- will-change: opacity;
+ opacity : 0;
+ transform : unset;
+ will-change: opacity;
}
.wpfade_transform_backwards-enter-active,
.wpfade_transform_backwards-leave-active {
- --transitionTime: 0.2s;
- transition : opacity var(--transitionTime) var(--appleEase);
+ --transitionTime: 0.2s;
+ transition : opacity var(--transitionTime) var(--appleEase);
}
.wpfade_transform_backwards-enter {
- opacity : 0;
- transform : unset;
- will-change: opacity;
+ opacity : 0;
+ transform : unset;
+ will-change: opacity;
}
.wpfade_transform_backwards-leave-to {
- opacity : 0;
- transform : unset;
- will-change: opacity;
+ opacity : 0;
+ transform : unset;
+ will-change: opacity;
}
.fabfade-enter-active,
@@ -3040,7 +2345,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.fabfade-enter,
.fabfade-leave-to {
- opacity: 0;
+ opacity : 0;
transform: scale(0.5);
}
@@ -3052,7 +2357,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.fsModeSwitch-enter,
.fsModeSwitch-leave-to {
transform: scale(1.10);
- opacity: 0;
+ opacity : 0;
}
.sidebartransition-enter-active,
@@ -3075,215 +2380,227 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
transform: translateX(400px);
}
-@media (prefers-color-scheme: dark) {
-
-}
+@media (prefers-color-scheme: dark) {}
:root {
- --gfx-closeBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjM2LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PmN2D9EAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEtJREFUGJWNkMENwDAIA1FGY/8hkn8HOAqPfBsFKvz1yZYtbqwAlUIB6saUAH2NJ4MvL4PLgK/x13LAGTSqEaVa1a0x7XvcmI3D1wbntaRbB2haYwAAAABJRU5ErkJggg==');
- --gfx-maxBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjU4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PlwQMBUAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAFBJREFUGJXV0LERgCAUBNHVsQADM3uwWWbojQIs47MEGhgAuS/eSw41qeFYqGlRA7iAm74DKLyrfRABoLrOgq+/hJXngi71BOoGZKBMHqhAbtMvQzel9pREAAAAAElFTkSuQmCC');
+ --gfx-closeBtn : url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjM2LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MzYtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PmN2D9EAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAEtJREFUGJWNkMENwDAIA1FGY/8hkn8HOAqPfBsFKvz1yZYtbqwAlUIB6saUAH2NJ4MvL4PLgK/x13LAGTSqEaVa1a0x7XvcmI3D1wbntaRbB2haYwAAAABJRU5ErkJggg==');
+ --gfx-maxBtn : url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjU4LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6NTgtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PlwQMBUAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAFBJREFUGJXV0LERgCAUBNHVsQADM3uwWWbojQIs47MEGhgAuS/eSw41qeFYqGlRA7iAm74DKLyrfRABoLrOgq+/hJXngi71BOoGZKBMHqhAbtMvQzel9pREAAAAAElFTkSuQmCC');
--gfx-restoreBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAIn2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgZGM6Zm9ybWF0PSJpbWFnZS9wbmciCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTAiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEyOjU1OjM3WiIKICAgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTEwLTA1VDE0OjI3OjI0LTA3OjAwIgogICB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTk5OWM2NWYtNDhhOS0wNjQyLWI2MTktZmJlYTExMmUxOGZiIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjY5MzMyOWNhLWNkNjctMzY0Zi04MzU1LTY5N2ZmYzI0ZDdlZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjgyZjQwYmU3LTE0YzItZjc0Ni1hZmE1LWQxYmIxNzAyMjM4OCIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSI+CiAgIDxwaG90b3Nob3A6VGV4dExheWVycz4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgcGhvdG9zaG9wOkxheWVyTmFtZT0i7qSiIgogICAgICBwaG90b3Nob3A6TGF5ZXJUZXh0PSLupKIiLz4KICAgIDwvcmRmOlNlcT4KICAgPC9waG90b3Nob3A6VGV4dExheWVycz4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0iY3JlYXRlZCIKICAgICAgeG1wTU06aW5zdGFuY2VJRD0ieG1wLmlpZDo4MmY0MGJlNy0xNGMyLWY3NDYtYWZhNS1kMWJiMTcwMjIzODgiCiAgICAgIHhtcE1NOnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIKICAgICAgeG1wTU06d2hlbj0iMjAyMC0wMi0xN1QxMjo1NTozN1oiLz4KICAgICA8cmRmOmxpCiAgICAgIHhtcE1NOmFjdGlvbj0ic2F2ZWQiCiAgICAgIHhtcE1NOmNoYW5nZWQ9Ii8iCiAgICAgIHhtcE1NOmluc3RhbmNlSUQ9InhtcC5paWQ6NjkzMzI5Y2EtY2Q2Ny0zNjRmLTgzNTUtNjk3ZmZjMjRkN2VkIgogICAgICB4bXBNTTpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiCiAgICAgIHhtcE1NOndoZW49IjIwMjAtMDItMTdUMTI6NTU6MzdaIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjEwLjEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjEtMTAtMDVUMTQ6Mjc6MjQtMDc6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PqiFCFwAAAGCaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRv0tCURTHP2lhmGFRQUODhDVZlELU0qD0C6pBDbJa9OWPQO3xnhHRGrQKBVFLv4b6C2oNmoOgKIJoC5qLWkpe56mgRJ7Luedzv/eew73ngiWcVjJ6/QBksjktOOF3zUcWXLZX7DTQQSu+qKKrM6HxMDXt64E6M971mbVqn/vXmpbjugJ1jcKjiqrlhCeFp9dzqsm7wu1KKrosfC7s0eSCwvemHivxm8nJEv+YrIWDAbC0CLuSVRyrYiWlZYTl5bgz6TWlfB/zJY54di4ksVu8C50gE/hxMcUYAYYYZETmIfrw0i8rauQPFPNnWZVcRWaVDTRWSJIih0fUNakel5gQPS4jzYbZ/7991RM+b6m6ww8NL4bx0QO2HSjkDeP72DAKJ2B9hqtsJX/1CIY/Rc9XNPchOLfg4rqixfbgchs6n9SoFi1KVnFLIgHvZ9AcgbZbsC+Welbe5/QRwpvyVTewfwC9ct659At2bGftHD0UJwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAHNJREFUGJWtkKEOwlAMRc+QM5AwQYJFoPjZCWb2YRPIaeRTLwfTLQs0UxzX3tumtxCog78UdVTbZmM8AmsdXIABeKH2ak221dDuamnUCjyA+WtbB0zAGXgT0ycSFk31kBky/moUeBLpbsl91wi6Nnbfs/g+7XOQq6ifjfkAAAAASUVORK5CYII=');
- --gfx-minBtn: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAGOmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wMi0xN1QxMzowMDozMloiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4NWQwZWRiMC1mZDAwLWI2NGYtOWVmYi1hMmI0NTg3MDVhOGEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDphMzAwMWUxYS0yOTE5LWU0NDktYjk0Yy1jMjEyMjQ4YTlmOGEiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHN0RXZ0OndoZW49IjIwMjAtMDItMTdUMTM6MDA6MzJaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8cmRmOkJhZz4gPHJkZjpsaSBwaG90b3Nob3A6TGF5ZXJOYW1lPSLupKEiIHBob3Rvc2hvcDpMYXllclRleHQ9Iu6koSIvPiA8L3JkZjpCYWc+IDwvcGhvdG9zaG9wOlRleHRMYXllcnM+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+FwvRXAAAABdJREFUGNNj/P//PwMxgHGIKPw/XDwDAOr1HuzlELLnAAAAAElFTkSuQmCC');
+ --gfx-minBtn : url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAGOmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wMi0xN1QxMzowMDozMloiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAyLTE3VDEzOjAwOjMyWiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4NWQwZWRiMC1mZDAwLWI2NGYtOWVmYi1hMmI0NTg3MDVhOGEiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDphMzAwMWUxYS0yOTE5LWU0NDktYjk0Yy1jMjEyMjQ4YTlmOGEiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3ODdmNzk5Yy00YjExLWU1NGEtYjIwZC02ODYxN2VkOWM1ZTIiIHN0RXZ0OndoZW49IjIwMjAtMDItMTdUMTM6MDA6MzJaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg1ZDBlZGIwLWZkMDAtYjY0Zi05ZWZiLWEyYjQ1ODcwNWE4YSIgc3RFdnQ6d2hlbj0iMjAyMC0wMi0xN1QxMzowMDozMloiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPiA8cmRmOkJhZz4gPHJkZjpsaSBwaG90b3Nob3A6TGF5ZXJOYW1lPSLupKEiIHBob3Rvc2hvcDpMYXllclRleHQ9Iu6koSIvPiA8L3JkZjpCYWc+IDwvcGhvdG9zaG9wOlRleHRMYXllcnM+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+FwvRXAAAABdJREFUGNNj/P//PwMxgHGIKPw/XDwDAOr1HuzlELLnAAAAAElFTkSuQmCC');
}
#apple-music-video-container {
background: black;
- position: absolute;
- float: left;
- display: none;
- width: 100%;
- height: 100%;
- bottom: 0;
- z-index: 100000;
+ position : absolute;
+ float : left;
+ display : none;
+ width : 100%;
+ height : 100%;
+ bottom : 0;
+ z-index : 100000;
}
#apple-music-video-container {
// AM Web Style Fullscreen Button
#player-fullscreen {
- background-size : 50%;
- background-position: center;
- background-repeat : no-repeat;
- filter : opacity(0.6);
- // filter: drop-shadow(0px 0px 4px rgb(0 0 0 / 80%));
- background-color : transparent;
- border-radius : 10px;
- transition : 0.2s ease-in-out filter;
- bottom : 0;
+ background-size : 50%;
+ background-position: center;
+ background-repeat : no-repeat;
+ filter : opacity(0.6);
+ // filter: drop-shadow(0px 0px 4px rgb(0 0 0 / 80%));
+ background-color : transparent;
+ border-radius : 10px;
+ transition : 0.2s ease-in-out filter;
+ bottom : 0;
- &:hover {
- filter : opacity(1);
- transition: 0.2s ease-in-out filter;
- }
+ &:hover {
+ filter : opacity(1);
+ transition: 0.2s ease-in-out filter;
+ }
}
// AM Web Style PiP Button
#player-pip {
- background-color: transparent;
- border-radius : 10px;
- bottom : 0;
- filter : opacity(0.6);
- transition : 0.2s ease-in-out filter;
+ background-color: transparent;
+ border-radius : 10px;
+ bottom : 0;
+ filter : opacity(0.6);
+ transition : 0.2s ease-in-out filter;
- &:hover {
- filter : opacity(1);
- transition: 0.2s ease-in-out filter;
- }
+ &:hover {
+ filter : opacity(1);
+ transition: 0.2s ease-in-out filter;
+ }
}
- .playback-info{
- position: absolute;
- width:100%;
- bottom: 0;
- padding: 20px 40px;
- background-image: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0.5) 50%);
- .song-artist{
- font-size: 1.7rem;
- font-weight: bold;
- }
- .song-name{
- font-size: 1.2rem;
- font-weight: bold;
- color:rgb(255,255,255,0.8);
- }
+
+ .playback-info {
+ position : absolute;
+ width : 100%;
+ bottom : 0;
+ padding : 20px 40px;
+ background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 50%);
+
+ .song-artist {
+ font-size : 1.7rem;
+ font-weight: bold;
+ }
+
+ .song-name {
+ font-size : 1.2rem;
+ font-weight: bold;
+ color : rgb(255, 255, 255, 0.8);
+ }
}
- input[type="range"]{
- align-self: center;
- height: 4px;
- border-radius: .5rem;
- margin-inline: 10px;
+
+ input[type="range"] {
+ align-self : center;
+ height : 4px;
+ border-radius: .5rem;
+ margin-inline: 10px;
}
-
- .song-progress input[type="range"]{
- appearance: initial;
- &::-webkit-slider-thumb {
- box-shadow: 0px 0px 0px #000000;
- border: 1px solid #39404D;
- background: #fff;
- height:0.7rem;
- width:0.7rem;
- border-radius: 50%;
- cursor: pointer;
- -webkit-appearance: none;
- }
+
+ .song-progress input[type="range"] {
+ appearance: initial;
+
+ &::-webkit-slider-thumb {
+ box-shadow : 0px 0px 0px #000000;
+ border : 1px solid #39404D;
+ background : #fff;
+ height : 0.7rem;
+ width : 0.7rem;
+ border-radius : 50%;
+ cursor : pointer;
+ -webkit-appearance: none;
+ }
}
}
#apple-music-video-player {
- position: absolute;
- top: 50%;
- width: 100%;
+ position : absolute;
+ top : 50%;
+ width : 100%;
transform: translate(0, -50%);
- height: 100%;
+ height : 100%;
}
#app.twopanel #apple-music-video-container {
- top:0;
+ top : 0;
bottom: unset;
}
+
.inactive {
opacity: 0;
}
+
#apple-music-video-player-controls {
position: absolute;
- z-index: 100001;
- float: left;
- width: 100%;
- height: 100%;
- .playback-info{
+ z-index : 100001;
+ float : left;
+ width : 100%;
+ height : 100%;
+
+ .playback-info {
.song-progress {
display: flex;
}
- .app-chrome-item.display--large{
- position: relative;
- display: flex;
+
+ .app-chrome-item.display--large {
+ position : relative;
+ display : flex;
flex-direction: row;
- flex-wrap: nowrap;
- align-items: center;
+ flex-wrap : nowrap;
+ align-items : center;
+
.playback-button {
- position: absolute;
- top: 50%;
- left: 50%;
+ position : absolute;
+ top : 50%;
+ left : 50%;
transform: translate(-50%, -50%);
- padding: 3px;
+ padding : 3px;
}
}
+
.song-artist-album {
- font-weight: 400;
- font-size: 12px;
- text-align: center;
- /*height: 1.2em;
- line-height: 1.2em;*/
- z-index: 1;
- align-items: center;
+ font-weight : 400;
+ font-size : 12px;
+ text-align : center;
+ /*height : 1.2em;
+ line-height : 1.2em;*/
+ z-index : 1;
+ align-items : center;
justify-content: center;
- width: 80%;
- max-width: 340px;
- overflow: hidden;
-
+ width : 80%;
+ max-width : 340px;
+ overflow : hidden;
+
.song-artist-album-content {
font-weight: 400;
- font-size: 12px;
- text-align: center;
- width: 100%;
-
+ font-size : 12px;
+ text-align : center;
+ width : 100%;
+
&.song-artist-normal {
height: inherit;
}
}
-
-
+
+
&.song-artist-marquee {
- > marquee {
+ >marquee {
margin-bottom: -3px;
}
}
}
-
+
}
}
#apple-music-video-player-controls #player-exit {
- position: absolute;
- z-index: 100001;
- float: left;
- width: 100%;
- margin: 10px;
- cursor: pointer;
+ position : absolute;
+ z-index : 100001;
+ float : left;
+ width : 100%;
+ margin-left : 10px;
+ margin-right : 10px;
+ margin-top : 10px;
+ margin-bottom: 10px;
+ cursor : pointer;
}
#apple-music-video-player-controls #player-pip {
- position: absolute;
- z-index: 100001;
- width: 32px;
- height: 32px;
- margin: 10px;
- right: 50px;
- border-radius: 100%;
- display: flex;
+ position : absolute;
+ z-index : 100001;
+ width : 32px;
+ height : 32px;
+ margin : 10px;
+ right : 50px;
+ border-radius : 100%;
+ display : flex;
justify-content: center;
- align-items: center;
- cursor: pointer;
+ align-items : center;
+ cursor : pointer;
}
-#apple-music-video-player-controls #player-pip > svg {
+#apple-music-video-player-controls #player-pip>svg {
width: 50%;
}
#apple-music-video-player-controls #player-fullscreen {
- position: absolute;
- z-index: 100001;
- width: 32px;
- height: 32px;
- margin: 10px;
- right: 0px;
- border-radius: 100%;
- display: flex;
+ position : absolute;
+ z-index : 100001;
+ width : 32px;
+ height : 32px;
+ margin : 10px;
+ right : 0px;
+ border-radius : 100%;
+ display : flex;
justify-content: center;
- align-items: center;
- cursor: pointer;
+ align-items : center;
+ cursor : pointer;
}
-#apple-music-video-player-controls #player-fullscreen > svg {
+#apple-music-video-player-controls #player-fullscreen>svg {
width: 70%;
}
@@ -3296,16 +2613,16 @@ img[src=""] {
}
div#captions {
- font-size: 1.2rem;
- position: absolute;
- top: 85%;
- text-align: center;
- width: auto;
- align-self: center;
- left: 50%;
- transform: translate(-50%, -50%);
- background: rgba(0, 0, 0, 0.6);
- color: yellow;
+ font-size : 1.2rem;
+ position : absolute;
+ top : 85%;
+ text-align : center;
+ width : auto;
+ align-self : center;
+ left : 50%;
+ transform : translate(-50%, -50%);
+ background : rgba(0, 0, 0, 0.6);
+ color : yellow;
white-space: pre-line;
font-family: 'Inter', 'Noto Sans JP', 'Source Han Sans SC', 'Source Han Sans HK', 'Source Han Sans SC', 'Source Han Sans HK', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans HK', 'Noto Sans KR', sans-serif;
}
@@ -3316,12 +2633,12 @@ div#captions {
.item-navigate:hover {
text-decoration: underline;
- cursor: pointer;
+ cursor : pointer;
}
.title-browse-sp {
- width: 100%;
- text-align: left;
+ width : 100%;
+ text-align : left;
margin-bottom: 2px;
}
@@ -3342,26 +2659,27 @@ div#captions {
}
body.no-gpu {
- --ciderShadow-Generic: var(--mediaItemShadow);
- --mediaItemShadow-Shadow: var(--mediaItemShadow);
+ --ciderShadow-Generic : var(--mediaItemShadow);
+ --mediaItemShadow-Shadow : var(--mediaItemShadow);
--mediaItemShadow-ShadowSubtle: var(--mediaItemShadow);
.bg-artwork-container {
- display: none;
+ display : none;
animation: none !important;
- .bg-artwork{
+
+ .bg-artwork {
animation: none !important;
}
}
.floating-header {
- background: black;
+ background : black;
backdrop-filter: unset;
}
.artworkContainer {
- animation: unset!important;
- opacity: 0.7;
+ animation: unset !important;
+ opacity : 0.7;
}
.info-rect-card {
@@ -3371,27 +2689,28 @@ body.no-gpu {
}
.menu-panel .menu-panel-body {
- background: rgb(30 30 30);
+ background : rgb(30 30 30);
backdrop-filter: unset;
}
#navigation-bar {
backdrop-filter: unset;
- mix-blend-mode: unset;
- background: rgb(0 0 0);
+ mix-blend-mode : unset;
+ background : rgb(0 0 0);
}
.addtoplaylist-panel {
.modal-window {
- background: rgb(18 18 18);
+ background : rgb(18 18 18);
backdrop-filter: unset;
}
}
.app-drawer {
backdrop-filter: unset;
- mix-blend-mode: unset;
- background: #1c1c1c;
+ mix-blend-mode : unset;
+ background : #1c1c1c;
+ transition: unset;
}
.wpfade-enter-active,
@@ -3422,35 +2741,47 @@ body.no-gpu {
.qrimg {
- width: -webkit-fill-available;
+ width : -webkit-fill-available;
max-block-size: -webkit-fill-available;
- object-fit: contain;
- overflow-x: hidden;
- overflow-y: hidden;
+ object-fit : contain;
+ overflow-x : hidden;
+ overflow-y : hidden;
+}
+
+.moreinfo-modal {
+ .modal-window {
+ height: max-content !important;
+
+ .modal-content {
+ height : max-content !important;
+ padding-block: 25px;
+ }
+ }
+
}
.equalizer-panel {
.modal-window {
- height: 330px;
+ height : 330px;
max-height: 330px;
- width: 740px;
- max-width: 800px;
- overflow: hidden;
+ width : 740px;
+ max-width : 800px;
+ overflow : hidden;
.info-header {
padding-left: 12px;
}
.visual-container {
- display: flex;
+ display : flex;
justify-content: center;
- align-items: center;
- overflow: hidden;
+ align-items : center;
+ overflow : hidden;
}
.modal-header {
- padding: 16px;
+ padding : 16px;
position: relative;
overflow: hidden;
@@ -3471,17 +2802,17 @@ body.no-gpu {
}
.input-container {
- display: inline-grid;
- width: 54px;
+ display : inline-grid;
+ width : 54px;
justify-items: center;
- font-size: 0.7em;
+ font-size : 0.7em;
}
.input-container.mini {
- display: inline-grid;
- width: 43px;
+ display : inline-grid;
+ width : 43px;
justify-items: center;
- font-size: 0.7em;
+ font-size : 0.7em;
}
.freq-header {
@@ -3489,30 +2820,30 @@ body.no-gpu {
}
.reset-button {
- width: 50%;
+ width : 50%;
margin-left: 25%;
- text-align: center;
+ text-align : center;
}
input.eq-slider {
-webkit-appearance: slider-vertical;
- width: 5%;
+ width : 5%;
}
input[type="number"] {
padding: unset;
- width: 55px;
+ width : 55px;
}
.header input.eq-slider {
-webkit-appearance: slider-vertical;
- width: 5%;
- opacity: 0;
+ width : 5%;
+ opacity : 0;
}
}
.modal-lowercontent {
- padding: 16px;
+ padding : 16px;
background-color: var(--modalBackground);
}
}
@@ -3523,22 +2854,22 @@ body[platform='darwin'] {
display: none;
}
- .app-chrome .app-chrome-item > .app-mainmenu {
- opacity: 0;
- width: 52px;
- pointer-events: none;
+ .app-chrome .app-chrome-item>.app-mainmenu {
+ opacity : 0;
+ width : 52px;
+ pointer-events : none;
-webkit-app-region: drag;
}
}
.percent {
- display: inline-block;
+ display : inline-block;
position: relative;
}
.percent::after {
- position: relative;
- right: 2em;
+ position : relative;
+ right : 2em;
transition: all .05s ease-in-out;
}
@@ -3552,7 +2883,7 @@ body[platform='darwin'] {
}
.playbackrate-text {
- align-items: end;
+ align-items : end;
margin-right: 5px;
}
@@ -3560,52 +2891,52 @@ body[platform='darwin'] {
color: transparent;
}
-.spatialproperties-panel.modal-fullscreen{
+.spatialproperties-panel.modal-fullscreen {
flex-direction: column;
-}
-
-.cursor {
- background: rgb(255 255 255 / 50%);
- width: 16px;
- height: 16px;
- position: fixed;
- z-index: 9999999999;
- pointer-events: none;
- border-radius: 100%;
- box-shadow: 0px 0px 0px 2px rgb(200 200 200 / 100%);
- top: 0;
- left: 0;
- display: none;
}
-.keybinds-page{
-
- .md-option-header {
- padding: 10px 0px;
- border-bottom: unset;
- border-top: unset;
- font-weight: 600;
- background: rgba(255, 255, 255, 0);
- font-size: 2em;
- }
+.cursor {
+ background : rgb(255 255 255 / 50%);
+ width : 16px;
+ height : 16px;
+ position : fixed;
+ z-index : 9999999999;
+ pointer-events: none;
+ border-radius : 100%;
+ box-shadow : 0px 0px 0px 2px rgb(200 200 200 / 100%);
+ top : 0;
+ left : 0;
+ display : none;
+}
- .md-option-header-sub {
- padding: 15px 10px;
- border-bottom: unset;
- border-top: unset;
- background: rgba(255, 255, 255, 0);
- font-weight: 600;
- font-size: 1.7em;
- }
+.keybinds-page {
- .md-option-line{
- padding: 15px 20px;
- font-size: 0.90em;
- }
+ .md-option-header {
+ padding : 10px 0px;
+ border-bottom: unset;
+ border-top : unset;
+ font-weight : 600;
+ background : rgba(255, 255, 255, 0);
+ font-size : 2em;
+ }
+
+ .md-option-header-sub {
+ padding : 15px 10px;
+ border-bottom: unset;
+ border-top : unset;
+ background : rgba(255, 255, 255, 0);
+ font-weight : 600;
+ font-size : 1.7em;
+ }
+
+ .md-option-line {
+ padding : 15px 20px;
+ font-size: 0.90em;
+ }
}
.content-inner.keybinds-page {
- top: var(--navigationBarHeight);
+ top : var(--navigationBarHeight);
padding: 15px;
}
@@ -3613,4 +2944,4 @@ body[platform='darwin'] {
@import url("less/linux.less");
@import url("less/compact.less");
@import url("less/directives.less");
-@import url("less/macosemu.less");
+@import url("less/macosemu.less");
\ No newline at end of file
diff --git a/src/renderer/views/app/app-content.ejs b/src/renderer/views/app/app-content.ejs
deleted file mode 100644
index ed10c736..00000000
--- a/src/renderer/views/app/app-content.ejs
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- <%- include('../svg/chevron-left.svg') %>
-
-
- <%- include('../svg/chevron-right.svg') %>
-
-
-
-
- <% for(var i=0; i < Object.keys(env.appRoutes).length ; i++) {%>
-
- v-on:enter="<%- env.appRoutes[i].onEnter %>"
- <%
- }
- %>
- :name="chrome.desiredPageTransition">
-
- <%- env.appRoutes[i].component %>
-
-
- <% } %>
-
-
-
- <%- include('../pages/madeforyou') %>');
- %>
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/renderer/views/app/app-navigation.ejs b/src/renderer/views/app/app-navigation.ejs
index 9ebaa5ed..2f072641 100644
--- a/src/renderer/views/app/app-navigation.ejs
+++ b/src/renderer/views/app/app-navigation.ejs
@@ -65,7 +65,7 @@
-
{{$root.getLz('term.sponsor')}}
-
-
-
+
+
+
{{$root.getLz('term.socials')}}
-
-
-
+
+
+
{{$root.getLz('term.ciderTeam')}}
-
+
-
+
{{ member.name }}
+
{{ member.role }}
-
+
@@ -64,25 +69,29 @@
name: 'cryptofyre',
link: 'https://github.com/cryptofyre',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/33162551?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/33162551?v=4',
+ twitter: 'https://twitter.com/cryptofyre'
},
{
name: 'Core',
link: 'https://github.com/coredev-uk',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/64542347?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/64542347?v=4',
+ twitter: 'https://twitter.com/core_hdd'
},
{
name: 'Quacksire',
link: 'https://github.com/quacksire',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/19170969?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/19170969?v=4',
+ twitter: 'https://twitter.com/duckdoquack'
},
{
name: 'booploops',
link: 'https://github.com/booploops',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/49113086?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/49113086?v=4',
+ twitter: 'https://twitter.com/boopl00ps'
},
{
name: 'vapormusic',
@@ -94,25 +103,29 @@
name: 'crypticplank',
link: 'https://github.com/crypticplank',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/52553007?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/52553007?v=4',
+ twitter: 'https://twitter.com/crypticplank'
},
{
name: 'Maikiwi',
link: 'https://github.com/maikirakiwi',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/74925636?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/74925636?v=4',
+ twitter: 'https://twitter.com/notmaikiwi'
},
{
name: 'yazninja',
link: 'https://github.com/yazninja',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/71800112?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/71800112?v=4',
+ twitter: 'https://twitter.com/YazNinjaa'
},
{
name: 'GamingLiamStudios',
link: 'https://github.com/GamingLiamStudios',
role: app.getLz('term.developer'),
- avatar: 'https://avatars.githubusercontent.com/u/58615717?v=4'
+ avatar: 'https://avatars.githubusercontent.com/u/58615717?v=4',
+ twitter: 'https://twitter.com/GLStudios_'
},
{
name: 'Amaru',
diff --git a/src/renderer/views/pages/artist.ejs b/src/renderer/views/pages/artist.ejs
index c926794f..539393dc 100644
--- a/src/renderer/views/pages/artist.ejs
+++ b/src/renderer/views/pages/artist.ejs
@@ -25,7 +25,8 @@
+ :style="{ 'color': '#' +hasHeroObject()?.textColor1 ?? ''}"
+ >
{
app.mk.play()
})" :aria-label="app.getLz('term.play')"><%- include("../svg/play.svg") %>
@@ -178,11 +179,21 @@
return this.data.attributes?.editorialArtwork?.centeredFullscreenBackground.url
} else if(this.data.attributes?.editorialArtwork?.bannerUber) {
return this.data.attributes?.editorialArtwork?.bannerUber.url
- }else if(this.data.attributes?.editorialArtwork?.subscriptionHero){
+ } else if(this.data.attributes?.editorialArtwork?.subscriptionHero){
return this.data.attributes?.editorialArtwork?.subscriptionHero.url
}
return false;
},
+ hasHeroObject() {
+ if(this.data.attributes?.editorialArtwork?.centeredFullscreenBackground){
+ return this.data.attributes?.editorialArtwork?.centeredFullscreenBackground
+ } else if(this.data.attributes?.editorialArtwork?.bannerUber) {
+ return this.data.attributes?.editorialArtwork?.bannerUber
+ } else if(this.data.attributes?.editorialArtwork?.subscriptionHero){
+ return this.data.attributes?.editorialArtwork?.subscriptionHero
+ }
+ return [];
+ },
isHeaderVisible(visible) {
this.headerVisible = visible
},
diff --git a/src/renderer/views/pages/audiolabs.ejs b/src/renderer/views/pages/audiolabs.ejs
index 9d477b71..9d621ddd 100644
--- a/src/renderer/views/pages/audiolabs.ejs
+++ b/src/renderer/views/pages/audiolabs.ejs
@@ -1,5 +1,5 @@
\ No newline at end of file
diff --git a/src/renderer/views/pages/cider-multiroom.ejs b/src/renderer/views/pages/cider-multiroom.ejs
index 4c8b306b..e9550e76 100644
--- a/src/renderer/views/pages/cider-multiroom.ejs
+++ b/src/renderer/views/pages/cider-multiroom.ejs
@@ -1,13 +1,14 @@
+
\ No newline at end of file
diff --git a/src/renderer/views/pages/cider-profile.ejs b/src/renderer/views/pages/cider-profile.ejs
new file mode 100644
index 00000000..f0abd54a
--- /dev/null
+++ b/src/renderer/views/pages/cider-profile.ejs
@@ -0,0 +1,67 @@
+
+
\ No newline at end of file
diff --git a/src/renderer/views/pages/groupings.ejs b/src/renderer/views/pages/groupings.ejs
index 3c05eefb..612c00cd 100644
--- a/src/renderer/views/pages/groupings.ejs
+++ b/src/renderer/views/pages/groupings.ejs
@@ -17,7 +17,7 @@
+ :items="recom.relationships.children ? recom.relationships.children.data : recom.relationships.contents.data">
diff --git a/src/renderer/views/pages/installed-themes.ejs b/src/renderer/views/pages/installed-themes.ejs
index 6a4b2563..453fd424 100644
--- a/src/renderer/views/pages/installed-themes.ejs
+++ b/src/renderer/views/pages/installed-themes.ejs
@@ -1,10 +1,12 @@
-
\ No newline at end of file
+ -->
\ No newline at end of file
diff --git a/src/renderer/views/pages/library-artists copy.ejs b/src/renderer/views/pages/library-artists copy.ejs
deleted file mode 100644
index f1871d04..00000000
--- a/src/renderer/views/pages/library-artists copy.ejs
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{$root.getLz('term.sortOrder.ascending')}}
- {{$root.getLz('term.sortOrder.descending')}}
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/renderer/views/pages/library-recentlyadded.ejs b/src/renderer/views/pages/library-recentlyadded.ejs
index 9f5b2151..b65150c9 100644
--- a/src/renderer/views/pages/library-recentlyadded.ejs
+++ b/src/renderer/views/pages/library-recentlyadded.ejs
@@ -1,13 +1,13 @@
@@ -75,21 +120,125 @@
template: '#cider-library-songs',
data: function () {
return {
+ // currentPage is oneIndexed
+ currentPage: 1,
library: this.$root.library,
mediaItemSize: "compact",
+ pageSize: 250,
prefs: this.$root.cfg.libraryPrefs.songs,
- app : this.$root
+ app: this.$root
}
},
mounted() {
+ document.querySelector("#app-content")
+ .addEventListener("scroll", this.handleScroll)
this.$root.getLibrarySongsFull()
},
- methods: {
- sayHello: function () {
- alert('Hello world!');
+ destroyed() {
+ document.querySelector("#app-content")
+ .removeEventListener("scroll", this.handleScroll)
+ },
+ watch: {
+ 'library.songs.displayListing.length': function () {
+ if (this.isInfinite) {
+ // If a search reduces the number of things to show, we want to limit
+ // the number of songs shown as well. This is to prevent you scrolling
+ // to load your entire library, searching for one song, and then having
+ // th re-render the entire library
+ if (this.currentPage > this.numPages) {
+ this.currentPage = this.numPages;
+ }
+ }
},
- play: function () {
+ 'prefs.scroll': function () {
+ // When changing modes, set the page to 1. This is primarily to
+ // prevent going to a high page (e.g., 50) and then switching to infinite
+ // and showing 12.5k songs
+ this.currentPage = 1;
+ }
+ },
+ computed: {
+ isInfinite: function () {
+ return this.prefs.scroll === "infinite"
+ },
+ currentSlice: function () {
+ if (this.isInfinite) {
+ return this.library.songs.displayListing.slice(
+ 0, this.currentPage * this.pageSize
+ );
+ } else {
+ const startingPage = Math.min(this.numPages, this.currentPage);
+ return this.library.songs.displayListing.slice(
+ (startingPage - 1) * this.pageSize,
+ startingPage * this.pageSize
+ );
+ }
+ },
+ numPages: function () {
+ return Math.ceil(this.library.songs.displayListing.length / this.pageSize) || 1;
+ },
+ pagesToShow: function () {
+ let start = this.currentPage - 2;
+ let end = this.currentPage + 2;
+
+ if (start < 1) {
+ end += (1 - start);
+ start = 1;
+ }
+
+ const endDifference = end - this.numPages;
+ if (endDifference > 0) {
+ end = this.numPages;
+ start = Math.max(1, start - endDifference);
+ }
+
+ const array = [];
+ for (let idx = start; idx <= end; idx++) {
+ array.push(idx);
+ }
+ return array;
+ }
+ },
+ methods: {
+ // Infinite Scrolling
+ handleScroll: function (event) {
+ if (this.isInfinite &&
+ this.currentPage < this.numPages &&
+ event.target.scrollTop >= event.target.scrollHeight - event.target.clientHeight) {
+ this.currentPage += 1;
+ }
+ },
+ // Pagination
+ isCurrentPage: function (idx) {
+ return idx === this.currentPage ||
+ (idx === this.numPages && this.currentPage > this.numPages);
+ },
+ changePage: function (event) {
+ const value = event.target.valueAsNumber;
+
+ if (!isNaN(value) && value >= 1 && value <= this.numPages) {
+ this.currentPage = value;
+ }
+ },
+ goToPage: function (page) {
+ this.currentPage = page;
+ },
+ goToPrevious: function () {
+ if (this.currentPage > 1) {
+ this.currentPage -= 1;
+ }
+ },
+ goToNext: function () {
+ if (this.currentPage < this.numPages) {
+ this.currentPage += 1;
+ }
+ },
+ goToEnd: function () {
+ this.currentPage = this.numPages;
+ },
+ // Miscellaneous
+ play: function () {
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
@@ -101,11 +250,11 @@
let query = this.app.library.songs.displayListing.map(item => new MusicKit.MediaItem(item));
if (!app.mk.queue.isEmpty)
- app.mk.queue.splice(0, app.mk.queue._itemIDs.length);
+ app.mk.queue.splice(0, app.mk.queue._itemIDs.length);
app.mk.stop().then(() => {
- if (app.mk.shuffleMode == 1) {
- shuffleArray(query)
- }
+ if (app.mk.shuffleMode == 1) {
+ shuffleArray(query)
+ }
app.mk.queue.append(query)
app.mk.changeToMediaAtIndex(0)
});
diff --git a/src/renderer/views/pages/new/library-songs.ejs b/src/renderer/views/pages/new/library-songs.ejs
deleted file mode 100644
index a739868f..00000000
--- a/src/renderer/views/pages/new/library-songs.ejs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/src/renderer/views/pages/recordLabel.ejs b/src/renderer/views/pages/recordLabel.ejs
index 014440ea..5b96224b 100644
--- a/src/renderer/views/pages/recordLabel.ejs
+++ b/src/renderer/views/pages/recordLabel.ejs
@@ -10,93 +10,102 @@
size="220" type="artists">
-
+
{{ data.attributes.name }}
-
+
-
About
+ {{ $root.getLz("term.about") }}
-
{{ app.showingPlaylist.attributes.description.standard }}
-
-
-
-
-
-
-
{{ data.views["latest-releases"].attributes.title ?? ""}}
-
-
-
{{app.getLz('term.seeAll')}}
+
{{ $root.showingPlaylist.attributes.description.standard }}
+
-
-
+
+
+
+
{{ data.views["latest-releases"].attributes.title ?? ""}}
+
+
+
+ {{ $root.getLz('term.seeAll') }}
+
+
+
+
+
-
-
-
{{ data.views["top-releases"].attributes.title ?? ""}}
+
+
+
{{ data.views["top-releases"].attributes.title ?? "" }}
+
+
+
+ {{ $root.getLz('term.seeAll') }}
+
+
-
- {{app.getLz('term.seeAll')}}
-
-
-
-
+
+
-
-
-
-
Playlists
+
+
+
+
{{ $root.getLz('term.playlists') }}
+
+
+
+ {{ $root.getLz('term.seeAll') }}
+
+
-
- {{app.getLz('term.seeAll')}}
-
-
-
-
+
+
\ No newline at end of file
diff --git a/src/renderer/views/pages/search.ejs b/src/renderer/views/pages/search.ejs
index 966404e8..602b6c75 100644
--- a/src/renderer/views/pages/search.ejs
+++ b/src/renderer/views/pages/search.ejs
@@ -1,5 +1,22 @@
-
-
\ No newline at end of file
diff --git a/src/renderer/views/pages/themes-github.ejs b/src/renderer/views/pages/themes-github.ejs
index 95635852..a5f7dbab 100644
--- a/src/renderer/views/pages/themes-github.ejs
+++ b/src/renderer/views/pages/themes-github.ejs
@@ -1,5 +1,7 @@
-
+ -->
\ No newline at end of file
diff --git a/src/renderer/views/pages/zoo.ejs b/src/renderer/views/pages/zoo.ejs
index b8c955b7..e9a2d92d 100644
--- a/src/renderer/views/pages/zoo.ejs
+++ b/src/renderer/views/pages/zoo.ejs
@@ -1,5 +1,6 @@