Skip to content

Commit bc5a4de

Browse files
committed
Initialize camera on-demand.
1 parent 6e0a068 commit bc5a4de

File tree

5 files changed

+60
-37
lines changed

5 files changed

+60
-37
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import 'package:camera/camera.dart';
22
import 'package:flutter/widgets.dart';
33
import 'package:powersync_flutter_demo/powersync.dart';
44

5-
late final CameraDescription? camera;
6-
75
Future<CameraDescription?> setupCamera() async {
86
// Ensure that plugin services are initialized so that `availableCameras()`
97
// can be called before `runApp()`

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ import 'dart:async';
33
import 'package:camera/camera.dart';
44
import 'package:flutter/material.dart';
55
import 'package:powersync/powersync.dart' as powersync;
6-
import 'package:powersync_flutter_demo/attachments/camera_helpers.dart';
76
import 'package:powersync_flutter_demo/attachments/queue.dart';
87
import 'package:powersync_flutter_demo/models/todo_item.dart';
98
import 'package:powersync_flutter_demo/powersync.dart';
109

1110
class TakePhotoWidget extends StatefulWidget {
1211
final String todoId;
12+
final CameraDescription camera;
1313

14-
const TakePhotoWidget({super.key, required this.todoId});
14+
const TakePhotoWidget(
15+
{super.key, required this.todoId, required this.camera});
1516

1617
@override
1718
State<StatefulWidget> createState() {
@@ -28,7 +29,7 @@ class _TakePhotoWidgetState extends State<TakePhotoWidget> {
2829
super.initState();
2930

3031
_cameraController = CameraController(
31-
camera!,
32+
widget.camera,
3233
ResolutionPreset.medium,
3334
);
3435

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import 'dart:io';
22

3+
import 'package:camera/camera.dart';
34
import 'package:flutter/material.dart';
5+
import 'package:powersync_flutter_demo/attachments/camera_helpers.dart';
46
import 'package:powersync_flutter_demo/attachments/photo_capture_widget.dart';
57
import 'package:powersync_flutter_demo/attachments/queue.dart';
68

@@ -19,31 +21,61 @@ class PhotoWidget extends StatefulWidget {
1921
}
2022
}
2123

24+
class _ResolvedPhotoState {
25+
String? photoPath;
26+
bool fileExists;
27+
CameraDescription? camera;
28+
29+
_ResolvedPhotoState(
30+
{required this.photoPath,
31+
required this.fileExists,
32+
required this.camera});
33+
}
34+
2235
class _PhotoWidgetState extends State<PhotoWidget> {
2336
late String photoPath;
2437

25-
Future<Map<String, dynamic>> _getPhoto(photoId) async {
38+
Future<_ResolvedPhotoState> _getPhotoState(photoId) async {
39+
final camera = await setupCamera();
2640
if (photoId == null) {
27-
return {"photoPath": null, "fileExists": false};
41+
return _ResolvedPhotoState(
42+
photoPath: null, fileExists: false, camera: camera);
2843
}
2944
photoPath = await attachmentQueue.getLocalUri('$photoId.jpg');
3045

3146
bool fileExists = await File(photoPath).exists();
3247

33-
return {"photoPath": photoPath, "fileExists": fileExists};
48+
return _ResolvedPhotoState(
49+
photoPath: null, fileExists: fileExists, camera: camera);
3450
}
3551

3652
@override
3753
Widget build(BuildContext context) {
3854
return FutureBuilder(
39-
future: _getPhoto(widget.todo.photoId),
40-
builder: (BuildContext context, AsyncSnapshot snapshot) {
55+
future: _getPhotoState(widget.todo.photoId),
56+
builder: (BuildContext context,
57+
AsyncSnapshot<_ResolvedPhotoState> snapshot) {
58+
if (snapshot.data == null) {
59+
return Container();
60+
}
61+
final data = snapshot.data!;
4162
Widget takePhotoButton = ElevatedButton(
4263
onPressed: () {
64+
if (data.camera == null) {
65+
const snackBar = SnackBar(
66+
content: Text('No camera available'),
67+
backgroundColor:
68+
Colors.red, // Optional: to highlight it's an error
69+
);
70+
71+
ScaffoldMessenger.of(context).showSnackBar(snackBar);
72+
return;
73+
}
4374
Navigator.push(
4475
context,
4576
MaterialPageRoute(
46-
builder: (context) => TakePhotoWidget(todoId: widget.todo.id),
77+
builder: (context) => TakePhotoWidget(
78+
todoId: widget.todo.id, camera: data.camera!),
4779
),
4880
);
4981
},
@@ -54,29 +86,25 @@ class _PhotoWidgetState extends State<PhotoWidget> {
5486
return takePhotoButton;
5587
}
5688

57-
if (snapshot.hasData) {
58-
String filePath = snapshot.data['photoPath'];
59-
bool fileIsDownloading = !snapshot.data['fileExists'];
60-
61-
if (fileIsDownloading) {
62-
return const Text("Downloading...");
63-
}
64-
65-
File imageFile = File(filePath);
66-
int lastModified = imageFile.existsSync()
67-
? imageFile.lastModifiedSync().millisecondsSinceEpoch
68-
: 0;
69-
Key key = ObjectKey('$filePath:$lastModified');
70-
71-
return Image.file(
72-
key: key,
73-
imageFile,
74-
width: 50,
75-
height: 50,
76-
);
89+
String? filePath = data.photoPath;
90+
bool fileIsDownloading = data.fileExists;
91+
92+
if (fileIsDownloading) {
93+
return const Text("Downloading...");
7794
}
7895

79-
return takePhotoButton;
96+
File imageFile = File(filePath!);
97+
int lastModified = imageFile.existsSync()
98+
? imageFile.lastModifiedSync().millisecondsSinceEpoch
99+
: 0;
100+
Key key = ObjectKey('$filePath:$lastModified');
101+
102+
return Image.file(
103+
key: key,
104+
imageFile,
105+
width: 50,
106+
height: 50,
107+
);
80108
});
81109
}
82110
}

demos/supabase-todolist/lib/main.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import 'package:flutter/foundation.dart';
22
import 'package:flutter/material.dart';
33
import 'package:logging/logging.dart';
44
import 'package:powersync_flutter_demo/app_config.dart';
5-
import 'package:powersync_flutter_demo/attachments/camera_helpers.dart';
65
import 'package:powersync_flutter_demo/attachments/queue.dart';
76
import 'package:powersync_flutter_demo/models/schema.dart';
87

@@ -38,8 +37,6 @@ void main() async {
3837
initializeAttachmentQueue(db);
3938
}
4039

41-
camera = await setupCamera();
42-
4340
final loggedIn = isLoggedIn();
4441
runApp(MyApp(loggedIn: loggedIn));
4542
}

demos/supabase-todolist/lib/widgets/todo_item_widget.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import 'package:flutter/material.dart';
22
import 'package:powersync_flutter_demo/app_config.dart';
3-
import 'package:powersync_flutter_demo/attachments/camera_helpers.dart';
43
import 'package:powersync_flutter_demo/attachments/photo_widget.dart';
54
import 'package:powersync_flutter_demo/attachments/queue.dart';
65

@@ -54,7 +53,7 @@ class TodoItemWidget extends StatelessWidget {
5453
onPressed: () async => await deleteTodo(todo),
5554
tooltip: 'Delete Item',
5655
),
57-
AppConfig.supabaseStorageBucket.isEmpty || camera == null
56+
AppConfig.supabaseStorageBucket.isEmpty
5857
? Container()
5958
: PhotoWidget(todo: todo),
6059
],

0 commit comments

Comments
 (0)