refactor: refactor pendant history

This commit is contained in:
qishaoxuan
2022-07-27 23:00:20 +08:00
parent 4c35337dbb
commit 56a9e2ead5
4 changed files with 65 additions and 48 deletions

View File

@@ -1,10 +1,12 @@
import React, { ReactNode, useRef } from 'react'; import React, { ReactNode, useRef, useEffect, useState } from 'react';
import { getLatestPropertyValue } from '../utils'; import { getPendantHistory } from '../utils';
import { import {
getRecastItemValue, getRecastItemValue,
RecastMetaProperty, RecastMetaProperty,
useRecastBlock, useRecastBlock,
useRecastBlockMeta, useRecastBlockMeta,
RecastBlockValue,
RecastPropertyId,
} from '../../recast-block'; } from '../../recast-block';
import { AsyncBlock } from '../../editor'; import { AsyncBlock } from '../../editor';
import { Popover, PopperHandler, styled } from '@toeverything/components/ui'; import { Popover, PopperHandler, styled } from '@toeverything/components/ui';
@@ -14,27 +16,60 @@ import { UpdatePendantPanel } from '../pendant-operation-panel';
export const PendantHistoryPanel = ({ export const PendantHistoryPanel = ({
block, block,
endElement, endElement,
onClose,
}: { }: {
block: AsyncBlock; block: AsyncBlock;
endElement?: ReactNode; endElement?: ReactNode;
onClose?: () => void;
}) => { }) => {
const popoverHandlerRef = useRef<{ [key: string]: PopperHandler }>({}); const groupBlock = useRecastBlock();
const { getProperties } = useRecastBlockMeta();
const { getProperty } = useRecastBlockMeta(); const { getProperty } = useRecastBlockMeta();
const { getAllValue } = getRecastItemValue(block); const { getAllValue } = getRecastItemValue(block);
const recastBlock = useRecastBlock(); const recastBlock = useRecastBlock();
const latestPropertyValues = getLatestPropertyValue({ const [history, setHistory] = useState<RecastBlockValue[]>([]);
recastBlockId: recastBlock.id, const popoverHandlerRef = useRef<{ [key: string]: PopperHandler }>({});
blockId: block.id,
});
const blockValues = getAllValue();
const history = latestPropertyValues useEffect(() => {
.filter(latest => !blockValues.find(v => v && v.id === latest.value.id)) const init = async () => {
.map(v => v.value); const currentBlockValues = getAllValue();
const allProperties = getProperties();
const missProperties = allProperties.filter(
property => !currentBlockValues.find(v => v.id === property.id)
);
const pendantHistory = getPendantHistory({
recastBlockId: recastBlock.id,
});
const historyMap = missProperties.reduce<{
[key: RecastPropertyId]: string;
}>((history, property) => {
if (pendantHistory[property.id]) {
history[property.id] = pendantHistory[property.id];
}
return history;
}, {});
const blockHistory = await Promise.all(
Object.entries(historyMap).map(
async ([propertyId, blockId]) => {
const latestValueBlock = (
await groupBlock.children()
).find((block: AsyncBlock) => block.id === blockId);
return getRecastItemValue(latestValueBlock).getValue(
propertyId as RecastPropertyId
);
}
)
);
setHistory(blockHistory);
};
init();
}, [getAllValue, getProperties, groupBlock, recastBlock]);
return ( return (
<StyledPendantHistoryPanel> <StyledPendantHistoryPanel>
@@ -57,11 +92,13 @@ export const PendantHistoryPanel = ({
popoverHandlerRef.current[ popoverHandlerRef.current[
item.id item.id
].setVisible(false); ].setVisible(false);
onClose?.();
}} }}
onCancel={() => { onCancel={() => {
popoverHandlerRef.current[ popoverHandlerRef.current[
item.id item.id
].setVisible(false); ].setVisible(false);
onClose?.();
}} }}
titleEditable={false} titleEditable={false}
/> />
@@ -85,6 +122,7 @@ export const PendantHistoryPanel = ({
</StyledPendantHistoryPanel> </StyledPendantHistoryPanel>
); );
}; };
const StyledPendantHistoryPanel = styled('div')` const StyledPendantHistoryPanel = styled('div')`
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;

View File

@@ -36,6 +36,9 @@ export const PendantPopover: FC<
trigger="click" trigger="click"
/> />
} }
onClose={() => {
popoverHandlerRef.current?.setVisible(false);
}}
/> />
} }
offset={[0, 0]} offset={[0, 0]}

View File

@@ -1,4 +1,4 @@
import { removePropertyValueRecord, setLatestPropertyValue } from './utils'; import { removePropertyValueRecord, setPendantHistory } from './utils';
import { AsyncBlock } from '../editor'; import { AsyncBlock } from '../editor';
import { import {
getRecastItemValue, getRecastItemValue,
@@ -19,10 +19,10 @@ export const usePendant = (block: AsyncBlock) => {
value: newValue, value: newValue,
}; };
await setValue(nv); await setValue(nv);
setLatestPropertyValue({ setPendantHistory({
recastBlockId: recastBlock.id, recastBlockId: recastBlock.id,
blockId: block.id, blockId: block.id,
value: nv, propertyId: property.id,
}); });
}; };

View File

@@ -9,15 +9,12 @@ import { PendantConfig, PendantTypes } from './types';
type Props = { type Props = {
recastBlockId: string; recastBlockId: string;
blockId: string; blockId: string;
value: RecastBlockValue; propertyId: RecastPropertyId;
}; };
type StorageMap = { type StorageMap = {
[recastBlockId: string]: { [recastBlockId: string]: {
[propertyId: RecastPropertyId]: { [propertyId: RecastPropertyId]: string;
blockId: string;
value: RecastBlockValue;
};
}; };
}; };
@@ -30,10 +27,10 @@ const ensureLocalStorage = () => {
} }
}; };
export const setLatestPropertyValue = ({ export const setPendantHistory = ({
recastBlockId, recastBlockId,
blockId, blockId,
value, propertyId,
}: Props) => { }: Props) => {
ensureLocalStorage(); ensureLocalStorage();
const data: StorageMap = JSON.parse( const data: StorageMap = JSON.parse(
@@ -44,43 +41,22 @@ export const setLatestPropertyValue = ({
data[recastBlockId] = {}; data[recastBlockId] = {};
} }
const propertyValueRecord = data[recastBlockId]; const propertyValueRecord = data[recastBlockId];
const propertyId = value.id; propertyValueRecord[propertyId] = blockId;
propertyValueRecord[propertyId] = {
blockId: blockId,
value,
};
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(data)); localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(data));
}; };
export const getLatestPropertyValue = ({ export const getPendantHistory = ({
recastBlockId, recastBlockId,
}: { }: {
recastBlockId: string; recastBlockId: string;
blockId: string; }) => {
}): Array<{
blockId: string;
value: RecastBlockValue;
propertyId: RecastPropertyId;
}> => {
ensureLocalStorage(); ensureLocalStorage();
const data: StorageMap = JSON.parse( const data: StorageMap = JSON.parse(
localStorage.getItem(LOCAL_STORAGE_NAME) as string localStorage.getItem(LOCAL_STORAGE_NAME) as string
); );
if (!data[recastBlockId]) { return data[recastBlockId] ?? {};
return [];
}
const returnData = [];
for (const propertyId in data[recastBlockId]) {
returnData.push({
propertyId: propertyId as RecastPropertyId,
...data[recastBlockId][propertyId as RecastPropertyId],
});
}
return returnData;
}; };
export const removePropertyValueRecord = ({ export const removePropertyValueRecord = ({