Compare commits

...

44 commits
v1.6.1 ... main

Author SHA1 Message Date
Core
fea44a75cb
automated release 2024-05-18 19:32:23 +01:00
Core
7782e430aa
Merge branch 'main' of github.com:ciderapp/Cider 2024-05-18 19:22:57 +01:00
Core
237c4eff02
chore: release v1.6.3 2024-05-18 19:22:29 +01:00
Shawn
e814b13b22
Implement MPRIS Raise method to allow showing the window (#1845)
* add functionality to raise window on mpris method call

* since electron tray doesn't support double click on linux, open on single click there
2024-05-18 19:07:49 +01:00
Core
b1d0f698a1
Disable azure pipelines 2024-05-18 16:31:08 +01:00
Core
05d32089dd
fix: Bump to ESM and update all deps (#1851)
* chore: Bump various packages

* feat: Update everything to ESM

* fix: building and porting js to cjs
2024-05-18 16:29:24 +01:00
Core
89ee84b7e4
Create dependabot.yml 2024-05-18 15:55:46 +01:00
cryptofyre
b1b828dde2 chore: Prettified Code
[ci skip]
2024-03-01 04:11:17 +00:00
cryptofyre
1b4d1c8d3c
Update support-notice.yml 2024-02-29 22:10:42 -06:00
Core
53d1b80ee1
Merge pull request #1793 from ciderapp/snyk-upgrade-6b2b38d8654fd2bfd7d337f4cea30ffa
[Snyk] Upgrade @crowdin/ota-client from 1.0.0 to 1.1.0
2023-11-05 19:18:25 +00:00
Core
30bb111f52
Merge pull request #1781 from ciderapp/snyk-upgrade-7b8c15cb6fb98f39891262f14401e413
[Snyk] Upgrade @sentry/integrations from 7.58.1 to 7.69.0
2023-11-05 19:18:17 +00:00
Core
868fc9c08b
Merge pull request #1780 from ciderapp/snyk-upgrade-2c733606982a2f290d9f4d8f266d9a1a
[Snyk] Upgrade ws from 8.13.0 to 8.14.1
2023-11-05 19:18:11 +00:00
snyk-bot
b1e3e7ebe3
fix: upgrade @crowdin/ota-client from 1.0.0 to 1.1.0
Snyk has created this PR to upgrade @crowdin/ota-client from 1.0.0 to 1.1.0.

See this package in npm:


See this project in Snyk:
f28b84c2-c731-4fc4-9a1a-5a33cb90ef55?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-11-05 18:55:38 +00:00
snyk-bot
9adbd27402
fix: upgrade @sentry/integrations from 7.58.1 to 7.69.0
Snyk has created this PR to upgrade @sentry/integrations from 7.58.1 to 7.69.0.

See this package in npm:


See this project in Snyk:
f28b84c2-c731-4fc4-9a1a-5a33cb90ef55?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-10-05 05:09:07 +00:00
snyk-bot
41680a2d47
fix: upgrade ws from 8.13.0 to 8.14.1
Snyk has created this PR to upgrade ws from 8.13.0 to 8.14.1.

See this package in npm:


See this project in Snyk:
f28b84c2-c731-4fc4-9a1a-5a33cb90ef55?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-10-02 09:55:13 +00:00
booploops
c20001cd49
Update README.md 2023-08-12 16:08:03 -07:00
coredev-uk
dfc75d0bcb chore: Prettified Code
[ci skip]
2023-07-15 15:09:27 +00:00
Core
f8e16c546d
^ same again 2023-07-15 16:08:52 +01:00
Core
ff5ec2283d
Remove unused deps 2023-07-15 16:08:42 +01:00
Hudson Curren
58a2eefcda
Merge pull request #1742 from maple3142/fix-command-injection
Fix command injection in link handler
2023-07-02 13:31:41 +12:00
maple
38e57d5b3b
Fix command injection in link handler 2023-06-19 15:39:03 +08:00
yazninja
723a9e4df3
Update Azure CI 2023-06-07 10:49:39 +03:00
yazninja
6190b573ff update version to 1.6.2 2023-06-07 10:48:22 +03:00
yazninja
ac77672454
fix Audio Labs UI (#1736) 2023-06-07 10:46:57 +03:00
Core
24b62cb713
Update ci 2023-06-06 02:29:23 +01:00
coredev-uk
246450fde3 chore: Prettified Code
[ci skip]
2023-06-06 01:29:17 +00:00
Core
27a3a73124
Merge pull request #1735 from ciderapp/crowdin-api
janky ass implementation of crowdin api
2023-06-06 02:28:42 +01:00
Core
301f10055b
Implement crowdin api 2023-06-06 02:26:13 +01:00
Core
3a073468a4
Ok 2023-06-05 03:36:52 +01:00
Core
548732b273
Node 16 or later 2023-06-05 00:02:25 +01:00
Core
718034599e
Merge pull request #1730 from 00nktk/patch-1
fix SteamOS check
2023-06-02 23:03:39 +01:00
Nikita
68e1d3b99a
fix SteamOS check 2023-05-31 19:25:06 +03:00
Core
2d186dba76
No electron builder, your cannot publish 2023-05-25 21:33:58 +01:00
SoNothing
8fc789b753
Add EOL notice to README & issue correction in Upgrade modal (#1726) 2023-05-25 01:15:47 -07:00
Abhinav A
bbac83e485
Update README.md (#1716) 2023-05-24 10:27:39 -07:00
Core
bfd1655e92
Update azure-pipelines.yml 2023-05-24 15:10:15 +01:00
Core
3d6a2d9488
Update azure-pipelines.yml 2023-05-24 15:06:54 +01:00
Core
7deb8a161d
Fix macOS Building 2023-05-18 16:24:36 +01:00
yazninja
5071426b47
build macos in azure (#1711) 2023-05-15 12:38:18 +03:00
yazninja
a9da3bfab3 use node 18 2023-05-14 22:32:32 +03:00
yazninja
8061859298 add azure pipelines badge 2023-05-14 01:37:32 +03:00
yazninja
198dd9c5cf update upgrade details 2023-05-14 01:37:13 +03:00
yazninja
f02385fc0a replace, don't delete artifacts 2023-05-12 23:32:45 +03:00
yazninja
2cd4a3a272 pls upload now 2023-05-12 23:14:08 +03:00
66 changed files with 7183 additions and 7747 deletions

11
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"

View file

@ -1,131 +0,0 @@
name: "macOS build"
on:
push:
branches: [ main, stable ]
paths-ignore:
- 'README.md'
- 'SECURITY.md'
- '.gitmodules'
- '.gitignore'
- 'LICENSE'
- 'cider.lock'
jobs:
build-macos:
name: build-macos
runs-on: macos-11
permissions:
actions: read
contents: write
security-events: write
strategy:
fail-fast: false
matrix:
node-version: [ 18 ]
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '12.4'
- uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Run Version Script
env:
GH_REQUEST_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
sudo chmod +x resources/version.sh && ./resources/version.sh || true
- name: Sign in to EVS
run: |
python3 -m pip install --upgrade castlabs-evs
python3 -m castlabs_evs.account refresh -A ${{ secrets.EVS_ACCOUNT_NAME }} -P ${{ secrets.EVS_PASSWD }}
- name: Setup Environment
run: brew install automake #libtool autoconf
- name: Install and Configure Node Modules
run: |
npm run bootstrap
cp resources/verror-types node_modules/@types/verror/index.d.ts
cp resources/macPackager.js node_modules/app-builder-lib/out/macPackager.js
rm -r node_modules/pouchdb-node/node_modules/leveldown || true
rm -r node_modules/pouchdb-adapter-leveldb/node_modules/leveldown || true
- name: Build the DMG
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLEID: ${{ secrets.APPLEID }}
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
APPLE_ID: ${{ secrets.APPLEID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLEIDPASS }}
PSC_NAME: ${{ secrets.PSC_NAME }}
DEVELOPER_DIR: /Applications/Xcode_12.4.app/Contents/Developer
run: npm run dist -m --publish=never
- name: Add license to DMG
run: npx dmg-license resources/license.json dist/*.dmg
- name: Upload macOS Latest
uses: svenstaro/upload-release-action@v2
with:
repo_name: ciderapp/cider-releases
repo_token: ${{ secrets.RELEASE_TOKEN }}
file: dist/latest-mac.yml
tag: v${{ env.RELEASE_VERSION }}
- name: Import
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.CSC_LINK }}
p12-password: ${{ secrets.CSC_KEY_PASSWORD }}
- name: Build the PKG
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLEID: ${{ secrets.APPLEID }}
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
run: |
pkgbuild --component dist/mac-universal/Cider.app --install-location /Applications dist/Cider-${{ env.APP_VERSION }}-universal.pkg --sign ${{ secrets.PSC_NAME }}
xcrun altool --notarize-app --primary-bundle-id com.ciderapp.cider -f dist/Cider*.pkg --username ${{ secrets.APPLEID }} --password ${{ secrets.APPLEIDPASS }}
sleep 5m
xcrun stapler staple dist/*.pkg || true
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2.2.3
with:
name: Cider-macOS-${{ env.APP_VERSION }}
path: |
dist/*.dmg
dist/*.pkg
dist/latest-mac.yml
- name: Upload Files (DMG)
uses: svenstaro/upload-release-action@v2
with:
repo_name: ciderapp/cider-releases
repo_token: ${{ secrets.RELEASE_TOKEN }}
file: dist/Cider-${{ env.APP_VERSION }}-universal.dmg
tag: v${{ env.RELEASE_VERSION }}
- name: Upload Files (PKG)
uses: svenstaro/upload-release-action@v2
with:
repo_name: ciderapp/cider-releases
repo_token: ${{ secrets.RELEASE_TOKEN }}
file: dist/Cider-${{ env.APP_VERSION }}-universal.pkg
tag: v${{ env.RELEASE_VERSION }}

View file

@ -6,6 +6,39 @@ on:
- main
jobs:
compile-and-post:
runs-on: ubuntu-latest
container:
image: electronuserland/builder:wine
steps:
- name: Checkout 🛎
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Install Dependencies 📦
run: yarn install
- name: Build 🏗
run: yarn dist:all
- name: Upload Release 🚀
uses: softprops/action-gh-release@v2.0.5
with:
files: |
./dist/*.exe
./dist/*.deb
./dist/*.AppImage
./dist/*.rpm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
prettier:
runs-on: ubuntu-latest

View file

@ -14,5 +14,5 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
respondableId: ${{ github.event.issue.node_id }}
response: "Support for Cider 1.0 is in a reduced state. Do not expect replies or acknowledgement for issues that do not break full functionality of the app (Media playback, plugin functionality etc.).\n\nIf you are interested in joining the Cider 2 open alpha, you can join our Discord [here](https://discord.gg/AppleMusic)."
author: ${{ github.event.issue.user.login }}
response: "Cider 1.x is no longer actively maintained. We highly suggest moving to the newer version versions of the app available at https://cider.sh through official storefronts ex. Itch.io, or the Microsoft Store."
author: ${{ github.event.issue.user.login }}

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "src/cider-i18n"]
path = src/cider-i18n
url = https://github.com/ciderapp/cider-i18n

2
.nvmrc
View file

@ -1 +1 @@
16.17.0
20.2.0

View file

@ -1,5 +1,6 @@
src/renderer/*hls*.js
build/*
dist/*
src/renderer/lib/*
*.min.*
.pnpm-store

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,5 @@
yarnPath: .yarn/releases/yarn-3.5.1.cjs
nodeLinker: "node-modules"
compressionLevel: mixed
enableGlobalCache: false
nodeLinker: node-modules

View file

@ -1,5 +1,18 @@
## ⚠ Cider Classic has approached its End-of-Life status.
This application is now no longer being actively maintained.
No support will be given on Windows.
Thanks for your continued support.
[Get Cider 2 today.](https://cider.sh/download)
<a href="https://cider.sh/download"><img src="./src/renderer/assets/c1-c2.png" height="64px" alt="Banner"></a>
<a href="https://cidercollective.itch.io/cider"><img src="https://cider.sh/assets/itch-badge.svg" height="64px" alt="Banner"></a>
---
<p align="center">
<img src="./resources/banner.png" width="80%" height="60%" alt="Banner"><br>
<a href="https://cider.sh"><img src="./resources/banner.png" width="80%" height="60%" alt="Banner"></a>
<br>
<b>A new cross-platform Apple Music experience based on Electron and Vue.js written from scratch with performance & visuals in mind. 🚀</b>
<br><br>
<img src="https://img.shields.io/github/stars/ciderapp/Cider?label=Stars" alt="GitHub Stars"/>
@ -15,7 +28,7 @@
<a target="_blank" href="https://twitter.com/UseCider"><img src="https://img.shields.io/twitter/follow/UseCider?label=Twitter&color=%231DA1F2&logo=twitter&style=flat" alt="Twitter"/></a>
<a target="_blank" href="https://reddit.com/r/applemusicelectron"><img src="https://custom-icon-badges.herokuapp.com/reddit/subreddit-subscribers/applemusicelectron?label=Reddit&color=FF5700&logo=redditnew" alt="Reddit"/></a>
<br><br>
<a href="https://circleci.com/gh/ciderapp/Cider/tree/main"><img src="https://circleci.com/gh/ciderapp/Cider/tree/main.svg?style=svg" alt="CircleCI Status"/></a>
<a href="https://dev.azure.com/cidercollective/Cider/_build?definitionId=14"><img src="https://dev.azure.com/cidercollective/Cider/_apis/build/status%2FCider%201.x?branchName=main" alt="Azure Pipelines Status"/></a>
</p>
#### Links

View file

@ -1,180 +0,0 @@
# Cider-1 Azure Pipeline Workflow
# Maintained by Cider Devops.
# Don't make changes unless you know what you're doing.
trigger:
branches:
include:
- main
paths:
include:
- src/**/*
- azure-pipelines.yml
variables:
COMMIT_URL: "$(Build.Repository.Uri)/commit/$(Build.SourceVersion)"
BUILD_URL: "$(System.CollectionUri)/$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn/cache
YARN_ENABLE_IMMUTABLE_INSTALLS: false
jobs:
# Linux Production Build Test
# This job is used to test the production build of the Linux distribution.
# Also tests Pull Requests.
- job: compile_linux
displayName: "Compile Linux Distribution"
pool: Linux
steps:
- task: NodeTool@0
displayName: "Install Node.js"
inputs:
versionSource: "fromFile"
versionFilePath: ".nvmrc"
# - ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
# - task: Cache@2
# inputs:
# key: 'yarn | "$(Agent.OS)" | yarn.lock'
# path: $(YARN_CACHE_FOLDER)
# displayName: Cache yarn
- script: |
yarn set version from sources
displayName: "Setup yarn"
# Install dependencies (immutable for non-PR builds)
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
- script: yarn install
displayName: "Install Dependencies"
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
- script: yarn install
displayName: "Install Dependencies"
- script: yarn dist:linux
env: {GH_TOKEN : $(GH_TOKEN)}
displayName: "Compile Distribution"
- task: CopyFiles@2
displayName: "Copy to artifacts staging directory"
inputs:
SourceFolder: 'dist'
Contents: |
*.AppImage
*.deb
*.snap
*.rpm
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
displayName: Upload Artifacts
inputs:
ArtifactName: "Cider-1"
publishLocation: "Container"
# - task: DownloadBuildArtifacts@1
# inputs:
# buildType: 'current'
# downloadType: 'specific'
# downloadPath: '$(System.ArtifactsDirectory)'
# Windows Production Build Test
# This job is used to test the production build of the Windows distribution.
# Also tests Pull Requests.
- job: compile_windows
displayName: "Compile Windows Distribution"
pool: Linux
steps:
- task: NodeTool@0
displayName: "Install Node.js"
inputs:
versionSource: "fromFile"
versionFilePath: ".nvmrc"
# - ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
# - task: Cache@2
# inputs:
# key: 'yarn | "$(Agent.OS)" | yarn.lock'
# path: $(YARN_CACHE_FOLDER)
# displayName: Cache yarn
- script: |
yarn set version from sources
displayName: "Setup yarn"
# Install dependencies (immutable for non-PR builds)
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
- script: yarn install
displayName: "Install Dependencies"
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
- script: yarn install
displayName: "Install Dependencies"
- script: yarn dist:win
env: {GH_TOKEN : $(GH_TOKEN)}
displayName: "Compile Distribution"
- task: CopyFiles@2
displayName: "Copy to artifacts staging directory"
inputs:
SourceFolder: "dist"
Contents: "*.exe"
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
displayName: Upload Artifacts
inputs:
ArtifactName: "Cider-1"
publishLocation: "Container"
- job: compile_winget
displayName: "Compile for Winget"
pool: Linux
steps:
- task: NodeTool@0
displayName: "Install Node.js"
inputs:
versionSource: "fromFile"
versionFilePath: ".nvmrc"
- script: yarn set version from sources
displayName: "Setup yarn"
- script: yarn install
displayName: "Install Dependencies"
- script: yarn run winget
env: {GH_TOKEN : $(GH_TOKEN)}
displayName: "Compile Distribution"
- task: CopyFiles@2
displayName: "Copy to artifacts staging directory"
inputs:
SourceFolder: "dist"
Contents: "*.exe"
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
displayName: Upload Artifacts
inputs:
ArtifactName: "Cider-1"
publishLocation: "Container"
- job: upload_files
dependsOn:
- compile_linux
- compile_windows
- compile_winget
pool: Linux
steps:
- task: GitHubRelease@1
inputs:
gitHubConnection: 'ciderapp'
repositoryName: 'ciderapp/Cider'
action: 'create'
target: '$(Build.SourceVersion)'
tagSource: 'userSpecifiedTag'
tag: 'v1.6.1'
title: 'Cider Version 1.6.1'
releaseNotesSource: 'inline'
releaseNotesInline: 'Test build from azure CI'
assets: '$(System.ArtifactsDirectory)/Cider-1/*'
addChangeLog: false

View file

@ -1,3 +0,0 @@
files:
- source: /src/i18n/source/en_US.json
translation: /src/i18n/%locale_with_underscore%.json

View file

@ -2,12 +2,14 @@
"name": "cider",
"applicationId": "Cider",
"productName": "Cider",
"version": "1.6.1",
"version": "1.6.3",
"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",
"exports": "./build/index.js",
"main": "./build/index.js",
"author": "Cider Collective <cryptofyre@cider.sh> (https://cider.sh)",
"repository": "github:ciderapp/Cider",
"type": "module",
"bugs": {
"url": "https://github.com/ciderapp/Cider/issues?q=is%3Aopen+is%3Aissue+label%3Abug"
},
@ -17,10 +19,11 @@
"bootstrap": "npx -y check-engine && yarn",
"build": "tsc && lessc ./src/renderer/style.less ./src/renderer/style.css",
"start": "npm run build && electron ./build/index.js",
"dist": "npm run build && electron-builder",
"dist:win": "npm run build && electron-builder --win",
"dist:linux": "npm run build && electron-builder --linux",
"dist:universalNotWorking": "npm run build && electron-builder --mac --universal",
"dist": "npm run build && electron-builder --publish=never",
"dist:win": "npm run build && electron-builder --win --publish=never",
"dist:linux": "npm run build && electron-builder --linux --publish=never",
"dist:all": "npm run build && electron-builder -wl --publish=never",
"dist:universalNotWorking": "npm run build && electron-builder --mac --universal --publish:never",
"winget": "npm run build && electron-builder --win -c winget.json",
"msft": "npm run build && electron-builder -c msft-package.json",
"mstest": "npm run build && electron-builder -c msft-test.json",
@ -29,63 +32,66 @@
"format:write": "npx prettier --write \"src/**/*.{js,json,ts,less}\""
},
"dependencies": {
"@achingbrain/ssdp": "^4.0.1",
"@sentry/electron": "^4.2.0",
"@sentry/integrations": "^7.31.1",
"adm-zip": "^0.5.10",
"airtunes2": "github:ciderapp/node_airtunes2",
"castv2-client": "^1.2.0",
"chokidar": "^3.5.3",
"@achingbrain/ssdp": "^4.0.6",
"@crowdin/ota-client": "^1.1.1",
"@sentry/electron": "^4.24.0",
"@sentry/integrations": "7.114.0",
"adm-zip": "^0.5.12",
"airtunes2": "ciderapp/node_airtunes2",
"castv2-client": "ciderapp/node-castv2-client",
"chokidar": "^3.6.0",
"discord-auto-rpc": "^1.0.17",
"dns-js": "github:ciderapp/node-dns-js",
"ejs": "^3.1.8",
"electron-fetch": "^1.9.1",
"electron-log": "^4.4.8",
"ejs": "^3.1.10",
"electron-log": "^5.1.4",
"electron-notarize": "^1.2.2",
"electron-store": "^8.1.0",
"electron-updater": "^5.3.0",
"electron-store": "^9.0.0",
"electron-updater": "6.2.1",
"electron-window-state": "^5.0.3",
"express": "^4.18.2",
"get-port": "5.1.1",
"jimp": "^0.22.7",
"express": "^4.19.2",
"get-port": "7.1.0",
"jimp": "^0.22.12",
"lastfmapi": "^0.1.1",
"mdns-js": "github:ciderapp/node-mdns-js",
"mpris-service": "^2.1.2",
"music-metadata": "7.12.6",
"node-gyp": "^9.3.1",
"mdns-js": "ciderapp/node-mdns-js",
"mpris-service": "ciderapp/mpris-service",
"music-metadata": "7.14.0",
"node-fetch": "^3.3.2",
"node-ssdp": "^4.0.1",
"node-ssdp-js": "^0.9.6",
"qrcode": "^1.5.1",
"qrcode": "^1.5.3",
"request": "^2.88.2",
"run-script-os": "^1.1.6",
"simple-ssdp": "^1.0.2",
"source-map-support": "^0.5.21",
"ssdp-js": "^1.0.1",
"ts-md5": "1.3.1",
"upnp-mediarenderer-client": "github:vapormusic/node-upnp-mediarenderer-client",
"v8-compile-cache": "^2.3.0",
"wallpaper": "5.0.1",
"ws": "^8.12.0",
"xml2js": "^0.5.0",
"youtube-search-without-api-key": "^1.1.0"
"upnp-mediarenderer-client": "vapormusic/node-upnp-mediarenderer-client",
"v8-compile-cache": "^2.4.0",
"wallpaper": "7.2.1",
"ws": "^8.17.0",
"xml2js": "^0.6.2",
"youtube-search-without-api-key": "^2.0.1"
},
"devDependencies": {
"@types/adm-zip": "^0.5.0",
"@types/discord-rpc": "4.0.4",
"@types/express": "^4.17.15",
"@types/musickit": "github:ciderapp/musickit-types",
"@types/node": "^20.1.1",
"@types/qrcode-terminal": "^0.12.0",
"@types/ws": "^8.5.4",
"electron": "github:castlabs/electron-releases",
"electron-builder": "^23.6.0",
"@types/adm-zip": "^0.5.5",
"@types/discord-rpc": "4.0.8",
"@types/express": "^4.17.21",
"@types/musickit": "ciderapp/musickit-types",
"@types/node": "^20.12.12",
"@types/node-ssdp": "^4.0.4",
"@types/qrcode-terminal": "^0.12.2",
"@types/request": "^2.48.12",
"@types/upnp-mediarenderer-client": "^1.4.3",
"@types/ws": "^8.5.10",
"@types/xml2js": "^0.4.14",
"electron": "github:castlabs/electron-releases#v30.0.4+wvcus",
"electron-builder": "^24.13.3",
"electron-builder-notarize-pkg": "^1.2.0",
"electron-webpack": "^2.8.2",
"less": "^4.1.3",
"prettier": "2.8.8",
"typescript": "^5.0.4",
"less": "^4.2.0",
"node-gyp": "^10.1.0",
"prettier": "3.2.5",
"typescript": "^5.4.5",
"vue-devtools": "^5.1.4",
"webpack": "~5.82.0"
"webpack": "~5.91.0"
},
"fileAssociations": [
{
@ -110,14 +116,14 @@
}
],
"build": {
"electronVersion": "24.3.0",
"electronVersion": "30.0.6",
"electronDownload": {
"version": "24.3.0+wvcus",
"version": "30.0.6+wvcus",
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
},
"appId": "cider",
"afterPack": "./resources/afterPack.js",
"afterSign": "./resources/notarize.js",
"afterPack": "./resources/afterPack.cjs",
"afterSign": "./resources/notarize.cjs",
"protocols": [
{
"name": "Cider",
@ -141,7 +147,7 @@
"target": [
"AppImage",
"deb",
"snap"
"rpm"
],
"synopsis": "A new look into listening and enjoying music in style and performance. ",
"category": "AudioVideo",
@ -225,9 +231,8 @@
"devtool": "source-map"
},
"engines": {
"node": "^19 || ^18 || ^16 || ^14.19",
"node": ">= 18",
"npm": ">= 6.13.4",
"yarn": ">= 1.21.1"
},
"packageManager": "yarn@3.5.1"
}
}

@ -1 +0,0 @@
Subproject commit 1a427976edb6c19bf16620c15cba75f5052f7313

View file

@ -1,9 +1,10 @@
import { app, Menu, nativeImage, Tray, ipcMain, clipboard, shell } from "electron";
import { readFileSync } from "fs";
import * as path from "path";
import * as log from "electron-log";
import * as os from "os";
import { utils } from "./utils";
import { Menu, Tray, app, clipboard, ipcMain, nativeImage, shell } from "electron";
import log from "electron-log";
import { readFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import os from "os";
import { utils } from "../base/utils.js";
/**
* @file Creates App instance
@ -45,7 +46,7 @@ export class AppEvents {
// Log File Location
if (app.commandLine.hasSwitch("log") || app.commandLine.hasSwitch("l")) {
console.log(path.join(app.getPath("userData"), "logs"));
console.log(join(app.getPath("userData"), "logs"));
app.exit();
}
@ -94,7 +95,7 @@ export class AppEvents {
if (process.platform === "linux") {
app.commandLine.appendSwitch("disable-features", "MediaSessionService");
if (os.version().indexOf("SteamOS")) {
if (os.version().includes("SteamOS")) {
app.commandLine.appendSwitch("enable-features", "UseOzonePlatform");
app.commandLine.appendSwitch("ozone-platform", "x11");
}
@ -107,7 +108,7 @@ export class AppEvents {
if (process.defaultApp) {
if (process.argv.length >= 2) {
this.protocols.forEach((protocol: string) => {
app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(process.argv[1])]);
app.setAsDefaultProtocolClient(protocol, process.execPath, [resolve(process.argv[1])]);
});
}
} else {
@ -144,7 +145,7 @@ export class AppEvents {
title: "Web Remote",
description: "Connect to your Web Remote",
},
"https://webremote.cider.sh"
"https://webremote.cider.sh",
);
}
@ -173,7 +174,7 @@ export class AppEvents {
console.log("token: ", authURI.split("lastfm?token=")[1]);
utils
.getWindow()
.webContents.executeJavaScript(`ipcRenderer.send('lastfm:auth', "${authURI.split("lastfm?token=")[1]}")`)
.webContents.executeJavaScript(`ipcRenderer.send('lastfm:auth', ${JSON.stringify(authURI.split("lastfm?token=")[1])})`)
.catch(console.error);
}
} else if (arg.includes("playpause")) {
@ -220,7 +221,7 @@ export class AppEvents {
} else if (arg.includes("/beep")) {
shell.beep();
} else {
utils.getWindow().webContents.executeJavaScript(`app.appRoute('${arg.split("//")[1]}')`);
utils.getWindow().webContents.executeJavaScript(`app.appRoute(${JSON.stringify(arg.split("//")[1])})`);
}
}
@ -263,15 +264,15 @@ export class AppEvents {
*/
private InitTray() {
const icons = {
win32: nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.ico`)).resize({
win32: nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.ico`)).resize({
width: 32,
height: 32,
}),
linux: nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.png`)).resize({
linux: nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.png`)).resize({
width: 32,
height: 32,
}),
darwin: nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.png`)).resize({
darwin: nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.png`)).resize({
width: 20,
height: 20,
}),
@ -280,7 +281,7 @@ export class AppEvents {
this.tray.setToolTip(app.getName());
this.setTray(false);
this.tray.on("double-click", () => {
this.tray.on("double-click", () => { // supports windows and mac only
if (utils.getWindow()) {
if (utils.getWindow().isVisible()) {
utils.getWindow().focus();
@ -290,6 +291,16 @@ export class AppEvents {
}
});
this.tray.on("click", () => {
if (utils.getWindow() && process.platform === "linux") { // use single click to open when double doesn't work
if (utils.getWindow().isVisible()) {
utils.getWindow().focus();
} else {
utils.getWindow().show();
}
}
});
utils.getWindow().on("show", () => {
this.setTray(true);
});
@ -314,7 +325,7 @@ export class AppEvents {
private setTray(visible: boolean = utils.getWindow().isVisible()) {
this.i18n = utils.getLocale(utils.getStoreValue("general.language"));
const ciderIcon = nativeImage.createFromPath(path.join(__dirname, `../../resources/icons/icon.png`)).resize({
const ciderIcon = nativeImage.createFromPath(join(dirname(fileURLToPath(import.meta.url)), `../../resources/icons/icon.png`)).resize({
width: 24,
height: 24,
});

View file

@ -1,22 +1,21 @@
import { join } from "path";
import { app, BrowserWindow as bw, ipcMain, ShareMenu, shell, screen, dialog, nativeTheme, ipcRenderer } from "electron";
import * as windowStateKeeper from "electron-window-state";
import * as express from "express";
import * as getPort from "get-port";
import { search } from "youtube-search-without-api-key";
import { existsSync, rmSync, mkdirSync, readdirSync, readFileSync, writeFileSync, statSync, unlinkSync, rmdirSync, lstatSync } from "fs";
import { Stream } from "stream";
import { networkInterfaces } from "os";
import * as mm from "music-metadata";
import fetch from "electron-fetch";
import { wsapi } from "./wsapi";
import { utils } from "./utils";
import { Plugins } from "./plugins";
import AdmZip from "adm-zip";
import { watch } from "chokidar";
import * as os from "os";
import wallpaper from "wallpaper";
import * as AdmZip from "adm-zip";
import { LocalFiles } from "../providers/local/";
import { ShareMenu, app, BrowserWindow as bw, dialog, ipcMain, nativeTheme, screen, shell } from "electron";
import windowStateKeeper from "electron-window-state";
import express from "express";
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "fs";
import getPort from "get-port";
import { LocalFiles } from "../providers/local/index.js";
import mm from "music-metadata";
import fetch from "node-fetch";
import os, { networkInterfaces } from "os";
import { join } from "path";
import { Stream } from "stream";
import { getWallpaper } from "wallpaper";
import { search } from "youtube-search-without-api-key";
import { Plugins } from "./plugins.js";
import { utils } from "./utils.js";
import { wsapi } from "./wsapi.js";
/**
* @file Creates the BrowserWindow
@ -708,7 +707,7 @@ export class BrowserWindow {
cancel: false,
});
}
}
},
);
BrowserWindow.win.webContents.session.webRequest.onBeforeSendHeaders(async (details: { url: string; requestHeaders: { [x: string]: string } }, callback: (arg0: { requestHeaders: any }) => void) => {
@ -785,15 +784,15 @@ export class BrowserWindow {
"media-user-token": options.mediaToken,
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cider/1.4.2 Chrome/100.0.4896.75 Electron/18.0.3 Safari/537.36",
},
}
},
);
let json = await res.json();
return json;
});
ipcMain.on("get-wallpaper", async (event, args) => {
const wpPath: string = await wallpaper.get();
const Jimp = require("jimp");
const wpPath: string = await getWallpaper();
const Jimp = (await import("jimp")).default;
const img = await Jimp.read(wpPath);
const blurAmount = args.blurAmount ?? 256;
if (blurAmount) {
@ -885,7 +884,7 @@ export class BrowserWindow {
if (url.endsWith("/")) url = url.slice(0, -1);
let response = await utils.fetch(`${url}/archive/refs/heads/main.zip`);
let repo = url.split("/").slice(-2).join("/");
let apiRepo = await utils.fetch(`https://api.github.com/repos/${repo}`).then((res) => res.json());
let apiRepo = await utils.fetch(`https://api.github.com/repos/${repo}`).then((res) => res.json()) as { id: number};
console.debug(`REPO ID: ${apiRepo.id}`);
// extract the files from the first folder in the zip response
let zip = new AdmZip(await response.buffer());
@ -895,7 +894,7 @@ export class BrowserWindow {
}
console.log(join(utils.getPath("plugins"), "gh_" + apiRepo.id));
zip.extractEntryTo(entry, join(utils.getPath("plugins"), "gh_" + apiRepo.id), false, true);
let commit = await utils.fetch(`https://api.github.com/repos/${repo}/commits`).then((res) => res.json());
let commit = await utils.fetch(`https://api.github.com/repos/${repo}/commits`).then((res) => res.json()) as { sha: string }[];
console.debug(`COMMIT SHA: ${commit[0].sha}`);
let theme = JSON.parse(readFileSync(join(utils.getPath("plugins"), "gh_" + apiRepo.id, "package.json"), "utf8"));
theme.id = apiRepo.id;
@ -928,7 +927,7 @@ export class BrowserWindow {
"User-Agent": utils.getWindow().webContents.getUserAgent(),
},
})
.then((res) => res.json());
.then((res) => res.json()) as { id: number}
console.error(apiRepo);
console.debug(`REPO ID: ${apiRepo.id}`);
// extract the files from the first folder in the zip response
@ -942,7 +941,7 @@ export class BrowserWindow {
let subFolder = entry.entryName.split("/").slice(1, -1).join("/");
zip.extractEntryTo(entry, join(utils.getPath("themes"), "gh_" + apiRepo.id, "/", subFolder), false, true);
});
let commit = await utils.fetch(`https://api.github.com/repos/${repo}/commits`).then((res) => res.json());
let commit = await utils.fetch(`https://api.github.com/repos/${repo}/commits`).then((res) => res.json()) as { sha: string }[];
console.debug(`COMMIT SHA: ${commit[0].sha}`);
let theme = JSON.parse(readFileSync(join(utils.getPath("themes"), "gh_" + apiRepo.id, "theme.json"), "utf8"));
theme.id = apiRepo.id;
@ -1048,22 +1047,19 @@ export class BrowserWindow {
});
ipcMain.on("get-i18n-listing", (event) => {
console.debug("[i18n] Getting i18n listing from " + utils.getPath("i18nPath"));
const i18nFiles = readdirSync(utils.getPath("i18nPath")).filter((file) => file.endsWith(".json")),
i18nListing = [];
const translations = utils.i18n;
const i18nListing: any = [];
for (let i = 0; i < i18nFiles.length; i++) {
if (i18nFiles[i] == "index.json") continue;
console.debug("[i18n] Processing file: " + join(utils.getPath("i18nPath"), i18nFiles[i]));
const i18n: { [index: string]: Object } = JSON.parse(readFileSync(join(utils.getPath("i18nPath"), i18nFiles[i]), "utf8"));
for (const lang in translations) {
i18nListing.push({
code: i18nFiles[i].replace(".json", ""),
nameNative: i18n["i18n.languageName"] ?? i18nFiles[i].replace(".json", ""),
nameEnglish: i18n["i18n.languageNameEnglish"] ?? i18nFiles[i].replace(".json", ""),
category: i18n["i18n.category"] ?? "",
authors: i18n["i18n.authors"] ?? "",
code: lang,
nameNative: translations[lang][0].content["i18n.languageName"] ?? lang,
nameEnglish: translations[lang][0].content["i18n.languageNameEnglish"] ?? lang,
category: translations[lang][0].content["i18n.category"] ?? "",
authors: translations[lang][0].content["i18n.authors"] ?? "",
});
}
event.returnValue = i18nListing;
});
@ -1353,11 +1349,12 @@ export class BrowserWindow {
{
ip: `${BrowserWindow.getIP()}`,
},
`http://${BrowserWindow.getIP()}:${this.remotePort}`
`http://${BrowserWindow.getIP()}:${this.remotePort}`,
);
}
// Get previews for normalization
ipcMain.on("getPreviewURL", (_event, url) => {
fetch(url)
.then((res) => res.buffer())
.then(async (buffer) => {
@ -1667,7 +1664,7 @@ export class BrowserWindow {
*/
private async broadcastRemote() {
const myString = `http://${BrowserWindow.getIP()}:${this.remotePort}`;
const mdns = require("mdns-js");
const mdns = (await import("mdns-js")).default;
const encoded = Buffer.from(myString).toString("base64");
const x = mdns.tcp("cider-remote");
const txt_record = {

View file

@ -1,32 +0,0 @@
var util = require("util");
var castv2Cli = require("castv2-client");
var RequestResponseController = castv2Cli.RequestResponseController;
function CiderCastController(client, sourceId, destinationId) {
RequestResponseController.call(this, client, sourceId, destinationId, "urn:x-cast:com.ciderapp.customdata");
this.once("close", onclose);
var self = this;
function onclose() {
self.stop();
}
}
util.inherits(CiderCastController, RequestResponseController);
CiderCastController.prototype.sendIp = function (ip) {
// TODO: Implement Callback
let data = {
ip: ip,
};
this.request(data);
};
CiderCastController.prototype.kill = function () {
// TODO: Implement Callback
let data = {
action: "stop",
};
this.request(data);
};
module.exports = CiderCastController;

View file

@ -0,0 +1,32 @@
// @ts-nocheck
import castv2Cli from "castv2-client";
const RequestResponseController = castv2Cli.RequestResponseController;
export class CiderCastController extends RequestResponseController {
constructor(client: string, sourceId: string, destinationId: string) {
super(client, sourceId, destinationId, "urn:x-cast:com.ciderapp.customdata");
this.once("close", onclose);
var self = this;
function onclose() {
self.stop();
}
}
sendIp(ip: string) {
// TODO: Implement Callback
let data = {
ip: ip,
};
this.request(data);
}
kill() {
// TODO: Implement Callback
let data = {
action: "stop",
};
this.request(data);
}
}

View file

@ -1,80 +0,0 @@
//@ts-nocheck
var util = require("util");
// var debug = require('debug')('castv2-client');
var Application = require("castv2-client").Application;
var MediaController = require("castv2-client").MediaController;
var CiderCastController = require("./castcontroller");
function CiderReceiver(client, session) {
Application.apply(this, arguments);
this.media = this.createController(MediaController);
this.mediaReceiver = this.createController(CiderCastController);
this.media.on("status", onstatus);
var self = this;
function onstatus(status) {
self.emit("status", status);
}
}
// FE96A351
// 27E1334F
CiderReceiver.APP_ID = "FE96A351";
util.inherits(CiderReceiver, Application);
CiderReceiver.prototype.getStatus = function (callback) {
this.media.getStatus.apply(this.media, arguments);
};
CiderReceiver.prototype.load = function (media, options, callback) {
this.media.load.apply(this.media, arguments);
};
CiderReceiver.prototype.play = function (callback) {
this.media.play.apply(this.media, arguments);
};
CiderReceiver.prototype.pause = function (callback) {
this.media.pause.apply(this.media, arguments);
};
CiderReceiver.prototype.stop = function (callback) {
this.media.stop.apply(this.media, arguments);
};
CiderReceiver.prototype.seek = function (currentTime, callback) {
this.media.seek.apply(this.media, arguments);
};
CiderReceiver.prototype.queueLoad = function (items, options, callback) {
this.media.queueLoad.apply(this.media, arguments);
};
CiderReceiver.prototype.queueInsert = function (items, options, callback) {
this.media.queueInsert.apply(this.media, arguments);
};
CiderReceiver.prototype.queueRemove = function (itemIds, options, callback) {
this.media.queueRemove.apply(this.media, arguments);
};
CiderReceiver.prototype.queueReorder = function (itemIds, options, callback) {
this.media.queueReorder.apply(this.media, arguments);
};
CiderReceiver.prototype.queueUpdate = function (items, callback) {
this.media.queueUpdate.apply(this.media, arguments);
};
CiderReceiver.prototype.sendIp = function (opts) {
this.mediaReceiver.sendIp.apply(this.mediaReceiver, arguments);
};
CiderReceiver.prototype.kill = function (opts) {
this.mediaReceiver.kill.apply(this.mediaReceiver, arguments);
};
module.exports = CiderReceiver;

View file

@ -0,0 +1,80 @@
// @ts-nocheck
import castv2Cli from "castv2-client";
import { CiderCastController } from "./castcontroller.js";
const Application = castv2Cli.Application;
const MediaController = castv2Cli.MediaController;
export class CiderReceiver extends Application {
// FE96A351
// 27E1334F
public APP_ID = "FE96A351";
constructor(_client: unknown, _session: unknown) {
super();
super.apply(this, arguments);
this.media = this.createController(MediaController);
this.mediaReceiver = this.createController(CiderCastController);
this.media.on("status", onstatus);
var self = this;
function onstatus(status: string) {
self.emit("status", status);
}
}
getStatus(callback: unknown) {
this.media.getStatus.apply(this.media, arguments);
}
load(media: unknown, options: unknown, callback: unknown) {
this.media.load.apply(this.media, arguments);
}
play(callback: unknown) {
this.media.play.apply(this.media, arguments);
}
pause(callback: unknown) {
this.media.pause.apply(this.media, arguments);
}
stop(callback: unknown) {
this.media.stop.apply(this.media, arguments);
}
seek(currentTime: unknown, callback: unknown) {
this.media.seek.apply(this.media, arguments);
}
queueLoad(items: unknown, options: unknown, callback: unknown) {
this.media.queueLoad.apply(this.media, arguments);
}
queueInsert(items: unknown, options: unknown, callback: unknown) {
this.media.queueInsert.apply(this.media, arguments);
}
queueRemove(itemIds: unknown, options: unknown, callback: unknown) {
this.media.queueRemove.apply(this.media, arguments);
}
queueReorder(itemIds: unknown, options: unknown, callback: unknown) {
this.media.queueReorder.apply(this.media, arguments);
}
queueUpdate(items: unknown, callback: unknown) {
this.media.queueUpdate.apply(this.media, arguments);
}
sendIp(opts: unknown) {
this.mediaReceiver.sendIp.apply(this.mediaReceiver, arguments);
}
kill(opts: unknown) {
this.mediaReceiver.kill.apply(this.mediaReceiver, arguments);
}
}

View file

@ -1,7 +1,8 @@
import * as fs from "fs";
import * as path from "path";
import * as electron from "electron";
import { utils } from "./utils";
import {app} from "electron";
import { existsSync, lstatSync, readdirSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { utils } from "./utils.js";
//
// Hello, this is our loader for the various plugins that the Cider Development Team built for our
@ -17,8 +18,8 @@ import { utils } from "./utils";
*/
export class Plugins {
private static PluginMap: any = {};
private basePluginsPath = path.join(__dirname, "../plugins");
private userPluginsPath = path.join(electron.app.getPath("userData"), "Plugins");
private basePluginsPath = join(dirname(fileURLToPath(import.meta.url)), "../plugins");
private userPluginsPath = join(app.getPath("userData"), "Plugins");
private readonly pluginsList: any = {};
constructor() {
@ -36,10 +37,10 @@ export class Plugins {
public getPlugins(): any {
let plugins: any = {};
if (fs.existsSync(this.basePluginsPath)) {
fs.readdirSync(this.basePluginsPath).forEach((file) => {
if (existsSync(this.basePluginsPath)) {
readdirSync(this.basePluginsPath).forEach(async (file) => {
if (file.endsWith(".ts") || file.endsWith(".js")) {
const plugin = require(path.join(this.basePluginsPath, file)).default;
const plugin = (await import(join(this.basePluginsPath, file))).default;
if (plugins[file] || plugin.name in plugins) {
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
} else {
@ -49,12 +50,12 @@ export class Plugins {
});
}
if (fs.existsSync(this.userPluginsPath)) {
fs.readdirSync(this.userPluginsPath).forEach((file) => {
if (existsSync(this.userPluginsPath)) {
readdirSync(this.userPluginsPath).forEach(async (file) => {
// Plugins V1
if (file.endsWith(".ts") || file.endsWith(".js")) {
if (!electron.app.isPackaged) {
const plugin = require(path.join(this.userPluginsPath, file)).default;
if (!app.isPackaged) {
const plugin = (await import(join(this.userPluginsPath, file))).default;
file = file.replace(".ts", "").replace(".js", "");
if (plugins[file] || plugin in plugins) {
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
@ -62,7 +63,7 @@ export class Plugins {
plugins[file] = new plugin(utils);
}
} else {
const plugin = require(path.join(this.userPluginsPath, file));
const plugin = await import(join(this.userPluginsPath, file));
file = file.replace(".ts", "").replace(".js", "");
if (plugins[file] || plugin in plugins) {
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
@ -72,17 +73,17 @@ export class Plugins {
}
}
// Plugins V2
else if (fs.lstatSync(path.join(this.userPluginsPath, file)).isDirectory()) {
const pluginPath = path.join(this.userPluginsPath, file);
if (fs.existsSync(path.join(pluginPath, "package.json"))) {
const pluginPackage = require(path.join(pluginPath, "package.json"));
const plugin = require(path.join(pluginPath, pluginPackage.main));
else if (lstatSync(join(this.userPluginsPath, file)).isDirectory()) {
const pluginPath = join(this.userPluginsPath, file);
if (existsSync(join(pluginPath, "package.json"))) {
const pluginPackage = await import(join(pluginPath, "package.json"));
const plugin = await import(join(pluginPath, pluginPackage.main));
if (plugins[plugin.name] || plugin.name in plugins) {
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
} else {
Plugins.PluginMap[pluginPackage.name] = file;
const pluginEnv = {
app: electron.app,
app: app,
store: utils.getStore(),
utils: utils,
win: utils.getWindow(),

View file

@ -1,11 +1,11 @@
import * as ElectronStore from "electron-store";
import ElectronStore from "electron-store";
import { app, ipcMain } from "electron";
import fetch from "electron-fetch";
import fetch from "node-fetch";
export class Store {
static cfg: ElectronStore;
static cfg: ElectronStore<any>;
private defaults: any = {
private defaults = {
main: {
PLATFORM: process.platform,
UPDATABLE: app.isPackaged && (!process.mas || !process.windowsStore || !process.env.FLATPAK_ID),
@ -236,18 +236,13 @@ export class Store {
},
},
};
private migrations: any = {};
private schema: ElectronStore.Schema<any> = {
"connectivity.discord_rpc": {
type: "object",
},
};
private migrations = {};
constructor() {
Store.cfg = new ElectronStore({
name: "cider-config",
defaults: this.defaults,
schema: this.schema,
migrations: this.migrations,
clearInvalidConfig: false, //disabled for now
});

View file

@ -1,12 +1,16 @@
import * as fs from "fs";
import * as path from "path";
import { Store } from "./store";
import { BrowserWindow as bw } from "./browserwindow";
import { app, BrowserWindow, ipcMain } from "electron";
import fetch from "electron-fetch";
import { BrowserWindow, app, ipcMain } from "electron";
import ElectronStore from "electron-store";
import fetch from "node-fetch";
import { readFileSync } from "node:fs";
import { join, resolve,dirname } from "node:path";
import { BrowserWindow as bw } from "./browserwindow.js";
import { Store } from "./store.js";
import { fileURLToPath } from "node:url";
export class utils {
static hash = "fda9a6528649ea90dee35390wog"
static i18n: any = {};
/**
* Playback Functions
*/
@ -34,16 +38,14 @@ export class utils {
* Paths for the application to use
*/
static paths: any = {
srcPath: path.join(__dirname, "../../src"),
rendererPath: path.join(__dirname, "../../src/renderer"),
mainPath: path.join(__dirname, "../../src/main"),
resourcePath: path.join(__dirname, "../../resources"),
i18nPath: path.join(__dirname, "../../src/cider-i18n"),
i18nPathSrc: path.join(__dirname, "../../src/il8n/source"),
ciderCache: path.resolve(app.getPath("userData"), "CiderCache"),
themes: path.resolve(app.getPath("userData"), "Themes"),
plugins: path.resolve(app.getPath("userData"), "Plugins"),
externals: path.resolve(app.getPath("userData"), "externals"),
srcPath: join(dirname(fileURLToPath(import.meta.url)), "../../src"),
rendererPath: join(dirname(fileURLToPath(import.meta.url)), "../../src/renderer"),
mainPath: join(dirname(fileURLToPath(import.meta.url)), "../../src/main"),
resourcePath: join(dirname(fileURLToPath(import.meta.url)), "../../resources"),
ciderCache: resolve(app.getPath("userData"), "CiderCache"),
themes: resolve(app.getPath("userData"), "Themes"),
plugins: resolve(app.getPath("userData"), "Plugins"),
externals: resolve(app.getPath("userData"), "externals"),
};
/**
@ -81,10 +83,8 @@ export class utils {
/**
* MitM the electron fetch for a function that proxies github.
* Written in TS so Maikiwi doesn't fuck up
* @param url {string} URL param
* @param opts {object} Other options
*/
static async fetch(url: string, opts = {}) {
static async fetch(url: string, opts: object = {}) {
Object.assign(opts, {
headers: {
"User-Agent": utils.getWindow().webContents.getUserAgent(),
@ -102,6 +102,14 @@ export class utils {
return await fetch(url, opts);
}
}
static async initializeTranslations() {
const otaClient = (await import('@crowdin/ota-client')).default.default;
const crowdin = new otaClient(this.hash)
this.i18n = await crowdin.getTranslations();
}
/**
* Fetches the i18n locale for the given language.
* @param language {string} The language to fetch the locale for.
@ -109,23 +117,12 @@ export class utils {
* @returns {string | Object} The locale value.
*/
static getLocale(language: string, key?: string): string | object {
let i18n: { [index: string]: Object } = JSON.parse(fs.readFileSync(path.join(this.paths.i18nPath, "en_US.json"), "utf8"));
if (language !== "en_US" && fs.existsSync(path.join(this.paths.i18nPath, `${language}.json`))) {
i18n = Object.assign(i18n, JSON.parse(fs.readFileSync(path.join(this.paths.i18nPath, `${language}.json`), "utf8")));
let i18n: any = {};
if (!this.i18n[language]) {
i18n = this.i18n["en"][0].content;
} else {
i18n = this.i18n[language ?? "en"][0].content;
}
/* else if (!fs.existsSync(path.join(this.paths.i18nPath, `${language}.json`))) {
fetch(`https://raw.githubusercontent.com/ciderapp/Cider/main/src/i18n/${language}.json`)
.then(res => res.json())
.then(res => {
if (res) {
i18n = Object.assign(i18n, res);
fs.writeFileSync(path.join(this.paths.i18nPath, `${language}.json`), JSON.stringify(res));
} else {
i18n = Object.assign(i18n, JSON.parse(fs.readFileSync(path.join(this.paths.i18nPath, `en_US.json`), "utf8")));
}
})
} */
if (key) {
return i18n[key];
@ -190,6 +187,6 @@ export class utils {
static loadPluginFrontend(path: string): void {}
static loadJSFrontend(path: string): void {
bw.win.webContents.executeJavaScript(fs.readFileSync(path, "utf8"));
bw.win.webContents.executeJavaScript(readFileSync(path, "utf8"));
}
}

View file

@ -1,7 +1,5 @@
import * as ws from "ws";
import * as electron from "electron";
const WebSocketServer = ws.Server;
import WebSocket, { WebSocketServer } from 'ws';
import electron from "electron";
interface standardResponse {
status?: Number;

View file

@ -1,16 +1,22 @@
require("v8-compile-cache");
// @ts-ignore
await import("v8-compile-cache");
import { app, components, ipcMain } from "electron";
import { join } from "path";
import { Store } from "./base/store";
import { AppEvents } from "./base/app";
import { Plugins } from "./base/plugins";
import { BrowserWindow } from "./base/browserwindow";
import { Store } from "./base/store.js";
import { AppEvents } from "./base/app.js";
import { Plugins } from "./base/plugins.js";
import { BrowserWindow } from "./base/browserwindow.js";
import { init as Sentry } from "@sentry/electron";
import { RewriteFrames } from "@sentry/integrations";
import { utils } from "./base/utils.js";
const appName = 'sh.cider.classic';
if (!app.isPackaged) {
app.setPath("userData", join(app.getPath("appData"), "Cider"));
app.setPath('userData', join(app.getPath('appData'), `${appName}.dev`));
} else {
app.setPath('userData', join(app.getPath('appData'), appName));
}
// Analytics for debugging fun yeah.
@ -30,18 +36,20 @@ const CiderPlug = new Plugins();
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* App Event Handlers
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
app.on("ready", () => {
app.on("ready", async () => {
await utils.initializeTranslations();
Cider.ready(CiderPlug);
console.log("[Cider] Application is Ready. Creating Window.");
if (!app.isPackaged) {
console.info("[Cider] Running in development mode.");
require("vue-devtools").install();
// @ts-ignore
(await import("vue-devtools")).default.install();
}
console.log("aa");
components.whenReady().then(async () => {
const bw = new BrowserWindow();
console.log("[Cider] Creating Window.");
const win = await bw.createWindow();
app.getGPUInfo("complete").then((gpuInfo) => {
@ -86,27 +94,3 @@ app.on("before-quit", () => {
CiderPlug.callPlugins("onBeforeQuit");
console.warn(`${app.getName()} exited.`);
});
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Widevine Event Handlers
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// @ts-ignore
app.on("widevine-ready", (version, lastVersion) => {
if (null !== lastVersion) {
console.log("[Cider][Widevine] Widevine " + version + ", upgraded from " + lastVersion + ", is ready to be used!");
} else {
console.log("[Cider][Widevine] Widevine " + version + " is ready to be used!");
}
});
// @ts-ignore
app.on("widevine-update-pending", (currentVersion, pendingVersion) => {
console.log("[Cider][Widevine] Widevine " + currentVersion + " is ready to be upgraded to " + pendingVersion + "!");
});
// @ts-ignore
app.on("widevine-error", (error) => {
console.log("[Cider][Widevine] Widevine installation encountered an error: " + error);
app.exit();
});

View file

@ -1,8 +1,10 @@
import * as electron from "electron";
import * as os from "os";
import { resolve } from "path";
import * as CiderReceiver from "../base/castreceiver";
const MediaRendererClient = require("upnp-mediarenderer-client");
import electron from "electron";
import os from "os";
import {CiderReceiver} from "../base/castreceiver.js";
import MediaRendererClient from "upnp-mediarenderer-client";
import request from "request";
import castv2 from "castv2-client";
import mdnsjs from "mdns-js";
export default class ChromecastPlugin {
/**
@ -13,8 +15,8 @@ export default class ChromecastPlugin {
private _lastfm: any;
private _store: any;
private _timer: any;
private audioClient = require("castv2-client").Client;
private mdns = require("mdns-js");
private audioClient = castv2.Client;
private mdns = mdnsjs;
private devices: any = [];
private castDevices: any = [];
@ -35,7 +37,7 @@ export default class ChromecastPlugin {
// private bufcount2 = 0;
// private headerSent = false;
private searchForGCDevices() {
private async searchForGCDevices() {
try {
let browser = this.mdns.createBrowser(this.mdns.tcp("googlecast"));
browser.on("ready", browser.discover);
@ -47,7 +49,7 @@ export default class ChromecastPlugin {
this.ondeviceup(service.addresses[0], name + " (" + (service.type[0]?.description ?? "") + ")", "", "googlecast");
}
});
const Client = require("node-ssdp").Client;
const Client = (await import("node-ssdp")).Client;
// also do a SSDP/UPnP search
let ssdpBrowser = new Client();
ssdpBrowser.on("response", (headers: any, statusCode: any, rinfo: any) => {
@ -84,7 +86,6 @@ export default class ChromecastPlugin {
}
private getServiceDescription(url: any, address: any) {
const request = require("request");
request.get(url, (error: any, response: any, body: any) => {
if (!error && response.statusCode === 200) {
this.parseServiceDescription(body, address, url);
@ -113,8 +114,8 @@ export default class ChromecastPlugin {
}
}
private parseServiceDescription(body: any, address: any, url: any) {
const parseString = require("xml2js").parseString;
private async parseServiceDescription(body: any, address: any, url: any) {
const parseString = (await import("xml2js")).parseString;
parseString(body, (err: any, result: any) => {
if (!err && result && result.root && result.root.device) {
const device = result.root.device[0];
@ -167,7 +168,7 @@ export default class ChromecastPlugin {
},
(err: any, status: any) => {
console.log("media loaded playerState=%s", status);
}
},
);
client.getStatus((x: any, status: any) => {

View file

@ -1,6 +1,6 @@
import { AutoClient } from "discord-auto-rpc";
import { ipcMain } from "electron";
import fetch from "electron-fetch";
import fetch from "node-fetch";
export default class DiscordRPC {
/**
@ -67,8 +67,8 @@ export default class DiscordRPC {
url: artworkUrl,
},
})
.then((res) => res.json())
.then(function (json) {
.then(async (res) => {
const json = await res.json() as { imageUrl: string };
self._activityCache.largeImageKey = "https://images.weserv.nl/?url=" + json.imageUrl + "&w=1024&h=1024&output=jpg";
self._client.setActivity(self._activityCache);
});

View file

@ -1,3 +1,6 @@
// @ts-ignore
import LastfmAPI from "lastfmapi";
export default class lastfm {
/**
* Base Plugin Information
@ -73,7 +76,6 @@ export default class lastfm {
*/
private initializeLastFM(token: string, api: { key: string; secret: string }): void {
console.debug(`[${lastfm.name}:initialize] Initializing LastFM`);
const LastfmAPI = require("lastfmapi");
this._lfm = new LastfmAPI({
api_key: api.key,
secret: api.secret,
@ -135,7 +137,7 @@ export default class lastfm {
attributes.lfmAlbum = data;
callback(attributes);
}
}
},
);
} else {
this._lfm.track.getCorrection(attributes.primaryArtist, attributes.name, (err: any, data: any) => {

View file

@ -1,5 +1,5 @@
import { app, Menu, shell } from "electron";
import { utils } from "../base/utils";
import { utils } from "../base/utils.js";
export default class Thumbar {
/**
@ -18,272 +18,7 @@ export default class Thumbar {
private isNotMac: boolean = process.platform !== "darwin";
private isMac: boolean = process.platform === "darwin";
private _menuTemplate: any = [
{
label: app.getName(),
submenu: [
{
label: `${utils.getLocale(utils.getStoreValue("general.language"), "term.about")} ${app.getName()}`,
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.toggleprivate"),
accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.settings"),
accelerator: utils.getStoreValue("general.keybindings.settings").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.openSettingsPage()`),
},
...(this.isMac ? [{ type: "separator" }, { role: "services" }, { type: "separator" }, { role: "hide" }, { role: "hideOthers" }, { role: "unhide" }, { type: "separator" }, { role: "quit" }] : []),
...(this.isNotMac
? [
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.quit"),
accelerator: "Control+Q",
click: () => app.quit(),
},
]
: []),
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.view"),
submenu: [
...(this.isMac ? [{ 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"),
accelerator: utils.getStoreValue("general.keybindings.search").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript("app.focusSearch()"),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.listenNow"),
accelerator: utils.getStoreValue("general.keybindings.listnow").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('listen_now')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.browse"),
accelerator: utils.getStoreValue("general.keybindings.browse").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.recentlyAdded"),
accelerator: utils.getStoreValue("general.keybindings.recentAdd").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-recentlyadded')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.songs"),
accelerator: utils.getStoreValue("general.keybindings.songs").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-songs')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.albums"),
accelerator: utils.getStoreValue("general.keybindings.albums").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.artists"),
accelerator: utils.getStoreValue("general.keybindings.artists").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-artists')`),
},
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.window"),
submenu: [
{
role: "minimize",
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.minimize"),
},
{ type: "separator" },
...(this.isMac
? [
{
label: "Show",
click: () => utils.getWindow().show(),
},
{ role: "zoom" },
{ type: "separator" },
{ role: "front" },
{ role: "close" },
{
label: "Edit",
submenu: [{ role: "undo" }, { role: "redo" }, { type: "separator" }, { role: "cut" }, { role: "copy" }, { role: "paste" }],
},
{ type: "separator" },
]
: []),
...(this.isNotMac
? [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.zoom"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomin"),
role: "zoomIn",
accelerator: utils.getStoreValue("general.keybindings.zoomn").join("+"),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomout"),
role: "zoomOut",
accelerator: utils.getStoreValue("general.keybindings.zoomt").join("+"),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomreset"),
role: "resetZoom",
accelerator: utils.getStoreValue("general.keybindings.zoomrst").join("+"),
},
],
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.fullscreen"),
accelerator: "Control+Enter",
role: "togglefullscreen",
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "action.close"),
accelerator: "Control+W",
role: "close",
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.reload"),
accelerator: "Control+R",
role: "reload",
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.forcereload"),
accelerator: "Control+Shift+R",
role: "forceReload",
},
]
: []),
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.controls"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.playpause"),
accelerator: "Space",
click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.next"),
accelerator: "CommandOrControl+Right",
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.previous"),
accelerator: "CommandOrControl+Left",
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.volumeup"),
accelerator: "CommandOrControl+Up",
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.volumedown"),
accelerator: "CommandOrControl+Down",
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeDown()`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.cast2"),
accelerator: utils.getStoreValue("general.keybindings.castToDevices").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.webremote"),
accelerator: utils.getStoreValue("general.keybindings.webRemote").join("+"),
sublabel: "Opens in external window",
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('remote-pair')`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.audioSettings"),
accelerator: utils.getStoreValue("general.keybindings.audioSettings").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.audioSettings = true`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.plugins"),
accelerator: utils.getStoreValue("general.keybindings.pluginMenu").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`),
},
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.account"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.accountSettings"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('apple-account-settings')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.signout"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.unauthorize()`),
},
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.support"),
role: "help",
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.discord"),
click: () => shell.openExternal("https://discord.gg/AppleMusic").catch(console.error),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.github"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/wiki/Troubleshooting").catch(console.error),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.report"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.bug"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug%2Ctriage&template=bug_report.yaml&title=%5BBug%5D%3A+").catch(console.error),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.feature"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/discussions/new?category=feature-request").catch(console.error),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.trans"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=%F0%9F%8C%90+Translations&template=translation.yaml&title=%5BTranslation%5D%3A+").catch(console.error),
},
],
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.license"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/blob/main/LICENSE").catch(console.error),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.toggledevtools"),
accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join("+"),
click: () => utils.getWindow().webContents.openDevTools(),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.conf"),
click: () => utils.getStoreInstance().openInEditor(),
},
],
},
];
private _menuTemplate: any = [];
/*******************************************************************************************
* Public Methods
@ -300,6 +35,273 @@ export default class Thumbar {
* Runs on app ready
*/
onReady(_win: Electron.BrowserWindow): void {
this._menuTemplate = [
{
label: app.getName(),
submenu: [
{
label: `${utils.getLocale(utils.getStoreValue("general.language"), "term.about")} ${app.getName()}`,
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('about')`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.toggleprivate"),
accelerator: utils.getStoreValue("general.keybindings.togglePrivateSession").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.cfg.general.privateEnabled = !app.cfg.general.privateEnabled`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.settings"),
accelerator: utils.getStoreValue("general.keybindings.settings").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.openSettingsPage()`),
},
...(this.isMac ? [{ type: "separator" }, { role: "services" }, { type: "separator" }, { role: "hide" }, { role: "hideOthers" }, { role: "unhide" }, { type: "separator" }, { role: "quit" }] : []),
...(this.isNotMac
? [
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.quit"),
accelerator: "Control+Q",
click: () => app.quit(),
},
]
: []),
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.view"),
submenu: [
...(this.isMac ? [{ 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"),
accelerator: utils.getStoreValue("general.keybindings.search").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript("app.focusSearch()"),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.listenNow"),
accelerator: utils.getStoreValue("general.keybindings.listnow").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('listen_now')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.browse"),
accelerator: utils.getStoreValue("general.keybindings.browse").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('browse')`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.recentlyAdded"),
accelerator: utils.getStoreValue("general.keybindings.recentAdd").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-recentlyadded')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.songs"),
accelerator: utils.getStoreValue("general.keybindings.songs").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-songs')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.albums"),
accelerator: utils.getStoreValue("general.keybindings.albums").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-albums')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.artists"),
accelerator: utils.getStoreValue("general.keybindings.artists").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('library-artists')`),
},
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.window"),
submenu: [
{
role: "minimize",
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.minimize"),
},
{ type: "separator" },
...(this.isMac
? [
{
label: "Show",
click: () => utils.getWindow().show(),
},
{ role: "zoom" },
{ type: "separator" },
{ role: "front" },
{ role: "close" },
{
label: "Edit",
submenu: [{ role: "undo" }, { role: "redo" }, { type: "separator" }, { role: "cut" }, { role: "copy" }, { role: "paste" }],
},
{ type: "separator" },
]
: []),
...(this.isNotMac
? [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.zoom"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomin"),
role: "zoomIn",
accelerator: utils.getStoreValue("general.keybindings.zoomn").join("+"),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomout"),
role: "zoomOut",
accelerator: utils.getStoreValue("general.keybindings.zoomt").join("+"),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.zoomreset"),
role: "resetZoom",
accelerator: utils.getStoreValue("general.keybindings.zoomrst").join("+"),
},
],
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.fullscreen"),
accelerator: "Control+Enter",
role: "togglefullscreen",
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "action.close"),
accelerator: "Control+W",
role: "close",
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.reload"),
accelerator: "Control+R",
role: "reload",
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.forcereload"),
accelerator: "Control+Shift+R",
role: "forceReload",
},
]
: []),
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.controls"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.playpause"),
accelerator: "Space",
click: () => utils.getWindow().webContents.executeJavaScript(`app.SpacePause()`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.next"),
accelerator: "CommandOrControl+Right",
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.next()`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.previous"),
accelerator: "CommandOrControl+Left",
click: () => utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.previous()`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.volumeup"),
accelerator: "CommandOrControl+Up",
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeUp()`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.volumedown"),
accelerator: "CommandOrControl+Down",
click: () => utils.getWindow().webContents.executeJavaScript(`app.volumeDown()`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.cast2"),
accelerator: utils.getStoreValue("general.keybindings.castToDevices").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.castMenu = true`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.webremote"),
accelerator: utils.getStoreValue("general.keybindings.webRemote").join("+"),
sublabel: "Opens in external window",
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('remote-pair')`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.audioSettings"),
accelerator: utils.getStoreValue("general.keybindings.audioSettings").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.audioSettings = true`),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.plugins"),
accelerator: utils.getStoreValue("general.keybindings.pluginMenu").join("+"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.modals.pluginMenu = true`),
},
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.account"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.accountSettings"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.appRoute('apple-account-settings')`),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.signout"),
click: () => utils.getWindow().webContents.executeJavaScript(`app.unauthorize()`),
},
],
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.support"),
role: "help",
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.discord"),
click: () => shell.openExternal("https://discord.gg/AppleMusic").catch(console.error),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "term.github"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/wiki/Troubleshooting").catch(console.error),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.report"),
submenu: [
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.bug"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=bug%2Ctriage&template=bug_report.yaml&title=%5BBug%5D%3A+").catch(console.error),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.feature"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/discussions/new?category=feature-request").catch(console.error),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.trans"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/issues/new?assignees=&labels=%F0%9F%8C%90+Translations&template=translation.yaml&title=%5BTranslation%5D%3A+").catch(console.error),
},
],
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.license"),
click: () => shell.openExternal("https://github.com/ciderapp/Cider/blob/main/LICENSE").catch(console.error),
},
{ type: "separator" },
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.toggledevtools"),
accelerator: utils.getStoreValue("general.keybindings.openDeveloperTools").join("+"),
click: () => utils.getWindow().webContents.openDevTools(),
},
{
label: utils.getLocale(utils.getStoreValue("general.language"), "menubar.options.conf"),
click: () => utils.getStoreInstance().openInEditor(),
},
],
},
];
const menu = Menu.buildFromTemplate(this._menuTemplate);
Menu.setApplicationMenu(menu);
}

View file

@ -1,5 +1,4 @@
// @ts-ignore
import * as Player from "mpris-service";
import Player from 'mpris-service';
export default class mpris {
/**
@ -9,7 +8,7 @@ export default class mpris {
/**
* MPRIS Service
*/
private static player: Player.Player;
private static player: Player;
/**
* Base Plugin Details (Eventually implemented into a GUI in settings)
*/
@ -47,7 +46,7 @@ export default class mpris {
* Connects to MPRIS Service
*/
private static connect() {
const player = Player({
const player = new Player({
name: "cider",
identity: "Cider",
supportedInterfaces: ["player"],
@ -74,6 +73,10 @@ export default class mpris {
player.on("volume", (volume: string) => {
renderer.executeJavaScript(`app.mk.volume = ${parseFloat(volume)}`);
});
player.on("raise", () => {
mpris.utils.getWindow().show();
mpris.utils.getWindow().focus();
});
mpris.utils.getIPCMain().on("mpris:playbackTimeDidChange", (event: any, time: number) => {
player.getPosition = () => time;

View file

@ -1,4 +1,4 @@
import fetch from "electron-fetch";
import fetch from "node-fetch";
import { app, nativeImage, Notification } from "electron";
import NativeImage = Electron.NativeImage;
import { createWriteStream } from "fs";
@ -17,7 +17,7 @@ export default class playbackNotifications {
private _utils: any;
private _notification: Notification | undefined;
private _artworkImage: { [key: string]: NativeImage } = {};
private _artworkNums: Array<string> = [];
private _artworkNums: string[] = [];
/**
* Creates playback notification

View file

@ -1,13 +1,8 @@
import * as electron from "electron";
import * as os from "os";
import * as fs from "fs";
import { join, resolve } from "path";
import * as CiderReceiver from "../base/castreceiver";
import fetch from "electron-fetch";
import electron from "electron";
import fetch from "node-fetch";
import { Stream } from "stream";
import { spawn } from "child_process";
import { Worker } from "worker_threads";
import { Blob } from "buffer";
import mdnsjs from "mdns-js";
export default class RAOP {
/**
@ -24,7 +19,7 @@ export default class RAOP {
private airtunes: any;
// private device: any;
private mdns = require("mdns-js");
private mdns = mdnsjs;
private ok: any = 1;
private devices: any = [];
private castDevices: any = [];
@ -163,8 +158,8 @@ export default class RAOP {
/**
* Runs on app ready
*/
onReady(win: any): void {
this.u = require("airtunes2");
async onReady(win: any): Promise<void> {
this.u = (await import("airtunes2")).default;
this._win = win;
electron.ipcMain.on("getKnownAirplayDevices", (event) => {

View file

@ -1,5 +1,5 @@
import { nativeImage, nativeTheme } from "electron";
import { utils } from "../base/utils";
import { utils } from "../base/utils.js";
import { join } from "path";
export default class Thumbar {

View file

@ -1,4 +1,4 @@
import * as WebSocket from "ws";
import WebSocket from "ws";
/**
* 0-pad a number.

View file

@ -1,12 +0,0 @@
// import * as PouchDB from "pouchdb-node";
// import { join } from "path";
// import { app } from "electron";
// PouchDB.plugin(require("pouchdb-upsert"));
// export class ProviderDB {
// public static db: any = null;
// static init() {
// if (ProviderDB.db == null) {
// ProviderDB.db = new PouchDB(join(app.getPath("userData"), "tracksdb"));
// }
// }
// }

View file

@ -1,11 +1,10 @@
// import { ProviderDB } from "./db";
import * as path from "path";
const { readdir } = require("fs").promises;
import { utils } from "../../base/utils";
import * as mm from "music-metadata";
import { Md5 } from "ts-md5";
import e from "express";
import { EventEmitter } from "events";
import mm from "music-metadata";
import { resolve } from "node:path";
import { Md5 } from "ts-md5";
import { utils } from "../../base/utils.js";
import { readdirSync } from "node:fs";
export class LocalFiles {
static localSongs: any = [];
@ -127,13 +126,14 @@ export class LocalFiles {
this.localSongsArts = metadatalistart;
return metadatalist;
}
static async getFiles(dir: any) {
const dirents = await readdir(dir, { withFileTypes: true });
static async getFiles(dir: string): Promise<string[]> {
const dirents = readdirSync(dir, { withFileTypes: true });
const files = await Promise.all(
dirents.map((dirent: any) => {
const res = path.resolve(dir, dirent.name);
const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? this.getFiles(res) : res;
})
}),
);
return Array.prototype.concat(...files);
}

View file

@ -292,5 +292,5 @@ document.addEventListener(
app.showMenuPanel(menuPanel, e);
}
},
false
false,
);

View file

@ -129,7 +129,9 @@ input[type="range"].md-slider::-webkit-slider-runnable-track {
@media (prefers-color-scheme: light) {
.md-btn {
box-shadow: rgb(0 0 0 / 10%) 0px 0px 1px, rgb(0 0 0 / 20%) 0px 1px 1px;
box-shadow:
rgb(0 0 0 / 10%) 0px 0px 1px,
rgb(0 0 0 / 20%) 0px 1px 1px;
border: 1px solid rgb(0 0 0 / 15%);
}

View file

@ -990,7 +990,9 @@
}
.modal.fade .modal-dialog {
transition: transform 0.1s var(--appleEase), opacity 0.1s var(--appleEase);
transition:
transform 0.1s var(--appleEase),
opacity 0.1s var(--appleEase);
transform: scale(0.9);
opacity: 0;
}
@ -1327,7 +1329,11 @@
font-size: 1rem;
border-radius: 0.25rem;
font-family: inherit;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
transition:
color 0.15s ease-in-out,
background-color 0.15s ease-in-out,
border-color 0.15s ease-in-out,
box-shadow 0.15s ease-in-out;
border: 1px solid rgba(100, 100, 100, 0.35);
border-top: 1px solid rgba(100, 100, 100, 0.5);
border-radius: 6px;
@ -7853,7 +7859,9 @@ fieldset:disabled .btn {
backface-visibility: hidden;
transition: -webkit-transform 0.6s ease-in-out;
transition: transform 0.6s ease-in-out;
transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
transition:
transform 0.6s ease-in-out,
-webkit-transform 0.6s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {

View file

@ -52,7 +52,9 @@
opacity: 0;
border-radius: 10px;
transform: scale(0.5);
transition: transform 0.2s ease-in-out, opacity 0.2s ease-in-out;
transition:
transform 0.2s ease-in-out,
opacity 0.2s ease-in-out;
}
&:after {
@ -63,7 +65,9 @@
background-color: transparent;
&:before {
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
transition:
transform 0.1s ease-in-out,
opacity 0.1s ease-in-out;
opacity: 0.1;
transform: scale(1);
}
@ -103,7 +107,9 @@
background: var(--color2);
-webkit-app-region: no-drag;
height: var(--chromeHeight2);
box-shadow: 0px -2px 6px rgb(20 20 20 / 12%), 0px -1px 0px 0px rgb(200 200 200 / 12%);
box-shadow:
0px -2px 6px rgb(20 20 20 / 12%),
0px -1px 0px 0px rgb(200 200 200 / 12%);
z-index: 4;
.app-chrome-playback-duration-bottom {
@ -140,7 +146,9 @@
border-radius: 100%;
background: var(--keyColor);
cursor: default;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
&:hover {
@ -239,7 +247,9 @@
border-radius: 100%;
background: var(--keyColor);
cursor: default;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
}
}

View file

@ -37,7 +37,9 @@
border-top: 1px solid rgba(100, 100, 100, 0.5);
color: #eee;
white-space: nowrap;
transition: transform 0.2s var(--appleEase), box-shadow 0.2s var(--appleEase);
transition:
transform 0.2s var(--appleEase),
box-shadow 0.2s var(--appleEase);
&.md-btn-block {
display: block;
@ -70,7 +72,9 @@
&:active {
filter: brightness(75%);
transform: scale(0.98);
transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase);
transition:
transform 0s var(--appleEase),
box-shadow 0.2s var(--appleEase);
}
&.md-btn-icon {
@ -1187,12 +1191,16 @@
&.mediaitem-video {
height: 200px;
width: 240px;
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
.artwork {
height: 120px;
width: 212px;
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
}
&:not(.noscale) {
@ -1225,12 +1233,16 @@
&.mediaitem-brick {
height: 200px;
width: 240px;
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
.artwork {
height: 123px;
width: 220px;
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
}
&:not(.noscale) {
@ -1263,12 +1275,16 @@
&.mediaitem-small {
width: calc(140px, var(--windowRelativeScale));
height: calc(180px, var(--windowRelativeScale));
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
.artwork {
height: calc(128px, var(--windowRelativeScale));
width: calc(128px, var(--windowRelativeScale));
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
}
}
@ -1281,7 +1297,9 @@
position: relative;
border-radius: calc(var(--mediaItemRadius) * 2);
box-shadow: var(--mediaItemShadow-ShadowSubtle);
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear;
.artwork {
width: 230px;
@ -1289,7 +1307,10 @@
overflow: hidden;
border-radius: 0px;
margin: 0;
transition: width var(--transitionDuration) linear, height var(--transitionDuration) linear, filter 0.2s ease-in-out;
transition:
width var(--transitionDuration) linear,
height var(--transitionDuration) linear,
filter 0.2s ease-in-out;
.mediaitem-artwork {
border-radius: 0px;
@ -1703,7 +1724,9 @@ input[type="checkbox"][switch]:checked:active::before {
background-position: center;
background-repeat: no-repeat;
border-radius: 8px;
box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55);
box-shadow:
inset 0px 0px 0px 1px rgb(200 200 200 / 16%),
0 8px 40px rgb(0 0 0 / 0.55);
transition: transform 0.1s var(--appleEase);
}
@ -1765,7 +1788,9 @@ input[type="checkbox"][switch]:checked:active::before {
z-index: -1;
transform: scale(0.5);
pointer-events: none;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
&:hover {
@ -1805,7 +1830,9 @@ input[type="checkbox"][switch]:checked:active::before {
z-index: -1;
transform: scale(0.5);
pointer-events: none;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
&:hover {
@ -2056,7 +2083,9 @@ input[type="checkbox"][switch]:checked:active::before {
background-position: center;
background-repeat: no-repeat;
border-radius: 8px;
box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55);
box-shadow:
inset 0px 0px 0px 1px rgb(200 200 200 / 16%),
0 8px 40px rgb(0 0 0 / 0.55);
}
.list-entry-image.artist {
@ -2254,7 +2283,10 @@ input[type="checkbox"][switch]:checked:active::before {
border-radius: 50px;
z-index: -1;
opacity: 0;
transition: background-color 0.5s var(--appleEase), opacity 0.25s var(--appleEase), border-radius 0.32s var(--appleEase);
transition:
background-color 0.5s var(--appleEase),
opacity 0.25s var(--appleEase),
border-radius 0.32s var(--appleEase);
}
&:hover {
@ -2267,7 +2299,11 @@ input[type="checkbox"][switch]:checked:active::before {
&:after {
opacity: 1;
background-color: #eee;
transition: background-color 0.25s var(--appleEase), border-radius 0.25s var(--appleEase), color 0s var(--appleEase), opacity 0s var(--appleEase);
transition:
background-color 0.25s var(--appleEase),
border-radius 0.25s var(--appleEase),
color 0s var(--appleEase),
opacity 0s var(--appleEase);
}
}

View file

@ -89,7 +89,9 @@
opacity: 0;
border-radius: 10px;
transform: scale(0.5);
transition: transform 0.2s ease-in-out, opacity 0.2s ease-in-out;
transition:
transform 0.2s ease-in-out,
opacity 0.2s ease-in-out;
}
&:after {
@ -100,7 +102,9 @@
background-color: transparent;
&:before {
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
transition:
transform 0.1s ease-in-out,
opacity 0.1s ease-in-out;
opacity: 0.1;
transform: scale(1);
}
@ -453,7 +457,9 @@
border-radius: 100%;
background: var(--songProgressColor);
cursor: default;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
&::-moz-range-thumb {

View file

@ -107,7 +107,10 @@
height: calc(12px * 6);
border-radius: 6px;
transform: rotateX(60deg) rotateZ(-45deg);
transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
transition:
transform 0.2s linear,
width 0.2s linear,
height 0.2s linear;
}
.listener {
@ -116,7 +119,10 @@
height: 32px;
border-radius: 6px;
transform: rotateX(60deg) rotateZ(-45deg);
transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
transition:
transform 0.2s linear,
width 0.2s linear,
height 0.2s linear;
background: white;
color: black;
z-index: 2;
@ -128,7 +134,10 @@
height: 32px;
border-radius: 6px;
transform: rotateX(60deg) rotateZ(-45deg);
transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
transition:
transform 0.2s linear,
width 0.2s linear,
height 0.2s linear;
background: yellow;
z-index: 2;
}
@ -321,12 +330,16 @@
opacity: 0;
transform: scale(0.98);
z-index: -1;
transition: transform 0.25s ease-out, opacity 0.25s ease-out;
transition:
transform 0.25s ease-out,
opacity 0.25s ease-out;
}
&:hover {
&::before {
transition: transform 0s ease-in, opacity 0s ease-in;
transition:
transform 0s ease-in,
opacity 0s ease-in;
opacity: 1;
transform: scale(1);
}
@ -334,7 +347,9 @@
&:active {
&::before {
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
transition:
transform 0.1s ease-in-out,
opacity 0.1s ease-in-out;
opacity: 1;
transform: scale(0.98);
background: var(--selected-click);

View file

@ -379,7 +379,9 @@
border-radius: 100%;
background: var(--songProgressColor);
cursor: default;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
&::-moz-range-thumb {

View file

@ -298,7 +298,9 @@
background-color: rgba(0, 0, 0, 0.25);
border: none;
cursor: pointer;
transition: opacity 0.2s ease, background-color 0.2s ease;
transition:
opacity 0.2s ease,
background-color 0.2s ease;
outline: none;
opacity: 0.35;
height: 100%;

View file

@ -748,7 +748,9 @@
}
.mediaContainer {
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
transition:
width 0.5s ease-in-out,
height 0.5s ease-in-out;
width: 260px;
height: 260px;
}
@ -948,7 +950,9 @@
}
.playlist-desc {
transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out;
transition:
height 0.2s ease-in-out,
opacity 0.2s ease-in-out;
box-sizing: border-box;
font-size: 14px;
flex-shrink: unset;
@ -1088,7 +1092,9 @@
font-size: 0.9em;
margin: 6px;
opacity: 0.7;
transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out;
transition:
height 0.2s ease-in-out,
opacity 0.2s ease-in-out;
height: 0.9em;
}
@ -1152,19 +1158,25 @@
}
.mediaContainer {
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
transition:
width 0.5s ease-in-out,
height 0.5s ease-in-out;
width: 128px !important;
height: 128px !important;
}
.playlist-time {
transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out;
transition:
height 0.2s ease-in-out,
opacity 0.2s ease-in-out;
height: 0px;
opacity: 0;
}
.playlist-desc {
transition: height 0.2s ease-in-out, opacity 0.2s ease-in-out;
transition:
height 0.2s ease-in-out,
opacity 0.2s ease-in-out;
height: 0px !important;
opacity: 0;
}
@ -1413,7 +1425,9 @@
&:active {
filter: brightness(75%);
transform: scale(0.98);
transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase);
transition:
transform 0s var(--appleEase),
box-shadow 0.2s var(--appleEase);
}
}
@ -1555,7 +1569,9 @@
background: rgb(0 0 0 / 20%);
z-index: 1;
border: 0px;
transition: background 0.2s var(--appleEase), transform 0.2s var(--appleEase);
transition:
background 0.2s var(--appleEase),
transform 0.2s var(--appleEase);
&:hover {
background: var(--selected);
@ -1625,7 +1641,9 @@
.spfade-enter-active,
.spfade-leave-active {
--transitionTime: 0.2s;
transition: opacity var(--transitionTime) var(--appleEase), transform var(--transitionTime) var(--appleEase);
transition:
opacity var(--transitionTime) var(--appleEase),
transform var(--transitionTime) var(--appleEase);
will-change: opacity, transform;
}
@ -2120,7 +2138,11 @@
position: relative;
flex: 1;
backdrop-filter: var(--glassFilterHeavy);
transition: width 0.25s ease-in-out, height 0.25s ease-in-out, max-width 0.25s ease-in-out, max-height 0.25s ease-in-out;
transition:
width 0.25s ease-in-out,
height 0.25s ease-in-out,
max-width 0.25s ease-in-out,
max-height 0.25s ease-in-out;
.header-text {
position: absolute;

View file

@ -211,7 +211,7 @@ function simulateGamepad() {
notyf.success("Pairing successful!");
appLoop();
},
{ once: true }
{ once: true },
);
document.addEventListener("keydown", (e) => {

View file

@ -19,7 +19,7 @@ const app = new Vue({
pluginInstalled: false,
pluginMenuEntries: [],
pluginMenuTopEntries: [],
lz: ipcRenderer.sendSync("get-i18n", "en_US"),
lz: ipcRenderer.sendSync("get-i18n", "en"),
lzListing: ipcRenderer.sendSync("get-i18n-listing"),
radiohls: null,
search: {
@ -288,7 +288,7 @@ const app = new Vue({
let currentPath = window.location.hash.slice(1);
console.debug("hashchange", currentPath);
},
false
false,
);
},
methods: {
@ -759,7 +759,7 @@ const app = new Vue({
data: pitems,
}),
},
}
},
)
.then(() => {
if (app.page === "playlist_" + pid) {
@ -1030,7 +1030,7 @@ const app = new Vue({
app.stringTemplateParser(app.getLz("settings.option.connectivity.discordRPC.reconnectedToUser"), {
user: `${user.username}#${user.discriminator}`,
userid: user.id,
})
}),
);
}
});
@ -1590,7 +1590,7 @@ const app = new Vue({
fetchOptions: {
method: "POST",
},
}
},
);
} else {
if (app.cfg.home.followedArtists.includes(id)) {
@ -1608,7 +1608,7 @@ const app = new Vue({
fetchOptions: {
method: "DELETE",
},
}
},
);
}
},
@ -1746,7 +1746,7 @@ const app = new Vue({
attributes: { name: name },
}),
},
}
},
)
.then((res) => {
self.refreshPlaylists(false, false);
@ -1765,7 +1765,7 @@ const app = new Vue({
attributes: { name: name },
}),
},
}
},
)
.then((res) => {
self.refreshPlaylists(false, false);
@ -1784,7 +1784,7 @@ const app = new Vue({
attributes: { description: name },
}),
},
}
},
)
.then((res) => {
self.refreshPlaylists(false, false);
@ -1820,7 +1820,7 @@ const app = new Vue({
},
}),
},
}
},
)
.then((res) => {
res = res.data.data[0];
@ -1853,7 +1853,7 @@ const app = new Vue({
fetchOptions: {
method: "DELETE",
},
}
},
)
.then((res) => {
// remove this playlist from playlists.listing if it exists
@ -2011,7 +2011,7 @@ const app = new Vue({
"art[url]": "f",
l: this.mklang,
},
{ includeResponseMeta: !0 }
{ includeResponseMeta: !0 },
);
console.debug(artistData.data.data[0]);
this.artistPage.data = artistData.data.data[0];
@ -3213,7 +3213,7 @@ const app = new Vue({
{
includeResponseMeta: !0,
reload: !0,
}
},
)
).data;
this.listennow.timestamp = Date.now();
@ -3308,7 +3308,7 @@ const app = new Vue({
attributes: { name: name },
}),
},
}
},
)
.then((res) => {
let playlist = res.data.data[0];
@ -3384,7 +3384,7 @@ const app = new Vue({
fetchOptions: {
method: "DELETE",
},
}
},
)
.then((data) => {
self.getLibrarySongsFull(true);
@ -4281,7 +4281,7 @@ const app = new Vue({
"art[url]": "f",
"art[social-profiles:url]": "c",
},
{ includeResponseMeta: !0 }
{ includeResponseMeta: !0 },
)
.then(function (results) {
results.data.results["meta"] = results.data.meta;
@ -4536,7 +4536,7 @@ const app = new Vue({
},
}),
},
}
},
);
},
dislike(item) {
@ -4561,7 +4561,7 @@ const app = new Vue({
},
}),
},
}
},
);
},
unlove(item) {
@ -4580,7 +4580,7 @@ const app = new Vue({
fetchOptions: {
method: "DELETE",
},
}
},
);
},
checkScrollDirectionIsUp(event) {

View file

@ -166,7 +166,7 @@ const wsapi = {
fetchOptions: {
method: "DELETE",
},
}
},
)
.then(function () {
ipcRenderer.send("wsapi-rate", kind, id, rating);
@ -190,7 +190,7 @@ const wsapi = {
},
}),
},
}
},
)
.then(function () {
ipcRenderer.send("wsapi-rate", kind, id, rating);

View file

@ -72,7 +72,22 @@ body {
background-size: cover;
background-position: center;
background: #0000;
font-family: "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-family:
"Pretendard Variable",
"Noto Sans JP",
"Noto Sans KR",
"Noto Sans TC",
"Noto Sans SC",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Oxygen,
Ubuntu,
Cantarell,
"Open Sans",
"Helvetica Neue",
sans-serif;
transition: opacity 0.1s var(--appleEase);
}
@ -934,7 +949,9 @@ input[type="range"].web-slider::-webkit-slider-runnable-track {
.app-chrome {
background-color: var(--baseColorMix);
box-shadow: 0px 3px 6px rgb(20 20 20 / 12%), 0px 1px 0px 0px rgb(200 200 200 / 12%);
box-shadow:
0px 3px 6px rgb(20 20 20 / 12%),
0px 1px 0px 0px rgb(200 200 200 / 12%);
width: 100%;
height: var(--chromeHeight1);
display: flex;
@ -1461,7 +1478,9 @@ div[data-type="musicVideo"] .info-rect .title::before {
border-radius: 100%;
background: var(--songProgressColor);
cursor: default;
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
&::-moz-range-thumb {
@ -1696,7 +1715,22 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
overflow-x: hidden;
display: flex;
flex-flow: column;
font-family: "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-family:
"Pretendard Variable",
"Noto Sans JP",
"Noto Sans KR",
"Noto Sans TC",
"Noto Sans SC",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Oxygen,
Ubuntu,
Cantarell,
"Open Sans",
"Helvetica Neue",
sans-serif;
}
.lyric-body .no-lyrics {
@ -1756,7 +1790,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
opacity: 1;
transform: scale(1);
/*background: var(--keyColor);*/
transition: transform 0.2s var(--appleEase), opacity 0.35s var(--appleEase);
transition:
transform 0.2s var(--appleEase),
opacity 0.35s var(--appleEase);
}
.lyric-line:not(.active) {
@ -1800,7 +1836,22 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.lyrics-translation {
font-size: 1.6rem;
font-weight: 450;
font-family: "Pretendard Variable", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-family:
"Pretendard Variable",
"Noto Sans JP",
"Noto Sans KR",
"Noto Sans TC",
"Noto Sans SC",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Oxygen,
Ubuntu,
Cantarell,
"Open Sans",
"Helvetica Neue",
sans-serif;
filter: contrast(0.5);
}
@ -1909,7 +1960,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
&:active {
filter: brightness(75%);
transform: scale(0.98);
transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase);
transition:
transform 0s var(--appleEase),
box-shadow 0.2s var(--appleEase);
}
.svg-icon {
@ -2258,7 +2311,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.replaycard-enter-active,
.replaycard-leave-active {
transition: opacity 0.5s var(--appleEase), transform 0.5s var(--appleEase);
transition:
opacity 0.5s var(--appleEase),
transform 0.5s var(--appleEase);
}
.replaycard-enter,
@ -2279,7 +2334,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.modal-enter-active,
.modal-leave-active {
transition: opacity 0.1s var(--appleEase), transform 0.1s var(--appleEase);
transition:
opacity 0.1s var(--appleEase),
transform 0.1s var(--appleEase);
}
.modal-enter,
@ -2337,7 +2394,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.fabfade-enter-active,
.fabfade-leave-active {
transition: transform 0.1s var(--appleEase), opacity 0.1s var(--appleEase);
transition:
transform 0.1s var(--appleEase),
opacity 0.1s var(--appleEase);
}
.fabfade-enter,
@ -2348,7 +2407,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
.fsModeSwitch-enter-active,
.fsModeSwitch-leave-active {
transition: transform 1s var(--appleEase), opacity 1s var(--appleEase);
transition:
transform 1s var(--appleEase),
opacity 1s var(--appleEase);
}
.fsModeSwitch-enter,

View file

@ -59,7 +59,7 @@ define(["./workbox-962786f2"], function (e) {
],
{
ignoreURLParametersMatching: [/^utm_/, /^fbclid$/, /^X-Amz-Algorithm/, /^X-Amz-Date/, /^X-Amz-SignedHeaders/, /^X-Amz-Expires/, /^X-Amz-Credential/, /^X-Amz-Signature/],
}
},
),
e.registerRoute(/\.(?:png|jpg|jpeg|svg|webp)$/, new e.CacheFirst({ cacheName: "imageinternet", plugins: [] }), "GET"),
e.registerRoute(/https:\/\/is[0-9]-ssl\.mzstatic\.com\/image+/, new e.CacheFirst(), "GET"),

View file

@ -13,7 +13,9 @@
.drawertransition-enter-active,
.drawertransition-leave-active {
transition: margin 0.25s var(--appleEase), opacity 0.25s var(--appleEase);
transition:
margin 0.25s var(--appleEase),
opacity 0.25s var(--appleEase);
}
.drawertransition-enter,
@ -29,7 +31,9 @@
.drawertransition-enter-active,
.drawertransition-leave-active {
transition: right 0.25s var(--appleEase), opacity 0.25s var(--appleEase);
transition:
right 0.25s var(--appleEase),
opacity 0.25s var(--appleEase);
}
.drawertransition-enter,

View file

@ -98,7 +98,9 @@
.wpfade_transform-enter-active,
.wpfade_transform-leave-active {
--transitionTime: 0.2s;
transition: opacity var(--transitionTime) var(--appleEase), transform var(--transitionTime) var(--appleEase);
transition:
opacity var(--transitionTime) var(--appleEase),
transform var(--transitionTime) var(--appleEase);
will-change: opacity, transform;
}
@ -116,7 +118,9 @@
.wpfade_transform_backwards-enter-active,
.wpfade_transform_backwards-leave-active {
--transitionTime: 0.2s;
transition: opacity var(--transitionTime) var(--appleEase), transform var(--transitionTime) var(--appleEase);
transition:
opacity var(--transitionTime) var(--appleEase),
transform var(--transitionTime) var(--appleEase);
}
.wpfade_transform_backwards-enter {

View file

@ -44,7 +44,7 @@ await app.mk.api.personalRecommendations(
{
includeResponseMeta: !0,
reload: !0,
}
},
);
// Browse page
@ -86,7 +86,7 @@ await app.mk.api.library.recentlyAdded(
{
reload: !0,
includePagination: !0,
}
},
);
// Songs
@ -136,7 +136,7 @@ app
"limit[artists:top-songs]": 20,
"art[url]": "f",
},
{ includeResponseMeta: !0 }
{ includeResponseMeta: !0 },
)
.then((data) => {
console.log(data);

View file

@ -7,7 +7,7 @@
@contextmenu.self="closePromo">
<div class="modal-window">
<div class="modal-header">
<div class="modal-title">Cider 2 Free Upgrade - Last Call!</div>
<div class="modal-title">Cider 2 Free Upgrade Last Call!</div>
<button
class="close-btn"
@click="closePromo"
@ -23,15 +23,17 @@
class="p-3"
style="font-size: 14px">
Earlier this year, we released Cider 2, a complete rewrite of Cider.
<br />Cider 2 is a paid upgrade, but we're offering it for free to all Cider users who purchased Cider 1 <b>on or before November 30th, 2022.</b>
<br />Cider 2 is a paid upgrade, but we're offering it <b>for free</b> to Cider users who have purchased Cider 1.
<br />
<br />
If you are eligible for a free upgrade, you can download Cider 2 from the Microsoft Store.
Download Cider 2 from the Microsoft Store today!
<br />
<br />
<b> The cutoff date for this upgrade is: <br />June, 30th 2023. </b>
<b>This limited offer is valid until June 4th, 2023.</b>
<br />
<br />
<i>Upon opening the website, please click "Get in Store app" to continue.</i>
<br />
<br />
<label>
@ -39,7 +41,7 @@
type="checkbox"
style="accent-color: var(--keyColor)"
v-model="showOnStartup" />
Show this offer again on next startup
Show this reminder again on next startup
</label>
<template v-if="hasSeen">
<br />
@ -48,7 +50,7 @@
type="checkbox"
style="accent-color: var(--keyColor)"
v-model="removeItemFromMainMenu" />
Remove upgrade item from Main Menu
Remove upgrade button from Quick Navigation/Main Menu
</label>
</template>
</p>

View file

@ -1700,10 +1700,17 @@
if (langs[i].category === undefined || langs[i].category === "") {
categories.unsorted.push(langs[i])
} else {
categories[langs[i].category].push(langs[i])
try {
categories[langs[i].category].push(langs[i])
}
catch {
categories["unsorted"].push(langs[i])
}
}
}
// return
console.log(categories)
return categories
},
addExperiment(flag) {

View file

@ -28,9 +28,9 @@
v-model="app.cfg.audio.maikiwiAudio.ciderPPE_value"
v-on:change="CiderAudio.hierarchical_loading()">
<option v-for="(item, index) in ciderPPE"
:value="item.displayName"
:value="item.name"
:key="index.name">
{{item}}
{{item.displayName}}
</option>
</select>
</div>
@ -140,14 +140,19 @@
app: this.$root,
arprofiles: CiderAudio.atmosphereRealizerProfiles,
spprofiles: CiderAudio.spatialProfiles,
ciderPPE: [{name: "MAIKIWI", displayName: "Maikiwi " + $root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive')},
{name: "MAIKIWI_LEGACY", displayName: "Maikiwi " + $root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')},
{name: "NATURAL", displayName: $root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard')},
{name: "LEGACY", displayName: $root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')}]
ciderPPE: [{name: "MAIKIWI", displayName: "Maikiwi " + app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive')},
{name: "MAIKIWI_LEGACY", displayName: "Maikiwi " + app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')},
{name: "NATURAL", displayName: app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard')},
{name: "LEGACY", displayName: app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')}]
}
},
mounted: function () {
return {
ciderPPE: [{name: "MAIKIWI", displayName: "Maikiwi " + app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive')},
{name: "MAIKIWI_LEGACY", displayName: "Maikiwi " + app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')},
{name: "NATURAL", displayName: app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard')},
{name: "LEGACY", displayName: app.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')}]
}
},
methods: {
}

View file

@ -32,7 +32,7 @@ define(["exports"], function (t) {
if (s && (e.origin === location.origin || 0 === s.index)) return s.slice(1);
},
e,
s
s,
);
}
}
@ -59,7 +59,7 @@ define(["exports"], function (t) {
"string" == typeof e && (e = [e]);
const s = new Request(...e);
return this.handleRequest({ request: s, event: t });
})
}),
);
t.waitUntil(s), t.ports && t.ports[0] && s.then(() => t.ports[0].postMessage(!0));
}
@ -306,7 +306,7 @@ define(["exports"], function (t) {
request: n,
event: this.event,
params: this.params,
})
}),
);
this.h[s] = n;
}
@ -601,7 +601,7 @@ define(["exports"], function (t) {
params: { cacheKey: s },
request: i,
event: t,
})
}),
);
}
const { updatedURLs: s, notUpdatedURLs: n } = e;

View file

@ -85,7 +85,7 @@ var app = new Vue({
id: id,
params: params,
library: library,
})
}),
);
},
resetPlayerUI() {
@ -157,7 +157,7 @@ var app = new Vue({
JSON.stringify({
action: "set-autoplay",
autoplay: value,
})
}),
);
this.getCurrentMediaItem();
if (value) {
@ -176,7 +176,7 @@ var app = new Vue({
JSON.stringify({
action: "seek",
time: time,
})
}),
);
},
setVolume(volume) {
@ -184,49 +184,49 @@ var app = new Vue({
JSON.stringify({
action: "volume",
volume: volume,
})
}),
);
},
getVolumeMax() {
socket.send(
JSON.stringify({
action: "volumeMax",
})
}),
);
},
getQueue() {
socket.send(
JSON.stringify({
action: "get-queue",
})
}),
);
},
play() {
socket.send(
JSON.stringify({
action: "play",
})
}),
);
},
pause() {
socket.send(
JSON.stringify({
action: "pause",
})
}),
);
},
next() {
socket.send(
JSON.stringify({
action: "next",
})
}),
);
},
previous() {
socket.send(
JSON.stringify({
action: "previous",
})
}),
);
},
searchArtist() {
@ -251,7 +251,7 @@ var app = new Vue({
action: "play-mediaitem",
id: id,
kind: kind,
})
}),
);
this.screen = "player";
},
@ -261,7 +261,7 @@ var app = new Vue({
action: "play-next",
type: type,
id: id,
})
}),
);
},
playLater(type, id) {
@ -270,7 +270,7 @@ var app = new Vue({
action: "play-later",
type: type,
id: id,
})
}),
);
},
getLibraryStatus(type, id) {
@ -280,7 +280,7 @@ var app = new Vue({
action: "library-status",
type: type,
id: id,
})
}),
);
} else {
this.player.status = {};
@ -301,7 +301,7 @@ var app = new Vue({
action: actionType,
term: this.search.query,
limit: 20,
})
}),
);
},
quickSearch() {
@ -314,7 +314,7 @@ var app = new Vue({
JSON.stringify({
action: "quick-play",
term: search,
})
}),
);
},
parseTime(value) {
@ -464,7 +464,7 @@ var app = new Vue({
action: "queue-move",
from: evt.moved.oldIndex,
to: evt.moved.newIndex,
})
}),
);
this.getQueue();
return true;
@ -473,7 +473,7 @@ var app = new Vue({
socket.send(
JSON.stringify({
action: "repeat",
})
}),
);
this.getCurrentMediaItem();
},
@ -481,7 +481,7 @@ var app = new Vue({
socket.send(
JSON.stringify({
action: "shuffle",
})
}),
);
this.getCurrentMediaItem();
},
@ -490,7 +490,7 @@ var app = new Vue({
JSON.stringify({
action: "set-shuffle",
shuffle: val,
})
}),
);
this.getCurrentMediaItem();
},
@ -535,7 +535,7 @@ var app = new Vue({
socket.send(
JSON.stringify({
action: "get-lyrics",
})
}),
);
},
showLyrics() {
@ -567,7 +567,7 @@ var app = new Vue({
socket.send(
JSON.stringify({
action: "get-currentmediaitem",
})
}),
);
},
setStreamerOverlay() {
@ -717,7 +717,7 @@ var app = new Vue({
type: params.kind,
id: params.id,
rating: rating,
})
}),
);
}
},
@ -731,7 +731,7 @@ var app = new Vue({
type: params.kind,
id: params.id,
add: shouldAdd,
})
}),
);
}
},
@ -739,7 +739,7 @@ var app = new Vue({
socket.send(
JSON.stringify({
action: "quit",
})
}),
);
},
},

View file

@ -393,12 +393,12 @@
return r ? Se(r, i) : i;
}
: t
? e
? function () {
return Se("function" == typeof t ? t.call(this, this) : t, "function" == typeof e ? e.call(this, this) : e);
}
: t
: e;
? e
? function () {
return Se("function" == typeof t ? t.call(this, this) : t, "function" == typeof e ? e.call(this, this) : e);
}
: t
: e;
}
function Ne(e, t) {
var n = t ? (e ? e.concat(t) : Array.isArray(t) ? t : [t]) : e;
@ -697,13 +697,13 @@
return i(e)
? [he(e)]
: Array.isArray(e)
? (function e(o, a) {
var s = [];
var c, u, l, f;
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)));
return s;
})(e)
: void 0;
? (function e(o, a) {
var s = [];
var c, u, l, f;
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)));
return s;
})(e)
: void 0;
}
function ct(e) {
return n(e) && n(e.text) && !1 === e.isComment;
@ -1135,23 +1135,23 @@
return Array.isArray(u)
? u
: n(u)
? (n(l) &&
(function e(i, o, a) {
i.ns = o;
"foreignObject" === i.tag && ((o = void 0), (a = !0));
if (n(i.children))
for (var s = 0, c = i.children.length; s < c; s++) {
var u = i.children[s];
n(u.tag) && (t(u.ns) || (r(a) && "svg" !== u.tag)) && e(u, o, a);
}
})(u, l),
n(a) &&
(function (e) {
o(e.style) && tt(e.style);
o(e.class) && tt(e.class);
})(a),
u)
: ve();
? (n(l) &&
(function e(i, o, a) {
i.ns = o;
"foreignObject" === i.tag && ((o = void 0), (a = !0));
if (n(i.children))
for (var s = 0, c = i.children.length; s < c; s++) {
var u = i.children[s];
n(u.tag) && (t(u.ns) || (r(a) && "svg" !== u.tag)) && e(u, o, a);
}
})(u, l),
n(a) &&
(function (e) {
o(e.style) && tt(e.style);
o(e.class) && tt(e.class);
})(a),
u)
: ve();
})(e, a, s, c, u)
);
}
@ -1323,17 +1323,17 @@
this.lazy
? (this.dirty = !0)
: this.sync
? this.run()
: (function (e) {
var t = e.id;
if (null == nn[t]) {
if (((nn[t] = !0), on)) {
for (var n = en.length - 1; n > an && en[n].id > e.id; ) n--;
en.splice(n + 1, 0, e);
} else en.push(e);
rn || ((rn = !0), Qe(ln));
}
})(this);
? this.run()
: (function (e) {
var t = e.id;
if (null == nn[t]) {
if (((nn[t] = !0), on)) {
for (var n = en.length - 1; n > an && en[n].id > e.id; ) n--;
en.splice(n + 1, 0, e);
} else en.push(e);
rn || ((rn = !0), Qe(ln));
}
})(this);
}),
(pn.prototype.run = function () {
if (this.active) {
@ -1408,7 +1408,7 @@
fe();
}
})(t, e)
: t || {})
: t || {}),
) || (t = {});
var n = Object.keys(t),
r = e.$options.props,
@ -1883,21 +1883,21 @@
return r;
})(e)
: o(e)
? (function (e) {
var t = "";
for (var n in e) e[n] && (t && (t += " "), (t += n));
return t;
})(e)
: "string" == typeof e
? e
: "";
? (function (e) {
var t = "";
for (var n in e) e[n] && (t && (t += " "), (t += n));
return t;
})(e)
: "string" == typeof e
? e
: "";
}
var Jn = {
svg: "http://www.w3.org/2000/svg",
math: "http://www.w3.org/1998/Math/MathML",
},
qn = p(
"html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"
"html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot",
),
Wn = p("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignobject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view", !0),
Zn = function (e) {
@ -2201,8 +2201,8 @@
isDynamicArg: o,
modifiers: a,
},
s
)
s,
),
),
(e.plain = !1);
}
@ -2564,7 +2564,7 @@
null,
t.map(function (t, n) {
return Pi(t) + Pi(e[n]);
})
}),
);
}
function Pi(e) {
@ -2795,23 +2795,23 @@
t(h)
? (h = r[++p])
: t(m)
? (m = r[--v])
: or(h, g)
? (x(h, g, o, i, d), (h = r[++p]), (g = i[++d]))
: or(m, b)
? (x(m, b, o, i, y), (m = r[--v]), (b = i[--y]))
: or(h, b)
? (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)
? (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((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]));
? (m = r[--v])
: or(h, g)
? (x(h, g, o, i, d), (h = r[++p]), (g = i[++d]))
: or(m, b)
? (x(m, b, o, i, y), (m = r[--v]), (b = i[--y]))
: or(h, b)
? (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)
? (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((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, h, y, o, l)
: n(y)
? (n(e.text) && u.setTextContent(p, ""), _(p, null, y, 0, y.length - 1, o))
: n(h)
? $(h, 0, h.length - 1)
: n(e.text) && u.setTextContent(p, "")
? (n(e.text) && u.setTextContent(p, ""), _(p, null, y, 0, y.length - 1, o))
: n(h)
? $(h, 0, h.length - 1)
: n(e.text) && u.setTextContent(p, "")
: e.text !== i.text && u.setTextContent(p, i.text),
n(v) && n((d = v.hook)) && n((d = d.postpatch)) && d(e, i);
}
@ -3176,7 +3176,7 @@
Oi,
(n._moveCb = function e(r) {
(r && r.target !== n) || (r && !/transform$/.test(r.propertyName)) || (n.removeEventListener(Oi, e), (n._moveCb = null), Di(n, t));
})
}),
);
}
}));
@ -3232,7 +3232,7 @@
e._isMounted && !e._isDestroyed && Qt(e, "beforeUpdate");
},
},
!0
!0,
),
(n = !1),
null == e.$vnode && ((e._isMounted = !0), Qt(e, "mounted")),
@ -3635,7 +3635,7 @@
n,
(function (e, t) {
return e.rawAttrsMap[":" + t] || e.rawAttrsMap["v-bind:" + t] || e.rawAttrsMap[t];
})(e, "slot")
})(e, "slot"),
));
if ("template" === e.tag) {
var r = Rr(e, oa);
@ -3969,7 +3969,7 @@
.map(function (e) {
return "$event." + e + "Key";
})
.join("||")
.join("||"),
);
} else a.push(s);
return (
@ -4040,7 +4040,7 @@
value: e.value,
dynamic: e.dynamic,
};
})
}),
)
: null,
a = e.attrsMap["v-bind"];
@ -4361,7 +4361,7 @@
delimiters: n.delimiters,
comments: n.comments,
},
this
this,
),
o = i.render,
a = i.staticRenderFns;

View file

@ -1,22 +1,30 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es6",
"module": "commonjs",
"allowJs": true,
"noImplicitAny": true,
"strict": true,
"outDir": "build",
"inlineSources": true,
"sourceMap": true,
"outDir": "./build",
"baseUrl": ".",
"allowJs": true,
"esModuleInterop": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
// Needed to address https://github.com/quasarframework/app-extension-typescript/issues/36
"noEmit": false,
"resolveJsonModule": true,
"paths": {
"*": ["node_modules/*"]
},
"skipLibCheck": true,
// Avoid cross-os errors due to inconsistent file casing
"forceConsistentCasingInFileNames": true,
"sourceMap": true,
"strict": true,
"target": "esnext",
"isolatedModules": true,
"useDefineForClassFields": true,
// Fix Volar issue https://github.com/johnsoncodehk/volar/issues/1153
"jsx": "preserve",
"lib": ["esnext", "dom"],
"experimentalDecorators": true,
"baseUrl": "./",
"allowSyntheticDefaultImports": true,
"typeRoots": ["node_modules/musickit-typescript", "node_modules/@types"]
"noImplicitThis": true,
"skipLibCheck": true /* Skip type checking of declaration files. */,
"typeRoots": ["node_modules/musickit-typescript", "node_modules/@types"],
},
"include": ["src/main/**/*"]
"include": ["src/**/*.ts"],
}

View file

@ -5,8 +5,8 @@
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
},
"appId": "cider",
"afterPack": "./resources/afterPack.js",
"afterSign": "./resources/notarize.js",
"afterPack": "./resources/afterPack.cjs",
"afterSign": "./resources/notarize.cjs",
"protocols": [
{
"name": "Cider",

11737
yarn.lock

File diff suppressed because it is too large Load diff