From b0e66fcf454b1ceedf9e6d50dc908b4ed2aacd12 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Thu, 16 Jul 2026 22:05:52 -0700 Subject: [PATCH] allow undo changes and deleted rows --- src/i18n/locales/en.json | 1 + .../tag-editor/components/song-edit-modal.tsx | 8 +- .../components/tag-field-row.module.css | 5 + .../tag-editor/components/tag-field-row.tsx | 143 +++++++++++------- .../tag-editor/hooks/use-metadata-editor.ts | 36 ++++- src/shared/components/icon/icon.tsx | 2 + 6 files changed, 134 insertions(+), 61 deletions(-) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index baeba4142..9e4e51665 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -161,6 +161,7 @@ "trackGain": "Track gain", "trackPeak": "Track peak", "translation": "Translation", + "undo": "Undo", "unknown": "Unknown", "version": "Version", "year": "Year", diff --git a/src/renderer/features/tag-editor/components/song-edit-modal.tsx b/src/renderer/features/tag-editor/components/song-edit-modal.tsx index 62ef0254c..0ca427163 100644 --- a/src/renderer/features/tag-editor/components/song-edit-modal.tsx +++ b/src/renderer/features/tag-editor/components/song-edit-modal.tsx @@ -96,12 +96,16 @@ export const SongEditModal = ({ songs }: { songs: Song[] }) => { {editor.sortedFieldEntries.map(([key, value]) => ( { } onChange={(v) => editor.handleFieldChange(key, v)} onRemove={() => editor.handleRemoveField(key)} + onReset={() => editor.handleResetField(key)} + onRevert={() => editor.handleRevertField(key)} tagKey={key} value={value} /> diff --git a/src/renderer/features/tag-editor/components/tag-field-row.module.css b/src/renderer/features/tag-editor/components/tag-field-row.module.css index 75dd41843..6628e18c1 100644 --- a/src/renderer/features/tag-editor/components/tag-field-row.module.css +++ b/src/renderer/features/tag-editor/components/tag-field-row.module.css @@ -10,3 +10,8 @@ .dirty-label { box-shadow: inset 2px 0 0 var(--mantine-primary-color-filled); } + +.removed-row { + opacity: 0.55; + transition: opacity 0.15s ease-in-out; +} diff --git a/src/renderer/features/tag-editor/components/tag-field-row.tsx b/src/renderer/features/tag-editor/components/tag-field-row.tsx index 1c63d5bf7..7c04e7873 100644 --- a/src/renderer/features/tag-editor/components/tag-field-row.tsx +++ b/src/renderer/features/tag-editor/components/tag-field-row.tsx @@ -2,13 +2,12 @@ import type { TagValue } from '/@/shared/types/tag-editor'; import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { RiCloseLine } from 'react-icons/ri'; import type { KnownTag } from '../utils/known-tags'; import styles from './tag-field-row.module.css'; -import { Button } from '/@/shared/components/button/button'; +import { ActionIcon } from '/@/shared/components/action-icon/action-icon'; import { Checkbox } from '/@/shared/components/checkbox/checkbox'; import { NumberInput } from '/@/shared/components/number-input/number-input'; import { Table } from '/@/shared/components/table/table'; @@ -17,6 +16,7 @@ import { TextInput } from '/@/shared/components/text-input/text-input'; import { Textarea } from '/@/shared/components/textarea/textarea'; interface FavoriteTagsInputProps { + disabled: boolean; favoriteValues: string[]; mixedPlaceholder?: string; onAddFavorite: (value: string) => void; @@ -29,11 +29,14 @@ interface TagFieldRowProps { isDirty?: boolean; isMixed: boolean; isMultiValue: boolean; + isRemoved: boolean; meta: KnownTag; mixedPlaceholder?: string; onAddFavorite: (value: string) => void; onChange: (value: TagValue) => void; onRemove: () => void; + onReset: () => void; + onRevert: () => void; tagKey: string; value: TagValue; } @@ -41,6 +44,7 @@ interface TagFieldRowProps { const ADD_FAVORITE_PREFIX = '__feishin_add_favorite__:'; const FavoriteTagsInput = ({ + disabled, favoriteValues, mixedPlaceholder, onAddFavorite, @@ -73,6 +77,7 @@ const FavoriteTagsInput = ({ { const normalizedValues = values.map((item) => item.startsWith(ADD_FAVORITE_PREFIX) @@ -107,64 +112,94 @@ export const TagFieldRow = ({ isDirty, isMixed, isMultiValue, + isRemoved, meta, mixedPlaceholder, onAddFavorite, onChange, onRemove, + onReset, + onRevert, tagKey, value, -}: TagFieldRowProps) => ( - - {meta.label} - - {isMultiValue && tagKey !== 'lyrics' ? ( - - ) : meta.type === 'textarea' ? ( -