Files
labelimage/components/label/useBottomToolsStore.ts
2026-04-08 15:14:17 +08:00

142 lines
3.8 KiB
TypeScript

import { create } from "zustand"
interface KeyFrameData {
key_frame: boolean
label1_ts: number
label1_uid: number
review1_ts: number
review1_uid: number
review2_ts: number
review2_uid: number
}
interface BottomToolsState {
activeImage: string
setActiveImage: (val: string) => void
pendingImage: string
frameSwitchStatus: "idle" | "preparing"
frameSwitchToken: number
requestFrameSwitch: (val: string) => number
commitFrameSwitch: (val: string, token: number) => void
clearPendingFrameSwitch: (token?: number) => void
inputNumber: string
setInputNumber: (val: string) => void
activeImageId: number
setActiveImageId: (val: number) => void
onlyKeyFrame: boolean
setOnlyKeyFrame: (val: boolean) => void
keyFrameData: Map<string, KeyFrameData>
setKeyFrameData: (imageId: string, value: KeyFrameData) => void
allItems: string[]
setAllItems: (arr: string[]) => void
selectedItems: string[]
setSelectedItems: (
imageId: string,
ctrlKey: boolean,
shiftKey: boolean
) => void
}
const initialBottomToolsState = {
activeImage: "",
inputNumber: "",
}
export const useBottomToolsStore = create<BottomToolsState>()((set, get) => ({
activeImage: initialBottomToolsState.activeImage,
setActiveImage: (val: string) =>
set((state: BottomToolsState) => ({
...state,
activeImage: val,
pendingImage: "",
frameSwitchStatus: "idle",
})),
pendingImage: "",
frameSwitchStatus: "idle",
frameSwitchToken: 0,
requestFrameSwitch: (val: string): number => {
const nextToken = get().frameSwitchToken + 1
set((state: BottomToolsState) => ({
...state,
pendingImage: val,
frameSwitchStatus:
val && val !== state.activeImage ? "preparing" : "idle",
frameSwitchToken: nextToken,
}))
return nextToken
},
commitFrameSwitch: (val: string, token: number) =>
set((state: BottomToolsState) => {
if (state.frameSwitchToken !== token) return state
return {
...state,
activeImage: val,
pendingImage: "",
frameSwitchStatus: "idle",
}
}),
clearPendingFrameSwitch: (token?: number) =>
set((state: BottomToolsState) => {
if (token != null && state.frameSwitchToken !== token) return state
return {
...state,
pendingImage: "",
frameSwitchStatus: "idle",
}
}),
inputNumber: initialBottomToolsState.inputNumber,
setInputNumber: (val: string) =>
set((state: BottomToolsState) => ({
...state,
inputNumber: val,
})),
activeImageId: 0,
setActiveImageId: (val) =>
set((state: BottomToolsState) => ({
...state,
activeImageId: val,
})),
onlyKeyFrame: false,
setOnlyKeyFrame: (val) =>
set((state) => ({
...state,
onlyKeyFrame: val,
})),
keyFrameData: new Map(),
setKeyFrameData: (imageId, value) => {
const data = get().keyFrameData
data.set(imageId, value)
return set((state) => ({
...state,
keyFrameData: data,
}))
},
allItems: [],
setAllItems: (arr) =>
set((state) => ({
...state,
allItems: arr,
})),
selectedItems: [],
setSelectedItems: (id, ctrlKey, shiftKey) => {
let arr = [...get().selectedItems]
if ((ctrlKey && shiftKey) || (!ctrlKey && !shiftKey)) arr = []
else if (ctrlKey && !shiftKey) {
arr.push(id)
} else if (!ctrlKey && shiftKey) {
const allItems = get().allItems
const prevId = arr.length ? arr[arr.length - 1] : get().activeImage
const prevIndex = allItems.findIndex((v) => v === prevId)
const currentIndex = allItems.findIndex((v) => v === id)
arr =
prevIndex < currentIndex
? allItems.slice(prevIndex, currentIndex + 1)
: allItems.slice(currentIndex, prevIndex + 1)
}
return set((state) => ({
...state,
selectedItems: arr,
}))
},
}))