Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[APP-1968] Increase image upload resolution (#10073)

authored by

Eric Bailey and committed by
GitHub
34d8c6fe 5bcb9090

+61 -10
+1
src/analytics/features/types.ts
··· 9 9 ImportContactsOnboardingDisable = 'import_contacts:onboarding:disable', 10 10 ImportContactsSettingsDisable = 'import_contacts:settings:disable', 11 11 LiveNowBetaDisable = 'live_now_beta:disable', 12 + ImageUploadsHighResolution = 'image_uploads:high_resolution', 12 13 13 14 AATest = 'aa-test', 14 15 }
+3
src/analytics/metrics/types.ts
··· 230 230 231 231 'composer:gif:open': {} 232 232 'composer:gif:select': {} 233 + 'composer:image:edit': { 234 + platform: Platform['OS'] 235 + } 233 236 'composerPrompt:press': {} 234 237 'composerPrompt:camera:press': {} 235 238 'composerPrompt:gallery:press': {}
+19 -2
src/lib/api/index.ts
··· 51 51 langs?: string[] 52 52 } 53 53 54 + type FeatureFlags = { 55 + highResolutionImages?: boolean 56 + } 57 + 54 58 export async function post( 55 59 agent: BskyAgent, 56 60 queryClient: QueryClient, 57 61 opts: PostOpts, 62 + featureFlags?: FeatureFlags, 58 63 ) { 59 64 const thread = opts.thread 60 65 opts.onStateChange?.(t`Processing...`) ··· 91 96 queryClient, 92 97 draft, 93 98 opts.onStateChange, 99 + featureFlags, 94 100 ) 95 101 let labels: $Typed<ComAtprotoLabelDefs.SelfLabels> | undefined 96 102 if (draft.labels.length) { ··· 230 236 queryClient: QueryClient, 231 237 draft: PostDraft, 232 238 onStateChange: ((state: string) => void) | undefined, 239 + featureFlags?: FeatureFlags, 233 240 ): Promise< 234 241 | $Typed<AppBskyEmbedImages.Main> 235 242 | $Typed<AppBskyEmbedVideo.Main> ··· 240 247 > { 241 248 if (draft.embed.quote) { 242 249 const [resolvedMedia, resolvedQuote] = await Promise.all([ 243 - resolveMedia(agent, queryClient, draft.embed, onStateChange), 250 + resolveMedia( 251 + agent, 252 + queryClient, 253 + draft.embed, 254 + onStateChange, 255 + featureFlags, 256 + ), 244 257 resolveRecord(agent, queryClient, draft.embed.quote.uri), 245 258 ]) 246 259 if (resolvedMedia) { ··· 263 276 queryClient, 264 277 draft.embed, 265 278 onStateChange, 279 + featureFlags, 266 280 ) 267 281 if (resolvedMedia) { 268 282 return resolvedMedia ··· 288 302 queryClient: QueryClient, 289 303 embedDraft: EmbedDraft, 290 304 onStateChange: ((state: string) => void) | undefined, 305 + featureFlags?: FeatureFlags, 291 306 ): Promise< 292 307 | $Typed<AppBskyEmbedExternal.Main> 293 308 | $Typed<AppBskyEmbedImages.Main> ··· 303 318 const images: AppBskyEmbedImages.Image[] = await Promise.all( 304 319 imagesDraft.map(async (image, i) => { 305 320 logger.debug(`Compressing image #${i}`) 306 - const {path, width, height, mime} = await compressImage(image) 321 + const {path, width, height, mime} = await compressImage(image, { 322 + highResolution: featureFlags?.highResolutionImages, 323 + }) 307 324 logger.debug(`Uploading image #${i}`) 308 325 const res = await uploadBlob(agent, path, mime) 309 326 return {
+16 -2
src/state/gallery.ts
··· 200 200 return img 201 201 } 202 202 203 - export async function compressImage(img: ComposerImage): Promise<PickerImage> { 203 + export async function compressImage( 204 + img: ComposerImage, 205 + options?: { 206 + highResolution?: boolean 207 + }, 208 + ): Promise<PickerImage> { 204 209 const source = img.transformed || img.source 205 210 206 - const [w, h] = containImageRes(source.width, source.height, POST_IMG_MAX) 211 + const [w, h] = containImageRes( 212 + source.width, 213 + source.height, 214 + options?.highResolution 215 + ? { 216 + width: 4000, 217 + height: 4000, 218 + } 219 + : POST_IMG_MAX, 220 + ) 207 221 208 222 let minQualityPercentage = 0 209 223 let maxQualityPercentage = 101 // exclusive
+15 -6
src/view/com/composer/Composer.tsx
··· 825 825 try { 826 826 logger.info(`composer: posting...`) 827 827 postUri = ( 828 - await apilib.post(agent, queryClient, { 829 - thread, 830 - replyTo: replyTo?.uri, 831 - onStateChange: setPublishingStage, 832 - langs: currentLanguages, 833 - }) 828 + await apilib.post( 829 + agent, 830 + queryClient, 831 + { 832 + thread, 833 + replyTo: replyTo?.uri, 834 + onStateChange: setPublishingStage, 835 + langs: currentLanguages, 836 + }, 837 + { 838 + highResolutionImages: ax.features.enabled( 839 + ax.features.ImageUploadsHighResolution, 840 + ), 841 + }, 842 + ) 834 843 ).uris[0] 835 844 836 845 /*
+7
src/view/com/composer/photos/Gallery.tsx
··· 4 4 type ImageStyle, 5 5 Keyboard, 6 6 type LayoutChangeEvent, 7 + Platform, 7 8 StyleSheet, 8 9 TouchableOpacity, 9 10 View, ··· 24 25 import * as Dialog from '#/components/Dialog' 25 26 import {MediaInsetBorder} from '#/components/MediaInsetBorder' 26 27 import {Text} from '#/components/Typography' 28 + import {useAnalytics} from '#/analytics' 27 29 import {IS_IOS, IS_NATIVE} from '#/env' 28 30 import {type PostAction} from '../state/composer' 29 31 import {EditImageDialog} from './EditImageDialog' ··· 147 149 }: GalleryItemProps): React.ReactNode => { 148 150 const {_} = useLingui() 149 151 const t = useTheme() 152 + const ax = useAnalytics() 150 153 151 154 const altTextControl = Dialog.useDialogControl() 152 155 const editControl = Dialog.useDialogControl() ··· 161 164 } 162 165 163 166 const onImageEdit = () => { 167 + ax.metric('composer:image:edit', { 168 + platform: Platform.OS, 169 + }) 170 + 164 171 if (IS_NATIVE) { 165 172 cropImage(image).then(next => { 166 173 onChange(next)