mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d29a692ef | |||
| 3f9eb446f7 | |||
| d8f7b49ab6 | |||
| 35e70a3eff | |||
| ef9c16e940 | |||
| 0b39c35132 | |||
| 9f5b4e5410 |
@@ -24,11 +24,9 @@ jobs:
|
|||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Extract metadata (tags, labels) for Docker
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Setup Docker buildx
|
- name: Setup Docker buildx
|
||||||
@@ -41,6 +39,6 @@ jobs:
|
|||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
platforms: |
|
platforms: |
|
||||||
linux/amd64
|
linux/amd64
|
||||||
linux/arm/v7
|
linux/arm/v7
|
||||||
linux/arm64/v8
|
linux/arm64/v8
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "feishin",
|
"name": "feishin",
|
||||||
"version": "0.15.0",
|
"version": "0.15.1",
|
||||||
"description": "A modern self-hosted music player.",
|
"description": "A modern self-hosted music player.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"subsonic",
|
"subsonic",
|
||||||
@@ -170,9 +170,7 @@
|
|||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"abstract-socket",
|
|
||||||
"electron",
|
"electron",
|
||||||
"electron-winstaller",
|
|
||||||
"esbuild"
|
"esbuild"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const formatArtists = (artists: null | RelatedArtist[] | undefined) =>
|
|||||||
{artist.id ? (
|
{artist.id ? (
|
||||||
<Text
|
<Text
|
||||||
component={Link}
|
component={Link}
|
||||||
fw={500}
|
fw={700}
|
||||||
isLink
|
isLink
|
||||||
overflow="visible"
|
overflow="visible"
|
||||||
size="md"
|
size="md"
|
||||||
@@ -106,7 +106,7 @@ const FormatGenre = (item: Album | AlbumArtist | Playlist | Song) => {
|
|||||||
{index > 0 && <Separator />}
|
{index > 0 && <Separator />}
|
||||||
<Text
|
<Text
|
||||||
component={Link}
|
component={Link}
|
||||||
fw={500}
|
fw={700}
|
||||||
isLink
|
isLink
|
||||||
overflow="visible"
|
overflow="visible"
|
||||||
size="md"
|
size="md"
|
||||||
@@ -260,7 +260,7 @@ const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
|||||||
song.album && (
|
song.album && (
|
||||||
<Text
|
<Text
|
||||||
component={Link}
|
component={Link}
|
||||||
fw={500}
|
fw={700}
|
||||||
isLink
|
isLink
|
||||||
overflow="visible"
|
overflow="visible"
|
||||||
size="md"
|
size="md"
|
||||||
|
|||||||
@@ -6,16 +6,16 @@
|
|||||||
transition:
|
transition:
|
||||||
opacity 0.3s ease-in-out,
|
opacity 0.3s ease-in-out,
|
||||||
transform 0.3s ease-in-out;
|
transform 0.3s ease-in-out;
|
||||||
|
}
|
||||||
&.active {
|
|
||||||
opacity: 1;
|
.lyric-line:global(.active) {
|
||||||
}
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
&.unsynchronized {
|
|
||||||
opacity: 1;
|
.lyric-line:global(.unsynchronized) {
|
||||||
}
|
opacity: 1;
|
||||||
|
}
|
||||||
&.synchronized {
|
|
||||||
cursor: pointer;
|
.lyric-line:global(.synchronized) {
|
||||||
}
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
.active {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ import isElectron from 'is-electron';
|
|||||||
import { useCallback, useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
import styles from './synchronized-lyrics.module.css';
|
import styles from './synchronized-lyrics.module.css';
|
||||||
import './synchronized-lyrics.css';
|
|
||||||
|
|
||||||
import { LyricLine } from '/@/renderer/features/lyrics/lyric-line';
|
import { LyricLine } from '/@/renderer/features/lyrics/lyric-line';
|
||||||
import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble';
|
import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble';
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ export const PlayButton = ({ isPaused, ...props }: PlayButtonProps) => {
|
|||||||
<ActionIcon
|
<ActionIcon
|
||||||
className={styles.main}
|
className={styles.main}
|
||||||
icon={isPaused ? 'mediaPlay' : 'mediaPause'}
|
icon={isPaused ? 'mediaPlay' : 'mediaPause'}
|
||||||
|
iconProps={{
|
||||||
|
size: 'lg',
|
||||||
|
}}
|
||||||
tooltip={
|
tooltip={
|
||||||
isPaused
|
isPaused
|
||||||
? t('player.play', { postProcess: 'sentenceCase' })
|
? t('player.play', { postProcess: 'sentenceCase' })
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import AudioMotionAnalyzer from 'audiomotion-analyzer';
|
import AudioMotionAnalyzer from 'audiomotion-analyzer';
|
||||||
import { createRef, useCallback, useEffect, useState } from 'react';
|
import { createRef, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import styles from './visualizer.module.css';
|
import styles from './visualizer.module.css';
|
||||||
|
|
||||||
@@ -12,8 +12,6 @@ export const Visualizer = () => {
|
|||||||
const accent = useSettingsStore((store) => store.general.accent);
|
const accent = useSettingsStore((store) => store.general.accent);
|
||||||
const [motion, setMotion] = useState<AudioMotionAnalyzer>();
|
const [motion, setMotion] = useState<AudioMotionAnalyzer>();
|
||||||
|
|
||||||
const [, setLength] = useState(500);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { context, gain } = webAudio || {};
|
const { context, gain } = webAudio || {};
|
||||||
if (gain && context && canvasRef.current && !motion) {
|
if (gain && context && canvasRef.current && !motion) {
|
||||||
@@ -35,28 +33,6 @@ export const Visualizer = () => {
|
|||||||
return () => {};
|
return () => {};
|
||||||
}, [accent, canvasRef, motion, webAudio]);
|
}, [accent, canvasRef, motion, webAudio]);
|
||||||
|
|
||||||
const resize = useCallback(() => {
|
|
||||||
const body = document.querySelector('.full-screen-player-queue-container');
|
|
||||||
const header = document.querySelector('.full-screen-player-queue-header');
|
|
||||||
|
|
||||||
if (body && header) {
|
|
||||||
const width = body.clientWidth - 30;
|
|
||||||
const height = body.clientHeight - header.clientHeight - 30;
|
|
||||||
|
|
||||||
setLength(Math.min(width, height));
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
resize();
|
|
||||||
|
|
||||||
window.addEventListener('resize', resize);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('resize', resize);
|
|
||||||
};
|
|
||||||
}, [resize]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.container}
|
className={styles.container}
|
||||||
|
|||||||
Reference in New Issue
Block a user