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 {STATUS_PAGE_URL} from '#/lib/constants'
|
||||||
import {type CommonNavigatorParams} from '#/lib/routes/types'
|
import {type CommonNavigatorParams} from '#/lib/routes/types'
|
||||||
|
import {purgeTemporaryImageFiles} from '#/state/gallery'
|
||||||
import * as SettingsList from '#/screens/Settings/components/SettingsList'
|
import * as SettingsList from '#/screens/Settings/components/SettingsList'
|
||||||
import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom'
|
import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom'
|
||||||
import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle'
|
import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle'
|
||||||
@@ -41,7 +42,13 @@ export function AboutSettingsScreen({}: Props) {
|
|||||||
useMutation({
|
useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const freeSpaceBefore = await FileSystem.getFreeDiskStorageAsync()
|
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 freeSpaceAfter = await FileSystem.getFreeDiskStorageAsync()
|
||||||
const spaceDiff = freeSpaceBefore - freeSpaceAfter
|
const spaceDiff = freeSpaceBefore - freeSpaceAfter
|
||||||
return spaceDiff * -1
|
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 */
|
/** Purge files that were created to accomodate image manipulation */
|
||||||
export async function purgeTemporaryImageFiles() {
|
export async function purgeTemporaryImageFiles() {
|
||||||
const cacheDir = IS_NATIVE && getImageCacheDirectory()
|
if (!IS_NATIVE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheDir = getImageCacheDirectory()
|
||||||
if (cacheDir) {
|
if (cacheDir) {
|
||||||
await deleteAsync(cacheDir, {idempotent: true})
|
await deleteAsync(cacheDir, {idempotent: true})
|
||||||
await makeDirectoryAsync(cacheDir)
|
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) {
|
function joinPath(a: string, b: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user