Skip to content

Commit 6ab5154

Browse files
committed
Use path on native platforms
1 parent a60952e commit 6ab5154

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

demos/supabase-todolist/lib/attachments/photo_widget.dart

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import 'dart:io';
12
import 'dart:typed_data';
23

4+
import 'package:flutter/foundation.dart';
35
import 'package:flutter/material.dart';
46
import 'package:powersync_core/attachments/attachments.dart';
7+
import 'package:powersync_core/attachments/io.dart';
58
import 'package:powersync_flutter_demo/attachments/camera_helpers.dart';
69
import 'package:powersync_flutter_demo/attachments/photo_capture_widget.dart';
710

@@ -44,19 +47,38 @@ class PhotoWidget extends StatelessWidget {
4447
);
4548
}
4649

47-
return AttachmentImage(attachment: attachment);
50+
if (!data.fileExists) {
51+
return const Text('Downloading...');
52+
}
53+
54+
if (kIsWeb) {
55+
// We can't use Image.file on the web, so fall back to loading the
56+
// image from OPFS.
57+
return _WebAttachmentImage(attachment: attachment);
58+
} else {
59+
final path =
60+
(localStorage as IOLocalStorage).pathFor(attachment.filename);
61+
return Image.file(
62+
key: ValueKey(attachment),
63+
File(path),
64+
width: 50,
65+
height: 50,
66+
);
67+
}
4868
},
4969
);
5070
}
5171

5272
static Stream<_AttachmentState> _attachmentState(String? id) {
5373
return db.watch('SELECT * FROM attachments_queue WHERE id = ?',
54-
parameters: [id]).map((rows) {
74+
parameters: [id]).asyncMap((rows) async {
5575
if (rows.isEmpty) {
56-
return const _AttachmentState(null);
76+
return const _AttachmentState(null, false);
5777
}
5878

59-
return _AttachmentState(Attachment.fromRow(rows.single));
79+
final attachment = Attachment.fromRow(rows.single);
80+
final exists = await localStorage.fileExists(attachment.filename);
81+
return _AttachmentState(attachment, exists);
6082
});
6183
}
6284
}
@@ -98,25 +120,24 @@ class TakePhotoButton extends StatelessWidget {
98120

99121
final class _AttachmentState {
100122
final Attachment? attachment;
123+
final bool fileExists;
101124

102-
const _AttachmentState(this.attachment);
125+
const _AttachmentState(this.attachment, this.fileExists);
103126
}
104127

105-
/// A widget showing an [Attachment] as an image.
128+
/// A widget showing an [Attachment] as an image by loading it into memory.
106129
///
107-
/// For better web support, always loads the attachment into memory first. If
108-
/// you're only targeting native platforms, a more efficient mechanism would be
109-
/// to use `IOLocalStorage.pathFor` with an [Image.file] image.
110-
class AttachmentImage extends StatefulWidget {
130+
/// On native platforms, using a file path is more efficient.
131+
class _WebAttachmentImage extends StatefulWidget {
111132
final Attachment attachment;
112133

113-
const AttachmentImage({super.key, required this.attachment});
134+
const _WebAttachmentImage({required this.attachment});
114135

115136
@override
116-
State<AttachmentImage> createState() => _AttachmentImageState();
137+
State<_WebAttachmentImage> createState() => _AttachmentImageState();
117138
}
118139

119-
class _AttachmentImageState extends State<AttachmentImage> {
140+
class _AttachmentImageState extends State<_WebAttachmentImage> {
120141
Future<Uint8List?>? _imageBytes;
121142

122143
void _loadBytes() {
@@ -142,7 +163,7 @@ class _AttachmentImageState extends State<AttachmentImage> {
142163
}
143164

144165
@override
145-
void didUpdateWidget(covariant AttachmentImage oldWidget) {
166+
void didUpdateWidget(covariant _WebAttachmentImage oldWidget) {
146167
super.didUpdateWidget(oldWidget);
147168
if (oldWidget.attachment != widget.attachment) {
148169
_loadBytes();
@@ -154,16 +175,12 @@ class _AttachmentImageState extends State<AttachmentImage> {
154175
return FutureBuilder(
155176
future: _imageBytes,
156177
builder: (context, snapshot) {
157-
if (snapshot.connectionState == ConnectionState.done) {
158-
if (snapshot.data case final bytes?) {
159-
return Image.memory(
160-
bytes,
161-
width: 50,
162-
height: 50,
163-
);
164-
} else {
165-
return const Text('Downloading...');
166-
}
178+
if (snapshot.data case final bytes?) {
179+
return Image.memory(
180+
bytes,
181+
width: 50,
182+
height: 50,
183+
);
167184
} else {
168185
return Container();
169186
}

0 commit comments

Comments
 (0)