mirror of https://github.com/msgbyte/tailchat
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
1.8 KiB
TypeScript
80 lines
1.8 KiB
TypeScript
import type React from 'react';
|
|
import create from 'zustand';
|
|
import { immer } from 'zustand/middleware/immer';
|
|
|
|
interface ElementDisplayRect {
|
|
left: number;
|
|
top: number;
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
interface KeepAliveState {
|
|
cachedComponents: Record<
|
|
string,
|
|
{
|
|
visible: boolean;
|
|
element: React.ReactElement;
|
|
rect: ElementDisplayRect;
|
|
}
|
|
>;
|
|
mount: (cacheId: string, element: React.ReactElement) => void;
|
|
show: (cacheId: string) => void;
|
|
hide: (cacheId: string) => void;
|
|
updateRect: (cacheId: string, rect: ElementDisplayRect) => void;
|
|
}
|
|
|
|
export const useKeepAliveStore = create<KeepAliveState>()(
|
|
immer((set) => ({
|
|
cachedComponents: {},
|
|
mount: (cacheId, element) => {
|
|
set((state) => {
|
|
const cachedComponents = state.cachedComponents;
|
|
if (cachedComponents[cacheId]) {
|
|
// 已经挂载过
|
|
state.cachedComponents[cacheId].visible = true;
|
|
return;
|
|
}
|
|
|
|
cachedComponents[cacheId] = {
|
|
visible: true,
|
|
element,
|
|
rect: {
|
|
left: 0,
|
|
top: 0,
|
|
width: 0,
|
|
height: 0,
|
|
},
|
|
};
|
|
});
|
|
},
|
|
show: (cacheId) => {
|
|
set((state) => {
|
|
if (!state.cachedComponents[cacheId]) {
|
|
return;
|
|
}
|
|
|
|
state.cachedComponents[cacheId].visible = true;
|
|
});
|
|
},
|
|
hide: (cacheId) => {
|
|
set((state) => {
|
|
if (!state.cachedComponents[cacheId]) {
|
|
return;
|
|
}
|
|
|
|
state.cachedComponents[cacheId].visible = false;
|
|
});
|
|
},
|
|
updateRect: (cacheId: string, rect: ElementDisplayRect) => {
|
|
set((state) => {
|
|
if (!state.cachedComponents[cacheId]) {
|
|
return;
|
|
}
|
|
|
|
state.cachedComponents[cacheId].rect = rect;
|
|
});
|
|
},
|
|
}))
|
|
);
|