diff --git a/src/screens/Settings/components/ExportCarDialog.tsx b/src/screens/Settings/components/ExportCarDialog.tsx index cf47564763..9369943929 100644 --- a/src/screens/Settings/components/ExportCarDialog.tsx +++ b/src/screens/Settings/components/ExportCarDialog.tsx @@ -3,6 +3,7 @@ import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {DM_SERVICE_HEADERS} from '#/lib/constants' import {saveBytesToDisk} from '#/lib/media/manip' import {logger} from '#/logger' import {useAgent} from '#/state/session' @@ -23,14 +24,14 @@ export function ExportCarDialog({ const {_} = useLingui() const t = useTheme() const agent = useAgent() - const [loading, setLoading] = useState(false) + const [loading, setLoading] = useState<'repo' | 'chat' | false>(false) const download = useCallback(async () => { if (!agent.session) { return // shouldnt ever happen } try { - setLoading(true) + setLoading('repo') const did = agent.session.did const downloadRes = await agent.com.atproto.sync.getRepo({did}) const saveRes = await saveBytesToDisk( @@ -51,6 +52,40 @@ export function ExportCarDialog({ } }, [_, control, agent]) + const downloadChatData = useCallback(async () => { + if (!agent.session) { + return + } + try { + setLoading('chat') + // Using raw fetch because the XRPC client incorrectly tries to JSON-parse + // application/jsonl responses (substring match on application/json). + const res = await agent.sessionManager.fetchHandler( + '/xrpc/chat.bsky.actor.exportAccountData', + {headers: DM_SERVICE_HEADERS}, + ) + if (!res.ok) { + throw new Error(`HTTP ${res.status}`) + } + const data = new Uint8Array(await res.arrayBuffer()) + const saveRes = await saveBytesToDisk( + 'chat.jsonl', + data, + res.headers.get('content-type') || 'application/jsonl', + ) + + if (saveRes) { + Toast.show(_(msg`File saved successfully!`)) + } + } catch (e) { + logger.error('Error occurred while downloading chat data', {message: e}) + Toast.show(_(msg`Error occurred while saving file`), {type: 'error'}) + } finally { + setLoading(false) + control.close() + } + }, [_, control, agent]) + return ( @@ -77,13 +112,34 @@ export function ExportCarDialog({ color="primary" size="large" label={_(msg`Download CAR file`)} - disabled={loading} + disabled={!!loading} onPress={download}> Download CAR file - {loading && } + {loading === 'repo' && } + + + + + You can also download your chat data as a "JSONL" file. This file + only includes chat messages that you have sent and does not + include chat messages that you have received. + + + +