Skip to content

Commit

Permalink
增加了打轴模式布局,增加大量动画改进
Browse files Browse the repository at this point in the history
  • Loading branch information
Steve-xmh committed Oct 27, 2024
1 parent e2f9a67 commit 742f2b6
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 158 deletions.
1 change: 1 addition & 0 deletions libs/kuromoji.js
Submodule kuromoji.js added at 36e902
7 changes: 4 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* https://github.com/Steve-xmh/amll-ttml-tool/blob/main/LICENSE
*/

import { Box, Flex, Theme } from "@radix-ui/themes";
import { Box, Button, DropdownMenu, Flex, Theme } from "@radix-ui/themes";
import "@radix-ui/themes/styles.css";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { AnimatePresence } from "framer-motion";
Expand All @@ -21,6 +21,7 @@ import LyricLinesView from "./components/LyricLinesView";
import RibbonBar from "./components/RibbonBar";
import { TitleBar } from "./components/TitleBar";
import { ToolMode, isDarkThemeAtom, toolModeAtom } from "./states";
import { Trans } from "react-i18next";

function App() {
const isDarkTheme = useAtomValue(isDarkThemeAtom);
Expand Down Expand Up @@ -48,8 +49,8 @@ function App() {
<TitleBar />
<RibbonBar />
<AnimatePresence>
{toolMode === ToolMode.Edit && <LyricLinesView key="edit" />}
{toolMode !== ToolMode.Edit && <Box flexGrow="1" key="not-edit" />}
{toolMode !== ToolMode.Preview && <LyricLinesView key="edit" />}
{toolMode === ToolMode.Preview && <Box flexGrow="1" key="not-edit" />}
</AnimatePresence>
<Box flexShrink="1">
<AudioControls />
Expand Down
67 changes: 62 additions & 5 deletions src/components/LyricLinesView/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,76 @@
*/

.lyricWord {
display: inline-block;
padding: 0.25em 0.5em;
white-space: pre;
&.edit {
display: inline-block;
padding: 0.25em 0.5em;
border-radius: var(--radius-4);

background-color: var(--color-panel);
box-shadow: var(--base-card-surface-box-shadow);
}

&.sync {
padding: var(--space-2);
display: flex;
flex-direction: column;
align-items: center;

border-right: solid 1px var(--gray-a5);
}
}

.displayWord {
font-size: 1.5em;
}

.startTime, .endTime {
padding: 0.05em 0.5em;
border-radius: var(--radius-4);
color: var(--white-a6)
}

background-color: var(--color-panel);
box-shadow: var(--base-card-surface-box-shadow);
.startTime {
background-color: var(--green-a4);
}

.endTime {
background-color: var(--red-a4);
}

.lyricWord,
.lyricWord * {
white-space: nowrap;
word-wrap: none;
word-break: keep-all;
text-wrap: nowrap;
max-lines: 1;
}

.lyricLine {
border-radius: var(--radius-4);
box-shadow: var(--base-card-surface-box-shadow);
user-select: none;
display: flex;
}

.lyricWordsContainer {
min-width: 0;
padding: var(--space-3);
flex-grow: 1;
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: var(--space-2);

&.sync {
flex-wrap: nowrap;
overflow: auto;
padding: 0 var(--space-3);
gap: 0;
border-left: solid 1px var(--gray-a5);
border-right: solid 1px var(--gray-a5);
}
}

.blank {
Expand Down
115 changes: 67 additions & 48 deletions src/components/LyricLinesView/lyric-line-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,21 @@ import { Flex, IconButton, Text } from "@radix-ui/themes";
import Add16Filled from "@ricons/fluent/Add16Filled";
import { Icon } from "@ricons/utils";
import classNames from "classnames";
import { useAtom, useSetAtom } from "jotai";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import type { FC } from "react";
import { uid } from "uid";
import {
currentLyricLinesAtom,
selectedLinesAtom,
selectedWordsAtom,
ToolMode,
toolModeAtom,
} from "../../states";
import type { LyricLine } from "../../utils/ttml-types";
import styles from "./index.module.css";
import { LyricWordView } from "./lyric-word-view";
import { motion } from "framer-motion";
import { msToTimestamp } from "../../utils/timestamp";

export const LyricLineView: FC<{ line: LyricLine; lineIndex: number }> = ({
line,
Expand All @@ -32,12 +36,12 @@ export const LyricLineView: FC<{ line: LyricLine; lineIndex: number }> = ({
const [selectedLines, setSelectedLines] = useAtom(selectedLinesAtom);
const setSelectedWords = useSetAtom(selectedWordsAtom);
const editLyricLines = useSetAtom(currentLyricLinesAtom);
const toolMode = useAtomValue(toolModeAtom);

return (
<Flex
mx="2"
my="1"
p="3"
direction="row"
className={classNames(
styles.lyricLine,
Expand All @@ -63,54 +67,69 @@ export const LyricLineView: FC<{ line: LyricLine; lineIndex: number }> = ({
setSelectedWords(new Set());
}
}}
asChild
>
<Text
style={{
minWidth: "2em",
}}
align="right"
color="gray"
>
{lineIndex}
</Text>
<Flex gap="1" flexGrow="1" wrap="wrap">
{line.words.map((word, wi) => (
<LyricWordView
key={`lyric-line-word-${wi}`}
word={word}
wordIndex={wi}
line={line}
lineIndex={lineIndex}
/>
))}
</Flex>
<IconButton
variant="ghost"
onClick={(evt) => {
evt.preventDefault();
evt.stopPropagation();
const newWordId = uid();
editLyricLines((state) => {
state.lyricLines[lineIndex].words.push({
id: newWordId,
word: "",
startTime: 0,
endTime: 0,
obscene: false,
wordType: "normal",
emptyBeat: 0,
<motion.div layout="size" layoutId={`lyric-line-view-index-${lineIndex}`}>
<Text
style={{
minWidth: "2em",
}}
align="right"
color="gray"
>
{lineIndex}
</Text>
<div
className={classNames(
styles.lyricWordsContainer,
toolMode === ToolMode.Edit && styles.edit,
toolMode === ToolMode.Sync && styles.sync,
)}
>
{line.words.map((word, wi) => (
<LyricWordView
key={`lyric-line-word-${wi}`}
word={word}
wordIndex={wi}
line={line}
lineIndex={lineIndex}
/>
))}
</div>
{toolMode === ToolMode.Edit && <IconButton
variant="ghost"
onClick={(evt) => {
evt.preventDefault();
evt.stopPropagation();
const newWordId = uid();
editLyricLines((state) => {
state.lyricLines[lineIndex].words.push({
id: newWordId,
word: "",
startTime: 0,
endTime: 0,
obscene: false,
wordType: "normal",
emptyBeat: 0,
});
});
});
setSelectedWords(new Set([newWordId]));
}}
>
<Icon>
<Add16Filled
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
</Icon>
</IconButton>
setSelectedWords(new Set([newWordId]));
}}
>
<Icon>
<Add16Filled
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
</Icon>
</IconButton>}
{
toolMode === ToolMode.Sync && <Flex pr="3" gap="1" direction="column" align="stretch">
<div className={styles.startTime}>{msToTimestamp(line.startTime)}</div>
<div className={styles.endTime}>{msToTimestamp(line.endTime)}</div>
</Flex>
}
</motion.div>
</Flex>
);
};
Loading

0 comments on commit 742f2b6

Please sign in to comment.