diff --git a/packages/shared/src/api/channelContentConfig.ts b/packages/shared/src/api/channelContentConfig.ts index 7ff17c60ea..638825cd94 100644 --- a/packages/shared/src/api/channelContentConfig.ts +++ b/packages/shared/src/api/channelContentConfig.ts @@ -212,6 +212,14 @@ export const allContentRenderers = { displayName: 'Scratchpad', enumTag: 'scratchpad', }, + 'tlon.r1.content.notebook': { + displayName: 'Notebook detail', + enumTag: 'notebookDetail', + }, + 'tlon.r1.content.gallery': { + displayName: 'Gallery detail', + enumTag: 'galleryDetail', + }, } as const satisfies Record; export const CollectionRendererId = makeEnum(allCollectionRenderers); diff --git a/packages/shared/src/utils/object.ts b/packages/shared/src/utils/object.ts index d3de0ad673..22f5357427 100644 --- a/packages/shared/src/utils/object.ts +++ b/packages/shared/src/utils/object.ts @@ -32,3 +32,15 @@ export function objectEntries>( ): { [K in keyof T]: [K, T[K]] }[keyof T][] { return objectKeys(obj).map((key) => [key, obj[key]]); } + +/** + * ```ts + * Optional<{ foo: string, bar: number, qux?: boolean }, 'foo'> = { + * foo?: string; + * bar: number; + * qux?: boolean; + * } + * ``` + */ +export type Optional = Omit & + Partial>; diff --git a/packages/ui/src/components/ActionSheet.tsx b/packages/ui/src/components/ActionSheet.tsx index 9dd64e658a..7a8f8409ca 100644 --- a/packages/ui/src/components/ActionSheet.tsx +++ b/packages/ui/src/components/ActionSheet.tsx @@ -24,6 +24,7 @@ import { import { useCopy } from '../hooks/useCopy'; import useIsWindowNarrow from '../hooks/useIsWindowNarrow'; +import { ForwardingProps } from '../utils/react'; import { Icon, IconType } from './Icon'; import { ListItem } from './ListItem'; import { Sheet } from './Sheet'; @@ -180,9 +181,7 @@ const ActionSheetHeader = ActionSheetHeaderFrame.styleable( ({ children, ...props }, ref) => { return ( - - {children} - + {children} ); } @@ -494,24 +493,31 @@ export const SimpleActionSheetHeader = ({ }; export const SimpleActionSheet = ({ - open, - onOpenChange, title, subtitle, icon, actions, accent, -}: { - title?: string; - subtitle?: string; - icon?: ReactElement; - actions: Action[]; - accent?: Accent; - open: boolean; - onOpenChange: (open: boolean) => void; -}) => { + disableScroll, + ...forwardedProps +}: ForwardingProps< + typeof ActionSheetComponent, + { + title?: string; + subtitle?: string; + icon?: ReactElement; + actions: Action[]; + accent?: Accent; + disableScroll?: boolean; + }, + 'children' +>) => { + const Content = disableScroll + ? ActionSheet.Content + : ActionSheet.ScrollableContent; + return ( - + {title || subtitle ? ( ) : null} - + {actions.map((action, index) => ( ))} - - + + ); }; diff --git a/packages/ui/src/components/AddGalleryPost.tsx b/packages/ui/src/components/AddGalleryPost.tsx index d95bc81530..a0a2363acf 100644 --- a/packages/ui/src/components/AddGalleryPost.tsx +++ b/packages/ui/src/components/AddGalleryPost.tsx @@ -50,6 +50,7 @@ export default function AddGalleryPost({ open={showAddGalleryPost} onOpenChange={setShowAddGalleryPost} actions={actions} + disableScroll /> ); }; diff --git a/packages/ui/src/contexts/componentsKits.tsx b/packages/ui/src/contexts/componentsKits.tsx index 66e117d448..6074cf7291 100644 --- a/packages/ui/src/contexts/componentsKits.tsx +++ b/packages/ui/src/contexts/componentsKits.tsx @@ -6,6 +6,7 @@ import { } from '@tloncorp/shared'; import * as db from '@tloncorp/shared/db'; import { Story } from '@tloncorp/shared/urbit'; +import { Optional } from '@tloncorp/shared/utils'; import { ReactElement, createContext, useContext, useMemo } from 'react'; import { Text } from 'react-native'; @@ -16,8 +17,11 @@ import { ColorPost } from '../components/ColorPost'; import { useContactName } from '../components/ContactNameV2'; import { StandaloneDrawingInput } from '../components/DrawingInput'; import { EditableNotePostContent } from '../components/EditableNotePostContent'; -import { GalleryPost } from '../components/GalleryPost'; -import { NotebookPost } from '../components/NotebookPost'; +import { GalleryPost, GalleryPostDetailView } from '../components/GalleryPost'; +import { + NotebookPost, + NotebookPostDetailView, +} from '../components/NotebookPost'; import { YellPost } from '../components/YellPost'; import { ChatInput, @@ -63,23 +67,10 @@ export type RenderItemType = | RenderItemFunction | React.MemoExoticComponent; -export type MinimalRenderItemProps = { - post: db.Post; - showAuthor?: boolean; - showReplies?: boolean; - onPress?: (post: db.Post) => void; - onPressReplies?: (post: db.Post) => void; - onPressImage?: (post: db.Post, imageUri?: string) => void; - onLongPress?: (post: db.Post) => void; - editing?: boolean; - setEditingPost?: (post: db.Post | undefined) => void; - setViewReactionsPost?: (post: db.Post) => void; - editPost?: (post: db.Post, content: Story) => Promise; - onPressRetry?: (post: db.Post) => void; - onPressDelete?: (post: db.Post) => void; - isHighlighted?: boolean; - contentRendererConfiguration?: Record; -}; +export type MinimalRenderItemProps = Optional< + RenderItemProps, + 'onPressRetry' | 'onPressDelete' +>; export type MinimalRenderItemType = React.ComponentType; type DraftInputRendererComponent = React.ComponentType<{ @@ -135,6 +126,8 @@ const BUILTIN_CONTENT_RENDERERS: { [id: string]: RenderItemType } = { }, [PostContentRendererId.yell]: YellPost, [PostContentRendererId.scratchpad]: EditableNotePostContent, + [PostContentRendererId.notebookDetail]: NotebookPostDetailView, + [PostContentRendererId.galleryDetail]: GalleryPostDetailView, }; const BUILTIN_DRAFT_INPUTS: { [id: string]: DraftInputRendererComponent } = { [DraftInputId.chat]: ChatInput,