get image aspect ratio when restoring

This commit is contained in:
Samuel Newman
2026-01-28 11:07:18 +02:00
parent 39024e6a36
commit fe57c73c38
2 changed files with 138 additions and 113 deletions
+1 -1
View File
@@ -461,7 +461,7 @@ export const ComposePost = ({
})
// Convert server draft to composer posts (videos returned separately)
const {posts, restoredVideos} = draftToComposerPosts(
const {posts, restoredVideos} = await draftToComposerPosts(
draftSummary.draft,
loadedMedia,
)
+39 -14
View File
@@ -4,6 +4,7 @@
import {type AppBskyDraftDefs, RichText} from '@atproto/api'
import {nanoid} from 'nanoid/non-secure'
import {getImageDim} from '#/lib/media/manip'
import {type ComposerImage} from '#/state/gallery'
import {type Gif} from '#/state/queries/tenor'
import {
@@ -399,13 +400,14 @@ function parseGifFromUrl(
* the compression and upload pipeline. The caller should handle the restoredVideos
* by initiating video processing for each entry.
*/
export function draftToComposerPosts(
export async function draftToComposerPosts(
draft: AppBskyDraftDefs.Draft,
loadedMedia: Map<string, string>,
): {posts: PostDraft[]; restoredVideos: Map<number, RestoredVideo>} {
): Promise<{posts: PostDraft[]; restoredVideos: Map<number, RestoredVideo>}> {
const restoredVideos = new Map<number, RestoredVideo>()
const posts = draft.posts.map((post, index) => {
const posts = await Promise.all(
draft.posts.map(async (post, index) => {
const richtext = new RichText({text: post.text || ''})
richtext.detectFacetsWithoutResolution()
@@ -417,28 +419,49 @@ export function draftToComposerPosts(
// Restore images
if (post.embedImages && post.embedImages.length > 0) {
const images: ComposerImage[] = []
for (const img of post.embedImages) {
const imagePromises = post.embedImages.map(async img => {
const path = loadedMedia.get(img.localRef.path)
if (path) {
if (!path) {
return null
}
let width = 0
let height = 0
try {
const dims = await getImageDim(path)
width = dims.width
height = dims.height
} catch (e) {
logger.warn('Failed to get image dimensions', {
path,
error: e,
})
}
logger.debug('restoring image with localRefPath', {
localRefPath: img.localRef.path,
loadedPath: path,
width,
height,
})
images.push({
return {
alt: img.alt || '',
// Preserve the original localRefPath for reuse when saving
localRefPath: img.localRef.path,
source: {
id: nanoid(),
path,
width: 0, // Will be recalculated when loaded
height: 0,
mime: 'image/jpeg', // Default, will be detected
width,
height,
mime: 'image/jpeg',
},
} as ComposerImage
})
}
}
const images = (await Promise.all(imagePromises)).filter(
(img): img is ComposerImage => img !== null,
)
if (images.length > 0) {
embed.media = {type: 'images', images}
}
@@ -501,7 +524,8 @@ export function draftToComposerPosts(
mimeType,
localRefPath: vid.localRef.path,
captions:
vid.captions?.map(c => ({lang: c.lang, content: c.content})) ?? [],
vid.captions?.map(c => ({lang: c.lang, content: c.content})) ??
[],
})
}
}
@@ -538,7 +562,8 @@ export function draftToComposerPosts(
labels,
embed,
} as PostDraft
})
}),
)
return {posts, restoredVideos}
}