Restore list atom

This commit is contained in:
Ginger 2025-02-16 12:16:09 -05:00
parent 514c75e0b5
commit ddb6e38e7d
3 changed files with 52 additions and 43 deletions

View file

@ -189,7 +189,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
}
setSelectedFiles({
type: 'PUT',
items: fileItems,
item: fileItems,
});
},
[setSelectedFiles, room]
@ -227,7 +227,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
const uploads = Array.isArray(upload) ? upload : [upload];
setSelectedFiles({
type: 'DELETE',
items: selectedFiles.filter((f) => uploads.find((u) => u === f.file)),
item: selectedFiles.filter((f) => uploads.find((u) => u === f.file)),
});
uploads.forEach((u) => roomUploadAtomFamily.remove(u));
},
@ -436,7 +436,11 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
isEncrypted={!!fileItem.encInfo}
fileItem={fileItem}
setMetadata={(metadata) =>
setSelectedFiles({ type: 'MODIFY', item: fileItem, metadata })
setSelectedFiles({
type: 'REPLACE',
item: fileItem,
replacement: { ...fileItem, metadata },
})
}
onRemove={handleRemoveUpload}
/>

42
src/app/state/list.ts Normal file
View file

@ -0,0 +1,42 @@
import { atom } from 'jotai';
export type ListAction<T> =
| {
type: 'PUT';
item: T | T[];
}
| {
type: 'REPLACE';
item: T;
replacement: T;
}
| {
type: 'DELETE';
item: T | T[];
};
export const createListAtom = <T>() => {
const baseListAtom = atom<T[]>([]);
return atom<T[], [ListAction<T>], undefined>(
(get) => get(baseListAtom),
(get, set, action) => {
const items = get(baseListAtom);
const newItems = Array.isArray(action.item) ? action.item : [action.item];
if (action.type === 'DELETE') {
set(
baseListAtom,
items.filter((item) => !newItems.includes(item))
);
return;
}
if (action.type === 'PUT') {
set(baseListAtom, [...items, ...newItems]);
return;
}
if (action.type === 'REPLACE') {
set(baseListAtom, items.map((item) => item === action.item ? action.replacement : item));
}
}
);
};
export type TListAtom<T> = ReturnType<typeof createListAtom<T>>;

View file

@ -5,6 +5,7 @@ import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
import { IEventRelation } from 'matrix-js-sdk';
import { createUploadAtomFamily } from '../upload';
import { TUploadContent } from '../../utils/matrix';
import { createListAtom } from '../list';
export type TUploadMetadata = {
markedAsSpoiler: boolean;
@ -17,48 +18,10 @@ export type TUploadItem = {
encInfo: EncryptedAttachmentInfo | undefined;
};
export type UploadListAction =
| {
type: 'PUT';
items: TUploadItem[];
}
| {
type: 'DELETE';
items: TUploadItem[];
}
| {
type: 'MODIFY';
item: TUploadItem;
metadata: TUploadMetadata;
};
export const createUploadListAtom = () => {
const baseListAtom = atom<TUploadItem[]>([]);
return atom<TUploadItem[], [UploadListAction], undefined>(
(get) => get(baseListAtom),
(get, set, action) => {
const items = get(baseListAtom);
if (action.type === 'DELETE') {
set(
baseListAtom,
items.filter((item) => !action.items.includes(item))
);
return;
}
if (action.type === 'PUT') {
set(baseListAtom, [...items, ...action.items]);
return;
}
if (action.type === 'MODIFY') {
set(baseListAtom, items.map((item) => item === action.item ? {...item, metadata: action.metadata} : item));
}
}
);
};
export type TUploadListAtom = ReturnType<typeof createUploadListAtom>;
export type TUploadListAtom = ReturnType<typeof createListAtom<TUploadItem>>;
export const roomIdToUploadItemsAtomFamily = atomFamily<string, TUploadListAtom>(
createUploadListAtom
createListAtom
);
export const roomUploadAtomFamily = createUploadAtomFamily();