Clean up media-upload temp files on iOS (#11007)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import {useMutation} from '@tanstack/react-query'
|
||||
|
||||
import {STATUS_PAGE_URL} from '#/lib/constants'
|
||||
import {type CommonNavigatorParams} from '#/lib/routes/types'
|
||||
import {purgeTemporaryImageFiles} from '#/state/gallery'
|
||||
import * as SettingsList from '#/screens/Settings/components/SettingsList'
|
||||
import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom'
|
||||
import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle'
|
||||
@@ -41,7 +42,13 @@ export function AboutSettingsScreen({}: Props) {
|
||||
useMutation({
|
||||
mutationFn: async () => {
|
||||
const freeSpaceBefore = await FileSystem.getFreeDiskStorageAsync()
|
||||
await Image.clearDiskCache()
|
||||
await Promise.all([
|
||||
// expo-image's disk cache
|
||||
Image.clearDiskCache(),
|
||||
// full-resolution media-upload leftovers (picker/manipulator copies);
|
||||
// the only in-app way for iOS users to reclaim this space
|
||||
purgeTemporaryImageFiles(),
|
||||
])
|
||||
const freeSpaceAfter = await FileSystem.getFreeDiskStorageAsync()
|
||||
const spaceDiff = freeSpaceBefore - freeSpaceAfter
|
||||
return spaceDiff * -1
|
||||
|
||||
+24
-1
@@ -358,14 +358,37 @@ function blobToDataUri(blob: Blob): Promise<string> {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches that the OS image picker and manipulator write into when attaching
|
||||
* media to a post. They live alongside our own `bsky-composer` dir under the OS
|
||||
* cache directory. expo-image-picker copies every originally selected photo and
|
||||
* video here, and expo-image-manipulator leaves intermediate full-resolution
|
||||
* outputs here (compressImage makes several manipulateAsync passes, only the
|
||||
* last of which gets moved into `bsky-composer`). Nothing else cleans these up,
|
||||
* so on iOS - where the OS exposes no "clear cache" - they accumulate
|
||||
* indefinitely, one full-resolution copy per attached item.
|
||||
*/
|
||||
const SYSTEM_MEDIA_CACHE_DIRS = ['ImagePicker', 'ImageManipulator']
|
||||
|
||||
/** Purge files that were created to accomodate image manipulation */
|
||||
export async function purgeTemporaryImageFiles() {
|
||||
const cacheDir = IS_NATIVE && getImageCacheDirectory()
|
||||
if (!IS_NATIVE) {
|
||||
return
|
||||
}
|
||||
|
||||
const cacheDir = getImageCacheDirectory()
|
||||
if (cacheDir) {
|
||||
await deleteAsync(cacheDir, {idempotent: true})
|
||||
await makeDirectoryAsync(cacheDir)
|
||||
}
|
||||
|
||||
// We don't recreate these - the respective expo modules recreate them on
|
||||
// demand the next time they run.
|
||||
await Promise.all(
|
||||
SYSTEM_MEDIA_CACHE_DIRS.map(dir =>
|
||||
deleteAsync(joinPath(cacheDirectory!, dir), {idempotent: true}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
function joinPath(a: string, b: string) {
|
||||
|
||||
Reference in New Issue
Block a user