develop → main: 合并开发分支 (#51)

* fix(ci): fix release workflow artifact upload issue

- Split artifact upload into 3 separate steps (Chrome, Firefox, Source)
- Update download steps to match new artifact names
- Add if-no-files-found: error for better error handling
- Fix Node.js 20 compatibility issue with upload-artifact@v4 glob pattern

* docs: 更新 AGENTS.md,添加测试工具和翻译文件结构说明

* docs: 更新 AGENTS.md,完善 CI 步骤和存储键名格式说明

* fix: remove unnecessary animations from StorageCleaner page

- Remove entrance animations (animate-in, fade-in, zoom-in) from all components
- Remove scale effect (active:scale-[0.99]) from clean button
- Remove transition effects (transition-all, transition-colors) from OptionItem, StorageOptionsGrid, AutoRefreshToggle
- Remove bouncing animation from error icon
- Remove pulsing animation from warning banner
- Keep animate-spin on button loading spinner as functional indicator

* fix: remove unnecessary animations from RightClickRestorer page

* fix: remove all unnecessary animations from all pages

- Remove dead code animations (animate-in, fade-in, slide-in, zoom-in, shake) from tailwindcss-animate plugin (not installed)
- Remove decorative transition effects (transition-all, transition-colors) from all page components
- Remove scale effects (active:scale-95) from buttons
- Remove bounce animations (animate-bounce) from icons
- Keep functional animate-spin on loading spinners as they provide essential loading feedback

Affected pages: Dashboard, Timestamp, Jwt, JsonTools, Base64Converter, HtmlToMarkdown, MarkdownToHtml, QrCode, TextStatistics

---------

Co-authored-by: Ubuntu <ubuntu@localhost.localdomain>
This commit is contained in:
LingandRX
2026-05-26 15:08:53 +08:00
committed by GitHub
parent 92d524d832
commit 42d3fedbaa
32 changed files with 108 additions and 113 deletions
@@ -57,7 +57,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
};
return (
<div className="w-full flex flex-col space-y-4 animate-in fade-in duration-300">
<div className="w-full flex flex-col space-y-4">
<div className="flex h-11 items-center px-1.5 bg-secondary/40 rounded-xl border border-border/60 w-fit">
<SwitchButtonGroup
value={direction}
@@ -86,7 +86,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
}}
onClick={() => fileInputRef.current?.click()}
className={cn(
'flex flex-col items-center justify-center min-h-[190px] border-2 border-dashed rounded-2xl p-8 cursor-pointer transition-all duration-300',
'flex flex-col items-center justify-center min-h-[190px] border-2 border-dashed rounded-2xl p-8 cursor-pointer',
isDragging
? 'border-primary bg-primary/10'
: info
@@ -107,7 +107,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
{isLoading ? (
<div className="w-9 h-9 border-3 border-primary/20 border-t-primary rounded-full animate-spin" />
) : info ? (
<div className="flex flex-col items-center gap-1.5 text-center w-full animate-in fade-in duration-200">
<div className="flex flex-col items-center gap-1.5 text-center w-full">
{mode === 'image' && result && (
<div className="relative p-1 border border-border bg-background rounded-lg shadow-sm mb-1 max-w-[180px] overflow-hidden">
<img
@@ -117,9 +117,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
/>
</div>
)}
<Upload
className={cn('w-8 h-8 text-primary', mode === 'file' && 'animate-bounce')}
/>
<Upload className={cn('w-8 h-8 text-primary')} />
<span className="text-sm font-bold text-foreground/90 max-w-[280px] truncate">
{info.name}
</span>
+3 -3
View File
@@ -45,7 +45,7 @@ export default function FileMode() {
};
return (
<div className="w-full flex flex-col space-y-4 animate-in fade-in duration-300">
<div className="w-full flex flex-col space-y-4">
<div className="flex h-11 items-center px-1.5 bg-secondary/40 rounded-xl border border-border/60 w-fit">
<SwitchButtonGroup
value={direction}
@@ -79,7 +79,7 @@ export default function FileMode() {
}}
onClick={() => fileInputRef.current?.click()}
className={cn(
'flex flex-col items-center justify-center min-h-[190px] border-2 border-dashed rounded-2xl p-8 cursor-pointer transition-all duration-300',
'flex flex-col items-center justify-center min-h-[190px] border-2 border-dashed rounded-2xl p-8 cursor-pointer',
isDragging
? 'border-primary bg-primary/10'
: info
@@ -100,7 +100,7 @@ export default function FileMode() {
<div className="w-9 h-9 border-3 border-primary/20 border-t-primary rounded-full animate-spin" />
) : info ? (
<div className="flex flex-col items-center gap-1.5 text-center">
<Upload className="w-8 h-8 text-primary animate-bounce" />
<Upload className="w-8 h-8 text-primary" />
<span className="text-sm font-bold text-foreground/90 max-w-[280px] truncate">
{info.name}
</span>
+4 -4
View File
@@ -52,7 +52,7 @@ export default function ImageMode() {
};
return (
<div className="w-full flex flex-col space-y-4 animate-in fade-in duration-300">
<div className="w-full flex flex-col space-y-4">
<div className="flex h-11 items-center px-1.5 bg-secondary/40 rounded-xl border border-border/60 w-fit">
<SwitchButtonGroup
value={direction}
@@ -82,7 +82,7 @@ export default function ImageMode() {
}}
onClick={() => fileInputRef.current?.click()}
className={cn(
'flex flex-col items-center justify-center min-h-[190px] border-2 border-dashed rounded-2xl p-8 cursor-pointer transition-all duration-300',
'flex flex-col items-center justify-center min-h-[190px] border-2 border-dashed rounded-2xl p-8 cursor-pointer',
isDragging
? 'border-primary bg-primary/10'
: info
@@ -103,7 +103,7 @@ export default function ImageMode() {
{isLoading ? (
<div className="w-9 h-9 border-3 border-primary/20 border-t-primary rounded-full animate-spin" />
) : info ? (
<div className="flex flex-col items-center gap-1.5 text-center animate-in fade-in duration-200 w-full">
<div className="flex flex-col items-center gap-1.5 text-center w-full">
{result && (
<div className="relative p-1 border border-border bg-background rounded-lg shadow-sm mb-1 max-w-[180px] overflow-hidden">
<img
@@ -233,7 +233,7 @@ export default function ImageMode() {
onClear={resetAll}
/>
{decoded && (
<div className="animate-in slide-in-from-bottom-2 duration-300">
<div>
<DecodeResultPaper
title={t('decodedImageOutput')}
mimeType={decoded.mimeType}
+4 -4
View File
@@ -93,7 +93,7 @@ export default function TextMode({ onSwitchToImageMode }: TextModeProps = {}) {
};
return (
<div className="w-full flex flex-col space-y-4 animate-in fade-in duration-300">
<div className="w-full flex flex-col space-y-4">
{/* 受控方向切流中枢 */}
<div className="flex h-11 items-center px-1.5 bg-secondary/40 rounded-xl border border-border/60 w-fit">
<SwitchButtonGroup
@@ -125,7 +125,7 @@ export default function TextMode({ onSwitchToImageMode }: TextModeProps = {}) {
- 完美向全站 shadcn 暗黑生态看齐,采用标准的 bg-primary/10 混合变体。
*/}
{showImageHint && (
<div className="flex items-center justify-between p-3.5 rounded-xl bg-primary/10 border border-primary/20 animate-in slide-in-from-top-1 duration-200">
<div className="flex items-center justify-between p-3.5 rounded-xl bg-primary/10 border border-primary/20">
<span className="text-xs font-semibold text-primary tracking-tight">
{t('imageDataUriHint')}
</span>
@@ -134,7 +134,7 @@ export default function TextMode({ onSwitchToImageMode }: TextModeProps = {}) {
variant="ghost"
size="sm"
onClick={onSwitchToImageMode}
className="h-7 rounded-md text-xs font-bold text-primary hover:text-primary hover:bg-primary/20 dark:hover:bg-primary/10 transition-colors px-2.5"
className="h-7 rounded-md text-xs font-bold text-primary hover:text-primary hover:bg-primary/20 dark:hover:bg-primary/10 px-2.5"
>
{t('switchToImageMode')}
</Button>
@@ -143,7 +143,7 @@ export default function TextMode({ onSwitchToImageMode }: TextModeProps = {}) {
{/* 5. 编码/解码核心数据承载流卡片 */}
{output && (
<div className="p-4 rounded-2xl bg-card border border-border shadow-sm flex flex-col space-y-3 animate-in slide-in-from-bottom-2 duration-300">
<div className="p-4 rounded-2xl bg-card border border-border shadow-sm flex flex-col space-y-3">
<div className="flex justify-between items-center select-none">
<span className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground/90">
{outputLabel}
+1 -1
View File
@@ -20,7 +20,7 @@ export default function Index() {
);
return (
<div className="p-4 w-full flex flex-col space-y-4 min-h-[520px] select-none animate-in fade-in duration-300">
<div className="p-4 w-full flex flex-col space-y-4 min-h-[520px] select-none">
<SwitchButtonGroup
value={pageMode}
options={[