adjust dark mode and layout

This commit is contained in:
鲁树人
2025-05-18 23:18:01 +09:00
parent 6cb1f9f87f
commit 3ab73d8369
16 changed files with 53 additions and 45 deletions

View File

@@ -11,31 +11,23 @@ interface FileRowProps {
export function FileRow({ id, file }: FileRowProps) {
const dispatch = useAppDispatch();
const isDecrypted = file.state === ProcessState.COMPLETE;
const metadata = file.metadata;
const nameWithoutExt = file.fileName.replace(/\.[a-z\d]{3,6}$/, '');
const decryptedName = nameWithoutExt + '.' + file.ext;
const decryptedName = file.cleanName + '.' + file.ext;
return (
<div className="card bg-base-100 shadow-sm w-full md:w-[30%] " data-testid="file-row">
<div className="card-body items-center text-center px-2">
<h2
className="card-title overflow-hidden text-ellipsis block max-w-full whitespace-nowrap"
data-testid="audio-meta-song-name"
>
{metadata?.name ?? nameWithoutExt}
<h2 className="card-title max-w-full whitespace-nowrap flex gap-0" data-testid="audio-meta-song-name">
<span className="grow overflow-hidden text-ellipsis" title={decryptedName}>
{file.cleanName}
</span>
{isDecrypted && file.ext && <div className="ml-2 badge badge-accent">{file.ext}</div>}
</h2>
<div className="w-full grow">
{file.state === ProcessState.ERROR && <FileError error={file.errorMessage} code={file.errorCode} />}
{isDecrypted && (
<audio
className="max-w-[100%]"
aria-disabled={!file.decrypted}
controls
autoPlay={false}
src={file.decrypted}
/>
<audio className="w-full" aria-disabled={!file.decrypted} controls autoPlay={false} src={file.decrypted} />
)}
</div>

View File

@@ -14,5 +14,5 @@ test('should be able to render a list of 3 items', () => {
});
expect(screen.getAllByTestId('file-row')).toHaveLength(3);
expect(screen.getByText('Für Alice')).toBeInTheDocument();
expect(screen.getByText('ready')).toBeInTheDocument();
});

View File

@@ -3,17 +3,14 @@ import { untouchedFile } from './__fixture__/file-list';
import { FileRow } from '../FileRow';
import { completedFile } from './__fixture__/file-list';
test('should render no metadata when unavailable', () => {
test('should render basic title (ready)', () => {
renderWithProviders(<FileRow id="file://ready" file={untouchedFile} />);
expect(screen.getAllByTestId('file-row')).toHaveLength(1);
expect(screen.getByTestId('audio-meta-song-name')).toHaveTextContent('ready');
expect(screen.queryByTestId('audio-meta-album-name')).toBeFalsy();
expect(screen.queryByTestId('audio-meta-song-artist')).toBeFalsy();
expect(screen.queryByTestId('audio-meta-album-artist')).toBeFalsy();
});
test('should render metadata when file has been processed', () => {
test('should render basic title (done)', () => {
renderWithProviders(<FileRow id="file://done" file={completedFile} />);
expect(screen.getAllByTestId('file-row')).toHaveLength(1);

View File

@@ -1,6 +1,7 @@
import { DecryptedAudioFile, ProcessState } from '../../fileListingSlice';
export const untouchedFile: DecryptedAudioFile = {
cleanName: 'ready',
fileName: 'ready.bin',
raw: 'blob://localhost/file-a',
decrypted: '',
@@ -13,6 +14,7 @@ export const untouchedFile: DecryptedAudioFile = {
export const completedFile: DecryptedAudioFile = {
fileName: 'hello-b.bin',
cleanName: 'hello-b',
raw: 'blob://localhost/file-b',
decrypted: 'blob://localhost/file-b-decrypted',
ext: 'flac',
@@ -30,6 +32,7 @@ export const completedFile: DecryptedAudioFile = {
export const fileWithError: DecryptedAudioFile = {
fileName: 'hello-c.bin',
cleanName: 'hello-c',
raw: 'blob://localhost/file-c',
decrypted: 'blob://localhost/file-c-decrypted',
ext: 'flac',

View File

@@ -5,9 +5,11 @@ import type { RootState } from '~/store';
import { DECRYPTION_WORKER_ACTION_NAME, type DecryptionResult } from '~/decrypt-worker/constants';
import type {
DecryptCommandOptions,
FetchMusicExNamePayload, ParseKugouHeaderPayload, ParseKugouHeaderResponse,
FetchMusicExNamePayload,
ParseKugouHeaderPayload,
ParseKugouHeaderResponse,
ParseKuwoHeaderPayload,
ParseKuwoHeaderResponse
ParseKuwoHeaderResponse,
} from '~/decrypt-worker/types';
import { decryptionQueue, workerClientBus } from '~/decrypt-worker/client';
import { DecryptErrorType } from '~/decrypt-worker/util/DecryptError';
@@ -15,8 +17,9 @@ import {
selectKugouKey,
selectKWMv2Key,
selectQMCv2KeyByFileName,
selectQtfmAndroidKey
selectQtfmAndroidKey,
} from '../settings/settingsSelector';
import { cleanFilename } from '~/util/cleanFilename';
export enum ProcessState {
QUEUED = 'QUEUED',
@@ -40,6 +43,7 @@ export interface AudioMetadata {
export interface DecryptedAudioFile {
fileName: string;
cleanName: string;
raw: string; // blob uri
ext: string;
decrypted: string; // blob uri
@@ -106,6 +110,7 @@ export const fileListingSlice = createSlice({
addNewFile: (state, { payload }: PayloadAction<{ id: string; fileName: string; blobURI: string }>) => {
state.files[payload.id] = {
fileName: payload.fileName,
cleanName: cleanFilename(payload.fileName),
raw: payload.blobURI,
decrypted: '',
ext: '',

View File

@@ -20,7 +20,7 @@ export function ResponsiveNav({
className={`@container/nav grow grid grid-cols-1 grid-rows-[auto_1fr] md:grid-rows-1 md:grid-cols-[10rem_1fr] ${className}`}
>
{/* Sidebar */}
<aside className={`bg-gray-100 md:p-4 md:block ${navigationClassName}`}>{navigation}</aside>
<aside className={`bg-base-300 md:p-4 md:block ${navigationClassName}`}>{navigation}</aside>
{/* Main content */}
<div className={`p-4 grow ${contentClassName}`}>{children}</div>