Skip to content

Commit

Permalink
refactor: pass props by passing props id
Browse files Browse the repository at this point in the history
  • Loading branch information
swkatmask committed Jul 10, 2024
1 parent 766bbe0 commit b15ed23
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 23 deletions.
4 changes: 2 additions & 2 deletions globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ namespace JSX {
'mask-calendar-widget': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
'mask-page-inspector': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
'mask-decrypted-post': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement> & { props: string },
React.HTMLAttributes<HTMLElement> & { 'props-id': string },
HTMLElement
>;
'mask-post-inspector': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement> & { props: string },
React.HTMLAttributes<HTMLElement> & { 'props-id': string },
HTMLElement
>;
}
Expand Down
37 changes: 25 additions & 12 deletions src/components/Posts/PostBody.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use client';

import { Select, t, Trans } from '@lingui/macro';
import { compact } from 'lodash-es';
import { EMPTY_LIST } from '@masknet/shared-base';
import { compact, noop, uniqueId } from 'lodash-es';
import { useRouter } from 'next/navigation.js';
import { forwardRef, useMemo, useState } from 'react';
import { forwardRef, useLayoutEffect, useMemo, useState } from 'react';
import { useInView } from 'react-cool-inview';
import { useAsync } from 'react-use';

Expand All @@ -19,14 +20,14 @@ import { Quote } from '@/components/Posts/Quote.js';
import { IS_APPLE, IS_SAFARI } from '@/constants/bowser.js';
import { STATUS } from '@/constants/enum.js';
import { env } from '@/constants/env.js';
import { EMPTY_LIST } from '@/constants/index.js';
import { classNames } from '@/helpers/classNames.js';
import { formatUrl } from '@/helpers/formatUrl.js';
import { getEncryptedPayloadFromImageAttachment, getEncryptedPayloadFromText } from '@/helpers/getEncryptedPayload.js';
import { getPostUrl } from '@/helpers/getPostUrl.js';
import { isValidUrl } from '@/helpers/isValidUrl.js';
import { trimify } from '@/helpers/trimify.js';
import { useIsProfileMuted } from '@/hooks/useIsProfileMuted.js';
import { propsMap } from '@/mask/custom-elements/props-pool.js';
import type { Post } from '@/providers/types/SocialMedia.js';

interface PostBodyProps {
Expand Down Expand Up @@ -65,6 +66,7 @@ export const PostBody = forwardRef<HTMLDivElement, PostBodyProps>(function PostB
},
});

const [propsId, setPropsId] = useState(uniqueId);
const { value: payloads } = useAsync(async () => {
// decode the image upon post viewing, to reduce unnecessary load of images
if (!postViewed) return;
Expand All @@ -80,6 +82,24 @@ export const PostBody = forwardRef<HTMLDivElement, PostBodyProps>(function PostB

const muted = useIsProfileMuted(author, isDetail);

useLayoutEffect(() => {
setPropsId(() => uniqueId());
}, [payloads]);

useLayoutEffect(() => {
if (!postViewed) return noop;
propsMap.set(propsId, {
post,
payloads:
payloads?.payloadFromImageAttachment || payloads?.payloadFromText
? compact([payloads.payloadFromImageAttachment, payloads.payloadFromText])
: undefined,
});
return () => {
propsMap.delete(propsId);
};
}, [post, payloads, propsId, postViewed]);

const payloadFromImageAttachment = payloads?.payloadFromImageAttachment;
const payloadImageUrl = payloadFromImageAttachment?.[2];
const attachments = metadata.content?.attachments ?? EMPTY_LIST;
Expand Down Expand Up @@ -203,16 +223,9 @@ export const PostBody = forwardRef<HTMLDivElement, PostBodyProps>(function PostB

{postViewed ? (
payloads?.payloadFromImageAttachment || payloads?.payloadFromText ? (
<mask-decrypted-post
props={encodeURIComponent(
JSON.stringify({
post,
payloads: compact([payloads.payloadFromImageAttachment, payloads.payloadFromText]),
}),
)}
/>
<mask-decrypted-post key={propsId} props-id={propsId} />
) : (
<mask-post-inspector props={encodeURIComponent(JSON.stringify({ post }))} />
<mask-post-inspector key={propsId} props-id={propsId} />
)
) : null}

Expand Down
15 changes: 6 additions & 9 deletions src/mask/custom-elements/WidgetWithProps.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { createRoot } from 'react-dom/client';

import { parseJSON } from '@/helpers/parseJSON.js';
import { propsMap } from '@/mask/custom-elements/props-pool.js';
import { Widget } from '@/mask/custom-elements/Widget.js';

export class WidgetWithProps<T> extends Widget {
get props() {
const raw = this.getAttribute('props');
if (!raw) return;

return parseJSON<T>(decodeURIComponent(raw));
}

override connectedCallback() {
this.root = createRoot(this);
this.root.render(<this.Component {...this.props} />);

const propsId = this.getAttribute('props-id');
const props = propsId ? (propsMap.get(propsId) as T) : undefined;

this.root.render(<this.Component {...props} />);
}
}
1 change: 1 addition & 0 deletions src/mask/custom-elements/props-pool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const propsMap = new Map<string, unknown>();

0 comments on commit b15ed23

Please sign in to comment.