WIP draft previews
This commit is contained in:
@@ -408,7 +408,7 @@ async function resolveMedia(
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveRecord(
|
export async function resolveRecord(
|
||||||
agent: BskyAgent,
|
agent: BskyAgent,
|
||||||
queryClient: QueryClient,
|
queryClient: QueryClient,
|
||||||
uri: string,
|
uri: string,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Type converters for Draft API - convert between ComposerState and server Draft types.
|
* Type converters for Draft API - convert between ComposerState and server Draft types.
|
||||||
*/
|
*/
|
||||||
import {type AppBskyDraftDefs, AtUri, RichText} from '@atproto/api'
|
import {type AppBskyDraftDefs, type AppBskyFeedDefs, AtUri, RichText} from '@atproto/api'
|
||||||
import {nanoid} from 'nanoid/non-secure'
|
import {nanoid} from 'nanoid/non-secure'
|
||||||
|
import * as VideoThumbnails from 'expo-video-thumbnails'
|
||||||
|
|
||||||
import {resolveLink} from '#/lib/api/resolve'
|
import {resolveLink} from '#/lib/api/resolve'
|
||||||
import {getImageDim} from '#/lib/media/manip'
|
import {getImageDim} from '#/lib/media/manip'
|
||||||
@@ -18,6 +19,7 @@ import {
|
|||||||
import {type VideoState} from '#/view/com/composer/state/video'
|
import {type VideoState} from '#/view/com/composer/state/video'
|
||||||
import {logger} from './logger'
|
import {logger} from './logger'
|
||||||
import {type DraftPostDisplay, type DraftSummary} from './schema'
|
import {type DraftPostDisplay, type DraftSummary} from './schema'
|
||||||
|
import * as storage from './storage'
|
||||||
|
|
||||||
const TENOR_HOSTNAME = 'media.tenor.com'
|
const TENOR_HOSTNAME = 'media.tenor.com'
|
||||||
|
|
||||||
@@ -285,10 +287,10 @@ function serializeGif(gifMedia: {
|
|||||||
* Convert server DraftView to DraftSummary for list display.
|
* Convert server DraftView to DraftSummary for list display.
|
||||||
* Also checks which media files exist locally.
|
* Also checks which media files exist locally.
|
||||||
*/
|
*/
|
||||||
export function draftViewToSummary(
|
export async function draftViewToSummary(
|
||||||
view: AppBskyDraftDefs.DraftView,
|
view: AppBskyDraftDefs.DraftView,
|
||||||
localMediaExists: (path: string) => boolean,
|
localMediaExists: (path: string) => boolean,
|
||||||
): DraftSummary {
|
): Promise<DraftSummary> {
|
||||||
const firstPost = view.draft.posts[0]
|
const firstPost = view.draft.posts[0]
|
||||||
const previewText = firstPost?.text?.slice(0, 100) || ''
|
const previewText = firstPost?.text?.slice(0, 100) || ''
|
||||||
|
|
||||||
@@ -296,6 +298,85 @@ export function draftViewToSummary(
|
|||||||
let hasMedia = false
|
let hasMedia = false
|
||||||
let hasMissingMedia = false
|
let hasMissingMedia = false
|
||||||
|
|
||||||
|
const postsWithEmbed = await Promise.all(
|
||||||
|
view.draft.posts.map(async (post, i) => {
|
||||||
|
let embed: AppBskyFeedDefs.PostView['embed']
|
||||||
|
|
||||||
|
if (post.embedImages) {
|
||||||
|
embed = {
|
||||||
|
$type: 'app.bsky.embed.images#view',
|
||||||
|
images: await Promise.all(
|
||||||
|
post.embedImages.map(async image => {
|
||||||
|
const exists = localMediaExists(image.localRef.path)
|
||||||
|
const uri = exists ? await storage.loadMediaFromLocal(image.localRef.path) : ''
|
||||||
|
return {
|
||||||
|
$type: 'app.bsky.embed.images#viewImage',
|
||||||
|
thumb: uri,
|
||||||
|
fullsize: uri,
|
||||||
|
alt: image.alt || '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (post.embedVideos) {
|
||||||
|
const video = post.embedVideos[0]
|
||||||
|
const thumbnail = await VideoThumbnails.getThumbnailAsync(video.localRef.path, {
|
||||||
|
time: 0,
|
||||||
|
quality: 0.2,
|
||||||
|
})
|
||||||
|
embed = {
|
||||||
|
$type: 'app.bsky.embed.video#view',
|
||||||
|
cid: 'lol',
|
||||||
|
playlist: 'lol',
|
||||||
|
thumbnail: thumbnail.uri,
|
||||||
|
presentation: 'default', // TODO what about GIFs
|
||||||
|
}
|
||||||
|
} else if (post.embedExternals) {
|
||||||
|
const ext = post.embedExternals[0]
|
||||||
|
const resolved = await resolveLink(
|
||||||
|
createPublicAgent(),
|
||||||
|
ext.uri,
|
||||||
|
)
|
||||||
|
if (resolved.type === 'external') {
|
||||||
|
embed = {
|
||||||
|
$type: 'app.bsky.embed.external#view',
|
||||||
|
external: {
|
||||||
|
$type: 'app.bsky.embed.external#viewExternal',
|
||||||
|
uri: resolved.uri,
|
||||||
|
title: resolved.title,
|
||||||
|
description: resolved.description,
|
||||||
|
thumb: resolved.thumb?.source.path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (post.embedRecords) {
|
||||||
|
const quote = post.embedRecords[0]
|
||||||
|
const urip = new AtUri(quote.record.uri)
|
||||||
|
const url = `https://bsky.app/profile/${urip.host}/post/${urip.rkey}`
|
||||||
|
const resolvedQuote = await resolveLink(
|
||||||
|
createPublicAgent(),
|
||||||
|
url,
|
||||||
|
)
|
||||||
|
if (resolvedQuote.type === 'record') {
|
||||||
|
embed = {
|
||||||
|
$type: 'app.bsky.embed.record#view',
|
||||||
|
record: {
|
||||||
|
...resolvedQuote.view,
|
||||||
|
$type: 'app.bsky.embed.record#viewRecord', // TODO map to other types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
text: post.text,
|
||||||
|
embed,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log({postsWithEmbed})
|
||||||
|
|
||||||
const posts: DraftPostDisplay[] = view.draft.posts.map((post, index) => {
|
const posts: DraftPostDisplay[] = view.draft.posts.map((post, index) => {
|
||||||
const images: DraftPostDisplay['images'] = []
|
const images: DraftPostDisplay['images'] = []
|
||||||
const videos: DraftPostDisplay['video'][] = []
|
const videos: DraftPostDisplay['video'][] = []
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ export function useDraftsQuery() {
|
|||||||
const res = await agent.app.bsky.draft.getDrafts({cursor: pageParam})
|
const res = await agent.app.bsky.draft.getDrafts({cursor: pageParam})
|
||||||
return {
|
return {
|
||||||
cursor: res.data.cursor,
|
cursor: res.data.cursor,
|
||||||
drafts: res.data.drafts.map(view =>
|
drafts: await Promise.all(res.data.drafts.map(view =>
|
||||||
draftViewToSummary(view, path => storage.mediaExists(path)),
|
draftViewToSummary(view, path => storage.mediaExists(path)),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initialPageParam: undefined as string | undefined,
|
initialPageParam: undefined as string | undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user