Skip to content

Commit

Permalink
Improved URL +appRoute handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ericvicenti committed Sep 14, 2023
1 parent d36e7ea commit 67af50c
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 60 deletions.
3 changes: 1 addition & 2 deletions frontend/apps/site/publication-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Account,
EmbedBlock,
getCIDFromIPFSUrl,
extractEntityId,
HeadingBlock,
ImageBlock,
InlineContent,
Expand Down Expand Up @@ -168,7 +167,7 @@ function PublicationContextSidebar({
}) {
const groupContent = trpc.group.listContent.useQuery(
{
groupEid: extractEntityId(group?.id || '')?.[1] || '',
groupId: group?.id || '',
},
{enabled: !!group?.id},
)
Expand Down
21 changes: 14 additions & 7 deletions frontend/packages/app/src/components/quick-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ import {
} from '@mintter/app/src/models/documents'
import {fetchWebLink} from '@mintter/app/src/models/web-links'
import {useNavigate} from '@mintter/app/src/utils/navigation'
import {isHypermediaScheme} from '@mintter/shared'
import {
HYPERMEDIA_SCHEME,
isHypermediaScheme,
unpackHmId,
} from '@mintter/shared'
import {Spinner, YStack} from '@mintter/ui'
import {useListen} from '@mintter/app/src/app-context'
import {Command} from 'cmdk'
import {useState} from 'react'
import {toast} from 'react-hot-toast'
import './quick-switcher.css'
import {useAppContext} from '@mintter/app/src/app-context'
import {hmIdToAppRoute} from '../open-url'
import {unpackHmIdWithAppRoute} from '../open-url'

export default function QuickSwitcher() {
const [open, setOpen] = useState(false)
Expand Down Expand Up @@ -61,12 +65,15 @@ export default function QuickSwitcher() {
key="mtt-link"
value={search}
onSelect={() => {
if (isHypermediaScheme(search)) {
const navRoute = hmIdToAppRoute(search)

if (navRoute) {
const searched = unpackHmIdWithAppRoute(search)
console.log('== ~ QuickSwitcher ~ searched', searched)
if (
searched?.scheme === HYPERMEDIA_SCHEME ||
searched?.hostname === 'hyper.media'
) {
if (searched?.navRoute) {
setOpen(false)
navigate(navRoute)
navigate(searched?.navRoute)
} else {
console.log('== ~ QuickSwitcher ~ Querying Web URL', search)
setActionPromise(
Expand Down
9 changes: 5 additions & 4 deletions frontend/packages/app/src/editor/embed-block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
isHypermediaScheme,
serverBlockToEditorInline,
unpackDocId,
unpackHmId,
} from '@mintter/shared'
import {SizableText, Spinner, Text, XStack, YStack} from '@mintter/ui'
import {AlertCircle} from '@tamagui/lucide-icons'
Expand All @@ -31,7 +32,7 @@ import {createReactBlockSpec} from '../blocknote-react'
import {HMBlockSchema, hmBlockSchema} from '../client/schema'
import {BACKEND_FILE_URL} from '../constants'
import {usePublication} from '../models/documents'
import {hmIdToAppRoute, useOpenUrl} from '../open-url'
import {unpackHmIdWithAppRoute, useOpenUrl} from '../open-url'

function InlineContentView({inline}: {inline: InlineContent[]}) {
const openUrl = useOpenUrl()
Expand Down Expand Up @@ -174,9 +175,9 @@ function EmbedPresentation({
if (editor?.isEditable) {
return
}
const route = hmIdToAppRoute(block.props.ref)
if (route) {
spawn(route)
const unpacked = unpackHmIdWithAppRoute(block.props.ref)
if (unpacked?.navRoute && unpacked?.scheme === 'hm') {
spawn(unpacked?.navRoute)
}
}}
>
Expand Down
55 changes: 27 additions & 28 deletions frontend/packages/app/src/open-url.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import {useAppContext} from '@mintter/app/src/app-context'
import {NavRoute, useNavigate} from '@mintter/app/src/utils/navigation'
import {createHmId, isHypermediaScheme, unpackHmId} from '@mintter/shared'
import {UnpackedHypermediaId, createHmId, unpackHmId} from '@mintter/shared'
import {useMemo} from 'react'

export function hmIdToAppRoute(hmId: string): NavRoute | undefined {
export function unpackHmIdWithAppRoute(
hmId: string,
): (UnpackedHypermediaId & {navRoute?: NavRoute}) | null {
const hmIds = unpackHmId(hmId)

let pubRoute: NavRoute | undefined = undefined
if (hmIds?.scheme === 'hm') {
if (hmIds?.type === 'd') {
pubRoute = {
key: 'publication',
documentId: createHmId('d', hmIds.eid),
versionId: hmIds.version,
blockId: hmIds.blockRef,
}
} else if (hmIds?.type === 'g') {
pubRoute = {
key: 'group',
groupId: createHmId('g', hmIds.eid),
}
} else if (hmIds?.type === 'a') {
pubRoute = {
key: 'account',
accountId: hmIds.eid,
}
if (!hmIds) return null
let navRoute: NavRoute | undefined = undefined
if (hmIds?.type === 'd') {
navRoute = {
key: 'publication',
documentId: createHmId('d', hmIds.eid),
versionId: hmIds.version,
blockId: hmIds.blockRef,
}
} else if (hmIds?.type === 'g') {
navRoute = {
key: 'group',
groupId: createHmId('g', hmIds.eid),
}
} else if (hmIds?.type === 'a') {
navRoute = {
key: 'account',
accountId: hmIds.eid,
}
}
return pubRoute
return {...hmIds, navRoute}
}

export function useOpenUrl() {
Expand All @@ -37,13 +37,12 @@ export function useOpenUrl() {
return useMemo(() => {
return (url?: string, newWindow?: boolean) => {
if (!url) return

const pubRoute = hmIdToAppRoute(url)
if (pubRoute) {
const dest = unpackHmIdWithAppRoute(url)
if (dest?.navRoute) {
if (newWindow) {
spawn(pubRoute)
spawn(dest?.navRoute)
} else {
push(pubRoute)
push(dest?.navRoute)
}
return
} else {
Expand Down
34 changes: 15 additions & 19 deletions frontend/packages/shared/src/utils/entity-id-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,6 @@ export function getPublicDocUrl(docId: string, version?: string | undefined) {
return webUrl
}

export function extractEntityId(id: string): [string, string] | null {
// input is like hm://x/abcd. output is ['x', 'abcd']
const m = id.match(/^hm:\/\/([^/]+)\/(.+)$/)
if (!m) return null
const entityType = m[1]
const entityEId = m[2]
return [entityType, entityEId]
}

export function isValidSiteEntity(entityType: string) {
if (entityType === 'a') return true
if (entityType === 'd') return true
if (entityType === 'g') return true
return false
}

export function createPublicWebHmUrl(
type: keyof typeof HYPERMEDIA_ENTITY_TYPES,
eid: string,
Expand Down Expand Up @@ -102,12 +86,22 @@ function inKeys<V extends string>(
return null
}

export function unpackHmId(hypermediaId: string) {
export type UnpackedHypermediaId = {
type: keyof typeof HYPERMEDIA_ENTITY_TYPES
eid: string
version?: string
blockRef?: string
hostname?: string
scheme?: string
}

export function unpackHmId(hypermediaId: string): UnpackedHypermediaId | null {
const parsed = parseCustomURL(hypermediaId)
if (parsed?.scheme === HYPERMEDIA_SCHEME) {
const type = inKeys(parsed?.path[0], HYPERMEDIA_ENTITY_TYPES)
const eid = parsed?.path[1]
const version = parsed?.query.v
if (!type) return null
return {
type,
eid,
Expand All @@ -122,6 +116,7 @@ export function unpackHmId(hypermediaId: string) {
const eid = parsed?.path[2]
const version = parsed?.query.v
let hostname = parsed?.path[0]
if (!type) return null
return {
type,
eid,
Expand All @@ -134,7 +129,9 @@ export function unpackHmId(hypermediaId: string) {
return null
}

export function unpackDocId(inputUrl: string) {
export function unpackDocId(
inputUrl: string,
): (UnpackedHypermediaId & {docId: string}) | null {
const unpackedHm = unpackHmId(inputUrl)
if (!unpackedHm?.eid) return null
if (unpackedHm.type !== 'd') {
Expand All @@ -157,7 +154,6 @@ export function isHypermediaScheme(url?: string) {

export function isPublicGatewayLink(text: string) {
const matchesGateway = text.indexOf(HYPERMEDIA_PUBLIC_WEB_GATEWAY) === 0
console.log('PATH', text.split(HYPERMEDIA_PUBLIC_WEB_GATEWAY)[1])
return !!matchesGateway
}

Expand Down

0 comments on commit 67af50c

Please sign in to comment.