Update On Fri Nov 1 19:37:39 CET 2024

This commit is contained in:
github-action[bot]
2024-11-01 19:37:40 +01:00
parent 999152e7e6
commit 453bb0e96c
96 changed files with 2350 additions and 1157 deletions

4
yesplaymusic/.envrc Normal file
View File

@@ -0,0 +1,4 @@
source_url "https://raw.githubusercontent.com/cachix/devenv/82c0147677e510b247d8b9165c54f73d32dfd899/direnvrc" "sha256-7u4iDd1nZpxL4tCzmPG0dQgC5V+/44Ba+tHkPob1v2k="
export NIXPKGS_ALLOW_INSECURE=1
use devenv

View File

@@ -32,3 +32,12 @@ NeteaseCloudMusicApi-master.zip
# Local Netlify folder
.netlify
vercel.json
# Devenv
.devenv*
devenv.local.nix
# direnv
.direnv
# pre-commit
.pre-commit-config.yaml

View File

@@ -125,6 +125,16 @@ yarn run build
7.`/dist` 目录下的文件上传到你的 Web 服务器
## ⚙️ 宝塔面板 docker应用商店 部署
1. 安装宝塔面板,前往[宝塔面板官网](https://www.bt.cn/new/download.html) ,选择正式版的脚本下载安装。
2. 安装后登录宝塔面板,在左侧导航栏中点击 Docker首次进入会提示安装Docker服务点击立即安装按提示完成安装
3. 安装完成后在应用商店中找到YesPlayMusic点击安装配置域名、端口等基本信息即可完成安装。
4. 安装后在浏览器输入上一步骤设置的域名即可访问。
## ⚙️ Docker 部署
1. 构建 Docker Image

132
yesplaymusic/devenv.lock Normal file
View File

@@ -0,0 +1,132 @@
{
"nodes": {
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1730412360,
"owner": "cachix",
"repo": "devenv",
"rev": "45847cb1f14a6d8cfa86ea943703c54a8798ae7e",
"type": "github"
},
"original": {
"dir": "src/modules",
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1730272153,
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2d2a9ddbe3f2c00747398f3dc9b05f7f2ebb0f53",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1730327045,
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "080166c15633801df010977d9d7474b4a6c549d7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nodejs16": {
"locked": {
"lastModified": 1700230496,
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a71323f68d4377d12c04a5410e214495ec598d4c",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a71323f68d4377d12c04a5410e214495ec598d4c",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1730302582,
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
"nixpkgs": "nixpkgs",
"nodejs16": "nodejs16",
"pre-commit-hooks": "pre-commit-hooks"
}
}
},
"root": "root",
"version": 7
}

53
yesplaymusic/devenv.nix Normal file
View File

@@ -0,0 +1,53 @@
{ pkgs, lib, config, inputs, ... }:
let
nodejs16 = import inputs.nodejs16 { system = pkgs.stdenv.system; };
in
{
# https://devenv.sh/basics/
env.GREET = "devenv";
# https://devenv.sh/packages/
packages = [ pkgs.git ] ++ lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk; [
frameworks.AppKit
]);
# https://devenv.sh/languages/
languages.javascript.enable = true;
languages.javascript.package = nodejs16.pkgs.nodejs_16;
languages.javascript.corepack.enable = true;
# languages.rust.enable = true;
# https://devenv.sh/processes/
# processes.cargo-watch.exec = "cargo-watch";
# https://devenv.sh/services/
# services.postgres.enable = true;
# https://devenv.sh/scripts/
scripts.hello.exec = ''
echo hello from $GREET
'';
enterShell = ''
hello
git --version
'';
# https://devenv.sh/tasks/
# tasks = {
# "myproj:setup".exec = "mytool build";
# "devenv:enterShell".after = [ "myproj:setup" ];
# };
# https://devenv.sh/tests/
enterTest = ''
echo "Running tests"
git --version | grep --color=auto "${pkgs.git.version}"
'';
# https://devenv.sh/pre-commit-hooks/
# pre-commit.hooks.shellcheck.enable = true;
# See full reference at https://devenv.sh/reference/options/
}

19
yesplaymusic/devenv.yaml Normal file
View File

@@ -0,0 +1,19 @@
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
inputs:
nixpkgs:
url: github:nixos/nixpkgs/nixpkgs-unstable
nodejs16:
url: github:nixos/nixpkgs/a71323f68d4377d12c04a5410e214495ec598d4c
# https://github.com/cachix/devenv/issues/792#issuecomment-2043166453
impure: true
# If you're using non-OSS software, you can set allowUnfree to true.
# allowUnfree: true
# If you're willing to use a package that's vulnerable
# permittedInsecurePackages:
# - "openssl-1.1.1w"
# If you have more than one devenv you can merge them
#imports:
# - ./backend

View File

@@ -27,7 +27,7 @@
},
"dependencies": {
"@unblockneteasemusic/rust-napi": "^0.4.0",
"NeteaseCloudMusicApi": "^4.8.7",
"NeteaseCloudMusicApi": "^4.23.3",
"axios": "^0.26.1",
"change-case": "^4.1.2",
"cli-color": "^2.0.0",

View File

@@ -42,7 +42,9 @@
:exclude="$parent.albumObject.artist.name"
prefix="-"
/></span>
<span v-if="isAlbum && (track.mark & 1048576) === 1048576" class="explicit-symbol"
<span
v-if="isAlbum && (track.mark & 1048576) === 1048576"
class="explicit-symbol"
><ExplicitSymbol
/></span>
</div>

View File

@@ -240,7 +240,7 @@ export function initIpcMain(win, store, trayEventEmitter) {
details: track.name + ' - ' + track.ar.map(ar => ar.name).join(','),
state: track.al.name,
endTimestamp: Date.now() + track.dt,
largeImageKey: 'logo',
largeImageKey: track.al.picUrl,
largeImageText: 'Listening ' + track.name,
smallImageKey: 'play',
smallImageText: 'Playing',
@@ -252,7 +252,7 @@ export function initIpcMain(win, store, trayEventEmitter) {
client.updatePresence({
details: track.name + ' - ' + track.ar.map(ar => ar.name).join(','),
state: track.al.name,
largeImageKey: 'logo',
largeImageKey: track.al.picUrl,
largeImageText: 'YesPlayMusic',
smallImageKey: 'pause',
smallImageText: 'Pause',

View File

@@ -244,6 +244,8 @@ export default {
minePlaylists: 'My Playlists',
likedPlaylists: 'Liked Playlists',
cardiacMode: 'Cardiac Mode',
copyLyric: 'Copy Lyric',
copyLyricWithTranslation: 'Copy Lyric With Translation',
},
toast: {
savedToPlaylist: 'Saved to playlist',

View File

@@ -230,6 +230,8 @@ export default {
minePlaylists: 'My Playlists',
likedPlaylists: 'Liked Playlists',
cardiacMode: 'Cardiac Mode',
copyLyric: 'Copy Lyric',
copyLyricWithTranslation: 'Copy Lyric With Translation',
},
toast: {
savedToMyLikedSongs: 'Beğendiğim Müziklere Kaydet',

View File

@@ -243,6 +243,8 @@ export default {
minePlaylists: '创建的歌单',
likedPlaylists: '收藏的歌单',
cardiacMode: '心动模式',
copyLyric: '复制歌词',
copyLyricWithTranslation: '复制歌词(含翻译)',
},
toast: {
savedToPlaylist: '已添加到歌单',

View File

@@ -240,6 +240,8 @@ export default {
minePlaylists: '我建立的歌單',
likedPlaylists: '收藏的歌單',
cardiacMode: '心動模式',
copyLyric: '複製歌詞',
copyLyricWithTranslation: '複製歌詞(含翻譯)',
},
toast: {
savedToPlaylist: '已新增至歌單',

View File

@@ -36,6 +36,8 @@ let localStorage = {
server: '',
port: null,
},
enableRealIP: false,
realIP: null,
shortcuts: shortcuts,
},
data: {

View File

@@ -84,3 +84,30 @@ function trimContent(content) {
let t = content.trim();
return t.length < 1 ? content : t;
}
/**
* @param {string} lyric
*/
export async function copyLyric(lyric) {
const textToCopy = lyric;
if (navigator.clipboard && navigator.clipboard.writeText) {
try {
await navigator.clipboard.writeText(textToCopy);
} catch (err) {
alert('复制失败,请手动复制!');
}
} else {
const tempInput = document.createElement('textarea');
tempInput.value = textToCopy;
tempInput.style.position = 'absolute';
tempInput.style.left = '-9999px';
document.body.appendChild(tempInput);
tempInput.select();
try {
document.execCommand('copy');
} catch (err) {
alert('复制失败,请手动复制!');
}
document.body.removeChild(tempInput);
}
}

View File

@@ -38,8 +38,15 @@ service.interceptors.request.use(function (config) {
config.params.realIP = '211.161.244.70';
}
// Force real_ip
const enableRealIP = JSON.parse(
localStorage.getItem('settings')
).enableRealIP;
const realIP = JSON.parse(localStorage.getItem('settings')).realIP;
if (process.env.VUE_APP_REAL_IP) {
config.params.realIP = process.env.VUE_APP_REAL_IP;
} else if (enableRealIP) {
config.params.realIP = realIP;
}
const proxy = JSON.parse(localStorage.getItem('settings')).proxyConfig;

View File

@@ -28,7 +28,9 @@
<span v-else>Compilation by Various Artists</span>
</div>
<div class="date-and-count">
<span v-if="(album.mark & 1048576) === 1048576" class="explicit-symbol"
<span
v-if="(album.mark & 1048576) === 1048576"
class="explicit-symbol"
><ExplicitSymbol
/></span>
<span :title="album.publishTime | formatDate">{{

View File

@@ -248,7 +248,11 @@
@dblclick="clickLyricLine(line.time, true)"
>
<div class="content">
<span v-if="line.contents[0]">{{ line.contents[0] }}</span>
<span
v-if="line.contents[0]"
@click.right="openLyricMenu($event, line, 0)"
>{{ line.contents[0] }}</span
>
<br />
<span
v-if="
@@ -256,10 +260,26 @@
$store.state.settings.showLyricsTranslation
"
class="translation"
@click.right="openLyricMenu($event, line, 1)"
>{{ line.contents[1] }}</span
>
</div>
</div>
<ContextMenu v-if="!noLyric" ref="lyricMenu">
<div class="item" @click="copyLyric(false)">{{
$t('contextMenu.copyLyric')
}}</div>
<div
v-if="
rightClickLyric &&
rightClickLyric.contents[1] &&
$store.state.settings.showLyricsTranslation
"
class="item"
@click="copyLyric(true)"
>{{ $t('contextMenu.copyLyricWithTranslation') }}</div
>
</ContextMenu>
</div>
</transition>
</div>
@@ -284,9 +304,10 @@
import { mapState, mapMutations, mapActions } from 'vuex';
import VueSlider from 'vue-slider-component';
import ContextMenu from '@/components/ContextMenu.vue';
import { formatTrackTime } from '@/utils/common';
import { getLyric } from '@/api/track';
import { lyricParser } from '@/utils/lyrics';
import { lyricParser, copyLyric } from '@/utils/lyrics';
import ButtonIcon from '@/components/ButtonIcon.vue';
import * as Vibrant from 'node-vibrant/dist/vibrant.worker.min.js';
import Color from 'color';
@@ -299,6 +320,7 @@ export default {
components: {
VueSlider,
ButtonIcon,
ContextMenu,
},
data() {
return {
@@ -312,6 +334,7 @@ export default {
background: '',
date: this.formatTime(new Date()),
isFullscreen: !!document.fullscreenElement,
rightClickLyric: null,
};
},
computed: {
@@ -587,6 +610,21 @@ export default {
this.player.play();
}
},
openLyricMenu(e, lyric, idx) {
this.rightClickLyric = { ...lyric, idx };
this.$refs.lyricMenu.openMenu(e);
e.preventDefault();
},
copyLyric(withTranslation) {
if (this.rightClickLyric) {
const idx = this.rightClickLyric.idx;
if (!withTranslation) {
copyLyric(this.rightClickLyric.contents[idx]);
} else {
copyLyric(this.rightClickLyric.contents.join(' '));
}
}
},
setLyricsInterval() {
this.lyricsInterval = setInterval(() => {
const progress = this.player.seek(null, false) ?? 0;
@@ -926,6 +964,7 @@ export default {
transform-origin: center left;
transform: scale(0.95);
transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
user-select: none;
span {
opacity: 0.28;

View File

@@ -641,6 +641,33 @@
<button @click="sendProxyConfig">更新代理</button>
</div>
</div>
<div v-if="isElectron">
<h3>Real IP</h3>
<div class="item">
<div class="left">
<div class="title"> Real IP </div>
</div>
<div class="right">
<div class="toggle">
<input
id="enable-real-ip"
v-model="enableRealIP"
type="checkbox"
name="enable-real-ip"
/>
<label for="enable-real-ip"></label>
</div>
</div>
</div>
<div id="real-ip" :class="{ disabled: !enableRealIP }">
<input
v-model="realIP"
class="text-input"
placeholder="IP地址"
:disabled="!enableRealIP"
/>
</div>
</div>
<div v-if="isElectron">
<h3>快捷键</h3>
@@ -1124,6 +1151,28 @@ export default {
});
},
},
enableRealIP: {
get() {
return this.settings.enableRealIP || false;
},
set(value) {
this.$store.commit('updateSettings', {
key: 'enableRealIP',
value: value,
});
},
},
realIP: {
get() {
return this.settings.realIP || '';
},
set(value) {
this.$store.commit('updateSettings', {
key: 'realIP',
value: value,
});
},
},
proxyPort: {
get() {
return this.settings.proxyConfig?.port || '';
@@ -1566,11 +1615,13 @@ input[type='number'] {
-moz-appearance: textfield;
}
#proxy-form {
#proxy-form,
#real-ip {
display: flex;
align-items: center;
}
#proxy-form.disabled {
#proxy-form.disabled,
#real-ip.disabled {
opacity: 0.47;
button:hover {
transform: unset;

File diff suppressed because it is too large Load Diff