commit
d63e29ea0b
84 changed files with 2551 additions and 1402 deletions
|
@ -8,7 +8,7 @@ executors:
|
||||||
|
|
||||||
orbs: # Add orbs to your configuration
|
orbs: # Add orbs to your configuration
|
||||||
jira: circleci/jira@1.0.5 # invokes the Jira orb, making its commands accessible
|
jira: circleci/jira@1.0.5 # invokes the Jira orb, making its commands accessible
|
||||||
|
gh: circleci/github-cli@2.1
|
||||||
# The jobs for this project
|
# The jobs for this project
|
||||||
jobs:
|
jobs:
|
||||||
prepare-build:
|
prepare-build:
|
||||||
|
@ -111,14 +111,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: ~/Cider/
|
at: ~/Cider/
|
||||||
- run:
|
- gh/install
|
||||||
name: Installing GitHub Command Line Interface
|
|
||||||
command: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
|
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt install -y gh
|
|
||||||
- run:
|
- run:
|
||||||
name: Move Build Files
|
name: Move Build Files
|
||||||
command: |
|
command: |
|
||||||
|
@ -142,12 +135,13 @@ jobs:
|
||||||
echo "Attempting to create release for Cider v${APP_VERSION} on the ${CIRCLE_BRANCH} branch.";
|
echo "Attempting to create release for Cider v${APP_VERSION} on the ${CIRCLE_BRANCH} branch.";
|
||||||
if [[ "${APP_VERSION}" = *"beta"* ]]; then
|
if [[ "${APP_VERSION}" = *"beta"* ]]; then
|
||||||
echo $'**Beta Release**\nA full changelog is unavailable, but you can view the branch comparison [here](https://github.com/ciderapp/cider/compare/stable...main).\nThese builds are considered bleeding edge, expect bugs and please do not use this as a representation of the fu ll app.\nOur full support disclaimer can be found [here](https://docs.cider.sh/support/disclaimer#support-nightly-beta-releases).' > release-notes.md
|
echo $'**Beta Release**\nA full changelog is unavailable, but you can view the branch comparison [here](https://github.com/ciderapp/cider/compare/stable...main).\nThese builds are considered bleeding edge, expect bugs and please do not use this as a representation of the fu ll app.\nOur full support disclaimer can be found [here](https://docs.cider.sh/support/disclaimer#support-nightly-beta-releases).' > release-notes.md
|
||||||
|
gh release create "v${APP_VERSION}" --prerelease --title "Cider Version ${APP_VERSION} (${CIRCLE_BRANCH})" --notes-file release-notes.md -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
|
||||||
|
curl http://129.146.42.180/api/v1/github/sync/main
|
||||||
else
|
else
|
||||||
echo $'**Stable Release**\nA full changelog is unavailable, but you can view the branch comparison [here](https://github.com/ciderapp/cider/compare/stable...main).\nThese are the most stable builds we can provide. If you experience any issues, please report them [here](https://github.com/ciderapp/cider/issues/new).\nOur full support disclaimer can be found [here](https://docs.cider.sh/support/disclaimer#support-releases).' > release-notes.md
|
echo $'**Stable Release**\nA full changelog is unavailable, but you can view the branch comparison [here](https://github.com/ciderapp/cider/compare/stable...main).\nThese are the most stable builds we can provide. If you experience any issues, please report them [here](https://github.com/ciderapp/cider/issues/new).\nOur full support disclaimer can be found [here](https://docs.cider.sh/support/disclaimer#support-releases).' > release-notes.md
|
||||||
|
gh release create "v${APP_VERSION}" --title "Cider Version ${APP_VERSION} (${CIRCLE_BRANCH})" --notes-file release-notes.md -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
|
||||||
|
curl http://129.146.42.180/api/v1/github/sync/stable
|
||||||
fi;
|
fi;
|
||||||
gh release create "v${APP_VERSION}" --title "Cider Version ${APP_VERSION} (${CIRCLE_BRANCH})" --notes-file release-notes.md -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
|
# Orchestrate our job run sequence
|
||||||
workflows:
|
workflows:
|
||||||
|
|
26
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
26
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
|
@ -25,7 +25,7 @@ body:
|
||||||
placeholder: Tell us how you did it
|
placeholder: Tell us how you did it
|
||||||
value: "1. Clicked on..."
|
value: "1. Clicked on..."
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: environment
|
id: environment
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -33,12 +33,30 @@ body:
|
||||||
description: |
|
description: |
|
||||||
Examples:
|
Examples:
|
||||||
- **OS**: Ubuntu 20.04
|
- **OS**: Ubuntu 20.04
|
||||||
- **App Version** and/or **Commit ID**: 1.0.0 c9d43be
|
- **Desktop Environment (if applicable)**: i3wm
|
||||||
|
- **App Version**: 1.5.5-beta.22
|
||||||
|
- **Commit ID (if available)**: c9d43be
|
||||||
|
|
||||||
To find app version, Cider Menu -> About
|
*To find the app version, Cider Menu -> About*
|
||||||
value: |
|
value: |
|
||||||
- OS:
|
- OS:
|
||||||
- App Version and/or Commit ID:
|
- Desktop Environment:
|
||||||
|
- App Version:
|
||||||
|
- Commit ID:
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: download
|
||||||
|
attributes:
|
||||||
|
label: How did you download the software?
|
||||||
|
options:
|
||||||
|
- Microsoft Store
|
||||||
|
- GitHub
|
||||||
|
- Winget
|
||||||
|
- Winget (Nightly)
|
||||||
|
- Chocolatey
|
||||||
|
- Flathub
|
||||||
|
- AUR
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|
35
.github/workflows/build-macos.yml
vendored
35
.github/workflows/build-macos.yml
vendored
|
@ -23,7 +23,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
language: [ 'javascript' ]
|
node-version: [ 18 ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: maxim-lobanov/setup-xcode@v1
|
- uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
@ -34,6 +34,16 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v2.2.2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Run Version Script
|
- name: Run Version Script
|
||||||
env:
|
env:
|
||||||
GH_REQUEST_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
GH_REQUEST_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
|
@ -41,6 +51,9 @@ jobs:
|
||||||
sudo chmod +x resources/version.sh && ./resources/version.sh || true
|
sudo chmod +x resources/version.sh && ./resources/version.sh || true
|
||||||
echo "APP_VERSION=$(node -p -e 'require("./package.json").version')" >>$GITHUB_ENV
|
echo "APP_VERSION=$(node -p -e 'require("./package.json").version')" >>$GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Clear node_airtunes2 cache
|
||||||
|
run: rm -rf ~/Library/pnpm/store/v3/tmp/cf5bc2de2629636ca224995234b8eaa1 || true
|
||||||
|
|
||||||
- name: Sign in to EVS
|
- name: Sign in to EVS
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install --upgrade castlabs-evs
|
python3 -m pip install --upgrade castlabs-evs
|
||||||
|
@ -49,12 +62,9 @@ jobs:
|
||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: brew install automake #libtool autoconf
|
run: brew install automake #libtool autoconf
|
||||||
|
|
||||||
- name: Clear node_airtunes2 cache
|
|
||||||
run: sudo rm -rf /Users/runner/Library/Caches/Yarn/v6/.tmp/cf5bc2de2629636ca224995234b8eaa1 || true
|
|
||||||
|
|
||||||
- name: Install and Configure Node Modules
|
- name: Install and Configure Node Modules
|
||||||
run: |
|
run: |
|
||||||
yarn install
|
pnpm install
|
||||||
cp resources/verror-types node_modules/@types/verror/index.d.ts
|
cp resources/verror-types node_modules/@types/verror/index.d.ts
|
||||||
cp resources/macPackager.js node_modules/app-builder-lib/out/macPackager.js
|
cp resources/macPackager.js node_modules/app-builder-lib/out/macPackager.js
|
||||||
rm -r node_modules/pouchdb-node/node_modules/leveldown || true
|
rm -r node_modules/pouchdb-node/node_modules/leveldown || true
|
||||||
|
@ -70,7 +80,7 @@ jobs:
|
||||||
APPLE_ID_PASSWORD: ${{ secrets.APPLEIDPASS }}
|
APPLE_ID_PASSWORD: ${{ secrets.APPLEIDPASS }}
|
||||||
PSC_NAME: ${{ secrets.PSC_NAME }}
|
PSC_NAME: ${{ secrets.PSC_NAME }}
|
||||||
DEVELOPER_DIR: /Applications/Xcode_12.4.app/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_12.4.app/Contents/Developer
|
||||||
run: yarn dist:universalNotWorking -p never
|
run: pnpm dist:universalNotWorking -p never
|
||||||
|
|
||||||
- name: Add license to DMG
|
- name: Add license to DMG
|
||||||
run: npx dmg-license resources/license.json dist/*.dmg
|
run: npx dmg-license resources/license.json dist/*.dmg
|
||||||
|
@ -125,3 +135,16 @@ jobs:
|
||||||
repo_token: ${{ secrets.RELEASE_TOKEN }}
|
repo_token: ${{ secrets.RELEASE_TOKEN }}
|
||||||
file: dist/Cider-${{ env.APP_VERSION }}-universal.pkg
|
file: dist/Cider-${{ env.APP_VERSION }}-universal.pkg
|
||||||
tag: v${{ env.APP_VERSION }}
|
tag: v${{ env.APP_VERSION }}
|
||||||
|
- name: Trigger Bot Sync (main)
|
||||||
|
uses: indiesdev/curl@v1.1
|
||||||
|
with:
|
||||||
|
url: http://129.146.42.180/api/v1/github/sync/main
|
||||||
|
log-response: true
|
||||||
|
timeout: 60000
|
||||||
|
- name: Trigger Bot Sync (stable)
|
||||||
|
uses: indiesdev/curl@v1.1
|
||||||
|
with:
|
||||||
|
url: http://129.146.42.180/api/v1/github/sync/stable
|
||||||
|
log-response: true
|
||||||
|
timeout: 60000
|
||||||
|
|
||||||
|
|
71
.github/workflows/cider-chore.yml
vendored
71
.github/workflows/cider-chore.yml
vendored
|
@ -1,71 +0,0 @@
|
||||||
name: Cider Chores
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update-lockfile:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [ 18 ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
# Make sure the actual branch is checked out when running on pull requests
|
|
||||||
ref: ${{ github.head_ref }}
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2.2.2
|
|
||||||
with:
|
|
||||||
version: 7
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
|
|
||||||
- name: Update lockfile
|
|
||||||
run: pnpm i --lockfile-only
|
|
||||||
|
|
||||||
- name: Commit Updated Lockfile
|
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4.14.1
|
|
||||||
with:
|
|
||||||
commit_message: "chore: Updated Lockfile"
|
|
||||||
commit_user_name: "cider-chore[bot]"
|
|
||||||
commit_user_email: "cider-chore[bot]@users.noreply.github.com"
|
|
||||||
|
|
||||||
prettier:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [ 18 ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
# Make sure the actual branch is checked out when running on pull requests
|
|
||||||
ref: ${{ github.head_ref }}
|
|
||||||
|
|
||||||
- name: Prettify code
|
|
||||||
run: npm run prettier
|
|
||||||
|
|
||||||
- name: Commit Prettier Code
|
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4.14.1
|
|
||||||
with:
|
|
||||||
commit_message: "chore: Prettified Code\n [ci skip]"
|
|
||||||
commit_user_name: "cider-chore[bot]"
|
|
||||||
commit_user_email: "cider-chore[bot]@users.noreply.github.com"
|
|
118
.github/workflows/cider-chores.yml
vendored
Normal file
118
.github/workflows/cider-chores.yml
vendored
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
name: Cider Chores
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-lockfile:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [18]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Make sure the actual branch is checked out when running on pull requests
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v2.2.2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: Update lockfile
|
||||||
|
run: pnpm i --lockfile-only
|
||||||
|
|
||||||
|
- name: Commit Updated Lockfile
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4.14.1
|
||||||
|
with:
|
||||||
|
commit_message: "chore: Updated Lockfile"
|
||||||
|
commit_user_name: "cider-chore[bot]"
|
||||||
|
commit_user_email: "cider-chore[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
prettier:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [18]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Make sure the actual branch is checked out when running on pull requests
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
|
- name: Prettify code
|
||||||
|
run: npm run format:write
|
||||||
|
|
||||||
|
- name: Commit Prettier Code
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4.14.1
|
||||||
|
with:
|
||||||
|
commit_message: "chore: Prettified Code\n [ci skip]"
|
||||||
|
commit_user_name: "cider-chore[bot]"
|
||||||
|
commit_user_email: "cider-chore[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
update-i18n-source:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [18]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Update Source Files
|
||||||
|
run: cp src/i18n/en_US.json src/i18n/source/en_US.json
|
||||||
|
|
||||||
|
- name: Commit Updated Source File
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4.14.1
|
||||||
|
with:
|
||||||
|
commit_message: "chore: Updated i18n Source\n [ci skip]"
|
||||||
|
commit_user_name: "cider-chore[bot]"
|
||||||
|
commit_user_email: "cider-chore[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
|
||||||
|
synchronize-with-crowdin:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ false }} # disable for now
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: crowdin action
|
||||||
|
uses: crowdin/github-action@1.4.13
|
||||||
|
with:
|
||||||
|
upload_translations: true
|
||||||
|
download_translations: false
|
||||||
|
project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||||
|
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||||
|
source: '/src/i18n/source/**.*'
|
||||||
|
translation: '/src/i18n/%locale_with_underscore%.json'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
|
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||||
|
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
37
.github/workflows/pr-chores.yml
vendored
Normal file
37
.github/workflows/pr-chores.yml
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
name: PR Chores
|
||||||
|
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linter-check:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
node: [14]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout 🛎
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup pnpm 🚧F
|
||||||
|
uses: pnpm/action-setup@v2.2.2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Setup node env 🏗
|
||||||
|
uses: actions/setup-node@v3.4.1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
check-latest: true
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
|
- name: Install dependencies 👨🏻💻
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Run linter 👀
|
||||||
|
uses: wearerequired/lint-action@v2
|
||||||
|
with:
|
||||||
|
prettier: true
|
||||||
|
prettier_args: "'**/*.{js,json,ts,css,vue,less}'"
|
2
.github/workflows/stale-issues.yml
vendored
2
.github/workflows/stale-issues.yml
vendored
|
@ -19,4 +19,4 @@ jobs:
|
||||||
stale-issue-label: "stale"
|
stale-issue-label: "stale"
|
||||||
stale-pr-label: "stale"
|
stale-pr-label: "stale"
|
||||||
exempt-all-assignees: true
|
exempt-all-assignees: true
|
||||||
exempt-issue-labels: 'more-info,work-in-progress,accessibility-feature,help-wanted'
|
exempt-issue-labels: 'more-info,work-in-progress,accessibility-feature,help-wanted,persist'
|
||||||
|
|
1
.npmrc
1
.npmrc
|
@ -3,4 +3,3 @@ public-hoist-pattern=*
|
||||||
shamefully-hoist=true
|
shamefully-hoist=true
|
||||||
auto-install-peers=true
|
auto-install-peers=true
|
||||||
strict-peer-dependencies=false
|
strict-peer-dependencies=false
|
||||||
store-dir=.pnpm-store
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
src/renderer/apple-hls*
|
src/renderer/*hls*.js
|
||||||
build/*
|
build/*
|
||||||
src/renderer/lib/*
|
src/renderer/lib/*
|
||||||
*.min.*
|
*.min.*
|
||||||
|
.pnpm-store
|
||||||
|
|
15
.prettierrc
15
.prettierrc
|
@ -1,2 +1,13 @@
|
||||||
bracketSameLine: true
|
{
|
||||||
printWidth: 240
|
"printWidth": 600,
|
||||||
|
"singleAttributePerLine": true,
|
||||||
|
"bracketSameLine": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "src/renderer/main/**/*.js",
|
||||||
|
"options": {
|
||||||
|
"singleAttributePerLine": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<br><br>
|
<br><br>
|
||||||
<img src="https://img.shields.io/github/stars/ciderapp/Cider?label=Stars" alt="GitHub Stars"/>
|
<img src="https://img.shields.io/github/stars/ciderapp/Cider?label=Stars" alt="GitHub Stars"/>
|
||||||
<img src="https://img.shields.io/github/forks/ciderapp/Cider?label=Forks" alt="GitHub Forks"/>
|
<img src="https://img.shields.io/github/forks/ciderapp/Cider?label=Forks" alt="GitHub Forks"/>
|
||||||
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/cider-music"><img src="https://badges.crowdin.net/cider-music/localized.svg"></a>
|
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/cider-music"><img src="https://badges.crowdin.net/cider-i18n/localized.svg"></a>
|
||||||
<br>
|
<br>
|
||||||
<a target="_blank" href="https://ko-fi.com/cryptofyre"><img src="https://img.shields.io/badge/Buy%20Us%20a%20Coffee-donate-B48C69?logo=Ko-fi&logoColor=FFFFFF" alt="Buy Me A Coffee"/></a>
|
<a target="_blank" href="https://ko-fi.com/cryptofyre"><img src="https://img.shields.io/badge/Buy%20Us%20a%20Coffee-donate-B48C69?logo=Ko-fi&logoColor=FFFFFF" alt="Buy Me A Coffee"/></a>
|
||||||
<a target="_blank" href="https://opencollective.com/ciderapp"><img src="https://img.shields.io/opencollective/all/ciderapp?color=%237FADF2&label=Backers%20and%20Sponsors&logo=opencollective" alt="Open Collective"/></a>
|
<a target="_blank" href="https://opencollective.com/ciderapp"><img src="https://img.shields.io/opencollective/all/ciderapp?color=%237FADF2&label=Backers%20and%20Sponsors&logo=opencollective" alt="Open Collective"/></a>
|
||||||
|
|
3
crowdin.yml
Normal file
3
crowdin.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
files:
|
||||||
|
- source: /src/i18n/source/en_US.json
|
||||||
|
translation: /src/i18n/%locale_with_underscore%.json
|
29
package.json
29
package.json
|
@ -2,7 +2,7 @@
|
||||||
"name": "cider",
|
"name": "cider",
|
||||||
"applicationId": "Cider",
|
"applicationId": "Cider",
|
||||||
"productName": "Cider",
|
"productName": "Cider",
|
||||||
"version": "1.5.6",
|
"version": "1.5.7",
|
||||||
"description": "A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance in mind.",
|
"description": "A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance in mind.",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
"pack": "electron-builder --dir",
|
"pack": "electron-builder --dir",
|
||||||
"dist": "npm run build && electron-builder",
|
"dist": "npm run build && electron-builder",
|
||||||
"dist:macarm": "npm run build && electron-builder --mac --arm64",
|
"dist:macarm": "npm run build && electron-builder --mac --arm64",
|
||||||
|
"dist:linuxdir": "npm run build && electron-builder --linux dir",
|
||||||
"slim-build:macarm": "ditto --arch arm64 ./dist/mac-universal/Cider.app ./dist/mac-universal/arm64/Cider.app",
|
"slim-build:macarm": "ditto --arch arm64 ./dist/mac-universal/Cider.app ./dist/mac-universal/arm64/Cider.app",
|
||||||
"slim-build:macintel": "ditto --arch x86_64 ./dist/mac-universal/Cider.app ./dist/mac-universal/x86_x64/Cider.app",
|
"slim-build:macintel": "ditto --arch x86_64 ./dist/mac-universal/Cider.app ./dist/mac-universal/x86_x64/Cider.app",
|
||||||
"dist:universalNotWorking": "npm run build && electron-builder --mac --universal",
|
"dist:universalNotWorking": "npm run build && electron-builder --mac --universal",
|
||||||
|
@ -36,11 +37,12 @@
|
||||||
"msft": "npm run build && electron-builder -c msft-package.json",
|
"msft": "npm run build && electron-builder -c msft-package.json",
|
||||||
"mstest": "npm run build && electron-builder -c msft-test.json",
|
"mstest": "npm run build && electron-builder -c msft-test.json",
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"postinstall": "electron-builder install-app-deps",
|
||||||
"prettier": "npx prettier --write '**/*.{js,json,ts,css,less}'"
|
"format:check": "npx prettier --check \"src/**/*.{js,json,ts,less}\"",
|
||||||
|
"format:write": "npx prettier --write \"src/**/*.{js,json,ts,less}\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/electron": "^4.0.0",
|
"@sentry/electron": "^4.0.2",
|
||||||
"@sentry/integrations": "^7.8.1",
|
"@sentry/integrations": "^7.13.0",
|
||||||
"adm-zip": "0.4.10",
|
"adm-zip": "0.4.10",
|
||||||
"airtunes2": "git+https://github.com/ciderapp/node_airtunes2.git",
|
"airtunes2": "git+https://github.com/ciderapp/node_airtunes2.git",
|
||||||
"castv2-client": "^1.2.0",
|
"castv2-client": "^1.2.0",
|
||||||
|
@ -56,7 +58,7 @@
|
||||||
"electron-window-state": "^5.0.3",
|
"electron-window-state": "^5.0.3",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
"get-port": "5.1.1",
|
"get-port": "5.1.1",
|
||||||
"jimp": "^0.16.1",
|
"jimp": "^0.16.2",
|
||||||
"lastfmapi": "^0.1.1",
|
"lastfmapi": "^0.1.1",
|
||||||
"mdns-js": "git+https://github.com/ciderapp/node-mdns-js.git",
|
"mdns-js": "git+https://github.com/ciderapp/node-mdns-js.git",
|
||||||
"mpris-service": "^2.1.2",
|
"mpris-service": "^2.1.2",
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
"run-script-os": "^1.1.6",
|
"run-script-os": "^1.1.6",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"ts-md5": "1.2.11",
|
"ts-md5": "1.2.11",
|
||||||
|
"upnp-mediarenderer-client": "git+https://github.com/vapormusic/node-upnp-mediarenderer-client.git",
|
||||||
"v8-compile-cache": "^2.3.0",
|
"v8-compile-cache": "^2.3.0",
|
||||||
"wallpaper": "5.0.1",
|
"wallpaper": "5.0.1",
|
||||||
"ws": "^8.8.1",
|
"ws": "^8.8.1",
|
||||||
|
@ -77,17 +80,18 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/adm-zip": "^0.5.0",
|
"@types/adm-zip": "^0.5.0",
|
||||||
"@types/discord-rpc": "4.0.3",
|
"@types/discord-rpc": "4.0.3",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.14",
|
||||||
|
"@types/node": "^18.7.18",
|
||||||
"@types/qrcode-terminal": "^0.12.0",
|
"@types/qrcode-terminal": "^0.12.0",
|
||||||
"@types/ws": "^8.5.3",
|
"@types/ws": "^8.5.3",
|
||||||
"@types/node": "^18.7.13",
|
|
||||||
"electron": "git+https://github.com/castlabs/electron-releases.git",
|
"electron": "git+https://github.com/castlabs/electron-releases.git",
|
||||||
"electron-builder": "^23.0.2",
|
"electron-builder": "^23.3.3",
|
||||||
"electron-builder-notarize-pkg": "^1.2.0",
|
"electron-builder-notarize-pkg": "^1.2.0",
|
||||||
"electron-webpack": "^2.8.2",
|
"electron-webpack": "^2.8.2",
|
||||||
"less": "^4.1.3",
|
"less": "^4.1.3",
|
||||||
"musickit-typescript": "^1.2.4",
|
"musickit-typescript": "^1.2.4",
|
||||||
"typescript": "^4.7.4",
|
"prettier": "2.7.1",
|
||||||
|
"typescript": "^4.8.3",
|
||||||
"vue-devtools": "^5.1.4",
|
"vue-devtools": "^5.1.4",
|
||||||
"webpack": "~5.74.0"
|
"webpack": "~5.74.0"
|
||||||
},
|
},
|
||||||
|
@ -114,9 +118,9 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
"electronVersion": "20.1.0",
|
"electronVersion": "20.1.3",
|
||||||
"electronDownload": {
|
"electronDownload": {
|
||||||
"version": "20.1.0+wvcus",
|
"version": "20.1.3+wvcus",
|
||||||
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
|
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
|
||||||
},
|
},
|
||||||
"appId": "cider",
|
"appId": "cider",
|
||||||
|
@ -224,5 +228,8 @@
|
||||||
"NSUserNotificationAlertStyle": "alert"
|
"NSUserNotificationAlertStyle": "alert"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"electronWebpack": {
|
||||||
|
"devtool": "source-map"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
568
pnpm-lock.yaml
generated
568
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -543,6 +543,7 @@
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop.description": "Pwevent wooped twacks fwom being scwobbwed ow dispwayed in the Nyow Pwaying wist on Wast.fm.",
|
"settings.option.connectivity.lastfmScrobble.filterLoop.description": "Pwevent wooped twacks fwom being scwobbwed ow dispwayed in the Nyow Pwaying wist on Wast.fm.",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterTypes": "Fiwtew Media Types (Wast.fm)",
|
"settings.option.connectivity.lastfmScrobble.filterTypes": "Fiwtew Media Types (Wast.fm)",
|
||||||
"settings.option.connectivity.lastfmScrobble.manualToken": "Entew Wast.fm Token Manyuawwy",
|
"settings.option.connectivity.lastfmScrobble.manualToken": "Entew Wast.fm Token Manyuawwy",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.manualToken.link": "Cwick hewe to get a Wast.fm token",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connectError": "Wast.fm Connyection Timed Out",
|
"settings.notyf.connectivity.lastfmScrobble.connectError": "Wast.fm Connyection Timed Out",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Wast.fm Connyection Successfuw",
|
"settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Wast.fm Connyection Successfuw",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connecting": "Connyecting to Wast.fm...",
|
"settings.notyf.connectivity.lastfmScrobble.connecting": "Connyecting to Wast.fm...",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"notification.updatingLibrarySongs": "Updating library songs...",
|
"notification.updatingLibrarySongs": "Updating library songs...",
|
||||||
"notification.updatingLibraryAlbums": "Updating library albums...",
|
"notification.updatingLibraryAlbums": "Updating library albums...",
|
||||||
"notification.updatingLibraryArtists": "Updating library artists...",
|
"notification.updatingLibraryArtists": "Updating library artists...",
|
||||||
|
"notification.buildingPlaylistCache": "Building Playlist Cache...",
|
||||||
"term.variables": "Variables",
|
"term.variables": "Variables",
|
||||||
"term.appleInc": "Apple Inc.",
|
"term.appleInc": "Apple Inc.",
|
||||||
"term.appleMusic": "Apple Music",
|
"term.appleMusic": "Apple Music",
|
||||||
|
@ -260,6 +261,7 @@
|
||||||
"action.removeFromQueue.success": "Removed from Queue",
|
"action.removeFromQueue.success": "Removed from Queue",
|
||||||
"action.removeFromQueue.error": "Error Removing from Queue",
|
"action.removeFromQueue.error": "Error Removing from Queue",
|
||||||
"action.createPlaylist": "Create a New Playlist",
|
"action.createPlaylist": "Create a New Playlist",
|
||||||
|
"action.addToPlaylist.duplicate": "Item already exists in playlist. Do you want to continue?",
|
||||||
"action.addToPlaylist": "Add to Playlist",
|
"action.addToPlaylist": "Add to Playlist",
|
||||||
"action.removeFromPlaylist": "Remove from Playlist",
|
"action.removeFromPlaylist": "Remove from Playlist",
|
||||||
"action.addToFavorites": "Add to Favorites",
|
"action.addToFavorites": "Add to Favorites",
|
||||||
|
@ -494,6 +496,7 @@
|
||||||
"settings.option.visual.theme.viewInfo": "View Info",
|
"settings.option.visual.theme.viewInfo": "View Info",
|
||||||
"settings.option.visual.theme.github.available": "Available",
|
"settings.option.visual.theme.github.available": "Available",
|
||||||
"settings.option.visual.theme.github.applied": "Applied",
|
"settings.option.visual.theme.github.applied": "Applied",
|
||||||
|
"settings.notyf.visual.theme.updateAvailable": "[Themes] {{ theme }} has an update available",
|
||||||
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
||||||
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
||||||
"settings.header.visual.plugin": "Plugin",
|
"settings.header.visual.plugin": "Plugin",
|
||||||
|
@ -529,7 +532,13 @@
|
||||||
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
|
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.clientName": "Client Name",
|
"settings.option.connectivity.discordRPC.clientName": "Client Name",
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause",
|
"settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause",
|
||||||
"settings.option.connectivity.discordRPC.hideButtons": "Hide buttons on Discord Rich Presence",
|
"settings.option.connectivity.discordRPC.showActivityButtons": "Show Activity Buttons",
|
||||||
|
"settings.option.connectivity.discordRPC.firstButton": "First Activity Button",
|
||||||
|
"settings.option.connectivity.discordRPC.secondButton": "Second Activity Button",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.listenOnCider": "Listen on Cider",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.viewOnAppleMusic": "View on Apple Music",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.viewOnOtherMusicServices": "View on Other Music Services",
|
||||||
|
"settings.option.connectivity.discordRPC.showSongLink": "Show Song.link button instead of Apple Music button on Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.hideTimestamp": "Hide timestamp on Discord Rich Presence",
|
"settings.option.connectivity.discordRPC.hideTimestamp": "Hide timestamp on Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.detailsFormat": "Details Format",
|
"settings.option.connectivity.discordRPC.detailsFormat": "Details Format",
|
||||||
"settings.option.connectivity.discordRPC.stateFormat": "State Format",
|
"settings.option.connectivity.discordRPC.stateFormat": "State Format",
|
||||||
|
@ -542,6 +551,7 @@
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (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.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.filterTypes": "Filter Media Types (Last.fm)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.filterTypes.description": "Prevent tracks of the selected media types from being scrobbled or displayed in the Now Playing list on Last.fm.",
|
||||||
"settings.option.connectivity.lastfmScrobble.manualToken": "Enter Last.fm Token Manually",
|
"settings.option.connectivity.lastfmScrobble.manualToken": "Enter Last.fm Token Manually",
|
||||||
"settings.option.connectivity.lastfmScrobble.manualToken.link": "Click here to get a Last.fm token",
|
"settings.option.connectivity.lastfmScrobble.manualToken.link": "Click here to get a Last.fm token",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection Timed Out",
|
"settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection Timed Out",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"i18n.languageName": "Magyar",
|
"i18n.languageName": "Magyar",
|
||||||
"i18n.languageNameEnglish": "Hungarian",
|
"i18n.languageNameEnglish": "Hungarian",
|
||||||
"i18n.category": "main",
|
"i18n.category": "main",
|
||||||
"i18n.authors": "@Amaru",
|
"i18n.authors": "@Amaru @BenjaminStonawski",
|
||||||
"app.name": "Cider",
|
"app.name": "Cider",
|
||||||
"date.format": "${y} ${m} ${d}",
|
"date.format": "${y} ${m} ${d}",
|
||||||
"dialog.cancel": "Mégsem",
|
"dialog.cancel": "Mégsem",
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
"term.logout": "Kijelentkezés",
|
"term.logout": "Kijelentkezés",
|
||||||
"term.login": "Bejelentkezés",
|
"term.login": "Bejelentkezés",
|
||||||
"term.quickNav": "Főmenü",
|
"term.quickNav": "Főmenü",
|
||||||
"term.cast": "Tükrözés",
|
|
||||||
"term.about": "Névjegy",
|
"term.about": "Névjegy",
|
||||||
"term.privateSession": "Privát hallgatás",
|
"term.privateSession": "Privát hallgatás",
|
||||||
"term.disablePrivateSession": "Privát hallgatás kikapcsolása",
|
"term.disablePrivateSession": "Privát hallgatás kikapcsolása",
|
||||||
|
@ -32,6 +31,12 @@
|
||||||
"term.miniplayer": "Minilejátszó",
|
"term.miniplayer": "Minilejátszó",
|
||||||
"term.history": "Előzmények",
|
"term.history": "Előzmények",
|
||||||
"term.search": "Keresés",
|
"term.search": "Keresés",
|
||||||
|
"term.scroll": "Görgetési mód",
|
||||||
|
"term.scroll.infinite": "Végtelen",
|
||||||
|
"term.scroll.paged": "${songsPerPage} oldalanként",
|
||||||
|
"term.live": "ÉLŐ",
|
||||||
|
"term.showSearch": "Keresési mező megjelenítése",
|
||||||
|
"term.hideSearch": "Keresési mező elrejtése",
|
||||||
"term.library": "Könyvtár",
|
"term.library": "Könyvtár",
|
||||||
"term.listenNow": "Hallgatás most",
|
"term.listenNow": "Hallgatás most",
|
||||||
"term.browse": "Böngészés",
|
"term.browse": "Böngészés",
|
||||||
|
@ -41,8 +46,8 @@
|
||||||
"term.albums": "Albumok",
|
"term.albums": "Albumok",
|
||||||
"term.artists": "Előadók",
|
"term.artists": "Előadók",
|
||||||
"term.podcasts": "Podcastok",
|
"term.podcasts": "Podcastok",
|
||||||
"term.charts": "Listák",
|
|
||||||
"term.playlists": "Lejátszási listák",
|
"term.playlists": "Lejátszási listák",
|
||||||
|
"term.charts": "Listák",
|
||||||
"term.playlist": "Lejátszási lista",
|
"term.playlist": "Lejátszási lista",
|
||||||
"term.newPlaylist": "Új lejátszási lista",
|
"term.newPlaylist": "Új lejátszási lista",
|
||||||
"term.newPlaylistFolder": "Új mappa",
|
"term.newPlaylistFolder": "Új mappa",
|
||||||
|
@ -52,10 +57,12 @@
|
||||||
"term.navigateBack": "Visszalépés",
|
"term.navigateBack": "Visszalépés",
|
||||||
"term.navigateForward": "Előrelépés",
|
"term.navigateForward": "Előrelépés",
|
||||||
"term.play": "Lejátszás",
|
"term.play": "Lejátszás",
|
||||||
|
"term.playpause": "Lejátszás/Megállítás",
|
||||||
"term.pause": "Megállítás",
|
"term.pause": "Megállítás",
|
||||||
"term.stop": "Leállítás",
|
"term.stop": "Leállítás",
|
||||||
"term.previous": "Előző",
|
"term.previous": "Előző",
|
||||||
"term.next": "Következő",
|
"term.next": "Következő",
|
||||||
|
"term.skip": "Átugrás",
|
||||||
"term.shuffle": "Keverés",
|
"term.shuffle": "Keverés",
|
||||||
"term.enableShuffle": "Keverés bekapcsolása",
|
"term.enableShuffle": "Keverés bekapcsolása",
|
||||||
"term.disableShuffle": "Keverés kikapcsolása",
|
"term.disableShuffle": "Keverés kikapcsolása",
|
||||||
|
@ -178,6 +185,7 @@
|
||||||
"term.top": "Top",
|
"term.top": "Top",
|
||||||
"term.version": "Verzió",
|
"term.version": "Verzió",
|
||||||
"term.noVideos": "Nincs találat",
|
"term.noVideos": "Nincs találat",
|
||||||
|
"term.plugins": "Plug-in-ok",
|
||||||
"term.plugin": "Plug-in",
|
"term.plugin": "Plug-in",
|
||||||
"term.pluginMenu": "Plug-in Menü",
|
"term.pluginMenu": "Plug-in Menü",
|
||||||
"term.pluginMenu.none": "Nem találhatóak interaktív pluginok",
|
"term.pluginMenu.none": "Nem találhatóak interaktív pluginok",
|
||||||
|
@ -194,6 +202,22 @@
|
||||||
"term.confirmLogout": "Biztosan ki szeretnél jelentkezni?",
|
"term.confirmLogout": "Biztosan ki szeretnél jelentkezni?",
|
||||||
"term.creditDesignedBy": "Készítette ${authorUsername}",
|
"term.creditDesignedBy": "Készítette ${authorUsername}",
|
||||||
"term.discNumber": "${discNumber}. lemez",
|
"term.discNumber": "${discNumber}. lemez",
|
||||||
|
"term.reload": "Biztosan újraindítod a Cider-t?",
|
||||||
|
"term.toggleprivate": "Privát zenehallgatás",
|
||||||
|
"term.webremote": "Távirányító",
|
||||||
|
"term.cast": "Tükrözés",
|
||||||
|
"term.cast2": "Tükrözés eszközökre",
|
||||||
|
"term.quit": "Kilépés",
|
||||||
|
"term.zoomin": "Nagyítás",
|
||||||
|
"term.zoomout": "Kicsinyítés",
|
||||||
|
"term.zoomreset": "Nagyítás visszaállítása",
|
||||||
|
"term.fullscreen": "Teljes képernyő",
|
||||||
|
"term.nowPlaying": "Jelenleg lejátszás alatt",
|
||||||
|
"home.syncFavorites": "Kedvencek szinkronizálása",
|
||||||
|
"home.syncFavorites.gettingArtists": "Kedvenc előadók betöltése..",
|
||||||
|
"action.favorite": "Kedvenc",
|
||||||
|
"action.removeFavorite": "Eltávolítás a kedvencek közül",
|
||||||
|
"action.refresh": "Frissítés",
|
||||||
"home.title": "Kezdőlap",
|
"home.title": "Kezdőlap",
|
||||||
"home.recentlyPlayed": "Nemrég játszott",
|
"home.recentlyPlayed": "Nemrég játszott",
|
||||||
"home.recentlyAdded": "Nemrég hozzáadott",
|
"home.recentlyAdded": "Nemrég hozzáadott",
|
||||||
|
@ -222,6 +246,7 @@
|
||||||
"action.delete": "Törlés",
|
"action.delete": "Törlés",
|
||||||
"action.edit": "Szerkesztés",
|
"action.edit": "Szerkesztés",
|
||||||
"action.done": "Kész",
|
"action.done": "Kész",
|
||||||
|
"action.submit": "Befejezés",
|
||||||
"action.editTracklist": "Dalok szerkesztése",
|
"action.editTracklist": "Dalok szerkesztése",
|
||||||
"action.addToLibrary": "Hozzáadás a Könyvtárhoz",
|
"action.addToLibrary": "Hozzáadás a Könyvtárhoz",
|
||||||
"action.addToLibrary.success": "Hozzáadva a Könyvtárhoz",
|
"action.addToLibrary.success": "Hozzáadva a Könyvtárhoz",
|
||||||
|
@ -266,11 +291,7 @@
|
||||||
"action.export": "Exportálás",
|
"action.export": "Exportálás",
|
||||||
"action.showAlbum": "Teljes album megjelenítése",
|
"action.showAlbum": "Teljes album megjelenítése",
|
||||||
"action.tray.minimize": "Kicsinyítés a Tálcára",
|
"action.tray.minimize": "Kicsinyítés a Tálcára",
|
||||||
"action.tray.quit": "Bezárás",
|
|
||||||
"action.tray.show": "Cider megjelenítése",
|
"action.tray.show": "Cider megjelenítése",
|
||||||
"action.tray.playpause": "Lejátszás/Megállítás",
|
|
||||||
"action.tray.next": "Következő",
|
|
||||||
"action.tray.previous": "Előző",
|
|
||||||
"action.tray.listento": "Ezt hallgatja:",
|
"action.tray.listento": "Ezt hallgatja:",
|
||||||
"action.update": "Frissítés",
|
"action.update": "Frissítés",
|
||||||
"action.install": "Telepítés",
|
"action.install": "Telepítés",
|
||||||
|
@ -290,44 +311,25 @@
|
||||||
"action.createNew": "Új létrehozása...",
|
"action.createNew": "Új létrehozása...",
|
||||||
"action.openArtworkInBrowser": "Borító megnyitása a böngészőben",
|
"action.openArtworkInBrowser": "Borító megnyitása a böngészőben",
|
||||||
"action.scrollToTop": "Felülre",
|
"action.scrollToTop": "Felülre",
|
||||||
"menubar.options.about": "Névjegy",
|
"menubar.options.view": "Jelenítse meg a(z) ",
|
||||||
"menubar.options.settings": "Beállítások",
|
"menubar.options.reload": "Újratöltés",
|
||||||
"menubar.options.quit": "Bezárás",
|
"menubar.options.forcereload": "Kényszerített újratöltés",
|
||||||
"menubar.options.view": "View ",
|
|
||||||
"menubar.options.reload": "Reload",
|
|
||||||
"menubar.options.forcereload": "Force Reload",
|
|
||||||
"menubar.options.toggledevtools": "Fejlesztői eszközök",
|
"menubar.options.toggledevtools": "Fejlesztői eszközök",
|
||||||
"menubar.options.window": "Ablak",
|
"menubar.options.window": "Ablak",
|
||||||
"menubar.options.minimize": "Kicsinyítés",
|
"menubar.options.minimize": "Kicsinyítés",
|
||||||
"menubar.options.toggleprivate": "Privát hallgatás ki/be",
|
|
||||||
"menubar.options.webremote": "Távirányító",
|
|
||||||
"menubar.options.audio": "Hangbeállítások",
|
|
||||||
"menubar.options.plugins": "Plug-in Menü",
|
"menubar.options.plugins": "Plug-in Menü",
|
||||||
"menubar.options.controls": "Controls",
|
"menubar.options.controls": "Irányítások",
|
||||||
"menubar.options.next": "Következő",
|
|
||||||
"menubar.options.playpause": "Lejátszás/Megállítás",
|
|
||||||
"menubar.options.previous": "Előző",
|
|
||||||
"menubar.options.volumeup": "Hangerő fel",
|
"menubar.options.volumeup": "Hangerő fel",
|
||||||
"menubar.options.volumedown": "Hangerő le",
|
"menubar.options.volumedown": "Hangerő le",
|
||||||
"menubar.options.browse": "Böngészés",
|
|
||||||
"menubar.options.artists": "Előadók",
|
|
||||||
"menubar.options.search": "Keresés",
|
|
||||||
"menubar.options.albums": "Albumok",
|
|
||||||
"menubar.options.cast": "Tükrözés",
|
|
||||||
"menubar.options.account": "Fiók",
|
"menubar.options.account": "Fiók",
|
||||||
"menubar.options.accountsettings": "Fiókbeállítások",
|
|
||||||
"menubar.options.signout": "Kijelentkezés",
|
"menubar.options.signout": "Kijelentkezés",
|
||||||
"menubar.options.support": "Támogatás",
|
"menubar.options.support": "Támogatás",
|
||||||
"menubar.options.discord": "Discord",
|
"menubar.options.report": "Jelentsd be egy...",
|
||||||
"menubar.options.github": "GitHub Wiki",
|
"menubar.options.bug": "Hiba",
|
||||||
"menubar.options.report": "Report a...",
|
"menubar.options.feature": "Funkciókérés",
|
||||||
"menubar.options.bug": "Bug",
|
"menubar.options.trans": "Fordítással kapcsolatos bejelentés/kérelem",
|
||||||
"menubar.options.feature": "Feature Request",
|
|
||||||
"menubar.options.trans": "Translation Report/Request",
|
|
||||||
"menubar.options.license": "Licensz megtekintése",
|
"menubar.options.license": "Licensz megtekintése",
|
||||||
"menubar.options.conf": "Open Configuration File in Editor",
|
"menubar.options.conf": "Open Configuration File in Editor",
|
||||||
"menubar.options.listennow": "Hallgatás most",
|
|
||||||
"menubar.options.recentlyAdded": "Nemrég hozzáadott",
|
|
||||||
"menubar.options.songs": "Dalok",
|
"menubar.options.songs": "Dalok",
|
||||||
"settings.header.general": "Általános",
|
"settings.header.general": "Általános",
|
||||||
"settings.header.general.description": "A Cider általános beállításainak módosítása.",
|
"settings.header.general.description": "A Cider általános beállításainak módosítása.",
|
||||||
|
@ -348,13 +350,19 @@
|
||||||
"settings.option.general.customizeSidebar": "Oldalsáv elemeinek testreszabása",
|
"settings.option.general.customizeSidebar": "Oldalsáv elemeinek testreszabása",
|
||||||
"settings.option.general.customizeSidebar.customize": "Testreszabás",
|
"settings.option.general.customizeSidebar.customize": "Testreszabás",
|
||||||
"settings.option.general.keybindings": "Billentyűparancsok",
|
"settings.option.general.keybindings": "Billentyűparancsok",
|
||||||
|
"settings.option.general.keybindings.library": "Könyvtár",
|
||||||
|
"settings.option.general.keybindings.session": "Zenehallgatás",
|
||||||
|
"settings.option.general.keybindings.control": "Irányítások",
|
||||||
|
"settings.option.general.keybindings.interface": "Felület",
|
||||||
|
"settings.option.general.keybindings.advanced": "Haladó",
|
||||||
"settings.option.general.keybindings.pressCombination": "Nyomj le két billentyűt a parancs frissítéséhez.",
|
"settings.option.general.keybindings.pressCombination": "Nyomj le két billentyűt a parancs frissítéséhez.",
|
||||||
"settings.option.general.keybindings.pressEscape": "Nyomj Escape-et a visszalépéshez.",
|
"settings.option.general.keybindings.pressEscape": "Nyomj Escape-et a visszalépéshez.",
|
||||||
"settings.notyf.general.keybindings.update.success": "Billentyűparancs sikeresen frissítve",
|
"settings.notyf.general.keybindings.update.success": "Billentyűparancs sikeresen frissítve",
|
||||||
"settings.prompt.general.keybindings.update.success": "Billentyűparancs sikeresen frissítve. Kattints az OK-ra a Cider újraindításához!",
|
"settings.prompt.general.keybindings.update.success": "Billentyűparancs sikeresen frissítve. Kattints az OK-ra a Cider újraindításához!",
|
||||||
"settings.option.general.keybindings.open": "Megnyitás",
|
|
||||||
"settings.option.general.themeUpdateNotification": "Automatikus témafrissítések keresése",
|
"settings.option.general.themeUpdateNotification": "Automatikus témafrissítések keresése",
|
||||||
"settings.option.general.showLovedTracksInline": "Show loved tracks inline",
|
"settings.option.general.showLovedTracksInline": "Show loved tracks inline",
|
||||||
|
"settings.option.general.pagination": "Elemek megjelenítése oldalanként",
|
||||||
|
"settings.options.general.pagination.description": "Ez határozza meg, hogy mennyi zeneszám/album jelenjen meg eleinte a végtelen görgetésben, vagy hány zeneszám/album jelenjen meg egyetlen oldalon",
|
||||||
"settings.description.search": "Keresés",
|
"settings.description.search": "Keresés",
|
||||||
"settings.description.albums": "Albumkönyvtár",
|
"settings.description.albums": "Albumkönyvtár",
|
||||||
"settings.description.artists": "Előadókönyvtár",
|
"settings.description.artists": "Előadókönyvtár",
|
||||||
|
@ -410,6 +418,15 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Az Atmoszféra Változató™️ modul módját változtatja meg.",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.description": "Az Atmoszféra Változató™️ modul módját változtatja meg.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Natural (Standard)",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_STANDARD": "Natural (Standard)",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Natural (Plus)",
|
"settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.NATURAL_PLUS": "Natural (Plus)",
|
||||||
|
"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.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": "Cider Adrenaline Processor™️",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Feljavítja az AAC hang minőségét egy valós idejű algoritmus segítségével, ami kihasználja az emberi hallás pszichoakusztikus modelljeit és az AAC hang kódolási jellemzőit.",
|
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "Feljavítja az AAC hang minőségét egy valós idejű algoritmus segítségével, ami kihasználja az emberi hallás pszichoakusztikus modelljeit és az AAC hang kódolási jellemzőit.",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "A CAP nem kompatibilis a Térbeli Hanggal. Kapcsold ki a Térbeli Hangot a folytatáshoz.",
|
"settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility": "A CAP nem kompatibilis a Térbeli Hanggal. Kapcsold ki a Térbeli Hangot a folytatáshoz.",
|
||||||
|
@ -426,23 +443,22 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Előre beállított Térbeli hangzás, ami letiltja a Térbeli Hang testreszabási beállításait. A Térbeli Hangot be kell kapcsolni az engedélyezéshez.",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.description": "Előre beállított Térbeli hangzás, ami letiltja a Térbeli Hang testreszabási beállításait. A Térbeli Hangot be kell kapcsolni az engedélyezéshez.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Térbeli Hangprofil",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile": "Cider Térbeli Hangprofil",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Megváltoztatja a Térbeli Hang előbeállítás profilját.",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.description": "Megváltoztatja a Térbeli Hang előbeállítás profilját.",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Standard",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "Alapértelmezett",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "Soundstage",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.soundstage": "Hangszínpad",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Separation",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.separation": "Elválasztás",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimal",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "Minimális",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiophile",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "Audiofil",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffused",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "Diffúz",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Encore",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "Ráadás",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Expanded Encore",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "Kiterjesztett ráadás",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "A Térbeli Hang nem kompatibilis a CAP-pal. Kapcsold ki a CAP-ot a folytatáshoz.",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "A Térbeli Hang nem kompatibilis a CAP-pal. Kapcsold ki a CAP-ot a folytatáshoz.",
|
||||||
"settings.option.audio.dbspl.display": "dB SPL kijelzés",
|
"settings.option.audio.dbspl.display": "dB SPL kijelzés",
|
||||||
"settings.option.audio.dbspl.description": "(Haladó felhasználóknak) A hangerő dB SPL-ben történő kijelzése a dBFS helyett.",
|
"settings.option.audio.dbspl.description": "(Haladó felhasználóknak) A hangerő dB SPL-ben történő kijelzése a dBFS helyett.",
|
||||||
"settings.option.audio.dbfs.calibration": "0 dBFS kalibráció",
|
"settings.option.audio.dbfs.calibration": "0 dBFS kalibráció",
|
||||||
"settings.option.audio.dbfs.description": "Enter the peak Z-weighted dB SPL when Cider is at 0 dBFS.",
|
"settings.option.audio.dbfs.description": "Adja meg a csúcs Z-súlyozott dB SPL értékét, amikor a Cider 0 dBFS-en van.",
|
||||||
"settings.header.visual": "Vizuális",
|
"settings.header.visual": "Vizuális",
|
||||||
"settings.header.visual.description": "A Cider vizuális beállításainak módosítása.",
|
"settings.header.visual.description": "A Cider vizuális beállításainak módosítása.",
|
||||||
"settings.option.visual.windowStyle": "Ablakelrendezés",
|
"settings.option.visual.windowStyle": "Ablakelrendezés",
|
||||||
"settings.option.visual.purplePodcastPlaybackBar": "Lila lejátszási sáv a Podcastoknál",
|
|
||||||
"settings.option.visual.windowBackgroundStyle": "Ablakháttér stílusa",
|
"settings.option.visual.windowBackgroundStyle": "Ablakháttér stílusa",
|
||||||
"settings.header.visual.windowBackgroundStyle.none": "Sehol",
|
"settings.header.visual.windowBackgroundStyle.none": "Sehol",
|
||||||
"settings.header.visual.windowBackgroundStyle.artwork": "Borító",
|
"settings.header.visual.windowBackgroundStyle.artwork": "Borító",
|
||||||
|
@ -465,12 +481,14 @@
|
||||||
"settings.option.visual.uiscale": "Nagyítás mértéke",
|
"settings.option.visual.uiscale": "Nagyítás mértéke",
|
||||||
"settings.header.visual.theme": "Téma",
|
"settings.header.visual.theme": "Téma",
|
||||||
"settings.option.visual.theme.github.download": "Telepítés GitHub URL-ről",
|
"settings.option.visual.theme.github.download": "Telepítés GitHub URL-ről",
|
||||||
|
"settings.option.visual.theme.github.openfolder": "Témák mappa megnyitása",
|
||||||
"settings.option.visual.theme.github.explore": "Témák felfedezése",
|
"settings.option.visual.theme.github.explore": "Témák felfedezése",
|
||||||
"settings.header.visual.theme.github.page": "Témák a GitHub-ról",
|
"settings.header.visual.theme.github.page": "Témák a GitHub-ról",
|
||||||
"settings.option.visual.theme.github.install.confirm": "Biztosan szeretnéd telepíteni a(z) {{ repo }} témát?",
|
"settings.option.visual.theme.github.install.confirm": "Biztosan szeretnéd telepíteni a(z) {{ repo }} témát?",
|
||||||
"settings.prompt.visual.theme.github.URL": "Add meg a telepítendő téma URL-jét",
|
"settings.prompt.visual.theme.github.URL": "Add meg a telepítendő téma URL-jét",
|
||||||
"settings.prompt.visual.theme.uninstallTheme": "Biztos, hogy törölni szeretnéd a {{ theme }} témát?",
|
"settings.prompt.visual.theme.uninstallTheme": "Biztos, hogy törölni szeretnéd a {{ theme }} témát?",
|
||||||
"settings.option.visual.theme.checkForUpdates": "Frissítések keresése",
|
"settings.option.visual.theme.checkForUpdates": "Frissítések keresése",
|
||||||
|
"settings.header.visual.styles": "Stílusok",
|
||||||
"settings.option.visual.theme.manageStyles": "Témakezelő",
|
"settings.option.visual.theme.manageStyles": "Témakezelő",
|
||||||
"settings.option.visual.theme.uninstall": "Törlés",
|
"settings.option.visual.theme.uninstall": "Törlés",
|
||||||
"settings.option.visual.theme.viewInfo": "Információk",
|
"settings.option.visual.theme.viewInfo": "Információk",
|
||||||
|
@ -522,6 +540,13 @@
|
||||||
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Last.fm Now Playing engedélyezése",
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "Last.fm Now Playing engedélyezése",
|
||||||
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Közreműködő zenészek eltávolítása a címből (Last.fm)",
|
"settings.option.connectivity.lastfmScrobble.removeFeatured": "Közreműködő zenészek eltávolítása a címből (Last.fm)",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "Ismételt zeneszám szűrése (Last.fm)",
|
"settings.option.connectivity.lastfmScrobble.filterLoop": "Ismételt zeneszám szűrése (Last.fm)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.filterLoop.description": "Ismételt zeneszámok scrobble-zésének és megjelenítésének letiltása a jelenleg lejátszás alatt listában (Last.fm)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.filterTypes": "Médiatípusok szűrése (Last.fm)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.manualToken": "Last.fm Token beírása manuálisan",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.manualToken.link": "Last.fm Token legenerálásához kattints ide",
|
||||||
|
"settings.notyf.connectivity.lastfmScrobble.connectError": "A Last.fm csatlakozása során időtullépés lépett fel",
|
||||||
|
"settings.notyf.connectivity.lastfmScrobble.connectSuccess": "A Last.fm csatlakozása sikeres volt",
|
||||||
|
"settings.notyf.connectivity.lastfmScrobble.connecting": "Last.fm-hez való csatlakozás...",
|
||||||
"settings.header.debug": "Hibaelhárítás",
|
"settings.header.debug": "Hibaelhárítás",
|
||||||
"settings.option.debug.copy_log": "Napló másolása a vágólapra",
|
"settings.option.debug.copy_log": "Napló másolása a vágólapra",
|
||||||
"settings.option.debug.openAppData": "Cider mappa megnyitása",
|
"settings.option.debug.openAppData": "Cider mappa megnyitása",
|
||||||
|
@ -533,17 +558,24 @@
|
||||||
"settings.option.experimental.unknownPlugin.description": "Engedélyezi azon pluginok telepítését is, amik nem tartoznak a Cider Plugin Gyűjteménybe, ezáltal lehetséges biztonsági kockázatot jelenthetnek.",
|
"settings.option.experimental.unknownPlugin.description": "Engedélyezi azon pluginok telepítését is, amik nem tartoznak a Cider Plugin Gyűjteménybe, ezáltal lehetséges biztonsági kockázatot jelenthetnek.",
|
||||||
"settings.option.experimental.compactUI": "Kompakt felület",
|
"settings.option.experimental.compactUI": "Kompakt felület",
|
||||||
"settings.option.window.close_button_hide": "A bezárás gomb rejtse el az alkalmazást",
|
"settings.option.window.close_button_hide": "A bezárás gomb rejtse el az alkalmazást",
|
||||||
|
"settings.option.window.maxElementScale": "Maximális elem skála",
|
||||||
"settings.option.experimental.inline_playlists": "Ablakon belüli lejátszási listák és albumok",
|
"settings.option.experimental.inline_playlists": "Ablakon belüli lejátszási listák és albumok",
|
||||||
"settings.option.advanced.playlistTrackMapping": "Lejátszási lista feltérképezés",
|
"settings.option.advanced.playlistTrackMapping": "Lejátszási lista feltérképezés",
|
||||||
"settings.option.advanced.playlistTrackMapping.description": "Engedélyezi a lejátszási listák mély feltérképezését, ami meg tudja határozni, hogy egy zeneszám mely lejátszási listákba található. A lejátszási lista gyorsítótár felépítésének időtartalma nagy mértékben megnőhet.",
|
"settings.option.advanced.playlistTrackMapping.description": "Engedélyezi a lejátszási listák mély feltérképezését, ami meg tudja határozni, hogy egy zeneszám mely lejátszási listákba található. A lejátszási lista gyorsítótár felépítésének időtartalma nagy mértékben megnőhet.",
|
||||||
"settings.option.visual.transparent": "Átlátszó keret",
|
"settings.option.visual.transparent": "Átlátszó keret",
|
||||||
"settings.option.visual.transparent.description": "a Témák támogatása és újraindítás szükséges",
|
"settings.option.visual.transparent.description": "a Témák támogatása (újraindítás szükséges)",
|
||||||
|
"settings.option.visual.customAccentColor": "Egyedi kiemelőszín",
|
||||||
|
"settings.option.visual.accentColor": "Kiemelőszín",
|
||||||
|
"settings.option.visual.purplePodcastPlaybackBar": "Lila lejátszási sáv podcastok lejátszása esetén",
|
||||||
|
"settings.option.visual.compactArtistHeader": "Kompakt előadó fejléc",
|
||||||
|
"settings.option.visual.windowColor": "Az ablak színárnyalata",
|
||||||
|
"settings.header.visual.windowBackgroundStyle.color": "Színárnyalat",
|
||||||
"settings.header.advanced": "Haladó",
|
"settings.header.advanced": "Haladó",
|
||||||
"settings.header.connect": "Sync",
|
"settings.header.connect": "Szinkronizálás",
|
||||||
"settings.option.connect.link_account": "Enable Sync with Cider Connect",
|
"settings.option.connect.link_account": "Szinkronizálás a Cider Connect szolgáltatással engedélyezése",
|
||||||
"settings.option.connect.link_account.description": "Linking your Discord account with Cider Connect allows you to store userdata including Settings, EQ's, and eventually more once finished. (Work In Progress)",
|
"settings.option.connect.link_account.description": "A Discord fiók összekapcsolása a Cider Connect szolgáltatással lehetővé teszi a felhasználói adatok tárolását, beleértve a beállításokat, az EQ-kat és esetleg még többet. (Fejlesztés alatt)",
|
||||||
"spatial.notTurnedOn": "A Térbeli Hang ki van kapcsolva, használatához kapcsolja be.",
|
"spatial.notTurnedOn": "A Térbeli Hang ki van kapcsolva, használatához kapcsolja be.",
|
||||||
"spatial.spatialProperties": "Térbeli Hang",
|
"spatial.spatialProperties": "Térbeli hang",
|
||||||
"spatial.width": "Szélesség",
|
"spatial.width": "Szélesség",
|
||||||
"spatial.height": "Magasság",
|
"spatial.height": "Magasság",
|
||||||
"spatial.depth": "Hosszúság",
|
"spatial.depth": "Hosszúság",
|
||||||
|
@ -574,5 +606,32 @@
|
||||||
"share.platform.email": "Email",
|
"share.platform.email": "Email",
|
||||||
"share.platform.songLink": "song.link URL másolása",
|
"share.platform.songLink": "song.link URL másolása",
|
||||||
"share.platform.clipboard": "Link másolása",
|
"share.platform.clipboard": "Link másolása",
|
||||||
"about.thanks": "Köszönet a Cider Collective csapatának és minden hozzájárulónak."
|
"about.thanks": "Köszönet a Cider Collective csapatának és minden hozzájárulónak.",
|
||||||
|
"oobe.yes": "Igen",
|
||||||
|
"oobe.no": "Nem",
|
||||||
|
"oobe.next": "Következő",
|
||||||
|
"oobe.previous": "Előző",
|
||||||
|
"oobe.done": "Kész",
|
||||||
|
"oobe.amupsell.title": "Még mielőtt belevágnánk",
|
||||||
|
"oobe.amupsell.text": "A Cider Apple Music előfizetést igényel\nA Cider nem támogatja az Apple Music Voice Plan-t vagy más fajta promóciós próba előfizetéseket. Ha már Apple Music előfizető vagy, lépj tovább.",
|
||||||
|
"oobe.amupsell.subscribeBtn": "Előfizetés Apple Music-ra",
|
||||||
|
"oobe.amupsell.explainBtn": "Magyarázat",
|
||||||
|
"oobe.amupsell.subscribeUrl": "https://apple.co/3MdqJVQ",
|
||||||
|
"oobe.amupsell.amWebUrl": "https://beta.music.apple.com/",
|
||||||
|
"oobe.amupsell.promoExplained": "Egyes promóciós és nem egyesült államokbeli Apple Music próba-előfizetések nem férnek hozzá a szükséges Apple Music Web Player API-khoz, amelyek a Cider működéséhez szükségesek. Ha le szeretnéd ellenőrizni, hogy az aktív előfizetésed kompatibilis a Cider-rel, kattints a <a href='{{ amWebUrl }}'>{{ amWebUrl }}</a> linkre, jelentkezz be és próbálj meg lejátszani bármilyen zenét. Ha működik, akkor jó hírunk van! Készen állsz arra, hogy használd a Cider-t. Viszont ha mégsem működött, fizess elő Apple Music-ra ezen a linken: <a href='{{ subscribeUrl }}'>{{ subscribeUrl }}</a>",
|
||||||
|
"oobe.intro.title": "Üdvözlünk a Cider-ben!",
|
||||||
|
"oobe.intro.subtitle": "",
|
||||||
|
"oobe.intro.text": "Állítsunk be néhány dolgot, hogy tetszés szerint használhasd a Cider-t. Ezeket a beállításokat később bármikor módosíthatod.",
|
||||||
|
"oobe.general.title": "Általános",
|
||||||
|
"oobe.general.subtitle": "",
|
||||||
|
"oobe.general.text": "",
|
||||||
|
"oobe.audio.title": "Hang",
|
||||||
|
"oobe.audio.subtitle": "",
|
||||||
|
"oobe.audio.text": "A Cider egyedi hangolású és tervezett hangkészletekkel rendelkezik, amely gazdag, kiváló minőségű hangélményt biztosít.\nKöztük van a Cider Adrenaline, Atmosphere Realizer, és a Spatialized Audio.\nA hangkészletek engedélyezéséhez a \"Fejlett audiófunkciók\"-at be kell kapcsolni.\nA fejlett audiófunkciók engedélyezése hozzáférést biztosít ezekhez a hangkészletekhez a Cider Audio Labs szolgáltatásban, amely az alkalmazás beállításai között található.",
|
||||||
|
"oobe.audio.advancedFunctionality": "",
|
||||||
|
"oobe.visual.title": "Vizuális",
|
||||||
|
"oobe.visual.subtitle": "",
|
||||||
|
"oobe.visual.text": "",
|
||||||
|
"oobe.visual.layout.text": "A Cider két különböző ablakmegjelenéssel rendelkezik.\nA Maverick egy iTunes-ra hasonló megjelenést biztosít, a zenelejátszó az ablak tetején található.\nA Mojave egy új hullám a Cider Collective által készítve.\n\nBármikor megváltoztathatod a megjelenést a beállításokban.",
|
||||||
|
"oobe.amsignin.title": ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,8 +132,8 @@
|
||||||
"term.reset": "Resetten",
|
"term.reset": "Resetten",
|
||||||
"term.tracks": "nummers",
|
"term.tracks": "nummers",
|
||||||
"term.track": {
|
"term.track": {
|
||||||
"one" : "nummer",
|
"one": "nummer",
|
||||||
"other" : "nummers"
|
"other": "nummers"
|
||||||
},
|
},
|
||||||
"term.videos": "Video's",
|
"term.videos": "Video's",
|
||||||
"term.menu": "Menu",
|
"term.menu": "Menu",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"notification.updatingLibrarySongs": "Updating library songs...",
|
"notification.updatingLibrarySongs": "Updating library songs...",
|
||||||
"notification.updatingLibraryAlbums": "Updating library albums...",
|
"notification.updatingLibraryAlbums": "Updating library albums...",
|
||||||
"notification.updatingLibraryArtists": "Updating library artists...",
|
"notification.updatingLibraryArtists": "Updating library artists...",
|
||||||
|
"notification.buildingPlaylistCache": "Building Playlist Cache...",
|
||||||
"term.variables": "Variables",
|
"term.variables": "Variables",
|
||||||
"term.appleInc": "Apple Inc.",
|
"term.appleInc": "Apple Inc.",
|
||||||
"term.appleMusic": "Apple Music",
|
"term.appleMusic": "Apple Music",
|
||||||
|
@ -260,6 +261,7 @@
|
||||||
"action.removeFromQueue.success": "Removed from Queue",
|
"action.removeFromQueue.success": "Removed from Queue",
|
||||||
"action.removeFromQueue.error": "Error Removing from Queue",
|
"action.removeFromQueue.error": "Error Removing from Queue",
|
||||||
"action.createPlaylist": "Create a New Playlist",
|
"action.createPlaylist": "Create a New Playlist",
|
||||||
|
"action.addToPlaylist.duplicate": "Item already exists in playlist. Do you want to continue?",
|
||||||
"action.addToPlaylist": "Add to Playlist",
|
"action.addToPlaylist": "Add to Playlist",
|
||||||
"action.removeFromPlaylist": "Remove from Playlist",
|
"action.removeFromPlaylist": "Remove from Playlist",
|
||||||
"action.addToFavorites": "Add to Favorites",
|
"action.addToFavorites": "Add to Favorites",
|
||||||
|
@ -494,6 +496,7 @@
|
||||||
"settings.option.visual.theme.viewInfo": "View Info",
|
"settings.option.visual.theme.viewInfo": "View Info",
|
||||||
"settings.option.visual.theme.github.available": "Available",
|
"settings.option.visual.theme.github.available": "Available",
|
||||||
"settings.option.visual.theme.github.applied": "Applied",
|
"settings.option.visual.theme.github.applied": "Applied",
|
||||||
|
"settings.notyf.visual.theme.updateAvailable": "[Themes] {{ theme }} has an update available",
|
||||||
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
"settings.notyf.visual.theme.install.success": "Theme installed successfully",
|
||||||
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
"settings.notyf.visual.theme.install.error": "Theme installation failed",
|
||||||
"settings.header.visual.plugin": "Plugin",
|
"settings.header.visual.plugin": "Plugin",
|
||||||
|
@ -529,7 +532,13 @@
|
||||||
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
|
"settings.option.connectivity.discordRPC": "Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.clientName": "Client Name",
|
"settings.option.connectivity.discordRPC.clientName": "Client Name",
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause",
|
"settings.option.connectivity.discordRPC.clearOnPause": "Clear Discord Rich Presence on Pause",
|
||||||
"settings.option.connectivity.discordRPC.hideButtons": "Hide buttons on Discord Rich Presence",
|
"settings.option.connectivity.discordRPC.showActivityButtons": "Show Activity Buttons",
|
||||||
|
"settings.option.connectivity.discordRPC.firstButton": "First Activity Button",
|
||||||
|
"settings.option.connectivity.discordRPC.secondButton": "Second Activity Button",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.listenOnCider": "Listen on Cider",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.viewOnAppleMusic": "View on Apple Music",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.viewOnOtherMusicServices": "View on Other Music Services",
|
||||||
|
"settings.option.connectivity.discordRPC.showSongLink": "Show Song.link button instead of Apple Music button on Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.hideTimestamp": "Hide timestamp on Discord Rich Presence",
|
"settings.option.connectivity.discordRPC.hideTimestamp": "Hide timestamp on Discord Rich Presence",
|
||||||
"settings.option.connectivity.discordRPC.detailsFormat": "Details Format",
|
"settings.option.connectivity.discordRPC.detailsFormat": "Details Format",
|
||||||
"settings.option.connectivity.discordRPC.stateFormat": "State Format",
|
"settings.option.connectivity.discordRPC.stateFormat": "State Format",
|
||||||
|
@ -542,6 +551,7 @@
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (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.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.filterTypes": "Filter Media Types (Last.fm)",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.filterTypes.description": "Prevent tracks of the selected media types from being scrobbled or displayed in the Now Playing list on Last.fm.",
|
||||||
"settings.option.connectivity.lastfmScrobble.manualToken": "Enter Last.fm Token Manually",
|
"settings.option.connectivity.lastfmScrobble.manualToken": "Enter Last.fm Token Manually",
|
||||||
"settings.option.connectivity.lastfmScrobble.manualToken.link": "Click here to get a Last.fm token",
|
"settings.option.connectivity.lastfmScrobble.manualToken.link": "Click here to get a Last.fm token",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection Timed Out",
|
"settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm Connection Timed Out",
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
"date.format": "${y}年${m}月${d}日",
|
"date.format": "${y}年${m}月${d}日",
|
||||||
"dialog.cancel": "取消",
|
"dialog.cancel": "取消",
|
||||||
"dialog.ok": "好",
|
"dialog.ok": "好",
|
||||||
"notification.updatingLibrarySongs": "正在更新歌曲资料库...",
|
"notification.updatingLibrarySongs": "正在更新歌曲资料库……",
|
||||||
"notification.updatingLibraryAlbums": "正在更新专辑资料库...",
|
"notification.updatingLibraryAlbums": "正在更新专辑资料库……",
|
||||||
"notification.updatingLibraryArtists": "正在更新艺人资料库...",
|
"notification.updatingLibraryArtists": "正在更新艺人资料库……",
|
||||||
"term.variables": "Variables",
|
"term.variables": "变量",
|
||||||
"term.appleInc": "Apple Inc.",
|
"term.appleInc": "Apple Inc.",
|
||||||
"term.appleMusic": "Apple Music",
|
"term.appleMusic": "Apple Music",
|
||||||
"term.applePodcasts": "Apple Podcasts",
|
"term.applePodcasts": "Apple Podcasts",
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
"term.amLive": "Apple Music Live",
|
"term.amLive": "Apple Music Live",
|
||||||
"term.language": "语言",
|
"term.language": "语言",
|
||||||
"term.funLanguages": "恶搞",
|
"term.funLanguages": "恶搞",
|
||||||
"term.noLyrics": "加载中... / 无搜索结果 / 纯音乐",
|
"term.noLyrics": "纯音乐 / 无歌词",
|
||||||
"term.copyright": "版权所有",
|
"term.copyright": "版权所有",
|
||||||
"term.rightsReserved": "保留所有权利。",
|
"term.rightsReserved": "保留所有权利。",
|
||||||
"term.sponsor": "赞助",
|
"term.sponsor": "赞助",
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
"term.defaultPresets": "默认预设",
|
"term.defaultPresets": "默认预设",
|
||||||
"term.userPresets": "用户预设",
|
"term.userPresets": "用户预设",
|
||||||
"term.requestError": "请求出现一个问题。",
|
"term.requestError": "请求出现一个问题。",
|
||||||
"term.song.link.generate": "获取 song.link 共享链接...",
|
"term.song.link.generate": "获取 song.link 共享链接……",
|
||||||
"term.musicVideos": "音乐视频",
|
"term.musicVideos": "音乐视频",
|
||||||
"term.stations": "电台",
|
"term.stations": "电台",
|
||||||
"term.curators": "策展人",
|
"term.curators": "策展人",
|
||||||
|
@ -199,7 +199,7 @@
|
||||||
"term.fullscreen": "全屏模式",
|
"term.fullscreen": "全屏模式",
|
||||||
"term.nowPlaying": "正在播放",
|
"term.nowPlaying": "正在播放",
|
||||||
"home.syncFavorites": "同步喜爱艺人",
|
"home.syncFavorites": "同步喜爱艺人",
|
||||||
"home.syncFavorites.gettingArtists": "获取喜爱艺人...",
|
"home.syncFavorites.gettingArtists": "获取喜爱艺人……",
|
||||||
"action.favorite": "喜爱",
|
"action.favorite": "喜爱",
|
||||||
"action.removeFavorite": "取消喜爱",
|
"action.removeFavorite": "取消喜爱",
|
||||||
"action.refresh": "刷新",
|
"action.refresh": "刷新",
|
||||||
|
@ -212,7 +212,7 @@
|
||||||
"home.friendsListeningTo": "朋友正在听",
|
"home.friendsListeningTo": "朋友正在听",
|
||||||
"home.followedArtists": "关注的艺人",
|
"home.followedArtists": "关注的艺人",
|
||||||
"error.appleMusicSubRequired": "需要订阅 Apple Music 以使用 Cider",
|
"error.appleMusicSubRequired": "需要订阅 Apple Music 以使用 Cider",
|
||||||
"error.connectionError": "无法连接到 Apple Music。",
|
"error.connectionError": "无法连接至 Apple Music。",
|
||||||
"error.noResults": "没有结果。",
|
"error.noResults": "没有结果。",
|
||||||
"error.noResults.description": "尝试更改搜索条件。",
|
"error.noResults.description": "尝试更改搜索条件。",
|
||||||
"podcast.followOnCider": "在 Cider 中关注",
|
"podcast.followOnCider": "在 Cider 中关注",
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
"action.update": "更新",
|
"action.update": "更新",
|
||||||
"action.install": "安装",
|
"action.install": "安装",
|
||||||
"action.copy": "拷贝",
|
"action.copy": "拷贝",
|
||||||
"action.newpreset": "新建预设...",
|
"action.newpreset": "新建预设……",
|
||||||
"action.deletepreset": "删除预设",
|
"action.deletepreset": "删除预设",
|
||||||
"action.open": "打开",
|
"action.open": "打开",
|
||||||
"action.close": "关闭",
|
"action.close": "关闭",
|
||||||
|
@ -292,8 +292,8 @@
|
||||||
"action.cast.airplay": "隔空播放",
|
"action.cast.airplay": "隔空播放",
|
||||||
"action.cast.airplay.underdevelopment": "隔空播放仍处于开发阶段中,敬请期待。",
|
"action.cast.airplay.underdevelopment": "隔空播放仍处于开发阶段中,敬请期待。",
|
||||||
"action.cast.scan": "搜索",
|
"action.cast.scan": "搜索",
|
||||||
"action.cast.scanning": "搜索中...",
|
"action.cast.scanning": "搜索中……",
|
||||||
"action.createNew": "添加...",
|
"action.createNew": "添加……",
|
||||||
"action.openArtworkInBrowser": "在浏览器中打开专辑封面",
|
"action.openArtworkInBrowser": "在浏览器中打开专辑封面",
|
||||||
"action.scrollToTop": "回到顶部",
|
"action.scrollToTop": "回到顶部",
|
||||||
"menubar.options.view": "查看",
|
"menubar.options.view": "查看",
|
||||||
|
@ -309,12 +309,12 @@
|
||||||
"menubar.options.account": "账户",
|
"menubar.options.account": "账户",
|
||||||
"menubar.options.signout": "注销",
|
"menubar.options.signout": "注销",
|
||||||
"menubar.options.support": "支持",
|
"menubar.options.support": "支持",
|
||||||
"menubar.options.report": "报告...",
|
"menubar.options.report": "报告……",
|
||||||
"menubar.options.bug": "Bug",
|
"menubar.options.bug": "Bug",
|
||||||
"menubar.options.feature": "功能请求",
|
"menubar.options.feature": "功能请求",
|
||||||
"menubar.options.trans": "翻译报告/请求",
|
"menubar.options.trans": "翻译报告/请求",
|
||||||
"menubar.options.license": "查看授权",
|
"menubar.options.license": "查看授权",
|
||||||
"menubar.options.conf": "在编辑器打开配置文件",
|
"menubar.options.conf": "在编辑器中打开配置文件",
|
||||||
"menubar.options.zoom": "缩放",
|
"menubar.options.zoom": "缩放",
|
||||||
"settings.header.general": "通用",
|
"settings.header.general": "通用",
|
||||||
"settings.header.general.description": "调整 Cider 的通用设置",
|
"settings.header.general.description": "调整 Cider 的通用设置",
|
||||||
|
@ -325,14 +325,14 @@
|
||||||
"settings.option.general.resumebehavior.locally.description": "Cider 将还原您在这台电脑上的最后一次操作。",
|
"settings.option.general.resumebehavior.locally.description": "Cider 将还原您在这台电脑上的最后一次操作。",
|
||||||
"settings.option.general.resumebehavior.history": "历史",
|
"settings.option.general.resumebehavior.history": "历史",
|
||||||
"settings.option.general.resumebehavior.history.description": "Cider 将跨设备将您的整个 Apple Music 历史记录中的最后一首歌曲排队入列。",
|
"settings.option.general.resumebehavior.history.description": "Cider 将跨设备将您的整个 Apple Music 历史记录中的最后一首歌曲排队入列。",
|
||||||
"settings.option.general.resumetabs": "启动时打开的选项页面",
|
"settings.option.general.resumetabs": "启动时打开的页面",
|
||||||
"settings.option.general.resumetabs.description": "您可以选择启动 Cider 时要默认打开的页面。",
|
"settings.option.general.resumetabs.description": "您可以选择启动 Cider 时默认打开的页面。",
|
||||||
"settings.option.general.resumetabs.dynamic": "动态",
|
"settings.option.general.resumetabs.dynamic": "动态",
|
||||||
"settings.option.general.resumetabs.dynamic.description": "Cider 将自动打开您上次停留的页面。",
|
"settings.option.general.resumetabs.dynamic.description": "Cider 将自动打开您上次停留的页面。",
|
||||||
"settings.option.general.language.main": "语言",
|
"settings.option.general.language.main": "语言",
|
||||||
"settings.option.general.language.fun": "恶搞语言",
|
"settings.option.general.language.fun": "恶搞语言",
|
||||||
"settings.option.general.language.unsorted": "未分类",
|
"settings.option.general.language.unsorted": "未分类",
|
||||||
"settings.option.general.customizeSidebar": "自定义侧边栏的功能",
|
"settings.option.general.customizeSidebar": "自定义侧边栏项目",
|
||||||
"settings.option.general.customizeSidebar.customize": "自定义",
|
"settings.option.general.customizeSidebar.customize": "自定义",
|
||||||
"settings.option.general.keybindings": "快捷操作键",
|
"settings.option.general.keybindings": "快捷操作键",
|
||||||
"settings.option.general.keybindings.library": "资料库",
|
"settings.option.general.keybindings.library": "资料库",
|
||||||
|
@ -356,7 +356,7 @@
|
||||||
"settings.description.remote": "远程控制",
|
"settings.description.remote": "远程控制",
|
||||||
"settings.description.audio": "音频设定",
|
"settings.description.audio": "音频设定",
|
||||||
"settings.description.plugins": "插件目录",
|
"settings.description.plugins": "插件目录",
|
||||||
"settings.description.cast": "投射到装置",
|
"settings.description.cast": "投射到设备",
|
||||||
"settings.description.settings": "设置",
|
"settings.description.settings": "设置",
|
||||||
"settings.description.developer": "开发者工具",
|
"settings.description.developer": "开发者工具",
|
||||||
"settings.description.listnow": "现在就听",
|
"settings.description.listnow": "现在就听",
|
||||||
|
@ -384,7 +384,7 @@
|
||||||
"settings.header.audio.quality.standard.description": "64 kbps",
|
"settings.header.audio.quality.standard.description": "64 kbps",
|
||||||
"settings.option.audio.seamlessTransition": "无缝播放",
|
"settings.option.audio.seamlessTransition": "无缝播放",
|
||||||
"settings.option.audio.enableAdvancedFunctionality": "启用高级音频功能",
|
"settings.option.audio.enableAdvancedFunctionality": "启用高级音频功能",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.description": "打开 AudioContext 将启用类似音量平衡和等化器的高级设置。但这并不一定适合每部电脑,可能会发生音乐卡顿。",
|
"settings.option.audio.enableAdvancedFunctionality.description": "打开高级音频功能将启用类似音量平衡和等化器的高级设置。但这并不一定适合每部电脑,可能会发生音乐卡顿。",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.lowcores": "您的电脑可能无法处理这些功能, 您确定要继续?",
|
"settings.warn.audio.enableAdvancedFunctionality.lowcores": "您的电脑可能无法处理这些功能, 您确定要继续?",
|
||||||
"settings.option.audio.audioLab": "Cider 音频实验室",
|
"settings.option.audio.audioLab": "Cider 音频实验室",
|
||||||
"settings.option.audio.audioLab.description": "包含由 Cider 开发团队进行的各种音频优化功能。",
|
"settings.option.audio.audioLab.description": "包含由 Cider 开发团队进行的各种音频优化功能。",
|
||||||
|
@ -434,11 +434,11 @@
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "微调",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal": "微调",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "发烧友",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "发烧友",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "扩散",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.diffused": "扩散",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "安可",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.bplk": "安可舞台",
|
||||||
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "延长版安可",
|
"settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.hw2k": "大型安可舞台",
|
||||||
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "空间音频并不兼容数码增强音频处理器。请关闭数码增强音频处理器后再继续进行操作。",
|
"settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "空间音频并不兼容数码增强音频处理器。请关闭数码增强音频处理器后再继续进行操作。",
|
||||||
"settings.option.audio.dbspl.display": "显示 dB SPL(声压)",
|
"settings.option.audio.dbspl.display": "显示 dB SPL(声压)",
|
||||||
"settings.option.audio.dbspl.description": "(专业用户选项) 音量滑动条显示 dB SPL 而非 dBFS。",
|
"settings.option.audio.dbspl.description": "(专业用户选项)音量滑动条显示 dB SPL 而非 dBFS。",
|
||||||
"settings.option.audio.dbfs.calibration": "0 dBFS 校正",
|
"settings.option.audio.dbfs.calibration": "0 dBFS 校正",
|
||||||
"settings.option.audio.dbfs.description": "输入当 Cider 为 0 dBFS 时的峰值 Z 加权 dB SPL。",
|
"settings.option.audio.dbfs.description": "输入当 Cider 为 0 dBFS 时的峰值 Z 加权 dB SPL。",
|
||||||
"settings.header.visual": "外观",
|
"settings.header.visual": "外观",
|
||||||
|
@ -504,7 +504,7 @@
|
||||||
"settings.header.lyrics": "歌词",
|
"settings.header.lyrics": "歌词",
|
||||||
"settings.header.lyrics.description": "调整 Cider 的歌词设置",
|
"settings.header.lyrics.description": "调整 Cider 的歌词设置",
|
||||||
"settings.option.lyrics.enableMusixmatch": "启用 Musixmatch 歌词",
|
"settings.option.lyrics.enableMusixmatch": "启用 Musixmatch 歌词",
|
||||||
"settings.option.lyrics.enableMusixmatchKaraoke": "启用卡拉 OK 模式(仅 Musixmatch)",
|
"settings.option.lyrics.enableMusixmatchKaraoke": "启用卡拉OK模式(仅限 Musixmatch)",
|
||||||
"settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌词语言偏好",
|
"settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌词语言偏好",
|
||||||
"settings.option.lyrics.enableYoutubeLyrics": "播放 MV 时使用 YouTube 歌词",
|
"settings.option.lyrics.enableYoutubeLyrics": "播放 MV 时使用 YouTube 歌词",
|
||||||
"settings.option.lyrics.enableQQLyrics": "启用 QQ 音乐的歌词",
|
"settings.option.lyrics.enableQQLyrics": "启用 QQ 音乐的歌词",
|
||||||
|
@ -514,23 +514,30 @@
|
||||||
"settings.option.connectivity.discordRPC": "Discord 动态",
|
"settings.option.connectivity.discordRPC": "Discord 动态",
|
||||||
"settings.option.connectivity.discordRPC.clientName": "应用程序名称",
|
"settings.option.connectivity.discordRPC.clientName": "应用程序名称",
|
||||||
"settings.option.connectivity.discordRPC.clearOnPause": "暂停时清除 Discord 动态",
|
"settings.option.connectivity.discordRPC.clearOnPause": "暂停时清除 Discord 动态",
|
||||||
"settings.option.connectivity.discordRPC.hideButtons": "隐藏 Discord 动态上的按钮",
|
"settings.option.connectivity.discordRPC.showActivityButtons": "显示动态按钮",
|
||||||
|
"settings.option.connectivity.discordRPC.firstButton": "第一动态按钮",
|
||||||
|
"settings.option.connectivity.discordRPC.secondButton": "第二动态按钮",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.listenOnCider": "在 Cider 中聆听",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.viewOnAppleMusic": "在 Apple Music 中查看",
|
||||||
|
"settings.option.connectivity.discordRPC.buttons.viewOnOtherMusicServices": "在其他音乐服务中查看",
|
||||||
|
"settings.option.connectivity.discordRPC.showSongLink": "在 Discord 动态中显示 Song.link 按钮而非 Apple Music 按钮",
|
||||||
"settings.option.connectivity.discordRPC.hideTimestamp": "隐藏 Discord 动态上的时间戳",
|
"settings.option.connectivity.discordRPC.hideTimestamp": "隐藏 Discord 动态上的时间戳",
|
||||||
"settings.option.connectivity.discordRPC.detailsFormat": "详细信息格式",
|
"settings.option.connectivity.discordRPC.detailsFormat": "详细信息格式",
|
||||||
"settings.option.connectivity.discordRPC.stateFormat": "动态格式",
|
"settings.option.connectivity.discordRPC.stateFormat": "动态格式",
|
||||||
"settings.option.connectivity.discordRPC.reload": "重新加载 DiscordRPC",
|
"settings.option.connectivity.discordRPC.reload": "重新加载 Discord 动态",
|
||||||
"settings.option.connectivity.discordRPC.reconnectedToUser": "DiscordRPC 重新连接至用户:{{user}} ({{userid}})",
|
"settings.option.connectivity.discordRPC.reconnectedToUser": "Discord 动态已重新连接至用户:{{user}} ({{userid}})",
|
||||||
"settings.option.connectivity.lastfmScrobble": "Last.FM 音乐记录",
|
"settings.option.connectivity.lastfmScrobble": "Last.fm 音乐记录",
|
||||||
"settings.option.connectivity.lastfmScrobble.delay": "Last.FM 歌曲追踪延迟 (%)",
|
"settings.option.connectivity.lastfmScrobble.delay": "Last.fm 歌曲追踪延迟(%)",
|
||||||
"settings.option.connectivity.lastfmScrobble.nowPlaying": "打开 Last.FM 正在聆听",
|
"settings.option.connectivity.lastfmScrobble.nowPlaying": "打开 Last.fm 正在聆听",
|
||||||
"settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除合作者 (Last.FM)",
|
"settings.option.connectivity.lastfmScrobble.removeFeatured": "从歌名里去除合作者(Last.fm)",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "不记录单曲循环 (Last.FM)",
|
"settings.option.connectivity.lastfmScrobble.filterLoop": "不记录单曲循环(Last.fm)",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop.description": "防止循环单曲被记录或展示在Last.FM 的正在播放列表中。",
|
"settings.option.connectivity.lastfmScrobble.filterLoop.description": "防止循环单曲被记录或展示在 Last.fm 的正在播放列表中。",
|
||||||
"settings.option.connectivity.lastfmScrobble.filterTypes": "过滤媒体类型 (Last.fm)",
|
"settings.option.connectivity.lastfmScrobble.filterTypes": "过滤媒体类型(Last.fm)",
|
||||||
"settings.option.connectivity.lastfmScrobble.manualToken": "手动输入 Last.fm 验证码",
|
"settings.option.connectivity.lastfmScrobble.manualToken": "手动输入 Last.fm 验证码",
|
||||||
|
"settings.option.connectivity.lastfmScrobble.manualToken.link": "点击此处以获取 Last.fm 验证码",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm 连接超时",
|
"settings.notyf.connectivity.lastfmScrobble.connectError": "Last.fm 连接超时",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.fm 连接成功",
|
"settings.notyf.connectivity.lastfmScrobble.connectSuccess": "Last.fm 连接成功",
|
||||||
"settings.notyf.connectivity.lastfmScrobble.connecting": "正在连接至 Last.fm...",
|
"settings.notyf.connectivity.lastfmScrobble.connecting": "正在连接至 Last.fm……",
|
||||||
"settings.header.debug": "调试",
|
"settings.header.debug": "调试",
|
||||||
"settings.option.debug.copy_log": "拷贝日志至剪贴板",
|
"settings.option.debug.copy_log": "拷贝日志至剪贴板",
|
||||||
"settings.option.debug.openAppData": "打开 Cider 程序文件夹",
|
"settings.option.debug.openAppData": "打开 Cider 程序文件夹",
|
||||||
|
|
|
@ -78,11 +78,15 @@ export class AppEvents {
|
||||||
case "webgpu":
|
case "webgpu":
|
||||||
console.info("WebGPU is enabled.");
|
console.info("WebGPU is enabled.");
|
||||||
app.commandLine.appendSwitch("enable-unsafe-webgpu");
|
app.commandLine.appendSwitch("enable-unsafe-webgpu");
|
||||||
|
if (process.platform === "linux") {
|
||||||
|
app.commandLine.appendSwitch("enable-features", "Vulkan");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "disabled":
|
case "disabled":
|
||||||
console.info("Hardware acceleration is disabled.");
|
console.info("Hardware acceleration is disabled.");
|
||||||
app.commandLine.appendSwitch("disable-gpu");
|
app.commandLine.appendSwitch("disable-gpu");
|
||||||
|
app.disableHardwareAcceleration();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +236,7 @@ export class AppEvents {
|
||||||
|
|
||||||
startArgs.forEach((arg) => {
|
startArgs.forEach((arg) => {
|
||||||
console.log(arg);
|
console.log(arg);
|
||||||
if (arg.includes("cider://")) {
|
if (arg.includes("cider://") || arg.includes("itms://") || arg.includes("itmss://") || arg.includes("music://") || arg.includes("musics://")) {
|
||||||
console.debug("[InstanceHandler] (second-instance) Link detected with " + arg);
|
console.debug("[InstanceHandler] (second-instance) Link detected with " + arg);
|
||||||
this.LinkHandler(arg);
|
this.LinkHandler(arg);
|
||||||
} else if (arg.includes("--force-quit")) {
|
} else if (arg.includes("--force-quit")) {
|
||||||
|
@ -328,10 +332,10 @@ export class AppEvents {
|
||||||
|
|
||||||
{
|
{
|
||||||
visible: visible,
|
visible: visible,
|
||||||
label: 'track info',
|
label: 'track info',
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
{type: 'separator'},
|
{type: 'separator'},
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { app, BrowserWindow as bw, ipcMain, ShareMenu, shell, screen, dialog } from "electron";
|
import { app, BrowserWindow as bw, ipcMain, ShareMenu, shell, screen, dialog, nativeTheme } from "electron";
|
||||||
import * as windowStateKeeper from "electron-window-state";
|
import * as windowStateKeeper from "electron-window-state";
|
||||||
import * as express from "express";
|
import * as express from "express";
|
||||||
import * as getPort from "get-port";
|
import * as getPort from "get-port";
|
||||||
|
@ -90,6 +90,7 @@ export class BrowserWindow {
|
||||||
"components/equalizer",
|
"components/equalizer",
|
||||||
"components/add-to-playlist",
|
"components/add-to-playlist",
|
||||||
"components/queue",
|
"components/queue",
|
||||||
|
"components/smarthints",
|
||||||
"components/mediaitem-scroller-horizontal",
|
"components/mediaitem-scroller-horizontal",
|
||||||
"components/mediaitem-scroller-horizontal-large",
|
"components/mediaitem-scroller-horizontal-large",
|
||||||
"components/mediaitem-scroller-horizontal-sp",
|
"components/mediaitem-scroller-horizontal-sp",
|
||||||
|
@ -441,6 +442,8 @@ export class BrowserWindow {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nativeTheme.themeSource = utils.getStoreValue("visual.overrideDisplayTheme");
|
||||||
|
|
||||||
// Start the webserver for the browser window to load
|
// Start the webserver for the browser window to load
|
||||||
// LocalFiles.DB.init()
|
// LocalFiles.DB.init()
|
||||||
this.startWebServer();
|
this.startWebServer();
|
||||||
|
@ -476,7 +479,7 @@ export class BrowserWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < expectedFiles.length; i++) {
|
for (let i = 0; i < expectedFiles.length; i++) {
|
||||||
const file = join(utils.getPath("ciderCache"), expectedFiles[i]);
|
const file = join(join(app.getPath("userData"), "CiderCache"), expectedFiles[i]);
|
||||||
if (!existsSync(file)) {
|
if (!existsSync(file)) {
|
||||||
writeFileSync(file, JSON.stringify([]));
|
writeFileSync(file, JSON.stringify([]));
|
||||||
}
|
}
|
||||||
|
@ -555,15 +558,11 @@ export class BrowserWindow {
|
||||||
res.send("Stopped");
|
res.send("Stopped");
|
||||||
break;
|
break;
|
||||||
case "next":
|
case "next":
|
||||||
BrowserWindow.win.webContents.executeJavaScript(
|
BrowserWindow.win.webContents.executeJavaScript("if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);}");
|
||||||
"if (MusicKit.getInstance().queue.nextPlayableItemIndex != -1 && MusicKit.getInstance().queue.nextPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.nextPlayableItemIndex);}"
|
|
||||||
);
|
|
||||||
res.send("Next");
|
res.send("Next");
|
||||||
break;
|
break;
|
||||||
case "previous":
|
case "previous":
|
||||||
BrowserWindow.win.webContents.executeJavaScript(
|
BrowserWindow.win.webContents.executeJavaScript("if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex);}");
|
||||||
"if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex);}"
|
|
||||||
);
|
|
||||||
res.send("Previous");
|
res.send("Previous");
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
|
@ -619,6 +618,8 @@ export class BrowserWindow {
|
||||||
const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
|
const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
|
||||||
if (!this.chromecastIP.includes(ip)) {
|
if (!this.chromecastIP.includes(ip)) {
|
||||||
this.headerSent = false;
|
this.headerSent = false;
|
||||||
|
this.audioStream._readableState.buffer.clear();
|
||||||
|
this.audioStream._readableState.length = 0;
|
||||||
this.chromecastIP.push(ip);
|
this.chromecastIP.push(ip);
|
||||||
}
|
}
|
||||||
req.socket.setTimeout(Number.MAX_SAFE_INTEGER);
|
req.socket.setTimeout(Number.MAX_SAFE_INTEGER);
|
||||||
|
@ -730,18 +731,11 @@ export class BrowserWindow {
|
||||||
details.requestHeaders["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cider/1.0.0 Chrome/96.0.4664.45 Electron/16.0.0 Safari/537.36";
|
details.requestHeaders["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cider/1.0.0 Chrome/96.0.4664.45 Electron/16.0.0 Safari/537.36";
|
||||||
}
|
}
|
||||||
if (details.url.includes("https://qq.com")) {
|
if (details.url.includes("https://qq.com")) {
|
||||||
(details.requestHeaders["Accept"] = "*/*"),
|
(details.requestHeaders["Accept"] = "*/*"), (details.requestHeaders["Accept-Encoding"] = "gzip, deflate, br"), (details.requestHeaders["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"), (details.requestHeaders["Referer"] = "https://y.qq.com/"), (details.requestHeaders["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 (");
|
||||||
(details.requestHeaders["Accept-Encoding"] = "gzip, deflate, br"),
|
|
||||||
(details.requestHeaders["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"),
|
|
||||||
(details.requestHeaders["Referer"] = "https://y.qq.com/"),
|
|
||||||
(details.requestHeaders["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 (");
|
|
||||||
("KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3) ");
|
("KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3) ");
|
||||||
}
|
}
|
||||||
if (details.url.includes("https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg")) {
|
if (details.url.includes("https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg")) {
|
||||||
(details.requestHeaders["Accept"] = "*/*"),
|
(details.requestHeaders["Accept"] = "*/*"), (details.requestHeaders["Accept-Encoding"] = "gzip, deflate, br"), (details.requestHeaders["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"), (details.requestHeaders["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 (");
|
||||||
(details.requestHeaders["Accept-Encoding"] = "gzip, deflate, br"),
|
|
||||||
(details.requestHeaders["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"),
|
|
||||||
(details.requestHeaders["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 (");
|
|
||||||
("KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3) ");
|
("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";
|
details.requestHeaders["Referer"] = "https://y.qq.com/portal/player.html";
|
||||||
}
|
}
|
||||||
|
@ -1073,13 +1067,13 @@ export class BrowserWindow {
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle("put-cache", (_event, arg) => {
|
ipcMain.handle("put-cache", (_event, arg) => {
|
||||||
writeFileSync(join(utils.getPath("ciderCache"), `${arg.file}.json`), arg.data);
|
writeFileSync(join(join(app.getPath("userData"), "CiderCache"), `${arg.file}.json`), arg.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on("get-cache", (event, arg) => {
|
ipcMain.on("get-cache", (event, arg) => {
|
||||||
let read = "";
|
let read = "";
|
||||||
if (existsSync(join(utils.getPath("ciderCache"), `${arg}.json`))) {
|
if (existsSync(join(join(app.getPath("userData"), "CiderCache"), `${arg}.json`))) {
|
||||||
read = readFileSync(join(utils.getPath("ciderCache"), `${arg}.json`), "utf8");
|
read = readFileSync(join(join(app.getPath("userData"), "CiderCache"), `${arg}.json`), "utf8");
|
||||||
}
|
}
|
||||||
event.returnValue = read;
|
event.returnValue = read;
|
||||||
});
|
});
|
||||||
|
@ -1135,6 +1129,11 @@ export class BrowserWindow {
|
||||||
BrowserWindow.win.setBounds({ x, y });
|
BrowserWindow.win.setBounds({ x, y });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Override light, dark
|
||||||
|
ipcMain.on("changeDisplayTheme", (event, theme) => {
|
||||||
|
nativeTheme.themeSource = theme;
|
||||||
|
});
|
||||||
|
|
||||||
//Fullscreen
|
//Fullscreen
|
||||||
ipcMain.on("setFullScreen", (_event, flag) => {
|
ipcMain.on("setFullScreen", (_event, flag) => {
|
||||||
BrowserWindow.win.setFullScreen(flag);
|
BrowserWindow.win.setFullScreen(flag);
|
||||||
|
@ -1351,7 +1350,7 @@ export class BrowserWindow {
|
||||||
.then(async (buffer) => {
|
.then(async (buffer) => {
|
||||||
const metadata = await mm.parseBuffer(buffer, "audio/x-m4a");
|
const metadata = await mm.parseBuffer(buffer, "audio/x-m4a");
|
||||||
let SoundCheckTag = metadata.native.iTunes[1].value;
|
let SoundCheckTag = metadata.native.iTunes[1].value;
|
||||||
console.log("sc", SoundCheckTag);
|
console.debug("sc", SoundCheckTag);
|
||||||
BrowserWindow.win.webContents.send("SoundCheckTag", SoundCheckTag);
|
BrowserWindow.win.webContents.send("SoundCheckTag", SoundCheckTag);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -1476,7 +1475,7 @@ export class BrowserWindow {
|
||||||
|
|
||||||
// Set window Handler
|
// Set window Handler
|
||||||
BrowserWindow.win.webContents.setWindowOpenHandler((x: any) => {
|
BrowserWindow.win.webContents.setWindowOpenHandler((x: any) => {
|
||||||
if (x.url.includes("apple") || x.url.includes("localhost")) {
|
if (x.url.includes("apple.com") || x.url.includes("localhost")) {
|
||||||
return { action: "allow" };
|
return { action: "allow" };
|
||||||
}
|
}
|
||||||
shell.openExternal(x.url).catch(console.error);
|
shell.openExternal(x.url).catch(console.error);
|
||||||
|
@ -1498,11 +1497,7 @@ export class BrowserWindow {
|
||||||
if (details.family === "IPv4" && !details.internal) {
|
if (details.family === "IPv4" && !details.internal) {
|
||||||
if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ":" + alias : ""))) {
|
if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ":" + alias : ""))) {
|
||||||
if (details.address.substring(0, 8) === "192.168." || details.address.substring(0, 7) === "172.16." || details.address.substring(0, 3) === "10.") {
|
if (details.address.substring(0, 8) === "192.168." || details.address.substring(0, 7) === "172.16." || details.address.substring(0, 3) === "10.") {
|
||||||
if (
|
if (!ip.startsWith("192.168.") || (String(ip2).startsWith("192.168.") && !ip.startsWith("192.168.") && String(ip2).startsWith("172.16.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.")) || (String(ip2).startsWith("10.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.") && !ip.startsWith("10."))) {
|
||||||
!ip.startsWith("192.168.") ||
|
|
||||||
(String(ip2).startsWith("192.168.") && !ip.startsWith("192.168.") && String(ip2).startsWith("172.16.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.")) ||
|
|
||||||
(String(ip2).startsWith("10.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.") && !ip.startsWith("10."))
|
|
||||||
) {
|
|
||||||
ip = details.address;
|
ip = details.address;
|
||||||
}
|
}
|
||||||
++alias;
|
++alias;
|
||||||
|
|
|
@ -88,6 +88,7 @@ export class Plugins {
|
||||||
win: utils.getWindow(),
|
win: utils.getWindow(),
|
||||||
dir: pluginPath,
|
dir: pluginPath,
|
||||||
dirName: file,
|
dirName: file,
|
||||||
|
express: utils.getExpress(),
|
||||||
};
|
};
|
||||||
plugins[plugin.name] = new plugin(pluginEnv);
|
plugins[plugin.name] = new plugin(pluginEnv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,11 +72,18 @@ export class Store {
|
||||||
discord_rpc: {
|
discord_rpc: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
client: "Cider",
|
client: "Cider",
|
||||||
|
activity: {
|
||||||
|
state_format: "by {artist}",
|
||||||
|
details_format: "{title}",
|
||||||
|
hide_timestamp: false,
|
||||||
|
buttons: {
|
||||||
|
enabled: true,
|
||||||
|
first: "listenOnCider",
|
||||||
|
second: "viewOnAppleMusic",
|
||||||
|
options: ["listenOnCider", "viewOnAppleMusic", "viewOnOtherMusicServices"],
|
||||||
|
},
|
||||||
|
},
|
||||||
clear_on_pause: true,
|
clear_on_pause: true,
|
||||||
hide_buttons: false,
|
|
||||||
hide_timestamp: false,
|
|
||||||
state_format: "by {artist}",
|
|
||||||
details_format: "{title}",
|
|
||||||
},
|
},
|
||||||
lastfm: {
|
lastfm: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
@ -200,6 +207,7 @@ export class Store {
|
||||||
accentColor: "#fc3c44",
|
accentColor: "#fc3c44",
|
||||||
purplePodcastPlaybackBar: false,
|
purplePodcastPlaybackBar: false,
|
||||||
maxElementScale: -1, // -1 default, anything else is a custom scale
|
maxElementScale: -1, // -1 default, anything else is a custom scale
|
||||||
|
overrideDisplayTheme: "system", // system , dark, light
|
||||||
},
|
},
|
||||||
lyrics: {
|
lyrics: {
|
||||||
enable_mxm: true,
|
enable_mxm: true,
|
||||||
|
@ -232,7 +240,6 @@ export class Store {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.defaults.general.language = this.checkLocale(app.getLocale().replace("-", "_")) ?? "en_US";
|
|
||||||
Store.cfg = new ElectronStore({
|
Store.cfg = new ElectronStore({
|
||||||
name: "cider-config",
|
name: "cider-config",
|
||||||
defaults: this.defaults,
|
defaults: this.defaults,
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
"components/moreinfo-modal",
|
"components/moreinfo-modal",
|
||||||
"components/equalizer",
|
"components/equalizer",
|
||||||
"components/add-to-playlist",
|
"components/add-to-playlist",
|
||||||
|
"components/smarthints",
|
||||||
"components/queue",
|
"components/queue",
|
||||||
"components/mediaitem-scroller-horizontal",
|
"components/mediaitem-scroller-horizontal",
|
||||||
"components/mediaitem-scroller-horizontal-large",
|
"components/mediaitem-scroller-horizontal-large",
|
||||||
|
|
|
@ -208,9 +208,7 @@ export class wsapi {
|
||||||
response.message = "Next";
|
response.message = "Next";
|
||||||
break;
|
break;
|
||||||
case "previous":
|
case "previous":
|
||||||
this._win.webContents.executeJavaScript(
|
this._win.webContents.executeJavaScript(`if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex)}`);
|
||||||
`if (MusicKit.getInstance().queue.previousPlayableItemIndex != -1 && MusicKit.getInstance().queue.previousPlayableItemIndex != null) {MusicKit.getInstance().changeToMediaAtIndex(MusicKit.getInstance().queue.previousPlayableItemIndex)}`
|
|
||||||
);
|
|
||||||
response.message = "Previous";
|
response.message = "Previous";
|
||||||
break;
|
break;
|
||||||
case "musickit-api":
|
case "musickit-api":
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
require("v8-compile-cache");
|
require("v8-compile-cache");
|
||||||
|
|
||||||
|
import { app, components, ipcMain } from "electron";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { app } from "electron";
|
|
||||||
if (!app.isPackaged) {
|
|
||||||
app.setPath("userData", join(app.getPath("appData"), "Cider"));
|
|
||||||
}
|
|
||||||
|
|
||||||
import { Store } from "./base/store";
|
import { Store } from "./base/store";
|
||||||
import { AppEvents } from "./base/app";
|
import { AppEvents } from "./base/app";
|
||||||
import { Plugins } from "./base/plugins";
|
import { Plugins } from "./base/plugins";
|
||||||
import { BrowserWindow } from "./base/browserwindow";
|
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 { RewriteFrames } from "@sentry/integrations";
|
||||||
import { components, ipcMain } from "electron";
|
|
||||||
|
if (!app.isPackaged) {
|
||||||
|
app.setPath("userData", join(app.getPath("appData"), "Cider"));
|
||||||
|
}
|
||||||
|
|
||||||
// Analytics for debugging fun yeah.
|
// Analytics for debugging fun yeah.
|
||||||
Sentry({
|
Sentry({
|
||||||
|
@ -54,7 +53,9 @@ app.on("ready", () => {
|
||||||
win.on("ready-to-show", () => {
|
win.on("ready-to-show", () => {
|
||||||
console.debug("[Cider] Window is Ready.");
|
console.debug("[Cider] Window is Ready.");
|
||||||
CiderPlug.callPlugins("onReady", win);
|
CiderPlug.callPlugins("onReady", win);
|
||||||
win.show();
|
if (!app.commandLine.hasSwitch("hidden")) {
|
||||||
|
win.show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -62,9 +63,11 @@ app.on("ready", () => {
|
||||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
* Renderer Event Handlers
|
* Renderer Event Handlers
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||||
|
let rendererInitialized = false;
|
||||||
ipcMain.handle("renderer-ready", (event) => {
|
ipcMain.handle("renderer-ready", (event) => {
|
||||||
|
if (rendererInitialized) return;
|
||||||
CiderPlug.callPlugins("onRendererReady", event);
|
CiderPlug.callPlugins("onRendererReady", event);
|
||||||
|
rendererInitialized = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on("playbackStateDidChange", (_event, attributes) => {
|
ipcMain.on("playbackStateDidChange", (_event, attributes) => {
|
||||||
|
@ -75,6 +78,10 @@ ipcMain.on("nowPlayingItemDidChange", (_event, attributes) => {
|
||||||
CiderPlug.callPlugins("onNowPlayingItemDidChange", attributes);
|
CiderPlug.callPlugins("onNowPlayingItemDidChange", attributes);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on("playbackTimeDidChange", (_event, attributes) => {
|
||||||
|
CiderPlug.callPlugins("playbackTimeDidChange", attributes);
|
||||||
|
});
|
||||||
|
|
||||||
app.on("before-quit", () => {
|
app.on("before-quit", () => {
|
||||||
CiderPlug.callPlugins("onBeforeQuit");
|
CiderPlug.callPlugins("onBeforeQuit");
|
||||||
console.warn(`${app.getName()} exited.`);
|
console.warn(`${app.getName()} exited.`);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as electron from "electron";
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
import { resolve } from "path";
|
import { resolve } from "path";
|
||||||
import * as CiderReceiver from "../base/castreceiver";
|
import * as CiderReceiver from "../base/castreceiver";
|
||||||
|
const MediaRendererClient = require("upnp-mediarenderer-client");
|
||||||
|
|
||||||
export default class ChromecastPlugin {
|
export default class ChromecastPlugin {
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +29,7 @@ export default class ChromecastPlugin {
|
||||||
private connectedHosts: any = {};
|
private connectedHosts: any = {};
|
||||||
private connectedPlayer: any;
|
private connectedPlayer: any;
|
||||||
private ciderPort: any = 9000;
|
private ciderPort: any = 9000;
|
||||||
|
private scanCount: any = 0;
|
||||||
// private server = false;
|
// private server = false;
|
||||||
// private bufcount = 0;
|
// private bufcount = 0;
|
||||||
// private bufcount2 = 0;
|
// private bufcount2 = 0;
|
||||||
|
@ -67,19 +69,15 @@ export default class ChromecastPlugin {
|
||||||
|
|
||||||
ssdpBrowser.search("urn:dial-multiscreen-org:device:dial:1");
|
ssdpBrowser.search("urn:dial-multiscreen-org:device:dial:1");
|
||||||
|
|
||||||
// // actual upnp devices
|
// actual upnp devices
|
||||||
// if (app.cfg.get("audio.enableDLNA")) {
|
let ssdpBrowser2 = new Client();
|
||||||
// let ssdpBrowser2 = new Client();
|
ssdpBrowser2.on("response", (headers: any, statusCode: any, rinfo: any) => {
|
||||||
// ssdpBrowser2.on('response', (headers, statusCode, rinfo) => {
|
var location = getLocation(headers);
|
||||||
// var location = getLocation(headers);
|
if (location != null) {
|
||||||
// if (location != null) {
|
this.getServiceDescription(location, rinfo.address);
|
||||||
// this.getServiceDescription(location, rinfo.address);
|
}
|
||||||
// }
|
});
|
||||||
|
ssdpBrowser2.search("urn:schemas-upnp-org:device:MediaRenderer:1");
|
||||||
// });
|
|
||||||
// ssdpBrowser2.search('urn:schemas-upnp-org:device:MediaRenderer:1');
|
|
||||||
|
|
||||||
// }
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Search GC err", e);
|
console.log("Search GC err", e);
|
||||||
}
|
}
|
||||||
|
@ -202,11 +200,7 @@ export default class ChromecastPlugin {
|
||||||
if (details.family === "IPv4" && !details.internal) {
|
if (details.family === "IPv4" && !details.internal) {
|
||||||
if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ":" + alias : ""))) {
|
if (!/(loopback|vmware|internal|hamachi|vboxnet|virtualbox)/gi.test(dev + (alias ? ":" + alias : ""))) {
|
||||||
if (details.address.substring(0, 8) === "192.168." || details.address.substring(0, 7) === "172.16." || details.address.substring(0, 3) === "10.") {
|
if (details.address.substring(0, 8) === "192.168." || details.address.substring(0, 7) === "172.16." || details.address.substring(0, 3) === "10.") {
|
||||||
if (
|
if (!ip.startsWith("192.168.") || (ip2.startsWith("192.168.") && !ip.startsWith("192.168.") && ip2.startsWith("172.16.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.")) || (ip2.startsWith("10.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.") && !ip.startsWith("10."))) {
|
||||||
!ip.startsWith("192.168.") ||
|
|
||||||
(ip2.startsWith("192.168.") && !ip.startsWith("192.168.") && ip2.startsWith("172.16.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.")) ||
|
|
||||||
(ip2.startsWith("10.") && !ip.startsWith("192.168.") && !ip.startsWith("172.16.") && !ip.startsWith("10."))
|
|
||||||
) {
|
|
||||||
ip = details.address;
|
ip = details.address;
|
||||||
}
|
}
|
||||||
++alias;
|
++alias;
|
||||||
|
@ -257,26 +251,29 @@ export default class ChromecastPlugin {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// upnp devices
|
// upnp devices
|
||||||
//try {
|
try {
|
||||||
// client = new MediaRendererClient(UPNPDesc);
|
let client = new MediaRendererClient(UPNPDesc);
|
||||||
// const options = {
|
const options = {
|
||||||
// autoplay: true,
|
autoplay: true,
|
||||||
// contentType: 'audio/x-wav',
|
contentType: "audio/x-wav",
|
||||||
// dlnaFeatures: 'DLNA.ORG_PN=-;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000',
|
dlnaFeatures: "DLNA.ORG_PN=-;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000",
|
||||||
// metadata: {
|
metadata: {
|
||||||
// title: 'Apple Music Electron',
|
title: "Cider",
|
||||||
// creator: 'Streaming ...',
|
creator: "Streaming ...",
|
||||||
// type: 'audio', // can be 'video', 'audio' or 'image'
|
type: "audio", // can be 'video', 'audio' or 'image'
|
||||||
// // url: 'http://' + getIp() + ':' + server.address().port + '/',
|
// url: 'http://' + getIp() + ':' + server.address().port + '/',
|
||||||
// // protocolInfo: 'DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000;
|
// protocolInfo: 'DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000;
|
||||||
// }
|
},
|
||||||
// };
|
};
|
||||||
// client.load('http://' + getIp() + ':' + server.address().port + '/a.wav', options, function (err, _result) {
|
client.load("http://" + this.getIp() + ":" + this.ciderPort + "/audio.wav", options, function (err: any, _result: any) {
|
||||||
// if (err) throw err;
|
if (err) throw err;
|
||||||
// console.log('playing ...');
|
console.log("playing ...");
|
||||||
// });
|
});
|
||||||
// } catch (e) {
|
if (!this.connectedHosts[device.host]) {
|
||||||
// }
|
this.connectedHosts[device.host] = client;
|
||||||
|
this.activeConnections.push(client);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,6 +315,10 @@ export default class ChromecastPlugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("getChromeCastDevices", (_event, _data) => {
|
electron.ipcMain.on("getChromeCastDevices", (_event, _data) => {
|
||||||
|
if (this.scanCount++ == 2) {
|
||||||
|
this.scanCount = 0;
|
||||||
|
this.castDevices = [];
|
||||||
|
}
|
||||||
this.searchForGCDevices();
|
this.searchForGCDevices();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -48,15 +48,21 @@ export default class DiscordRPC {
|
||||||
* Runs on app ready
|
* Runs on app ready
|
||||||
*/
|
*/
|
||||||
onReady(_win: any): void {
|
onReady(_win: any): void {
|
||||||
const self = this;
|
|
||||||
this.connect();
|
this.connect();
|
||||||
console.debug(`[Plugin][${this.name}] Ready.`);
|
console.debug(`[Plugin][${this.name}] Ready.`);
|
||||||
ipcMain.on("updateRPCImage", async (_event, imageurl) => {
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up ipc listeners for the plugin
|
||||||
|
*/
|
||||||
|
onRendererReady() {
|
||||||
|
const self = this;
|
||||||
|
ipcMain.on("discordrpc:updateImage", async (_event, imageurl) => {
|
||||||
if (!this._utils.getStoreValue("general.privateEnabled")) {
|
if (!this._utils.getStoreValue("general.privateEnabled")) {
|
||||||
let b64data = "";
|
let b64data = "";
|
||||||
let postbody = "";
|
let postbody = "";
|
||||||
if (imageurl.startsWith("/ciderlocalart")) {
|
if (imageurl.startsWith("/ciderlocalart")) {
|
||||||
let port = await _win.webContents.executeJavaScript(`app.clientPort`);
|
let port = await this._utils.getWindow().webContents.executeJavaScript(`app.clientPort`);
|
||||||
console.log("http://localhost:" + port + imageurl);
|
console.log("http://localhost:" + port + imageurl);
|
||||||
const response = await fetch("http://localhost:" + port + imageurl);
|
const response = await fetch("http://localhost:" + port + imageurl);
|
||||||
b64data = (await response.buffer()).toString("base64");
|
b64data = (await response.buffer()).toString("base64");
|
||||||
|
@ -66,7 +72,7 @@ export default class DiscordRPC {
|
||||||
body: postbody,
|
body: postbody,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": _win.webContents.getUserAgent(),
|
"User-Agent": this._utils.getWindow().webContents.getUserAgent(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
|
@ -81,7 +87,7 @@ export default class DiscordRPC {
|
||||||
body: postbody,
|
body: postbody,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": _win.webContents.getUserAgent(),
|
"User-Agent": this._utils.getWindow().webContents.getUserAgent(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
|
@ -92,17 +98,22 @@ export default class DiscordRPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ipcMain.on("reloadRPC", () => {
|
ipcMain.on("discordrpc:reload", (_event, configUpdate = null) => {
|
||||||
console.log(`[DiscordRPC][reload] Reloading DiscordRPC.`);
|
console.log(`[DiscordRPC][reload] Reloading DiscordRPC.`);
|
||||||
this._client.destroy();
|
|
||||||
|
|
||||||
|
if (this._client) {
|
||||||
|
this._client.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._utils.getStoreValue("connectivity.discord_rpc.enabled")) return;
|
||||||
this._client
|
this._client
|
||||||
.endlessLogin({
|
.endlessLogin({
|
||||||
clientId: this._utils.getStoreValue("connectivity.discord_rpc.client") === "Cider" ? "911790844204437504" : "886578863147192350",
|
clientId: this._utils.getStoreValue("connectivity.discord_rpc.client") === "Cider" ? "911790844204437504" : "886578863147192350",
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
console.log(`[DiscordRPC][reload] DiscordRPC Reloaded.`);
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
this._utils.getWindow().webContents.send("rpcReloaded", this._client.user);
|
if (configUpdate == null) this._utils.getWindow().webContents.send("rpcReloaded", this._client.user);
|
||||||
if (this._activityCache && this._activityCache.details && this._activityCache.state) {
|
if (this._activityCache && this._activityCache.details && this._activityCache.state) {
|
||||||
console.info(`[DiscordRPC][reload] Restoring activity cache.`);
|
console.info(`[DiscordRPC][reload] Restoring activity cache.`);
|
||||||
this._client.setActivity(this._activityCache);
|
this._client.setActivity(this._activityCache);
|
||||||
|
@ -111,6 +122,13 @@ export default class DiscordRPC {
|
||||||
.catch((e: any) => console.error(`[DiscordRPC][reload] ${e}`));
|
.catch((e: any) => console.error(`[DiscordRPC][reload] ${e}`));
|
||||||
// this.connect(true)
|
// this.connect(true)
|
||||||
});
|
});
|
||||||
|
ipcMain.on("onPrivacyModeChange", (_event, enabled) => {
|
||||||
|
if (enabled && this._client) {
|
||||||
|
this._client.clearActivity();
|
||||||
|
} else if (!enabled && this._activityCache && this._activityCache.details && this._activityCache.state) {
|
||||||
|
this._client.setActivity(this._activityCache);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,7 +151,7 @@ export default class DiscordRPC {
|
||||||
* Runs on song change
|
* Runs on song change
|
||||||
* @param attributes Music Attributes
|
* @param attributes Music Attributes
|
||||||
*/
|
*/
|
||||||
onNowPlayingItemDidChange(attributes: object): void {
|
playbackTimeDidChange(attributes: object): void {
|
||||||
this._attributes = attributes;
|
this._attributes = attributes;
|
||||||
this.setActivity(attributes);
|
this.setActivity(attributes);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +176,7 @@ export default class DiscordRPC {
|
||||||
this._client.once("ready", () => {
|
this._client.once("ready", () => {
|
||||||
console.info(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${this._client.user.id}.`);
|
console.info(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${this._client.user.id}.`);
|
||||||
|
|
||||||
if (this._activityCache && this._activityCache.details && this._activityCache.state) {
|
if (this._activityCache && this._activityCache.details && this._activityCache.state && !this._utils.getStoreValue("general.privateEnabled")) {
|
||||||
console.info(`[DiscordRPC][connect] Restoring activity cache.`);
|
console.info(`[DiscordRPC][connect] Restoring activity cache.`);
|
||||||
this._client.setActivity(this._activityCache);
|
this._client.setActivity(this._activityCache);
|
||||||
}
|
}
|
||||||
|
@ -180,14 +198,14 @@ export default class DiscordRPC {
|
||||||
* @param attributes Music Attributes
|
* @param attributes Music Attributes
|
||||||
*/
|
*/
|
||||||
private setActivity(attributes: any) {
|
private setActivity(attributes: any) {
|
||||||
if (!this._client) {
|
if (!this._client || !attributes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if show buttons is (true) or (false)
|
// Check if show buttons is (true) or (false)
|
||||||
let activity: Object = {
|
let activity: Object = {
|
||||||
details: this._utils.getStoreValue("connectivity.discord_rpc.details_format"),
|
details: this._utils.getStoreValue("connectivity.discord_rpc.activity.details_format"),
|
||||||
state: this._utils.getStoreValue("connectivity.discord_rpc.state_format"),
|
state: this._utils.getStoreValue("connectivity.discord_rpc.activity.state_format"),
|
||||||
largeImageKey: attributes?.artwork?.url?.replace("{w}", "1024").replace("{h}", "1024"),
|
largeImageKey: attributes?.artwork?.url?.replace("{w}", "1024").replace("{h}", "1024"),
|
||||||
largeImageText: attributes.albumName,
|
largeImageText: attributes.albumName,
|
||||||
instance: false, // Whether the activity is in a game session
|
instance: false, // Whether the activity is in a game session
|
||||||
|
@ -201,10 +219,14 @@ export default class DiscordRPC {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the activity
|
if (!activity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!attributes.status && this._utils.getStoreValue("connectivity.discord_rpc.clear_on_pause")) {
|
if (!attributes.status && this._utils.getStoreValue("connectivity.discord_rpc.clear_on_pause")) {
|
||||||
this._client.clearActivity();
|
this._client.clearActivity();
|
||||||
} else if (activity && this._activityCache !== activity) {
|
} else if (activity && this._activityCache !== activity) {
|
||||||
|
if (this._utils.getStoreValue("general.privateEnabled")) return;
|
||||||
this._client.setActivity(activity);
|
this._client.setActivity(activity);
|
||||||
}
|
}
|
||||||
this._activityCache = activity;
|
this._activityCache = activity;
|
||||||
|
@ -214,16 +236,29 @@ export default class DiscordRPC {
|
||||||
* Filter the Discord activity object
|
* Filter the Discord activity object
|
||||||
*/
|
*/
|
||||||
private filterActivity(activity: any, attributes: any): Object {
|
private filterActivity(activity: any, attributes: any): Object {
|
||||||
// Add the buttons if people want them
|
// Handling Activity Buttons
|
||||||
if (!this._utils.getStoreValue("connectivity.discord_rpc.hide_buttons")) {
|
if (this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.enabled") && this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first") != "disabled") {
|
||||||
activity.buttons = [
|
const activityUrls: { [key: string]: any } = {
|
||||||
{ label: "Listen on Cider", url: attributes.url.cider },
|
listenOnCider: "cider",
|
||||||
{ label: "View on Apple Music", url: attributes.url.appleMusic },
|
viewOnAppleMusic: "appleMusic",
|
||||||
]; //To change attributes.url => preload/cider-preload.js
|
viewOnOtherMusicServices: "songLink",
|
||||||
|
};
|
||||||
|
|
||||||
|
const firstActivity = this._utils.getLocale(this._utils.getStoreValue("general.language"), `settings.option.connectivity.discordRPC.buttons.${this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first")}`);
|
||||||
|
const secondActivity = this._utils.getLocale(this._utils.getStoreValue("general.language"), `settings.option.connectivity.discordRPC.buttons.${this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.second")}`);
|
||||||
|
|
||||||
|
if (this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.second") != "disabled") {
|
||||||
|
activity.buttons = [
|
||||||
|
{ label: firstActivity, url: attributes.url[activityUrls[this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first")]] },
|
||||||
|
{ label: secondActivity, url: attributes.url[activityUrls[this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.second")]] },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
activity.buttons = [{ label: firstActivity, url: attributes.url[activityUrls[this._utils.getStoreValue("connectivity.discord_rpc.activity.buttons.first")]] }];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the timestamp if its playing and people want them
|
// Add the timestamp if its playing and people want them
|
||||||
if (!this._utils.getStoreValue("connectivity.discord_rpc.hide_timestamp") && attributes.status) {
|
if (!this._utils.getStoreValue("connectivity.discord_rpc.hide_timestamp") && attributes.status && new Date(attributes.endTime).getTime() > 0 && isFinite(attributes.endTime) && isFinite(attributes.startTime)) {
|
||||||
activity.startTimestamp = Date.now() - (attributes?.durationInMillis - attributes?.remainingTime);
|
activity.startTimestamp = Date.now() - (attributes?.durationInMillis - attributes?.remainingTime);
|
||||||
activity.endTimestamp = attributes.endTime;
|
activity.endTimestamp = attributes.endTime;
|
||||||
}
|
}
|
||||||
|
@ -280,12 +315,6 @@ export default class DiscordRPC {
|
||||||
activity.largeImageKey = "cider";
|
activity.largeImageKey = "cider";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timestamp
|
|
||||||
if (new Date(attributes.endTime).getTime() < 0) {
|
|
||||||
delete activity.startTime;
|
|
||||||
delete activity.endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not sure
|
// not sure
|
||||||
if (!attributes.artistName) {
|
if (!attributes.artistName) {
|
||||||
delete activity.state;
|
delete activity.state;
|
||||||
|
@ -294,6 +323,10 @@ export default class DiscordRPC {
|
||||||
if (!activity.largeImageText || activity.largeImageText.length < 2) {
|
if (!activity.largeImageText || activity.largeImageText.length < 2) {
|
||||||
delete activity.largeImageText;
|
delete activity.largeImageText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (activity.status === "" || activity.details === "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,9 @@ export default class lastfm {
|
||||||
|
|
||||||
onReady(_win: Electron.BrowserWindow): void {
|
onReady(_win: Electron.BrowserWindow): void {
|
||||||
this.initializeLastFM("", this._apiCredentials);
|
this.initializeLastFM("", this._apiCredentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRendererReady(): void {
|
||||||
// Register the ipcMain handlers
|
// Register the ipcMain handlers
|
||||||
this._utils.getIPCMain().handle("lastfm:url", (event: any) => {
|
this._utils.getIPCMain().handle("lastfm:url", (event: any) => {
|
||||||
console.debug(`[${lastfm.name}:url] Called.`);
|
console.debug(`[${lastfm.name}:url] Called.`);
|
||||||
|
@ -48,32 +50,21 @@ export default class lastfm {
|
||||||
});
|
});
|
||||||
|
|
||||||
this._utils.getIPCMain().on("lastfm:nowPlayingChange", (event: any, attributes: any) => {
|
this._utils.getIPCMain().on("lastfm:nowPlayingChange", (event: any, attributes: any) => {
|
||||||
if (this._utils.getStoreValue("connectivity.lastfm.filter_loop") || this._utils.getStoreValue("general.privateEnabled")) return;
|
if (this._utils.getStoreValue("connectivity.lastfm.filter_loop") || this._utils.getStoreValue("general.privateEnabled") || attributes.type === "radioStation") return;
|
||||||
|
this.updateNowPlayingTrack(attributes);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._utils.getIPCMain().on("lastfm:FilteredNowPlayingItemDidChange", (event: any, attributes: any) => {
|
||||||
|
if (this._utils.getStoreValue("general.privateEnabled") || attributes.type === "radioStation") return;
|
||||||
this.updateNowPlayingTrack(attributes);
|
this.updateNowPlayingTrack(attributes);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._utils.getIPCMain().on("lastfm:scrobbleTrack", (event: any, attributes: any) => {
|
this._utils.getIPCMain().on("lastfm:scrobbleTrack", (event: any, attributes: any) => {
|
||||||
if (this._utils.getStoreValue("general.privateEnabled")) return;
|
if (this._utils.getStoreValue("general.privateEnabled") || attributes.type === "radioStation") return;
|
||||||
this.scrobbleTrack(attributes);
|
this.scrobbleTrack(attributes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on playback State Change
|
|
||||||
* @param attributes Music Attributes (attributes.status = current state)
|
|
||||||
*/
|
|
||||||
onPlaybackStateDidChange(attributes: object): void {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs on song change
|
|
||||||
* @param attributes Music Attributes
|
|
||||||
* @param scrobble
|
|
||||||
*/
|
|
||||||
onNowPlayingItemDidChange(attributes: any, scrobble = false): void {
|
|
||||||
if (this._utils.getStoreValue("general.privateEnabled")) return;
|
|
||||||
this.updateNowPlayingTrack(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize LastFM
|
* Initialize LastFM
|
||||||
* @param token
|
* @param token
|
||||||
|
@ -179,13 +170,7 @@ export default class lastfm {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.type] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._scrobbleCache.track === attributes.lfmTrack.name)) return;
|
||||||
!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
|
// Scrobble
|
||||||
const scrobble = {
|
const scrobble = {
|
||||||
|
@ -225,13 +210,9 @@ export default class lastfm {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!this._authenticated || !attributes || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.playParams.kind] || this._utils.getStoreValue("connectivity.lastfm.filter_types")[attributes.type] || (this._utils.getStoreValue("connectivity.lastfm.filter_loop") && this._nowPlayingCache.track === attributes.lfmTrack.name)) return;
|
||||||
!this._authenticated ||
|
|
||||||
!attributes ||
|
console.log(this._utils.getStoreValue("connectivity.lastfm.filter_types"));
|
||||||
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 = {
|
const nowPlaying = {
|
||||||
artist: attributes.lfmTrack.artist.name,
|
artist: attributes.lfmTrack.artist.name,
|
||||||
|
|
|
@ -53,20 +53,7 @@ export default class Thumbar {
|
||||||
{
|
{
|
||||||
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.view"),
|
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.view"),
|
||||||
submenu: [
|
submenu: [
|
||||||
...(this.isMac
|
...(this.isMac ? [{ role: "reload" }, { role: "forceReload" }, { role: "toggleDevTools" }, { type: "separator" }, { role: "resetZoom" }, { role: "zoomIn" }, { role: "zoomOut" }, { type: "separator" }, { role: "togglefullscreen" }, { type: "separator" }] : []),
|
||||||
? [
|
|
||||||
{ role: "reload" },
|
|
||||||
{ role: "forceReload" },
|
|
||||||
{ role: "toggleDevTools" },
|
|
||||||
{ type: "separator" },
|
|
||||||
{ role: "resetZoom" },
|
|
||||||
{ role: "zoomIn" },
|
|
||||||
{ role: "zoomOut" },
|
|
||||||
{ type: "separator" },
|
|
||||||
{ role: "togglefullscreen" },
|
|
||||||
{ type: "separator" },
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
{
|
{
|
||||||
label: utils.getLocale(utils.getStoreValue("general.language"), "term.search"),
|
label: utils.getLocale(utils.getStoreValue("general.language"), "term.search"),
|
||||||
accelerator: utils.getStoreValue("general.keybindings.search").join("+"),
|
accelerator: utils.getStoreValue("general.keybindings.search").join("+"),
|
||||||
|
|
|
@ -27,7 +27,6 @@ export default class mpris {
|
||||||
*/
|
*/
|
||||||
constructor(utils: any) {
|
constructor(utils: any) {
|
||||||
mpris.utils = utils;
|
mpris.utils = utils;
|
||||||
|
|
||||||
console.debug(`[Plugin][${mpris.name}] Loading Complete.`);
|
console.debug(`[Plugin][${mpris.name}] Loading Complete.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +102,7 @@ export default class mpris {
|
||||||
*/
|
*/
|
||||||
private static updateMetaData(attributes: any) {
|
private static updateMetaData(attributes: any) {
|
||||||
mpris.player.metadata = {
|
mpris.player.metadata = {
|
||||||
"mpris:trackid": mpris.player.objectPath(`track/${attributes.playParams.id.replace(/[.]+/g, "")}`),
|
"mpris:trackid": mpris.player.objectPath(`track/${attributes.playParams.id.replace(/[^a-zA-Z 0-9]+/g, "")}`),
|
||||||
"mpris:length": attributes.durationInMillis * 1000, // In microseconds
|
"mpris:length": attributes.durationInMillis * 1000, // In microseconds
|
||||||
"mpris:artUrl": attributes.artwork.url.replace("/{w}x{h}bb", "/512x512bb").replace("/2000x2000bb", "/35x35bb"),
|
"mpris:artUrl": attributes.artwork.url.replace("/{w}x{h}bb", "/512x512bb").replace("/2000x2000bb", "/35x35bb"),
|
||||||
"xesam:title": `${attributes.name}`,
|
"xesam:title": `${attributes.name}`,
|
||||||
|
@ -170,7 +169,7 @@ export default class mpris {
|
||||||
* @param attributes Music Attributes
|
* @param attributes Music Attributes
|
||||||
*/
|
*/
|
||||||
@mpris.linuxOnly
|
@mpris.linuxOnly
|
||||||
onNowPlayingItemDidChange(attributes: object): void {
|
playbackTimeDidChange(attributes: object): void {
|
||||||
mpris.updateMetaData(attributes);
|
mpris.updateMetaData(attributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default class RAOP {
|
||||||
private portairplay: any = "";
|
private portairplay: any = "";
|
||||||
|
|
||||||
private airtunes: any;
|
private airtunes: any;
|
||||||
private device: any;
|
// private device: any;
|
||||||
private mdns = require("mdns-js");
|
private mdns = require("mdns-js");
|
||||||
private ok: any = 1;
|
private ok: any = 1;
|
||||||
private devices: any = [];
|
private devices: any = [];
|
||||||
|
@ -38,7 +38,7 @@ export default class RAOP {
|
||||||
Worker, isMainThread, parentPort, workerData
|
Worker, isMainThread, parentPort, workerData
|
||||||
} = require('node:worker_threads');
|
} = require('node:worker_threads');
|
||||||
function getAudioConv (buffers) {
|
function getAudioConv (buffers) {
|
||||||
|
|
||||||
function interleave16(leftChannel, rightChannel) {
|
function interleave16(leftChannel, rightChannel) {
|
||||||
var length = leftChannel.length + rightChannel.length;
|
var length = leftChannel.length + rightChannel.length;
|
||||||
var result = new Int16Array(length);
|
var result = new Int16Array(length);
|
||||||
|
@ -89,7 +89,7 @@ export default class RAOP {
|
||||||
|
|
||||||
private ondeviceup(name: any, host: any, port: any, addresses: any, text: any, airplay2: any = null) {
|
private ondeviceup(name: any, host: any, port: any, addresses: any, text: any, airplay2: any = null) {
|
||||||
// console.log(this.castDevices.findIndex((item: any) => {return (item.name == host.replace(".local","") && item.port == port )}))
|
// console.log(this.castDevices.findIndex((item: any) => {return (item.name == host.replace(".local","") && item.port == port )}))
|
||||||
let shown_name = (host ?? "Unknown").replace(".local", "");
|
let shown_name = name;
|
||||||
try {
|
try {
|
||||||
let model = text.filter((u: any) => String(u).startsWith("model="));
|
let model = text.filter((u: any) => String(u).startsWith("model="));
|
||||||
let manufacturer = text.filter((u: any) => String(u).startsWith("manufacturer="));
|
let manufacturer = text.filter((u: any) => String(u).startsWith("manufacturer="));
|
||||||
|
@ -105,7 +105,7 @@ export default class RAOP {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.castDevices.findIndex((item: any) => {
|
this.castDevices.findIndex((item: any) => {
|
||||||
return item != null && item.name == shown_name && item.port == port && item.host == host_name && item.host != "Unknown";
|
return item != null && item.name == shown_name && item.host == host_name && item.host != "Unknown";
|
||||||
}) == -1
|
}) == -1
|
||||||
) {
|
) {
|
||||||
this.castDevices.push({
|
this.castDevices.push({
|
||||||
|
@ -158,8 +158,8 @@ export default class RAOP {
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("getAirplayDevice", (event, data) => {
|
electron.ipcMain.on("getAirplayDevice", (event, data) => {
|
||||||
// this.castDevices = [];
|
this.castDevices = [];
|
||||||
console.log("scan for airplay devices");
|
console.debug("scan for airplay devices");
|
||||||
|
|
||||||
const browser = this.mdns.createBrowser(this.mdns.tcp("raop"));
|
const browser = this.mdns.createBrowser(this.mdns.tcp("raop"));
|
||||||
browser.on("ready", browser.discover);
|
browser.on("ready", browser.discover);
|
||||||
|
@ -168,9 +168,10 @@ export default class RAOP {
|
||||||
if (service.addresses && service.fullname && service.fullname.includes("_raop._tcp")) {
|
if (service.addresses && service.fullname && service.fullname.includes("_raop._tcp")) {
|
||||||
// console.log(service.txt)
|
// console.log(service.txt)
|
||||||
this._win.webContents.executeJavaScript(`console.log(
|
this._win.webContents.executeJavaScript(`console.log(
|
||||||
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
"${service.name} ${service.host}:${service.port} ${service.addresses} ${service.fullname}"
|
||||||
)`);
|
)`);
|
||||||
this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt);
|
let itemname = service.fullname.substring(service.fullname.indexOf("@") + 1, service.fullname.indexOf("._raop._tcp"));
|
||||||
|
this.ondeviceup(itemname, service.host, service.port, service.addresses, service.txt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -183,7 +184,8 @@ export default class RAOP {
|
||||||
this._win.webContents.executeJavaScript(`console.log(
|
this._win.webContents.executeJavaScript(`console.log(
|
||||||
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
||||||
)`);
|
)`);
|
||||||
this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt, true);
|
let itemname = service.fullname.substring(service.fullname.indexOf("@") + 1, service.fullname.indexOf("._airplay._tcp"));
|
||||||
|
this.ondeviceup(itemname, service.host, service.port, service.addresses, service.txt, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -201,52 +203,73 @@ export default class RAOP {
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv) => {
|
electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv, silent) => {
|
||||||
if (ipv4 != this.ipairplay || ipport != this.portairplay) {
|
if (ipv4 != this.ipairplay || ipport != this.portairplay) {
|
||||||
if (this.airtunes == null) {
|
if (this.airtunes == null) {
|
||||||
this.airtunes = new this.u();
|
this.airtunes = new this.u();
|
||||||
}
|
}
|
||||||
this.ipairplay = ipv4;
|
this.ipairplay = ipv4;
|
||||||
this.portairplay = ipport;
|
this.portairplay = ipport;
|
||||||
this.device = this.airtunes.add(ipv4, {
|
let identifier = ipv4 + ":" + ipport + "ap";
|
||||||
port: ipport,
|
let idx = this.devices.findIndex((a: any) => {
|
||||||
volume: airplay2dv ? 30 : 50,
|
return a.id == identifier;
|
||||||
password: sepassword,
|
|
||||||
txt: txt,
|
|
||||||
airplay2: airplay2dv,
|
|
||||||
debug: true,
|
|
||||||
});
|
});
|
||||||
// console.log('lol',txt)
|
if (idx != -1) {
|
||||||
this.device.on("status", (status: any) => {
|
delete this.devices[idx];
|
||||||
|
this.devices = this.devices.filter((n: any) => n); // remove old controller
|
||||||
|
}
|
||||||
|
this.devices.push({
|
||||||
|
id: identifier,
|
||||||
|
ip: ipv4,
|
||||||
|
port: ipport,
|
||||||
|
state: 0,
|
||||||
|
controller: this.airtunes.add(ipv4, {
|
||||||
|
port: ipport,
|
||||||
|
volume: airplay2dv ? 30 : 50,
|
||||||
|
password: sepassword,
|
||||||
|
txt: txt,
|
||||||
|
airplay2: airplay2dv,
|
||||||
|
debug: null,
|
||||||
|
forceAlac: false,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
idx = this.devices.findIndex((a: any) => {
|
||||||
|
return a.id == identifier;
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log('lol', this.devices)
|
||||||
|
this.devices[idx].controller.on("status", (status: any) => {
|
||||||
console.log("device status", status);
|
console.log("device status", status);
|
||||||
if (status == "ready") {
|
if (status == "ready") {
|
||||||
this._win.webContents.setAudioMuted(true);
|
this._win.webContents.setAudioMuted(true);
|
||||||
this._win.webContents.executeJavaScript(`CiderAudio.sendAudio()`).catch((err: any) => console.error(err));
|
this._win.webContents.executeJavaScript(`CiderAudio.sendAudio()`).catch((err: any) => console.error(err));
|
||||||
}
|
}
|
||||||
if (status == "need_password") {
|
if (status == "need_password") {
|
||||||
this._win.webContents.executeJavaScript(`app.setAirPlayCodeUI()`);
|
this._win.webContents.executeJavaScript(`app.setAirPlayCodeUI('${this.devices[idx].id}')`);
|
||||||
}
|
}
|
||||||
if (status == "pair_success") {
|
if (status == "pair_success") {
|
||||||
this._win.webContents.executeJavaScript(`app.sendAirPlaySuccess()`);
|
this._win.webContents.executeJavaScript(`app.sendAirPlaySuccess(${silent},'${this.devices[idx].id}')`);
|
||||||
}
|
}
|
||||||
if (status == "pair_failed") {
|
if (status == "pair_failed") {
|
||||||
this._win.webContents.executeJavaScript(`app.sendAirPlayFailed()`);
|
this._win.webContents.executeJavaScript(`app.sendAirPlayFailed()`);
|
||||||
|
this.disconnectAirplay(this.devices[idx].id);
|
||||||
}
|
}
|
||||||
if (status == "stopped") {
|
if (status == "stopped") {
|
||||||
this.airtunes.stopAll(() => {
|
// this.airtunes.stopAll(() => {
|
||||||
console.log("end");
|
// console.log("end");
|
||||||
});
|
// });
|
||||||
this._win.webContents.executeJavaScript(`app.airplayDisconnect(true, ${[ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv]})`).catch((err: any) => console.error(err));
|
if (this.devices[idx]?.state != null && this.devices[idx].state != -1) this._win.webContents.executeJavaScript(`app.airplayDisconnect(true, ${JSON.stringify([ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv])})`).catch((err: any) => console.error(err));
|
||||||
this.airtunes = null;
|
// this.airtunes = null;
|
||||||
this.device = null;
|
// this.device = null;
|
||||||
this.ipairplay = "";
|
// this.ipairplay = "";
|
||||||
this.portairplay = "";
|
// this.portairplay = "";
|
||||||
this.ok = 1;
|
// this.ok = 1;
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.ok == 1) {
|
if (this.ok == 1) {
|
||||||
console.log(this.device.key, title ?? "", artist ?? "", album ?? "");
|
console.log(this.devices[idx].controller.key, title ?? "", artist ?? "", album ?? "");
|
||||||
this.airtunes.setTrackInfo(this.device.key, title ?? "", artist ?? "", album ?? "");
|
this.airtunes.setTrackInfo(this.devices[idx].controller.key, title ?? "", artist ?? "", album ?? "");
|
||||||
this.uploadImageAirplay(artworkURL);
|
this.uploadImageAirplay(artworkURL);
|
||||||
console.log("done");
|
console.log("done");
|
||||||
this.ok == 2;
|
this.ok == 2;
|
||||||
|
@ -257,15 +280,25 @@ export default class RAOP {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("setAirPlayPasscode", (event, passcode) => {
|
electron.ipcMain.on("setAirPlayPasscode", (event, passcode, identifier) => {
|
||||||
if (this.device) {
|
if (this.devices.length > 0) {
|
||||||
this.device.setPasscode(passcode);
|
let idx = this.devices.findIndex((a: any) => {
|
||||||
|
return a.id == identifier;
|
||||||
|
});
|
||||||
|
if (idx != -1) {
|
||||||
|
this.devices[idx].controller.setPasscode(passcode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("setAirPlayVolume", (event, volume) => {
|
electron.ipcMain.on("setAirPlayVolume", (event, volume, identifier) => {
|
||||||
if (this.device) {
|
if (this.devices.length > 0) {
|
||||||
this.device.setVolume(volume);
|
let idx = this.devices.findIndex((a: any) => {
|
||||||
|
return a.id == identifier;
|
||||||
|
});
|
||||||
|
if (idx != -1) {
|
||||||
|
this.devices[idx].controller.setVolume(volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -318,33 +351,70 @@ export default class RAOP {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("disconnectAirplay", (event) => {
|
electron.ipcMain.on("disconnectAirplay", (event, identifier = "") => {
|
||||||
this._win.webContents.setAudioMuted(false);
|
console.log("iden", identifier);
|
||||||
this.airtunes.stopAll(function () {
|
this.disconnectAirplay(identifier);
|
||||||
console.log("end");
|
|
||||||
});
|
|
||||||
this._win.webContents.executeJavaScript("app.airplayDisconnect(false)").catch((err: any) => console.error(err));
|
|
||||||
this.airtunes = null;
|
|
||||||
this.device = null;
|
|
||||||
this.ipairplay = "";
|
|
||||||
this.portairplay = "";
|
|
||||||
this.ok = 1;
|
|
||||||
this.i = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("updateAirplayInfo", (event, title, artist, album, artworkURL) => {
|
electron.ipcMain.on("updateAirplayInfo", (event, title, artist, album, artworkURL) => {
|
||||||
if (this.airtunes && this.device) {
|
if (this.airtunes && this.devices.length > 0) {
|
||||||
console.log(this.device.key, title, artist, album);
|
for (let i in this.devices) {
|
||||||
this.airtunes.setTrackInfo(this.device.key, title, artist, album);
|
console.log(this.devices[i].controller.key, title, artist, album);
|
||||||
|
this.airtunes.setTrackInfo(this.devices[i].controller.key, title, artist, album);
|
||||||
|
}
|
||||||
this.uploadImageAirplay(artworkURL);
|
this.uploadImageAirplay(artworkURL);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("updateRPCImage", (_event, imageurl) => {
|
electron.ipcMain.on("discordrpc:updateImage", (_event, imageurl) => {
|
||||||
this.uploadImageAirplay(imageurl);
|
this.uploadImageAirplay(imageurl);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
private disconnectAirplay(identifier: any = "") {
|
||||||
|
console.log("awdas");
|
||||||
|
this._win.webContents
|
||||||
|
.executeJavaScript(`app.airplayDisconnect(false, [], '${identifier}')`)
|
||||||
|
.then(() => {
|
||||||
|
if (identifier == "") {
|
||||||
|
if (this.airtunes) {
|
||||||
|
for (let i in this.devices) {
|
||||||
|
this.devices[i].state = -1;
|
||||||
|
}
|
||||||
|
this.airtunes.stopAll(() => {
|
||||||
|
console.log("endAll");
|
||||||
|
this.airtunes = null;
|
||||||
|
this.devices = [];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.devices = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let idx = this.devices.findIndex((a: any) => {
|
||||||
|
return a.id == identifier;
|
||||||
|
});
|
||||||
|
if (idx != -1) {
|
||||||
|
this.devices[idx].state = -1;
|
||||||
|
this.devices[idx].controller.stop(() => {
|
||||||
|
console.log(this.devices[idx].id, "stopped");
|
||||||
|
});
|
||||||
|
|
||||||
|
delete this.devices[idx];
|
||||||
|
this.devices = this.devices.filter((n: any) => n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.devices.length == 0) {
|
||||||
|
console.log("cleanup airtunes");
|
||||||
|
this._win.webContents.setAudioMuted(false);
|
||||||
|
this.airtunes = null;
|
||||||
|
|
||||||
|
this.ipairplay = "";
|
||||||
|
this.portairplay = "";
|
||||||
|
this.ok = 1;
|
||||||
|
this.i = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err: any) => console.error("lsdsd", err));
|
||||||
|
}
|
||||||
private uploadImageAirplay = (url: any) => {
|
private uploadImageAirplay = (url: any) => {
|
||||||
try {
|
try {
|
||||||
if (url != null && url != "") {
|
if (url != null && url != "") {
|
||||||
|
@ -352,7 +422,11 @@ export default class RAOP {
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then((res) => res.buffer())
|
.then((res) => res.buffer())
|
||||||
.then((buffer) => {
|
.then((buffer) => {
|
||||||
this.airtunes.setArtwork(this.device.key, buffer, "image/png");
|
if (this.airtunes && this.devices.length > 0) {
|
||||||
|
for (let i in this.devices) {
|
||||||
|
this.airtunes.setArtwork(this.devices[i].controller.key, buffer, "image/png");
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
@ -390,16 +464,19 @@ export default class RAOP {
|
||||||
* @param attributes Music Attributes (attributes.status = current state)
|
* @param attributes Music Attributes (attributes.status = current state)
|
||||||
*/
|
*/
|
||||||
onPlaybackStateDidChange(attributes: any): void {
|
onPlaybackStateDidChange(attributes: any): void {
|
||||||
if (this.airtunes && this.device) {
|
if (this.airtunes && this.devices.length > 0) {
|
||||||
let title = attributes?.name ?? "";
|
let title = attributes?.name ?? "";
|
||||||
let artist = attributes?.artistName ?? "";
|
let artist = attributes?.artistName ?? "";
|
||||||
let album = attributes?.albumName ?? "";
|
let album = attributes?.albumName ?? "";
|
||||||
let artworkURL = attributes?.artwork?.url ?? null;
|
for (let i in this.devices) {
|
||||||
console.log(this.device.key, title, artist, album);
|
console.log(this.devices[i].controller.key, title, artist, album);
|
||||||
this.airtunes.setTrackInfo(this.device.key, title, artist, album);
|
this.airtunes.setTrackInfo(this.devices[i].controller.key, title, artist, album);
|
||||||
if (artworkURL != null) {
|
}
|
||||||
|
let artworkURL = attributes?.artwork?.url ?? null;
|
||||||
|
|
||||||
|
if (artworkURL != null) {
|
||||||
|
this.uploadImageAirplay(artworkURL.replace("{w}", "1024").replace("{h}", "1024"));
|
||||||
}
|
}
|
||||||
this.uploadImageAirplay(artworkURL.replace("{w}", "1024").replace("{h}", "1024"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ const MusicKitInterop = {
|
||||||
/* MusicKit.Events.playbackStateDidChange */
|
/* MusicKit.Events.playbackStateDidChange */
|
||||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => {
|
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => {
|
||||||
const attributes = MusicKitInterop.getAttributes();
|
const attributes = MusicKitInterop.getAttributes();
|
||||||
|
if (!attributes) return;
|
||||||
if (MusicKitInterop.filterTrack(attributes, true, false)) {
|
if (MusicKitInterop.filterTrack(attributes, true, false)) {
|
||||||
global.ipcRenderer.send("playbackStateDidChange", attributes);
|
global.ipcRenderer.send("playbackStateDidChange", attributes);
|
||||||
global.ipcRenderer.send("wsapi-updatePlaybackState", attributes);
|
global.ipcRenderer.send("wsapi-updatePlaybackState", attributes);
|
||||||
|
@ -18,11 +19,12 @@ const MusicKitInterop = {
|
||||||
/* MusicKit.Events.playbackProgressDidChange */
|
/* MusicKit.Events.playbackProgressDidChange */
|
||||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, async () => {
|
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, async () => {
|
||||||
const attributes = MusicKitInterop.getAttributes();
|
const attributes = MusicKitInterop.getAttributes();
|
||||||
|
if (!attributes) return;
|
||||||
// wsapi call
|
// wsapi call
|
||||||
ipcRenderer.send("wsapi-updatePlaybackState", attributes);
|
ipcRenderer.send("wsapi-updatePlaybackState", attributes);
|
||||||
// lastfm call
|
// lastfm call
|
||||||
if (app.mk.currentPlaybackProgress === app.cfg.connectivity.lastfm.scrobble_after / 100) {
|
if (app.mk.currentPlaybackProgress === app.cfg.connectivity.lastfm.scrobble_after / 100) {
|
||||||
attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchPrimaryArtist() : attributes.artistName;
|
attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName;
|
||||||
ipcRenderer.send("lastfm:scrobbleTrack", attributes);
|
ipcRenderer.send("lastfm:scrobbleTrack", attributes);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -30,16 +32,21 @@ const MusicKitInterop = {
|
||||||
/* MusicKit.Events.playbackTimeDidChange */
|
/* MusicKit.Events.playbackTimeDidChange */
|
||||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackTimeDidChange, () => {
|
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackTimeDidChange, () => {
|
||||||
ipcRenderer.send("mpris:playbackTimeDidChange", MusicKit.getInstance()?.currentPlaybackTime * 1000 * 1000 ?? 0);
|
ipcRenderer.send("mpris:playbackTimeDidChange", MusicKit.getInstance()?.currentPlaybackTime * 1000 * 1000 ?? 0);
|
||||||
|
const attributes = MusicKitInterop.getAttributes();
|
||||||
|
if (!attributes) return;
|
||||||
|
ipcRenderer.send("playbackTimeDidChange", attributes);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* MusicKit.Events.nowPlayingItemDidChange */
|
/* MusicKit.Events.nowPlayingItemDidChange */
|
||||||
MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, async () => {
|
MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, async () => {
|
||||||
console.debug("[cider:preload] nowPlayingItemDidChange");
|
|
||||||
const attributes = MusicKitInterop.getAttributes();
|
const attributes = MusicKitInterop.getAttributes();
|
||||||
attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchPrimaryArtist() : attributes.artistName;
|
if (!attributes) return;
|
||||||
|
attributes.primaryArtist = app.cfg.connectivity.lastfm.remove_featured ? await this.fetchSongRelationships() : attributes.artistName;
|
||||||
|
|
||||||
|
global.ipcRenderer.send("nowPlayingItemDidChange", attributes);
|
||||||
|
|
||||||
if (MusicKitInterop.filterTrack(attributes, false, true)) {
|
if (MusicKitInterop.filterTrack(attributes, false, true)) {
|
||||||
global.ipcRenderer.send("nowPlayingItemDidChange", attributes);
|
global.ipcRenderer.send("lastfm:FilteredNowPlayingItemDidChange", attributes);
|
||||||
} else if (attributes.name !== "no-title-found" && attributes.playParams.id !== "no-id-found") {
|
} else if (attributes.name !== "no-title-found" && attributes.playParams.id !== "no-id-found") {
|
||||||
global.ipcRenderer.send("lastfm:nowPlayingChange", attributes);
|
global.ipcRenderer.send("lastfm:nowPlayingChange", attributes);
|
||||||
}
|
}
|
||||||
|
@ -52,6 +59,7 @@ const MusicKitInterop = {
|
||||||
await this.sleep(750);
|
await this.sleep(750);
|
||||||
MusicKit.getInstance().playbackRate = app.cfg.audio.playbackRate;
|
MusicKit.getInstance().playbackRate = app.cfg.audio.playbackRate;
|
||||||
}
|
}
|
||||||
|
console.debug("[cider:preload] nowPlayingItemDidChange");
|
||||||
});
|
});
|
||||||
|
|
||||||
/* MusicKit.Events.authorizationStatusDidChange */
|
/* MusicKit.Events.authorizationStatusDidChange */
|
||||||
|
@ -81,31 +89,47 @@ const MusicKitInterop = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchPrimaryArtist() {
|
async fetchSongRelationships({ id = this.getAttributes().songId, relationship = "primaryName" } = {}) {
|
||||||
const songID = app.mk.nowPlayingItem.attributes.playParams.catalogId || app.mk.nowPlayingItem.attributes.playParams.id;
|
if (!id) return null;
|
||||||
const res = await MusicKit.getInstance().api.v3.music("/v1/catalog/" + MusicKit.getInstance().storefrontId + `/songs/${songID}`, {
|
const res = await MusicKit.getInstance().api.v3.music("/v1/catalog/" + MusicKit.getInstance().storefrontId + `/songs/${id}`, {
|
||||||
include: {
|
include: {
|
||||||
songs: ["artists"],
|
songs: ["artists"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res || !res.data) {
|
if (!res || !res.data) {
|
||||||
console.warn("[cider:preload] fetchPrimaryArtist: no response");
|
console.warn("[cider:preload] fetchSongRelationships: no response");
|
||||||
return app.mk.nowPlayingItem.attributes.artistName;
|
if (id === this.getAttributes().songId) {
|
||||||
|
return this.getAttributes().artistName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!res.data.data.length) {
|
||||||
|
console.error(`[cider:preload] fetchSongRelationships: Unable to locate song with id of ${id}`);
|
||||||
|
if (id === this.getAttributes().songId) {
|
||||||
|
return this.getAttributes().artistName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res.data.data.length) {
|
|
||||||
console.error(`[cider:preload] fetchPrimaryArtist: Unable to locate song with id of ${songID}`);
|
|
||||||
return app.mk.nowPlayingItem.attributes.artistName;
|
|
||||||
}
|
|
||||||
const songData = res.data.data[0];
|
const songData = res.data.data[0];
|
||||||
const artistData = songData.relationships.artists.data;
|
const artistData = songData.relationships.artists.data;
|
||||||
if (artistData.length < 1) {
|
const albumData = songData.relationships.albums.data;
|
||||||
console.error(`[cider:preload] fetchPrimaryArtist: Unable to find artists related to the song with id of ${songID}`);
|
|
||||||
return app.mk.nowPlayingItem.attributes.artistName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const primaryArtist = artistData[0];
|
const primaryArtist = artistData[0];
|
||||||
return primaryArtist.attributes.name;
|
|
||||||
|
switch (relationship) {
|
||||||
|
default:
|
||||||
|
case "primaryName":
|
||||||
|
if (artistData.length < 1) {
|
||||||
|
console.error(`[cider:preload] fetchSongRelationships: Unable to find artists related to the song with id of ${id}`);
|
||||||
|
return app.mk.nowPlayingItem.attributes.artistName;
|
||||||
|
}
|
||||||
|
return primaryArtist.attributes.name;
|
||||||
|
|
||||||
|
case "primaryArtist":
|
||||||
|
return primaryArtist;
|
||||||
|
|
||||||
|
case "album":
|
||||||
|
return albumData[0];
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getAttributes: function () {
|
getAttributes: function () {
|
||||||
|
@ -117,6 +141,7 @@ const MusicKitInterop = {
|
||||||
const attributes = nowPlayingItem != null ? nowPlayingItem.attributes : {};
|
const attributes = nowPlayingItem != null ? nowPlayingItem.attributes : {};
|
||||||
|
|
||||||
attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id;
|
attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id;
|
||||||
|
attributes.type = nowPlayingItem?.type ?? "";
|
||||||
attributes.status = isPlayingExport ?? null;
|
attributes.status = isPlayingExport ?? null;
|
||||||
attributes.name = attributes?.name ?? "no-title-found";
|
attributes.name = attributes?.name ?? "no-title-found";
|
||||||
attributes.artwork = attributes?.artwork ?? { url: "" };
|
attributes.artwork = attributes?.artwork ?? { url: "" };
|
||||||
|
@ -126,6 +151,7 @@ const MusicKitInterop = {
|
||||||
attributes.url = {
|
attributes.url = {
|
||||||
cider: `https://cider.sh/link?play/s/${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"}`,
|
appleMusic: attributes.websiteUrl ? attributes.websiteUrl : `https://music.apple.com/${mk.storefrontId}/song/${nowPlayingItem?._songId ?? nowPlayingItem?.songId ?? "no-id-found"}`,
|
||||||
|
songLink: "https://song.link/i/" + attributes.songId,
|
||||||
};
|
};
|
||||||
if (attributes.playParams.id === "no-id-found") {
|
if (attributes.playParams.id === "no-id-found") {
|
||||||
attributes.playParams.id = nowPlayingItem?.id ?? "no-id-found";
|
attributes.playParams.id = nowPlayingItem?.id ?? "no-id-found";
|
||||||
|
@ -139,6 +165,10 @@ const MusicKitInterop = {
|
||||||
attributes.currentPlaybackProgress = currentPlaybackProgress ?? 0;
|
attributes.currentPlaybackProgress = currentPlaybackProgress ?? 0;
|
||||||
attributes.startTime = Date.now();
|
attributes.startTime = Date.now();
|
||||||
attributes.endTime = Math.round(attributes?.playParams?.id === cache.playParams.id ? Date.now() + attributes?.remainingTime : attributes?.startTime + attributes?.durationInMillis);
|
attributes.endTime = Math.round(attributes?.playParams?.id === cache.playParams.id ? Date.now() + attributes?.remainingTime : attributes?.startTime + attributes?.durationInMillis);
|
||||||
|
|
||||||
|
if (attributes.name === "no-title-found") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return attributes;
|
return attributes;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -301,9 +301,7 @@ const CiderAudio = {
|
||||||
filterlessGain = filterlessGain * spatialProfile.gainComp;
|
filterlessGain = filterlessGain * spatialProfile.gainComp;
|
||||||
}
|
}
|
||||||
filterlessGain = Math.pow(10, (-1 * (20 * Math.log10(filterlessGain))) / 20).toFixed(4);
|
filterlessGain = Math.pow(10, (-1 * (20 * Math.log10(filterlessGain))) / 20).toFixed(4);
|
||||||
filterlessGain > 1.0
|
filterlessGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(filterlessGain, CiderAudio.context.currentTime + 0.3);
|
||||||
? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3)
|
|
||||||
: CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(filterlessGain, CiderAudio.context.currentTime + 0.3);
|
|
||||||
console.debug(`[Cider][Audio] IntelliGainComp: ${filterlessGain > 1.0 ? 0 : (20 * Math.log10(filterlessGain)).toFixed(2)} dB (${filterlessGain > 1.0 ? 1 : filterlessGain})`);
|
console.debug(`[Cider][Audio] IntelliGainComp: ${filterlessGain > 1.0 ? 0 : (20 * Math.log10(filterlessGain)).toFixed(2)} dB (${filterlessGain > 1.0 ? 1 : filterlessGain})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -358,9 +356,7 @@ const CiderAudio = {
|
||||||
maxGain = maxGain * spatialProfile.gainComp;
|
maxGain = maxGain * spatialProfile.gainComp;
|
||||||
}
|
}
|
||||||
maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4);
|
maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4);
|
||||||
maxGain > 1.0
|
maxGain > 1.0 ? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3) : CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudio.context.currentTime + 0.3);
|
||||||
? CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudio.context.currentTime + 0.3)
|
|
||||||
: CiderAudio.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudio.context.currentTime + 0.3);
|
|
||||||
console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`);
|
console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`);
|
||||||
},
|
},
|
||||||
sendAudio: function () {
|
sendAudio: function () {
|
||||||
|
@ -397,7 +393,7 @@ const CiderAudio = {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._bufferSize = 1024;
|
this._bufferSize = 2048;
|
||||||
this._buffers = null;
|
this._buffers = null;
|
||||||
this._initBuffer();
|
this._initBuffer();
|
||||||
}
|
}
|
||||||
|
@ -839,49 +835,49 @@ const CiderAudio = {
|
||||||
switch (destination) {
|
switch (destination) {
|
||||||
case "spatial":
|
case "spatial":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.spatialNode);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.spatialNode);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> Spatial");
|
console.debug("[Cider][Audio] llpw_n1 -> Spatial");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n6":
|
case "n6":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
|
console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer2");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n5":
|
case "n5":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
|
console.debug("[Cider][Audio] llpw_n1 -> atmosphereRealizer1");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n4":
|
case "n4":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");
|
console.debug("[Cider][Audio] llpw_n1 -> vibrantbassNode");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n3":
|
case "n3":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.audioBands[0]);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.audioBands[0]);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> audioBands");
|
console.debug("[Cider][Audio] llpw_n1 -> audioBands");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n2":
|
case "n2":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.opportunisticCorrection);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> opportunisticCorrection");
|
console.debug("[Cider][Audio] llpw_n1 -> opportunisticCorrection");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n1":
|
case "n1":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.audioNodes.llpw[0]);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> llpw");
|
console.debug("[Cider][Audio] llpw_n1 -> llpw");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n0":
|
case "n0":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.llpw.at(-1).connect(CiderAudio.context.destination);
|
CiderAudio.audioNodes.llpw[CiderAudio.audioNodes.llpw.length - 1].connect(CiderAudio.context.destination);
|
||||||
console.debug("[Cider][Audio] llpw_n1 -> destination");
|
console.debug("[Cider][Audio] llpw_n1 -> destination");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
|
@ -910,50 +906,50 @@ const CiderAudio = {
|
||||||
switch (destination) {
|
switch (destination) {
|
||||||
case "spatial":
|
case "spatial":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.spatialNode);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.spatialNode);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> Spatial");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> Spatial");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "n6":
|
case "n6":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer2");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer2");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n5":
|
case "n5":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer1");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> atmosphereRealizer1");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n4":
|
case "n4":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> vibrantbassNode");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> vibrantbassNode");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n3":
|
case "n3":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.audioBands[0]);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.audioBands[0]);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> audioBands");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> audioBands");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n2":
|
case "n2":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.opportunisticCorrection);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> opportunisticCorrection");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> opportunisticCorrection");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n1":
|
case "n1":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.audioNodes.llpw[0]);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> llpw");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> llpw");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n0":
|
case "n0":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.vibrantbassNode.at(-1).connect(CiderAudio.context.destination);
|
CiderAudio.audioNodes.vibrantbassNode[CiderAudio.audioNodes.vibrantbassNode.length - 1].connect(CiderAudio.context.destination);
|
||||||
console.debug("[Cider][Audio] vibrantbass_n4 -> destination");
|
console.debug("[Cider][Audio] vibrantbass_n4 -> destination");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
|
@ -1168,48 +1164,48 @@ const CiderAudio = {
|
||||||
|
|
||||||
switch (destination) {
|
switch (destination) {
|
||||||
case "spatial":
|
case "spatial":
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.spatialNode);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.spatialNode);
|
||||||
console.debug("[Cider][Audio] Equalizer -> Spatial");
|
console.debug("[Cider][Audio] Equalizer -> Spatial");
|
||||||
break;
|
break;
|
||||||
case "n6":
|
case "n6":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer2);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer2);
|
||||||
console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer2");
|
console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer2");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n5":
|
case "n5":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.atmosphereRealizer1);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.atmosphereRealizer1);
|
||||||
console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1");
|
console.debug("[Cider][Audio] Equalizer -> atmosphereRealizer1");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n4":
|
case "n4":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.vibrantbassNode[0]);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.vibrantbassNode[0]);
|
||||||
console.debug("[Cider][Audio] Equalizer -> vibrantbassNode");
|
console.debug("[Cider][Audio] Equalizer -> vibrantbassNode");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n3":
|
case "n3":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.audioBands[0]);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.audioBands[0]);
|
||||||
console.debug("[Cider][Audio] Equalizer -> audioBands");
|
console.debug("[Cider][Audio] Equalizer -> audioBands");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n2":
|
case "n2":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.opportunisticCorrection);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.opportunisticCorrection);
|
||||||
console.debug("[Cider][Audio] Equalizer -> opportunisticCorrection");
|
console.debug("[Cider][Audio] Equalizer -> opportunisticCorrection");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n1":
|
case "n1":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.audioNodes.llpw[0]);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.audioNodes.llpw[0]);
|
||||||
console.debug("[Cider][Audio] Equalizer -> llpw");
|
console.debug("[Cider][Audio] Equalizer -> llpw");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case "n0":
|
case "n0":
|
||||||
try {
|
try {
|
||||||
CiderAudio.audioNodes.audioBands.at(-1).connect(CiderAudio.context.destination);
|
CiderAudio.audioNodes.audioBands[CiderAudio.audioNodes.audioBands.length - 1].connect(CiderAudio.context.destination);
|
||||||
console.debug("[Cider][Audio] Equalizer -> destination");
|
console.debug("[Cider][Audio] Equalizer -> destination");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -171,9 +171,7 @@ const CiderAudioRenderer = {
|
||||||
maxGain = maxGain * spatialProfile.gainComp;
|
maxGain = maxGain * spatialProfile.gainComp;
|
||||||
}
|
}
|
||||||
maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4);
|
maxGain = Math.pow(10, (-1 * (20 * Math.log10(maxGain))) / 20).toFixed(4);
|
||||||
maxGain > 1.0
|
maxGain > 1.0 ? CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudioRenderer.context.currentTime + 0.3) : CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudioRenderer.context.currentTime + 0.3);
|
||||||
? CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(1.0, CiderAudioRenderer.context.currentTime + 0.3)
|
|
||||||
: CiderAudioRenderer.audioNodes.intelliGainComp.gain.exponentialRampToValueAtTime(maxGain, CiderAudioRenderer.context.currentTime + 0.3);
|
|
||||||
console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`);
|
console.debug(`[Cider][Audio] IntelliGainComp: ${maxGain > 1.0 ? 0 : (20 * Math.log10(maxGain)).toFixed(2)} dB (${maxGain > 1.0 ? 1 : maxGain})`);
|
||||||
},
|
},
|
||||||
atmosphereRealizer2_n6: function (status, destination) {
|
atmosphereRealizer2_n6: function (status, destination) {
|
||||||
|
|
|
@ -1589,9 +1589,7 @@ typeof window !== "undefined" &&
|
||||||
}
|
}
|
||||||
|
|
||||||
var levelDetails = levelInfo.details;
|
var levelDetails = levelInfo.details;
|
||||||
var avgDuration =
|
var avgDuration = (partCurrent ? (levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.partTarget) : levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.averagetargetduration) || currentFragDuration;
|
||||||
(partCurrent ? (levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.partTarget) : levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.averagetargetduration) ||
|
|
||||||
currentFragDuration;
|
|
||||||
var adjustedbw = void 0; // follow algorithm captured from stagefright :
|
var adjustedbw = void 0; // follow algorithm captured from stagefright :
|
||||||
// https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
|
// https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
|
||||||
// Pick the highest bandwidth stream below or equal to estimated bandwidth.
|
// Pick the highest bandwidth stream below or equal to estimated bandwidth.
|
||||||
|
@ -1607,9 +1605,7 @@ typeof window !== "undefined" &&
|
||||||
|
|
||||||
var bitrate = levels[i].maxBitrate;
|
var bitrate = levels[i].maxBitrate;
|
||||||
var fetchDuration = (bitrate * avgDuration) / adjustedbw;
|
var fetchDuration = (bitrate * avgDuration) / adjustedbw;
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_6__["logger"].trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: " + i + "/" + Math.round(adjustedbw) + "/" + bitrate + "/" + avgDuration + "/" + maxFetchDuration + "/" + fetchDuration); // if adjusted bw is greater than level bitrate AND
|
||||||
"level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: " + i + "/" + Math.round(adjustedbw) + "/" + bitrate + "/" + avgDuration + "/" + maxFetchDuration + "/" + fetchDuration
|
|
||||||
); // if adjusted bw is greater than level bitrate AND
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
adjustedbw > bitrate && // fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches
|
adjustedbw > bitrate && // fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches
|
||||||
|
@ -1971,11 +1967,7 @@ typeof window !== "undefined" &&
|
||||||
|
|
||||||
if (this.bufferFlushed) {
|
if (this.bufferFlushed) {
|
||||||
this.bufferFlushed = false;
|
this.bufferFlushed = false;
|
||||||
this.afterBufferFlushed(
|
this.afterBufferFlushed(this.mediaBuffer ? this.mediaBuffer : this.media, _loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO);
|
||||||
this.mediaBuffer ? this.mediaBuffer : this.media,
|
|
||||||
_loader_fragment__WEBPACK_IMPORTED_MODULE_7__["ElementaryStreamTypes"].AUDIO,
|
|
||||||
_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferInfo = this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO);
|
var bufferInfo = this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO);
|
||||||
|
@ -2024,10 +2016,7 @@ typeof window !== "undefined" &&
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === "identity" && !((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)) {
|
||||||
((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === "identity" &&
|
|
||||||
!((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)
|
|
||||||
) {
|
|
||||||
this.loadKey(frag, trackDetails);
|
this.loadKey(frag, trackDetails);
|
||||||
} else {
|
} else {
|
||||||
this.loadFragment(frag, trackDetails, targetBufferTime);
|
this.loadFragment(frag, trackDetails, targetBufferTime);
|
||||||
|
@ -2176,12 +2165,7 @@ typeof window !== "undefined" &&
|
||||||
var transmuxer = this.transmuxer;
|
var transmuxer = this.transmuxer;
|
||||||
|
|
||||||
if (!transmuxer) {
|
if (!transmuxer) {
|
||||||
transmuxer = this.transmuxer = new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__["default"](
|
transmuxer = this.transmuxer = new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__["default"](this.CiderHls, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this));
|
||||||
this.CiderHls,
|
|
||||||
_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO,
|
|
||||||
this._handleTransmuxComplete.bind(this),
|
|
||||||
this._handleTransmuxerFlush.bind(this)
|
|
||||||
);
|
|
||||||
} // Check if we have video initPTS
|
} // Check if we have video initPTS
|
||||||
// If not we need to wait for it
|
// If not we need to wait for it
|
||||||
|
|
||||||
|
@ -2198,9 +2182,7 @@ typeof window !== "undefined" &&
|
||||||
var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial);
|
var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial);
|
||||||
transmuxer.push(payload, initSegmentData, audioCodec, "", frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS);
|
transmuxer.push(payload, initSegmentData, audioCodec, "", frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS);
|
||||||
} else {
|
} else {
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_14__["logger"].log("Unknown video PTS for cc " + frag.cc + ", waiting for video PTS before demuxing audio frag " + frag.sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId);
|
||||||
"Unknown video PTS for cc " + frag.cc + ", waiting for video PTS before demuxing audio frag " + frag.sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId
|
|
||||||
);
|
|
||||||
|
|
||||||
var _this$waitingData = (this.waitingData = this.waitingData || {
|
var _this$waitingData = (this.waitingData = this.waitingData || {
|
||||||
frag: frag,
|
frag: frag,
|
||||||
|
@ -3267,9 +3249,7 @@ typeof window !== "undefined" &&
|
||||||
state = this.state;
|
state = this.state;
|
||||||
var currentTime = media ? media.currentTime : 0;
|
var currentTime = media ? media.currentTime : 0;
|
||||||
var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(mediaBuffer || media, currentTime, config.maxBufferHole);
|
var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__["BufferHelper"].bufferInfo(mediaBuffer || media, currentTime, config.maxBufferHole);
|
||||||
this.log(
|
this.log("media seeking to " + (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
|
||||||
"media seeking to " + (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state
|
|
||||||
);
|
|
||||||
|
|
||||||
if (state === State.ENDED) {
|
if (state === State.ENDED) {
|
||||||
this.resetLoadingState();
|
this.resetLoadingState();
|
||||||
|
@ -3619,19 +3599,7 @@ typeof window !== "undefined" &&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log(
|
this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? "of [" + details.startSN + "-" + details.endSN + "] " : "") + (this.logPrefix === "[stream-controller]" ? "level" : "track") + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3))); // Don't update nextLoadPosition for fragments which are not buffered
|
||||||
"Loading fragment " +
|
|
||||||
frag.sn +
|
|
||||||
" cc: " +
|
|
||||||
frag.cc +
|
|
||||||
" " +
|
|
||||||
(details ? "of [" + details.startSN + "-" + details.endSN + "] " : "") +
|
|
||||||
(this.logPrefix === "[stream-controller]" ? "level" : "track") +
|
|
||||||
": " +
|
|
||||||
frag.level +
|
|
||||||
", target: " +
|
|
||||||
parseFloat(targetBufferTime.toFixed(3))
|
|
||||||
); // Don't update nextLoadPosition for fragments which are not buffered
|
|
||||||
|
|
||||||
if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.sn) && !this.bitrateTest) {
|
if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(frag.sn) && !this.bitrateTest) {
|
||||||
this.nextLoadPosition = frag.start + frag.duration;
|
this.nextLoadPosition = frag.start + frag.duration;
|
||||||
|
@ -4099,18 +4067,7 @@ typeof window !== "undefined" &&
|
||||||
if (firstLevelLoad || (!aligned && !slidingStart)) {
|
if (firstLevelLoad || (!aligned && !slidingStart)) {
|
||||||
Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__["alignStream"])(fragPrevious, lastLevel, details);
|
Object(_utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__["alignStream"])(fragPrevious, lastLevel, details);
|
||||||
var alignedSlidingStart = details.fragments[0].start;
|
var alignedSlidingStart = details.fragments[0].start;
|
||||||
this.log(
|
this.log("Live playlist sliding: " + alignedSlidingStart.toFixed(2) + " start-sn: " + (previousDetails ? previousDetails.startSN : "na") + "->" + details.startSN + " prev-sn: " + (fragPrevious ? fragPrevious.sn : "na") + " fragments: " + length);
|
||||||
"Live playlist sliding: " +
|
|
||||||
alignedSlidingStart.toFixed(2) +
|
|
||||||
" start-sn: " +
|
|
||||||
(previousDetails ? previousDetails.startSN : "na") +
|
|
||||||
"->" +
|
|
||||||
details.startSN +
|
|
||||||
" prev-sn: " +
|
|
||||||
(fragPrevious ? fragPrevious.sn : "na") +
|
|
||||||
" fragments: " +
|
|
||||||
length
|
|
||||||
);
|
|
||||||
return alignedSlidingStart;
|
return alignedSlidingStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5767,11 +5724,7 @@ typeof window !== "undefined" &&
|
||||||
ot: ot,
|
ot: ot,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO || ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO || ot == _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED) {
|
||||||
ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO ||
|
|
||||||
ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].AUDIO ||
|
|
||||||
ot == _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED
|
|
||||||
) {
|
|
||||||
data.br = level.bitrate / 1000;
|
data.br = level.bitrate / 1000;
|
||||||
data.tb = _this.getTopBandwidth(ot);
|
data.tb = _this.getTopBandwidth(ot);
|
||||||
data.bl = _this.getBufferLength(ot);
|
data.bl = _this.getBufferLength(ot);
|
||||||
|
@ -5871,10 +5824,7 @@ typeof window !== "undefined" &&
|
||||||
// apply baseline data
|
// apply baseline data
|
||||||
_extends(data, this.createData());
|
_extends(data, this.createData());
|
||||||
|
|
||||||
var isVideo =
|
var isVideo = data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].INIT || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED;
|
||||||
data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].INIT ||
|
|
||||||
data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].VIDEO ||
|
|
||||||
data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__["CMCDObjectType"].MUXED;
|
|
||||||
|
|
||||||
if (this.starved && isVideo) {
|
if (this.starved && isVideo) {
|
||||||
data.bs = true;
|
data.bs = true;
|
||||||
|
@ -8610,10 +8560,7 @@ typeof window !== "undefined" &&
|
||||||
levels = levels.filter(function (_ref2) {
|
levels = levels.filter(function (_ref2) {
|
||||||
var audioCodec = _ref2.audioCodec,
|
var audioCodec = _ref2.audioCodec,
|
||||||
videoCodec = _ref2.videoCodec;
|
videoCodec = _ref2.videoCodec;
|
||||||
return (
|
return (!audioCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(audioCodec, "audio")) && (!videoCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(videoCodec, "video"));
|
||||||
(!audioCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(audioCodec, "audio")) &&
|
|
||||||
(!videoCodec || Object(_utils_codecs__WEBPACK_IMPORTED_MODULE_3__["isCodecSupportedInMp4"])(videoCodec, "video"))
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.audioTracks) {
|
if (data.audioTracks) {
|
||||||
|
@ -9319,10 +9266,7 @@ typeof window !== "undefined" &&
|
||||||
ccOffset = oldFrag.cc - newFrag.cc;
|
ccOffset = oldFrag.cc - newFrag.cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.startPTS) && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.endPTS)) {
|
||||||
Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.startPTS) &&
|
|
||||||
Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(oldFrag.endPTS)
|
|
||||||
) {
|
|
||||||
newFrag.start = newFrag.startPTS = oldFrag.startPTS;
|
newFrag.start = newFrag.startPTS = oldFrag.startPTS;
|
||||||
newFrag.startDTS = oldFrag.startDTS;
|
newFrag.startDTS = oldFrag.startDTS;
|
||||||
newFrag.appendedPTS = oldFrag.appendedPTS;
|
newFrag.appendedPTS = oldFrag.appendedPTS;
|
||||||
|
@ -9902,10 +9846,7 @@ typeof window !== "undefined" &&
|
||||||
} // We want to load the key if we're dealing with an identity key, because we will decrypt
|
} // We want to load the key if we're dealing with an identity key, because we will decrypt
|
||||||
// this content using the key we fetch. Other keys will be handled by the DRM CDM via EME.
|
// this content using the key we fetch. Other keys will be handled by the DRM CDM via EME.
|
||||||
|
|
||||||
if (
|
if (((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === "identity" && !((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)) {
|
||||||
((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.keyFormat) === "identity" &&
|
|
||||||
!((_frag$decryptdata2 = frag.decryptdata) !== null && _frag$decryptdata2 !== void 0 && _frag$decryptdata2.key)
|
|
||||||
) {
|
|
||||||
this.loadKey(frag, levelDetails);
|
this.loadKey(frag, levelDetails);
|
||||||
} else {
|
} else {
|
||||||
this.loadFragment(frag, levelDetails, targetBufferTime);
|
this.loadFragment(frag, levelDetails, targetBufferTime);
|
||||||
|
@ -10257,13 +10198,7 @@ typeof window !== "undefined" &&
|
||||||
// this.log(`Transmuxing ${frag.sn} of [${details.startSN} ,${details.endSN}],level ${frag.level}, cc ${frag.cc}`);
|
// this.log(`Transmuxing ${frag.sn} of [${details.startSN} ,${details.endSN}],level ${frag.level}, cc ${frag.cc}`);
|
||||||
|
|
||||||
var transmuxer = (this.transmuxer =
|
var transmuxer = (this.transmuxer =
|
||||||
this.transmuxer ||
|
this.transmuxer || new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__["default"](this.CiderHls, _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this)));
|
||||||
new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__["default"](
|
|
||||||
this.CiderHls,
|
|
||||||
_types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].MAIN,
|
|
||||||
this._handleTransmuxComplete.bind(this),
|
|
||||||
this._handleTransmuxerFlush.bind(this)
|
|
||||||
));
|
|
||||||
var partIndex = part ? part.index : -1;
|
var partIndex = part ? part.index : -1;
|
||||||
var partial = partIndex !== -1;
|
var partial = partIndex !== -1;
|
||||||
var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial);
|
var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__["ChunkMetadata"](frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial);
|
||||||
|
@ -14779,8 +14714,8 @@ typeof window !== "undefined" &&
|
||||||
*/
|
*/
|
||||||
var chromeVersion = null;
|
var chromeVersion = null;
|
||||||
var BitratesMap = [
|
var BitratesMap = [
|
||||||
32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112,
|
32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56,
|
||||||
128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,
|
64, 80, 96, 112, 128, 144, 160,
|
||||||
];
|
];
|
||||||
var SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000];
|
var SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000];
|
||||||
var SamplesCoefficients = [
|
var SamplesCoefficients = [
|
||||||
|
@ -18354,9 +18289,7 @@ typeof window !== "undefined" &&
|
||||||
var _sourceBuffer$prototy;
|
var _sourceBuffer$prototy;
|
||||||
|
|
||||||
var sourceBuffer = getSourceBuffer();
|
var sourceBuffer = getSourceBuffer();
|
||||||
return (
|
return typeof (sourceBuffer === null || sourceBuffer === void 0 ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) === null || _sourceBuffer$prototy === void 0 ? void 0 : _sourceBuffer$prototy.changeType) === "function";
|
||||||
typeof (sourceBuffer === null || sourceBuffer === void 0 ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) === null || _sourceBuffer$prototy === void 0 ? void 0 : _sourceBuffer$prototy.changeType) === "function"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
@ -18743,10 +18676,7 @@ typeof window !== "undefined" &&
|
||||||
var start = segment.byteRangeStartOffset;
|
var start = segment.byteRangeStartOffset;
|
||||||
var end = segment.byteRangeEndOffset;
|
var end = segment.byteRangeEndOffset;
|
||||||
|
|
||||||
if (
|
if (Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(start) && Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(end)) {
|
||||||
Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(start) &&
|
|
||||||
Object(_home_runner_work_CiderHls_js_CiderHls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__["isFiniteNumber"])(end)
|
|
||||||
) {
|
|
||||||
loaderContext.rangeStart = start;
|
loaderContext.rangeStart = start;
|
||||||
loaderContext.rangeEnd = end;
|
loaderContext.rangeEnd = end;
|
||||||
}
|
}
|
||||||
|
@ -18854,12 +18784,7 @@ typeof window !== "undefined" &&
|
||||||
this._url = null;
|
this._url = null;
|
||||||
this.baseurl = void 0;
|
this.baseurl = void 0;
|
||||||
this.relurl = void 0;
|
this.relurl = void 0;
|
||||||
this.elementaryStreams =
|
this.elementaryStreams = ((_this$elementaryStrea = {}), (_this$elementaryStrea[ElementaryStreamTypes.AUDIO] = null), (_this$elementaryStrea[ElementaryStreamTypes.VIDEO] = null), (_this$elementaryStrea[ElementaryStreamTypes.AUDIOVIDEO] = null), _this$elementaryStrea);
|
||||||
((_this$elementaryStrea = {}),
|
|
||||||
(_this$elementaryStrea[ElementaryStreamTypes.AUDIO] = null),
|
|
||||||
(_this$elementaryStrea[ElementaryStreamTypes.VIDEO] = null),
|
|
||||||
(_this$elementaryStrea[ElementaryStreamTypes.AUDIOVIDEO] = null),
|
|
||||||
_this$elementaryStrea);
|
|
||||||
this.baseurl = baseurl;
|
this.baseurl = baseurl;
|
||||||
} // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array
|
} // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array
|
||||||
|
|
||||||
|
@ -19730,11 +19655,7 @@ typeof window !== "undefined" &&
|
||||||
function isMP4Url(url) {
|
function isMP4Url(url) {
|
||||||
var _URLToolkit$parseURL$, _URLToolkit$parseURL;
|
var _URLToolkit$parseURL$, _URLToolkit$parseURL;
|
||||||
|
|
||||||
return MP4_REGEX_SUFFIX.test(
|
return MP4_REGEX_SUFFIX.test((_URLToolkit$parseURL$ = (_URLToolkit$parseURL = url_toolkit__WEBPACK_IMPORTED_MODULE_1__["parseURL"](url)) === null || _URLToolkit$parseURL === void 0 ? void 0 : _URLToolkit$parseURL.path) != null ? _URLToolkit$parseURL$ : "");
|
||||||
(_URLToolkit$parseURL$ = (_URLToolkit$parseURL = url_toolkit__WEBPACK_IMPORTED_MODULE_1__["parseURL"](url)) === null || _URLToolkit$parseURL === void 0 ? void 0 : _URLToolkit$parseURL.path) != null
|
|
||||||
? _URLToolkit$parseURL$
|
|
||||||
: ""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var M3U8Parser = /*#__PURE__*/ (function () {
|
var M3U8Parser = /*#__PURE__*/ (function () {
|
||||||
|
@ -20819,9 +20740,7 @@ typeof window !== "undefined" &&
|
||||||
timeout = false;
|
timeout = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_3__["logger"].warn("[playlist-loader]: A network " + (timeout ? "timeout" : "error") + " occurred while loading " + context.type + " level: " + context.level + " id: " + context.id + ' group-id: "' + context.groupId + '"');
|
||||||
"[playlist-loader]: A network " + (timeout ? "timeout" : "error") + " occurred while loading " + context.type + " level: " + context.level + " id: " + context.id + ' group-id: "' + context.groupId + '"'
|
|
||||||
);
|
|
||||||
var details = _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].UNKNOWN;
|
var details = _errors__WEBPACK_IMPORTED_MODULE_2__["ErrorDetails"].UNKNOWN;
|
||||||
var fatal = false;
|
var fatal = false;
|
||||||
var loader = this.getInternalLoader(context);
|
var loader = this.getInternalLoader(context);
|
||||||
|
@ -21004,20 +20923,20 @@ typeof window !== "undefined" &&
|
||||||
if (channelCount === 1) {
|
if (channelCount === 1) {
|
||||||
// ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
|
// ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
|
||||||
return new Uint8Array([
|
return new Uint8Array([
|
||||||
0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
||||||
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
|
||||||
]);
|
]);
|
||||||
} else if (channelCount === 2) {
|
} else if (channelCount === 2) {
|
||||||
// ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
|
// ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
|
||||||
return new Uint8Array([
|
return new Uint8Array([
|
||||||
0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
||||||
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
|
||||||
]);
|
]);
|
||||||
} else if (channelCount === 3) {
|
} else if (channelCount === 3) {
|
||||||
// ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
|
// ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
|
||||||
return new Uint8Array([
|
return new Uint8Array([
|
||||||
0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
||||||
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22334,13 +22253,7 @@ typeof window !== "undefined" &&
|
||||||
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset);
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
audio = this.remuxAudio(
|
audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO ? videoTimeOffset : undefined);
|
||||||
audioTrack,
|
|
||||||
audioTimeOffset,
|
|
||||||
this.isAudioContiguous,
|
|
||||||
accurateTimeOffset,
|
|
||||||
hasVideo || enoughVideoSamples || playlistType === _types_loader__WEBPACK_IMPORTED_MODULE_6__["PlaylistLevelType"].AUDIO ? videoTimeOffset : undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
if (enoughVideoSamples) {
|
if (enoughVideoSamples) {
|
||||||
var audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0; // if initSegment was generated without video samples, regenerate it again
|
var audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0; // if initSegment was generated without video samples, regenerate it again
|
||||||
|
@ -22531,9 +22444,7 @@ typeof window !== "undefined" &&
|
||||||
if (ptsDtsShift < averageSampleDuration * -2) {
|
if (ptsDtsShift < averageSampleDuration * -2) {
|
||||||
// Fix for "CNN special report, with CC" in test-streams (including Safari browser)
|
// Fix for "CNN special report, with CC" in test-streams (including Safari browser)
|
||||||
// With large PTS < DTS errors such as this, we want to correct CTS while maintaining increasing DTS values
|
// With large PTS < DTS errors such as this, we want to correct CTS while maintaining increasing DTS values
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("PTS < DTS detected in video samples, offsetting DTS from PTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-averageSampleDuration, true) + " ms");
|
||||||
"PTS < DTS detected in video samples, offsetting DTS from PTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-averageSampleDuration, true) + " ms"
|
|
||||||
);
|
|
||||||
var lastDts = ptsDtsShift;
|
var lastDts = ptsDtsShift;
|
||||||
|
|
||||||
for (var _i = 0; _i < nbSamples; _i++) {
|
for (var _i = 0; _i < nbSamples; _i++) {
|
||||||
|
@ -22543,9 +22454,7 @@ typeof window !== "undefined" &&
|
||||||
} else {
|
} else {
|
||||||
// Fix for "Custom IV with bad PTS DTS" in test-streams
|
// Fix for "Custom IV with bad PTS DTS" in test-streams
|
||||||
// With smaller PTS < DTS errors we can simply move all DTS back. This increases CTS without causing buffer gaps or decode errors in Safari
|
// With smaller PTS < DTS errors we can simply move all DTS back. This increases CTS without causing buffer gaps or decode errors in Safari
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("PTS < DTS detected in video samples, shifting DTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(ptsDtsShift, true) + " ms to overcome this issue");
|
||||||
"PTS < DTS detected in video samples, shifting DTS by " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(ptsDtsShift, true) + " ms to overcome this issue"
|
|
||||||
);
|
|
||||||
|
|
||||||
for (var _i2 = 0; _i2 < nbSamples; _i2++) {
|
for (var _i2 = 0; _i2 < nbSamples; _i2++) {
|
||||||
inputSamples[_i2].dts = inputSamples[_i2].dts + ptsDtsShift;
|
inputSamples[_i2].dts = inputSamples[_i2].dts + ptsDtsShift;
|
||||||
|
@ -22563,13 +22472,9 @@ typeof window !== "undefined" &&
|
||||||
|
|
||||||
if (foundHole || foundOverlap) {
|
if (foundHole || foundOverlap) {
|
||||||
if (foundHole) {
|
if (foundHole) {
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(delta, true) + " ms (" + delta + "dts) hole between fragments detected, filling it");
|
||||||
"AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(delta, true) + " ms (" + delta + "dts) hole between fragments detected, filling it"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected");
|
||||||
"AVC: " + Object(_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__["toMsFromMpegTsClock"])(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firstDTS = nextAvcDts;
|
firstDTS = nextAvcDts;
|
||||||
|
@ -22682,9 +22587,7 @@ typeof window !== "undefined" &&
|
||||||
mp4SampleDuration = lastFrameDuration;
|
mp4SampleDuration = lastFrameDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].log("[mp4-remuxer]: It is approximately " + deltaToFrameEnd / 90 + " ms to the next segment; using duration " + mp4SampleDuration / 90 + " ms for the last video frame.");
|
||||||
"[mp4-remuxer]: It is approximately " + deltaToFrameEnd / 90 + " ms to the next segment; using duration " + mp4SampleDuration / 90 + " ms for the last video frame."
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
mp4SampleDuration = lastFrameDuration;
|
mp4SampleDuration = lastFrameDuration;
|
||||||
}
|
}
|
||||||
|
@ -22759,10 +22662,7 @@ typeof window !== "undefined" &&
|
||||||
|
|
||||||
var timeOffsetMpegTS = timeOffset * inputTimeScale;
|
var timeOffsetMpegTS = timeOffset * inputTimeScale;
|
||||||
this.isAudioContiguous = contiguous =
|
this.isAudioContiguous = contiguous =
|
||||||
contiguous ||
|
contiguous || (inputSamples.length && nextAudioPts > 0 && ((accurateTimeOffset && Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) || Math.abs(normalizePts(inputSamples[0].pts - initPTS, timeOffsetMpegTS) - nextAudioPts) < 20 * inputSampleDuration)); // compute normalized PTS
|
||||||
(inputSamples.length &&
|
|
||||||
nextAudioPts > 0 &&
|
|
||||||
((accurateTimeOffset && Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) || Math.abs(normalizePts(inputSamples[0].pts - initPTS, timeOffsetMpegTS) - nextAudioPts) < 20 * inputSampleDuration)); // compute normalized PTS
|
|
||||||
|
|
||||||
inputSamples.forEach(function (sample) {
|
inputSamples.forEach(function (sample) {
|
||||||
sample.pts = normalizePts(sample.pts - initPTS, timeOffsetMpegTS);
|
sample.pts = normalizePts(sample.pts - initPTS, timeOffsetMpegTS);
|
||||||
|
@ -22833,9 +22733,7 @@ typeof window !== "undefined" &&
|
||||||
this.nextAudioPts = nextAudioPts = nextPts;
|
this.nextAudioPts = nextAudioPts = nextPts;
|
||||||
}
|
}
|
||||||
|
|
||||||
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn(
|
_utils_logger__WEBPACK_IMPORTED_MODULE_5__["logger"].warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round((1000 * delta) / inputTimeScale) + " ms gap.");
|
||||||
"[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round((1000 * delta) / inputTimeScale) + " ms gap."
|
|
||||||
);
|
|
||||||
|
|
||||||
for (var j = 0; j < missing; j++) {
|
for (var j = 0; j < missing; j++) {
|
||||||
var newStamp = Math.max(nextPts, 0);
|
var newStamp = Math.max(nextPts, 0);
|
||||||
|
|
|
@ -334,6 +334,15 @@
|
||||||
width: 42px;
|
width: 42px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
&.circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
.mediaitem-artwork {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -349,6 +358,11 @@
|
||||||
color: #eee;
|
color: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.hintactive {
|
||||||
|
background: var(--keyColor);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
.queue-info {
|
.queue-info {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -392,6 +406,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-hints .cd-queue-item {
|
||||||
|
&:hover {
|
||||||
|
background: var(--selected);
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
.circular-play-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background: var(--selected-click);
|
||||||
|
color: #eee;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Circle Play Button */
|
||||||
|
.circular-play-button {
|
||||||
|
position: relative;
|
||||||
|
opacity: 0;
|
||||||
|
top: -34px;
|
||||||
|
z-index: 5;
|
||||||
|
left: 8px;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(100, 100, 100, 0.5);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 100%;
|
||||||
|
height: 26px;
|
||||||
|
box-shadow: var(--ciderShadow-Generic);
|
||||||
|
}
|
||||||
|
|
||||||
/* horizontal media scroller */
|
/* horizontal media scroller */
|
||||||
.cd-hmedia-scroller {
|
.cd-hmedia-scroller {
|
||||||
&::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
|
@ -1842,6 +1888,12 @@ input[type="checkbox"][switch]:checked:active::before {
|
||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.playback-button.stop {
|
||||||
|
background-image: url("./assets/cider-icons/stop.svg");
|
||||||
|
background-size: 38px;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
.playback-button.play {
|
.playback-button.play {
|
||||||
background-image: url("./assets/cider-icons/play.svg");
|
background-image: url("./assets/cider-icons/play.svg");
|
||||||
background-size: 38px;
|
background-size: 38px;
|
||||||
|
|
|
@ -58,6 +58,10 @@ const Events = {
|
||||||
try {
|
try {
|
||||||
app.mk._services.mediaItemPlayback._currentPlayer.destroy();
|
app.mk._services.mediaItemPlayback._currentPlayer.destroy();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
try {
|
||||||
|
this.radiohls.destroy();
|
||||||
|
this.radiohls = null;
|
||||||
|
} catch (_) {}
|
||||||
try {
|
try {
|
||||||
let searchInt = setInterval(function () {
|
let searchInt = setInterval(function () {
|
||||||
if (document.getElementById("apple-music-player")) {
|
if (document.getElementById("apple-music-player")) {
|
||||||
|
|
|
@ -20,11 +20,13 @@ const app = new Vue({
|
||||||
pluginMenuEntries: [],
|
pluginMenuEntries: [],
|
||||||
lz: ipcRenderer.sendSync("get-i18n", "en_US"),
|
lz: ipcRenderer.sendSync("get-i18n", "en_US"),
|
||||||
lzListing: ipcRenderer.sendSync("get-i18n-listing"),
|
lzListing: ipcRenderer.sendSync("get-i18n-listing"),
|
||||||
|
radiohls: null,
|
||||||
search: {
|
search: {
|
||||||
term: "",
|
term: "",
|
||||||
cursor: -1,
|
cursor: -1,
|
||||||
hints: [],
|
hints: [],
|
||||||
showHints: false,
|
showHints: false,
|
||||||
|
showSearchView: false,
|
||||||
results: {},
|
results: {},
|
||||||
resultsSocial: {},
|
resultsSocial: {},
|
||||||
resultsLibrary: {},
|
resultsLibrary: {},
|
||||||
|
@ -44,11 +46,7 @@ const app = new Vue({
|
||||||
browsepage: [],
|
browsepage: [],
|
||||||
listennow: [],
|
listennow: [],
|
||||||
madeforyou: [],
|
madeforyou: [],
|
||||||
radio: {
|
radio: [],
|
||||||
personal: {},
|
|
||||||
recent: {},
|
|
||||||
amlive: {},
|
|
||||||
},
|
|
||||||
mklang: "en",
|
mklang: "en",
|
||||||
webview: {
|
webview: {
|
||||||
url: "",
|
url: "",
|
||||||
|
@ -159,6 +157,7 @@ const app = new Vue({
|
||||||
miniTmpY: "",
|
miniTmpY: "",
|
||||||
tmpVar: [],
|
tmpVar: [],
|
||||||
notification: false,
|
notification: false,
|
||||||
|
hintscontext: false,
|
||||||
chrome: {
|
chrome: {
|
||||||
sidebarCollapsed: false,
|
sidebarCollapsed: false,
|
||||||
nativeControls: false,
|
nativeControls: false,
|
||||||
|
@ -247,6 +246,8 @@ const app = new Vue({
|
||||||
idleTimer: null,
|
idleTimer: null,
|
||||||
idleState: false,
|
idleState: false,
|
||||||
appVisible: true,
|
appVisible: true,
|
||||||
|
currentAirPlayCodeID: "",
|
||||||
|
airplayTrys: [],
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
cfg: {
|
cfg: {
|
||||||
|
@ -256,6 +257,12 @@ const app = new Vue({
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
|
"cfg.connectivity.discord_rpc.enabled"(newValue) {
|
||||||
|
ipcRenderer.send("discordrpc:reload", newValue);
|
||||||
|
},
|
||||||
|
"mk.privateEnabled"(newValue) {
|
||||||
|
ipcRenderer.send("onPrivacyModeChange", newValue);
|
||||||
|
},
|
||||||
page: () => {
|
page: () => {
|
||||||
document.getElementById("app-content").scrollTo(0, 0);
|
document.getElementById("app-content").scrollTo(0, 0);
|
||||||
app.resetState();
|
app.resetState();
|
||||||
|
@ -287,6 +294,12 @@ const app = new Vue({
|
||||||
},
|
},
|
||||||
async oobeInit() {
|
async oobeInit() {
|
||||||
this.appMode = "oobe";
|
this.appMode = "oobe";
|
||||||
|
for (const [k, v] of Object.entries(ipcRenderer.sendSync("get-i18n-listing"))) {
|
||||||
|
if (v.code === navigator.language.replace("-", "_")) {
|
||||||
|
this.cfg.general.language = v.code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.setLz(this.cfg.general.language);
|
this.setLz(this.cfg.general.language);
|
||||||
this.setLzManual();
|
this.setLzManual();
|
||||||
clearTimeout(this.hangtimer);
|
clearTimeout(this.hangtimer);
|
||||||
|
@ -569,7 +582,24 @@ const app = new Vue({
|
||||||
window.location.hash = `#charts/top`;
|
window.location.hash = `#charts/top`;
|
||||||
} else {
|
} else {
|
||||||
const id = url.split("id=")[1];
|
const id = url.split("id=")[1];
|
||||||
window.location.hash = `#groupings/${id}`;
|
if (id != null) {
|
||||||
|
window.location.hash = `#groupings/${id}`;
|
||||||
|
} else {
|
||||||
|
const params = new Proxy(new URLSearchParams(new URL(url).search), {
|
||||||
|
get: (searchParams, prop) => searchParams.get(prop),
|
||||||
|
});
|
||||||
|
let id = params.fcId;
|
||||||
|
app
|
||||||
|
.getTypeFromID("room", id, false, {
|
||||||
|
platform: "web",
|
||||||
|
extend: "editorialArtwork,uber,lockupStyle",
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
let kind = "multiroom";
|
||||||
|
window.location.hash = `${kind}/${id}`;
|
||||||
|
document.querySelector("#app-content").scrollTop = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
|
@ -633,9 +663,46 @@ const app = new Vue({
|
||||||
this.modals.addToPlaylist = false;
|
this.modals.addToPlaylist = false;
|
||||||
app.newPlaylist(app.getLz("term.newPlaylist"), pl_items);
|
app.newPlaylist(app.getLz("term.newPlaylist"), pl_items);
|
||||||
},
|
},
|
||||||
|
async isSongInPlaylist(song_ids, playlist_id) {
|
||||||
|
let isInPlaylist = false;
|
||||||
|
const playlistTracks = (
|
||||||
|
await app.mk.api.v3.music(`/v1/me/library/playlists/${playlist_id}/tracks`, {
|
||||||
|
platform: "web",
|
||||||
|
l: app.mklang,
|
||||||
|
})
|
||||||
|
).data?.data;
|
||||||
|
|
||||||
|
playlistTracks.forEach((track) => {
|
||||||
|
if (song_ids.includes(track.id)) {
|
||||||
|
isInPlaylist = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return isInPlaylist;
|
||||||
|
},
|
||||||
|
addToPlaylist(pid, pitems) {
|
||||||
|
app.mk.api.v3
|
||||||
|
.music(
|
||||||
|
`/v1/me/library/playlists/${pid}/tracks`,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
fetchOptions: {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
data: pitems,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
if (app.page === "playlist_" + pid) {
|
||||||
|
app.getPlaylistFromID(app.showingPlaylist.id, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
async addSelectedToPlaylist(playlist_id) {
|
async addSelectedToPlaylist(playlist_id) {
|
||||||
let self = this;
|
let self = this;
|
||||||
let pl_items = [];
|
let pl_items = [];
|
||||||
|
const song_ids = [];
|
||||||
for (let i = 0; i < self.selectedMediaItems.length; i++) {
|
for (let i = 0; i < self.selectedMediaItems.length; i++) {
|
||||||
if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") {
|
if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") {
|
||||||
self.selectedMediaItems[i].kind = "songs";
|
self.selectedMediaItems[i].kind = "songs";
|
||||||
|
@ -643,6 +710,7 @@ const app = new Vue({
|
||||||
id: self.selectedMediaItems[i].id,
|
id: self.selectedMediaItems[i].id,
|
||||||
type: self.selectedMediaItems[i].kind,
|
type: self.selectedMediaItems[i].kind,
|
||||||
});
|
});
|
||||||
|
song_ids.push(self.selectedMediaItems[i].id);
|
||||||
} else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) {
|
} else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) {
|
||||||
self.selectedMediaItems[i].kind = "albums";
|
self.selectedMediaItems[i].kind = "albums";
|
||||||
let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`);
|
let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`);
|
||||||
|
@ -650,12 +718,14 @@ const app = new Vue({
|
||||||
return { id: i.id, type: i.type };
|
return { id: i.id, type: i.type };
|
||||||
});
|
});
|
||||||
pl_items = pl_items.concat(ids);
|
pl_items = pl_items.concat(ids);
|
||||||
|
song_ids.push(...ids.map((id) => id.id));
|
||||||
} else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") {
|
} else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") {
|
||||||
self.selectedMediaItems[i].kind = "library-songs";
|
self.selectedMediaItems[i].kind = "library-songs";
|
||||||
pl_items.push({
|
pl_items.push({
|
||||||
id: self.selectedMediaItems[i].id,
|
id: self.selectedMediaItems[i].id,
|
||||||
type: self.selectedMediaItems[i].kind,
|
type: self.selectedMediaItems[i].kind,
|
||||||
});
|
});
|
||||||
|
song_ids.push(self.selectedMediaItems[i].id);
|
||||||
} else if (self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums" || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) {
|
} else if (self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums" || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) {
|
||||||
self.selectedMediaItems[i].kind = "library-albums";
|
self.selectedMediaItems[i].kind = "library-albums";
|
||||||
let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`);
|
let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`);
|
||||||
|
@ -663,32 +733,26 @@ const app = new Vue({
|
||||||
return { id: i.id, type: i.type };
|
return { id: i.id, type: i.type };
|
||||||
});
|
});
|
||||||
pl_items = pl_items.concat(ids);
|
pl_items = pl_items.concat(ids);
|
||||||
|
song_ids.push(...ids.map((id) => id.id));
|
||||||
} else {
|
} else {
|
||||||
pl_items.push({
|
pl_items.push({
|
||||||
id: self.selectedMediaItems[i].id,
|
id: self.selectedMediaItems[i].id,
|
||||||
type: self.selectedMediaItems[i].kind,
|
type: self.selectedMediaItems[i].kind,
|
||||||
});
|
});
|
||||||
|
song_ids.push(self.selectedMediaItems[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.modals.addToPlaylist = false;
|
this.modals.addToPlaylist = false;
|
||||||
await app.mk.api.v3
|
|
||||||
.music(
|
if (await this.isSongInPlaylist(song_ids, playlist_id)) {
|
||||||
`/v1/me/library/playlists/${playlist_id}/tracks`,
|
app.confirm(app.getLz("action.addToPlaylist.duplicate"), (result) => {
|
||||||
{},
|
if (result === true) {
|
||||||
{
|
app.addToPlaylist(playlist_id, pl_items);
|
||||||
fetchOptions: {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
data: pl_items,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
if (this.page == "playlist_" + this.showingPlaylist.id) {
|
|
||||||
this.getPlaylistFromID(this.showingPlaylist.id, true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
app.addToPlaylist(playlist_id, pl_items);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async init() {
|
async init() {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
@ -773,6 +837,8 @@ const app = new Vue({
|
||||||
this.mk.volume = -1;
|
this.mk.volume = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore mk
|
||||||
|
|
||||||
// load cached library
|
// load cached library
|
||||||
let librarySongs = await CiderCache.getCache("library-songs");
|
let librarySongs = await CiderCache.getCache("library-songs");
|
||||||
let libraryAlbums = await CiderCache.getCache("library-albums");
|
let libraryAlbums = await CiderCache.getCache("library-albums");
|
||||||
|
@ -995,6 +1061,11 @@ const app = new Vue({
|
||||||
return;
|
return;
|
||||||
} // EVIL EMPTY OBJECTS BE GONE
|
} // EVIL EMPTY OBJECTS BE GONE
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.radiohls.destroy();
|
||||||
|
this.radiohls = null;
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((MusicKit.getInstance().nowPlayingItem["type"] ?? "").includes("ideo")) {
|
if ((MusicKit.getInstance().nowPlayingItem["type"] ?? "").includes("ideo")) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -1141,8 +1212,6 @@ const app = new Vue({
|
||||||
if (this.cfg.general.themeUpdateNotification && !this.isDev) {
|
if (this.cfg.general.themeUpdateNotification && !this.isDev) {
|
||||||
this.checkForThemeUpdates();
|
this.checkForThemeUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.invoke("scanLibrary");
|
|
||||||
},
|
},
|
||||||
setWindowScaleFactor() {
|
setWindowScaleFactor() {
|
||||||
let scale = (((window.devicePixelRatio * window.innerWidth) / 1280) * window.innerHeight) / 720;
|
let scale = (((window.devicePixelRatio * window.innerWidth) / 1280) * window.innerHeight) / 720;
|
||||||
|
@ -1181,7 +1250,7 @@ const app = new Vue({
|
||||||
const notify = notyf.open({
|
const notify = notyf.open({
|
||||||
className: "notyf-info",
|
className: "notyf-info",
|
||||||
type: "info",
|
type: "info",
|
||||||
message: `[Themes] ${theme.name} has an update available.`,
|
message: app.stringTemplateParser(app.getLz("settings.notyf.visual.theme.updateAvailable"), { theme: theme.name }),
|
||||||
});
|
});
|
||||||
notify.on("click", () => {
|
notify.on("click", () => {
|
||||||
app.openSettingsPage("github-themes");
|
app.openSettingsPage("github-themes");
|
||||||
|
@ -1457,15 +1526,15 @@ const app = new Vue({
|
||||||
const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks");
|
const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks");
|
||||||
|
|
||||||
if (cachedPlaylist) {
|
if (cachedPlaylist) {
|
||||||
console.debug("using cached playlists");
|
console.debug("[CiderCache] Using cached playlist");
|
||||||
this.playlists.listing = cachedPlaylist;
|
this.playlists.listing = cachedPlaylist;
|
||||||
self.sortPlaylists();
|
self.sortPlaylists();
|
||||||
} else {
|
} else {
|
||||||
console.debug("playlist has no cache");
|
console.debug("[CiderCache] Playlist has no cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedTrackMapping) {
|
if (cachedTrackMapping) {
|
||||||
console.debug("using cached track mapping");
|
console.debug("[CiderCache] Using cached track mapping");
|
||||||
this.playlists.trackMapping = cachedTrackMapping;
|
this.playlists.trackMapping = cachedTrackMapping;
|
||||||
}
|
}
|
||||||
if (localOnly) {
|
if (localOnly) {
|
||||||
|
@ -1473,7 +1542,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.library.backgroundNotification.message = "Building playlist cache...";
|
this.library.backgroundNotification.message = app.getLz("notification.buildingPlaylistCache");
|
||||||
this.library.backgroundNotification.show = true;
|
this.library.backgroundNotification.show = true;
|
||||||
|
|
||||||
async function deepScan(parent = "p.playlistsroot") {
|
async function deepScan(parent = "p.playlistsroot") {
|
||||||
|
@ -1895,10 +1964,31 @@ const app = new Vue({
|
||||||
async getSearchHints() {
|
async getSearchHints() {
|
||||||
if (this.search.term == "") {
|
if (this.search.term == "") {
|
||||||
this.search.hints = [];
|
this.search.hints = [];
|
||||||
|
this.search.showHints = true;
|
||||||
|
this.search.showSearchView = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let hints = await (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/hints?term=${this.search.term}`)).data.results;
|
let hints = await (
|
||||||
this.search.hints = hints ? hints.terms : [];
|
await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/suggestions?term=${encodeURIComponent(this.search.term)}`, {
|
||||||
|
"fields[albums]": "artwork,name,playParams,url,artistName,id",
|
||||||
|
"fields[artists]": "url,name,artwork,id",
|
||||||
|
"fields[songs]": "artwork,name,playParams,url,artistName,id",
|
||||||
|
kinds: "terms,topResults",
|
||||||
|
l: this.mklang,
|
||||||
|
"limit[results:terms]": 5,
|
||||||
|
"limit[results:topResults]": 5,
|
||||||
|
"omit[resource]": "autos",
|
||||||
|
platform: "web",
|
||||||
|
types: "activities,albums,artists,editorial-items,music-movies,playlists,record-labels,songs,stations",
|
||||||
|
})
|
||||||
|
).data.results;
|
||||||
|
let shints = hints ? hints.suggestions : [];
|
||||||
|
for (let item in shints) {
|
||||||
|
if ((shints[item]?.displayTerm ?? "").includes("?fields[")) {
|
||||||
|
shints[item].displayTerm = shints[item].searchTerm = shints[item].displayTerm.split("?fields[")[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.search.hints = shints;
|
||||||
},
|
},
|
||||||
getSongProgress() {
|
getSongProgress() {
|
||||||
if (this.playerLCD.userInteraction) {
|
if (this.playerLCD.userInteraction) {
|
||||||
|
@ -1916,6 +2006,7 @@ const app = new Vue({
|
||||||
* @memberOf app
|
* @memberOf app
|
||||||
*/
|
*/
|
||||||
convertTime(seconds, format = "short") {
|
convertTime(seconds, format = "short") {
|
||||||
|
if (app.mk?.nowPlayingItem?.type === "radioStation") return;
|
||||||
if (isNaN(seconds) || seconds === Infinity) {
|
if (isNaN(seconds) || seconds === Infinity) {
|
||||||
seconds = 0;
|
seconds = 0;
|
||||||
}
|
}
|
||||||
|
@ -1996,26 +2087,36 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
if (kind.toString().includes("apple-curator")) {
|
if (kind.toString().includes("apple-curator")) {
|
||||||
kind = "appleCurator";
|
kind = "appleCurator";
|
||||||
app.getTypeFromID("appleCurator", id, false, {
|
app
|
||||||
platform: "web",
|
.getTypeFromID("appleCurator", id, false, {
|
||||||
include: "grouping,playlists",
|
platform: "web",
|
||||||
extend: "editorialArtwork",
|
include: "grouping,playlists",
|
||||||
"art[url]": "f",
|
extend: "editorialArtwork",
|
||||||
});
|
"art[url]": "f",
|
||||||
window.location.hash = `${kind}/${id}`;
|
})
|
||||||
document.querySelector("#app-content").scrollTop = 0;
|
.then(() => {
|
||||||
|
kind = "appleCurator";
|
||||||
|
window.location.hash = `${kind}/${id}`;
|
||||||
|
document.querySelector("#app-content").scrollTop = 0;
|
||||||
|
});
|
||||||
} else if (kind == "editorial-elements" || kind == "editorial-items") {
|
} else if (kind == "editorial-elements" || kind == "editorial-items") {
|
||||||
console.debug(item);
|
console.debug(item);
|
||||||
if (item.relationships?.contents?.data != null && item.relationships?.contents?.data.length > 0) {
|
if (item.relationships?.contents?.data != null && item.relationships?.contents?.data.length > 0) {
|
||||||
this.routeView(item.relationships.contents.data[0]);
|
this.routeView(item.relationships.contents.data[0]);
|
||||||
} else if (item.attributes?.link?.url != null) {
|
} else if (item.attributes?.link?.url != null) {
|
||||||
if (item.attributes.link.url.includes("viewMultiRoom")) {
|
if (item.attributes.link.url.includes("viewMultiRoom") || item.attributes.link.url.includes("/collection/")) {
|
||||||
const params = new Proxy(new URLSearchParams(new URL(item.attributes.link.url).search), {
|
const params = new Proxy(new URLSearchParams(new URL(item.attributes.link.url).search), {
|
||||||
get: (searchParams, prop) => searchParams.get(prop),
|
get: (searchParams, prop) => searchParams.get(prop),
|
||||||
});
|
});
|
||||||
id = params.fcId;
|
id = params.fcId;
|
||||||
|
kind = "multiroom";
|
||||||
|
if (item.attributes.link.url.includes("viewMultiRoom")) {
|
||||||
|
kind = "multiroom";
|
||||||
|
} else {
|
||||||
|
kind = "room";
|
||||||
|
}
|
||||||
app
|
app
|
||||||
.getTypeFromID("multiroom", id, false, {
|
.getTypeFromID(kind, id, false, {
|
||||||
platform: "web",
|
platform: "web",
|
||||||
extend: "editorialArtwork,uber,lockupStyle",
|
extend: "editorialArtwork,uber,lockupStyle",
|
||||||
})
|
})
|
||||||
|
@ -2116,6 +2217,17 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
|
|
||||||
// app.getTypeFromID((kind), (id), (isLibrary), params);
|
// app.getTypeFromID((kind), (id), (isLibrary), params);
|
||||||
|
} else if (kind.toString().includes("song")) {
|
||||||
|
const albumUrl = new Promise(async (resolve, reject) => {
|
||||||
|
resolve(await MusicKitInterop.fetchSongRelationships({ id: id, relationship: "album" }));
|
||||||
|
});
|
||||||
|
albumUrl.then((data) => {
|
||||||
|
if (data && data.type === "albums" && data.id) {
|
||||||
|
window.location.hash = `album/${data.id}${isLibrary ? "/" + isLibrary : ""}`;
|
||||||
|
} else {
|
||||||
|
app.playMediaItemById(id, kind, isLibrary, item.attributes.url ?? "");
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
app.playMediaItemById(id, kind, isLibrary, item.attributes.url ?? "");
|
app.playMediaItemById(id, kind, isLibrary, item.attributes.url ?? "");
|
||||||
}
|
}
|
||||||
|
@ -2184,6 +2296,11 @@ const app = new Vue({
|
||||||
artistId = item.relationships.artists.data[0].id;
|
artistId = item.relationships.artists.data[0].id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (item.relationships.albums && item.relationships.albums.data.length > 0) {
|
||||||
|
if (item.relationships.albums.data[0].attributes.artistUrl) {
|
||||||
|
artistId = item.relationships.albums.data[0].attributes.artistUrl.split("/").pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (artistId == "") {
|
if (artistId == "") {
|
||||||
const url = item.relationships.catalog.data[0].attributes.artistUrl;
|
const url = item.relationships.catalog.data[0].attributes.artistUrl;
|
||||||
artistId = url.substring(url.lastIndexOf("/") + 1);
|
artistId = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
@ -2324,7 +2441,7 @@ const app = new Vue({
|
||||||
} finally {
|
} finally {
|
||||||
if (kind == "appleCurator") {
|
if (kind == "appleCurator") {
|
||||||
app.appleCurator = a.data.data[0];
|
app.appleCurator = a.data.data[0];
|
||||||
} else if (kind == "multiroom") {
|
} else if (kind == "multiroom" || kind == "room") {
|
||||||
app.multiroom = a.data.data[0];
|
app.multiroom = a.data.data[0];
|
||||||
} else {
|
} else {
|
||||||
this.getPlaylistContinuous(a, true);
|
this.getPlaylistContinuous(a, true);
|
||||||
|
@ -2333,7 +2450,7 @@ const app = new Vue({
|
||||||
} finally {
|
} finally {
|
||||||
if (kind == "appleCurator") {
|
if (kind == "appleCurator") {
|
||||||
app.appleCurator = a.data.data[0];
|
app.appleCurator = a.data.data[0];
|
||||||
} else if (kind == "multiroom") {
|
} else if (kind == "multiroom" || kind == "room") {
|
||||||
app.multiroom = a.data.data[0];
|
app.multiroom = a.data.data[0];
|
||||||
} else {
|
} else {
|
||||||
this.getPlaylistContinuous(a, true);
|
this.getPlaylistContinuous(a, true);
|
||||||
|
@ -2344,28 +2461,32 @@ const app = new Vue({
|
||||||
let self = this;
|
let self = this;
|
||||||
let prefs = this.cfg.libraryPrefs.songs;
|
let prefs = this.cfg.libraryPrefs.songs;
|
||||||
|
|
||||||
const albumAdded = {};
|
|
||||||
|
|
||||||
for (const listing of self.library?.albums?.listing ?? []) {
|
|
||||||
albumAdded[listing.id] = listing.attributes?.dateAdded;
|
|
||||||
}
|
|
||||||
|
|
||||||
let startTime = new Date().getTime();
|
|
||||||
|
|
||||||
function sortSongs() {
|
function sortSongs() {
|
||||||
// sort this.library.songs.displayListing by song.attributes[self.library.songs.sorting] in descending or ascending order based on alphabetical order and numeric order
|
// sort this.library.songs.displayListing by song.attributes[self.library.songs.sorting] in descending or ascending order based on alphabetical order and numeric order
|
||||||
// check if song.attributes[self.library.songs.sorting] is a number and if so, sort by number if not, sort by alphabetical order ignoring case
|
// check if song.attributes[self.library.songs.sorting] is a number and if so, sort by number if not, sort by alphabetical order ignoring case
|
||||||
self.library.songs.displayListing.sort((a, b) => {
|
self.library.songs.displayListing.sort((a, b) => {
|
||||||
let aa = a.attributes[prefs.sort];
|
let aa = a.attributes[prefs.sort];
|
||||||
let bb = b.attributes[prefs.sort];
|
let bb = b.attributes[prefs.sort];
|
||||||
if (prefs.sort == "genre") {
|
if (prefs.sort === "genre") {
|
||||||
aa = a.attributes.genreNames[0];
|
aa = a.attributes.genreNames[0];
|
||||||
bb = b.attributes.genreNames[0];
|
bb = b.attributes.genreNames[0];
|
||||||
} else if (prefs.sort == "dateAdded") {
|
} else if (prefs.sort === "dateAdded") {
|
||||||
let albumida = a.relationships?.albums?.data[0]?.id;
|
aa = a.relationships?.albums?.data[0]?.attributes?.dateAdded;
|
||||||
let albumidb = b.relationships?.albums?.data[0]?.id;
|
bb = b.relationships?.albums?.data[0]?.attributes?.dateAdded;
|
||||||
aa = startTime - new Date(albumAdded[albumida] ?? "1970-01-01T00:01:01Z").getTime();
|
} else if (prefs.sort === "artistName") {
|
||||||
bb = startTime - new Date(albumAdded[albumidb] ?? "1970-01-01T00:01:01Z").getTime();
|
if (a.relationships?.artists?.data[0]?.id === b.relationships?.artists?.data[0]?.id) {
|
||||||
|
aa = a.attributes.albumName;
|
||||||
|
bb = b.attributes.albumName;
|
||||||
|
}
|
||||||
|
if (a.relationships?.albums?.data[0]?.id === b.relationships?.albums?.data[0]?.id) {
|
||||||
|
aa = a.attributes.trackNumber;
|
||||||
|
bb = b.attributes.trackNumber;
|
||||||
|
}
|
||||||
|
} else if (prefs.sort === "albumName") {
|
||||||
|
if (a.relationships?.albums?.data[0]?.id === b.relationships?.albums?.data[0]?.id) {
|
||||||
|
aa = a.attributes.trackNumber;
|
||||||
|
bb = b.attributes.trackNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (aa == null) {
|
if (aa == null) {
|
||||||
aa = "";
|
aa = "";
|
||||||
|
@ -2373,13 +2494,13 @@ const app = new Vue({
|
||||||
if (bb == null) {
|
if (bb == null) {
|
||||||
bb = "";
|
bb = "";
|
||||||
}
|
}
|
||||||
if (prefs.sortOrder == "asc") {
|
if (prefs.sortOrder === "asc") {
|
||||||
if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) {
|
if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) {
|
||||||
return aa - bb;
|
return aa - bb;
|
||||||
} else {
|
} else {
|
||||||
return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase());
|
return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase());
|
||||||
}
|
}
|
||||||
} else if (prefs.sortOrder == "desc") {
|
} else if (prefs.sortOrder === "desc") {
|
||||||
if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) {
|
if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) {
|
||||||
return bb - aa;
|
return bb - aa;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2576,7 +2697,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
let truemethod = !method.endsWith("s") ? method + "s" : method;
|
let truemethod = !method.endsWith("s") ? method + "s" : method;
|
||||||
try {
|
try {
|
||||||
if (method.includes(`multiroom`)) {
|
if (method.includes(`room`)) {
|
||||||
return await this.mk.api.v3.music(`v1/editorial/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2);
|
return await this.mk.api.v3.music(`v1/editorial/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2);
|
||||||
} else if (library) {
|
} else if (library) {
|
||||||
return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2);
|
return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2);
|
||||||
|
@ -2972,6 +3093,38 @@ const app = new Vue({
|
||||||
this.getListenNow(attempt + 1);
|
this.getListenNow(attempt + 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async getRadioPage(attempt = 0) {
|
||||||
|
if (this.radio.timestamp > Date.now() - 120000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attempt > 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
app.mk.api.v3
|
||||||
|
.music(`/v1/editorial/${app.mk.storefrontId}/groupings`, {
|
||||||
|
platform: "web",
|
||||||
|
name: "radio",
|
||||||
|
"omit[resource:artists]": "relationships",
|
||||||
|
"include[albums]": "artists",
|
||||||
|
"include[songs]": "artists",
|
||||||
|
"include[music-videos]": "artists",
|
||||||
|
extend: "editorialArtwork,artistUrl",
|
||||||
|
"fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes",
|
||||||
|
"art[url]": "f",
|
||||||
|
l: app.mklang,
|
||||||
|
})
|
||||||
|
.then((radio) => {
|
||||||
|
app.radio = radio.data.data[0];
|
||||||
|
console.debug(app.radio);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.radio.timestamp = Date.now();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
this.getRadioPage(attempt + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
async getBrowsePage(attempt = 0) {
|
async getBrowsePage(attempt = 0) {
|
||||||
if (this.browsepage.timestamp > Date.now() - 120000) {
|
if (this.browsepage.timestamp > Date.now() - 120000) {
|
||||||
return;
|
return;
|
||||||
|
@ -2990,7 +3143,7 @@ const app = new Vue({
|
||||||
extend: "editorialArtwork,artistUrl",
|
extend: "editorialArtwork,artistUrl",
|
||||||
"fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes",
|
"fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes",
|
||||||
"art[url]": "f",
|
"art[url]": "f",
|
||||||
l: this.mklang,
|
l: app.mklang,
|
||||||
});
|
});
|
||||||
this.browsepage = browse.data.data[0];
|
this.browsepage = browse.data.data[0];
|
||||||
this.browsepage.timestamp = Date.now();
|
this.browsepage.timestamp = Date.now();
|
||||||
|
@ -3005,9 +3158,7 @@ const app = new Vue({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
let mfu = await app.mk.api.v3.music(
|
let mfu = await app.mk.api.v3.music("/v1/me/library/playlists?platform=web&extend=editorialVideo&fields%5Bplaylists%5D=lastModifiedDate&filter%5Bfeatured%5D=made-for-you&include%5Blibrary-playlists%5D=catalog&fields%5Blibrary-playlists%5D=artwork%2Cname%2CplayParams%2CdateAdded");
|
||||||
"/v1/me/library/playlists?platform=web&extend=editorialVideo&fields%5Bplaylists%5D=lastModifiedDate&filter%5Bfeatured%5D=made-for-you&include%5Blibrary-playlists%5D=catalog&fields%5Blibrary-playlists%5D=artwork%2Cname%2CplayParams%2CdateAdded"
|
|
||||||
);
|
|
||||||
this.madeforyou = mfu.data;
|
this.madeforyou = mfu.data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
@ -3187,10 +3338,7 @@ const app = new Vue({
|
||||||
let id,
|
let id,
|
||||||
songLang = "";
|
songLang = "";
|
||||||
try {
|
try {
|
||||||
if (
|
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) {
|
||||||
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"] ?? "";
|
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"];
|
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"];
|
vanity_id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["commontrack_vanity_id"];
|
||||||
|
@ -3880,15 +4028,22 @@ const app = new Vue({
|
||||||
if (e.keyCode == "40") {
|
if (e.keyCode == "40") {
|
||||||
if (this.search.hints.length - 1 < this.search.cursor + 1) return;
|
if (this.search.hints.length - 1 < this.search.cursor + 1) return;
|
||||||
this.search.cursor++;
|
this.search.cursor++;
|
||||||
this.search.term = this.search.hints[this.search.cursor];
|
let item = this.search.hints[this.search.cursor];
|
||||||
|
this.search.term = item.content ? item.content?.attributes?.name ?? "" : item.displayTerm;
|
||||||
} else if (e.keyCode == "38") {
|
} else if (e.keyCode == "38") {
|
||||||
if (this.search.cursor == 0) return;
|
if (this.search.cursor == 0) return;
|
||||||
this.search.cursor--;
|
this.search.cursor--;
|
||||||
this.search.term = this.search.hints[this.search.cursor];
|
let item = this.search.hints[this.search.cursor];
|
||||||
|
this.search.term = item.content ? item.content?.attributes?.name ?? "" : item.displayTerm;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async searchQuery(term = this.search.term) {
|
async searchQuery(term = this.search.term) {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
if (typeof term === "object") {
|
||||||
|
this.routeView(term);
|
||||||
|
this.search.term = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (term == "") {
|
if (term == "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4016,23 +4171,28 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getMediaItemArtwork(url, height = 64, width) {
|
getMediaItemArtwork(url, height = 64, width) {
|
||||||
if (typeof url == "undefined" || url == "") {
|
try {
|
||||||
|
if (typeof url == "undefined" || url == "") {
|
||||||
|
return "./assets/MissingArtwork.svg";
|
||||||
|
}
|
||||||
|
height = parseInt(height * window.devicePixelRatio);
|
||||||
|
if (width) {
|
||||||
|
width = parseInt(width * window.devicePixelRatio);
|
||||||
|
}
|
||||||
|
let newurl = `${(url ?? "")
|
||||||
|
.replace("{w}", width ?? height)
|
||||||
|
.replace("{h}", height)
|
||||||
|
.replace("{f}", "webp")
|
||||||
|
.replace("{c}", width === 900 || width === 380 || width === 600 ? "sr" : "cc")}`;
|
||||||
|
|
||||||
|
if (newurl.includes("900x516")) {
|
||||||
|
newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr");
|
||||||
|
}
|
||||||
|
return newurl;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(url);
|
||||||
return "./assets/MissingArtwork.svg";
|
return "./assets/MissingArtwork.svg";
|
||||||
}
|
}
|
||||||
height = parseInt(height * window.devicePixelRatio);
|
|
||||||
if (width) {
|
|
||||||
width = parseInt(width * window.devicePixelRatio);
|
|
||||||
}
|
|
||||||
let newurl = `${url
|
|
||||||
.replace("{w}", width ?? height)
|
|
||||||
.replace("{h}", height)
|
|
||||||
.replace("{f}", "webp")
|
|
||||||
.replace("{c}", width === 900 || width === 380 || width === 600 ? "sr" : "cc")}`;
|
|
||||||
|
|
||||||
if (newurl.includes("900x516")) {
|
|
||||||
newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr");
|
|
||||||
}
|
|
||||||
return newurl;
|
|
||||||
},
|
},
|
||||||
_rgbToRgb(rgb = [0, 0, 0]) {
|
_rgbToRgb(rgb = [0, 0, 0]) {
|
||||||
// if rgb
|
// if rgb
|
||||||
|
@ -4091,13 +4251,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
this.currentArtUrl = "";
|
this.currentArtUrl = "";
|
||||||
this.currentArtUrlRaw = "";
|
this.currentArtUrlRaw = "";
|
||||||
if (
|
if (app.mk.nowPlayingItem != null && app.mk.nowPlayingItem.attributes != null && app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url != "") {
|
||||||
app.mk.nowPlayingItem != null &&
|
|
||||||
app.mk.nowPlayingItem.attributes != null &&
|
|
||||||
app.mk.nowPlayingItem.attributes.artwork != null &&
|
|
||||||
app.mk.nowPlayingItem.attributes.artwork.url != null &&
|
|
||||||
app.mk.nowPlayingItem.attributes.artwork.url != ""
|
|
||||||
) {
|
|
||||||
this.currentArtUrlRaw = this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? "";
|
this.currentArtUrlRaw = this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? "";
|
||||||
this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? "").replace("{w}", artworkSize).replace("{h}", artworkSize);
|
this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? "").replace("{w}", artworkSize).replace("{h}", artworkSize);
|
||||||
if (this.mk.nowPlayingItem._assets[0].artworkURL) {
|
if (this.mk.nowPlayingItem._assets[0].artworkURL) {
|
||||||
|
@ -4115,7 +4269,7 @@ const app = new Vue({
|
||||||
if (this.mk.nowPlayingItem._assets[0].artworkURL) {
|
if (this.mk.nowPlayingItem._assets[0].artworkURL) {
|
||||||
this.currentArtUrl = this.mk.nowPlayingItem._assets[0].artworkURL;
|
this.currentArtUrl = this.mk.nowPlayingItem._assets[0].artworkURL;
|
||||||
}
|
}
|
||||||
ipcRenderer.send("updateRPCImage", this.currentArtUrl ?? "");
|
ipcRenderer.send("discordrpc:updateImage", this.currentArtUrl ?? "");
|
||||||
try {
|
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) {}
|
} catch (e) {}
|
||||||
|
@ -4333,24 +4487,62 @@ const app = new Vue({
|
||||||
|
|
||||||
// tracks are found in relationship.data
|
// tracks are found in relationship.data
|
||||||
},
|
},
|
||||||
setAirPlayCodeUI() {
|
setAirPlayCodeUI(identifier) {
|
||||||
this.modals.airplayPW = true;
|
this.modals.airplayPW = true;
|
||||||
|
this.currentAirPlayCodeID = identifier;
|
||||||
},
|
},
|
||||||
sendAirPlaySuccess() {
|
sendAirPlaySuccess(silent = false, identifier = "") {
|
||||||
notyf.success("Device paired successfully!");
|
if (!silent) {
|
||||||
|
notyf.success("Device paired successfully!");
|
||||||
|
}
|
||||||
|
console.log("delete idx-pre", identifier);
|
||||||
|
let idx = this.airplayTrys.findIndex((a) => {
|
||||||
|
return a.id == identifier;
|
||||||
|
});
|
||||||
|
console.log("delete idx", idx);
|
||||||
|
if (idx != -1) delete this.airplayTrys[idx];
|
||||||
|
this.airplayTrys = this.airplayTrys.filter((n) => n);
|
||||||
},
|
},
|
||||||
sendAirPlayFailed() {
|
sendAirPlayFailed() {
|
||||||
notyf.success("Device paring failed!");
|
notyf.success("Device paring failed!");
|
||||||
},
|
},
|
||||||
airplayDisconnect(dropped, array = []) {
|
airplayDisconnect(dropped, array = [], identifier = "") {
|
||||||
console.log("airplay dropped", dropped, array);
|
console.log("airplay dropped", dropped, array, identifier);
|
||||||
// if (dropped) {
|
if (dropped) {
|
||||||
// let [ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv] = array;
|
let [ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv] = array;
|
||||||
// ipcRenderer.send("performAirplayPCM", ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv);
|
console.log(ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv);
|
||||||
// } else {
|
let idx = this.airplayTrys.findIndex((a) => {
|
||||||
// app.activeCasts = [];
|
return a.id == ipv4 + ":" + ipport + "ap";
|
||||||
// notyf.error("Devices disconnected!");
|
});
|
||||||
// }
|
if (idx == -1) {
|
||||||
|
this.airplayTrys.push({
|
||||||
|
id: ipv4 + ":" + ipport + "ap",
|
||||||
|
attempts: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
idx = this.airplayTrys.findIndex((a) => {
|
||||||
|
return a.id == ipv4 + ":" + ipport + "ap";
|
||||||
|
});
|
||||||
|
if (this.airplayTrys[idx].attempts > 3) {
|
||||||
|
delete this.airplayTrys[idx];
|
||||||
|
this.airplayTrys = this.airplayTrys.filter((n) => n);
|
||||||
|
console.log("delete idx", idx);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.airplayTrys[idx].attempts = this.airplayTrys[idx].attempts + 1;
|
||||||
|
setTimeout(() => {
|
||||||
|
ipcRenderer.send("performAirplayPCM", ipv4, ipport, sepassword, title, artist, album, artworkURL, txt, airplay2dv, true);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (identifier == "") {
|
||||||
|
app.activeCasts = [];
|
||||||
|
notyf.error("Devices disconnected!");
|
||||||
|
} else {
|
||||||
|
app.activeCasts;
|
||||||
|
notyf.error("Device disconnected!");
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
windowFocus(val) {
|
windowFocus(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
|
@ -4446,7 +4638,7 @@ const app = new Vue({
|
||||||
name: app.getLz("action.removeFromLibrary"),
|
name: app.getLz("action.removeFromLibrary"),
|
||||||
hidden: true,
|
hidden: true,
|
||||||
action: function () {
|
action: function () {
|
||||||
self.removeFromLibrary();
|
self.removeFromLibrary(app.mk.nowPlayingItem.type, MusicKitInterop.getAttributes().songId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4469,8 +4661,13 @@ const app = new Vue({
|
||||||
{
|
{
|
||||||
icon: "./assets/feather/user.svg",
|
icon: "./assets/feather/user.svg",
|
||||||
name: app.getLz("action.goToArtist"),
|
name: app.getLz("action.goToArtist"),
|
||||||
action: function () {
|
action: async function () {
|
||||||
app.appRoute(`artist/${app.mk.nowPlayingItem.relationships.artists.data[0].id}`);
|
if (app.mk.nowPlayingItem.relationships.artists.data[0].id) {
|
||||||
|
app.appRoute(`artist/${app.mk.nowPlayingItem.relationships.artists.data[0].id}`);
|
||||||
|
} else {
|
||||||
|
const primaryArtist = await MusicKitInterop.fetchSongRelationships({ relationship: "primaryArtist" });
|
||||||
|
app.appRoute(`artist/${primaryArtist.id}`);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4918,7 +5115,36 @@ const app = new Vue({
|
||||||
});
|
});
|
||||||
// Load first source
|
// Load first source
|
||||||
let src = sources[0];
|
let src = sources[0];
|
||||||
app.mk._services.mediaItemPlayback._currentPlayer._playAssetURL(src, false);
|
if (src.includes("http")) {
|
||||||
|
app.mk._services.mediaItemPlayback._currentPlayer._playAssetURL(src, false);
|
||||||
|
} else {
|
||||||
|
if (Hls.isSupported()) {
|
||||||
|
let d = "WIDEVINE_SOFTWARE";
|
||||||
|
let h = {
|
||||||
|
initDataTypes: ["cenc", "keyids"],
|
||||||
|
distinctiveIdentifier: "optional",
|
||||||
|
persistentState: "required",
|
||||||
|
};
|
||||||
|
let p = {
|
||||||
|
platformInfo: { requiresCDMAttachOnStart: !0, maxSecurityLevel: d, keySystemConfig: h },
|
||||||
|
appData: { serviceName: "Apple Music" },
|
||||||
|
};
|
||||||
|
if (app.radiohls != null && app.radiohls.destroy != null) {
|
||||||
|
app.radiohls.destroy();
|
||||||
|
app.radiohls = null;
|
||||||
|
app.radiohls = new CiderHls();
|
||||||
|
app.radiohls.loadSource(e);
|
||||||
|
app.radiohls.attachMedia(app.mk._services.mediaItemPlayback._currentPlayer._targetElement);
|
||||||
|
app.mk._services.mediaItemPlayback._currentPlayer._targetElement.play();
|
||||||
|
} else {
|
||||||
|
app.radiohls = null;
|
||||||
|
app.radiohls = new CiderHls();
|
||||||
|
app.radiohls.loadSource(e);
|
||||||
|
app.radiohls.attachMedia(app.mk._services.mediaItemPlayback._currentPlayer._targetElement);
|
||||||
|
app.mk._services.mediaItemPlayback._currentPlayer._targetElement.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -724,7 +724,7 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
|
|
||||||
.search-hints-container {
|
.search-hints-container {
|
||||||
top: 44px;
|
top: 44px;
|
||||||
background: rgb(30 30 30);
|
// background: rgb(30 30 30);
|
||||||
#cmenu.container();
|
#cmenu.container();
|
||||||
|
|
||||||
.search-hints {
|
.search-hints {
|
||||||
|
@ -1339,6 +1339,12 @@ body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.cl
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.live-icon {
|
||||||
|
filter: none !important;
|
||||||
|
margin-left: 0.5em !important;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.chrome-icon-container {
|
.chrome-icon-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
:title="$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')"
|
:title="$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
></div>
|
></div>
|
||||||
|
<svg class="audio-type live-icon" v-if="mk.nowPlayingItem?.attributes?.isLive === true" :title="$root.getLz('term.live')" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--keyColor)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" v-b-tooltip.hover><path d="M5 12.55a11 11 0 0 1 14.08 0"></path><path d="M1.42 9a16 16 0 0 1 21.16 0"></path><path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path><line x1="12" y1="20" x2="12.01" y2="20"></line></svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
|
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
|
||||||
|
@ -101,10 +102,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="app-chrome--center">
|
<div class="app-chrome--center">
|
||||||
<div class="app-chrome-playback-duration-bottom">
|
<div class="app-chrome-playback-duration-bottom">
|
||||||
<b-row v-if="mkReady()">
|
<b-row v-if="mkReady() && mk.nowPlayingItem?.attributes?.isLive !== true">
|
||||||
<b-col sm="auto" v-if="!mk.nowPlayingItem?.isLiveRadioStation">{{ convertTime(getSongProgress()) }}
|
<b-col sm="auto">{{ convertTime(getSongProgress()) }}</b-col>
|
||||||
</b-col>
|
|
||||||
<b-col sm="auto" v-else>--:--</b-col>
|
|
||||||
<b-col>
|
<b-col>
|
||||||
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
|
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
|
||||||
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
|
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
</b-popover>
|
</b-popover>
|
||||||
<div class="playback-info">
|
<div class="playback-info">
|
||||||
<div class="chrome-icon-container">
|
<div class="chrome-icon-container">
|
||||||
<div class="audio-type private-icon" v-if="cfg.general.privateEnabled === true"></div>
|
<div class="audio-type private-icon" v-if="cfg.general.privateEnabled === true" :title="$root.getLz('term.privateSession')" v-b-tooltip.hover></div>
|
||||||
<div class="audio-type spatial-icon" v-if="cfg.audio.maikiwiAudio.spatial === true"
|
<div class="audio-type spatial-icon" v-if="cfg.audio.maikiwiAudio.spatial === true"
|
||||||
:title="$root.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization') + ' (' + getProfileLz('CTS', cfg.audio.maikiwiAudio.spatialProfile) + ')'"
|
:title="$root.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization') + ' (' + getProfileLz('CTS', cfg.audio.maikiwiAudio.spatialProfile) + ')'"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
|
@ -149,6 +149,7 @@
|
||||||
:title="$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')"
|
:title="$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
></div>
|
></div>
|
||||||
|
<svg class="audio-type live-icon" v-if="mk.nowPlayingItem?.attributes?.isLive === true" :title="$root.getLz('term.live')" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--keyColor)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" v-b-tooltip.hover><path d="M5 12.55a11 11 0 0 1 14.08 0"></path><path d="M1.42 9a16 16 0 0 1 21.16 0"></path><path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path><line x1="12" y1="20" x2="12.01" y2="20"></line></svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-rect">
|
<div class="info-rect">
|
||||||
<div class="song-name"
|
<div class="song-name"
|
||||||
|
@ -185,7 +186,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="song-progress">
|
<div class="song-progress" v-if="mk.nowPlayingItem?.attributes?.isLive !== true">
|
||||||
<div class="song-duration" style="justify-content: space-between; height: 1px"
|
<div class="song-duration" style="justify-content: space-between; height: 1px"
|
||||||
:style="[chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
:style="[chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
||||||
<p style="width: auto">{{ convertTime(getSongProgress()) }}</p>
|
<p style="width: auto">{{ convertTime(getSongProgress()) }}</p>
|
||||||
|
@ -277,10 +278,10 @@
|
||||||
<div class="app-chrome-item search">
|
<div class="app-chrome-item search">
|
||||||
<div class="search-input-container">
|
<div class="search-input-container">
|
||||||
<div class="search-input--icon"></div>
|
<div class="search-input--icon"></div>
|
||||||
<input type="search" spellcheck="false" @click="$root.appRoute('search');"
|
<input type="search" spellcheck="false" @click="$root.appRoute('search');search.showHints = true"
|
||||||
@focus="search.showHints = true"
|
@focus="search.showHints = true"
|
||||||
@blur="setTimeout(()=>{search.showHints = false}, 300)"
|
@blur="setTimeout(()=>{if(hintscontext != true){search.showHints = false} }, 300)"
|
||||||
v-on:keyup.enter="searchQuery();search.showHints = false;search.cursor = -1" @change="$root.appRoute('search');"
|
v-on:keyup.enter="searchQuery(search.hints[search.cursor]?.content ?? search.hints[search.cursor]?.searchTerm ?? search.term);search.showHints = false;search.showSearchView = true;search.cursor = -1" @change="$root.appRoute('search');"
|
||||||
v-on:keyup="searchCursor"
|
v-on:keyup="searchCursor"
|
||||||
@input="getSearchHints()"
|
@input="getSearchHints()"
|
||||||
:placeholder="$root.getLz('term.search') + '...'" v-model="search.term" ref="searchInput"
|
:placeholder="$root.getLz('term.search') + '...'" v-model="search.term" ref="searchInput"
|
||||||
|
@ -288,10 +289,13 @@
|
||||||
|
|
||||||
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
|
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
|
||||||
<div class="search-hints">
|
<div class="search-hints">
|
||||||
<button class="search-hint text-overflow-elipsis" :class="{active: (search.cursor == index)}" v-for="(hint, index) in search.hints"
|
<button class="search-hint text-overflow-elipsis" :class="{active: (search.cursor == index)}" v-for="(hint, index) in search.hints.filter((a) => {return a.content == null})"
|
||||||
@click="search.term = hint;search.showHints = false;searchQuery(hint);search.cursor = -1">
|
@click="search.term = hint.searchTerm;search.showHints = false;searchQuery(hint.searchTerm);search.cursor = -1">
|
||||||
{{ hint }}
|
{{ hint.displayTerm }}
|
||||||
</button>
|
</button>
|
||||||
|
<template v-for="(item, position) in search.hints.filter((a) => {return a.content != null})">
|
||||||
|
<mediaitem-smarthints :item="item.content" :position="position"> </mediaitem-smarthints>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<div class="name">{{app.getLz('action.createPlaylist')}}</div>
|
<div class="name">{{app.getLz('action.createPlaylist')}}</div>
|
||||||
</button>
|
</button>
|
||||||
<sidebar-playlist :playlist-select="playlistSelect" :relate-media-items="relateItems"
|
<sidebar-playlist :playlist-select="playlistSelect" :relate-media-items="relateItems"
|
||||||
v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')" :item="item">
|
v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')" v-bind:key="item.id" :item="item">
|
||||||
</sidebar-playlist>
|
</sidebar-playlist>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-search">
|
<div class="modal-search">
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
},
|
},
|
||||||
enterPassword() {
|
enterPassword() {
|
||||||
console.log('Entered passCode: ', this.passcode)
|
console.log('Entered passCode: ', this.passcode)
|
||||||
ipcRenderer.send("setAirPlayPasscode", this.passcode)
|
ipcRenderer.send("setAirPlayPasscode", this.passcode, this.$root.currentAirPlayCodeID)
|
||||||
this.close()
|
this.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,13 @@
|
||||||
<small>{{ device.host }}</small>
|
<small>{{ device.host }}</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment_auto"
|
<div class="md-option-segment_auto"
|
||||||
style="display: flex;justify-content: center;align-items: center"
|
style="display: flex;justify-content: center;align-items: center" @click="disconnectAirPlayCast(device)"
|
||||||
v-if="activeCasts.some(item => { return item.host == device.host && item.name == device.name && item.port == device.port})">
|
v-if="activeCasts.some(item => { return item.host == device.host && item.name == device.name && item.port == device.port})">
|
||||||
Connected
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20px" height="20px" viewBox="0 0 20 20" version="1.1">
|
||||||
|
<g id="surface1">
|
||||||
|
<path style="stroke:none;fill-rule:evenodd;fill:#fff;fill-opacity:1;" d="M 10 0 C 15.523438 0 20 4.476562 20 10 C 20 15.523438 15.523438 20 10 20 C 4.476562 20 0 15.523438 0 10 C 0 4.476562 4.476562 0 10 0 Z M 12.136719 5.988281 C 12.421875 5.703125 12.597656 5.472656 12.953125 5.828125 L 14.089844 6.988281 C 14.464844 7.355469 14.445312 7.570312 14.089844 7.914062 L 11.933594 10.0625 L 14.011719 12.136719 C 14.296875 12.421875 14.527344 12.597656 14.171875 12.953125 L 13.011719 14.089844 C 12.644531 14.464844 12.429688 14.445312 12.089844 14.089844 L 10 12 L 7.914062 14.082031 C 7.574219 14.433594 7.359375 14.453125 6.992188 14.082031 L 5.828125 12.945312 C 5.472656 12.59375 5.703125 12.417969 5.992188 12.128906 L 8.066406 10.0625 L 5.917969 7.917969 C 5.566406 7.574219 5.546875 7.359375 5.917969 6.992188 L 7.054688 5.828125 C 7.40625 5.472656 7.582031 5.703125 7.871094 5.992188 L 10 8.128906 Z M 12.136719 5.988281 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment_auto" v-else
|
<div class="md-option-segment_auto" v-else
|
||||||
style="display: flex;justify-content: center;align-items: center">
|
style="display: flex;justify-content: center;align-items: center">
|
||||||
|
@ -135,8 +139,27 @@
|
||||||
ipcRenderer.send('performGCCast', device, "Cider", "Playing ...", "Test build", '');
|
ipcRenderer.send('performGCCast', device, "Cider", "Playing ...", "Test build", '');
|
||||||
},
|
},
|
||||||
setAirPlayCast(device) {
|
setAirPlayCast(device) {
|
||||||
|
if (!this.activeCasts.some(item => { return item.host == device.host && item.name == device.name && item.port == device.port})) {
|
||||||
this.activeCasts.push(device);
|
this.activeCasts.push(device);
|
||||||
ipcRenderer.send("performAirplayPCM", device.host, device.port, null, "", "", "", "", device.txt, device.airplay2)
|
ipcRenderer.send("performAirplayPCM", device.host, device.port, null, "", "", "", "", device.txt, device.airplay2, false)}
|
||||||
|
},
|
||||||
|
disconnectAirPlayCast(device) {
|
||||||
|
app.confirm("Do you want to disconnect this device?",(res) => {
|
||||||
|
if (res){
|
||||||
|
ipcRenderer.send('disconnectAirplay', device.host +":"+ device.port+"ap");
|
||||||
|
console.log('disconnectAirplay', device.host +":"+ device.port+"ap")
|
||||||
|
let idx = this.activeCasts.findIndex(((a) => {return a.host == device.host && a.port == device.port}))
|
||||||
|
console.log(idx)
|
||||||
|
if (idx != -1) {
|
||||||
|
delete this.activeCasts[idx]
|
||||||
|
delete this.$root.activeCasts[idx]
|
||||||
|
this.activeCasts = this.activeCasts.filter(a => {return !(a.host == device.host && a.port == device.port)})
|
||||||
|
console.log(this.activeCasts)
|
||||||
|
if (this.activeCasts.length == 0){
|
||||||
|
this.stopCasting()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
stopCasting() {
|
stopCasting() {
|
||||||
CiderAudio.stopAudio();
|
CiderAudio.stopAudio();
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row fs-row" v-if="tabMode != 'catalog'">
|
<div class="row fs-row" v-if="tabMode != 'catalog'">
|
||||||
<div class="col artwork-col">
|
<div class="col artwork-col">
|
||||||
<div class="artwork" @click="app.fullscreen(false)">
|
<div class="artwork" :class="$root.mk.isPlaying && 'playing'" @click="app.fullscreen(false)">
|
||||||
<mediaitem-artwork
|
<mediaitem-artwork
|
||||||
:size="600"
|
:size="600"
|
||||||
:video="video"
|
:video="video"
|
||||||
|
|
|
@ -11,4 +11,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<div v-for="items in itemPages">
|
<div v-for="items in itemPages">
|
||||||
<mediaitem-list-item
|
<mediaitem-list-item
|
||||||
v-for="(song, index) in items" :show-library-status="showLibraryStatus"
|
v-for="(song, index) in items" :show-library-status="showLibraryStatus"
|
||||||
|
v-bind:key="song.id"
|
||||||
:parent="'listitem-hr' + simplifiedParent"
|
:parent="'listitem-hr' + simplifiedParent"
|
||||||
:index="song.index"
|
:index="song.index"
|
||||||
:item="song"></mediaitem-list-item>
|
:item="song"></mediaitem-list-item>
|
||||||
|
|
|
@ -494,6 +494,10 @@
|
||||||
"name": `${app.getLz('action.share')} (song.link)`,
|
"name": `${app.getLz('action.share')} (song.link)`,
|
||||||
"action": async function() {
|
"action": async function() {
|
||||||
let item = self.item
|
let item = self.item
|
||||||
|
if(item.type.startsWith('library-')) {
|
||||||
|
self.item.attributes.url = self.item.relationships.catalog.data[0].attributes.url
|
||||||
|
item.attributes.url = item.relationships.catalog.data[0].attributes.url
|
||||||
|
}
|
||||||
if (!item.attributes.url) {
|
if (!item.attributes.url) {
|
||||||
if (item.type.includes("library")) {
|
if (item.type.includes("library")) {
|
||||||
let result = (await app.mk.api.v3.music(`/v1/me/library/${item.type.replace("library-", '')}/${item.id}/catalog`)).data.data[0]
|
let result = (await app.mk.api.v3.music(`/v1/me/library/${item.type.replace("library-", '')}/${item.id}/catalog`)).data.data[0]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script type="text/x-template" id="mediaitem-mvview-sp">
|
<script type="text/x-template" id="mediaitem-mvview-sp">
|
||||||
<div style="position: relative; display: inline-flex;">
|
<div v-if="(item.attributes?.editorialArtwork?.subscriptionHero?.url ?? item.attributes?.artwork?.url ?? '') !='' " style="position: relative; display: inline-flex;">
|
||||||
<div @click.self='log(item);app.routeView(item)'
|
<div @click.self='log(item);app.routeView(item)'
|
||||||
class="cd-mediaitem-mvview">
|
class="cd-mediaitem-mvview">
|
||||||
<div style="height: 70px; min-height: 70px; max-height: 70px; width: 100%; margin-left: 5px;">
|
<div style="height: 70px; min-height: 70px; max-height: 70px; width: 100%; margin-left: 5px;">
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="artwork">
|
<div class="artwork">
|
||||||
<mediaitem-artwork
|
<mediaitem-artwork
|
||||||
:url="item.attributes?.editorialArtwork.subscriptionHero.url ?? item.attributes?.artwork"
|
:url="item.attributes?.editorialArtwork?.subscriptionHero?.url ?? item.attributes?.artwork?.url"
|
||||||
:video="(item.attributes != null && item.attributes?.editorialVideo != null) ? (item.attributes?.editorialVideo?.motionDetailSquare ? item.attributes?.editorialVideo?.motionDetailSquare?.video : (item.attributes?.editorialVideo?.motionSquareVideo1x1 ? item?.attributes?.editorialVideo?.motionSquareVideo1x1?.video : '')) : '' "
|
:video="(item.attributes != null && item.attributes?.editorialVideo != null) ? (item.attributes?.editorialVideo?.motionDetailSquare ? item.attributes?.editorialVideo?.motionDetailSquare?.video : (item.attributes?.editorialVideo?.motionSquareVideo1x1 ? item?.attributes?.editorialVideo?.motionSquareVideo1x1?.video : '')) : '' "
|
||||||
:size="516" :width="900"
|
:size="516" :width="900"
|
||||||
></mediaitem-artwork>
|
></mediaitem-artwork>
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
((item?.attributes?.kind != null || item?.attributes?.type == 'editorial-elements')
|
((item?.attributes?.kind != null || item?.attributes?.type == 'editorial-elements')
|
||||||
? item :
|
? item :
|
||||||
((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) ?? (item)"
|
((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) ?? (item)"
|
||||||
:imagesize="imagesize"
|
:imagesize="imagesize" v-bind:key="item.id"
|
||||||
:badge="item.attributes ?? [] " v-for="item in items"></mediaitem-mvview-sp>
|
:badge="item.attributes ?? [] " v-for="item in items"></mediaitem-mvview-sp>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<mediaitem-square :kind="kind" size="600" :key="item?.id ?? ''"
|
<mediaitem-square :kind="kind" size="600" :key="item?.id ?? ''"
|
||||||
:item="item ? ((item.attributes?.kind != null || item.type == 'editorial-elements') ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
|
:item="item ? ((item.attributes?.kind != null || item.type == 'editorial-elements') ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
|
||||||
:imagesize="imagesize"
|
:imagesize="imagesize"
|
||||||
|
v-bind:key="item.id"
|
||||||
v-for="item in items"></mediaitem-square>
|
v-for="item in items"></mediaitem-square>
|
||||||
</template>
|
</template>
|
||||||
</vue-horizontal>
|
</vue-horizontal>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="cd-hmedia-scroller hmedia-scroller-card">
|
<div class="cd-hmedia-scroller hmedia-scroller-card">
|
||||||
<vue-horizontal>
|
<vue-horizontal>
|
||||||
<template>
|
<template>
|
||||||
<mediaitem-square kind="card" :item="item" size="300" :reasonShown="withReason"
|
<mediaitem-square kind="card" :item="item" size="300" :reasonShown="withReason" v-bind:key="item.id"
|
||||||
v-for="item in items"></mediaitem-square>
|
v-for="item in items"></mediaitem-square>
|
||||||
</template>
|
</template>
|
||||||
</vue-horizontal>
|
</vue-horizontal>
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<%- include("../svg/play.svg") %>
|
<%- include("../svg/play.svg") %>
|
||||||
</button>
|
</button>
|
||||||
<div class="badge-container" v-if="itemBadges.length != 0">
|
<div class="badge-container" v-if="itemBadges.length != 0">
|
||||||
<div class="socialBadge" v-for="badge in itemBadges.limit(1)">
|
<div class="socialBadge" v-for="badge in itemBadges.limit(1)" v-bind:key="badge.id">
|
||||||
<mediaitem-artwork
|
<mediaitem-artwork
|
||||||
:url="(badge.attributes.artwork ? badge.attributes.artwork.url : '')"
|
:url="(badge.attributes.artwork ? badge.attributes.artwork.url : '')"
|
||||||
:size="32"></mediaitem-artwork>
|
:size="32"></mediaitem-artwork>
|
||||||
|
@ -45,9 +45,9 @@
|
||||||
<div class="title"
|
<div class="title"
|
||||||
:title="item.attributes?.name ?? (item.relationships?.contents?.data[0]?.attributes?.name ?? (item.attributes?.editorialNotes?.name ?? ''))"
|
:title="item.attributes?.name ?? (item.relationships?.contents?.data[0]?.attributes?.name ?? (item.attributes?.editorialNotes?.name ?? ''))"
|
||||||
v-if="item.attributes.artistNames == null || kind != 'card'" @click='app.routeView(item)'>
|
v-if="item.attributes.artistNames == null || kind != 'card'" @click='app.routeView(item)'>
|
||||||
<div class="item-navigate text-overflow-elipsis">{{ item.attributes?.name.replace(/ /g, ' ').replace(/Apple Music |^Apple |/g, '') ??
|
<div class="item-navigate text-overflow-elipsis">{{ (item.attributes?.editorialElementKind == "394" && item.relationships?.contents?.data[0]?.attributes?.shortName != null ) ? item.relationships?.contents?.data[0]?.attributes?.shortName : (item.attributes?.name ? ((removeamtext ) ? item.attributes?.name.replace(/ /g, ' ').replace(/Apple Music |^Apple |/g, '') : item.attributes?.name.replace(/ /g, ' ')) :
|
||||||
(item.relationships?.contents?.data[0]?.attributes?.name ??
|
(item.relationships?.contents?.data[0]?.attributes?.name ??
|
||||||
(item.attributes?.editorialNotes?.name ?? '')) }}
|
(item.attributes?.editorialNotes?.name ?? ''))) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="explicit-icon" v-if="item.attributes && item.attributes.contentRating == 'explicit'"
|
<div class="explicit-icon" v-if="item.attributes && item.attributes.contentRating == 'explicit'"
|
||||||
style="background-image: url(./assets/explicit.svg);height: 12px;width: 12px;filter: contrast(0);background-repeat: no-repeat;margin-top: 2.63px;margin-left: 4px;"></div>
|
style="background-image: url(./assets/explicit.svg);height: 12px;width: 12px;filter: contrast(0);background-repeat: no-repeat;margin-top: 2.63px;margin-left: 4px;"></div>
|
||||||
|
@ -98,6 +98,11 @@ Vue.component('mediaitem-square', {
|
||||||
default: 'cc',
|
default: 'cc',
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
removeamtext: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
'contextExt': { type: Object, required: false },
|
'contextExt': { type: Object, required: false },
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
|
@ -571,7 +576,7 @@ Vue.component('mediaitem-square', {
|
||||||
icon: "./assets/feather/play.svg",
|
icon: "./assets/feather/play.svg",
|
||||||
name: app.getLz('action.startRadio'),
|
name: app.getLz('action.startRadio'),
|
||||||
action: () => {
|
action: () => {
|
||||||
app.mk.setStationQueue({ artist: this.item.id }).then(() => {
|
app.mk.setStationQueue({ artist: 'a-'+this.item.id }).then(() => {
|
||||||
app.mk.play()
|
app.mk.play()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -581,7 +586,7 @@ Vue.component('mediaitem-square', {
|
||||||
icon: "./assets/feather/share.svg",
|
icon: "./assets/feather/share.svg",
|
||||||
name: app.getLz('term.share'),
|
name: app.getLz('term.share'),
|
||||||
action: () => {
|
action: () => {
|
||||||
self.app.copyToClipboard(this.item.id.attributes.url)
|
self.app.copyToClipboard(this.item.attributes.url)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script type="text/x-template" id="cider-menu-panel">
|
<script type="text/x-template" id="cider-menu-panel">
|
||||||
<div class="menu-panel" @click.self="menuPanel.visible = false" @contextmenu.self="menuPanel.visible = false">
|
<div class="menu-panel" @click.self="menuPanel.visible = false; if($root.hintscontext){$root.hintscontext = false;focusOther()}" @contextmenu.self="menuPanel.visible = false; if($root.hintscontext){$root.hintscontext = false;focusOther()}">
|
||||||
|
|
||||||
<div class="menu-panel-body" ref="menubody" :style="elStyle" :class="getBodyClasses()">
|
<div class="menu-panel-body" ref="menubody" :style="elStyle" :class="getBodyClasses()">
|
||||||
<div class="menu-header-text" v-if="content.name != ''">
|
<div class="menu-header-text" v-if="content.name != ''">
|
||||||
|
@ -56,12 +56,22 @@
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.event) {
|
if (this.event) {
|
||||||
this.position = [this.event.clientX, this.event.clientY];
|
this.position = [this.event.clientX, this.event.clientY];
|
||||||
}
|
this.$nextTick(() => {
|
||||||
this.$nextTick(() => {
|
|
||||||
// this.size = [document.querySelector(".menu-panel-body").offsetWidth, document.querySelector(".menu-panel-body").offsetHeight];
|
// this.size = [document.querySelector(".menu-panel-body").offsetWidth, document.querySelector(".menu-panel-body").offsetHeight];
|
||||||
// ugly hack
|
// ugly hack
|
||||||
setTimeout(this.getStyle, 1)
|
setTimeout(this.getStyle, 0.8)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.addEventListener('mouseover', event => {
|
||||||
|
this.event = event
|
||||||
|
this.position = [event.clientX, event.clientY]
|
||||||
|
console.log("pos", this.position)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
setTimeout(this.getStyle, 0.8)})
|
||||||
|
},{once: true})
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getBodyClasses() {
|
getBodyClasses() {
|
||||||
|
@ -78,6 +88,9 @@
|
||||||
return "active";
|
return "active";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
focusOther(){
|
||||||
|
document.querySelector('.search-input-container input').focus()
|
||||||
|
},
|
||||||
getStyle() {
|
getStyle() {
|
||||||
let style = {}
|
let style = {}
|
||||||
this.size = [this.$refs.menubody.offsetWidth, this.$refs.menubody.offsetHeight];
|
this.size = [this.$refs.menubody.offsetWidth, this.$refs.menubody.offsetHeight];
|
||||||
|
@ -132,7 +145,7 @@
|
||||||
action(item) {
|
action(item) {
|
||||||
item.action()
|
item.action()
|
||||||
if (!item["keepOpen"]) {
|
if (!item["keepOpen"]) {
|
||||||
this.menuPanel.visible = false
|
this.menuPanel.visible = false;if(app.hintscontext){ app.hintscontext = false; document.querySelector('.search-input-container input').focus(); app.search.showHints = false}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="queue-body" v-if="page == 'history'">
|
<div class="queue-body" v-if="page == 'history'">
|
||||||
<mediaitem-list-item :show-library-status="false" v-for="item in history"
|
<mediaitem-list-item :show-library-status="false" v-for="item in history"
|
||||||
|
v-bind:key="item.id"
|
||||||
:item="item"></mediaitem-list-item>
|
:item="item"></mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="queue-body" v-if="page == 'queue'">
|
<div class="queue-body" v-if="page == 'queue'">
|
||||||
|
|
|
@ -471,6 +471,22 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="md-option-line">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
{{'Display Style'}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<select class="md-select"
|
||||||
|
v-model="$root.cfg.visual.overrideDisplayTheme"
|
||||||
|
@change="changeDisplayTheme">
|
||||||
|
<option value="system">System</option>
|
||||||
|
<option value="dark">Dark</option>
|
||||||
|
<option value="light">Light</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="md-option-line">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.visual.windowBackgroundStyle')}}
|
{{$root.getLz('settings.option.visual.windowBackgroundStyle')}}
|
||||||
|
@ -905,95 +921,128 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
||||||
<div class="md-option-segment">
|
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.clientName')}}
|
|
||||||
</div>
|
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<label>
|
|
||||||
<select class="md-select" v-model="app.cfg.connectivity.discord_rpc.client">
|
|
||||||
<option value="Cider">{{$root.getLz('app.name')}}</option>
|
|
||||||
<option value="AppleMusic">{{$root.getLz('term.appleMusic')}}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.clearOnPause')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.reload')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<button class="md-btn" @click="reloadDiscordRPC()">
|
||||||
|
{{$root.getLz('menubar.options.reload')}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
v-model="app.cfg.connectivity.discord_rpc.clear_on_pause" switch />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.hideButtons')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.clientName')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<select class="md-select" v-model="app.cfg.connectivity.discord_rpc.client">
|
||||||
|
<option value="Cider">{{$root.getLz('app.name')}}</option>
|
||||||
|
<option value="AppleMusic">{{$root.getLz('term.appleMusic')}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
v-model="app.cfg.connectivity.discord_rpc.hide_buttons" switch />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.hideTimestamp')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.clearOnPause')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox"
|
||||||
|
v-model="app.cfg.connectivity.discord_rpc.clear_on_pause" switch />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
v-model="app.cfg.connectivity.discord_rpc.hide_timestamp" switch />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.detailsFormat')}}<br />
|
{{$root.getLz('settings.option.connectivity.discordRPC.hideTimestamp')}}
|
||||||
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title},
|
</div>
|
||||||
{album},
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
{trackNumber}</small>
|
<label>
|
||||||
|
<input type="checkbox"
|
||||||
|
v-model="app.cfg.connectivity.discord_rpc.activity.hide_timestamp" switch />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<label>
|
|
||||||
<input type="text"
|
|
||||||
v-model="app.cfg.connectivity.discord_rpc.details_format" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.stateFormat')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.detailsFormat')}}<br />
|
||||||
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title},
|
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title},
|
||||||
{album},
|
{album},
|
||||||
{trackNumber}</small>
|
{trackNumber}</small>
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="text"
|
||||||
|
v-model="app.cfg.connectivity.discord_rpc.activity.details_format" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<label>
|
|
||||||
<input type="text"
|
|
||||||
v-model="app.cfg.connectivity.discord_rpc.state_format" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.enabled != false">
|
<div class="md-option-line">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.discordRPC.reload')}}
|
{{$root.getLz('settings.option.connectivity.discordRPC.stateFormat')}}
|
||||||
|
<small>{{$root.getLz('term.variables')}}: {artist}, {composer}, {title},
|
||||||
|
{album},
|
||||||
|
{trackNumber}</small>
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="text"
|
||||||
|
v-model="app.cfg.connectivity.discord_rpc.activity.state_format" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
|
||||||
<button class="md-btn" @click="reloadDiscordRPC()">
|
<div class="md-option-line">
|
||||||
{{$root.getLz('menubar.options.reload')}}
|
<div class="md-option-segment">
|
||||||
</button>
|
{{$root.getLz('settings.option.connectivity.discordRPC.showActivityButtons')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox"
|
||||||
|
v-model="app.cfg.connectivity.discord_rpc.activity.buttons.enabled" switch />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="app.cfg.connectivity.discord_rpc.activity.buttons.enabled == true">
|
||||||
|
<div class="md-option-line">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
{{$root.getLz('settings.option.connectivity.discordRPC.firstButton')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<select class="md-select" v-model="app.cfg.connectivity.discord_rpc.activity.buttons.first" @change="if ($event.target.value == 'disabled') app.cfg.connectivity.discord_rpc.activity.buttons.second = 'disabled';">
|
||||||
|
<option v-for="option in app.cfg.connectivity.discord_rpc.activity.buttons.options" v-bind:value="option" v-show="app.cfg.connectivity.discord_rpc.activity.buttons.second != option">{{ $root.getLz(`settings.option.connectivity.discordRPC.buttons.${option}`) }}</option>
|
||||||
|
<option value="disabled">{{$root.getLz('term.disabled')}}</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="md-option-line" v-show="app.cfg.connectivity.discord_rpc.activity.buttons.first != 'disabled'">
|
||||||
|
<div class="md-option-segment">
|
||||||
|
{{$root.getLz('settings.option.connectivity.discordRPC.secondButton')}}
|
||||||
|
</div>
|
||||||
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
|
<label>
|
||||||
|
<select class="md-select" v-model="app.cfg.connectivity.discord_rpc.activity.buttons.second">
|
||||||
|
<option v-for="option in app.cfg.connectivity.discord_rpc.activity.buttons.options" v-bind:value="option" v-show="app.cfg.connectivity.discord_rpc.activity.buttons.first != option">{{ $root.getLz(`settings.option.connectivity.discordRPC.buttons.${option}`) }}</option>
|
||||||
|
<option value="disabled">{{$root.getLz('term.disabled')}}</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1069,11 +1118,12 @@
|
||||||
<div class="md-option-line" v-show="app.cfg.connectivity.lastfm.enabled">
|
<div class="md-option-line" v-show="app.cfg.connectivity.lastfm.enabled">
|
||||||
<div class="md-option-segment">
|
<div class="md-option-segment">
|
||||||
{{$root.getLz('settings.option.connectivity.lastfmScrobble.filterTypes')}}
|
{{$root.getLz('settings.option.connectivity.lastfmScrobble.filterTypes')}}
|
||||||
|
<small>{{$root.getLz('settings.option.connectivity.lastfmScrobble.filterTypes.description')}}</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-option-segment md-option-segment_auto">
|
<div class="md-option-segment md-option-segment_auto">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" @change="filterChange" value="song">{{$root.getLz('term.songs')}}<br>
|
<input type="checkbox" v-model="app.cfg.connectivity.lastfm.filter_types['song']">{{$root.getLz('term.songs')}}<br>
|
||||||
<input type="checkbox" @change="filterChange" value="musicVideo">{{$root.getLz('term.musicVideos')}}<br>
|
<input type="checkbox" v-model="app.cfg.connectivity.lastfm.filter_types['musicVideo']">{{$root.getLz('term.musicVideos')}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1442,6 +1492,9 @@
|
||||||
openAppData() {
|
openAppData() {
|
||||||
ipcRenderer.send('open-appdata')
|
ipcRenderer.send('open-appdata')
|
||||||
},
|
},
|
||||||
|
changeDisplayTheme(){
|
||||||
|
ipcRenderer.send('changeDisplayTheme',app.cfg.visual.overrideDisplayTheme)
|
||||||
|
},
|
||||||
getLanguages: function() {
|
getLanguages: function() {
|
||||||
let langs = this.$root.lzListing
|
let langs = this.$root.lzListing
|
||||||
let categories = {
|
let categories = {
|
||||||
|
@ -1508,7 +1561,7 @@
|
||||||
ipcRenderer.send('cc-logout')
|
ipcRenderer.send('cc-logout')
|
||||||
},
|
},
|
||||||
reloadDiscordRPC() {
|
reloadDiscordRPC() {
|
||||||
ipcRenderer.send('reloadRPC')
|
ipcRenderer.send('discordrpc:reload')
|
||||||
},
|
},
|
||||||
lfmDisconnect() {
|
lfmDisconnect() {
|
||||||
this.$root.cfg.connectivity.lastfm.enabled = false;
|
this.$root.cfg.connectivity.lastfm.enabled = false;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="name">{{app.getLz('action.createPlaylist')}}</div>
|
<div class="name">{{app.getLz('action.createPlaylist')}}</div>
|
||||||
</button>
|
</button>
|
||||||
<sidebar-playlist :playlist-select="playlistSelect"
|
<sidebar-playlist :playlist-select="playlistSelect"
|
||||||
v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')" :item="item">
|
v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')" v-bind:key="item.id" :item="item">
|
||||||
</sidebar-playlist>
|
</sidebar-playlist>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-search">
|
<div class="modal-search">
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<div class="folder-body" v-if="item.type === 'library-playlist-folders' && folderOpened">
|
<div class="folder-body" v-if="item.type === 'library-playlist-folders' && folderOpened">
|
||||||
<template v-if="children.length != 0">
|
<template v-if="children.length != 0">
|
||||||
<sidebar-playlist v-for="item in children" :relate-media-items="relateMediaItems"
|
<sidebar-playlist v-for="item in children" :relate-media-items="relateMediaItems"
|
||||||
:playlist-select="playlistSelect" :item="item" :key="item.id"></sidebar-playlist>
|
:playlist-select="playlistSelect" :item="item" v-bind:key="item.id"></sidebar-playlist>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@click="$root.appRoute('search');"
|
@click="$root.appRoute('search');$root.search.showHints = true"
|
||||||
@focus="$root.search.showHints = true"
|
@focus="$root.search.showHints = true"
|
||||||
@blur="$root.setTimeout(()=>{$root.search.showHints = false}, 300)"
|
@blur="$root.setTimeout(()=>{if($root.hintscontext != true){$root.search.showHints = false} }, 300)"
|
||||||
v-on:keyup.enter="$root.searchQuery();$root.search.showHints = false;$root.search.cursor = -1"
|
v-on:keyup.enter="$root.searchQuery($root.search.hints[$root.search.cursor]?.content ?? $root.search.hints[$root.search.cursor]?.searchTerm ?? $root.search.term);$root.search.showHints = false;$root.search.showSearchView = true;$root.search.cursor = -1"
|
||||||
v-on:keyup="$root.searchCursor"
|
v-on:keyup="$root.searchCursor"
|
||||||
@change="$root.appRoute('search');"
|
@change="$root.appRoute('search');"
|
||||||
@input="$root.getSearchHints()"
|
@input="$root.getSearchHints()"
|
||||||
|
@ -27,11 +27,14 @@
|
||||||
<div class="search-hints">
|
<div class="search-hints">
|
||||||
<button
|
<button
|
||||||
class="search-hint text-overflow-elipsis"
|
class="search-hint text-overflow-elipsis"
|
||||||
v-for="hint in $root.search.hints"
|
v-for="(hint, index) in $root.search.hints.filter((a) => {return a.content == null})" :class="{active: ($root.search.cursor == index)}"
|
||||||
@click="$root.search.term = hint;$root.search.showHints = false;$root.searchQuery(hint);$root.search.cursor = -1"
|
@click="$root.search.term = hint.searchTerm;$root.search.showHints = false;$root.searchQuery(hint.searchTerm);$root.search.cursor = -1"
|
||||||
>
|
>
|
||||||
{{ hint }}
|
{{ hint.displayTerm }}
|
||||||
</button>
|
</button>
|
||||||
|
<template v-for="(item, position) in $root.search.hints.filter((a) => {return a.content != null})">
|
||||||
|
<mediaitem-smarthints :item="item.content" :position="position"> </mediaitem-smarthints>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -162,6 +165,7 @@
|
||||||
<template v-if="!$root.cfg.general.sidebarCollapsed.amplaylists">
|
<template v-if="!$root.cfg.general.sidebarCollapsed.amplaylists">
|
||||||
<sidebar-playlist
|
<sidebar-playlist
|
||||||
v-for="item in $root.getPlaylistFolderChildren('p.applemusic')"
|
v-for="item in $root.getPlaylistFolderChildren('p.applemusic')"
|
||||||
|
v-bind:key="item.id"
|
||||||
:item="item"
|
:item="item"
|
||||||
>
|
>
|
||||||
</sidebar-playlist>
|
</sidebar-playlist>
|
||||||
|
@ -184,6 +188,7 @@
|
||||||
</button>
|
</button>
|
||||||
<sidebar-playlist
|
<sidebar-playlist
|
||||||
v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')"
|
v-for="item in $root.getPlaylistFolderChildren('p.playlistsroot')"
|
||||||
|
v-bind:key="item.id"madeforyou
|
||||||
:item="item"
|
:item="item"
|
||||||
>
|
>
|
||||||
</sidebar-playlist>
|
</sidebar-playlist>
|
||||||
|
|
490
src/renderer/views/components/smarthints.ejs
Normal file
490
src/renderer/views/components/smarthints.ejs
Normal file
|
@ -0,0 +1,490 @@
|
||||||
|
<script type="text/x-template" id="mediaitem-smarthints">
|
||||||
|
<div class="cd-queue-item" @click="$root.search.showHints = false;$root.routeView(item);$root.search.cursor = -1;$root.search.term == ''" @contextmenu="$root.hintscontext = true;getContextMenu()"
|
||||||
|
:class="{'hintactive': ($root.search.cursor == position + $root.search.hints.filter((a) => {return a.content == null}).length)}">
|
||||||
|
<div class="row" @contextmenu="$root.hintscontext = true;getContextMenu()">
|
||||||
|
<div class="col-auto cider-flex-center" @contextmenu="$root.hintscontext = true;getContextMenu()">
|
||||||
|
<div class="artwork" :class="{'circle': item.type == 'artists'}">
|
||||||
|
<mediaitem-artwork
|
||||||
|
:url="item.attributes.artwork ? item.attributes.artwork.url : ''"
|
||||||
|
:size="32"
|
||||||
|
:style="{'position': 'relative', 'z-index': '-1'}"
|
||||||
|
></mediaitem-artwork>
|
||||||
|
<button class="circular-play-button" @click.stop="playTrack(item)">
|
||||||
|
<div class="_svg-icon" style="--icon:url(\.\/assets\/play\.svg); width: 15px;">
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col queue-info" @contextmenu="$root.hintscontext = true;getContextMenu()">
|
||||||
|
<div class="queue-title text-overflow-elipsis">{{ item.attributes.name }}
|
||||||
|
</div>
|
||||||
|
<div class="queue-subtitle text-overflow-elipsis">{{
|
||||||
|
item.attributes.artistName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="queue-explicit-icon cider-flex-center"
|
||||||
|
v-if="item.attributes.contentRating == 'explicit'">
|
||||||
|
<div class="explicit-icon"></div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="col queue-duration-info">
|
||||||
|
<div class="queue-duration cider-flex-center">
|
||||||
|
{{convertTimeToString(item.content.attributes.durationInMillis)}}
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
Vue.component('mediaitem-smarthints', {
|
||||||
|
template: '#mediaitem-smarthints',
|
||||||
|
props: {
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
app: this.$root,
|
||||||
|
guid: this.uuidv4(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async isInLibrary() {
|
||||||
|
if (this.item.type && !this.item.type.includes("library")) {
|
||||||
|
let params = {
|
||||||
|
relate: "library",
|
||||||
|
"fields": "inLibrary",
|
||||||
|
"extend": this.revisedRandId()
|
||||||
|
}
|
||||||
|
let kind = this.item.type ?? this.item.attributes.playParams.kind
|
||||||
|
let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
|
||||||
|
if (truekind === "musicVideos") {
|
||||||
|
truekind = "music-videos"
|
||||||
|
}
|
||||||
|
let res = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/?ids[${truekind}]=${this.item.attributes.playParams.id ?? this.item.id}`, params);
|
||||||
|
res = res.data.data[0]
|
||||||
|
this.addedToLibrary = (res && res.attributes && res.attributes.inLibrary) ? res.attributes.inLibrary : false
|
||||||
|
} else {
|
||||||
|
this.addedToLibrary = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
revisedRandId() {
|
||||||
|
return Math.random().toString(36).replace(/[^a-z]+/g, '').slice(2, 10);
|
||||||
|
},
|
||||||
|
uuidv4() {
|
||||||
|
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
||||||
|
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
getContextMenu(event) {
|
||||||
|
if (event){
|
||||||
|
if (this.item.type === "artists") {
|
||||||
|
return this.artistMenu(event)
|
||||||
|
} else {
|
||||||
|
return this.contextMenu(event)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.addEventListener('mouseover', event => {
|
||||||
|
if (this.item.type === "artists") {
|
||||||
|
return this.artistMenu(event)
|
||||||
|
} else {
|
||||||
|
return this.contextMenu(event)
|
||||||
|
}
|
||||||
|
},{once: true})}
|
||||||
|
|
||||||
|
},
|
||||||
|
async contextMenu(event) {
|
||||||
|
let self = this
|
||||||
|
let useMenu = "normal"
|
||||||
|
if (app.selectedMediaItems.length <= 1) {
|
||||||
|
app.selectedMediaItems = []
|
||||||
|
app.select_selectMediaItem(this.item.attributes.playParams.id ?? this.item.id, this.item.attributes.playParams.kind ?? this.item.type, this.index, this.guid, this.item.attributes.playParams.isLibrary ?? false)
|
||||||
|
} else {
|
||||||
|
useMenu = "multiple"
|
||||||
|
}
|
||||||
|
let menus = {
|
||||||
|
multiple: {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: app.getLz('action.playTracksNext').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||||
|
"icon": "./assets/arrow-bend-up.svg",
|
||||||
|
action: () => {
|
||||||
|
let itemsToPlay = {}
|
||||||
|
app.selectedMediaItems.forEach(item => {
|
||||||
|
if (!itemsToPlay[item.kind]) {
|
||||||
|
itemsToPlay[item.kind] = []
|
||||||
|
}
|
||||||
|
itemsToPlay[item.kind].push(item.id)
|
||||||
|
})
|
||||||
|
// loop through itemsToPlay
|
||||||
|
for (let kind in itemsToPlay) {
|
||||||
|
let ids = itemsToPlay[kind]
|
||||||
|
if (ids.length > 0) {
|
||||||
|
app.mk.playNext({ [kind + "s"]: itemsToPlay[kind] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(itemsToPlay)
|
||||||
|
app.selectedMediaItems = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: app.getLz('action.playTracksLater').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||||
|
"icon": "./assets/arrow-bend-down.svg",
|
||||||
|
action: () => {
|
||||||
|
let itemsToPlay = {}
|
||||||
|
app.selectedMediaItems.forEach(item => {
|
||||||
|
if (!itemsToPlay[item.kind]) {
|
||||||
|
itemsToPlay[item.kind] = []
|
||||||
|
}
|
||||||
|
itemsToPlay[item.kind].push(item.id)
|
||||||
|
})
|
||||||
|
// loop through itemsToPlay
|
||||||
|
for (let kind in itemsToPlay) {
|
||||||
|
let ids = itemsToPlay[kind]
|
||||||
|
if (ids.length > 0) {
|
||||||
|
app.mk.playLater({ [kind + "s"]: itemsToPlay[kind] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.selectedMediaItems = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
normal: {
|
||||||
|
headerItems: [
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/heart.svg",
|
||||||
|
"id": "love",
|
||||||
|
"name": app.getLz('action.love'),
|
||||||
|
"hidden": false,
|
||||||
|
"disabled": true,
|
||||||
|
"action": function () {
|
||||||
|
app.love(self.item)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/heart.svg",
|
||||||
|
"id": "unlove",
|
||||||
|
"active": true,
|
||||||
|
"name": app.getLz('action.unlove'),
|
||||||
|
"hidden": true,
|
||||||
|
"action": function () {
|
||||||
|
app.unlove(self.item)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/thumbs-down.svg",
|
||||||
|
"id": "dislike",
|
||||||
|
"name": app.getLz('action.dislike'),
|
||||||
|
"hidden": false,
|
||||||
|
"disabled": true,
|
||||||
|
"action": function () {
|
||||||
|
app.dislike(self.item)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/thumbs-down.svg",
|
||||||
|
"id": "undo_dislike",
|
||||||
|
"name": app.getLz('action.undoDislike'),
|
||||||
|
"active": true,
|
||||||
|
"hidden": true,
|
||||||
|
"action": function () {
|
||||||
|
app.unlove(self.item)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/list.svg",
|
||||||
|
"id": "addToPlaylist",
|
||||||
|
"name": app.getLz('action.addToPlaylist'),
|
||||||
|
"action": function () {
|
||||||
|
app.promptAddToPlaylist()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "addToLibrary",
|
||||||
|
"icon": "./assets/feather/plus.svg",
|
||||||
|
"name": app.getLz('action.addToLibrary'),
|
||||||
|
"hidden": false,
|
||||||
|
"disabled": true,
|
||||||
|
"action": function () {
|
||||||
|
let item_id = self.item.attributes.playParams.id ?? self.item.id;
|
||||||
|
let data_type = self.item.attributes.playParams.kind ?? self.item.type;
|
||||||
|
app.addToLibrary(item_id);
|
||||||
|
self.addedToLibrary = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "removeFromLibrary",
|
||||||
|
"icon": "./assets/feather/x-circle.svg",
|
||||||
|
"name": app.getLz('action.removeFromLibrary'),
|
||||||
|
"hidden": true,
|
||||||
|
"action": async function () {
|
||||||
|
console.log("remove");
|
||||||
|
let item_id = self.item.attributes.playParams.id ?? self.item.id;
|
||||||
|
let data_type = self.item.attributes.playParams.kind ?? self.item.type;
|
||||||
|
await self.removeFromLibrary(item_id);
|
||||||
|
self.addedToLibrary = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": app.getLz('action.playNext'),
|
||||||
|
"icon": "./assets/arrow-bend-up.svg",
|
||||||
|
"action": function () {
|
||||||
|
app.mk.playNext({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id })
|
||||||
|
app.mk.queue._reindex()
|
||||||
|
app.selectedMediaItems = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": app.getLz('action.playLater'),
|
||||||
|
"icon": "./assets/arrow-bend-down.svg",
|
||||||
|
"action": function () {
|
||||||
|
app.mk.playLater({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id })
|
||||||
|
app.mk.queue._reindex()
|
||||||
|
app.selectedMediaItems = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/share.svg",
|
||||||
|
"name": app.getLz('action.share'),
|
||||||
|
"action": function () {
|
||||||
|
if (!self.item.attributes.url && self.item.relationships) {
|
||||||
|
if (self.item.relationships.catalog) {
|
||||||
|
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {
|
||||||
|
self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.app.copyToClipboard(self.item.attributes.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "./assets/feather/share.svg",
|
||||||
|
"name": `${app.getLz('action.share')} (song.link)`,
|
||||||
|
"action": function () {
|
||||||
|
if (!self.item.attributes.url && self.item.relationships) {
|
||||||
|
if (self.item.relationships.catalog) {
|
||||||
|
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {
|
||||||
|
self.app.songLinkShare((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.app.songLinkShare(self.item.attributes.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((self.item.attributes.playParams.kind ?? self.item.type).includes("playlist")) {
|
||||||
|
// remove the add to playlist option by id "addToPlaylist" using the .filter() method
|
||||||
|
menus.normal.items = menus.normal.items.filter(function (item) {
|
||||||
|
return item.id != "addToPlaylist"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
app.showMenuPanel(menus[useMenu], event)
|
||||||
|
try {
|
||||||
|
await this.isInLibrary().then((_) => {
|
||||||
|
if (self.addedToLibrary) {
|
||||||
|
menus.normal.items.find(x => x.id == 'addToLibrary').hidden = true
|
||||||
|
menus.normal.items.find(x => x.id == 'removeFromLibrary').hidden = false
|
||||||
|
} else {
|
||||||
|
menus.normal.items.find(x => x.id == 'addToLibrary').disabled = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let rating = await app.getRating(self.item)
|
||||||
|
if (rating == 0) {
|
||||||
|
menus.normal.headerItems.find(x => x.id == 'love').disabled = false
|
||||||
|
menus.normal.headerItems.find(x => x.id == 'dislike').disabled = false
|
||||||
|
} else if (rating == 1) {
|
||||||
|
menus.normal.headerItems.find(x => x.id == 'unlove').hidden = false
|
||||||
|
menus.normal.headerItems.find(x => x.id == 'love').hidden = true
|
||||||
|
} else if (rating == -1) {
|
||||||
|
menus.normal.headerItems.find(x => x.id == 'undo_dislike').hidden = false
|
||||||
|
menus.normal.headerItems.find(x => x.id == 'dislike').hidden = true
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.contextExt) {
|
||||||
|
if (this.contextExt.normal) {
|
||||||
|
menus.normal.items = menus.normal.items.concat(this.contextExt.normal)
|
||||||
|
}
|
||||||
|
if (this.contextExt.multiple) {
|
||||||
|
menus.multiple.items = menus.multiple.items.concat(this.contextExt.multiple)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async artistMenu(event) {
|
||||||
|
let self = this
|
||||||
|
let followAction = "follow"
|
||||||
|
let followActions = {
|
||||||
|
follow: {
|
||||||
|
icon: "./assets/star.svg",
|
||||||
|
name: app.getLz('action.favorite'),
|
||||||
|
action: () => {
|
||||||
|
self.$root.setArtistFavorite(this.item.id, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unfollow: {
|
||||||
|
icon: "./assets/star.svg",
|
||||||
|
name: app.getLz('action.removeFavorite'),
|
||||||
|
action: () => {
|
||||||
|
self.$root.setArtistFavorite(this.item.id, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self.app.cfg.home.followedArtists.includes(this.item.id)) {
|
||||||
|
followAction = "unfollow"
|
||||||
|
}
|
||||||
|
app.showMenuPanel({
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
icon: "./assets/feather/play.svg",
|
||||||
|
name: app.getLz('action.startRadio'),
|
||||||
|
action: () => {
|
||||||
|
app.mk.setStationQueue({ artist: 'a-'+this.item.id }).then(() => {
|
||||||
|
app.mk.play()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
followActions[followAction],
|
||||||
|
{
|
||||||
|
icon: "./assets/feather/share.svg",
|
||||||
|
name: app.getLz('term.share'),
|
||||||
|
action: () => {
|
||||||
|
self.app.copyToClipboard(this.item.attributes.url)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "./assets/feather/external-link.svg",
|
||||||
|
name: app.getLz('action.openArtworkInBrowser'),
|
||||||
|
action: () => {
|
||||||
|
window.open(app.getMediaItemArtwork(this.getArtworkUrl(), 1024, 1024))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
}, event)
|
||||||
|
},
|
||||||
|
getArtworkUrl(size = -1, includeUrl = false) {
|
||||||
|
let artwork = this.item.attributes.artwork ? this.item.attributes.artwork.url : ''
|
||||||
|
if (size != -1) {
|
||||||
|
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', ((size === 900) ? "sr" : "cc"))
|
||||||
|
}
|
||||||
|
switch (this.kind) {
|
||||||
|
case "385":
|
||||||
|
artwork = this.item.attributes?.editorialArtwork?.subscriptionHero?.url
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!includeUrl) {
|
||||||
|
return artwork
|
||||||
|
} else {
|
||||||
|
return `url("${artwork}")`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
playTrack(item) {
|
||||||
|
let parent = this.parent
|
||||||
|
let childIndex = this.index
|
||||||
|
let kind = (item.attributes.playParams ? (item.attributes.playParams?.kind ?? (item.type ?? '')) : (item.type ?? ''));
|
||||||
|
let id = (item.attributes.playParams ? (item.attributes.playParams?.id ?? (item.id ?? '')) : (item.id ?? ''));
|
||||||
|
;
|
||||||
|
let isLibrary = item.attributes.playParams ? (item.attributes.playParams?.isLibrary ?? false) : false;
|
||||||
|
let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
|
||||||
|
console.log(item, parent, childIndex, kind, id, isLibrary, kind == "playlists", id.startsWith("p.") || id.startsWith("pl.u"))
|
||||||
|
app.mk.stop().then(() => {
|
||||||
|
if (parent != null && childIndex != null) {
|
||||||
|
app.queueParentandplayChild(parent, childIndex, item);
|
||||||
|
} else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))) {
|
||||||
|
function shuffleArray(array) {
|
||||||
|
for (var i = array.length - 1; i > 0; i--) {
|
||||||
|
var j = Math.floor(Math.random() * (i + 1));
|
||||||
|
var temp = array[i];
|
||||||
|
array[i] = array[j];
|
||||||
|
array[j] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.mk.setQueue({
|
||||||
|
[truekind]: [item.attributes.playParams?.id ?? item.id],
|
||||||
|
parameters: { l: this.app.mklang }
|
||||||
|
}).then(function() {
|
||||||
|
app.mk.play().then(function() {
|
||||||
|
var playlistId = id
|
||||||
|
|
||||||
|
function getPlaylist(id, isLibrary) {
|
||||||
|
if (isLibrary) {
|
||||||
|
return this.app.mk.api.v3.music(`/v1/me/library/playlists/${id}`)
|
||||||
|
} else {
|
||||||
|
return this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
getPlaylist(id, isLibrary).then(res => {
|
||||||
|
//let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
|
||||||
|
//if (app.mk.shuffleMode == 1){shuffleArray(query); }
|
||||||
|
// console.log(query)
|
||||||
|
// app.mk.queue.append(query)
|
||||||
|
if (!res.data.relationships.tracks.next) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
getPlaylistTracks(res.data.relationships.tracks.next)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlaylistTracks(next) {
|
||||||
|
app.apiCall(app.musicBaseUrl + next, res => {
|
||||||
|
// if (res.id != playlistId || next.includes(playlistId)) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
console.log('nextres', res)
|
||||||
|
let query = res.data.map(item => new MusicKit.MediaItem(item))
|
||||||
|
if (app.mk.shuffleMode == 1) {
|
||||||
|
shuffleArray(query);
|
||||||
|
console.log('shf')
|
||||||
|
}
|
||||||
|
app.mk.queue.append(query)
|
||||||
|
|
||||||
|
if (res.next) {
|
||||||
|
getPlaylistTracks(res.next)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
app.playMediaItemById(item.attributes.playParams?.id ?? item.id, item.attributes.playParams?.kind ?? item.type, item.attributes.playParams?.isLibrary ?? false, item.attributes.url)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeDestroy: function () {
|
||||||
|
// this.item = null;
|
||||||
|
// this.kind = null;
|
||||||
|
// this.size = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -63,7 +63,6 @@
|
||||||
|
|
||||||
<body class="notransparency" oncontextmenu="return false;" loading="1" os-release="<%= parseInt(env.osRelease) ;%>"
|
<body class="notransparency" oncontextmenu="return false;" loading="1" os-release="<%= parseInt(env.osRelease) ;%>"
|
||||||
platform="<%= env.platform ;%>">
|
platform="<%= env.platform ;%>">
|
||||||
<script src="<%- (env.dev ? " ./lib/vue.js" : "./lib/vue.dev.js"); %>"></script>
|
|
||||||
<script src="./lib/vue-horizontal.js"></script>
|
<script src="./lib/vue-horizontal.js"></script>
|
||||||
<script src="./lib/bootstrap-vue.min.js"></script>
|
<script src="./lib/bootstrap-vue.min.js"></script>
|
||||||
<script src="./lib/vuex.min.js"></script>
|
<script src="./lib/vuex.min.js"></script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script type="text/x-template" id="apple-account-settings">
|
<script type="text/x-template" id="apple-account-settings">
|
||||||
<div style="display:flex;width:100%;height:100%;padding-top: var(--navigationBarHeight);position:absolute;top:0;left:0;">
|
<div style="display:flex;width:100%;height:100%;padding-top: var(--navigationBarHeight);position:absolute;top:0;left:0;">
|
||||||
<webview id="foo"
|
<webview id="foo"
|
||||||
src="https://music.apple.com/includes/commerce/account/settings?product=music&isFullscreen=true&isModal=false"
|
src="https://beta.music.apple.com/includes/commerce/account/settings?product=music&isFullscreen=false&isModal=false&expectsModalLayout=false&isFullScreen=true"
|
||||||
style="display:inline-flex; width:100%;"></webview>
|
style="display:inline-flex; width:100%;"></webview>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script type="text/x-template" id="cider-applecurator">
|
<script type="text/x-template" id="cider-applecurator">
|
||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
<h1 class="header-text">{{ data.attributes.shortName ?? data.attributes.name}}</h1>
|
<h1 class="header-text">{{ data.attributes?.shortName ?? data.attributes.name}}</h1>
|
||||||
<template v-if="data.relationships && data.relationships.grouping">
|
<template v-if="data.relationships && data.relationships.grouping">
|
||||||
<template
|
<template
|
||||||
v-for="(recom,index) in data.relationships.grouping.data[0].relationships.tabs.data[0].relationships.children.data">
|
v-for="(recom,index) in data.relationships.grouping.data[0].relationships.tabs.data[0].relationships.children.data">
|
||||||
|
@ -43,6 +43,9 @@
|
||||||
return {
|
return {
|
||||||
app: this.$root
|
app: this.$root
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log('ping')
|
||||||
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="well" style="margin-top:0;">
|
<div class="well" style="margin-top:0;">
|
||||||
<template v-if="artistFeed.length > 0">
|
<template v-if="artistFeed.length > 0">
|
||||||
<mediaitem-list-item v-for="item in artistFeed" :item="item"></mediaitem-list-item>
|
<mediaitem-list-item v-for="item in artistFeed" v-bind:key="item.id" :item="item"></mediaitem-list-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
|
|
|
@ -8,7 +8,22 @@
|
||||||
<h1 class="header-text">{{data.attributes?.title ?? ""}}</h1>
|
<h1 class="header-text">{{data.attributes?.title ?? ""}}</h1>
|
||||||
<h2 class="header-desc" v-html='data.relationships?.children?.data[0]?.attributes?.description ?? ""'></h2>
|
<h2 class="header-desc" v-html='data.relationships?.children?.data[0]?.attributes?.description ?? ""'></h2>
|
||||||
<template v-if="data.relationships">
|
<template v-if="data.relationships">
|
||||||
<template v-for="(recom,index) in data.relationships.children.data">
|
<template v-if="data.type=='rooms' && (data?.relationships?.contents?.data ?? []).length > 0">
|
||||||
|
<!-- <div class="row">
|
||||||
|
<div class="col-auto cider-flex-center"
|
||||||
|
v-if="data?.relationships?.contents?.data.length > 10">
|
||||||
|
<button class="cd-btn-seeall"
|
||||||
|
@click="app.showCollection(recom, data.attributes.name ?? '', 'listen_now')">
|
||||||
|
{{app.getLz('term.seeAll')}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<template>
|
||||||
|
<mediaitem-square :item="item" :key="item?.id ?? ''"
|
||||||
|
v-for="item in data?.relationships?.contents?.data"></mediaitem-square>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else v-for="(recom,index) in (data.relationships?.children?.data ?? recom?.relationships?.contents?.data)">
|
||||||
<template v-if="(recom.relationships?.contents?.data ?? []).length > 0">
|
<template v-if="(recom.relationships?.contents?.data ?? []).length > 0">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col" v-if="recom.attributes.name != 'Chart Set'">
|
<div class="col" v-if="recom.attributes.name != 'Chart Set'">
|
||||||
|
@ -37,7 +52,7 @@
|
||||||
:items="recom.relationships.children ? recom.relationships.children.data.limit(10) : recom.relationships.contents.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
:items="recom.relationships.children ? recom.relationships.children.data.limit(10) : recom.relationships.contents.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -243,6 +243,7 @@
|
||||||
:showIndex="true"
|
:showIndex="true"
|
||||||
:showIndexPlaylist="(data.attributes.playParams?.kind ?? data.type ?? '').includes('playlist')"
|
:showIndexPlaylist="(data.attributes.playParams?.kind ?? data.type ?? '').includes('playlist')"
|
||||||
:context-ext="buildContextMenu()"
|
:context-ext="buildContextMenu()"
|
||||||
|
v-bind:key="item.id"
|
||||||
v-for="(item,index) in currentSlice"></mediaitem-list-item>
|
v-for="(item,index) in currentSlice"></mediaitem-list-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
@ -255,6 +256,7 @@
|
||||||
:showIndex="true"
|
:showIndex="true"
|
||||||
:showIndexPlaylist="(data.attributes.playParams?.kind ?? data.type ?? '').includes('playlist')"
|
:showIndexPlaylist="(data.attributes.playParams?.kind ?? data.type ?? '').includes('playlist')"
|
||||||
:context-ext="buildContextMenu()"
|
:context-ext="buildContextMenu()"
|
||||||
|
v-bind:key="item.id"
|
||||||
v-for="(item,index) in disc.tracks"></mediaitem-list-item>
|
v-for="(item,index) in disc.tracks"></mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -645,6 +647,7 @@
|
||||||
return {
|
return {
|
||||||
normal: [
|
normal: [
|
||||||
{
|
{
|
||||||
|
icon: "./assets/feather/x-circle.svg",
|
||||||
name: app.getLz('action.removeFromPlaylist'),
|
name: app.getLz('action.removeFromPlaylist'),
|
||||||
action: () => {
|
action: () => {
|
||||||
self.remove()
|
self.remove()
|
||||||
|
@ -653,6 +656,7 @@
|
||||||
],
|
],
|
||||||
multiple: [
|
multiple: [
|
||||||
{
|
{
|
||||||
|
icon: "./assets/feather/x-circle.svg",
|
||||||
name: app.getLz('action.removeFromPlaylist'),
|
name: app.getLz('action.removeFromPlaylist'),
|
||||||
action: () => {
|
action: () => {
|
||||||
self.remove()
|
self.remove()
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<div class="well artistfeed-well">
|
<div class="well artistfeed-well">
|
||||||
<template v-if="isSectionReady('recentlyPlayed')">
|
<template v-if="isSectionReady('recentlyPlayed')">
|
||||||
<mediaitem-list-item v-for="item in recentlyPlayed.limit(6)"
|
<mediaitem-list-item v-for="item in recentlyPlayed.limit(6)"
|
||||||
:item="item"></mediaitem-list-item>
|
:item="item" v-bind:key="item.id"></mediaitem-list-item>
|
||||||
</template>
|
</template>
|
||||||
<div class="spinner" v-else></div>
|
<div class="spinner" v-else></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="well artistfeed-well" style="margin-top:0;">
|
<div class="well artistfeed-well" style="margin-top:0;">
|
||||||
<template v-if="artistFeed.length > 0">
|
<template v-if="artistFeed.length > 0">
|
||||||
<mediaitem-list-item v-for="item in artistFeed.limit(6)" :item="item"></mediaitem-list-item>
|
<mediaitem-list-item v-for="item in artistFeed.limit(6)" :item="item" v-bind:key="item.id"></mediaitem-list-item>
|
||||||
</template>
|
</template>
|
||||||
<div class="spinner" v-else-if="followedArtists.length > 0"></div>
|
<div class="spinner" v-else-if="followedArtists.length > 0"></div>
|
||||||
<div class="no-artist" v-else> {{app.getLz('home.artistsFeed.noArtist')}}</div>
|
<div class="no-artist" v-else> {{app.getLz('home.artistsFeed.noArtist')}}</div>
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<mediaitem-list-item v-if="prefs.viewAs == 'list'" :show-duration="false" :show-meta-data="true"
|
<mediaitem-list-item v-if="prefs.viewAs == 'list'" :show-duration="false" :show-meta-data="true"
|
||||||
:show-library-status="false" :item="item" v-for="item in currentSlice">
|
:show-library-status="false" v-bind:key="item.id" :item="item" v-for="item in currentSlice">
|
||||||
</mediaitem-list-item>
|
</mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
<h1 class="header-text">{{$root.getLz('term.recentlyAdded')}}</h1>
|
<h1 class="header-text">{{$root.getLz('term.recentlyAdded')}}</h1>
|
||||||
<div class="well itemContainer collection-list-square" v-if="itemSize == 'normal'">
|
<div class="well itemContainer collection-list-square" v-if="itemSize == 'normal'">
|
||||||
<mediaitem-square v-for="item in items" :item="item"></mediaitem-square>
|
<mediaitem-square v-for="item in items" :item="item" v-bind:key="item.id"></mediaitem-square>
|
||||||
</div>
|
</div>
|
||||||
<div class="well itemContainer collection-list-square" v-else="itemSize == 'compact'">
|
<div class="well itemContainer collection-list-square" v-else="itemSize == 'compact'">
|
||||||
<mediaitem-list-item :show-meta-data="true" :show-library-status="false" v-for="item in items"
|
<mediaitem-list-item :show-meta-data="true" :show-library-status="false" v-for="item in items"
|
||||||
:item="item"></mediaitem-list-item>
|
:item="item" v-bind:key="item.id"></mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="well itemContainer collection-list-square" v-show="loading">
|
<div class="well itemContainer collection-list-square" v-show="loading">
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
|
|
|
@ -84,12 +84,12 @@
|
||||||
<div v-if="library.songs.downloadState == 3">Library contains no songs.</div>
|
<div v-if="library.songs.downloadState == 3">Library contains no songs.</div>
|
||||||
<div class="well" :key="1" v-if="prefs.size == 'compact'">
|
<div class="well" :key="1" v-if="prefs.size == 'compact'">
|
||||||
<mediaitem-list-item class-list="compact" :item="item" :parent="'librarysongs'" :index="index"
|
<mediaitem-list-item class-list="compact" :item="item" :parent="'librarysongs'" :index="index"
|
||||||
:show-meta-data="true" :show-library-status="false"
|
:show-meta-data="true" :show-library-status="false" v-bind:key="item.id"
|
||||||
v-for="(item, index) in currentSlice"></mediaitem-list-item>
|
v-for="(item, index) in currentSlice"></mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="well" :key="2" v-else>
|
<div class="well" :key="2" v-else>
|
||||||
<mediaitem-list-item :item="item" :parent="'librarysongs'" :index="index" :show-meta-data="true"
|
<mediaitem-list-item :item="item" :parent="'librarysongs'" :index="index" :show-meta-data="true"
|
||||||
:show-library-status="false"
|
:show-library-status="false" v-bind:key="item.id"
|
||||||
v-for="(item, index) in currentSlice"></mediaitem-list-item>
|
v-for="(item, index) in currentSlice"></mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="madeforyou-body">
|
<div class="madeforyou-body">
|
||||||
<mediaitem-square :item="item" v-for="item in madeforyou.data">
|
<mediaitem-square :item="item" v-for="item in madeforyou.data" v-bind:key="item.id">
|
||||||
</mediaitem-square>
|
</mediaitem-square>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -153,7 +153,9 @@
|
||||||
<div class="blurb"></div>
|
<div class="blurb"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="oobe-footer">
|
<div class="oobe-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
<div class="md-btn" @click="app.appMode ='player'">{{ getLz("oobe.done") }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="oobe-titlebar">
|
<div class="oobe-titlebar">
|
||||||
|
|
|
@ -171,6 +171,7 @@
|
||||||
:showIndex="true"
|
:showIndex="true"
|
||||||
:showIndexPlaylist="(data.attributes.playParams.kind ?? data.type ?? '').includes('playlist')"
|
:showIndexPlaylist="(data.attributes.playParams.kind ?? data.type ?? '').includes('playlist')"
|
||||||
:context-ext="buildContextMenu()"
|
:context-ext="buildContextMenu()"
|
||||||
|
v-bind:key="item.id"
|
||||||
v-for="(item,index) in data.relationships.tracks.data"></mediaitem-list-item>
|
v-for="(item,index) in data.relationships.tracks.data"></mediaitem-list-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
@ -183,6 +184,7 @@
|
||||||
:showIndex="true"
|
:showIndex="true"
|
||||||
:showIndexPlaylist="(data.attributes.playParams.kind ?? data.type ?? '').includes('playlist')"
|
:showIndexPlaylist="(data.attributes.playParams.kind ?? data.type ?? '').includes('playlist')"
|
||||||
:context-ext="buildContextMenu()"
|
:context-ext="buildContextMenu()"
|
||||||
|
v-bind:key="item.id"
|
||||||
v-for="(item,index) in disc.tracks"></mediaitem-list-item>
|
v-for="(item,index) in disc.tracks"></mediaitem-list-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -197,6 +199,7 @@
|
||||||
<div class="badge-container">
|
<div class="badge-container">
|
||||||
<div class="socialBadge"
|
<div class="socialBadge"
|
||||||
:title="`${badge.attributes.name} - @${badge.attributes.handle}`"
|
:title="`${badge.attributes.name} - @${badge.attributes.handle}`"
|
||||||
|
v-bind:key="badge.id"
|
||||||
v-for="badge in itemBadges">
|
v-for="badge in itemBadges">
|
||||||
<mediaitem-artwork
|
<mediaitem-artwork
|
||||||
:url="badge.attributes.artwork.url"
|
:url="badge.attributes.artwork.url"
|
||||||
|
@ -443,6 +446,7 @@
|
||||||
return {
|
return {
|
||||||
normal: [
|
normal: [
|
||||||
{
|
{
|
||||||
|
icon: "./assets/feather/x-circle.svg",
|
||||||
name: app.getLz('action.removeFromPlaylist'),
|
name: app.getLz('action.removeFromPlaylist'),
|
||||||
action: () => {
|
action: () => {
|
||||||
self.remove()
|
self.remove()
|
||||||
|
@ -451,6 +455,7 @@
|
||||||
],
|
],
|
||||||
multiple: [
|
multiple: [
|
||||||
{
|
{
|
||||||
|
icon: "./assets/feather/x-circle.svg",
|
||||||
name: app.getLz('action.removeFromPlaylist'),
|
name: app.getLz('action.removeFromPlaylist'),
|
||||||
action: () => {
|
action: () => {
|
||||||
self.remove()
|
self.remove()
|
||||||
|
|
|
@ -1,28 +1,76 @@
|
||||||
<script type="text/x-template" id="cider-radio">
|
<script type="text/x-template" id="cider-radio">
|
||||||
<div class="content-inner">
|
<div class="content-inner">
|
||||||
<h1 class="header-text">{{ app.getLz('term.radio') }}</h1>
|
<h1 class="header-text">{{$root.getLz("term.radio")}}</h1>
|
||||||
<div class="row">
|
<template v-if="data.relationships && data.relationships.tabs">
|
||||||
<div class="col">
|
<template v-for="(recom,index) in data.relationships.tabs.data[0].relationships.children.data">
|
||||||
<h3>{{ app.getLz('term.personalStations') }}</h3>
|
<div class="row">
|
||||||
</div>
|
<div class="col" v-if="recom.attributes.name != 'Chart Set'">
|
||||||
</div>
|
<h3>{{ recom.attributes.name ?? ""}}</h3>
|
||||||
<!-- <mediaitem-square :kind="'385'" size="600"-->
|
</div>
|
||||||
<!-- :item="item ? (item.attributes.kind ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"-->
|
<div class="col-auto cider-flex-center">
|
||||||
<!-- :imagesize="800"-->
|
<button class="cd-btn-seeall" v-if="recom.attributes.name == 'Recently Played' && recent.length > 10"
|
||||||
<!-- v-for="item of getFlattenedCategories()">-->
|
@click="app.showCollection({ data: recent }, recom.attributes.name ?? '', 'listen_now')">
|
||||||
<mediaitem-square :item="item" v-for="item in radio.personal"></mediaitem-square>
|
{{app.getLz('term.seeAll')}}
|
||||||
<div class="row">
|
</button>
|
||||||
<div class="col">
|
<template v-if="index != 0 && recom.relationships && ((recom.relationships.children && recom.relationships.children.data.length > 10) || (recom.relationships.contents && recom.relationships.contents.data.length > 10))">
|
||||||
<h3>{{ app.getLz('term.recentStations') }}</h3>
|
<button class="cd-btn-seeall" v-if="recom.relationships.room"
|
||||||
</div>
|
@click="app.showRoom(recom.relationships.room?.data[0].href)">
|
||||||
</div>
|
{{app.getLz('term.seeAll')}}
|
||||||
<mediaitem-square :item="station" v-for="station in radio.recent"></mediaitem-square>
|
</button>
|
||||||
<div class="row">
|
<button class="cd-btn-seeall" v-else
|
||||||
<div class="col">
|
@click="app.showCollection(recom.relationships.children ? recom.relationships.children : recom.relationships.contents, recom.attributes.name ?? '', 'listen_now')">
|
||||||
<h3>{{ app.getLz('term.amLive') }}</h3>
|
{{app.getLz('term.seeAll')}}
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</template>
|
||||||
<mediaitem-square :item="station" v-for="station in radio.am"></mediaitem-square>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="recom.attributes.name == 'Recently Played'">
|
||||||
|
<mediaitem-scroller-horizontal-mvview :imagesize="800"
|
||||||
|
:browsesp="index == 0|| (data.relationships.tabs.data[0].relationships.children.data[0].relationships == null && index === 1)"
|
||||||
|
:kind="recom.attributes.editorialElementKind"
|
||||||
|
:items="recent.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||||
|
</div>
|
||||||
|
<template v-else-if="(recom.relationships != null && ((recom.relationships.children && recom.relationships.children.data) || (recom.relationships.contents && recom.relationships.contents.data)))">
|
||||||
|
<template v-if="index === 0|| (data.relationships.tabs.data[0].relationships.children.data[0].relationships == null && index === 1)">
|
||||||
|
<mediaitem-scroller-horizontal-mvview :imagesize="800"
|
||||||
|
:browsesp="index == 0|| (data.relationships.tabs.data[0].relationships.children.data[0].relationships == null && index === 1)"
|
||||||
|
:kind="recom.attributes.editorialElementKind"
|
||||||
|
:items="recom.relationships.children ? recom.relationships.children.data.limit(10) : recom.relationships.contents.data.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="(['327']).includes(recom.attributes.editorialElementKind)">
|
||||||
|
<div class="mediaitem-list-item__grid">
|
||||||
|
<listitem-horizontal :items="recom.relationships.contents.data.limit(20)">
|
||||||
|
</listitem-horizontal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="(['385']).includes(recom.attributes.editorialElementKind)">
|
||||||
|
<mediaitem-scroller-horizontal-mvview :imagesize="800"
|
||||||
|
:kind="recom.attributes.editorialElementKind"
|
||||||
|
:items="recom.relationships.children ? recom.relationships.children.data.limit(10) : recom.relationships.contents.data.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="recom.attributes.name == 'Chart Set'">
|
||||||
|
<!-- ignored -->
|
||||||
|
</template>
|
||||||
|
<template v-else-if="(['488']).includes(recom.attributes.editorialElementKind)">
|
||||||
|
<!-- ignored -->
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<mediaitem-scroller-horizontal-large
|
||||||
|
:items="recom.relationships.children ? recom.relationships.children.data.limit(10) : recom.relationships.contents.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<template v-if="recom.attributes.links && recom.attributes.editorialElementKind.includes('391')">
|
||||||
|
<div class="grouping-container">
|
||||||
|
<button class="grouping-btn" @click="$root.goToGrouping(link.url)"
|
||||||
|
v-for="link in recom.attributes.links">{{ link.label }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -33,59 +81,30 @@
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
app: this.$root,
|
app: this.$root,
|
||||||
radio: { personal: [], recent: [], am: [] }
|
recent: []
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
async mounted() {
|
mounted() {
|
||||||
this.radio.personal = await this.getPersonalStations()
|
this.$root.getRadioPage();
|
||||||
this.radio.recent = await this.getRecentStations()
|
// debugger
|
||||||
this.radio.am = await this.getAmStations()
|
this.getRecentlyPlayed();
|
||||||
console.log(this.radio)
|
// debugger
|
||||||
// this.getPersonalStations();
|
|
||||||
// this.getAmStations();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getPersonalStations(attempts = 0) {
|
getRecentlyPlayed: async function (next = null) {
|
||||||
if (attempts > 3) {
|
const recent = await app.mk.api.v3.music(`${next ?? "/v1/me/recent/radio-stations"}`, {
|
||||||
return []
|
"platform": "web",
|
||||||
|
"art[url]": "f",
|
||||||
|
l: app.mklang
|
||||||
|
})
|
||||||
|
|
||||||
|
console.debug(recent.data.data)
|
||||||
|
this.recent = this.recent.concat(recent.data.data);
|
||||||
|
|
||||||
|
if (recent.data.next) {
|
||||||
|
this.getRecentlyPlayed(recent.data.next);
|
||||||
}
|
}
|
||||||
try {
|
}
|
||||||
return (await app.mk.api.v3.music(`/v1/catalog/${app.mk.api.v3.storefrontId}/stations`, {
|
|
||||||
"filter[identity]": "personal",
|
|
||||||
})).data.data
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Failed to get personal stations: ${e}`)
|
|
||||||
await this.getPersonalStations(attempts + 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getRecentStations(attempts = 0) {
|
|
||||||
if (attempts > 3) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return (await app.mk.api.v3.music(`/v1/me/recent/radio-stations`, {
|
|
||||||
"platform": "web",
|
|
||||||
"art[url]": "f",
|
|
||||||
l: app.mklang
|
|
||||||
})).data.data
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Failed to get recent stations: ${e}`)
|
|
||||||
await this.getRecentStations(attempts + 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getAmStations(attempt = 0) {
|
|
||||||
if (attempt > 3) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return (await app.mk.api.v3.music(`/v1/catalog/${app.mk.api.v3.storefrontId}/stations`, {
|
|
||||||
"filter[featured]": "apple-music-live-radio",
|
|
||||||
})).data.data
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Failed to get AM stations: ${e}`)
|
|
||||||
await this.getAmStations(attempt + 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,8 +23,10 @@
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h4>{{ convertToHours(loaded.attributes.listenTimeInMinutes) }}
|
<h4 @click="hourshow = !hourshow">{{convertToHours(loaded.attributes.listenTimeInMinutes)}}
|
||||||
{{$root.getLz('term.time.hours')}}</h4>
|
{{$root.getLz('term.time.hours')}}
|
||||||
|
{{hourshow ? "" : (loaded.attributes.listenTimeInMinutes % 60) }}
|
||||||
|
{{hourshow ? "" : $root.getLz('term.time.minutes')}}</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueAlbumCount }} {{$root.getLz('term.uniqueAlbums')}}</h4>
|
<h4>{{ loaded.attributes.uniqueAlbumCount }} {{$root.getLz('term.uniqueAlbums')}}</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueArtistCount }} {{$root.getLz('term.uniqueArtists')}}</h4>
|
<h4>{{ loaded.attributes.uniqueArtistCount }} {{$root.getLz('term.uniqueArtists')}}</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueSongCount }} {{$root.getLz('term.uniqueSongs')}}</h4>
|
<h4>{{ loaded.attributes.uniqueSongCount }} {{$root.getLz('term.uniqueSongs')}}</h4>
|
||||||
|
@ -101,6 +103,7 @@
|
||||||
loaded: {
|
loaded: {
|
||||||
id: -1
|
id: -1
|
||||||
},
|
},
|
||||||
|
hourshow: true,
|
||||||
musicTypeGenre: ""
|
musicTypeGenre: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,18 +3,22 @@
|
||||||
<div class="search-input-container fs-search" v-if="$root.appMode == 'fullscreen'">
|
<div class="search-input-container fs-search" v-if="$root.appMode == 'fullscreen'">
|
||||||
<div class="search-input--icon"></div>
|
<div class="search-input--icon"></div>
|
||||||
<input type="search" spellcheck="false" @focus="$root.search.showHints = true"
|
<input type="search" spellcheck="false" @focus="$root.search.showHints = true"
|
||||||
@blur="$root.setTimeout(()=>{$root.search.showHints = false}, 300)"
|
@blur="$root.setTimeout(()=>{if($root.hintscontext != true){$root.search.showHints = false} }, 300)"
|
||||||
v-on:keyup.enter="$root.searchQuery();$root.search.showHints = false" @input="$root.getSearchHints()"
|
v-on:keyup.enter="$root.searchQuery($root.search.hints[$root.search.cursor]?.content ?? $root.search.hints[$root.search.cursor]?.searchTerm ?? $root.search.term);$root.search.showHints = false; $root.search.showSearchView = true" @input="$root.getSearchHints()"
|
||||||
:placeholder="$root.getLz('term.search') + '...'" v-model="$root.search.term"
|
:placeholder="$root.getLz('term.search') + '...'" v-model="$root.search.term"
|
||||||
class="search-input" />
|
class="search-input" />
|
||||||
|
|
||||||
<div class="search-hints-container" v-if="$root.search.showHints && $root.search.hints.length != 0">
|
<div class="search-hints-container" v-if="$root.search.showHints && $root.search.hints.length != 0">
|
||||||
<div class="search-hints">
|
<div class="search-hints">
|
||||||
<button class="search-hint text-overflow-elipsis" v-for="hint in $root.search.hints"
|
<button class="search-hint text-overflow-elipsis" v-for="(hint, index) in $root.search.hints.filter((a) => {return a.content == null})" :class="{active: ($root.search.cursor == index)}"
|
||||||
@click="$root.search.term = hint;$root.search.showHints = false;$root.searchQuery(hint)">
|
@click="$root.search.term = hint.searchTerm;$root.search.showHints = false;$root.searchQuery(hint.searchTerm)">
|
||||||
{{ hint }}
|
{{ hint.displayTerm }}
|
||||||
</button>
|
</button>
|
||||||
|
<template v-for="(item, position) in $root.search.hints.filter((a) => {return a.content != null})">
|
||||||
|
<mediaitem-smarthints :item="item.content" :position="position"> </mediaitem-smarthints>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group searchToggle">
|
<div class="btn-group searchToggle">
|
||||||
|
@ -29,16 +33,12 @@
|
||||||
$root.getLz("term.library") }}
|
$root.getLz("term.library") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="search != null && search != [] && search.term != ''">
|
<div v-if="search != null && search != [] && search.term != '' && $root.search.showSearchView">
|
||||||
<template v-if="searchType == 'catalog'">
|
<template v-if="searchType == 'catalog'">
|
||||||
<h3>{{app.getLz('term.topResult')}}</h3>
|
<h3>{{app.getLz('term.topResult')}}</h3>
|
||||||
<mediaitem-scroller-horizontal
|
<mediaitem-scroller-horizontal
|
||||||
:items="search.results[search.results.meta.results.order[0]]['data']"></mediaitem-scroller-horizontal>
|
:items="search?.results[search?.results?.meta?.results?.order[0]]?.data"></mediaitem-scroller-horizontal>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div v-else style="text-align: center">
|
|
||||||
<h3>{{app.getLz('error.noResults')}}</h3>
|
|
||||||
<p>{{app.getLz('error.noResults.description')}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="col" v-if="search.results.song">
|
<div class="col" v-if="search.results.song">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
@ -55,6 +55,10 @@
|
||||||
</listitem-horizontal>
|
</listitem-horizontal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else style="text-align: center">
|
||||||
|
<h3>{{app.getLz('error.noResults')}}</h3>
|
||||||
|
<p>{{app.getLz('error.noResults.description')}}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="search.results['meta'] != null">
|
<template v-if="search.results['meta'] != null">
|
||||||
|
@ -131,21 +135,21 @@
|
||||||
<div v-if="categoriesReady || getCategories()">
|
<div v-if="categoriesReady || getCategories()">
|
||||||
<div>
|
<div>
|
||||||
<div class="col"
|
<div class="col"
|
||||||
v-if="categoriesView != null && categoriesView != [] && categoriesView[0].attributes != null && categoriesView[0].attributes.title != null">
|
v-if="categoriesView != null && categoriesView != [] && categoriesView[0]?.attributes != null && categoriesView[0]?.attributes.title != null">
|
||||||
<h3>{{$root.getLz('home.recentlyPlayed')}}</h3>
|
<h3>{{$root.getLz('home.recentlyPlayed')}}</h3>
|
||||||
<div class="mediaitem-list-item__grid">
|
<div class="mediaitem-list-item__grid">
|
||||||
<listitem-horizontal :items="recentlyPlayed.limit(10)">
|
<listitem-horizontal :items="recentlyPlayed.limit(10)">
|
||||||
</listitem-horizontal>
|
</listitem-horizontal>
|
||||||
</div>
|
</div>
|
||||||
<!-- <mediaitem-square :kind="'385'" size="600" v-for="item in recentlyPlayed.limit(10)" :item="item" :imagesize="800"></mediaitem-square>-->
|
<!-- <mediaitem-square :kind="'385'" size="600" v-for="item in recentlyPlayed.limit(10)" :item="item" :imagesize="800"></mediaitem-square>-->
|
||||||
<h3>{{categoriesView[0].attributes.title.stringForDisplay ?? ""}}</h3>
|
<h3>{{categoriesView[0]?.attributes?.title?.stringForDisplay ?? ""}}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="categories">
|
<div class="categories">
|
||||||
<mediaitem-square :kind="'385'" :imageformat="'bb'" size="600"
|
<mediaitem-square :kind="'385'" :imageformat="'bb'" size="600" :removeamtext="true"
|
||||||
:item="item ? (item.attributes.kind ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
|
:item="item ? (item.attributes.kind ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
|
||||||
:imagesize="800"
|
:imagesize="800"
|
||||||
v-for="item of getFlattenedCategories()">
|
v-for="item of getFlattenedCategories()"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
8
src/web-remote/assets/MissingArtwork.svg
Normal file
8
src/web-remote/assets/MissingArtwork.svg
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<rect x="0" y="0" width="1024" height="1024" style="fill:rgb(110,110,110);"/>
|
||||||
|
<g transform="matrix(6.05996,0,0,6.05996,189.003,209)">
|
||||||
|
<path d="M93.161,0.071C59.66,-1.043 32.22,11.314 32.22,11.314L32.2,74.023C28.789,72.669 24.641,72.348 20.428,73.372C11.345,75.579 5.397,83.192 7.143,90.379C8.889,97.566 17.667,101.604 26.749,99.398C35.313,97.317 41.087,90.429 40.256,83.626L40.256,36.771C40.256,36.771 59.66,29.987 84.829,28.286L84.829,63.135C81.455,61.843 77.386,61.55 73.25,62.555C64.167,64.761 58.219,72.374 59.965,79.562C61.71,86.749 70.488,90.786 79.571,88.58C87.502,86.653 93.042,80.603 93.158,74.316L93.161,74.32L93.161,0.071Z" style="fill-opacity:0.16;fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -507,6 +507,11 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-entry.artist-song {
|
||||||
|
padding: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.list-entry-image {
|
.list-entry-image {
|
||||||
--artwork: url("");
|
--artwork: url("");
|
||||||
width: 64px;
|
width: 64px;
|
||||||
|
@ -519,6 +524,11 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
box-shadow: var(--mediaItemShadow);
|
box-shadow: var(--mediaItemShadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.artist-song .list-entry-image {
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
.list-entry-image.artist {
|
.list-entry-image.artist {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
@ -586,6 +596,10 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mediaitem-scroller-horizontal::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.album-placeholder {
|
.album-placeholder {
|
||||||
height: 180px;
|
height: 180px;
|
||||||
width: 180px;
|
width: 180px;
|
||||||
|
@ -643,6 +657,10 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-tab-container::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.search-body-container {
|
.search-body-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -704,7 +722,7 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
}
|
}
|
||||||
|
|
||||||
.albumpage-album-notes > .notes-preview {
|
.albumpage-album-notes > .notes-preview {
|
||||||
height: 60px;
|
height: 48px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-webkit-mask-image: -webkit-gradient(linear, left 95%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
|
-webkit-mask-image: -webkit-gradient(linear, left 95%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
|
||||||
}
|
}
|
||||||
|
@ -757,13 +775,13 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
|
||||||
}
|
}
|
||||||
|
|
||||||
.artist-header {
|
.artist-header {
|
||||||
height: 400px;
|
/* height: 400px; */
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 12px auto;
|
/* margin: 12px auto; */
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12px;
|
/* padding: 12px; */
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: rgb(0 0 0 / 40%);
|
background: rgb(0 0 0 / 40%);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script type="text/x-template" id="mediaitem-artwork">
|
<script type="text/x-template" id="mediaitem-artwork">
|
||||||
<div class="mediaitem-artwork" :class="[{'rounded': (type == 'artists')}, classes]" :key="url"
|
<div class="mediaitem-artwork" :class="[{'rounded': (type == 'artists')}, classes]" :key="url"
|
||||||
v-observe-visibility="{callback: visibilityChanged}">
|
v-observe-visibility="{callback: visibilityChanged}">
|
||||||
<img :src="getMediaItemArtwork(url, size, width)"
|
<img :src="getMediaItemArtwork(url, size, width)" :style="{ width: size + 'px'}"
|
||||||
decoding="async" loading="lazy"
|
decoding="async" loading="lazy"
|
||||||
class="mediaitem-artwork--img">
|
class="mediaitem-artwork--img">
|
||||||
<!-- <div v-if="video && isVisible && getVideoPriority()" class="animatedartwork-view-box">
|
<!-- <div v-if="video && isVisible && getVideoPriority()" class="animatedartwork-view-box">
|
||||||
|
@ -86,6 +86,7 @@
|
||||||
this.isVisible = isVisible
|
this.isVisible = isVisible
|
||||||
},
|
},
|
||||||
getMediaItemArtwork(url, height = 64, width) {
|
getMediaItemArtwork(url, height = 64, width) {
|
||||||
|
try{
|
||||||
if (typeof url == "undefined" || url == "") {
|
if (typeof url == "undefined" || url == "") {
|
||||||
return "./assets/MissingArtwork.svg"
|
return "./assets/MissingArtwork.svg"
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,9 @@
|
||||||
if (newurl.includes("900x516")) {
|
if (newurl.includes("900x516")) {
|
||||||
newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr");
|
newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr");
|
||||||
}
|
}
|
||||||
return newurl
|
return newurl} catch (e){
|
||||||
|
return "./assets/MissingArtwork.svg"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -213,7 +213,7 @@
|
||||||
}
|
}
|
||||||
switch (this.kind) {
|
switch (this.kind) {
|
||||||
case "385":
|
case "385":
|
||||||
artwork = this.item.attributes.editorialArtwork.subscriptionHero.url
|
artwork = this.item.attributes?.editorialArtwork?.subscriptionHero?.url
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!includeUrl) {
|
if (!includeUrl) {
|
||||||
|
@ -320,7 +320,7 @@
|
||||||
{
|
{
|
||||||
"icon": "./assets/feather/heart.svg",
|
"icon": "./assets/feather/heart.svg",
|
||||||
"id": "love",
|
"id": "love",
|
||||||
"name": "Love",
|
"name": app.getLz("action.love"),
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"disabled": true,
|
"disabled": true,
|
||||||
"action": function() {
|
"action": function() {
|
||||||
|
@ -331,7 +331,7 @@
|
||||||
"icon": "./assets/feather/heart.svg",
|
"icon": "./assets/feather/heart.svg",
|
||||||
"id": "unlove",
|
"id": "unlove",
|
||||||
"active": true,
|
"active": true,
|
||||||
"name": "Unlove",
|
"name": app.getLz("action.unlove"),
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"action": function() {
|
"action": function() {
|
||||||
app.unlove(self.item)
|
app.unlove(self.item)
|
||||||
|
@ -340,7 +340,7 @@
|
||||||
{
|
{
|
||||||
"icon": "./assets/feather/thumbs-down.svg",
|
"icon": "./assets/feather/thumbs-down.svg",
|
||||||
"id": "dislike",
|
"id": "dislike",
|
||||||
"name": "Dislike",
|
"name": app.getLz("action.dislike"),
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"disabled": true,
|
"disabled": true,
|
||||||
"action": function() {
|
"action": function() {
|
||||||
|
@ -350,7 +350,7 @@
|
||||||
{
|
{
|
||||||
"icon": "./assets/feather/thumbs-down.svg",
|
"icon": "./assets/feather/thumbs-down.svg",
|
||||||
"id": "undo_dislike",
|
"id": "undo_dislike",
|
||||||
"name": "Undo dislike",
|
"name": app.getLz("action.undoDislike"),
|
||||||
"active": true,
|
"active": true,
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"action": function() {
|
"action": function() {
|
||||||
|
@ -362,7 +362,7 @@
|
||||||
{
|
{
|
||||||
"icon": "./assets/feather/list.svg",
|
"icon": "./assets/feather/list.svg",
|
||||||
"id": "addToPlaylist",
|
"id": "addToPlaylist",
|
||||||
"name": "Add to Playlist...",
|
"name": app.getLz("action.addToPlaylist") + " ...",
|
||||||
"action": function() {
|
"action": function() {
|
||||||
app.promptAddToPlaylist()
|
app.promptAddToPlaylist()
|
||||||
}
|
}
|
||||||
|
@ -370,7 +370,7 @@
|
||||||
{
|
{
|
||||||
"id": "addToLibrary",
|
"id": "addToLibrary",
|
||||||
"icon": "./assets/feather/plus.svg",
|
"icon": "./assets/feather/plus.svg",
|
||||||
"name": "Add to library",
|
"name": app.getLz("action.addToLibrary") + " ...",
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"disabled": true,
|
"disabled": true,
|
||||||
"action": function() {
|
"action": function() {
|
||||||
|
@ -383,7 +383,7 @@
|
||||||
{
|
{
|
||||||
"id": "removeFromLibrary",
|
"id": "removeFromLibrary",
|
||||||
"icon": "./assets/feather/x-circle.svg",
|
"icon": "./assets/feather/x-circle.svg",
|
||||||
"name": "Remove from library",
|
"name": app.getLz("action.removeFromLibrary"),
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"action": async function() {
|
"action": async function() {
|
||||||
console.log("remove");
|
console.log("remove");
|
||||||
|
@ -394,7 +394,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Play Next",
|
"name": app.getLz("action.playNext"),
|
||||||
"icon": "./assets/arrow-bend-up.svg",
|
"icon": "./assets/arrow-bend-up.svg",
|
||||||
"action": function() {
|
"action": function() {
|
||||||
app.mk.playNext({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id })
|
app.mk.playNext({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id })
|
||||||
|
@ -403,7 +403,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Play Later",
|
"name": app.getLz("action.playLater"),
|
||||||
"icon": "./assets/arrow-bend-down.svg",
|
"icon": "./assets/arrow-bend-down.svg",
|
||||||
"action": function() {
|
"action": function() {
|
||||||
app.mk.playLater({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id })
|
app.mk.playLater({ [self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id })
|
||||||
|
@ -413,7 +413,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "./assets/feather/share.svg",
|
"icon": "./assets/feather/share.svg",
|
||||||
"name": "Share",
|
"name": app.getLz("action.share"),
|
||||||
"action": function() {
|
"action": function() {
|
||||||
self.app.copyToClipboard(self.item.attributes.url)
|
self.app.copyToClipboard(self.item.attributes.url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,8 +263,8 @@
|
||||||
@click="trackSelect(song)">
|
@click="trackSelect(song)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="song.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(song.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(song.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -284,8 +284,8 @@
|
||||||
@click="trackSelect(song)">
|
@click="trackSelect(song)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="song.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(song.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(song.attributes.artwork?.url ?? './assets/MissingArtwork.svg' )}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -307,8 +307,8 @@
|
||||||
@click="showAlbum(album.id)">
|
@click="showAlbum(album.id)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="album.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(album.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(album.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -328,8 +328,8 @@
|
||||||
@click="showAlbum(album.id, true)">
|
@click="showAlbum(album.id, true)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="album.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(album.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(album.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -352,8 +352,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image artist"
|
<div class="list-entry-image artist"
|
||||||
v-if="artist.attributes.artwork"
|
:style="{'--artwork': getAlbumArtUrlList(artist?.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
:style="{'--artwork': getAlbumArtUrlList(artist.attributes.artwork.url)}">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -373,8 +372,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image artist"
|
<div class="list-entry-image artist"
|
||||||
v-if="artist.attributes.artwork"
|
:style="{'--artwork': getAlbumArtUrlList(artist.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
:style="{'--artwork': getAlbumArtUrlList(artist.attributes.artwork.url)}">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -396,8 +394,8 @@
|
||||||
@click="showPlaylist(playlist.attributes.playParams.id)">
|
@click="showPlaylist(playlist.attributes.playParams.id)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="playlist.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(playlist.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(playlist.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -418,8 +416,8 @@
|
||||||
>
|
>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="playlist.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(playlist.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(playlist.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -452,7 +450,7 @@
|
||||||
<div class="col-auto flex-center" v-if="search.selected.attributes.artwork"
|
<div class="col-auto flex-center" v-if="search.selected.attributes.artwork"
|
||||||
style="display:flex;align-items: center;">
|
style="display:flex;align-items: center;">
|
||||||
<div class="list-entry-image"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(search.selected.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(search.selected.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center" style="display:flex;align-items: center;">
|
<div class="col flex-center" style="display:flex;align-items: center;">
|
||||||
|
@ -625,17 +623,35 @@
|
||||||
<div class="artist-header" v-if="artistPage.data.attributes['artwork']"
|
<div class="artist-header" v-if="artistPage.data.attributes['artwork']"
|
||||||
:style="getMediaPalette(artistPage.data.attributes)">
|
:style="getMediaPalette(artistPage.data.attributes)">
|
||||||
<div class="artist-header-portrait"
|
<div class="artist-header-portrait"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(artistPage.data.attributes['artwork']['url'], 600)}">
|
:style="{'--artwork': getAlbumArtUrlList(artistPage.data.attributes['artwork']['url'] ?? './assets/MissingArtwork.svg', 600)}">
|
||||||
</div>
|
</div>
|
||||||
<h2>{{ artistPage.data.attributes["name"] }}</h2>
|
<h2>{{ artistPage.data.attributes["name"] }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="md-body artist-body">
|
<div class="md-body artist-body">
|
||||||
<h2>Songs</h2>
|
<h2>Songs</h2>
|
||||||
<div class="song-scroller-horizontal">
|
<div class="song-scroller-horizontal">
|
||||||
<button v-for="song in artistPage.data.relationships['songs'].data"
|
<div class="list-entry artist-song" v-for="song in artistPage.data.relationships['songs'].data"
|
||||||
|
@click="trackSelect(song)">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto flex-center">
|
||||||
|
<div class="list-entry-image"
|
||||||
|
:style="{'--artwork': getAlbumArtUrlList(song.attributes?.artwork?.url ?? './assets/MissingArtwork.svg', 45)}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col flex-center">
|
||||||
|
<div class="list-entry-name">
|
||||||
|
{{ song.attributes.name }}
|
||||||
|
</div>
|
||||||
|
<div class="list-entry-artist">
|
||||||
|
{{ song.attributes.artistName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <button v-for="song in artistPage.data.relationships['songs'].data"
|
||||||
class="song-placeholder" @click="trackSelect(song)">
|
class="song-placeholder" @click="trackSelect(song)">
|
||||||
{{ song.attributes.name }}
|
{{ song.attributes.name }}
|
||||||
</button>
|
</button> -->
|
||||||
</div>
|
</div>
|
||||||
<h2>Albums</h2>
|
<h2>Albums</h2>
|
||||||
<div class="mediaitem-scroller-horizontal">
|
<div class="mediaitem-scroller-horizontal">
|
||||||
|
@ -712,8 +728,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="song.item.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(song.item.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(song.item.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
@ -807,7 +823,7 @@
|
||||||
<div class="album-body-container">
|
<div class="album-body-container">
|
||||||
<div class="md-header">
|
<div class="md-header">
|
||||||
<div class="albumpage-artwork"
|
<div class="albumpage-artwork"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(albumPage.data.attributes['artwork'] ? albumPage.data.attributes['artwork']['url'] : '', 300)}">
|
:style="{'--artwork': getAlbumArtUrlList(albumPage.data.attributes['artwork'] ? albumPage.data.attributes['artwork']['url'] : './assets/MissingArtwork.svg', 300)}">
|
||||||
</div>
|
</div>
|
||||||
<div class="albumpage-album-name">
|
<div class="albumpage-album-name">
|
||||||
{{ albumPage.data.attributes["name"] }}
|
{{ albumPage.data.attributes["name"] }}
|
||||||
|
@ -853,8 +869,8 @@
|
||||||
@click="trackSelect(song)">
|
@click="trackSelect(song)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto flex-center">
|
<div class="col-auto flex-center">
|
||||||
<div class="list-entry-image" v-if="song.attributes.artwork"
|
<div class="list-entry-image"
|
||||||
:style="{'--artwork': getAlbumArtUrlList(song.attributes.artwork.url)}">
|
:style="{'--artwork': getAlbumArtUrlList(song.attributes?.artwork?.url ?? './assets/MissingArtwork.svg')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col flex-center">
|
<div class="col flex-center">
|
||||||
|
|
|
@ -262,29 +262,7 @@
|
||||||
ue.pop(), (ce.target = ue[ue.length - 1]);
|
ue.pop(), (ce.target = ue[ue.length - 1]);
|
||||||
}
|
}
|
||||||
var pe = function (e, t, n, r, i, o, a, s) {
|
var pe = function (e, t, n, r, i, o, a, s) {
|
||||||
(this.tag = e),
|
(this.tag = e), (this.data = t), (this.children = n), (this.text = r), (this.elm = i), (this.ns = void 0), (this.context = o), (this.fnContext = void 0), (this.fnOptions = void 0), (this.fnScopeId = void 0), (this.key = t && t.key), (this.componentOptions = a), (this.componentInstance = void 0), (this.parent = void 0), (this.raw = !1), (this.isStatic = !1), (this.isRootInsert = !0), (this.isComment = !1), (this.isCloned = !1), (this.isOnce = !1), (this.asyncFactory = s), (this.asyncMeta = void 0), (this.isAsyncPlaceholder = !1);
|
||||||
(this.data = t),
|
|
||||||
(this.children = n),
|
|
||||||
(this.text = r),
|
|
||||||
(this.elm = i),
|
|
||||||
(this.ns = void 0),
|
|
||||||
(this.context = o),
|
|
||||||
(this.fnContext = void 0),
|
|
||||||
(this.fnOptions = void 0),
|
|
||||||
(this.fnScopeId = void 0),
|
|
||||||
(this.key = t && t.key),
|
|
||||||
(this.componentOptions = a),
|
|
||||||
(this.componentInstance = void 0),
|
|
||||||
(this.parent = void 0),
|
|
||||||
(this.raw = !1),
|
|
||||||
(this.isStatic = !1),
|
|
||||||
(this.isRootInsert = !0),
|
|
||||||
(this.isComment = !1),
|
|
||||||
(this.isCloned = !1),
|
|
||||||
(this.isOnce = !1),
|
|
||||||
(this.asyncFactory = s),
|
|
||||||
(this.asyncMeta = void 0),
|
|
||||||
(this.isAsyncPlaceholder = !1);
|
|
||||||
},
|
},
|
||||||
de = { child: { configurable: !0 } };
|
de = { child: { configurable: !0 } };
|
||||||
(de.child.get = function () {
|
(de.child.get = function () {
|
||||||
|
@ -696,8 +674,7 @@
|
||||||
}
|
}
|
||||||
function it(e, n, i, o, a, s) {
|
function it(e, n, i, o, a, s) {
|
||||||
var c, u, l, f;
|
var c, u, l, f;
|
||||||
for (c in e)
|
for (c in e) (u = e[c]), (l = n[c]), (f = nt(c)), t(u) || (t(l) ? (t(u.fns) && (u = e[c] = rt(u, s)), r(f.once) && (u = e[c] = a(f.name, u, f.capture)), i(f.name, u, f.capture, f.passive, f.params)) : u !== l && ((l.fns = u), (e[c] = l)));
|
||||||
(u = e[c]), (l = n[c]), (f = nt(c)), t(u) || (t(l) ? (t(u.fns) && (u = e[c] = rt(u, s)), r(f.once) && (u = e[c] = a(f.name, u, f.capture)), i(f.name, u, f.capture, f.passive, f.params)) : u !== l && ((l.fns = u), (e[c] = l)));
|
|
||||||
for (c in n) t(e[c]) && o((f = nt(c)).name, n[c], f.capture);
|
for (c in n) t(e[c]) && o((f = nt(c)).name, n[c], f.capture);
|
||||||
}
|
}
|
||||||
function ot(e, i, o) {
|
function ot(e, i, o) {
|
||||||
|
@ -723,20 +700,7 @@
|
||||||
? (function e(o, a) {
|
? (function e(o, a) {
|
||||||
var s = [];
|
var s = [];
|
||||||
var c, u, l, f;
|
var c, u, l, f;
|
||||||
for (c = 0; c < o.length; c++)
|
for (c = 0; c < o.length; c++) t((u = o[c])) || "boolean" == typeof u || ((l = s.length - 1), (f = s[l]), Array.isArray(u) ? u.length > 0 && (ct((u = e(u, (a || "") + "_" + c))[0]) && ct(f) && ((s[l] = he(f.text + u[0].text)), u.shift()), s.push.apply(s, u)) : i(u) ? (ct(f) ? (s[l] = he(f.text + u)) : "" !== u && s.push(he(u))) : ct(u) && ct(f) ? (s[l] = he(f.text + u.text)) : (r(o._isVList) && n(u.tag) && t(u.key) && n(a) && (u.key = "__vlist" + a + "_" + c + "__"), s.push(u)));
|
||||||
t((u = o[c])) ||
|
|
||||||
"boolean" == typeof u ||
|
|
||||||
((l = s.length - 1),
|
|
||||||
(f = s[l]),
|
|
||||||
Array.isArray(u)
|
|
||||||
? u.length > 0 && (ct((u = e(u, (a || "") + "_" + c))[0]) && ct(f) && ((s[l] = he(f.text + u[0].text)), u.shift()), s.push.apply(s, u))
|
|
||||||
: i(u)
|
|
||||||
? ct(f)
|
|
||||||
? (s[l] = he(f.text + u))
|
|
||||||
: "" !== u && s.push(he(u))
|
|
||||||
: ct(u) && ct(f)
|
|
||||||
? (s[l] = he(f.text + u.text))
|
|
||||||
: (r(o._isVList) && n(u.tag) && t(u.key) && n(a) && (u.key = "__vlist" + a + "_" + c + "__"), s.push(u)));
|
|
||||||
return s;
|
return s;
|
||||||
})(e)
|
})(e)
|
||||||
: void 0;
|
: void 0;
|
||||||
|
@ -1166,8 +1130,7 @@
|
||||||
var u, l;
|
var u, l;
|
||||||
if ("string" == typeof i) {
|
if ("string" == typeof i) {
|
||||||
var f;
|
var f;
|
||||||
(l = (e.$vnode && e.$vnode.ns) || F.getTagNamespace(i)),
|
(l = (e.$vnode && e.$vnode.ns) || F.getTagNamespace(i)), (u = F.isReservedTag(i) ? new pe(F.parsePlatformTagName(i), a, s, void 0, void 0, e) : (a && a.pre) || !n((f = Le(e.$options, "components", i))) ? new pe(i, a, s, void 0, void 0, e) : Mt(f, a, e, s, i));
|
||||||
(u = F.isReservedTag(i) ? new pe(F.parsePlatformTagName(i), a, s, void 0, void 0, e) : (a && a.pre) || !n((f = Le(e.$options, "components", i))) ? new pe(i, a, s, void 0, void 0, e) : Mt(f, a, e, s, i));
|
|
||||||
} else u = Mt(i, a, e, s);
|
} else u = Mt(i, a, e, s);
|
||||||
return Array.isArray(u)
|
return Array.isArray(u)
|
||||||
? u
|
? u
|
||||||
|
@ -1862,9 +1825,7 @@
|
||||||
(function (e) {
|
(function (e) {
|
||||||
I.forEach(function (t) {
|
I.forEach(function (t) {
|
||||||
e[t] = function (e, n) {
|
e[t] = function (e, n) {
|
||||||
return n
|
return n ? ("component" === t && s(n) && ((n.name = n.name || e), (n = this.options._base.extend(n))), "directive" === t && "function" == typeof n && (n = { bind: n, update: n }), (this.options[t + "s"][e] = n), n) : this.options[t + "s"][e];
|
||||||
? ("component" === t && s(n) && ((n.name = n.name || e), (n = this.options._base.extend(n))), "directive" === t && "function" == typeof n && (n = { bind: n, update: n }), (this.options[t + "s"][e] = n), n)
|
|
||||||
: this.options[t + "s"][e];
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
})(e);
|
})(e);
|
||||||
|
@ -1887,9 +1848,7 @@
|
||||||
Mn = function (e, t) {
|
Mn = function (e, t) {
|
||||||
return Bn(t) || "false" === t ? "false" : "contenteditable" === e && In(t) ? t : "true";
|
return Bn(t) || "false" === t ? "false" : "contenteditable" === e && In(t) ? t : "true";
|
||||||
},
|
},
|
||||||
Fn = p(
|
Fn = p("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),
|
||||||
"allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"
|
|
||||||
),
|
|
||||||
Pn = "http://www.w3.org/1999/xlink",
|
Pn = "http://www.w3.org/1999/xlink",
|
||||||
Rn = function (e) {
|
Rn = function (e) {
|
||||||
return ":" === e.charAt(5) && "xlink" === e.slice(0, 5);
|
return ":" === e.charAt(5) && "xlink" === e.slice(0, 5);
|
||||||
|
@ -2109,19 +2068,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function hr(e, t, n, r) {
|
function hr(e, t, n, r) {
|
||||||
r || e.tagName.indexOf("-") > -1
|
r || e.tagName.indexOf("-") > -1 ? mr(e, t, n) : Fn(t) ? (Bn(n) ? e.removeAttribute(t) : ((n = "allowfullscreen" === t && "EMBED" === e.tagName ? "true" : t), e.setAttribute(t, n))) : Ln(t) ? e.setAttribute(t, Mn(t, n)) : Rn(t) ? (Bn(n) ? e.removeAttributeNS(Pn, Hn(t)) : e.setAttributeNS(Pn, t, n)) : mr(e, t, n);
|
||||||
? mr(e, t, n)
|
|
||||||
: Fn(t)
|
|
||||||
? Bn(n)
|
|
||||||
? e.removeAttribute(t)
|
|
||||||
: ((n = "allowfullscreen" === t && "EMBED" === e.tagName ? "true" : t), e.setAttribute(t, n))
|
|
||||||
: Ln(t)
|
|
||||||
? e.setAttribute(t, Mn(t, n))
|
|
||||||
: Rn(t)
|
|
||||||
? Bn(n)
|
|
||||||
? e.removeAttributeNS(Pn, Hn(t))
|
|
||||||
: e.setAttributeNS(Pn, t, n)
|
|
||||||
: mr(e, t, n);
|
|
||||||
}
|
}
|
||||||
function mr(e, t, n) {
|
function mr(e, t, n) {
|
||||||
if (Bn(n)) e.removeAttribute(t);
|
if (Bn(n)) e.removeAttribute(t);
|
||||||
|
@ -2264,15 +2211,7 @@
|
||||||
}
|
}
|
||||||
function Mr(t, n, r, i, o, a, s, c) {
|
function Mr(t, n, r, i, o, a, s, c) {
|
||||||
var u;
|
var u;
|
||||||
(i = i || e).right
|
(i = i || e).right ? (c ? (n = "(" + n + ")==='click'?'contextmenu':(" + n + ")") : "click" === n && ((n = "contextmenu"), delete i.right)) : i.middle && (c ? (n = "(" + n + ")==='click'?'mouseup':(" + n + ")") : "click" === n && (n = "mouseup")), i.capture && (delete i.capture, (n = Ir("!", n, c))), i.once && (delete i.once, (n = Ir("~", n, c))), i.passive && (delete i.passive, (n = Ir("&", n, c))), i.native ? (delete i.native, (u = t.nativeEvents || (t.nativeEvents = {}))) : (u = t.events || (t.events = {}));
|
||||||
? c
|
|
||||||
? (n = "(" + n + ")==='click'?'contextmenu':(" + n + ")")
|
|
||||||
: "click" === n && ((n = "contextmenu"), delete i.right)
|
|
||||||
: i.middle && (c ? (n = "(" + n + ")==='click'?'mouseup':(" + n + ")") : "click" === n && (n = "mouseup")),
|
|
||||||
i.capture && (delete i.capture, (n = Ir("!", n, c))),
|
|
||||||
i.once && (delete i.once, (n = Ir("~", n, c))),
|
|
||||||
i.passive && (delete i.passive, (n = Ir("&", n, c))),
|
|
||||||
i.native ? (delete i.native, (u = t.nativeEvents || (t.nativeEvents = {}))) : (u = t.events || (t.events = {}));
|
|
||||||
var l = Hr({ value: r.trim(), dynamic: c }, s);
|
var l = Hr({ value: r.trim(), dynamic: c }, s);
|
||||||
i !== e && (l.modifiers = i);
|
i !== e && (l.modifiers = i);
|
||||||
var f = u[n];
|
var f = u[n];
|
||||||
|
@ -2558,9 +2497,7 @@
|
||||||
Oi = "transitionend",
|
Oi = "transitionend",
|
||||||
Si = "animation",
|
Si = "animation",
|
||||||
Ti = "animationend";
|
Ti = "animationend";
|
||||||
Ci &&
|
Ci && (void 0 === window.ontransitionend && void 0 !== window.onwebkittransitionend && ((Ai = "WebkitTransition"), (Oi = "webkitTransitionEnd")), void 0 === window.onanimationend && void 0 !== window.onwebkitanimationend && ((Si = "WebkitAnimation"), (Ti = "webkitAnimationEnd")));
|
||||||
(void 0 === window.ontransitionend && void 0 !== window.onwebkittransitionend && ((Ai = "WebkitTransition"), (Oi = "webkitTransitionEnd")),
|
|
||||||
void 0 === window.onanimationend && void 0 !== window.onwebkitanimationend && ((Si = "WebkitAnimation"), (Ti = "webkitAnimationEnd")));
|
|
||||||
var Ni = V
|
var Ni = V
|
||||||
? window.requestAnimationFrame
|
? window.requestAnimationFrame
|
||||||
? window.requestAnimationFrame.bind(window)
|
? window.requestAnimationFrame.bind(window)
|
||||||
|
@ -2638,30 +2575,7 @@
|
||||||
n(i._leaveCb) && ((i._leaveCb.cancelled = !0), i._leaveCb());
|
n(i._leaveCb) && ((i._leaveCb.cancelled = !0), i._leaveCb());
|
||||||
var a = $i(e.data.transition);
|
var a = $i(e.data.transition);
|
||||||
if (!t(a) && !n(i._enterCb) && 1 === i.nodeType) {
|
if (!t(a) && !n(i._enterCb) && 1 === i.nodeType) {
|
||||||
for (
|
for (var s = a.css, c = a.type, u = a.enterClass, l = a.enterToClass, p = a.enterActiveClass, d = a.appearClass, v = a.appearToClass, h = a.appearActiveClass, m = a.beforeEnter, y = a.enter, g = a.afterEnter, _ = a.enterCancelled, b = a.beforeAppear, $ = a.appear, w = a.afterAppear, C = a.appearCancelled, x = a.duration, k = Zt, A = Zt.$vnode; A && A.parent; ) (k = A.context), (A = A.parent);
|
||||||
var s = a.css,
|
|
||||||
c = a.type,
|
|
||||||
u = a.enterClass,
|
|
||||||
l = a.enterToClass,
|
|
||||||
p = a.enterActiveClass,
|
|
||||||
d = a.appearClass,
|
|
||||||
v = a.appearToClass,
|
|
||||||
h = a.appearActiveClass,
|
|
||||||
m = a.beforeEnter,
|
|
||||||
y = a.enter,
|
|
||||||
g = a.afterEnter,
|
|
||||||
_ = a.enterCancelled,
|
|
||||||
b = a.beforeAppear,
|
|
||||||
$ = a.appear,
|
|
||||||
w = a.afterAppear,
|
|
||||||
C = a.appearCancelled,
|
|
||||||
x = a.duration,
|
|
||||||
k = Zt,
|
|
||||||
A = Zt.$vnode;
|
|
||||||
A && A.parent;
|
|
||||||
|
|
||||||
)
|
|
||||||
(k = A.context), (A = A.parent);
|
|
||||||
var O = !k._isMounted || !e.isRootInsert;
|
var O = !k._isMounted || !e.isRootInsert;
|
||||||
if (!O || $ || "" === $) {
|
if (!O || $ || "" === $) {
|
||||||
var S = O && d ? d : u,
|
var S = O && d ? d : u,
|
||||||
|
@ -2786,11 +2700,7 @@
|
||||||
var f = e.data,
|
var f = e.data,
|
||||||
p = e.children,
|
p = e.children,
|
||||||
m = e.tag;
|
m = e.tag;
|
||||||
n(m)
|
n(m) ? ((e.elm = e.ns ? u.createElementNS(e.ns, m) : u.createElement(m, e)), g(e), h(e, p, t), n(f) && y(e, t), v(i, e.elm, o)) : r(e.isComment) ? ((e.elm = u.createComment(e.text)), v(i, e.elm, o)) : ((e.elm = u.createTextNode(e.text)), v(i, e.elm, o));
|
||||||
? ((e.elm = e.ns ? u.createElementNS(e.ns, m) : u.createElement(m, e)), g(e), h(e, p, t), n(f) && y(e, t), v(i, e.elm, o))
|
|
||||||
: r(e.isComment)
|
|
||||||
? ((e.elm = u.createComment(e.text)), v(i, e.elm, o))
|
|
||||||
: ((e.elm = u.createTextNode(e.text)), v(i, e.elm, o));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function d(e, t) {
|
function d(e, t) {
|
||||||
|
@ -2894,9 +2804,7 @@
|
||||||
? (x(h, b, o, i, y), w && u.insertBefore(e, h.elm, u.nextSibling(m.elm)), (h = r[++p]), (b = i[--y]))
|
? (x(h, b, o, i, y), w && u.insertBefore(e, h.elm, u.nextSibling(m.elm)), (h = r[++p]), (b = i[--y]))
|
||||||
: or(m, g)
|
: or(m, g)
|
||||||
? (x(m, g, o, i, d), w && u.insertBefore(e, m.elm, h.elm), (m = r[--v]), (g = i[++d]))
|
? (x(m, g, o, i, d), w && u.insertBefore(e, m.elm, h.elm), (m = r[--v]), (g = i[++d]))
|
||||||
: (t(s) && (s = ar(r, p, v)),
|
: (t(s) && (s = ar(r, p, v)), t((c = n(g.key) ? s[g.key] : C(g, r, p, v))) ? f(g, o, e, h.elm, !1, i, d) : or((l = r[c]), g) ? (x(l, g, o, i, d), (r[c] = void 0), w && u.insertBefore(e, l.elm, h.elm)) : f(g, o, e, h.elm, !1, i, d), (g = i[++d]));
|
||||||
t((c = n(g.key) ? s[g.key] : C(g, r, p, v))) ? f(g, o, e, h.elm, !1, i, d) : or((l = r[c]), g) ? (x(l, g, o, i, d), (r[c] = void 0), w && u.insertBefore(e, l.elm, h.elm)) : f(g, o, e, h.elm, !1, i, d),
|
|
||||||
(g = i[++d]));
|
|
||||||
p > v ? _(e, t(i[y + 1]) ? null : i[y + 1].elm, i, d, y, o) : d > y && $(r, p, v);
|
p > v ? _(e, t(i[y + 1]) ? null : i[y + 1].elm, i, d, y, o) : d > y && $(r, p, v);
|
||||||
})(p, h, y, o, l)
|
})(p, h, y, o, l)
|
||||||
: n(y)
|
: n(y)
|
||||||
|
@ -3015,8 +2923,7 @@
|
||||||
})
|
})
|
||||||
: Ji(e, t, n.context),
|
: Ji(e, t, n.context),
|
||||||
(e._vOptions = [].map.call(e.options, Zi)))
|
(e._vOptions = [].map.call(e.options, Zi)))
|
||||||
: ("textarea" === n.tag || Yn(e.type)) &&
|
: ("textarea" === n.tag || Yn(e.type)) && ((e._vModifiers = t.modifiers), t.modifiers.lazy || (e.addEventListener("compositionstart", Gi), e.addEventListener("compositionend", Xi), e.addEventListener("change", Xi), W && (e.vmodel = !0)));
|
||||||
((e._vModifiers = t.modifiers), t.modifiers.lazy || (e.addEventListener("compositionstart", Gi), e.addEventListener("compositionend", Xi), e.addEventListener("change", Xi), W && (e.vmodel = !0)));
|
|
||||||
},
|
},
|
||||||
componentUpdated: function (e, t, n) {
|
componentUpdated: function (e, t, n) {
|
||||||
if ("select" === n.tag) {
|
if ("select" === n.tag) {
|
||||||
|
@ -3378,9 +3285,7 @@
|
||||||
},
|
},
|
||||||
$o = p("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),
|
$o = p("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),
|
||||||
wo = p("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),
|
wo = p("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),
|
||||||
Co = p(
|
Co = p("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),
|
||||||
"address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"
|
|
||||||
),
|
|
||||||
xo = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,
|
xo = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,
|
||||||
ko = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,
|
ko = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,
|
||||||
Ao = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + P.source + "]*",
|
Ao = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + P.source + "]*",
|
||||||
|
@ -3782,14 +3687,7 @@
|
||||||
for (t = 0, n = u.length; t < n; t++)
|
for (t = 0, n = u.length; t < n; t++)
|
||||||
if (((r = i = u[t].name), (o = u[t].value), Xo.test(r)))
|
if (((r = i = u[t].name), (o = u[t].value), Xo.test(r)))
|
||||||
if (((e.hasBindings = !0), (a = ma(r.replace(Xo, ""))) && (r = r.replace(ia, "")), ra.test(r)))
|
if (((e.hasBindings = !0), (a = ma(r.replace(Xo, ""))) && (r = r.replace(ia, "")), ra.test(r)))
|
||||||
(r = r.replace(ra, "")),
|
(r = r.replace(ra, "")), (o = Or(o)), (c = ta.test(r)) && (r = r.slice(1, -1)), a && (a.prop && !c && "innerHtml" === (r = b(r)) && (r = "innerHTML"), a.camel && !c && (r = b(r)), a.sync && ((s = Ur(o, "$event")), c ? Mr(e, '"update:"+(' + r + ")", s, null, !1, 0, u[t], !0) : (Mr(e, "update:" + b(r), s, null, !1, 0, u[t]), C(r) !== b(r) && Mr(e, "update:" + C(r), s, null, !1, 0, u[t])))), (a && a.prop) || (!e.component && Wo(e.tag, e.attrsMap.type, r)) ? Er(e, r, o, u[t], c) : jr(e, r, o, u[t], c);
|
||||||
(o = Or(o)),
|
|
||||||
(c = ta.test(r)) && (r = r.slice(1, -1)),
|
|
||||||
a &&
|
|
||||||
(a.prop && !c && "innerHtml" === (r = b(r)) && (r = "innerHTML"),
|
|
||||||
a.camel && !c && (r = b(r)),
|
|
||||||
a.sync && ((s = Ur(o, "$event")), c ? Mr(e, '"update:"+(' + r + ")", s, null, !1, 0, u[t], !0) : (Mr(e, "update:" + b(r), s, null, !1, 0, u[t]), C(r) !== b(r) && Mr(e, "update:" + C(r), s, null, !1, 0, u[t])))),
|
|
||||||
(a && a.prop) || (!e.component && Wo(e.tag, e.attrsMap.type, r)) ? Er(e, r, o, u[t], c) : jr(e, r, o, u[t], c);
|
|
||||||
else if (Go.test(r)) (r = r.replace(Go, "")), (c = ta.test(r)) && (r = r.slice(1, -1)), Mr(e, r, o, a, !1, 0, u[t], c);
|
else if (Go.test(r)) (r = r.replace(Go, "")), (c = ta.test(r)) && (r = r.slice(1, -1)), Mr(e, r, o, a, !1, 0, u[t], c);
|
||||||
else {
|
else {
|
||||||
var l = (r = r.replace(Xo, "")).match(na),
|
var l = (r = r.replace(Xo, "")).match(na),
|
||||||
|
@ -3884,8 +3782,7 @@
|
||||||
if (e.component) return Br(e, r, i), !1;
|
if (e.component) return Br(e, r, i), !1;
|
||||||
if ("select" === o)
|
if ("select" === o)
|
||||||
!(function (e, t, n) {
|
!(function (e, t, n) {
|
||||||
var r =
|
var r = 'var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return ' + (n && n.number ? "_n(val)" : "val") + "});";
|
||||||
'var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return ' + (n && n.number ? "_n(val)" : "val") + "});";
|
|
||||||
(r = r + " " + Ur(t, "$event.target.multiple ? $$selectedVal : $$selectedVal[0]")), Mr(e, "change", r, null, !0);
|
(r = r + " " + Ur(t, "$event.target.multiple ? $$selectedVal : $$selectedVal[0]")), Mr(e, "change", r, null, !0);
|
||||||
})(e, r, i);
|
})(e, r, i);
|
||||||
else if ("input" === o && "checkbox" === a)
|
else if ("input" === o && "checkbox" === a)
|
||||||
|
@ -3894,28 +3791,7 @@
|
||||||
i = Fr(e, "value") || "null",
|
i = Fr(e, "value") || "null",
|
||||||
o = Fr(e, "true-value") || "true",
|
o = Fr(e, "true-value") || "true",
|
||||||
a = Fr(e, "false-value") || "false";
|
a = Fr(e, "false-value") || "false";
|
||||||
Er(e, "checked", "Array.isArray(" + t + ")?_i(" + t + "," + i + ")>-1" + ("true" === o ? ":(" + t + ")" : ":_q(" + t + "," + o + ")")),
|
Er(e, "checked", "Array.isArray(" + t + ")?_i(" + t + "," + i + ")>-1" + ("true" === o ? ":(" + t + ")" : ":_q(" + t + "," + o + ")")), Mr(e, "change", "var $$a=" + t + ",$$el=$event.target,$$c=$$el.checked?(" + o + "):(" + a + ");if(Array.isArray($$a)){var $$v=" + (r ? "_n(" + i + ")" : i) + ",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&(" + Ur(t, "$$a.concat([$$v])") + ")}else{$$i>-1&&(" + Ur(t, "$$a.slice(0,$$i).concat($$a.slice($$i+1))") + ")}}else{" + Ur(t, "$$c") + "}", null, !0);
|
||||||
Mr(
|
|
||||||
e,
|
|
||||||
"change",
|
|
||||||
"var $$a=" +
|
|
||||||
t +
|
|
||||||
",$$el=$event.target,$$c=$$el.checked?(" +
|
|
||||||
o +
|
|
||||||
"):(" +
|
|
||||||
a +
|
|
||||||
");if(Array.isArray($$a)){var $$v=" +
|
|
||||||
(r ? "_n(" + i + ")" : i) +
|
|
||||||
",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&(" +
|
|
||||||
Ur(t, "$$a.concat([$$v])") +
|
|
||||||
")}else{$$i>-1&&(" +
|
|
||||||
Ur(t, "$$a.slice(0,$$i).concat($$a.slice($$i+1))") +
|
|
||||||
")}}else{" +
|
|
||||||
Ur(t, "$$c") +
|
|
||||||
"}",
|
|
||||||
null,
|
|
||||||
!0
|
|
||||||
);
|
|
||||||
})(e, r, i);
|
})(e, r, i);
|
||||||
else if ("input" === o && "radio" === a)
|
else if ("input" === o && "radio" === a)
|
||||||
!(function (e, t, n) {
|
!(function (e, t, n) {
|
||||||
|
@ -4243,19 +4119,7 @@
|
||||||
for (r = 0, i = n.length; r < i; r++) {
|
for (r = 0, i = n.length; r < i; r++) {
|
||||||
(o = n[r]), (a = !0);
|
(o = n[r]), (a = !0);
|
||||||
var u = t.directives[o.name];
|
var u = t.directives[o.name];
|
||||||
u && (a = !!u(e, o, t.warn)),
|
u && (a = !!u(e, o, t.warn)), a && ((c = !0), (s += '{name:"' + o.name + '",rawName:"' + o.rawName + '"' + (o.value ? ",value:(" + o.value + "),expression:" + JSON.stringify(o.value) : "") + (o.arg ? ",arg:" + (o.isDynamicArg ? o.arg : '"' + o.arg + '"') : "") + (o.modifiers ? ",modifiers:" + JSON.stringify(o.modifiers) : "") + "},"));
|
||||||
a &&
|
|
||||||
((c = !0),
|
|
||||||
(s +=
|
|
||||||
'{name:"' +
|
|
||||||
o.name +
|
|
||||||
'",rawName:"' +
|
|
||||||
o.rawName +
|
|
||||||
'"' +
|
|
||||||
(o.value ? ",value:(" + o.value + "),expression:" + JSON.stringify(o.value) : "") +
|
|
||||||
(o.arg ? ",arg:" + (o.isDynamicArg ? o.arg : '"' + o.arg + '"') : "") +
|
|
||||||
(o.modifiers ? ",modifiers:" + JSON.stringify(o.modifiers) : "") +
|
|
||||||
"},"));
|
|
||||||
}
|
}
|
||||||
if (c) return s.slice(0, -1) + "]";
|
if (c) return s.slice(0, -1) + "]";
|
||||||
})(e, t);
|
})(e, t);
|
||||||
|
@ -4408,9 +4272,7 @@
|
||||||
function Ya(e) {
|
function Ya(e) {
|
||||||
return e.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
return e.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
||||||
}
|
}
|
||||||
new RegExp(
|
new RegExp("\\b" + "do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,super,throw,while,yield,delete,export,import,return,switch,default,extends,finally,continue,debugger,function,arguments".split(",").join("\\b|\\b") + "\\b");
|
||||||
"\\b" + "do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,super,throw,while,yield,delete,export,import,return,switch,default,extends,finally,continue,debugger,function,arguments".split(",").join("\\b|\\b") + "\\b"
|
|
||||||
);
|
|
||||||
function Qa(e, t) {
|
function Qa(e, t) {
|
||||||
try {
|
try {
|
||||||
return new Function(e);
|
return new Function(e);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"inlineSources": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue