This commit is contained in:
otsmr 2025-11-04 14:00:21 +01:00
parent 2a3152e707
commit 57334d9eee
9 changed files with 207 additions and 34 deletions

View file

@ -1,5 +1,21 @@
package eu.twonly package eu.twonly
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import android.view.KeyEvent
import dev.darttools.flutter_android_volume_keydown.FlutterAndroidVolumeKeydownPlugin.eventSink
import android.view.KeyEvent.KEYCODE_VOLUME_DOWN
import android.view.KeyEvent.KEYCODE_VOLUME_UP
class MainActivity: FlutterFragmentActivity() class MainActivity : FlutterFragmentActivity() {
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KEYCODE_VOLUME_DOWN && eventSink != null) {
eventSink!!.success(true)
return true
}
if (keyCode == KEYCODE_VOLUME_UP && eventSink != null) {
eventSink!!.success(false)
return true
}
return super.onKeyDown(keyCode, event)
}
}

View file

@ -9,6 +9,8 @@ PODS:
- Flutter - Flutter
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- Flutter - Flutter
- emoji_picker_flutter (0.0.1):
- Flutter
- ffmpeg_kit_flutter_new (1.0.0): - ffmpeg_kit_flutter_new (1.0.0):
- ffmpeg_kit_flutter_new/full-gpl (= 1.0.0) - ffmpeg_kit_flutter_new/full-gpl (= 1.0.0)
- Flutter - Flutter
@ -82,6 +84,8 @@ PODS:
- flutter_secure_storage_darwin (10.0.0): - flutter_secure_storage_darwin (10.0.0):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- flutter_volume_controller (0.0.1):
- Flutter
- flutter_zxing (0.0.1): - flutter_zxing (0.0.1):
- Flutter - Flutter
- gal (1.0.0): - gal (1.0.0):
@ -248,6 +252,7 @@ DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- cryptography_flutter_plus (from `.symlinks/plugins/cryptography_flutter_plus/ios`) - cryptography_flutter_plus (from `.symlinks/plugins/cryptography_flutter_plus/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- emoji_picker_flutter (from `.symlinks/plugins/emoji_picker_flutter/ios`)
- ffmpeg_kit_flutter_new (from `.symlinks/plugins/ffmpeg_kit_flutter_new/ios`) - ffmpeg_kit_flutter_new (from `.symlinks/plugins/ffmpeg_kit_flutter_new/ios`)
- Firebase - Firebase
- firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
@ -260,6 +265,7 @@ DEPENDENCIES:
- flutter_keyboard_visibility_temp_fork (from `.symlinks/plugins/flutter_keyboard_visibility_temp_fork/ios`) - flutter_keyboard_visibility_temp_fork (from `.symlinks/plugins/flutter_keyboard_visibility_temp_fork/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_secure_storage_darwin (from `.symlinks/plugins/flutter_secure_storage_darwin/darwin`) - flutter_secure_storage_darwin (from `.symlinks/plugins/flutter_secure_storage_darwin/darwin`)
- flutter_volume_controller (from `.symlinks/plugins/flutter_volume_controller/ios`)
- flutter_zxing (from `.symlinks/plugins/flutter_zxing/ios`) - flutter_zxing (from `.symlinks/plugins/flutter_zxing/ios`)
- gal (from `.symlinks/plugins/gal/darwin`) - gal (from `.symlinks/plugins/gal/darwin`)
- GoogleUtilities - GoogleUtilities
@ -311,6 +317,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/cryptography_flutter_plus/ios" :path: ".symlinks/plugins/cryptography_flutter_plus/ios"
device_info_plus: device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios" :path: ".symlinks/plugins/device_info_plus/ios"
emoji_picker_flutter:
:path: ".symlinks/plugins/emoji_picker_flutter/ios"
ffmpeg_kit_flutter_new: ffmpeg_kit_flutter_new:
:path: ".symlinks/plugins/ffmpeg_kit_flutter_new/ios" :path: ".symlinks/plugins/ffmpeg_kit_flutter_new/ios"
firebase_core: firebase_core:
@ -327,6 +335,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_local_notifications/ios" :path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_secure_storage_darwin: flutter_secure_storage_darwin:
:path: ".symlinks/plugins/flutter_secure_storage_darwin/darwin" :path: ".symlinks/plugins/flutter_secure_storage_darwin/darwin"
flutter_volume_controller:
:path: ".symlinks/plugins/flutter_volume_controller/ios"
flutter_zxing: flutter_zxing:
:path: ".symlinks/plugins/flutter_zxing/ios" :path: ".symlinks/plugins/flutter_zxing/ios"
gal: gal:
@ -364,6 +374,7 @@ SPEC CHECKSUMS:
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
cryptography_flutter_plus: 44f4e9e4079395fcbb3e7809c0ac2c6ae2d9576f cryptography_flutter_plus: 44f4e9e4079395fcbb3e7809c0ac2c6ae2d9576f
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
emoji_picker_flutter: ece213fc274bdddefb77d502d33080dc54e616cc
ffmpeg_kit_flutter_new: 12426a19f10ac81186c67c6ebc4717f8f4364b7f ffmpeg_kit_flutter_new: 12426a19f10ac81186c67c6ebc4717f8f4364b7f
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
firebase_core: 744984dbbed8b3036abf34f0b98d80f130a7e464 firebase_core: 744984dbbed8b3036abf34f0b98d80f130a7e464
@ -378,6 +389,7 @@ SPEC CHECKSUMS:
flutter_keyboard_visibility_temp_fork: 95b2d534bacf6ac62e7fcbe5c2a9e2c2a17ce06f flutter_keyboard_visibility_temp_fork: 95b2d534bacf6ac62e7fcbe5c2a9e2c2a17ce06f
flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb
flutter_secure_storage_darwin: ce237a8775b39723566dc72571190a3769d70468 flutter_secure_storage_darwin: ce237a8775b39723566dc72571190a3769d70468
flutter_volume_controller: c2be490cb0487e8b88d0d9fc2b7e1c139a4ebccb
flutter_zxing: e8bcc43bd3056c70c271b732ed94e7a16fd62f93 flutter_zxing: e8bcc43bd3056c70c271b732ed94e7a16fd62f93
gal: baecd024ebfd13c441269ca7404792a7152fde89 gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1 GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1

View file

@ -32,7 +32,7 @@ Future<void> handleServerMessage(server.ServerToClient msg) async {
final ok = client.Response_Ok()..none = true; final ok = client.Response_Ok()..none = true;
var response = client.Response()..ok = ok; var response = client.Response()..ok = ok;
// try { try {
if (msg.v0.hasRequestNewPreKeys()) { if (msg.v0.hasRequestNewPreKeys()) {
response = await handleRequestNewPreKey(); response = await handleRequestNewPreKey();
} else if (msg.v0.hasNewMessage()) { } else if (msg.v0.hasNewMessage()) {
@ -42,9 +42,9 @@ Future<void> handleServerMessage(server.ServerToClient msg) async {
} else { } else {
Log.error('Unknown server message: $msg'); Log.error('Unknown server message: $msg');
} }
// } catch (e) { } catch (e) {
// Log.error(e); Log.error(e);
// } }
final v0 = client.V0() final v0 = client.V0()
..seq = msg.v0.seq ..seq = msg.v0.seq

View file

@ -3,6 +3,8 @@ import 'dart:io';
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_android_volume_keydown/flutter_android_volume_keydown.dart';
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -88,6 +90,7 @@ class CameraPreviewControllerView extends StatelessWidget {
required this.selectCamera, required this.selectCamera,
required this.selectedCameraDetails, required this.selectedCameraDetails,
required this.screenshotController, required this.screenshotController,
required this.isVisible,
super.key, super.key,
this.sendToGroup, this.sendToGroup,
}); });
@ -97,6 +100,7 @@ class CameraPreviewControllerView extends StatelessWidget {
final CameraController? cameraController; final CameraController? cameraController;
final SelectedCameraDetails selectedCameraDetails; final SelectedCameraDetails selectedCameraDetails;
final ScreenshotController screenshotController; final ScreenshotController screenshotController;
final bool isVisible;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -111,6 +115,7 @@ class CameraPreviewControllerView extends StatelessWidget {
cameraController: cameraController, cameraController: cameraController,
selectedCameraDetails: selectedCameraDetails, selectedCameraDetails: selectedCameraDetails,
screenshotController: screenshotController, screenshotController: screenshotController,
isVisible: isVisible,
); );
} else { } else {
return PermissionHandlerView( return PermissionHandlerView(
@ -133,6 +138,7 @@ class CameraPreviewView extends StatefulWidget {
required this.cameraController, required this.cameraController,
required this.selectedCameraDetails, required this.selectedCameraDetails,
required this.screenshotController, required this.screenshotController,
required this.isVisible,
super.key, super.key,
this.sendToGroup, this.sendToGroup,
}); });
@ -144,6 +150,7 @@ class CameraPreviewView extends StatefulWidget {
final CameraController? cameraController; final CameraController? cameraController;
final SelectedCameraDetails selectedCameraDetails; final SelectedCameraDetails selectedCameraDetails;
final ScreenshotController screenshotController; final ScreenshotController screenshotController;
final bool isVisible;
@override @override
State<CameraPreviewView> createState() => _CameraPreviewViewState(); State<CameraPreviewView> createState() => _CameraPreviewViewState();
@ -164,12 +171,71 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
final GlobalKey keyTriggerButton = GlobalKey(); final GlobalKey keyTriggerButton = GlobalKey();
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
StreamSubscription<HardwareButton>? androidVolumeDownSub;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
initVolumeControl();
initAsync(); initAsync();
} }
@override
void didUpdateWidget(covariant CameraPreviewView oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.isVisible != widget.isVisible) {
if (widget.isVisible) {
initVolumeControl();
} else {
deInitVolumeControl();
}
}
}
@override
void dispose() {
_videoRecordingTimer?.cancel();
deInitVolumeControl();
super.dispose();
}
Future<void> initVolumeControl() async {
if (Platform.isIOS) {
await FlutterVolumeController.updateShowSystemUI(false);
double? startedVolume;
FlutterVolumeController.addListener(
(volume) async {
if (startedVolume == null) {
startedVolume = volume;
return;
}
if (startedVolume == volume) {
return;
}
// reset the volume back to the original value
await FlutterVolumeController.setVolume(startedVolume!);
await takePicture();
},
);
}
if (Platform.isAndroid) {
androidVolumeDownSub = FlutterAndroidVolumeKeydown.stream.listen((event) {
takePicture();
});
}
}
Future<void> deInitVolumeControl() async {
if (Platform.isIOS) {
await FlutterVolumeController.updateShowSystemUI(true);
FlutterVolumeController.removeListener();
}
if (Platform.isAndroid) {
await androidVolumeDownSub?.cancel();
}
}
Future<void> initAsync() async { Future<void> initAsync() async {
_hasAudioPermission = await Permission.microphone.isGranted; _hasAudioPermission = await Permission.microphone.isGranted;
@ -184,12 +250,6 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
setState(() {}); setState(() {});
} }
@override
void dispose() {
_videoRecordingTimer?.cancel();
super.dispose();
}
Future<void> requestMicrophonePermission() async { Future<void> requestMicrophonePermission() async {
final statuses = await [ final statuses = await [
Permission.microphone, Permission.microphone,
@ -309,6 +369,9 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
// unawaited(mediaFileService.compressMedia()); // unawaited(mediaFileService.compressMedia());
} }
await deInitVolumeControl();
if (!mounted) return true;
final shouldReturn = await Navigator.push( final shouldReturn = await Navigator.push(
context, context,
PageRouteBuilder( PageRouteBuilder(
@ -333,11 +396,12 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
}); });
} }
if (!mounted) return true; if (!mounted) return true;
await initVolumeControl();
// shouldReturn is null when the user used the back button // shouldReturn is null when the user used the back button
if (shouldReturn != null && shouldReturn) { if (shouldReturn != null && shouldReturn) {
if (widget.sendToGroup == null) { if (widget.sendToGroup == null) {
globalUpdateOfHomeViewPageIndex(0); globalUpdateOfHomeViewPageIndex(0);
} else { } else if (mounted) {
Navigator.pop(context); Navigator.pop(context);
} }
return true; return true;

View file

@ -79,6 +79,7 @@ class CameraSendToViewState extends State<CameraSendToView> {
cameraController: cameraController, cameraController: cameraController,
selectedCameraDetails: selectedCameraDetails, selectedCameraDetails: selectedCameraDetails,
screenshotController: screenshotController, screenshotController: screenshotController,
isVisible: true,
), ),
], ],
), ),

View file

@ -473,6 +473,23 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
), ),
child: Row( child: Row(
children: [ children: [
Expanded(
child: Container(
color: Colors.grey,
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Theme.of(context).colorScheme.primary,
width: 2,
),
),
child: Row(
children: [
const FaIcon(FontAwesomeIcons.faceSmile),
Expanded( Expanded(
child: TextField( child: TextField(
controller: newMessageController, controller: newMessageController,
@ -487,7 +504,33 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
onSubmitted: (_) { onSubmitted: (_) {
_sendMessage(); _sendMessage();
}, },
decoration: inputTextMessageDeco(context), decoration: InputDecoration(
hintText: context.lang.chatListDetailInput,
// contentPadding: const EdgeInsets.symmetric(
// horizontal: 20,
// vertical: 10,
// ),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(
color: Theme.of(context)
.colorScheme
.primary,
width: 2,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: const BorderSide(
color: Colors.grey,
width: 2,
),
),
),
),
),
],
),
), ),
), ),
if (currentInputText != '') if (currentInputText != '')

View file

@ -193,6 +193,8 @@ class HomeViewState extends State<HomeView> {
screenshotController: screenshotController, screenshotController: screenshotController,
selectedCameraDetails: selectedCameraDetails, selectedCameraDetails: selectedCameraDetails,
selectCamera: selectCamera, selectCamera: selectCamera,
isVisible:
((1 - (offsetRatio * 4) % 1) == 1) && activePageIdx == 1,
), ),
), ),
), ),

View file

@ -386,6 +386,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.1" version: "0.3.1"
emoji_picker_flutter:
dependency: "direct main"
description:
name: emoji_picker_flutter
sha256: "9a44c102079891ea5877f78c70f2e3c6e9df7b7fe0a01757d31f1046eeaa016d"
url: "https://pub.dev"
source: hosted
version: "4.3.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -519,6 +527,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_android_volume_keydown:
dependency: "direct main"
description:
name: flutter_android_volume_keydown
sha256: bf7fed0be85541b939d9deb97b375cb12e6e703aa013754441318b0b9014e711
url: "https://pub.dev"
source: hosted
version: "1.0.1"
flutter_cache_manager: flutter_cache_manager:
dependency: transitive dependency: transitive
description: description:
@ -738,6 +754,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_volume_controller:
dependency: "direct main"
description:
name: flutter_volume_controller
sha256: "22edb0993ad03ecbc8d1164daeb5b39d798d409625db692675a86889403b1532"
url: "https://pub.dev"
source: hosted
version: "1.3.4"
flutter_web_plugins: flutter_web_plugins:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -1675,6 +1699,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
universal_io:
dependency: transitive
description:
name: universal_io
sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
url_launcher: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -20,12 +20,14 @@ dependencies:
device_info_plus: ^12.1.0 device_info_plus: ^12.1.0
drift: ^2.25.1 drift: ^2.25.1
drift_flutter: ^0.2.4 drift_flutter: ^0.2.4
emoji_picker_flutter: ^4.3.0
ffmpeg_kit_flutter_new: ^4.1.0 ffmpeg_kit_flutter_new: ^4.1.0
firebase_core: ^4.2.0 firebase_core: ^4.2.0
firebase_messaging: ^16.0.3 firebase_messaging: ^16.0.3
fixnum: ^1.1.1 fixnum: ^1.1.1
flutter: flutter:
sdk: flutter sdk: flutter
flutter_android_volume_keydown: ^1.0.1
flutter_image_compress: ^2.4.0 flutter_image_compress: ^2.4.0
flutter_local_notifications: ^19.1.0 flutter_local_notifications: ^19.1.0
flutter_localizations: flutter_localizations:
@ -36,6 +38,7 @@ dependencies:
ref: 71b75a36f35f2ce945998e20c6c6aa1820babfc6 # from develop ref: 71b75a36f35f2ce945998e20c6c6aa1820babfc6 # from develop
path: flutter_secure_storage/ path: flutter_secure_storage/
flutter_svg: ^2.0.17 flutter_svg: ^2.0.17
flutter_volume_controller: ^1.3.4
flutter_zxing: flutter_zxing:
path: ./dependencies/flutter_zxing path: ./dependencies/flutter_zxing
font_awesome_flutter: ^10.10.0 font_awesome_flutter: ^10.10.0