Item batch: clean up reducers and update store on upload

master
Tom Hacohen 4 years ago
parent 200102d222
commit 6e3bb42f96

@ -22,6 +22,8 @@ import { ContactType, EventType, TaskType, PimType } from "../pim-types";
import { useCredentials } from "../credentials"; import { useCredentials } from "../credentials";
import { CachedCollection } from "../Pim/helpers"; import { CachedCollection } from "../Pim/helpers";
import { getCollectionManager } from "../etebase-helpers"; import { getCollectionManager } from "../etebase-helpers";
import { useAsyncDispatch } from "../store";
import { itemBatch } from "../store/actions";
const CHUNK_SIZE = 40; const CHUNK_SIZE = 40;
@ -33,6 +35,7 @@ interface PropsType {
export default function ImportDialog(props: PropsType) { export default function ImportDialog(props: PropsType) {
const etebase = useCredentials()!; const etebase = useCredentials()!;
const dispatch = useAsyncDispatch();
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = React.useState(false);
const [itemsProcessed, setItemsProccessed] = React.useState<number>(); const [itemsProcessed, setItemsProccessed] = React.useState<number>();
@ -74,7 +77,7 @@ export default function ImportDialog(props: PropsType) {
const chunks = arrayToChunkIterator(eteItems, CHUNK_SIZE); const chunks = arrayToChunkIterator(eteItems, CHUNK_SIZE);
for (const chunk of chunks) { for (const chunk of chunks) {
await itemMgr.batch(chunk); await dispatch(itemBatch(collection, itemMgr, chunk));
} }
setItemsProccessed(items.length); setItemsProccessed(items.length);

@ -11,6 +11,8 @@ import * as Etebase from "etebase";
import { PimType } from "../pim-types"; import { PimType } from "../pim-types";
import { getCollectionManager } from "../etebase-helpers"; import { getCollectionManager } from "../etebase-helpers";
import { asyncDispatch } from "../store";
import { itemBatch } from "../store/actions";
export const defaultColor = "#8BC34A"; export const defaultColor = "#8BC34A";
@ -91,7 +93,7 @@ export async function itemSave(etebase: Etebase.Account, collection: Etebase.Col
eteItem = await itemMgr.create(meta, content); eteItem = await itemMgr.create(meta, content);
} }
await itemMgr.batch([eteItem]); await asyncDispatch(itemBatch(collection, itemMgr, [eteItem]));
} }
export async function itemDelete(etebase: Etebase.Account, collection: Etebase.Collection, items: Map<string, Map<string, Etebase.CollectionItem>>, item: PimType, collectionUid: string) { export async function itemDelete(etebase: Etebase.Account, collection: Etebase.Collection, items: Map<string, Map<string, Etebase.CollectionItem>>, item: PimType, collectionUid: string) {
@ -105,7 +107,8 @@ export async function itemDelete(etebase: Etebase.Account, collection: Etebase.C
meta.mtime = mtime; meta.mtime = mtime;
await eteItem.setMeta(meta); await eteItem.setMeta(meta);
await eteItem.delete(); await eteItem.delete();
await itemMgr.batch([eteItem]);
await asyncDispatch(itemBatch(collection, itemMgr, [eteItem]));
} }
interface PimFabPropsType { interface PimFabPropsType {

@ -88,6 +88,7 @@ export const setCacheItem = createAction(
return { return {
colUid: col.uid, colUid: col.uid,
itemUid: item.uid, itemUid: item.uid,
deleted: item.isDeleted,
}; };
} }
); );
@ -101,6 +102,25 @@ export const unsetCacheItem = createAction(
return { return {
colUid, colUid,
itemUid, itemUid,
deleted: true,
};
}
);
export const itemBatch = createAction(
"ITEM_BATCH",
async (_col: Etebase.Collection, itemMgr: Etebase.CollectionItemManager, items: Etebase.CollectionItem[], deps?: Etebase.CollectionItem[]) => {
await itemMgr.batch(items, deps);
const ret = [];
for (const item of items) {
ret.push(Etebase.toBase64(await itemMgr.cacheSave(item)));
}
return ret;
},
(col: Etebase.Collection, _itemMgr: Etebase.CollectionItemManager, items: Etebase.CollectionItem[], _deps?: Etebase.CollectionItem[]) => {
return {
colUid: col.uid,
items: items,
}; };
} }
); );

@ -25,11 +25,15 @@ if (process.env.NODE_ENV === "development") {
middleware.push(createLogger()); middleware.push(createLogger());
} }
export function asyncDispatch<T, V>(action: ActionMeta<Promise<T>, V>): Promise<ActionMeta<T, V>> {
return store.dispatch(action) as any;
}
export function useAsyncDispatch() { export function useAsyncDispatch() {
const dispatch = useDispatch(); const dispatch = useDispatch();
return function asyncDispatch<T, V>(action: ActionMeta<Promise<T>, V>): Promise<ActionMeta<T, V>> { return function (action: any): any {
return dispatch(action) as any; return dispatch(action) as any;
}; } as typeof asyncDispatch;
} }
export const store = createStore( export const store = createStore(

@ -5,6 +5,8 @@ import { Action, ActionMeta, ActionFunctionAny, combineActions, handleAction, ha
import { List, Map as ImmutableMap } from "immutable"; import { List, Map as ImmutableMap } from "immutable";
import * as Etebase from "etebase";
import * as actions from "./actions"; import * as actions from "./actions";
interface BaseModel { interface BaseModel {
@ -114,15 +116,34 @@ export const collections = handleActions(
export const items = handleActions( export const items = handleActions(
{ {
[actions.setCacheItem.toString()]: (state: CacheItemsData, action: ActionMeta<CacheItem, { colUid: string, itemUid: string }>) => { [combineActions(
actions.setCacheItem,
actions.unsetCacheItem
).toString()]: (state: CacheItemsData, action: ActionMeta<CacheItem, { colUid: string, itemUid: string, deleted: boolean }>) => {
if (action.payload !== undefined) { if (action.payload !== undefined) {
if (action.meta.deleted) {
return state.removeIn([action.meta.colUid, action.meta.itemUid]);
} else {
return state.setIn([action.meta.colUid, action.meta.itemUid], action.payload); return state.setIn([action.meta.colUid, action.meta.itemUid], action.payload);
} }
}
return state; return state;
}, },
[actions.unsetCacheItem.toString()]: (state: CacheItemsData, action: ActionMeta<string, { colUid: string, itemUid: string }>) => { [actions.itemBatch.toString()]: (state: CacheItemsData, action_: any) => {
// Fails without it for some reason
const action = action_ as ActionMeta<CacheItem[], { colUid: string, items: Etebase.CollectionItem[] }>;
if (action.payload !== undefined) { if (action.payload !== undefined) {
return state.removeIn([action.meta.colUid, action.meta.itemUid]); return state.withMutations((state) => {
let i = 0;
for (const item of action.meta.items) {
if (item.isDeleted) {
state.removeIn([action.meta.colUid, item.uid]);
} else {
state.setIn([action.meta.colUid, item.uid], action.payload[i]);
}
i++;
}
});
} }
return state; return state;
}, },

Loading…
Cancel
Save