mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 10:58:40 +00:00
fix #20
This commit is contained in:
parent
f37518fa05
commit
0da7d77e40
8 changed files with 221 additions and 47 deletions
|
|
@ -49,13 +49,7 @@
|
|||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" />
|
||||
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ PODS:
|
|||
- GoogleUtilities/UserDefaults (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- libwebp (1.5.0):
|
||||
- libwebp/demux (= 1.5.0)
|
||||
- libwebp/mux (= 1.5.0)
|
||||
|
|
@ -233,6 +235,7 @@ DEPENDENCIES:
|
|||
- flutter_volume_controller (from `.symlinks/plugins/flutter_volume_controller/ios`)
|
||||
- gal (from `.symlinks/plugins/gal/darwin`)
|
||||
- GoogleUtilities
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
||||
- no_screenshot (from `.symlinks/plugins/no_screenshot/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
|
|
@ -290,6 +293,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/flutter_volume_controller/ios"
|
||||
gal:
|
||||
:path: ".symlinks/plugins/gal/darwin"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
local_auth_darwin:
|
||||
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
||||
no_screenshot:
|
||||
|
|
@ -333,6 +338,7 @@ SPEC CHECKSUMS:
|
|||
GoogleAppMeasurement: fc0817122bd4d4189164f85374e06773b9561896
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
|
||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>To create videos that can be securely shared.</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Store photos in the gallery.</string>
|
||||
<string>Store photos in the gallery or send from the gallery.</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ String beautifulZoomScale(double scale) {
|
|||
|
||||
class _CameraZoomButtonsState extends State<CameraZoomButtons> {
|
||||
bool showWideAngleZoom = false;
|
||||
bool _isDisposed = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -37,9 +38,16 @@ class _CameraZoomButtonsState extends State<CameraZoomButtons> {
|
|||
|
||||
Future initAsync() async {
|
||||
showWideAngleZoom = (await widget.controller.getMinZoomLevel()) < 1;
|
||||
if (_isDisposed) return;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_isDisposed = true; // Set the flag to true when disposing
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var zoomButtonStyle = TextButton.styleFrom(
|
||||
|
|
|
|||
|
|
@ -350,6 +350,8 @@ Future setPushKeys(String storageKey, Map<int, PushUser> pushKeys) async {
|
|||
jsonToSend[key.toString()] = value.toJson();
|
||||
});
|
||||
|
||||
await storage.delete(key: storageKey);
|
||||
|
||||
String jsonString = jsonEncode(jsonToSend);
|
||||
await storage.write(
|
||||
key: storageKey,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:camera/camera.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:screenshot/screenshot.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/components/zoom_selector.dart';
|
||||
|
|
@ -27,6 +28,7 @@ class CameraPreviewView extends StatefulWidget {
|
|||
class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||
double scaleFactor = 1;
|
||||
bool sharePreviewIsShown = false;
|
||||
bool galleryLoadedImageIsShown = false;
|
||||
bool isFlashOn = false;
|
||||
bool showSelfieFlash = false;
|
||||
int cameraId = 0;
|
||||
|
|
@ -200,23 +202,10 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
imageBytes = screenshotController.capture(pixelRatio: 1);
|
||||
}
|
||||
|
||||
bool? shoudReturn = await Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
opaque: false,
|
||||
pageBuilder: (context, a1, a2) =>
|
||||
ShareImageEditorView(imageBytes: imageBytes, sendTo: widget.sendTo),
|
||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
||||
return child;
|
||||
},
|
||||
transitionDuration: Duration.zero,
|
||||
reverseTransitionDuration: Duration.zero,
|
||||
),
|
||||
);
|
||||
if (shoudReturn != null && shoudReturn) {
|
||||
if (!context.mounted) return;
|
||||
return Navigator.pop(context);
|
||||
if (await pushImageEditor(imageBytes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// does not work??
|
||||
if (Platform.isIOS) {
|
||||
await controller.resumePreview();
|
||||
|
|
@ -234,6 +223,28 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
});
|
||||
}
|
||||
|
||||
Future<bool> pushImageEditor(Future<Uint8List?> imageBytes) async {
|
||||
bool? shoudReturn = await Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
opaque: false,
|
||||
pageBuilder: (context, a1, a2) =>
|
||||
ShareImageEditorView(imageBytes: imageBytes, sendTo: widget.sendTo),
|
||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
||||
return child;
|
||||
},
|
||||
transitionDuration: Duration.zero,
|
||||
reverseTransitionDuration: Duration.zero,
|
||||
),
|
||||
);
|
||||
if (shoudReturn != null && shoudReturn) {
|
||||
if (!context.mounted) return false;
|
||||
Navigator.pop(context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get isFront =>
|
||||
controller.description.lensDirection == CameraLensDirection.front;
|
||||
|
||||
|
|
@ -264,11 +275,21 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
borderRadius: BorderRadius.circular(22),
|
||||
child: Stack(
|
||||
children: [
|
||||
CameraPreviewWidget(
|
||||
controller: controller,
|
||||
screenshotController: screenshotController,
|
||||
isFront: isFront,
|
||||
),
|
||||
if (!galleryLoadedImageIsShown)
|
||||
CameraPreviewWidget(
|
||||
controller: controller,
|
||||
screenshotController: screenshotController,
|
||||
isFront: isFront,
|
||||
),
|
||||
if (galleryLoadedImageIsShown)
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 1, color: context.color.primary),
|
||||
),
|
||||
),
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
onPanStart: (details) async {
|
||||
|
|
@ -368,27 +389,73 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
takePicture();
|
||||
},
|
||||
onLongPress: () async {},
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
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,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
galleryLoadedImageIsShown = true;
|
||||
sharePreviewIsShown = true;
|
||||
});
|
||||
final picker = ImagePicker();
|
||||
final pickedFile = await picker.pickImage(
|
||||
source: ImageSource.gallery);
|
||||
|
||||
if (pickedFile != null) {
|
||||
File imageFile = File(pickedFile.path);
|
||||
if (await pushImageEditor(
|
||||
imageFile.readAsBytes())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
print('No image selected.');
|
||||
}
|
||||
setState(() {
|
||||
galleryLoadedImageIsShown = false;
|
||||
sharePreviewIsShown = false;
|
||||
});
|
||||
},
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: 80,
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: Center(
|
||||
child: FaIcon(
|
||||
FontAwesomeIcons.photoFilm,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
takePicture();
|
||||
},
|
||||
onLongPress: () async {},
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 80)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
96
pubspec.lock
96
pubspec.lock
|
|
@ -401,6 +401,38 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_linux
|
||||
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+2"
|
||||
file_selector_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_macos
|
||||
sha256: "271ab9986df0c135d45c3cdb6bd0faa5db6f4976d3e4b437cf7d0f258d941bfc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4+2"
|
||||
file_selector_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+4"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -788,6 +820,70 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.3"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker
|
||||
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
image_picker_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "8bd392ba8b0c8957a157ae0dc9fcf48c58e6c20908d5880aea1d79734df090e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+22"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_for_web
|
||||
sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
image_picker_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_ios
|
||||
sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+2"
|
||||
image_picker_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_linux
|
||||
sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+2"
|
||||
image_picker_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_macos
|
||||
sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+2"
|
||||
image_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_platform_interface
|
||||
sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.1"
|
||||
image_picker_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_windows
|
||||
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ dependencies:
|
|||
fixnum: ^1.1.1
|
||||
mutex: ^3.1.0
|
||||
cached_network_image: ^3.4.1
|
||||
image_picker: ^1.1.2
|
||||
# avatar_maker
|
||||
# avatar_maker:
|
||||
# path: ./dependencies/avatar_maker/
|
||||
|
|
|
|||
Loading…
Reference in a new issue