Compare commits
No commits in common. 'd13c1129dec7c62db0fb2041a4fd06b10dba93a6' and '6d8850520470f6196eb83710b1e841f6f7d55df8' have entirely different histories.
d13c1129de
...
6d88505204
@ -0,0 +1,16 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
Dockerfile*
|
||||
docker-compose*
|
||||
.dockerignore
|
||||
.git
|
||||
.github
|
||||
.gitignore
|
||||
README.md
|
||||
LICENSE
|
||||
.vscode
|
||||
dist
|
||||
dist_electron
|
||||
build
|
||||
images
|
||||
script
|
@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
@ -0,0 +1,7 @@
|
||||
* text eol=lf
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.mp3 binary
|
||||
*.icns binary
|
||||
*.gif binary
|
@ -0,0 +1,116 @@
|
||||
name: Release
|
||||
|
||||
env:
|
||||
YARN_INSTALL_NOPT: yarn add --ignore-platform --ignore-optional
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04]
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Install Node.js, NPM and Yarn
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install RPM & Pacman (on Ubuntu)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install --no-install-recommends -y rpm &&
|
||||
sudo apt-get install --no-install-recommends -y bsdtar &&
|
||||
sudo apt-get install --no-install-recommends -y libopenjp2-tools
|
||||
|
||||
- name: Install Snapcraft (on Ubuntu)
|
||||
uses: samuelmeuli/action-snapcraft@v1
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
with:
|
||||
snapcraft_token: ${{ secrets.snapcraft_token }}
|
||||
|
||||
- id: get_unm_version
|
||||
name: Get the installed UNM version
|
||||
run: |
|
||||
yarn --ignore-optional
|
||||
unm_version=$(node -e "console.log(require('./node_modules/@unblockneteasemusic/rust-napi/package.json').version)")
|
||||
echo "::set-output name=unmver::${unm_version}"
|
||||
shell: bash
|
||||
|
||||
- name: Install UNM dependencies for Windows
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
${{ env.YARN_INSTALL_NOPT }} \
|
||||
@unblockneteasemusic/rust-napi-win32-x64-msvc@${{steps.get_unm_version.outputs.unmver}}
|
||||
shell: bash
|
||||
|
||||
- name: Install UNM dependencies for macOS
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
${{ env.YARN_INSTALL_NOPT }} \
|
||||
@unblockneteasemusic/rust-napi-darwin-x64@${{steps.get_unm_version.outputs.unmver}} \
|
||||
@unblockneteasemusic/rust-napi-darwin-arm64@${{steps.get_unm_version.outputs.unmver}} \
|
||||
dmg-license
|
||||
shell: bash
|
||||
|
||||
- name: Install UNM dependencies for Linux
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
${{ env.YARN_INSTALL_NOPT }} \
|
||||
@unblockneteasemusic/rust-napi-linux-x64-gnu@${{steps.get_unm_version.outputs.unmver}} \
|
||||
@unblockneteasemusic/rust-napi-linux-arm64-gnu@${{steps.get_unm_version.outputs.unmver}} \
|
||||
@unblockneteasemusic/rust-napi-linux-arm-gnueabihf@${{steps.get_unm_version.outputs.unmver}}
|
||||
shell: bash
|
||||
|
||||
- name: Build/release Electron app
|
||||
uses: samuelmeuli/action-electron-builder@v1.6.0
|
||||
env:
|
||||
VUE_APP_ELECTRON_API_URL: /api
|
||||
VUE_APP_ELECTRON_API_URL_DEV: /api
|
||||
# VUE_APP_ELECTRON_API_URL_DEV: http://127.0.0.1:10754
|
||||
VUE_APP_LASTFM_API_KEY: 09c55292403d961aa517ff7f5e8a3d9c
|
||||
VUE_APP_LASTFM_API_SHARED_SECRET: 307c9fda32b3904e53654baff215cb67
|
||||
with:
|
||||
# GitHub token, automatically provided to the action
|
||||
# (No need to define this secret in the repo settings)
|
||||
github_token: ${{ secrets.github_token }}
|
||||
|
||||
# If the commit is tagged with a version (e.g. "v1.0.0"),
|
||||
# release the app after building
|
||||
release: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
|
||||
use_vue_cli: true
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: YesPlayMusic-mac
|
||||
path: dist_electron/*-universal.dmg
|
||||
if-no-files-found: ignore
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: YesPlayMusic-win
|
||||
path: dist_electron/*Setup*.exe
|
||||
if-no-files-found: ignore
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: YesPlayMusic-linux
|
||||
path: dist_electron/*.AppImage
|
||||
if-no-files-found: ignore
|
@ -0,0 +1,34 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
.vercel
|
||||
|
||||
#Electron-builder output
|
||||
/dist_electron
|
||||
NeteaseCloudMusicApi-master
|
||||
NeteaseCloudMusicApi-master.zip
|
||||
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
vercel.json
|
@ -0,0 +1,3 @@
|
||||
build
|
||||
coverage
|
||||
dist
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": true,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf",
|
||||
"bracketSpacing": true,
|
||||
"htmlWhitespaceSensitivity": "strict"
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
FROM node:16.13.1-alpine as build
|
||||
ENV VUE_APP_NETEASE_API_URL=/api
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache python3 make g++ git
|
||||
COPY package.json yarn.lock ./
|
||||
RUN yarn install
|
||||
COPY . .
|
||||
RUN yarn build
|
||||
|
||||
FROM nginx:1.20.2-alpine as app
|
||||
|
||||
COPY --from=build /app/package.json /usr/local/lib/
|
||||
|
||||
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.14/main libuv \
|
||||
&& apk add --no-cache --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.14/main nodejs npm \
|
||||
&& npm i -g $(awk -F \" '{if($2=="NeteaseCloudMusicApi") print $2"@"$4}' /usr/local/lib/package.json) \
|
||||
&& rm -f /usr/local/lib/package.json
|
||||
|
||||
COPY --from=build /app/docker/nginx.conf.example /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
|
||||
CMD nginx ; exec npx NeteaseCloudMusicApi
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 qier222
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@vue/cli-plugin-babel/preset',
|
||||
{
|
||||
useBuiltIns: 'usage',
|
||||
shippedProposals: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
After Width: | Height: | Size: 523 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 750 B |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 965 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 105 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 353 KiB |
After Width: | Height: | Size: 276 KiB |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,12 @@
|
||||
services:
|
||||
YesPlayMusic:
|
||||
build:
|
||||
context: .
|
||||
image: yesplaymusic
|
||||
container_name: YesPlayMusic
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
ports:
|
||||
- 80:80
|
||||
restart: always
|
@ -0,0 +1,28 @@
|
||||
server {
|
||||
gzip on;
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location @rewrites {
|
||||
rewrite ^(.*)$ /index.html last;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_buffers 16 32k;
|
||||
proxy_buffer_size 128k;
|
||||
proxy_busy_buffers_size 128k;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Host $remote_addr;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://localhost:3000/;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 253 KiB |
After Width: | Height: | Size: 228 KiB |
After Width: | Height: | Size: 354 KiB |
After Width: | Height: | Size: 312 KiB |
After Width: | Height: | Size: 389 KiB |
After Width: | Height: | Size: 335 KiB |
After Width: | Height: | Size: 324 KiB |
After Width: | Height: | Size: 175 KiB |
After Width: | Height: | Size: 339 KiB |
After Width: | Height: | Size: 276 KiB |
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# 初始化 .replit 和 replit.nix
|
||||
if [[ $1 == i ]];then
|
||||
echo -e 'run = ["bash", "main.sh"]\n\nentrypoint = "main.sh"' >.replit
|
||||
echo -e "{ pkgs }: {\n\t\tdeps = [\n\t\t\tpkgs.nodejs-16_x\n\t\t\tpkgs.yarn\n\t\t\tpkgs.bashInteractive\n\t\t];\n}" > replit.nix
|
||||
exit
|
||||
fi
|
||||
|
||||
# 安装
|
||||
if [[ ! -d api ]];then
|
||||
mkdir api
|
||||
git clone https://github.com/Binaryify/NeteaseCloudMusicApi ./api && \
|
||||
cd api && npm install && cd ..
|
||||
fi
|
||||
|
||||
if [[ ! -d music ]];then
|
||||
mkdir music
|
||||
git clone https://github.com/qier222/YesPlayMusic ./music && \
|
||||
cd music && cp .env.example .env && npm install --force && npm run build && cd ..
|
||||
fi
|
||||
|
||||
# 启动
|
||||
PID=`ps -ef | grep npm | awk '{print $2}' | sed '$d'`
|
||||
|
||||
if [[ ! -z ${PID} ]];then echo $PID | xargs kill;fi
|
||||
nohup bash -c 'cd api && PORT=35216 node app.js' > api.log 2>&1
|
||||
nohup bash -c 'npx serve music/dist/' > music.log 2>&1
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
// 支持 @ 的别名解析
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"target": "ES6",
|
||||
"module": "commonjs",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
{
|
||||
"name": "yesplaymusic",
|
||||
"version": "0.4.7",
|
||||
"private": true,
|
||||
"description": "A third party music player for Netease Music",
|
||||
"author": "qier222<qier222@outlook.com>",
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"electron:build": "vue-cli-service electron:build -p never",
|
||||
"electron:build-all": "vue-cli-service electron:build -p never -mwl",
|
||||
"electron:build-mac": "vue-cli-service electron:build -p never -m",
|
||||
"electron:build-win": "vue-cli-service electron:build -p never -w",
|
||||
"electron:build-linux": "vue-cli-service electron:build -p never -l",
|
||||
"electron:serve": "vue-cli-service electron:serve",
|
||||
"electron:buildicon": "electron-icon-builder --input=./build/icons/icon.png --output=build --flatten",
|
||||
"electron:publish": "vue-cli-service electron:build -mwl -p always",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"postuninstall": "electron-builder install-app-deps",
|
||||
"prettier": "npx prettier --write ./src",
|
||||
"netease_api:run": "npx NeteaseCloudMusicApi"
|
||||
},
|
||||
"main": "background.js",
|
||||
"dependencies": {
|
||||
"@unblockneteasemusic/rust-napi": "^0.4.0",
|
||||
"NeteaseCloudMusicApi": "^4.8.7",
|
||||
"axios": "^0.26.1",
|
||||
"change-case": "^4.1.2",
|
||||
"cli-color": "^2.0.0",
|
||||
"color": "^4.2.3",
|
||||
"core-js": "^3.6.5",
|
||||
"crypto-js": "^4.0.0",
|
||||
"dayjs": "^1.8.36",
|
||||
"dexie": "^3.0.3",
|
||||
"discord-rich-presence": "^0.0.8",
|
||||
"electron": "^13.6.7",
|
||||
"electron-builder": "^23.0.0",
|
||||
"electron-context-menu": "^3.1.2",
|
||||
"electron-debug": "^3.1.0",
|
||||
"electron-devtools-installer": "^3.2",
|
||||
"electron-icon-builder": "^2.0.1",
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"electron-log": "^4.3.0",
|
||||
"electron-store": "^8.0.1",
|
||||
"electron-updater": "^5.0.1",
|
||||
"express": "^4.17.1",
|
||||
"express-fileupload": "^1.2.0",
|
||||
"express-http-proxy": "^1.6.2",
|
||||
"extract-zip": "^2.0.1",
|
||||
"howler": "^2.2.3",
|
||||
"js-cookie": "^2.2.1",
|
||||
"jsbi": "^4.1.0",
|
||||
"lodash": "^4.17.20",
|
||||
"md5": "^2.3.0",
|
||||
"mpris-service": "^2.1.2",
|
||||
"music-metadata": "^7.5.3",
|
||||
"node-vibrant": "^3.2.1-alpha.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"pac-proxy-agent": "^4.1.0",
|
||||
"plyr": "^3.6.2",
|
||||
"prettier": "2.5.1",
|
||||
"qrcode": "^1.4.4",
|
||||
"register-service-worker": "^1.7.1",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"tunnel": "^0.0.6",
|
||||
"vscode-codicons": "^0.0.17",
|
||||
"vue": "^2.6.11",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-gtag": "1",
|
||||
"vue-i18n": "^8.22.0",
|
||||
"vue-router": "^3.4.3",
|
||||
"vue-slider-component": "^3.2.5",
|
||||
"vuex": "^3.4.0",
|
||||
"x11": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^17.0.0",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-pwa": "~4.5.0",
|
||||
"@vue/cli-plugin-vuex": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.9.0",
|
||||
"husky": "^4.3.0",
|
||||
"sass": "^1.26.11",
|
||||
"sass-loader": "^10.0.2",
|
||||
"vue-cli-plugin-electron-builder": "~2.1.1",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
},
|
||||
"resolutions": {
|
||||
"icon-gen": "3.0.0",
|
||||
"degenerator": "2.2.0",
|
||||
"electron-builder": "^23.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"plugin:vue/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"globals": {
|
||||
"ipcRenderer": "off"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
],
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "npm run prettier"
|
||||
}
|
||||
},
|
||||
"__npminstall_done": false
|
||||
}
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 381 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 523 B |
After Width: | Height: | Size: 913 B |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 149 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 353 KiB |
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 308 B |
After Width: | Height: | Size: 311 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 953 B |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 344 B |
After Width: | Height: | Size: 218 B |
After Width: | Height: | Size: 215 B |
After Width: | Height: | Size: 932 B |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 816 B |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 750 B |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 801 B |
After Width: | Height: | Size: 779 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 871 B |
After Width: | Height: | Size: 855 B |
After Width: | Height: | Size: 656 B |
After Width: | Height: | Size: 610 B |
After Width: | Height: | Size: 499 B |
After Width: | Height: | Size: 746 B |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="referrer" content="no-referrer" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
||||
<title>
|
||||
<%= htmlWebpackPlugin.options.title %>
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
|
||||
properly without JavaScript enabled. Please enable it to
|
||||
continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:baidu
|
@ -0,0 +1,7 @@
|
||||
commit_template: 'style: with ${restyler.name}'
|
||||
restylers:
|
||||
- prettier
|
||||
- prettier-json
|
||||
- prettier-markdown
|
||||
- prettier-yaml
|
||||
- whitespace
|
@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<div
|
||||
id="app"
|
||||
class="no-scrollbar"
|
||||
:class="{ 'user-select-none': userSelectNone }"
|
||||
>
|
||||
<Scrollbar v-show="!showLyrics" ref="scrollbar" />
|
||||
<transition name="slide-up">
|
||||
<Player v-if="enablePlayer" v-show="showPlayer" ref="player" />
|
||||
</transition>
|
||||
<Navbar v-show="showNavbar" ref="navbar" />
|
||||
<main
|
||||
ref="main"
|
||||
:style="{ overflow: enableScrolling ? 'auto' : 'hidden' }"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<keep-alive>
|
||||
<router-view v-if="$route.meta.keepAlive"></router-view>
|
||||
</keep-alive>
|
||||
<router-view v-if="!$route.meta.keepAlive"></router-view>
|
||||
</main>
|
||||
|
||||
<Toast />
|
||||
<ModalAddTrackToPlaylist v-if="isAccountLoggedIn" />
|
||||
<ModalNewPlaylist v-if="isAccountLoggedIn" />
|
||||
<transition v-if="enablePlayer" name="slide-up">
|
||||
<Lyrics v-show="showLyrics" />
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModalAddTrackToPlaylist from './components/ModalAddTrackToPlaylist.vue';
|
||||
import ModalNewPlaylist from './components/ModalNewPlaylist.vue';
|
||||
import Scrollbar from './components/Scrollbar.vue';
|
||||
import Navbar from './components/Navbar.vue';
|
||||
import Player from './components/Player.vue';
|
||||
import Toast from './components/Toast.vue';
|
||||
import { ipcRenderer } from './electron/ipcRenderer';
|
||||
import { isAccountLoggedIn, isLooseLoggedIn } from '@/utils/auth';
|
||||
import Lyrics from './views/lyrics.vue';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
Navbar,
|
||||
Player,
|
||||
Toast,
|
||||
ModalAddTrackToPlaylist,
|
||||
ModalNewPlaylist,
|
||||
Lyrics,
|
||||
Scrollbar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isElectron: process.env.IS_ELECTRON, // true || undefined
|
||||
userSelectNone: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['showLyrics', 'settings', 'player', 'enableScrolling']),
|
||||
isAccountLoggedIn() {
|
||||
return isAccountLoggedIn();
|
||||
},
|
||||
showPlayer() {
|
||||
return (
|
||||
[
|
||||
'mv',
|
||||
'loginUsername',
|
||||
'login',
|
||||
'loginAccount',
|
||||
'lastfmCallback',
|
||||
].includes(this.$route.name) === false
|
||||
);
|
||||
},
|
||||
enablePlayer() {
|
||||
return this.player.enabled && this.$route.name !== 'lastfmCallback';
|
||||
},
|
||||
showNavbar() {
|
||||
return this.$route.name !== 'lastfmCallback';
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.isElectron) ipcRenderer(this);
|
||||
window.addEventListener('keydown', this.handleKeydown);
|
||||
this.fetchData();
|
||||
},
|
||||
methods: {
|
||||
handleKeydown(e) {
|
||||
if (e.code === 'Space') {
|
||||
if (e.target.tagName === 'INPUT') return false;
|
||||
if (this.$route.name === 'mv') return false;
|
||||
e.preventDefault();
|
||||
this.player.playOrPause();
|
||||
}
|
||||
},
|
||||
fetchData() {
|
||||
if (!isLooseLoggedIn()) return;
|
||||
this.$store.dispatch('fetchLikedSongs');
|
||||
this.$store.dispatch('fetchLikedSongsWithDetails');
|
||||
this.$store.dispatch('fetchLikedPlaylist');
|
||||
if (isAccountLoggedIn()) {
|
||||
this.$store.dispatch('fetchLikedAlbums');
|
||||
this.$store.dispatch('fetchLikedArtists');
|
||||
this.$store.dispatch('fetchLikedMVs');
|
||||
this.$store.dispatch('fetchCloudDisk');
|
||||
}
|
||||
},
|
||||
handleScroll() {
|
||||
this.$refs.scrollbar.handleScroll();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#app {
|
||||
position: relative;
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
main {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
padding: 64px 10vw 96px 10vw;
|
||||
box-sizing: border-box;
|
||||
scrollbar-width: none; // firefox
|
||||
}
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.no-scrollbar {
|
||||
overflow: scroll;
|
||||
}
|
||||
@media (max-width: 576px) {
|
||||
main {
|
||||
padding: 64px 5vw 96px 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
main::-webkit-scrollbar {
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
.slide-up-enter-active,
|
||||
.slide-up-leave-active {
|
||||
transition: transform 0.4s;
|
||||
}
|
||||
.slide-up-enter,
|
||||
.slide-up-leave-to {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
</style>
|
@ -0,0 +1,107 @@
|
||||
import request from '@/utils/request';
|
||||
import { mapTrackPlayableStatus } from '@/utils/common';
|
||||
|
||||
/**
|
||||
* 获取歌手单曲
|
||||
* 说明 : 调用此接口 , 传入歌手 id, 可获得歌手部分信息和热门歌曲
|
||||
* @param {number} id - 歌手 id, 可由搜索接口获得
|
||||
*/
|
||||
export function getArtist(id) {
|
||||
return request({
|
||||
url: '/artists',
|
||||
method: 'get',
|
||||
params: {
|
||||
id,
|
||||
timestamp: new Date().getTime(),
|
||||
},
|
||||
}).then(data => {
|
||||
data.hotSongs = mapTrackPlayableStatus(data.hotSongs);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取歌手专辑
|
||||
* 说明 : 调用此接口 , 传入歌手 id, 可获得歌手专辑内容
|
||||
* - id: 歌手 id
|
||||
* - limit: 取出数量 , 默认为 50
|
||||
* - offset: 偏移数量 , 用于分页 , 如 :( 页数 -1)*50, 其中 50 为 limit 的值 , 默认为 0
|
||||
* @param {Object} params
|
||||
* @param {number} params.id
|
||||
* @param {number=} params.limit
|
||||
* @param {number=} params.offset
|
||||
*/
|
||||
export function getArtistAlbum(params) {
|
||||
return request({
|
||||
url: '/artist/album',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 歌手榜
|
||||
* 说明 : 调用此接口 , 可获取排行榜中的歌手榜
|
||||
* - type : 地区
|
||||
* 1: 华语
|
||||
* 2: 欧美
|
||||
* 3: 韩国
|
||||
* 4: 日本
|
||||
* @param {number=} type
|
||||
*/
|
||||
export function toplistOfArtists(type = null) {
|
||||
let params = {};
|
||||
if (type) {
|
||||
params.type = type;
|
||||
}
|
||||
return request({
|
||||
url: '/toplist/artist',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 获取歌手 mv
|
||||
* 说明 : 调用此接口 , 传入歌手 id, 可获得歌手 mv 信息 , 具体 mv 播放地址可调 用/mv传入此接口获得的 mvid 来拿到 , 如 : /artist/mv?id=6452,/mv?mvid=5461064
|
||||
* @param {number} params.id 歌手 id, 可由搜索接口获得
|
||||
* @param {number} params.offset
|
||||
* @param {number} params.limit
|
||||
*/
|
||||
export function artistMv(params) {
|
||||
return request({
|
||||
url: '/artist/mv',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 收藏歌手
|
||||
* 说明 : 调用此接口 , 传入歌手 id, 可收藏歌手
|
||||
* - id: 歌手 id
|
||||
* - t: 操作,1 为收藏,其他为取消收藏
|
||||
* @param {Object} params
|
||||
* @param {number} params.id
|
||||
* @param {number} params.t
|
||||
*/
|
||||
export function followAArtist(params) {
|
||||
return request({
|
||||
url: '/artist/sub',
|
||||
method: 'post',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 相似歌手
|
||||
* 说明 : 调用此接口 , 传入歌手 id, 可获得相似歌手
|
||||
* - id: 歌手 id
|
||||
* @param {number} id
|
||||
*/
|
||||
export function similarArtists(id) {
|
||||
return request({
|
||||
url: '/simi/artist',
|
||||
method: 'post',
|
||||
params: { id },
|
||||
});
|
||||
}
|