Skip to content

Commit 206bd5f

Browse files
committed
fix: expo blob compatability and attachment row mapping
1 parent 7e40d26 commit 206bd5f

File tree

4 files changed

+21
-36
lines changed

4 files changed

+21
-36
lines changed

demos/react-native-supabase-todolist/app/views/todos/edit/[id].tsx

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ATTACHMENT_TABLE, AttachmentRecord } from '@powersync/attachments';
1+
import { ATTACHMENT_TABLE, attachmentFromSql, AttachmentRecord } from '@powersync/attachments';
22
import { usePowerSync, useQuery } from '@powersync/react-native';
33
import { CameraCapturedPicture } from 'expo-camera';
44
import _ from 'lodash';
@@ -12,21 +12,7 @@ import { TODO_TABLE, TodoRecord, LIST_TABLE } from '../../../../library/powersyn
1212
import { useSystem } from '../../../../library/powersync/system';
1313
import { TodoItemWidget } from '../../../../library/widgets/TodoItemWidget';
1414

15-
type TodoEntry = TodoRecord & Partial<Omit<AttachmentRecord, 'id'>> & { todo_id: string; attachment_id: string | null };
16-
17-
const toAttachmentRecord = _.memoize((entry: TodoEntry): AttachmentRecord | null => {
18-
return entry.attachment_id == null
19-
? null
20-
: {
21-
id: entry.attachment_id,
22-
filename: entry.filename!,
23-
state: entry.state!,
24-
timestamp: entry.timestamp,
25-
local_uri: entry.local_uri,
26-
media_type: entry.media_type,
27-
size: entry.size
28-
};
29-
});
15+
type TodoEntry = TodoRecord & { todo_id: string; attachment_id: string | null };
3016

3117
const TodoView: React.FC = () => {
3218
const system = useSystem();
@@ -61,10 +47,10 @@ const TodoView: React.FC = () => {
6147
if (completed) {
6248
const userID = await system.supabaseConnector.userId();
6349
updatedRecord.completed_at = new Date().toISOString();
64-
updatedRecord.completed_by = userID;
50+
updatedRecord.completed_by = userID!;
6551
} else {
66-
updatedRecord.completed_at = undefined;
67-
updatedRecord.completed_by = undefined;
52+
updatedRecord.completed_at = null;
53+
updatedRecord.completed_by = null;
6854
}
6955
await system.powersync.execute(
7056
`UPDATE ${TODO_TABLE}
@@ -165,7 +151,7 @@ const TodoView: React.FC = () => {
165151
<ScrollView style={{ maxHeight: '90%' }}>
166152
{todos.map((r) => {
167153
const record = { ...r, id: r.todo_id };
168-
const photoRecord = toAttachmentRecord(r);
154+
const photoRecord = attachmentFromSql(r);
169155
return (
170156
<TodoItemWidget
171157
key={r.todo_id}

demos/react-native-supabase-todolist/library/powersync/AppSchema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const AppSchema = new Schema({
2828
todos,
2929
lists,
3030
attachments: new AttachmentTable({
31-
name: 'attachments',
31+
viewName: 'attachments',
3232
}),
3333
});
3434

demos/react-native-supabase-todolist/library/storage/SupabaseRemoteStorageAdapter.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,28 @@ export class SupabaseRemoteStorageAdapter implements RemoteStorageAdapter {
2626
}
2727

2828
async downloadFile(attachment: AttachmentRecord): Promise<ArrayBuffer> {
29-
const { data, error } = await this.options.client.storage
30-
.from(this.options.bucket)
31-
.download(attachment.filename);
29+
const { data, error } = await this.options.client.storage.from(this.options.bucket).download(attachment.filename);
3230

3331
if (error) {
3432
throw error;
3533
}
3634

37-
// Convert Blob to ArrayBuffer
38-
return await data.arrayBuffer();
35+
return new Promise((resolve, reject) => {
36+
const reader = new FileReader();
37+
reader.onloadend = () => {
38+
resolve(reader.result as ArrayBuffer);
39+
};
40+
reader.onerror = reject;
41+
reader.readAsArrayBuffer(data);
42+
});
3943
}
4044

4145
async deleteFile(attachment: AttachmentRecord): Promise<void> {
42-
const { error } = await this.options.client.storage
43-
.from(this.options.bucket)
44-
.remove([attachment.filename]);
46+
const { error } = await this.options.client.storage.from(this.options.bucket).remove([attachment.filename]);
4547

4648
if (error) {
4749
console.debug('Failed to delete file from Supabase Storage', error);
4850
throw error;
4951
}
5052
}
5153
}
52-

demos/react-native-supabase-todolist/library/widgets/TodoItemWidget.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { CameraCapturedPicture } from 'expo-camera';
22
import React from 'react';
3-
import { ActivityIndicator, Alert, View, Modal, StyleSheet } from 'react-native';
3+
import { ActivityIndicator, Alert, View, Modal, StyleSheet, Text } from 'react-native';
44
import { ListItem, Button, Icon, Image } from '@rneui/themed';
55
import { CameraWidget } from './CameraWidget';
66
import { TodoRecord } from '../powersync/AppSchema';
77
import { AttachmentRecord } from '@powersync/attachments';
88
import { AppConfig } from '../supabase/AppConfig';
9-
import { useSystem } from '../powersync/system';
109
import { SafeAreaProvider } from 'react-native-safe-area-context';
1110

1211
export interface TodoItemWidgetProps {
@@ -21,7 +20,6 @@ export const TodoItemWidget: React.FC<TodoItemWidgetProps> = (props) => {
2120
const { record, photoAttachment, onDelete, onToggleCompletion, onSavePhoto } = props;
2221
const [loading, setLoading] = React.useState(false);
2322
const [isCameraVisible, setCameraVisible] = React.useState(false);
24-
const system = useSystem();
2523

2624
const handleCancel = React.useCallback(() => {
2725
setCameraVisible(false);
@@ -72,7 +70,7 @@ export const TodoItemWidget: React.FC<TodoItemWidgetProps> = (props) => {
7270
iconType="material-community"
7371
checkedIcon="checkbox-marked"
7472
uncheckedIcon="checkbox-blank-outline"
75-
checked={record.completed}
73+
checked={!!record.completed}
7674
onPress={async () => {
7775
setLoading(true);
7876
await onToggleCompletion(!record.completed);
@@ -97,9 +95,9 @@ export const TodoItemWidget: React.FC<TodoItemWidgetProps> = (props) => {
9795
}}>
9896
{/* <Icon name={'camera'} type="material" color={'black'} size={32} /> */}
9997
</Button>
100-
) : photoAttachment?.local_uri != null ? (
98+
) : photoAttachment?.localUri != null ? (
10199
<Image
102-
source={{ uri: system.attachmentQueue?.getLocalUri(photoAttachment.local_uri) }}
100+
source={{ uri: photoAttachment.localUri }}
103101
containerStyle={styles.item}
104102
PlaceholderContent={<ActivityIndicator />}
105103
/>

0 commit comments

Comments
 (0)