diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 4e9e3ee..f62872f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -32,6 +32,8 @@
android:value="2" />
+
+
+
+
diff --git a/lib/main.dart b/lib/main.dart
index 4e7b749..f358034 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,4 +1,3 @@
-import 'package:camera/camera.dart';
import 'package:twonly/src/providers/api_provider.dart';
import 'package:twonly/src/providers/db_provider.dart';
import 'package:flutter/material.dart';
@@ -30,8 +29,6 @@ void main() async {
'${record.level.name}: twonly:${record.loggerName}: ${record.message}');
});
- var cameras = await availableCameras();
-
// Create or open the database
dbProvider = DbProvider();
await dbProvider.ready;
@@ -54,5 +51,5 @@ void main() async {
// Run the app and pass in the SettingsController. The app listens to the
// SettingsController for changes, then passes it further down to the
// SettingsView.
- runApp(MyApp(settingsController: settingsController, cameras: cameras));
+ runApp(MyApp(settingsController: settingsController));
}
diff --git a/lib/src/app.dart b/lib/src/app.dart
index 128b4ae..1bdab9a 100644
--- a/lib/src/app.dart
+++ b/lib/src/app.dart
@@ -1,4 +1,3 @@
-import 'package:camera/camera.dart';
import 'package:twonly/main.dart';
import 'views/home_view.dart';
import 'views/register_view.dart';
@@ -11,11 +10,9 @@ import 'settings/settings_controller.dart';
/// The Widget that configures your application.
class MyApp extends StatefulWidget {
- const MyApp(
- {super.key, required this.settingsController, required this.cameras});
+ const MyApp({super.key, required this.settingsController});
final SettingsController settingsController;
- final List cameras;
@override
State createState() => _MyAppState();
@@ -106,8 +103,7 @@ class _MyAppState extends State {
if (snapshot.hasData) {
return snapshot.data!
? HomeView(
- settingsController: widget.settingsController,
- cameras: widget.cameras)
+ settingsController: widget.settingsController)
: RegisterView(
callbackOnSuccess: () {
_isUserCreated = isUserCreated();
@@ -132,16 +128,6 @@ class _MyAppState extends State {
borderRadius: BorderRadius.all(
Radius.circular(10.0)), // Rounded top corners
),
- // child: Padding(
- // padding: const EdgeInsets.all(
- // 8.0), // Padding around the child
- // child: Center(
- // child: Text(
- // 'Not Connected',
- // style: TextStyle(fontSize: 24),
- // ),
- // ),
- // ),
),
),
],
diff --git a/lib/src/model/contacts_model.dart b/lib/src/model/contacts_model.dart
new file mode 100644
index 0000000..440ffff
--- /dev/null
+++ b/lib/src/model/contacts_model.dart
@@ -0,0 +1,50 @@
+import 'dart:typed_data';
+
+import 'package:cv/cv.dart';
+import 'package:twonly/main.dart';
+
+class Contact {
+ Contact({required this.userId, required this.displayName});
+ final Uint8List userId;
+ final String displayName;
+}
+
+class DbContacts extends CvModelBase {
+ static const tableName = "contacts";
+
+ static const columnUserId = "contact_user_id";
+ final userId = CvField(columnUserId);
+
+ static const columnDisplayName = "display_name";
+ final displayName = CvField(columnDisplayName);
+
+ static const columnCreatedAt = "created_at";
+ final createdAt = CvField(columnCreatedAt);
+
+ static String getCreateTableString() {
+ return """
+ CREATE TABLE $tableName (
+ $columnUserId BINARY(16) NOT NULL PRIMARY KEY,
+ $columnDisplayName TEXT,
+ $columnCreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
+ )
+ """;
+ }
+
+ static Future> getUsers() async {
+ var users = await dbProvider.db!.query(tableName,
+ columns: [columnUserId, columnDisplayName, columnCreatedAt]);
+ if (users.isEmpty) return [];
+
+ List parsedUsers = [];
+ for (int i = 0; i < users.length; i++) {
+ parsedUsers.add(Contact(
+ userId: users.cast()[i][columnUserId],
+ displayName: users.cast()[i][columnDisplayName]));
+ }
+ return parsedUsers;
+ }
+
+ @override
+ List get fields => [userId, createdAt];
+}
diff --git a/lib/src/providers/api_provider.dart b/lib/src/providers/api_provider.dart
index 1f3ae1f..b8874da 100644
--- a/lib/src/providers/api_provider.dart
+++ b/lib/src/providers/api_provider.dart
@@ -9,7 +9,6 @@ import 'package:twonly/src/proto/api/client_to_server.pb.dart' as client;
import 'package:twonly/src/proto/api/client_to_server.pbserver.dart';
import 'package:twonly/src/proto/api/error.pb.dart';
import 'package:twonly/src/proto/api/server_to_client.pb.dart' as server;
-import 'package:twonly/src/proto/api/server_to_client.pbserver.dart';
import 'package:twonly/src/signal/signal_helper.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:twonly/src/utils.dart';
diff --git a/lib/src/providers/db_provider.dart b/lib/src/providers/db_provider.dart
index 12f971d..8a3e068 100644
--- a/lib/src/providers/db_provider.dart
+++ b/lib/src/providers/db_provider.dart
@@ -1,7 +1,6 @@
import 'dart:async';
-import 'dart:io';
import 'dart:math';
-import 'package:logging/logging.dart';
+import 'package:twonly/src/model/contacts_model.dart';
import 'package:twonly/src/model/identity_key_store_model.dart';
import 'package:twonly/src/model/model_constants.dart';
import 'package:twonly/src/model/pre_key_model.dart';
@@ -67,6 +66,8 @@ class DbProvider {
await db
.execute('DROP TABLE If EXISTS ${DbSignalIdentityKeyStore.tableName}');
await db.execute(DbSignalIdentityKeyStore.getCreateTableString());
+ await db.execute('DROP TABLE If EXISTS ${DbContacts.tableName}');
+ await db.execute(DbContacts.getCreateTableString());
}
Future open() async {
@@ -74,7 +75,8 @@ class DbProvider {
}
Future remove() async {
- await _createDb(db!);
+ await deleteDatabase(await fixPath(dbName));
+ // await _createDb(db!);
}
Future fixPath(String path) async => path;
@@ -82,8 +84,4 @@ class DbProvider {
Future close() async {
await db!.close();
}
-
- // Future deleteDb() async {
- // await deleteDatabase(await fixPath(dbName));
- // }
}
diff --git a/lib/src/signal/signal_helper.dart b/lib/src/signal/signal_helper.dart
index 7f8ccf3..a527040 100644
--- a/lib/src/signal/signal_helper.dart
+++ b/lib/src/signal/signal_helper.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:typed_data';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
+import 'package:logging/logging.dart';
import 'package:twonly/src/model/signal_identity_json.dart';
import 'package:twonly/src/proto/api/server_to_client.pb.dart';
import 'package:twonly/src/utils.dart';
@@ -170,9 +171,13 @@ class SignalHelper {
tempIdentityKey,
);
- await sessionBuilder.processPreKeyBundle(preKeyBundle);
-
- return true;
+ try {
+ await sessionBuilder.processPreKeyBundle(preKeyBundle);
+ return true;
+ } catch (e) {
+ Logger("signal_helper").shout("Error: $e");
+ return false;
+ }
}
static Future getSignalStore() async {
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index e0a4976..95a66bb 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -1,12 +1,10 @@
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
-import 'dart:ui';
-import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
-import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:logging/logging.dart';
import 'package:twonly/main.dart';
+import 'package:twonly/src/model/contacts_model.dart';
import 'package:twonly/src/signal/signal_helper.dart';
import 'package:twonly/src/providers/api_provider.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
@@ -88,18 +86,12 @@ Future addNewUser(String username) async {
print(res.value);
print(res.value.userdata.userId);
- await SignalHelper.addNewContact(res.value.userdata);
-
- // final Map req = {};
- // req['identityKey'] =
- // (await signalStore.getIdentityKeyPair()).getPublicKey().serialize();
-
- // req['signedPreKey'] = {
- // 'id': signedPreKey.id,
- // 'signature': signedPreKey.signature,
- // 'key': signedPreKey.getKeyPair().publicKey.serialize(),
- // };
-
+ if (await SignalHelper.addNewContact(res.value.userdata)) {
+ await dbProvider.db!.insert(DbContacts.tableName, {
+ DbContacts.columnDisplayName: username,
+ DbContacts.columnUserId: res.value.userdata.userId
+ });
+ }
print("Add new user: ${res}");
}
diff --git a/lib/src/views/_new_camera_preview_view.dart b/lib/src/views/_new_camera_preview_view.dart
deleted file mode 100644
index 75ca240..0000000
--- a/lib/src/views/_new_camera_preview_view.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// import 'package:camera/camera.dart';
-// import 'camera_editor_view.dart';
-// import 'package:flutter/gestures.dart';
-import 'package:flutter/material.dart';
-import 'package:camerawesome/camerawesome_plugin.dart';
-
-class CameraPreviewView extends StatelessWidget {
- const CameraPreviewView({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const MaterialApp(
- title: 'Custom CamerAwesome UI',
- home: CameraPage(),
- );
- }
-}
-
-class CameraPage extends StatelessWidget {
- const CameraPage({super.key});
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: CameraAwesomeBuilder.awesome(
- saveConfig: SaveConfig.photo(),
- sensorConfig: SensorConfig.single(
- sensor: Sensor.position(SensorPosition.back),
- aspectRatio: CameraAspectRatios.ratio_1_1,
- ),
- previewFit: CameraPreviewFit.contain,
- previewPadding: const EdgeInsets.only(left: 150, top: 100),
- previewAlignment: Alignment.topRight,
- // Buttons of CamerAwesome UI will use this theme
- theme: AwesomeTheme(
- bottomActionsBackgroundColor: Colors.cyan.withAlpha(150),
- buttonTheme: AwesomeButtonTheme(
- backgroundColor: Colors.cyan.withAlpha(150),
- iconSize: 20,
- foregroundColor: Colors.white,
- padding: const EdgeInsets.all(16),
- // Tap visual feedback (ripple, bounce...)
- buttonBuilder: (child, onTap) {
- return ClipOval(
- child: Material(
- color: Colors.transparent,
- shape: const CircleBorder(),
- child: InkWell(
- splashColor: Colors.cyan,
- highlightColor: Colors.cyan.withAlpha(150),
- onTap: onTap,
- child: child,
- ),
- ),
- );
- },
- ),
- ),
- topActionsBuilder: (state) => AwesomeTopActions(
- padding: EdgeInsets.zero,
- state: state,
- children: [
- Expanded(
- child: AwesomeFilterWidget(
- state: state,
- filterListPosition: FilterListPosition.aboveButton,
- filterListPadding: const EdgeInsets.only(top: 8),
- ),
- ),
- ],
- ),
- middleContentBuilder: (state) {
- return Column(
- children: [
- const Spacer(),
- Builder(builder: (context) {
- return Container(
- color: AwesomeThemeProvider.of(context)
- .theme
- .bottomActionsBackgroundColor,
- child: const Align(
- alignment: Alignment.bottomCenter,
- child: Padding(
- padding: EdgeInsets.only(bottom: 10, top: 10),
- child: Text(
- "Take your best shot!",
- style: TextStyle(
- color: Colors.white,
- fontWeight: FontWeight.bold,
- fontStyle: FontStyle.italic,
- ),
- ),
- ),
- ),
- );
- }),
- ],
- );
- },
- bottomActionsBuilder: (state) => AwesomeBottomActions(
- state: state,
- left: AwesomeFlashButton(
- state: state,
- ),
- right: AwesomeCameraSwitchButton(
- state: state,
- scale: 1.0,
- onSwitchTap: (state) {
- state.switchCameraSensor(
- aspectRatio: state.sensorConfig.aspectRatio,
- );
- },
- ),
- ),
- ),
- );
- }
-}
diff --git a/lib/src/views/camera_preview_view.dart b/lib/src/views/camera_preview_view.dart
index 3bd5fa2..75ca240 100644
--- a/lib/src/views/camera_preview_view.dart
+++ b/lib/src/views/camera_preview_view.dart
@@ -1,355 +1,118 @@
-import 'package:camera/camera.dart';
+// import 'package:camera/camera.dart';
+// import 'camera_editor_view.dart';
+// import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
-// import 'package:camerawesome/camerawesome_plugin.dart';
-import 'dart:math';
+import 'package:camerawesome/camerawesome_plugin.dart';
-class CameraPreviewView extends StatefulWidget {
- const CameraPreviewView({
- super.key,
- required this.cameras,
- });
-
- final List cameras;
- static const routeName = '/camera_preview';
-
- @override
- CameraPreviewViewState createState() => CameraPreviewViewState();
-}
-
-class CameraPreviewViewState extends State {
- late CameraController _controller;
- late Future _initializeControllerFuture;
-
- int _selectedCameraIdx = 0;
-
- double _baseScaleFactor = 1.0;
- double _basePanY = 0.0;
- double _scaleFactor = 1;
- double _minimumScaleFactor = 1;
-
- @override
- void initState() {
- super.initState();
- // To display the current output from the Camera,
- // create a CameraController.
-
- // _controller = CameraController(
- // // Get a specific camera from the list of available cameras.
- // widget.cameras.first,
- // // Define the resolution to use.
- // ResolutionPreset.max,
- // );
-
- // _controller.initialize().then((_) {
- // _controller.value = _controller.value.copyWith(previewSize: size);
- // setState(() {});
- // });
-
- // Next, initialize the controller. This returns a Future.
- // _initializeControllerFuture = _controller.initialize();
- }
-
- Future updateController() async {
- await _controller.setDescription(widget.cameras[_selectedCameraIdx]);
- }
-
- @override
- void dispose() {
- // Dispose of the controller when the widget is disposed.
- // _controller.dispose();
- super.dispose();
- }
-
- // function for cropping image
- Future takePicture() async {
- try {
- await _initializeControllerFuture;
- // final image = await _controller.takePicture();
-
- if (!context.mounted) return;
- // await Navigator.of(context).push(
- // MaterialPageRoute(
- // builder: (context) => CameraEditorView(
- // imagePath: image.path,
- // ),
- // ),
- // );
- } catch (e) {
- // If an error occurs, log the error to the console.
- print(e);
- }
- }
-
- List getImageSize(double height, double width) {
- // https://github.com/flutter/flutter/issues/15953#issuecomment-855182376
-
- final screenH = max(height, width);
- final screenW = min(height, width);
-
- var ratioContainer = screenH / screenW;
-
- var tmp = _controller.value.previewSize!;
- final previewH = max(tmp.height, tmp.width);
- final previewW = min(tmp.height, tmp.width);
-
- var ratio = previewH / previewW;
- var missing = ratioContainer - ratio;
-
- final maxHeight = screenH;
- final maxWidth = screenH * 0.5625;
-
- _minimumScaleFactor = 1 + missing;
-
- return [maxHeight, maxWidth];
- }
-
- Future updateScaleFactor(double newScale) async {
- var minFactor = await _controller.getMinZoomLevel();
- var maxFactor = await _controller.getMaxZoomLevel();
- if (newScale < minFactor) {
- newScale = minFactor;
- }
- if (newScale > maxFactor) {
- newScale = maxFactor;
- }
-
- print(newScale);
- if (newScale <= 1) {
- await _controller.setZoomLevel(newScale);
- } else {
- //await _controller.setZoomLevel(1.0);
- }
- setState(() {
- _scaleFactor = newScale;
- });
- }
+class CameraPreviewView extends StatelessWidget {
+ const CameraPreviewView({super.key});
@override
Widget build(BuildContext context) {
- return Container();
- var isFront = widget.cameras[_selectedCameraIdx].lensDirection ==
- CameraLensDirection.front;
- // Fill this out in the next steps.
- // You must wait until the controller is initialized before displaying the
- // camera preview. Use a FutureBuilder to display a loading spinner until the
- // controller has finished initializing.
- return Scaffold(
- body: GestureDetector(
- onPanStart: (details) async {
- if (_scaleFactor <= 1) {
- await updateScaleFactor(1);
- }
- setState(() {
- _basePanY = details.localPosition.dy;
- _baseScaleFactor = _scaleFactor;
- });
- },
- onPanUpdate: (details) async {
- final diff = details.localPosition.dy - _basePanY;
- final updateScale = diff / 50;
- var tmp = _baseScaleFactor - updateScale;
- if (tmp <= 1) tmp = 1.00001;
- updateScaleFactor(tmp);
- },
- // onScaleStart: (details) {
- // _baseScaleFactor = _scaleFactor;
- // },
- // onScaleUpdate: (details) async {
- // // print(scale.scale);
- // var scaleFactor =
- // ((_baseScaleFactor * details.scale * 10).round() / 10);
- // var maxFactor = await _controller.getMaxZoomLevel();
- // if (scaleFactor > maxFactor) scaleFactor = maxFactor;
- // if (scaleFactor != _scaleFactor) {
- // await updateScaleFactor(scaleFactor);
- // }
- // },
- onTap: () {},
- onDoubleTap: () {
- setState(() {
- _selectedCameraIdx = (_selectedCameraIdx + 1) % 2;
- updateController();
- });
- },
- child: Padding(
- padding: const EdgeInsets.only(top: 60, bottom: 40),
- child: ClipRRect(
- borderRadius: BorderRadius.circular(22),
- child: FutureBuilder(
- future: _initializeControllerFuture,
- builder: (context, snapshot) {
- if (snapshot.connectionState != ConnectionState.done) {
- return const Center(child: CircularProgressIndicator());
- }
- return Stack(
- alignment: Alignment.bottomCenter,
- children: [
- LayoutBuilder(
- builder:
- (BuildContext context, BoxConstraints constraints) {
- var height = constraints.maxHeight;
- var width = constraints.maxWidth;
+ return const MaterialApp(
+ title: 'Custom CamerAwesome UI',
+ home: CameraPage(),
+ );
+ }
+}
- return OverflowBox(
- maxHeight: getImageSize(height, width)[0],
- maxWidth: getImageSize(height, width)[1],
- child: Transform(
- alignment: Alignment.center,
- transform: Matrix4.rotationY(isFront ? pi : 0),
- child: Transform.scale(
- scale: _minimumScaleFactor +
- (_scaleFactor > 1 ? _scaleFactor : 1) -
- 1,
- child: CameraPreview(_controller)),
- ),
- );
- },
- ),
- Positioned(
- bottom: 50,
- child: Column(
- children: [
- CameraZoomButtons(
- key: widget.key,
- isFront: isFront,
- scaleFactor: _scaleFactor,
- updateScaleFactor: updateScaleFactor,
- controller: _controller,
- ),
- SizedBox(height: 10),
- GestureDetector(
- onTap: () async {
- await takePicture();
- },
- onLongPress: () async {},
- child: Container(
- height: 100,
- width: 100,
- clipBehavior: Clip.antiAliasWithSaveLayer,
- padding: const EdgeInsets.all(2),
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- border: Border.all(
- width: 7,
- color: Colors.white,
- ),
- ),
- ),
- ),
- ],
+class CameraPage extends StatelessWidget {
+ const CameraPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: CameraAwesomeBuilder.awesome(
+ saveConfig: SaveConfig.photo(),
+ sensorConfig: SensorConfig.single(
+ sensor: Sensor.position(SensorPosition.back),
+ aspectRatio: CameraAspectRatios.ratio_1_1,
+ ),
+ previewFit: CameraPreviewFit.contain,
+ previewPadding: const EdgeInsets.only(left: 150, top: 100),
+ previewAlignment: Alignment.topRight,
+ // Buttons of CamerAwesome UI will use this theme
+ theme: AwesomeTheme(
+ bottomActionsBackgroundColor: Colors.cyan.withAlpha(150),
+ buttonTheme: AwesomeButtonTheme(
+ backgroundColor: Colors.cyan.withAlpha(150),
+ iconSize: 20,
+ foregroundColor: Colors.white,
+ padding: const EdgeInsets.all(16),
+ // Tap visual feedback (ripple, bounce...)
+ buttonBuilder: (child, onTap) {
+ return ClipOval(
+ child: Material(
+ color: Colors.transparent,
+ shape: const CircleBorder(),
+ child: InkWell(
+ splashColor: Colors.cyan,
+ highlightColor: Colors.cyan.withAlpha(150),
+ onTap: onTap,
+ child: child,
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ topActionsBuilder: (state) => AwesomeTopActions(
+ padding: EdgeInsets.zero,
+ state: state,
+ children: [
+ Expanded(
+ child: AwesomeFilterWidget(
+ state: state,
+ filterListPosition: FilterListPosition.aboveButton,
+ filterListPadding: const EdgeInsets.only(top: 8),
+ ),
+ ),
+ ],
+ ),
+ middleContentBuilder: (state) {
+ return Column(
+ children: [
+ const Spacer(),
+ Builder(builder: (context) {
+ return Container(
+ color: AwesomeThemeProvider.of(context)
+ .theme
+ .bottomActionsBackgroundColor,
+ child: const Align(
+ alignment: Alignment.bottomCenter,
+ child: Padding(
+ padding: EdgeInsets.only(bottom: 10, top: 10),
+ child: Text(
+ "Take your best shot!",
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontStyle: FontStyle.italic,
+ ),
),
),
- ],
+ ),
);
- },
- ),
+ }),
+ ],
+ );
+ },
+ bottomActionsBuilder: (state) => AwesomeBottomActions(
+ state: state,
+ left: AwesomeFlashButton(
+ state: state,
+ ),
+ right: AwesomeCameraSwitchButton(
+ state: state,
+ scale: 1.0,
+ onSwitchTap: (state) {
+ state.switchCameraSensor(
+ aspectRatio: state.sensorConfig.aspectRatio,
+ );
+ },
),
),
),
);
}
}
-
-class CameraZoomButtons extends StatefulWidget {
- const CameraZoomButtons(
- {super.key,
- required this.isFront,
- required this.controller,
- required this.updateScaleFactor,
- required this.scaleFactor});
-
- final bool isFront;
- final CameraController controller;
- final double scaleFactor;
- final Function updateScaleFactor;
-
- @override
- State createState() => _CameraZoomButtonsState();
-}
-
-String beautifulZoomScale(double scale) {
- var tmp = scale.toStringAsFixed(1);
- if (tmp[0] == "0") {
- tmp = tmp.substring(1, tmp.length);
- }
- return tmp;
-}
-
-class _CameraZoomButtonsState extends State {
- @override
- Widget build(BuildContext context) {
- final zoomButtonStyle = TextButton.styleFrom(
- padding: EdgeInsets.zero,
- foregroundColor: Colors.white,
- minimumSize: Size(40, 40),
- alignment: Alignment.center,
- tapTargetSize: MaterialTapTargetSize.shrinkWrap);
-
- final zoomTextStyle = TextStyle(fontSize: 13);
- return ClipRRect(
- borderRadius: BorderRadius.circular(40.0),
- child: Container(
- color: const Color.fromARGB(90, 0, 0, 0),
- child: Row(
- children: widget.isFront
- ? []
- : [
- TextButton(
- style: zoomButtonStyle,
- onPressed: () async {
- var level = await widget.controller.getMinZoomLevel();
- widget.updateScaleFactor(level);
- },
- child: FutureBuilder(
- future: widget.controller.getMinZoomLevel(),
- builder: (context, snap) {
- if (snap.hasData) {
- var minLevel =
- beautifulZoomScale(snap.data!.toDouble());
- var currentLevel =
- beautifulZoomScale(widget.scaleFactor);
- return Text(
- widget.scaleFactor < 1
- ? "${currentLevel}x"
- : "${minLevel}x",
- style: zoomTextStyle,
- );
- } else {
- return Text("");
- }
- }),
- ),
- TextButton(
- style: zoomButtonStyle,
- onPressed: () {
- widget.updateScaleFactor(1.0);
- },
- child: Text(
- widget.scaleFactor >= 1
- ? "${beautifulZoomScale(widget.scaleFactor)}x"
- : "1.0x",
- style: zoomTextStyle,
- )),
- TextButton(
- style: zoomButtonStyle,
- onPressed: () async {
- var level = await widget.controller.getMaxZoomLevel();
- widget.updateScaleFactor(level);
- },
- child: FutureBuilder(
- future: widget.controller.getMaxZoomLevel(),
- builder: (context, snap) {
- if (snap.hasData) {
- var maxLevel = snap.data?.toInt();
- return Text("${maxLevel}x", style: zoomTextStyle);
- } else {
- return Text("");
- }
- }),
- )
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/src/views/home_view.dart b/lib/src/views/home_view.dart
index 1c1fa69..84691d6 100644
--- a/lib/src/views/home_view.dart
+++ b/lib/src/views/home_view.dart
@@ -1,4 +1,3 @@
-import 'package:camera/camera.dart';
import 'camera_preview_view.dart';
import 'chat_list_view.dart';
import 'permissions_view.dart';
@@ -7,10 +6,8 @@ import '../settings/settings_controller.dart';
import 'package:flutter/material.dart';
class HomeView extends StatefulWidget {
- const HomeView(
- {super.key, required this.settingsController, required this.cameras});
+ const HomeView({super.key, required this.settingsController});
final SettingsController settingsController;
- final List cameras;
@override
State createState() => HomeViewState();
@@ -36,7 +33,7 @@ class HomeViewState extends State {
},
children: [
ChatListView(),
- CameraPreviewView(cameras: widget.cameras),
+ CameraPreviewView(),
ProfileView(settingsController: widget.settingsController)
],
),
diff --git a/lib/src/views/new_message_view.dart b/lib/src/views/new_message_view.dart
index 01c6d44..3f3292f 100644
--- a/lib/src/views/new_message_view.dart
+++ b/lib/src/views/new_message_view.dart
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:twonly/src/model/contacts_model.dart';
import 'package:twonly/src/utils.dart';
+import 'package:twonly/src/views/search_username_view.dart';
class NewMessageView extends StatefulWidget {
const NewMessageView({super.key});
@@ -10,49 +12,42 @@ class NewMessageView extends StatefulWidget {
}
class _NewMessageView extends State {
- final List _known_users = [
- "Alisa",
- "Klaus",
- "John",
- "Emma",
- "Michael",
- "Sophia",
- "James",
- "Olivia",
- "Liam",
- "Ava",
- "Noah",
- "Isabella",
- "Lucas",
- "Mia",
- "Ethan",
- "Charlotte",
- ];
- List _filteredUsers = [];
+ List _knownUsers = [];
+ List _filteredUsers = [];
String _lastSearchQuery = '';
final TextEditingController searchUserName = TextEditingController();
@override
void initState() {
super.initState();
- // Initialize the filtered users with all known users
- _filteredUsers = List.from(_known_users);
+ _loadUsers();
+ }
+
+ Future _loadUsers() async {
+ final users = await DbContacts.getUsers();
+ setState(() {
+ _knownUsers = users;
+ _filteredUsers = List.from(_knownUsers);
+ });
}
Future _filterUsers(String query) async {
if (query.isEmpty) {
- _filteredUsers = List.from(_known_users);
+ _filteredUsers = List.from(_knownUsers);
return;
}
if (_lastSearchQuery.length < query.length) {
- _filteredUsers = _known_users
- .where((user) => user.toLowerCase().contains(query.toLowerCase()))
+ _filteredUsers = _knownUsers
+ .where((user) =>
+ user.displayName.toLowerCase().contains(query.toLowerCase()))
.toList();
} else {
_filteredUsers = _filteredUsers
- .where((user) => user.toLowerCase().contains(query.toLowerCase()))
+ .where((user) =>
+ user.displayName.toLowerCase().contains(query.toLowerCase()))
.toList();
}
+ _lastSearchQuery = query;
}
@override
@@ -103,6 +98,11 @@ class _NewMessageView extends State {
FilledButton(
onPressed: () {
// Handle Nach Nutzername suchen button press
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(
+ builder: (context) => SearchUsernameView()),
+ );
},
child: Text('Nach Nutzername suchen'),
),
@@ -120,23 +120,22 @@ class _NewMessageView extends State {
}
class UserList extends StatelessWidget {
- final List _known_users;
-
- UserList(this._known_users);
+ const UserList(this._knownUsers, {super.key});
+ final List _knownUsers;
@override
Widget build(BuildContext context) {
// Step 1: Sort the users alphabetically
- _known_users.sort();
+ _knownUsers.sort((a, b) => a.displayName.compareTo(b.displayName));
// Step 2: Group users by their initials
Map> groupedUsers = {};
- for (var user in _known_users) {
- String initial = user[0].toUpperCase();
+ for (var user in _knownUsers) {
+ String initial = user.displayName[0].toUpperCase();
if (!groupedUsers.containsKey(initial)) {
groupedUsers[initial] = [];
}
- groupedUsers[initial]!.add(user);
+ groupedUsers[initial]!.add(user.displayName);
}
// Step 3: Create a list of sections
diff --git a/lib/src/views/permissions_view.dart b/lib/src/views/permissions_view.dart
index b45403d..2ca84f3 100644
--- a/lib/src/views/permissions_view.dart
+++ b/lib/src/views/permissions_view.dart
@@ -61,7 +61,7 @@ class PermissionHandlerViewState extends State {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- "Connect needs access to the camera and microphone for obvious reasons.",
+ "twonly needs access to the camera and microphone.",
textAlign: TextAlign.center,
),
SizedBox(height: 50),
diff --git a/pubspec.lock b/pubspec.lock
index 6273fab..612b9ad 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -126,46 +126,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.9.3"
- camera:
- dependency: "direct main"
- description:
- name: camera
- sha256: "26ff41045772153f222ffffecba711a206f670f5834d40ebf5eed3811692f167"
- url: "https://pub.dev"
- source: hosted
- version: "0.11.0+2"
- camera_android_camerax:
- dependency: transitive
- description:
- name: camera_android_camerax
- sha256: "7cc6adf1868bdcf4e63a56b24b41692dfbad2bec1cdceea451c77798f6a605c3"
- url: "https://pub.dev"
- source: hosted
- version: "0.6.13"
- camera_avfoundation:
- dependency: transitive
- description:
- name: camera_avfoundation
- sha256: "3f81ee3e88a79b0b010f0233d42625926299551b05d5dc995267a0b35bc33247"
- url: "https://pub.dev"
- source: hosted
- version: "0.9.18"
- camera_platform_interface:
- dependency: transitive
- description:
- name: camera_platform_interface
- sha256: "953e7baed3a7c8fae92f7200afeb2be503ff1a17c3b4e4ed7b76f008c2810a31"
- url: "https://pub.dev"
- source: hosted
- version: "2.9.0"
- camera_web:
- dependency: transitive
- description:
- name: camera_web
- sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f"
- url: "https://pub.dev"
- source: hosted
- version: "0.3.5"
camerawesome:
dependency: "direct main"
description:
@@ -368,14 +328,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
- flutter_plugin_android_lifecycle:
- dependency: transitive
- description:
- name: flutter_plugin_android_lifecycle
- sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
- url: "https://pub.dev"
- source: hosted
- version: "2.0.24"
flutter_secure_storage:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 90345b0..900994e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,7 +10,6 @@ environment:
sdk: ^3.5.4
dependencies:
- camera: ^0.11.0+2
camerawesome: ^2.1.0
collection: ^1.18.0
cv: ^1.1.3