Skip to content

Commit

Permalink
Adjust to cloud updates & make sure we're getting the pending entry d…
Browse files Browse the repository at this point in the history
…ata in correctly
  • Loading branch information
benmerckx committed Sep 29, 2023
1 parent f3ad3a5 commit c6ebfbe
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 40 deletions.
6 changes: 2 additions & 4 deletions src/backend/data/ChangeSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface DeleteChange {
export interface UploadChange {
type: ChangeType.Upload
file: string
fileId: string
url: string
}
export type Change =
| WriteChange
Expand Down Expand Up @@ -197,9 +197,7 @@ export class ChangeSetCreator {
}

fileUploadChanges(mutation: UploadMutation): Array<Change> {
return [
{type: ChangeType.Upload, file: mutation.file, fileId: mutation.entryId}
]
return [{type: ChangeType.Upload, file: mutation.file, url: mutation.url}]
}

fileRemoveChanges({file: entryFile}: FileRemoveMutation): Array<Change> {
Expand Down
11 changes: 7 additions & 4 deletions src/cli/generate/LocalData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,19 @@ export class LocalData implements Source, Target, Media {
const {dashboardUrl} = this.options
if (!dashboardUrl)
throw new Error(`Cannot prepare upload without dashboard url`)
const fileId = createId()
const entryId = createId()
const dir = dirname(file)
const extension = extname(file).toLowerCase()
const name = basename(file, extension)
const fileName = `${slugify(name)}.${createId()}${extension}`
const fileName = `${slugify(name)}.${entryId}${extension}`
const fileLocation = join(dir, fileName)
return {
fileId,
entryId,
location: fileLocation,
previewUrl: '',
previewUrl: new URL(
`/preview?file=${encodeURIComponent(fileLocation)}`,
dashboardUrl
).href,
upload: {
url: new URL(
`/upload?file=${encodeURIComponent(fileLocation)}`,
Expand Down
5 changes: 2 additions & 3 deletions src/cloud/server/CloudAuthServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import {fetch, Request, Response} from '@alinea/iso'
import {Handler, router} from 'alinea/backend/router/Router'
import {Auth, Config, Connection, HttpError, outcome, User} from 'alinea/core'
import {verify} from 'alinea/core/util/JWT'
const version = '0.0.0'
// import {version} from '../../../package.json'
import PLazy from 'p-lazy'
import pkg from '../../../package.json'
import {AuthResult, AuthResultType} from '../AuthResult.js'
import {cloudConfig} from './CloudConfig.js'

Expand Down Expand Up @@ -73,7 +72,7 @@ export class CloudAuthServer implements Auth.Server {
const body: any = {
handshake_id: handShakeId,
status: {
version,
version: pkg.version,
roles: [
{
key: 'editor',
Expand Down
4 changes: 0 additions & 4 deletions src/cloud/server/CloudHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ export class CloudApi implements Media, Target, History {
.then<OutcomeJSON<Connection.UploadResponse>>(json)
.then<Outcome<Connection.UploadResponse>>(Outcome.fromJSON)
.then(Outcome.unpack)
.then(info => {
if ('filename' in info) info.location = info.filename as string
return info
})
}

delete(
Expand Down
2 changes: 1 addition & 1 deletion src/core/Connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export namespace Connection {
height?: number
}
export interface UploadResponse {
fileId: string
entryId: string
location: string
previewUrl: string
upload: {
Expand Down
2 changes: 1 addition & 1 deletion src/core/Mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export interface MoveMutation {
export interface UploadMutation {
type: MutationType.Upload
entryId: string
fileId: string
url: string
file: string
}

Expand Down
1 change: 1 addition & 0 deletions src/dashboard/atoms/DbAtoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const localDbAtom = atom(

return pending.flatMap(mutation => {
switch (mutation.type) {
case MutationType.Create:
case MutationType.Edit:
if (mutation.entry.parent)
return [mutation.entryId, mutation.entry.parent]
Expand Down
6 changes: 3 additions & 3 deletions src/dashboard/atoms/EntryAtoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {Projection} from 'alinea/core/pages/Projection'
import {generateKeyBetween} from 'alinea/core/util/FractionalIndexing'
import {entries} from 'alinea/core/util/Objects'
import DataLoader from 'dataloader'
import {atom, useAtomValue, useSetAtom} from 'jotai'
import {atom, useAtomValue} from 'jotai'
import {useMemo} from 'react'
import {useDashboard} from '../hook/UseDashboard.js'
import {configAtom} from './DashboardAtoms.js'
import {graphAtom, mutateAtom} from './DbAtoms.js'
import {graphAtom, useMutate} from './DbAtoms.js'
import {rootAtom, workspaceAtom} from './NavigationAtoms.js'

export function rootId(rootName: string) {
Expand Down Expand Up @@ -166,7 +166,7 @@ export function useEntryTreeProvider(): AsyncTreeDataLoader<EntryTreeItem> & {
): void
} {
const {loader} = useAtomValue(loaderAtom)
const mutate = useSetAtom(mutateAtom)
const mutate = useMutate()
const {config} = useDashboard()
return useMemo(() => {
return {
Expand Down
7 changes: 5 additions & 2 deletions src/dashboard/atoms/PendingAtoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ export function cleanupPending(modifiedAt: number) {
}

export function addPending(...mutations: Array<Mutation>) {
const mutationId = createId()
const res: Array<PendingMutation> = []
pendingDoc.transact(() => {
for (const mutation of mutations) {
const mutationId = createId()
const pending = {
...mutation,
mutationId,
Expand All @@ -56,7 +56,10 @@ export function addPending(...mutations: Array<Mutation>) {

export function removePending(...mutationIds: Array<string>) {
pendingDoc.transact(() => {
for (const mutationId of mutationIds) pendingMap.delete(mutationId)
for (const mutationId of mutationIds) {
console.log(`Removing ${mutationId}`)
pendingMap.delete(mutationId)
}
})
}

Expand Down
36 changes: 20 additions & 16 deletions src/dashboard/hook/UseUploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from 'alinea/core'
import {entryFileName, entryFilepath} from 'alinea/core/EntryFilenames'
import {createId} from 'alinea/core/Id'
import {MutationType} from 'alinea/core/Mutation'
import {Mutation, MutationType} from 'alinea/core/Mutation'
import {base64} from 'alinea/core/util/Encoding'
import {generateKeyBetween} from 'alinea/core/util/FractionalIndexing'
import {
Expand All @@ -26,6 +26,7 @@ import {useSetAtom} from 'jotai'
import pLimit from 'p-limit'
import {useState} from 'react'
import {rgbaToThumbHash, thumbHashToAverageRGBA} from 'thumbhash'
import {useMutate} from '../atoms/DbAtoms.js'
import {errorAtom} from '../atoms/ErrorAtoms.js'
import {useConfig} from './UseConfig.js'
import {useGraph} from './UseGraph.js'
Expand Down Expand Up @@ -79,7 +80,8 @@ async function process(
file: string
entry: Media.File
}>,
client: Connection
client: Connection,
mutate: (...mutations: Array<Mutation>) => Promise<void>
): Promise<Upload> {
switch (upload.status) {
case UploadStatus.Queued:
Expand Down Expand Up @@ -157,29 +159,28 @@ async function process(
if (!result.ok)
throw new HttpError(
result.status,
`Could not upload file: "${await result.text()}"`
`Could not reach server for upload`
)
})
return {...upload, info, status: UploadStatus.Uploaded}
}
case UploadStatus.Uploaded: {
// Create entry
const {file, entry} = await createEntry(upload)
await client.mutate([
const info = upload.info!
await mutate(
{
type: MutationType.Edit,
type: MutationType.Create,
entryId: entry.entryId,
file,
entry
},
{
type: MutationType.Upload,
entryId: entry.entryId,
fileId: upload.info!.fileId,
file: upload.info!.location
url: info.previewUrl,
file: info.location
}
])

)
return {...upload, result: entry, status: UploadStatus.Done}
}
case UploadStatus.Done:
Expand All @@ -191,11 +192,12 @@ export function useUploads(onSelect?: (entry: EntryRow) => void) {
const config = useConfig()
const graph = useGraph()
const {cnx: client} = useSession()
const mutate = useMutate()
const setErrorAtom = useSetAtom(errorAtom)
const [uploads, setUploads] = useState<Array<Upload>>([])

async function createEntry(upload: Upload) {
const entryId = createId()
const entryId = upload.info?.entryId ?? createId()
const {parentId} = upload.to
const buffer = await upload.file.arrayBuffer()
const contentHash = await createContentHash(
Expand Down Expand Up @@ -242,7 +244,7 @@ export function useUploads(onSelect?: (entry: EntryRow) => void) {
parent: parent?.entryId ?? null,
entryId: entryId,
type: 'MediaFile',
url: (parent ? parent.url : '/') + path,
url: (parent ? parent.url : '') + '/' + path,
title: basename(path, extension),
seeded: false,
modifiedAt: Date.now(),
Expand All @@ -253,14 +255,14 @@ export function useUploads(onSelect?: (entry: EntryRow) => void) {
level: parent ? parent.level + 1 : 0,
parentDir: parentDir,
filePath,
childrenDir: filePath.slice(0, -extension.length),
childrenDir: filePath.slice(0, -'.json'.length),
contentHash,
active: true,
main: true,
data: {
title: basename(path, extension),
location: fileLocation,
extension: extension.toLowerCase(),
extension: extension,
size: buffer.byteLength,
hash: contentHash,
width: upload.width,
Expand Down Expand Up @@ -290,8 +292,10 @@ export function useUploads(onSelect?: (entry: EntryRow) => void) {
}
while (true) {
const next = await tasker[upload.status](() =>
process(upload, createEntry, client)
)
process(upload, createEntry, client, mutate)
).catch(error => {
return {...upload, error, status: UploadStatus.Done}
})
update(next)
if (next.status === UploadStatus.Done) {
if (next.error) {
Expand Down
2 changes: 1 addition & 1 deletion src/dashboard/view/explorer/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function Explorer({
const queryClient = useQueryClient()
const changed = useAtomValue(changedEntriesAtom)
useEffect(() => {
queryClient.invalidateQueries('explorer')
if (changed.length > 0) queryClient.invalidateQueries('explorer')
}, [changed])

const {data, isLoading} = useQuery(
Expand Down
5 changes: 4 additions & 1 deletion src/dashboard/view/media/FileUploadRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ export function FileUploadRow(upload: Upload) {
</Chip>
<div className={styles.root.status()}>
{upload.status === UploadStatus.Done ? (
<Icon icon={upload.error ? IcBaselineErrorOutline : IcRoundCheck} />
<Icon
icon={upload.error ? IcBaselineErrorOutline : IcRoundCheck}
title={upload.error ? upload.error.message : 'Done'}
/>
) : (
<Loader />
)}
Expand Down

0 comments on commit c6ebfbe

Please sign in to comment.