diff --git a/frontend/apps/desktop/src/app-account.tsx b/frontend/apps/desktop/src/app-account.tsx
index bbdc8b469..533a64c2d 100644
--- a/frontend/apps/desktop/src/app-account.tsx
+++ b/frontend/apps/desktop/src/app-account.tsx
@@ -225,7 +225,7 @@ export function AccountWizardDialog() {
if (isSaveWords) {
saveWords.mutate({key: 'main', value: words})
}
- invalidate([queryKeys.KEYS_LIST])
+ invalidate([queryKeys.LOCAL_ACCOUNT_ID_LIST])
setCreatedAccount(res.accountId)
setStep('complete')
})
@@ -291,7 +291,7 @@ export function AccountWizardDialog() {
disabled={!isExistingWordsSave}
onPress={() => {
addExistingAccount.mutateAsync().then((res) => {
- invalidate([queryKeys.KEYS_LIST])
+ invalidate([queryKeys.LOCAL_ACCOUNT_ID_LIST])
setCreatedAccount(res.accountId)
setStep('complete')
})
diff --git a/frontend/apps/desktop/src/components/app-embeds.tsx b/frontend/apps/desktop/src/components/app-embeds.tsx
index c845128d5..0c9b879c5 100644
--- a/frontend/apps/desktop/src/components/app-embeds.tsx
+++ b/frontend/apps/desktop/src/components/app-embeds.tsx
@@ -1,4 +1,5 @@
-import {useAccount_deprecated, useProfile} from '@/models/accounts'
+import {useAccount_deprecated} from '@/models/accounts'
+import {useEntity} from '@/models/entities'
import {
API_FILE_URL,
BlockContentUnknown,
@@ -40,7 +41,6 @@ import {
import {YStackProps} from 'tamagui'
import {useAccounts} from '../models/accounts'
import {useComment} from '../models/comments'
-import {useDocument} from '../models/documents'
import {getAvatarUrl} from '../utils/account-url'
import {useNavRoute} from '../utils/navigation'
import {getRouteContext, useOpenInContext} from '../utils/route-context'
@@ -251,8 +251,8 @@ const EmbedSideAnnotation = forwardRef<
/>
)
if (unpacked && unpacked.type != 'd') return null
- const doc = useDocument(unpacked?.qid, unpacked?.version || undefined)
- const editors = useAccounts(doc.data?.authors || [])
+ const entity = useEntity(unpacked)
+ const editors = useAccounts(entity.data?.document?.authors || [])
return (
{/* */}
- {doc?.data?.metadata?.name}
+ {getDocumentTitle(entity?.data?.document)}
{/*
{formattedDateMedium(pub.data?.document?.publishTime)}
*/}
{/* */}
- {formattedDateMedium(doc.data?.updateTime)}
+ {formattedDateMedium(entity.data?.document?.updateTime)}
comment on{' '}
- {pubTarget?.data?.publication?.document?.title}
+ {getDocumentTitle(pubTarget?.data?.document)}
{/*
@@ -367,9 +362,7 @@ const CommentSideAnnotation = forwardRef(function CommentSideAnnotation(
*/}
{/* */}
- {formattedDateMedium(
- pubTarget.data?.publication?.document?.updateTime,
- )}
+ {formattedDateMedium(pubTarget.data?.document?.updateTime)}
- documentId && (
-
- )
- }
+ renderOpenButton={() => (
+
+ )}
/>
)
}
export function EmbedDocumentCard(props: EntityComponentProps) {
const docId = props.type == 'd' ? createHmId('d', props.eid) : undefined
- const doc = useDocument(
- docId,
- props.latest ? undefined : props.version || undefined,
- {
- enabled: !!docId,
- },
- )
+ const doc = useEntity(props)
let textContent = useMemo(() => {
- if (doc.data?.content) {
+ if (doc.data?.document?.content) {
let content = ''
- doc.data?.content.forEach((bn) => {
+ doc.data?.document?.content.forEach((bn) => {
content += bn.block?.text + ' '
})
return content
@@ -503,11 +474,11 @@ export function EmbedDocumentCard(props: EntityComponentProps) {
viewType={props.block.attributes?.view == 'card' ? 'card' : 'content'}
>
)
@@ -517,13 +488,14 @@ export function EmbedAccount(
props: EntityComponentProps,
parentBlockId: string | null,
) {
- console.log(`== ~ props EmbedAccount:`, props)
- const accountId = props.type == 'a' ? props.eid : undefined
- const profile = useProfile(accountId)
+ const profile = useEntity(props)
if (profile.status == 'success') {
+ const account =
+ profile.data?.type === 'a' ? profile.data?.account : undefined
+ if (!account) return null
if (props.block?.attributes?.view == 'content' && profile.data) {
- return
+ return
} else if (props.block?.attributes?.view == 'card') {
return (
-
+
)
}
@@ -542,7 +514,7 @@ export function EmbedAccount(
parentBlockId={parentBlockId}
viewType="card"
>
-
+
@@ -659,7 +631,7 @@ function AccountInlineEmbed(props: InlineEmbedComponentProps) {
function PublicationInlineEmbed(props: InlineEmbedComponentProps) {
const pubId = props?.type == 'd' ? props.qid : undefined
if (!pubId) throw new Error('Invalid props at PublicationInlineEmbed (pubId)')
- const doc = useDocument(pubId, props?.version || undefined)
+ const doc = useEntity(props)
const navigate = useNavigate()
return (
- {getDocumentTitle(doc.data)}
+ {getDocumentTitle(doc.data?.document)}
)
}
diff --git a/frontend/apps/desktop/src/components/citations.tsx b/frontend/apps/desktop/src/components/citations.tsx
index b006ff954..4a2eebda3 100644
--- a/frontend/apps/desktop/src/components/citations.tsx
+++ b/frontend/apps/desktop/src/components/citations.tsx
@@ -3,7 +3,8 @@ import {AccountLinkAvatar} from '@/components/account-link-avatar'
import {useAccount_deprecated} from '@/models/accounts'
import {useComment} from '@/models/comments'
import {useEntityMentions} from '@/models/content-graph'
-import {useDocTextContent, useDocument} from '@/models/documents'
+import {useDocTextContent} from '@/models/documents'
+import {useEntity} from '@/models/entities'
import {DocumentRoute} from '@/utils/routes'
import {useNavigate} from '@/utils/useNavigate'
import {
@@ -46,12 +47,20 @@ function CitationItem({mention}: {mention: Mention}) {
function PublicationCitationItem({mention}: {mention: Mention}) {
const spawn = useNavigate('spawn')
const unpackedSource = unpackHmId(mention.source)
- const doc = useDocument(mention.source, mention.sourceBlob?.cid, {
- enabled: !!mention.source,
- })
- let {data: account} = useAccount_deprecated(doc.data?.author)
+ const doc = useEntity(
+ unpackedSource
+ ? {
+ ...unpackedSource,
+ version: mention.sourceBlob?.cid || null,
+ }
+ : undefined,
+ {
+ enabled: !!unpackedSource,
+ },
+ )
+ let {data: account} = useAccount_deprecated(doc.data?.document?.owner)
- const docTextContent = useDocTextContent(doc.data)
+ const docTextContent = useDocTextContent(doc.data?.document)
const destRoute: DocumentRoute = {
key: 'document',
documentId: unpackedSource!.qid,
@@ -60,16 +69,18 @@ function PublicationCitationItem({mention}: {mention: Mention}) {
}
return (
{
if (unpackedSource) {
spawn(destRoute)
}
}}
- avatar={}
+ avatar={
+
+ }
/>
)
}
@@ -88,13 +99,7 @@ function CommentCitationItem({mention}: {mention: Mention}) {
return null
}, [comment])
- const doc = useDocument(
- commentTarget?.qid,
- commentTarget?.version || undefined,
- {
- enabled: !!commentTarget,
- },
- )
+ const doc = useEntity(commentTarget)
let {data: account} = useAccount_deprecated(comment?.author)
diff --git a/frontend/apps/desktop/src/components/comments.tsx b/frontend/apps/desktop/src/components/comments.tsx
index a7ae45b28..b1c266c02 100644
--- a/frontend/apps/desktop/src/components/comments.tsx
+++ b/frontend/apps/desktop/src/components/comments.tsx
@@ -1,5 +1,5 @@
import {useAccount_deprecated} from '@/models/accounts'
-import {useDocument} from '@/models/documents'
+import {useEntity} from '@/models/entities'
import {AppDocContentProvider} from '@/pages/document-content-provider'
import {trpc} from '@/trpc'
import {useNavigate} from '@/utils/useNavigate'
@@ -350,10 +350,10 @@ export function CommentPageTitlebarWithDocId({
}) {
const docId = useStream(targetDocIdStream)
const usableDocId = targetDocId || docId || undefined
- const doc = useDocument(usableDocId)
+ const doc = useEntity(unpackHmId(usableDocId))
const spawn = useNavigate('spawn')
- const author = doc.data?.author
- const title = getDocumentTitle(doc.data)
+ const author = doc.data?.document?.owner
+ const title = getDocumentTitle(doc.data?.document)
if (!doc || !author || !title || !usableDocId)
return (
@@ -377,7 +377,7 @@ export function CommentPageTitlebarWithDocId({
spawn({
key: 'document',
documentId: usableDocId,
- versionId: doc.data?.version,
+ versionId: doc.data?.document?.version,
})
}}
>
diff --git a/frontend/apps/desktop/src/components/commit-draft-button.tsx b/frontend/apps/desktop/src/components/commit-draft-button.tsx
index 5a21e0c0d..4ee381d25 100644
--- a/frontend/apps/desktop/src/components/commit-draft-button.tsx
+++ b/frontend/apps/desktop/src/components/commit-draft-button.tsx
@@ -4,7 +4,7 @@ import {useNavRoute} from '@/utils/navigation'
import {DraftRoute} from '@/utils/routes'
import {useNavigate} from '@/utils/useNavigate'
import {PlainMessage} from '@bufbuild/protobuf'
-import {Document} from '@shm/shared'
+import {Document, unpackHmId} from '@shm/shared'
import {
AlertCircle,
Button,
@@ -30,28 +30,28 @@ export default function CommitDraftButton() {
const draftRoute: DraftRoute | null = route.key === 'draft' ? route : null
if (!draftRoute)
throw new Error('DraftPublicationButtons requires draft route')
- const prevProfile = useProfileWithDraft(draftRoute.id)
-
- console.log(`== ~ CommitDraftButton ~ draft prevProfile:`, prevProfile.draft)
+ const unpackedDraftId = unpackHmId(draftRoute.id)
+ const prevProfile = useProfileWithDraft(
+ unpackedDraftId?.type === 'a' ? unpackedDraftId.eid : undefined,
+ )
// TODO: add also previous document here
const deleteDraft = trpc.drafts.delete.useMutation()
const publish = usePublishDraft(grpcClient, draftRoute.id)
const invalidate = useQueryInvalidator()
function handlePublish() {
- console.log('=== PUBLISHING...', prevProfile)
- if (prevProfile?.draft) {
+ if (prevProfile.draft) {
publish
.mutateAsync({
draft: prevProfile?.draft,
previous: prevProfile.profile as PlainMessage,
})
.then((res) => {
- console.log('== PUBLISHED', res)
deleteDraft.mutateAsync(res.id).finally(() => {
if (draftRoute?.id) {
invalidate(['trpc.drafts.get'])
if (draftRoute?.id.startsWith('hm://a/')) {
- navigate({key: 'account', accountId: draftRoute.id})
+ const accountId = unpackHmId(draftRoute.id)?.eid
+ accountId && navigate({key: 'account', accountId})
} else {
navigate({key: 'document', documentId: res.id})
}
diff --git a/frontend/apps/desktop/src/components/contacts-prompt.tsx b/frontend/apps/desktop/src/components/contacts-prompt.tsx
index 5ead974f6..04637ae4e 100644
--- a/frontend/apps/desktop/src/components/contacts-prompt.tsx
+++ b/frontend/apps/desktop/src/components/contacts-prompt.tsx
@@ -1,14 +1,16 @@
-import { AccessURLRow } from '@/url'
-import { HYPERMEDIA_PUBLIC_WEB_GATEWAY } from '@shm/shared'
-import { Button, Spinner, TextArea, XStack, toast } from '@shm/ui'
-import { UserPlus } from '@tamagui/lucide-icons'
-import { compressToEncodedURIComponent } from 'lz-string'
-import { ComponentProps, useMemo, useState } from 'react'
+import {useEntity} from '@/models/entities'
+import {getProfileName} from '@/pages/account-page'
+import {AccessURLRow} from '@/url'
+import {hmId, HYPERMEDIA_PUBLIC_WEB_GATEWAY} from '@shm/shared'
+import {Button, Spinner, TextArea, toast, XStack} from '@shm/ui'
+import {UserPlus} from '@tamagui/lucide-icons'
+import {compressToEncodedURIComponent} from 'lz-string'
+import {ComponentProps, useMemo, useState} from 'react'
import appError from '../errors'
-import { useMyAccount_deprecated } from '../models/accounts'
-import { useConnectPeer } from '../models/contacts'
-import { useDaemonInfo } from '../models/daemon'
-import { usePeerInfo } from '../models/networking'
+import {useMyAccount_deprecated} from '../models/accounts'
+import {useConnectPeer} from '../models/contacts'
+import {useDaemonInfo} from '../models/daemon'
+import {usePeerInfo} from '../models/networking'
import {
AppDialog,
DialogCloseButton,
@@ -29,13 +31,15 @@ function AddConnectionForm({
onClose,
}: {
onClose: () => void
- input: true | { connectionString?: string; name?: string | undefined }
+ input: true | {connectionString?: string; name?: string | undefined}
}) {
const [peerText, setPeer] = useState('')
const daemonInfo = useDaemonInfo()
const account = useMyAccount_deprecated()
+ const profile = useEntity(account ? hmId('a', account) : undefined)
const deviceId = daemonInfo.data?.peerId
const peerInfo = usePeerInfo(deviceId)
+ console.log('peerInfo', peerInfo.data, deviceId)
const connectionString =
typeof input === 'object' ? input.connectionString : undefined
@@ -47,10 +51,10 @@ function AddConnectionForm({
toast.success('Connection Added')
},
onError: (error) => {
- appError(`Connect to peer error: ${error?.rawMessage}`, { error })
+ appError(`Connect to peer error: ${error?.rawMessage}`, {error})
},
})
-
+ const myName = getProfileName(profile.data?.document)
const connectInfo = useMemo(() => {
if (!deviceId || !peerInfo.data?.addrs?.length) return null
return compressToEncodedURIComponent(
@@ -58,14 +62,14 @@ function AddConnectionForm({
a: peerInfo.data?.addrs.map((addr) => {
return addr.split('/p2p/').slice(0, -1).join('/p2p/')
}),
- n: account.data?.profile?.alias,
+ n: myName,
d: deviceId,
}),
)
}, [
deviceId,
peerInfo.data?.addrs?.length, // explicitly using addrs length because the address list is being polled and frequently changes order, which does not affect connecivity
- account.data?.profile?.alias,
+ myName,
])
return (
<>
diff --git a/frontend/apps/desktop/src/components/document-list.tsx b/frontend/apps/desktop/src/components/document-list.tsx
index c53cf71c4..2454b446e 100644
--- a/frontend/apps/desktop/src/components/document-list.tsx
+++ b/frontend/apps/desktop/src/components/document-list.tsx
@@ -1,24 +1,17 @@
-import { useDocumentList } from '@/models/documents'
-import { Delete, List, Spinner } from '@shm/ui'
+import {useDocumentList} from '@/models/documents'
+import {Delete, List, Spinner} from '@shm/ui'
-import { useAppContext } from '@/app-context'
-import { useCopyGatewayReference } from '@/components/copy-gateway-reference'
-import { DocumentListItem } from '@/components/document-list-item'
-import { copyLinkMenuItem } from '@/components/list-item'
-import {
- queryDocument
-} from '@/models/documents'
-import { getDocumentTitle, unpackHmId } from '@shm/shared'
-import { ReactNode } from 'react'
-import { useDeleteDialog } from './delete-dialog'
+import {useAppContext} from '@/app-context'
+import {useCopyGatewayReference} from '@/components/copy-gateway-reference'
+import {DocumentListItem} from '@/components/document-list-item'
+import {copyLinkMenuItem} from '@/components/list-item'
+import {getDocumentTitle, unpackHmId} from '@shm/shared'
+import {ReactNode} from 'react'
+import {useDeleteDialog} from './delete-dialog'
-export function DocumentsFullList({
- header,
-}: {
- header: ReactNode
-}) {
+export function DocumentsFullList({header}: {header: ReactNode}) {
const documents = useDocumentList({})
- const { queryClient, grpcClient } = useAppContext()
+ const {queryClient, grpcClient} = useAppContext()
const deleteDialog = useDeleteDialog()
const items = documents.data.documents
@@ -33,8 +26,8 @@ export function DocumentsFullList({
onEndReached={() => {
documents.fetchNextPage()
}}
- renderItem={({ item: document }) => {
- const { authors, author } = document
+ renderItem={({item: document}) => {
+ const {authors, author} = document
if (!document) return null
const docId = document.id
const id = unpackHmId(docId)
@@ -49,15 +42,7 @@ export function DocumentsFullList({
(d) => d.id == document?.id,
)}
onPointerEnter={() => {
- if (document?.id) {
- queryClient.client.prefetchQuery(
- queryDocument({
- grpcClient,
- docId: document.id,
- version: document.version,
- }),
- )
- }
+ // todo: prefetch here for improved perf
}}
document={document}
author={author}
diff --git a/frontend/apps/desktop/src/components/edit-profile-dialog.tsx b/frontend/apps/desktop/src/components/edit-profile-dialog.tsx
index 671464296..234d2e277 100644
--- a/frontend/apps/desktop/src/components/edit-profile-dialog.tsx
+++ b/frontend/apps/desktop/src/components/edit-profile-dialog.tsx
@@ -1,13 +1,5 @@
import {zodResolver} from '@hookform/resolvers/zod'
-import {
- Button,
- DialogTitle,
- Form,
- Label,
- Spinner,
- XStack,
- YStack,
-} from '@shm/ui'
+import {Button, Form, Label, XStack, YStack} from '@shm/ui'
import {useEffect} from 'react'
import {Control, useController, useForm} from 'react-hook-form'
import {z} from 'zod'
@@ -20,22 +12,11 @@ import {FormError, FormInput} from './form-input'
export function useEditProfileDialog() {
// for some reason the dialog doesn't work if the input is falsy
// input is not needed for this dialog, so we just use "true", lol
- return useAppDialog(EditProfileDialog)
+ return useAppDialog(EditProfileDialog)
}
function EditProfileDialog({onClose}: {onClose: () => void}) {
return null
- // const profile = useProfile()
- return (
- <>
- Edit Profile
- {profile ? (
-
- ) : (
-
- )}
- >
- )
}
const profileSchema = z.object({
diff --git a/frontend/apps/desktop/src/components/sidebar-neo.tsx b/frontend/apps/desktop/src/components/sidebar-neo.tsx
index 74116ba23..337108857 100644
--- a/frontend/apps/desktop/src/components/sidebar-neo.tsx
+++ b/frontend/apps/desktop/src/components/sidebar-neo.tsx
@@ -1,10 +1,9 @@
import {focusDraftBlock} from '@/draft-focusing'
-import {useMyAccount_deprecated, useProfile} from '@/models/accounts'
-import {useDocument} from '@/models/documents'
+import {useMyAccount_deprecated} from '@/models/accounts'
import {
- useEntitiesContent,
- useEntityContent,
- useEntityRoutes,
+ useEntity,
+ useRouteBreadcrumbRoutes,
+ useRouteEntities,
} from '@/models/entities'
import {useFavorites} from '@/models/favorites'
import {getProfileName} from '@/pages/account-page'
@@ -55,10 +54,10 @@ function _SidebarNeo() {
const replace = useNavigate('replace')
let myAccountSection: ReactNode = null
let standaloneSection: ReactNode = null
- const entityRoutes = useEntityRoutes(route)
+ const entityRoutes = useRouteBreadcrumbRoutes(route)
const firstEntityRoute = entityRoutes[0]
const isMyAccountDraftActive = route.key === 'draft' && route.id === myAccount
- const accountEntities = useEntitiesContent(
+ const accountEntities = useRouteEntities(
myAccountRoute ? [myAccountRoute] : [],
)
const isMyAccountActive =
@@ -67,7 +66,7 @@ function _SidebarNeo() {
firstEntityRoute.key === 'account' &&
firstEntityRoute.accountId === myAccount)
// const [collapseMe, setCollapseMe] = useState(!isMyAccountActive)
- // const entityContents = useEntitiesContent(
+ // const entityContents = useRouteEntities(
// myAccountRoute ? [myAccountRoute, ...entityRoutes] : entityRoutes,
// )
const handleNavigate = useCallback(function handleNavigate(
@@ -76,7 +75,6 @@ function _SidebarNeo() {
) {
if (doReplace) replace(route)
else navigate(route)
- // const destEntityRoutes = getEntityRoutes(route)
// const firstEntityRoute = destEntityRoutes[0]
// const isMyAccountActive =
// firstEntityRoute &&
@@ -141,6 +139,7 @@ function _SidebarNeo() {
/>
>
) : null}
+
function ResumeDraftButton({info}: {info: ItemDetails}) {
if (!info) throw new Error('ItemDetails required for ResumeDraftButton')
- const {docId} = info
+ const {id} = info
const navigate = useNavigate()
const draft = false
@@ -275,7 +272,7 @@ function ContextItems({
return (
<>
} />
@@ -727,7 +724,7 @@ function FavoriteAccountItem({
const id = unpackHmId(url)
const route = useNavRoute()
const accountId = id?.eid
- const {data} = useProfile(accountId)
+ const {data} = useEntity(id)
if (!accountId) return null
return (
{
onNavigate({key: 'account', accountId})
}}
- title={getProfileName(data)}
+ title={getProfileName(data?.document)}
/>
)
}
@@ -750,7 +747,7 @@ function FavoritePublicationItem({
}) {
const id = unpackHmId(url)
const route = useNavRoute()
- const doc = useDocument(id?.qid, id?.version || undefined)
+ const doc = useEntity(id)
const documentId = id?.qid
if (!documentId) return null
return (
@@ -764,7 +761,7 @@ function FavoritePublicationItem({
versionId: id?.version || undefined,
})
}}
- title={getDocumentTitle(doc)}
+ title={getDocumentTitle(doc.data?.document)}
/>
)
}
diff --git a/frontend/apps/desktop/src/components/sidebar.tsx b/frontend/apps/desktop/src/components/sidebar.tsx
index 711b712f1..ab95fd085 100644
--- a/frontend/apps/desktop/src/components/sidebar.tsx
+++ b/frontend/apps/desktop/src/components/sidebar.tsx
@@ -1,40 +1,9 @@
-import {useAccount_deprecated, useProfile} from '@/models/accounts'
-import {useDocument, useDocumentEmbeds} from '@/models/documents'
-import {useFavorites} from '@/models/favorites'
-import {appRouteOfId, getRouteKey, useNavRoute} from '@/utils/navigation'
-import {getRouteContext, getRouteParentContext} from '@/utils/route-context'
-import {
- AccountRoute,
- BaseEntityRoute,
- DocumentRoute,
- NavRoute,
-} from '@/utils/routes'
+import {useNavRoute} from '@/utils/navigation'
import {useNavigate} from '@/utils/useNavigate'
-import {
- HMBlockNode,
- HMDocument,
- UnpackedHypermediaId,
- getDocumentTitle,
- unpackHmId,
-} from '@shm/shared'
-import {Button, Home, SizableText, XStack, YStack} from '@shm/ui'
-import {
- Contact,
- File,
- FileText,
- Hash,
- Sparkles,
- Star,
-} from '@tamagui/lucide-icons'
-import {PropsWithChildren, ReactNode, memo, useMemo} from 'react'
-import {
- GenericSidebarContainer,
- SidebarDivider,
- SidebarGroupItem,
- SidebarItem,
- activeDocOutline,
- getDocOutline,
-} from './sidebar-base'
+import {Home} from '@shm/ui'
+import {Contact, File, Sparkles} from '@tamagui/lucide-icons'
+import {memo} from 'react'
+import {GenericSidebarContainer, SidebarItem} from './sidebar-base'
import {SidebarNeo} from './sidebar-neo'
export const AppSidebar = memo(MainAppSidebar)
@@ -92,512 +61,7 @@ export function MainAppSidebar() {
title="Contacts"
bold
/>
-
- {/*
- */}
- {/* {account.data && (
-
- )} */}
- {/* {myAccountOutlineContent} */}
- {/* {myAccount.data?.id && (
-
- )}
-
- {myAccountRoute ? null : (
-
- )} */}
)
}
-
-function SidebarFavorites() {
- const navigate = useNavigate()
- const favorites = useFavorites()
- const route = useNavRoute()
- return (
- {
- navigate({key: 'favorites'})
- }}
- title="Favorites"
- bold
- icon={Star}
- rightHover={
- [
- // {},
- // },
- // ]}
- // />,
- ]
- }
- items={favorites.map((fav) => {
- const {key, url} = fav
- if (key === 'account') {
- return
- }
- if (key === 'document') {
- return
- }
- return null
- })}
- />
- )
-}
-
-function FavoriteAccountItem({url}: {url: string}) {
- const id = unpackHmId(url)
- const route = useNavRoute()
- const accountId = id?.eid
- const account = useAccount_deprecated(accountId)
- const navigate = useNavigate()
- if (!accountId) return null
- return (
- {
- navigate({key: 'account', accountId})
- }}
- title={account.data?.profile?.alias || 'Unknown Account'}
- />
- )
-}
-
-function FavoritePublicationItem({url}: {url: string}) {
- const id = unpackHmId(url)
- const route = useNavRoute()
- const navigate = useNavigate()
- const doc = useDocument(id?.qid, id?.version || undefined)
- const documentId = id?.qid
- if (!documentId) return null
- return (
- {
- navigate({
- key: 'document',
- documentId,
- versionId: id?.version || undefined,
- })
- }}
- title={getDocumentTitle(doc.data)}
- />
- )
-}
-
-function RouteOutline({
- route,
- myAccountId,
-}: {
- route: NavRoute
- myAccountId: string | undefined
-}) {
- if (route.key === 'draft') {
- if (route.contextRoute?.key === 'document') {
- return (
- <>
-
-
- >
- )
- }
- if (route.contextRoute?.key === 'account') {
- return (
- <>
-
-
- >
- )
- }
- }
- if (route.key === 'account') {
- if (route.accountId === myAccountId) return null
- return (
- <>
-
-
- >
- )
- }
- if (route.key === 'document') {
- return (
- <>
-
-
- >
- )
- }
- return null
-}
-
-function useNavigateBlock(fromRoute: NavRoute) {
- const replace = useNavigate('replace')
- const thisRoute = useNavRoute()
- const navigate = useNavigate()
- function navigateBlock(
- blockId: string,
- entityId?: UnpackedHypermediaId,
- parentBlockId?: string,
- ) {
- if (entityId || getRouteKey(fromRoute) !== getRouteKey(thisRoute)) {
- const destRoute = entityId ? appRouteOfId(entityId) : fromRoute
- // uh, I'm sure this code is buggy:
- const context = entityId ? getRouteContext(fromRoute, parentBlockId) : []
- if (destRoute?.key === 'document') {
- navigate({
- ...destRoute,
- context,
- blockId,
- })
- } else if (destRoute?.key === 'account') {
- navigate({
- ...destRoute,
- tab: 'profile',
- context,
- blockId,
- })
- } else if (destRoute) {
- navigate(destRoute)
- }
- } else if (fromRoute.key === 'document') {
- replace({
- ...fromRoute,
- blockId,
- })
- } else if (fromRoute.key === 'account') {
- replace({
- ...fromRoute,
- tab: 'profile',
- blockId,
- })
- }
- }
- function focusBlock(
- blockId: string,
- entityId?: UnpackedHypermediaId,
- parentBlockId?: string,
- ) {
- const context = getRouteParentContext(fromRoute)
- const destRoute = entityId ? appRouteOfId(entityId) : fromRoute
- if (destRoute?.key === 'document') {
- navigate({
- ...destRoute,
- context,
- blockId: blockId,
- isBlockFocused: true,
- })
- } else if (destRoute?.key === 'account') {
- navigate({
- ...destRoute,
- context,
- blockId: blockId,
- isBlockFocused: true,
- })
- } else if (destRoute) {
- navigate(destRoute)
- }
- }
- return {navigateBlock, focusBlock}
-}
-
-function useContextItems(context: BaseEntityRoute[] | undefined) {
- const items =
- context?.map((contextRoute, index) => {
- if (contextRoute.key === 'account')
- return (
- context.slice(0, index)}
- />
- )
- if (contextRoute.key === 'document')
- return (
- context.slice(0, index)}
- />
- )
- return null
- }) || null
- return {items}
-}
-
-function useIntermediateContext(
- route: BaseEntityRoute,
- document: HMDocument | undefined | null,
- blockId: string | undefined,
-) {
- const headings = useMemo(() => {
- if (!blockId || !document) return null
- let blockHeadings: null | {id: string; text: string}[] = null
- if (!blockId) return []
- function findBlock(
- nodes: HMBlockNode[] | undefined,
- parentHeadings: {id: string; text: string}[],
- ) {
- return nodes?.find((blockNode) => {
- if (!blockId) return null
- if (blockNode.block.id === blockId) {
- blockHeadings = parentHeadings
- return true
- }
- if (blockNode.children?.length) {
- return findBlock(blockNode.children, [
- ...parentHeadings,
- {id: blockNode.block.id, text: blockNode.block.text},
- ])
- }
- return false
- })
- }
- findBlock(document?.content, [])
- return blockHeadings as null | {id: string; text: string}[]
- }, [document, blockId])
- const navigate = useNavigate()
- return headings?.map((heading) => {
- return (
- {
- navigate({...route, blockId: heading.id})
- }}
- />
- )
- })
-}
-
-function AccountContextItem({
- route,
- getContext,
-}: {
- route: AccountRoute
- getContext: () => BaseEntityRoute[]
-}) {
- const unpacked = unpackHmId(route.accountId)
- const {data} = useProfile(unpacked?.eid)
- const navigate = useNavigate()
- return (
- <>
- {
- navigate({...route, blockId: undefined, isBlockFocused: undefined})
- }}
- />
- {useIntermediateContext(route, data?.profile, route.blockId)}
- >
- )
-}
-
-function PublicationContextItem({
- route,
- getContext,
-}: {
- route: DocumentRoute
- getContext: () => BaseEntityRoute[]
-}) {
- const doc = useDocument(route.documentId, route.versionId)
- const navigate = useNavigate()
- return (
- <>
- {
- navigate({...route, blockId: undefined})
- }}
- />
- {useIntermediateContext(route, doc.data, route.blockId)}
- >
- )
-}
-
-function isDraftActive(route: NavRoute, documentId: string | undefined) {
- return route.key === 'draft' && route.draftId === documentId
-}
-
-function AccountRouteOutline({route}: {route: AccountRoute}) {
- const activeRoute = useNavRoute()
- const isActive =
- activeRoute.key === 'account' && activeRoute.accountId === route.accountId
- const account = useAccount_deprecated(route.accountId)
- const profilePub = useProfilePublicationWithDraft(route.accountId)
- const pubEmbeds = useDocumentEmbeds(
- profilePub.data?.document,
- !!profilePub.data,
- {
- skipCards: true,
- },
- )
- const docOutline = getDocOutline(
- profilePub?.data?.document?.children || [],
- pubEmbeds,
- )
- const navigate = useNavigate()
- const replace = useNavigate('replace')
- const {navigateBlock, focusBlock} = useNavigateBlock(route)
- const {outlineContent, isBlockActive, isBlockFocused} = activeDocOutline(
- docOutline,
- route.isBlockFocused ? undefined : route.blockId,
- route.isBlockFocused ? route.blockId : undefined,
- pubEmbeds,
- navigateBlock,
- focusBlock,
- navigate,
- )
- const {items: parentContext} = useContextItems(route.context)
- const isRootActive = isActive && !isBlockFocused
- return (
- <>
- {parentContext}
- {
- if (!isRootActive) {
- replace({
- ...route,
- blockId: undefined,
- isBlockFocused: undefined,
- })
- }
- }}
- title={account.data?.profile?.alias}
- icon={Contact}
- items={outlineContent}
- defaultExpanded
- />
- }
- isDraft={profilePub.data?.isDocumentDraft}
- onPressDraft={
- isDraftActive(activeRoute, profilePub?.data?.document?.id)
- ? null
- : () => {
- navigate({
- key: 'draft',
- draftId: profilePub.data?.drafts?.[0]?.id,
- contextRoute: route,
- })
- }
- }
- >
- >
- )
-}
-
-function DocumentRouteOutline({route}: {route: DocumentRoute}) {
- const activeRoute = useNavRoute()
- const doc = useDocument(route.documentId, route.versionId)
- const pubEmbeds = useDocumentEmbeds(doc.data, !!doc.data, {
- skipCards: true,
- })
- const outline = getDocOutline(doc.data?.content || [], pubEmbeds)
- const navigate = useNavigate()
- const replace = useNavigate('replace')
- const {navigateBlock, focusBlock} = useNavigateBlock(route)
- const {outlineContent, isBlockActive} = activeDocOutline(
- outline,
- route.isBlockFocused ? undefined : route.blockId,
- route.isBlockFocused ? route.blockId : undefined,
- pubEmbeds,
- navigateBlock,
- focusBlock,
- navigate,
- )
- const {items: parentContext} = useContextItems(route.context)
- return (
- <>
- {parentContext}
- {
- if (route.blockId) {
- replace({...route, blockId: undefined})
- }
- }}
- title={pub.data?.document?.title}
- icon={FileText}
- items={outlineContent}
- defaultExpanded
- />
- }
- isDraft={pub.data?.isDocumentDraft}
- onPressDraft={() => {
- isDraftActive(activeRoute, pub?.data?.document?.id)
- ? null
- : navigate({
- key: 'draft',
- draftId: pub.data?.drafts?.[0]?.id,
- contextRoute: route,
- variant: null,
- })
- }}
- >
- >
- )
-}
-
-function DraftItems({
- titleItem,
- children,
- onPressDraft,
- isDraft,
-}: PropsWithChildren<{
- titleItem: ReactNode
- onPressDraft: null | (() => void)
- isDraft?: boolean
-}>) {
- return (
-
- {titleItem}
- {isDraft ? (
-
-
- Unsaved Document
-
- {onPressDraft ? (
-
- ) : null}
-
- ) : null}
- {children}
-
- )
-}
diff --git a/frontend/apps/desktop/src/components/titlebar-common.tsx b/frontend/apps/desktop/src/components/titlebar-common.tsx
index 91850ac71..79c458ef0 100644
--- a/frontend/apps/desktop/src/components/titlebar-common.tsx
+++ b/frontend/apps/desktop/src/components/titlebar-common.tsx
@@ -6,12 +6,10 @@ import {useEditProfileDialog} from '@/components/edit-profile-dialog'
import {useFavoriteMenuItem} from '@/components/favoriting'
import {MenuItemType, OptionsDropdown} from '@/components/options-dropdown'
import {DraftPublicationButtons, VersionContext} from '@/components/variants'
-import {
- useAccount_deprecated,
- useMyAccountIds,
- useProfileWithDraft,
-} from '@/models/accounts'
-import {useDocument, usePushPublication} from '@/models/documents'
+import {useAccount_deprecated, useProfileWithDraft} from '@/models/accounts'
+import {useMyAccountIds} from '@/models/daemon'
+import {usePushPublication} from '@/models/documents'
+import {useEntity} from '@/models/entities'
import {useGatewayHost, useGatewayUrl} from '@/models/gateway-settings'
import {SidebarWidth, useSidebarContext} from '@/sidebar-context'
import {
@@ -67,12 +65,13 @@ export function DocOptionsButton() {
throw new Error(
'DocOptionsButton can only be rendered on publication route',
)
- const docId = route.documentId
+ const docId = unpackHmId(route.documentId)
+ if (!docId) throw new Error('Invalid document ID')
const gwHost = useGatewayHost()
const push = usePushPublication()
const deleteEntity = useDeleteDialog()
const [copyContent, onCopy, host] = useCopyGatewayReference()
- const doc = useDocument(route.documentId, route.versionId)
+ const doc = useEntity({...docId, version: route.versionId || null})
const menuItems: MenuItemType[] = [
{
key: 'link',
@@ -108,7 +107,7 @@ export function DocOptionsButton() {
onPress: () => {
deleteEntity.open({
id: route.documentId,
- title: getDocumentTitle(doc.data),
+ title: getDocumentTitle(doc.data?.document),
onSuccess: () => {
dispatch({type: 'pop'})
},
@@ -116,9 +115,8 @@ export function DocOptionsButton() {
},
},
]
- const id = unpackHmId(docId)
- const docUrl = id
- ? createHmId('d', id.eid, {
+ const docUrl = docId
+ ? createHmId('d', docId.eid, {
version: route.versionId,
})
: null
@@ -148,7 +146,7 @@ export function AccountOptionsButton() {
const editProfileDialog = useEditProfileDialog()
const myAccountIds = useMyAccountIds()
const {profile} = useProfileWithDraft(route.accountId)
- const isMyAccount = myAccountIds.includes(route.accountId)
+ const isMyAccount = myAccountIds.data?.includes(route.accountId)
if (isMyAccount) {
menuItems.push({
key: 'edit-account',
@@ -192,21 +190,21 @@ function EditAccountButton() {
const myAccountIds = useMyAccountIds()
const navigate = useNavigate()
const {draft} = useProfileWithDraft(route.accountId)
- if (!myAccountIds.includes(route.accountId)) {
+ if (!myAccountIds.data?.includes(route.accountId)) {
return null
}
if (route.tab !== 'profile' && route.tab) return null
const hasExistingDraft = !!draft
return (
<>
-
+
- name: {accountKey.name}
- {
- deleteKey.mutate(accountKey.name)
- }}
- >
- delete key
-
{draft ? (
- openDraft({id: accountKey.accountId})}>
+ openDraft({id: accountDraftId})}>
Resume editing
) : (
- openDraft({id: accountKey.accountId})}>
+ openDraft({id: accountDraftId})}>
{profile ? 'Edit Profile' : 'Create Draft'}
)}
diff --git a/frontend/apps/desktop/src/pages/settings.tsx b/frontend/apps/desktop/src/pages/settings.tsx
index ccfac800b..f929a698a 100644
--- a/frontend/apps/desktop/src/pages/settings.tsx
+++ b/frontend/apps/desktop/src/pages/settings.tsx
@@ -4,9 +4,15 @@ import {Avatar} from '@/components/avatar'
import {AvatarForm} from '@/components/avatar-form'
import {useEditProfileDialog} from '@/components/edit-profile-dialog'
import appError from '@/errors'
-import {useMyAccount_deprecated, useProfile} from '@/models/accounts'
+import {useMyAccount_deprecated} from '@/models/accounts'
import {useAutoUpdatePreference} from '@/models/app-settings'
-import {useDaemonInfo, useDeleteKey, useSavedMnemonics} from '@/models/daemon'
+import {
+ useDaemonInfo,
+ useDeleteKey,
+ useMyAccountIds,
+ useSavedMnemonics,
+} from '@/models/daemon'
+import {useEntity} from '@/models/entities'
import {useExperiments, useWriteExperiments} from '@/models/experiments'
import {
useGatewayUrl,
@@ -25,7 +31,7 @@ import {
import {useWalletOptIn} from '@/models/wallet'
import {trpc} from '@/trpc'
import {getAvatarUrl} from '@/utils/account-url'
-import {LightningWallet, State, VERSION} from '@shm/shared'
+import {hmId, LightningWallet, State, VERSION} from '@shm/shared'
import {
AlertDialog,
ArrowDownRight,
@@ -59,12 +65,12 @@ import {
TabsContentProps,
TabsProps,
TextArea,
+ toast,
Tooltip,
View,
XGroup,
XStack,
YStack,
- toast,
} from '@shm/ui'
import {
AtSign,
@@ -82,7 +88,7 @@ import {
import copyTextToClipboard from 'copy-text-to-clipboard'
import React, {useEffect, useId, useMemo, useState} from 'react'
import {dispatchWizardEvent} from 'src/app-account'
-import {useAccountKeys} from 'src/models/daemon'
+import {getProfileName} from './account-page'
export default function Settings() {
return (
@@ -323,7 +329,7 @@ export function ProfileForm({
export function ProfileInfo() {
const account = useMyAccount_deprecated()
- const profile = account.data?.profile
+ const profile = account?.profile
const accountId = account.data?.id
if (profile && accountId) {
@@ -342,49 +348,45 @@ export function ProfileInfo() {
function AccountKeys() {
const deleteKey = useDeleteKey()
- const {data: keys} = useAccountKeys()
+ const keys = useMyAccountIds()
const [selectedAccount, setSelectedAccount] = useState(
() => {
- if (keys && keys.length == 1) {
- return keys[0].name
+ if (keys.data && keys.data.length == 1) {
+ return keys.data[0]
}
return undefined
},
)
useEffect(() => {
- if (keys && keys.length == 1) {
- setSelectedAccount(keys[0].name)
+ if (keys.data && keys.data.length == 1) {
+ setSelectedAccount(keys.data[0])
}
- }, [keys])
+ }, [keys.data])
function handleDeleteCurrentAccount() {
- if (!account) return
- deleteKey.mutateAsync({name: account.name}).then(() => {})
+ if (!selectedAccount) return
+ deleteKey.mutateAsync({accountId: selectedAccount}).then(() => {})
}
- const account = useMemo(() => {
- return keys?.find((key) => key.name == selectedAccount)
- }, [selectedAccount])
-
- const {data: profile} = useProfile(account?.accountId)
-
- console.log(`== ~ AccountKeys ~ profile:`, profile)
+ const {data: profile} = useEntity(
+ selectedAccount ? hmId('a', selectedAccount) : undefined,
+ )
- const mnemonics = useSavedMnemonics(account?.name)
+ const mnemonics = useSavedMnemonics()
const [showWords, setShowWords] = useState(false)
return (
- {keys?.map((key) => (
+ {keys.data?.map((key) => (
setSelectedAccount(key.name)}
+ bg={selectedAccount == selectedAccount ? '$color5' : undefined}
+ onPress={() => setSelectedAccount(selectedAccount)}
/>
))}
@@ -434,7 +436,7 @@ function AccountKeys() {
>
Delete Account
- {`Are you really sure youc ant to delete ${account?.name} account?`}
+ {`Are you really sure youc ant to delete ${selectedAccount} account?`}
@@ -453,14 +455,14 @@ function AccountKeys() {
-
+
@@ -468,7 +470,7 @@ function AccountKeys() {
borderColor="$colorTransparent"
borderWidth={0}
disabled
- value={account?.accountId}
+ value={selectedAccount}
/>
diff --git a/frontend/apps/desktop/src/root.tsx b/frontend/apps/desktop/src/root.tsx
index 8adff9bb8..0c7ca2589 100644
--- a/frontend/apps/desktop/src/root.tsx
+++ b/frontend/apps/desktop/src/root.tsx
@@ -206,7 +206,6 @@ function MainApp({
} else if (value[0] === 'trpc.appSettings.getAutoUpdatePreference') {
utils.appSettings.getAutoUpdatePreference.invalidate()
} else if (value[0] == 'trpc.drafts.get') {
- console.log('=== INVALIDATE MEEE', value[0])
utils.drafts.get.invalidate()
} else if (value[0] == 'trpc.drafts.list') {
utils.drafts.list.invalidate()
diff --git a/frontend/apps/desktop/src/utils/open-draft.ts b/frontend/apps/desktop/src/utils/open-draft.ts
index 9378f12cb..30a2aa1a7 100644
--- a/frontend/apps/desktop/src/utils/open-draft.ts
+++ b/frontend/apps/desktop/src/utils/open-draft.ts
@@ -15,8 +15,6 @@ export function useOpenDraft(navigateMode: NavMode = 'spawn') {
id: opts?.id || undefined,
contextRoute,
}
- // invalidate([queryKeys.DRAFT_LIST])
- // invalidate([queryKeys.DOCUMENT_DRAFTS, draftId])
navigate(draftRoute)
}
return openNewDraft
diff --git a/frontend/packages/shared/src/document-content.tsx b/frontend/packages/shared/src/document-content.tsx
index 232a9e95d..a229ceadc 100644
--- a/frontend/packages/shared/src/document-content.tsx
+++ b/frontend/packages/shared/src/document-content.tsx
@@ -1,4 +1,3 @@
-import { Timestamp } from '@bufbuild/protobuf'
import {
API_HTTP_URL,
Block,
@@ -10,6 +9,7 @@ import {
HMBlockNode,
HMDocument,
HMInlineContent,
+ HMTimestamp,
Mention,
UnpackedHypermediaId,
clipContentBlocks,
@@ -22,7 +22,7 @@ import {
toHMInlineContent,
unpackHmId,
useHover,
- useLowlight
+ useLowlight,
} from '@shm/shared'
import {
BlockQuote,
@@ -58,11 +58,11 @@ import {
YStack,
YStackProps,
} from '@shm/ui'
-import { AlertCircle, MessageSquare, Reply } from '@tamagui/lucide-icons'
+import {AlertCircle, MessageSquare, Reply} from '@tamagui/lucide-icons'
import katex from 'katex'
import 'katex/dist/katex.min.css'
-import { common } from 'lowlight'
-import { nip19, nip21, validateEvent, verifySignature } from 'nostr-tools'
+import {common} from 'lowlight'
+import {nip19, nip21, validateEvent, verifySignature} from 'nostr-tools'
import {
PropsWithChildren,
createContext,
@@ -73,7 +73,7 @@ import {
useRef,
useState,
} from 'react'
-import { RiCheckFill, RiCloseCircleLine, RiRefreshLine } from 'react-icons/ri'
+import {RiCheckFill, RiCloseCircleLine, RiRefreshLine} from 'react-icons/ri'
import {
QuotedTweet,
TweetBody,
@@ -84,13 +84,10 @@ import {
enrichTweet,
useTweet,
} from 'react-tweet'
-import {
- contentLayoutUnit,
- contentTextUnit,
-} from './document-content-constants'
+import {contentLayoutUnit, contentTextUnit} from './document-content-constants'
import './document-content.css'
-import { HMAccount } from './hm-types'
-import { useRangeSelection } from './range-selection'
+import {HMAccount} from './hm-types'
+import {useRangeSelection} from './range-selection'
export type EntityComponentsRecord = {
Account: React.FC
@@ -109,12 +106,12 @@ export type DocContentContextValue = {
onCitationClick?: () => void
disableEmbedClick?: boolean
onCopyBlock:
- | null
- | ((blockId: string, blockRange?: BlockRange | ExpandedBlockRange) => void)
+ | null
+ | ((blockId: string, blockRange?: BlockRange | ExpandedBlockRange) => void)
onReplyBlock?: null | ((blockId: string) => void)
onBlockComment?:
- | null
- | ((blockId: string, blockRange?: BlockRange | ExpandedBlockRange) => void)
+ | null
+ | ((blockId: string, blockRange?: BlockRange | ExpandedBlockRange) => void)
layoutUnit: number
textUnit: number
debug: boolean
@@ -129,8 +126,9 @@ export type DocContentContextValue = {
importWebFile?: any
}
-export const docContentContext =
- createContext(null)
+export const docContentContext = createContext(
+ null,
+)
export type EntityComponentProps = BlockContentProps & UnpackedHypermediaId
@@ -234,9 +232,7 @@ export function useDocContentContext() {
let context = useContext(docContentContext)
if (!context) {
- throw new Error(
- `Please wrap with `,
- )
+ throw new Error(`Please wrap with `)
}
return context
@@ -245,9 +241,9 @@ export function useDocContentContext() {
function debugStyles(debug: boolean = false, color: ColorProp = '$color7') {
return debug
? {
- borderWidth: 1,
- borderColor: color,
- }
+ borderWidth: 1,
+ borderColor: color,
+ }
: {}
}
@@ -270,10 +266,9 @@ export function DocContent({
maxBlockCount?: number
marginVertical?: any
}) {
- const { wrapper, bubble, coords, state, send } = useRangeSelection()
+ const {wrapper, bubble, coords, state, send} = useRangeSelection()
- const { layoutUnit, onCopyBlock, onBlockComment } =
- useDocContentContext()
+ const {layoutUnit, onCopyBlock, onBlockComment} = useDocContentContext()
const allBlocks = document?.content || []
const focusedBlocks = getFocusedBlocks(allBlocks, focusBlockId)
const displayBlocks = maxBlockCount
@@ -301,7 +296,7 @@ export function DocContent({
@@ -324,12 +319,12 @@ export function DocContent({
typeof state.context.rangeStart == 'number' &&
typeof state.context.rangeEnd == 'number'
? {
- start: state.context.rangeStart,
- end: state.context.rangeEnd,
- }
+ start: state.context.rangeStart,
+ end: state.context.rangeEnd,
+ }
: {
- expanded: true,
- },
+ expanded: true,
+ },
)
}}
/>
@@ -341,15 +336,15 @@ export function DocContent({
size="$2"
icon={Comment}
onPress={() => {
- send({ type: 'CREATE_COMMENT' })
+ send({type: 'CREATE_COMMENT'})
onBlockComment(
state.context.blockId,
typeof state.context.rangeStart == 'number' &&
typeof state.context.rangeEnd == 'number'
? {
- start: state.context.rangeStart,
- end: state.context.rangeEnd,
- }
+ start: state.context.rangeStart,
+ end: state.context.rangeEnd,
+ }
: undefined,
)
}}
@@ -510,8 +505,8 @@ export function BlockNodeContent({
layoutUnit,
isFirstChild,
)
- const { hover, ...hoverProps } = useHover()
- const { citations } = useBlockCitations(blockNode.block?.id)
+ const {hover, ...hoverProps} = useHover()
+ const {citations} = useBlockCitations(blockNode.block?.id)
const [_expanded, setExpanded] = useState(expanded)
useEffect(() => {
@@ -523,19 +518,19 @@ export function BlockNodeContent({
const elm = useRef(null)
let bnChildren = blockNode.children?.length
? blockNode.children.map((bn, index) => (
-
- ))
+
+ ))
: null
const headingStyles = useMemo(() => {
@@ -568,7 +563,7 @@ export function BlockNodeContent({
useEffect(() => {
if (elm.current && isHighlight) {
- elm.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
+ elm.current.scrollIntoView({behavior: 'smooth', block: 'start'})
}
}, [isHighlight])
@@ -603,10 +598,10 @@ export function BlockNodeContent({
borderRadius={layoutUnit / 4}
bg={isHighlight ? '$yellow3' : '$backgroundTransparent'}
data-node-type="blockContainer"
- // onHoverIn={() => (props.embedDepth ? undefined : hoverProps.onHoverIn())}
- // onHoverOut={() =>
- // props.embedDepth ? undefined : hoverProps.onHoverOut()
- // }
+ // onHoverIn={() => (props.embedDepth ? undefined : hoverProps.onHoverIn())}
+ // onHoverOut={() =>
+ // props.embedDepth ? undefined : hoverProps.onHoverOut()
+ // }
>
{
if (blockNode.block?.id) {
- onCopyBlock(blockNode.block.id, { expanded: true })
+ onCopyBlock(blockNode.block.id, {expanded: true})
} else {
console.error('onCopyBlock Error: no blockId available')
}
@@ -905,7 +900,7 @@ function BlockContentParagraph({
parentBlockId,
...props
}: BlockContentProps) {
- const { debug, textUnit, comment } = useDocContentContext()
+ const {debug, textUnit, comment} = useDocContentContext()
let inline = useMemo(() => toHMInlineContent(new Block(block)), [block])
return (
@@ -931,7 +926,7 @@ export function BlockContentHeading({
parentBlockId,
...props
}: BlockContentProps) {
- const { textUnit, debug, ffSerif } = useDocContentContext()
+ const {textUnit, debug, ffSerif} = useDocContentContext()
let inline = useMemo(() => toHMInlineContent(new Block(block)), [block])
let headingTextStyles = useHeadingTextStyles(depth, textUnit)
let tag = `h${depth}`
@@ -968,7 +963,7 @@ export function DocHeading({
children?: string
right?: React.ReactNode
}) {
- const { textUnit, debug, layoutUnit } = useDocContentContext()
+ const {textUnit, debug, layoutUnit} = useDocContentContext()
let headingTextStyles = useHeadingTextStyles(1, textUnit)
let headingMarginStyles = useHeadingMarginStyles(1, layoutUnit)
@@ -976,14 +971,14 @@ export function DocHeading({
@@ -1103,7 +1098,7 @@ function BlockContentImage({
}: BlockContentProps) {
let inline = useMemo(() => toHMInlineContent(new Block(block)), [block])
const cid = getCIDFromIPFSUrl(block?.ref)
- const { ipfsBlobPrefix, textUnit } = useDocContentContext()
+ const {ipfsBlobPrefix, textUnit} = useDocContentContext()
if (!cid) return null
return (
@@ -1128,7 +1123,7 @@ function BlockContentImage({
{inline.length ? (
@@ -1147,7 +1142,7 @@ function BlockContentVideo({
}: BlockContentProps) {
let inline = useMemo(() => toHMInlineContent(new Block(block)), [])
const ref = block.ref || ''
- const { ipfsBlobPrefix, textUnit } = useDocContentContext()
+ const {ipfsBlobPrefix, textUnit} = useDocContentContext()
return (
}
-
-export function EmbedAccountContent({ account }: { account: HMAccount }) {
- const { ipfsBlobPrefix } = useDocContentContext()
+export function EmbedAccountContent({account}: {account: HMAccount}) {
+ const {ipfsBlobPrefix} = useDocContentContext()
return (
@@ -1531,7 +1524,7 @@ export function ContentEmbed({
onShowReferenced: (showReference: boolean) => void
renderOpenButton: () => React.ReactNode
EmbedWrapper: React.ComponentType<
- React.PropsWithChildren<{ hmRef: string; parentBlockId: string }>
+ React.PropsWithChildren<{hmRef: string; parentBlockId: string}>
>
parentBlockId: string | null
}) {
@@ -1544,30 +1537,30 @@ export function ContentEmbed({
const embedBlocks = props.blockRef
? selectedBlock
? [
- {
- ...selectedBlock,
- block: {
- ...selectedBlock.block,
- annotations:
- props.blockRange && 'start' in props.blockRange
- ? [
- ...currentAnnotations,
- {
- type: 'range',
- starts: [props.blockRange.start],
- ends: [props.blockRange.end],
- },
- ]
- : currentAnnotations,
+ {
+ ...selectedBlock,
+ block: {
+ ...selectedBlock.block,
+ annotations:
+ props.blockRange && 'start' in props.blockRange
+ ? [
+ ...currentAnnotations,
+ {
+ type: 'range',
+ starts: [props.blockRange.start],
+ ends: [props.blockRange.end],
+ },
+ ]
+ : currentAnnotations,
+ },
+ // children:
+ // props.blockRange &&
+ // 'expanded' in props.blockRange &&
+ // props.blockRange.expanded
+ // ? [...selectedBlock.children]
+ // : [],
},
- // children:
- // props.blockRange &&
- // 'expanded' in props.blockRange &&
- // props.blockRange.expanded
- // ? [...selectedBlock.children]
- // : [],
- },
- ]
+ ]
: null
: document?.content
@@ -1579,10 +1572,10 @@ export function ContentEmbed({
blockRange:
props.blockRange && 'start' in props.blockRange && selectedBlock
? {
- blockId: props.blockRef,
- start: props.blockRange.start,
- end: props.blockRange.end,
- }
+ blockId: props.blockRef,
+ start: props.blockRange.start,
+ end: props.blockRange.end,
+ }
: null,
},
}
@@ -1760,8 +1753,8 @@ export function BlockContentFile({
parentBlockId,
...props
}: BlockContentProps) {
- const { hover, ...hoverProps } = useHover()
- const { layoutUnit, saveCidAsFile } = useDocContentContext()
+ const {hover, ...hoverProps} = useHover()
+ const {layoutUnit, saveCidAsFile} = useDocContentContext()
const fileCid = block.ref ? getCIDFromIPFSUrl(block.ref) : ''
return (
)}
- {fileCid &&
- {
- saveCidAsFile(fileCid, block.attributes?.name || 'File')
- }}
- >
- Download
-
- }
+ {fileCid && (
+
+ {
+ saveCidAsFile(fileCid, block.attributes?.name || 'File')
+ }}
+ >
+ Download
+
+
+ )}
)
@@ -1833,7 +1828,7 @@ export function BlockContentNostr({
parentBlockId,
...props
}: BlockContentProps) {
- const { layoutUnit } = useDocContentContext()
+ const {layoutUnit} = useDocContentContext()
const name = block.attributes?.name ?? ''
const nostrNpud = nip19.npubEncode(name) ?? ''
@@ -1892,15 +1887,15 @@ export function BlockContentNostr({
flex={1}
>
{'Public Key: '}
- {nip21.test(uri) ? {header} : { header }}
+ {nip21.test(uri) ? {header} : {header}}
@@ -1933,10 +1928,10 @@ export function BlockContentXPost({
parentBlockId,
...props
}: BlockContentProps) {
- const { layoutUnit, onLinkClick } = useDocContentContext()
+ const {layoutUnit, onLinkClick} = useDocContentContext()
const urlArray = block.ref?.split('/')
const xPostId = urlArray?.[urlArray.length - 1].split('?')[0]
- const { data, error, isLoading } = useTweet(xPostId)
+ const {data, error, isLoading} = useTweet(xPostId)
let xPostContent
@@ -1990,28 +1985,28 @@ export function BlockContentCode({
parentBlockId,
...props
}: BlockContentProps) {
- const { layoutUnit, debug, textUnit } = useDocContentContext()
+ const {layoutUnit, debug, textUnit} = useDocContentContext()
function getHighlightNodes(result: any) {
return result.value || result.children || []
}
- const CodeHighlight = ({ node }: { node: any }) => {
+ const CodeHighlight = ({node}: {node: any}) => {
if (node.type === 'text') {
return node.value
}
if (node.type === 'element') {
- const { tagName, properties, children } = node
+ const {tagName, properties, children} = node
if (properties.className && Array.isArray(properties.className)) {
properties.className = properties.className[0]
}
return createElement(
tagName,
- { ...properties },
+ {...properties},
children &&
- children.map((child: any, index: number) => (
-
- )),
+ children.map((child: any, index: number) => (
+
+ )),
)
}
@@ -2054,8 +2049,8 @@ export function BlockContentCode({
>
{nodes.length > 0
? nodes.map((node, index) => (
-
- ))
+
+ ))
: block.text}
@@ -2068,7 +2063,7 @@ export function BlockContentMath({
parentBlockId,
...props
}: BlockContentProps) {
- const { layoutUnit } = useDocContentContext()
+ const {layoutUnit} = useDocContentContext()
const tex = katex.renderToString(block.text ? block.text : '', {
throwOnError: true,
@@ -2097,7 +2092,7 @@ export function BlockContentMath({
)
@@ -2128,7 +2123,7 @@ function CheckboxWithLabel({
size,
label,
...checkboxProps
-}: CheckboxProps & { size: SizeTokens; label: string }) {
+}: CheckboxProps & {size: SizeTokens; label: string}) {
const id = `checkbox-${size.toString().slice(1)}`
return (
@@ -2145,7 +2140,7 @@ function CheckboxWithLabel({
)
}
-function RadioGroupItemWithLabel(props: { value: string; label: string }) {
+function RadioGroupItemWithLabel(props: {value: string; label: string}) {
const id = `radiogroup-${props.value}`
return (
@@ -2170,8 +2165,8 @@ export function DocumentCardView({
title?: string
textContent?: string
editors?: Array
- AvatarComponent: React.FC<{ accountId?: string }>
- date?: Timestamp
+ AvatarComponent: React.FC<{accountId?: string}>
+ date?: HMTimestamp
}) {
return (
@@ -2222,7 +2217,7 @@ function EditorsAvatars({
AvatarComponent,
}: {
editors?: Array
- AvatarComponent: React.FC<{ accountId?: string }>
+ AvatarComponent: React.FC<{accountId?: string}>
}) {
return (
diff --git a/frontend/packages/shared/src/hm-types.ts b/frontend/packages/shared/src/hm-types.ts
index 20785439e..f8ff549c9 100644
--- a/frontend/packages/shared/src/hm-types.ts
+++ b/frontend/packages/shared/src/hm-types.ts
@@ -11,6 +11,7 @@ import type {
DeletedEntity,
Document,
Link,
+ UnpackedHypermediaId,
} from '@shm/shared'
import {HMTimestamp} from './utils'
@@ -195,17 +196,21 @@ export type HMEntity =
export type HMEntityContent =
| {
type: 'a'
+ id: UnpackedHypermediaId
document?: HMDocument | null
account?: HMAccount | null
}
| {
type: 'd'
+ id: UnpackedHypermediaId
document?: HMDocument
}
- | {
- type: 'd-draft'
- document: HMDocument
- }
+// todo, add comment and maybe draft
+// | {
+// type: 'd-draft'
+// id: UnpackedHypermediaId
+// document: HMDocument
+// }
export type HMComment = PlainMessage
diff --git a/yarn.lock b/yarn.lock
index c079e846e..cbd1b3ea9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12336,8 +12336,8 @@ __metadata:
linkType: hard
"cacache@npm:^18.0.0":
- version: 18.0.3
- resolution: "cacache@npm:18.0.3"
+ version: 18.0.4
+ resolution: "cacache@npm:18.0.4"
dependencies:
"@npmcli/fs": ^3.1.0
fs-minipass: ^3.0.0
@@ -12351,7 +12351,7 @@ __metadata:
ssri: ^10.0.0
tar: ^6.1.11
unique-filename: ^3.0.0
- checksum: b717fd9b36e9c3279bfde4545c3a8f6d5a539b084ee26a9504d48f83694beb724057d26e090b97540f9cc62bea18b9f6cf671c50e18fb7dac60eda9db691714f
+ checksum: b7422c113b4ec750f33beeca0f426a0024c28e3172f332218f48f963e5b970647fa1ac05679fe5bb448832c51efea9fda4456b9a95c3a1af1105fe6c1833cde2
languageName: node
linkType: hard