mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-04-18 14:22:53 +00:00
remove face filters
This commit is contained in:
parent
6df40e93df
commit
074211a815
21 changed files with 249 additions and 921 deletions
|
|
@ -23,12 +23,12 @@ android {
|
|||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
jvmTarget = "17"
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4 KiB |
100
ios/Podfile.lock
100
ios/Podfile.lock
|
|
@ -49,55 +49,55 @@ PODS:
|
|||
- file_picker (0.0.1):
|
||||
- DKImagePickerController/PhotoGallery
|
||||
- Flutter
|
||||
- Firebase (12.8.0):
|
||||
- Firebase/Core (= 12.8.0)
|
||||
- Firebase/Core (12.8.0):
|
||||
- Firebase (12.9.0):
|
||||
- Firebase/Core (= 12.9.0)
|
||||
- Firebase/Core (12.9.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (~> 12.8.0)
|
||||
- Firebase/CoreOnly (12.8.0):
|
||||
- FirebaseCore (~> 12.8.0)
|
||||
- Firebase/Messaging (12.8.0):
|
||||
- FirebaseAnalytics (~> 12.9.0)
|
||||
- Firebase/CoreOnly (12.9.0):
|
||||
- FirebaseCore (~> 12.9.0)
|
||||
- Firebase/Messaging (12.9.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 12.8.0)
|
||||
- firebase_core (4.4.0):
|
||||
- Firebase/CoreOnly (= 12.8.0)
|
||||
- FirebaseMessaging (~> 12.9.0)
|
||||
- firebase_core (4.5.0):
|
||||
- Firebase/CoreOnly (= 12.9.0)
|
||||
- Flutter
|
||||
- firebase_messaging (16.1.1):
|
||||
- Firebase/Messaging (= 12.8.0)
|
||||
- firebase_messaging (16.1.2):
|
||||
- Firebase/Messaging (= 12.9.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseAnalytics (12.8.0):
|
||||
- FirebaseAnalytics/Default (= 12.8.0)
|
||||
- FirebaseCore (~> 12.8.0)
|
||||
- FirebaseInstallations (~> 12.8.0)
|
||||
- FirebaseAnalytics (12.9.0):
|
||||
- FirebaseAnalytics/Default (= 12.9.0)
|
||||
- FirebaseCore (~> 12.9.0)
|
||||
- FirebaseInstallations (~> 12.9.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Network (~> 8.1)
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||
- nanopb (~> 3.30910.0)
|
||||
- FirebaseAnalytics/Default (12.8.0):
|
||||
- FirebaseCore (~> 12.8.0)
|
||||
- FirebaseInstallations (~> 12.8.0)
|
||||
- GoogleAppMeasurement/Default (= 12.8.0)
|
||||
- FirebaseAnalytics/Default (12.9.0):
|
||||
- FirebaseCore (~> 12.9.0)
|
||||
- FirebaseInstallations (~> 12.9.0)
|
||||
- GoogleAppMeasurement/Default (= 12.9.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Network (~> 8.1)
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||
- nanopb (~> 3.30910.0)
|
||||
- FirebaseCore (12.8.0):
|
||||
- FirebaseCoreInternal (~> 12.8.0)
|
||||
- FirebaseCore (12.9.0):
|
||||
- FirebaseCoreInternal (~> 12.9.0)
|
||||
- GoogleUtilities/Environment (~> 8.1)
|
||||
- GoogleUtilities/Logger (~> 8.1)
|
||||
- FirebaseCoreInternal (12.8.0):
|
||||
- FirebaseCoreInternal (12.9.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||
- FirebaseInstallations (12.8.0):
|
||||
- FirebaseCore (~> 12.8.0)
|
||||
- FirebaseInstallations (12.9.0):
|
||||
- FirebaseCore (~> 12.9.0)
|
||||
- GoogleUtilities/Environment (~> 8.1)
|
||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||
- PromisesObjC (~> 2.4)
|
||||
- FirebaseMessaging (12.8.0):
|
||||
- FirebaseCore (~> 12.8.0)
|
||||
- FirebaseInstallations (~> 12.8.0)
|
||||
- FirebaseMessaging (12.9.0):
|
||||
- FirebaseCore (~> 12.9.0)
|
||||
- FirebaseInstallations (~> 12.9.0)
|
||||
- GoogleDataTransport (~> 10.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Environment (~> 8.1)
|
||||
|
|
@ -140,23 +140,23 @@ PODS:
|
|||
- GoogleUtilities/Logger (~> 8.1)
|
||||
- GoogleUtilities/Network (~> 8.1)
|
||||
- nanopb (~> 3.30910.0)
|
||||
- GoogleAppMeasurement/Core (12.8.0):
|
||||
- GoogleAppMeasurement/Core (12.9.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Network (~> 8.1)
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||
- nanopb (~> 3.30910.0)
|
||||
- GoogleAppMeasurement/Default (12.8.0):
|
||||
- GoogleAppMeasurement/Default (12.9.0):
|
||||
- GoogleAdsOnDeviceConversion (~> 3.2.0)
|
||||
- GoogleAppMeasurement/Core (= 12.8.0)
|
||||
- GoogleAppMeasurement/IdentitySupport (= 12.8.0)
|
||||
- GoogleAppMeasurement/Core (= 12.9.0)
|
||||
- GoogleAppMeasurement/IdentitySupport (= 12.9.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Network (~> 8.1)
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||
- nanopb (~> 3.30910.0)
|
||||
- GoogleAppMeasurement/IdentitySupport (12.8.0):
|
||||
- GoogleAppMeasurement/Core (= 12.8.0)
|
||||
- GoogleAppMeasurement/IdentitySupport (12.9.0):
|
||||
- GoogleAppMeasurement/Core (= 12.9.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Network (~> 8.1)
|
||||
|
|
@ -276,7 +276,7 @@ PODS:
|
|||
- pro_video_editor (0.0.1):
|
||||
- Flutter
|
||||
- PromisesObjC (2.4.0)
|
||||
- restart_app (0.0.1):
|
||||
- restart_app (1.7.2):
|
||||
- Flutter
|
||||
- SDWebImage (5.21.6):
|
||||
- SDWebImage/Core (= 5.21.6)
|
||||
|
|
@ -285,7 +285,7 @@ PODS:
|
|||
- libwebp (~> 1.0)
|
||||
- SDWebImage/Core (~> 5.17)
|
||||
- Sentry/HybridSDK (8.56.2)
|
||||
- sentry_flutter (9.13.0):
|
||||
- sentry_flutter (9.14.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (= 8.56.2)
|
||||
|
|
@ -331,6 +331,8 @@ PODS:
|
|||
- video_player_avfoundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- workmanager_apple (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- app_links (from `.symlinks/plugins/app_links/ios`)
|
||||
|
|
@ -377,6 +379,7 @@ DEPENDENCIES:
|
|||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- video_compress (from `.symlinks/plugins/video_compress/ios`)
|
||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
|
||||
- workmanager_apple (from `.symlinks/plugins/workmanager_apple/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
|
|
@ -488,6 +491,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/video_compress/ios"
|
||||
video_player_avfoundation:
|
||||
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
|
||||
workmanager_apple:
|
||||
:path: ".symlinks/plugins/workmanager_apple/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
|
||||
|
|
@ -501,14 +506,14 @@ SPEC CHECKSUMS:
|
|||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||
emoji_picker_flutter: ece213fc274bdddefb77d502d33080dc54e616cc
|
||||
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
||||
Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d
|
||||
firebase_core: ee30637e6744af8e0c12a6a1e8a9718506ec2398
|
||||
firebase_messaging: 343de01a8d3e18b60df0c6d37f7174c44ae38e02
|
||||
FirebaseAnalytics: f20bbad8cb7f65d8a5eaefeb424ae8800a31bdfc
|
||||
FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c
|
||||
FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21
|
||||
FirebaseInstallations: 6a14ab3d694ebd9f839c48d330da5547e9ca9dc0
|
||||
FirebaseMessaging: 7f42cfd10ec64181db4e01b305a613791c8e782c
|
||||
Firebase: 065f2bb395062046623036d8e6dc857bc2521d56
|
||||
firebase_core: afac1aac13c931e0401c7e74ed1276112030efab
|
||||
firebase_messaging: 7cb2727feb789751fc6936bcc8e08408970e2820
|
||||
FirebaseAnalytics: cd7d01d352f3c237c9a0e31552c257cd0b0c0352
|
||||
FirebaseCore: 428912f751178b06bef0a1793effeb4a5e09a9b8
|
||||
FirebaseCoreInternal: b321eafae5362113bc182956fafc9922cfc77b72
|
||||
FirebaseInstallations: 7b64ffd006032b2b019a59b803858df5112d9eaa
|
||||
FirebaseMessaging: 7d6cdbff969127c4151c824fe432f0e301210f15
|
||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||
flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
|
||||
flutter_keyboard_visibility_temp_fork: 95b2d534bacf6ac62e7fcbe5c2a9e2c2a17ce06f
|
||||
|
|
@ -521,7 +526,7 @@ SPEC CHECKSUMS:
|
|||
google_mlkit_commons: a5e4ffae5bc59ea4c7b9025dc72cb6cb79dc1166
|
||||
google_mlkit_face_detection: ee4b72cfae062b4c972204be955d83055a4bfd36
|
||||
GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f
|
||||
GoogleAppMeasurement: 72c9a682fec6290327ea5e3c4b829b247fcb2c17
|
||||
GoogleAppMeasurement: fce7c1c90640d2f9f5c56771f71deacb2ba3f98c
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleMLKit: b1eee21a41c57704fe72483b15c85cb2c0cd7444
|
||||
GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8
|
||||
|
|
@ -543,11 +548,11 @@ SPEC CHECKSUMS:
|
|||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
pro_video_editor: 44ef9a6d48dbd757ed428cf35396dd05f35c7830
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
restart_app: 9cda5378aacc5000e3f66ee76a9201534e7d3ecf
|
||||
restart_app: 98825697952793b5a8e489df3d52ed5ac4fd536d
|
||||
SDWebImage: 1bb6a1b84b6fe87b972a102bdc77dd589df33477
|
||||
SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377
|
||||
Sentry: b53951377b78e21a734f5dc8318e333dbfc682d7
|
||||
sentry_flutter: dbed9a62ae39716b685a80140705c330d200d941
|
||||
sentry_flutter: 841fa2fe08dc72eb95e2320b76e3f751f3400cf5
|
||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||
|
|
@ -558,6 +563,7 @@ SPEC CHECKSUMS:
|
|||
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
|
||||
video_compress: f2133a07762889d67f0711ac831faa26f956980e
|
||||
video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a
|
||||
workmanager_apple: 904529ae31e97fc5be632cf628507652294a0778
|
||||
|
||||
PODFILE CHECKSUM: ae041999f13ba7b2285ff9ad9bc688ed647bbcb7
|
||||
|
||||
|
|
|
|||
|
|
@ -536,12 +536,14 @@ class Handshake_Authenticate extends $pb.GeneratedMessage {
|
|||
$core.List<$core.int>? authToken,
|
||||
$core.String? appVersion,
|
||||
$fixnum.Int64? deviceId,
|
||||
$core.bool? inBackground,
|
||||
}) {
|
||||
final result = create();
|
||||
if (userId != null) result.userId = userId;
|
||||
if (authToken != null) result.authToken = authToken;
|
||||
if (appVersion != null) result.appVersion = appVersion;
|
||||
if (deviceId != null) result.deviceId = deviceId;
|
||||
if (inBackground != null) result.inBackground = inBackground;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -564,6 +566,7 @@ class Handshake_Authenticate extends $pb.GeneratedMessage {
|
|||
2, _omitFieldNames ? '' : 'authToken', $pb.PbFieldType.OY)
|
||||
..aOS(3, _omitFieldNames ? '' : 'appVersion')
|
||||
..aInt64(4, _omitFieldNames ? '' : 'deviceId')
|
||||
..aOB(5, _omitFieldNames ? '' : 'inBackground')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -624,6 +627,15 @@ class Handshake_Authenticate extends $pb.GeneratedMessage {
|
|||
$core.bool hasDeviceId() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearDeviceId() => $_clearField(4);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool get inBackground => $_getBF(4);
|
||||
@$pb.TagNumber(5)
|
||||
set inBackground($core.bool value) => $_setBool(4, value);
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasInBackground() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearInBackground() => $_clearField(5);
|
||||
}
|
||||
|
||||
enum Handshake_Handshake {
|
||||
|
|
|
|||
|
|
@ -229,10 +229,20 @@ const Handshake_Authenticate$json = {
|
|||
'10': 'deviceId',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'in_background',
|
||||
'3': 5,
|
||||
'4': 1,
|
||||
'5': 8,
|
||||
'9': 2,
|
||||
'10': 'inBackground',
|
||||
'17': true
|
||||
},
|
||||
],
|
||||
'8': [
|
||||
{'1': '_app_version'},
|
||||
{'1': '_device_id'},
|
||||
{'1': '_in_background'},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
@ -254,10 +264,11 @@ final $typed_data.Uint8List handshakeDescriptor = $convert.base64Decode(
|
|||
'QSFQoGaXNfaW9zGAggASgIUgVpc0lvcxIbCglsYW5nX2NvZGUYCSABKAlSCGxhbmdDb2RlEiIK'
|
||||
'DXByb29mX29mX3dvcmsYCiABKANSC3Byb29mT2ZXb3JrQg4KDF9pbnZpdGVfY29kZRoSChBHZX'
|
||||
'RBdXRoQ2hhbGxlbmdlGkMKDEdldEF1dGhUb2tlbhIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQS'
|
||||
'GgoIcmVzcG9uc2UYAiABKAxSCHJlc3BvbnNlGqwBCgxBdXRoZW50aWNhdGUSFwoHdXNlcl9pZB'
|
||||
'GgoIcmVzcG9uc2UYAiABKAxSCHJlc3BvbnNlGugBCgxBdXRoZW50aWNhdGUSFwoHdXNlcl9pZB'
|
||||
'gBIAEoA1IGdXNlcklkEh0KCmF1dGhfdG9rZW4YAiABKAxSCWF1dGhUb2tlbhIkCgthcHBfdmVy'
|
||||
'c2lvbhgDIAEoCUgAUgphcHBWZXJzaW9uiAEBEiAKCWRldmljZV9pZBgEIAEoA0gBUghkZXZpY2'
|
||||
'VJZIgBAUIOCgxfYXBwX3ZlcnNpb25CDAoKX2RldmljZV9pZEILCglIYW5kc2hha2U=');
|
||||
'VJZIgBARIoCg1pbl9iYWNrZ3JvdW5kGAUgASgISAJSDGluQmFja2dyb3VuZIgBAUIOCgxfYXBw'
|
||||
'X3ZlcnNpb25CDAoKX2RldmljZV9pZEIQCg5faW5fYmFja2dyb3VuZEILCglIYW5kc2hha2U=');
|
||||
|
||||
@$core.Deprecated('Use applicationDataDescriptor instead')
|
||||
const ApplicationData$json = {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ class ErrorCode extends $pb.ProtobufEnum {
|
|||
ErrorCode._(1034, _omitEnumNames ? '' : 'IPAPaymentExpired');
|
||||
static const ErrorCode UserIsNotInFreePlan =
|
||||
ErrorCode._(1035, _omitEnumNames ? '' : 'UserIsNotInFreePlan');
|
||||
static const ErrorCode ForegroundSessionConnected =
|
||||
ErrorCode._(1036, _omitEnumNames ? '' : 'ForegroundSessionConnected');
|
||||
|
||||
static const $core.List<ErrorCode> values = <ErrorCode>[
|
||||
Unknown,
|
||||
|
|
@ -131,6 +133,7 @@ class ErrorCode extends $pb.ProtobufEnum {
|
|||
RegistrationDisabled,
|
||||
IPAPaymentExpired,
|
||||
UserIsNotInFreePlan,
|
||||
ForegroundSessionConnected,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, ErrorCode> _byValue =
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ const ErrorCode$json = {
|
|||
{'1': 'RegistrationDisabled', '2': 1033},
|
||||
{'1': 'IPAPaymentExpired', '2': 1034},
|
||||
{'1': 'UserIsNotInFreePlan', '2': 1035},
|
||||
{'1': 'ForegroundSessionConnected', '2': 1036},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
@ -77,4 +78,5 @@ final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode(
|
|||
'duZWRQcmVLZXkQgwgSEwoOVXNlcklkTm90Rm91bmQQhAgSFwoSVXNlcklkQWxyZWFkeVRha2Vu'
|
||||
'EIUIEhcKEkFwcFZlcnNpb25PdXRkYXRlZBCGCBIYChNOZXdEZXZpY2VSZWdpc3RlcmVkEIcIEh'
|
||||
'cKEkludmFsaWRQcm9vZk9mV29yaxCICBIZChRSZWdpc3RyYXRpb25EaXNhYmxlZBCJCBIWChFJ'
|
||||
'UEFQYXltZW50RXhwaXJlZBCKCBIYChNVc2VySXNOb3RJbkZyZWVQbGFuEIsI');
|
||||
'UEFQYXltZW50RXhwaXJlZBCKCBIYChNVc2VySXNOb3RJbkZyZWVQbGFuEIsIEh8KGkZvcmVncm'
|
||||
'91bmRTZXNzaW9uQ29ubmVjdGVkEIwI');
|
||||
|
|
|
|||
|
|
@ -46,10 +46,6 @@ class MainCameraPreview extends StatelessWidget {
|
|||
Positioned.fill(
|
||||
child: mainCameraController.customPaint!,
|
||||
),
|
||||
if (mainCameraController.facePaint != null)
|
||||
Positioned.fill(
|
||||
child: mainCameraController.facePaint!,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/utils/qr.dart';
|
||||
import 'package:twonly/src/utils/screenshot.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/face_filters.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/main_camera_controller.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/permissions_view.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/send_to.dart';
|
||||
|
|
@ -458,36 +457,6 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
});
|
||||
}
|
||||
|
||||
Future<void> pressSideButtonLeft() async {
|
||||
if (!mc.isSelectingFaceFilters) {
|
||||
return pickImageFromGallery();
|
||||
}
|
||||
if (mc.currentFilterType.index == 1) {
|
||||
mc.setFilter(FaceFilterType.none);
|
||||
setState(() {
|
||||
mc.isSelectingFaceFilters = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
mc.setFilter(mc.currentFilterType.goLeft());
|
||||
}
|
||||
|
||||
Future<void> pressSideButtonRight() async {
|
||||
if (!mc.isSelectingFaceFilters) {
|
||||
setState(() {
|
||||
mc.isSelectingFaceFilters = true;
|
||||
});
|
||||
}
|
||||
if (mc.currentFilterType.index == FaceFilterType.values.length - 1) {
|
||||
mc.setFilter(FaceFilterType.none);
|
||||
setState(() {
|
||||
mc.isSelectingFaceFilters = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
mc.setFilter(mc.currentFilterType.goRight());
|
||||
}
|
||||
|
||||
Future<void> startVideoRecording() async {
|
||||
if (mc.cameraController != null &&
|
||||
mc.cameraController!.value.isRecordingVideo) {
|
||||
|
|
@ -724,84 +693,27 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (!mc.isVideoRecording)
|
||||
GestureDetector(
|
||||
onTap: pressSideButtonLeft,
|
||||
child: Align(
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: 80,
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: Center(
|
||||
child: FaIcon(
|
||||
mc.isSelectingFaceFilters
|
||||
? mc.currentFilterType.index == 1
|
||||
? FontAwesomeIcons.xmark
|
||||
: FontAwesomeIcons.arrowLeft
|
||||
: FontAwesomeIcons.photoFilm,
|
||||
color: Colors.white,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: takePicture,
|
||||
// onLongPress: startVideoRecording,
|
||||
key: keyTriggerButton,
|
||||
child: Align(
|
||||
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: mc.isVideoRecording
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
),
|
||||
),
|
||||
child: mc.currentFilterType.preview,
|
||||
GestureDetector(
|
||||
onTap: takePicture,
|
||||
// onLongPress: startVideoRecording,
|
||||
key: keyTriggerButton,
|
||||
child: Align(
|
||||
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: mc.isVideoRecording
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!mc.isVideoRecording)
|
||||
if (isFront)
|
||||
GestureDetector(
|
||||
onTap: pressSideButtonRight,
|
||||
child: Align(
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: 80,
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: Center(
|
||||
child: FaIcon(
|
||||
mc.isSelectingFaceFilters
|
||||
? mc.currentFilterType.index ==
|
||||
FaceFilterType
|
||||
.values.length -
|
||||
1
|
||||
? FontAwesomeIcons.xmark
|
||||
: FontAwesomeIcons.arrowRight
|
||||
: FontAwesomeIcons
|
||||
.faceGrinTongueSquint,
|
||||
color: Colors.white,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
const SizedBox(width: 80),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/beard_filter_painter.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/dog_filter_painter.dart';
|
||||
|
||||
enum FaceFilterType {
|
||||
none,
|
||||
dogBrown,
|
||||
beardUpperLipGreen,
|
||||
beardUpperLip,
|
||||
}
|
||||
|
||||
extension FaceFilterTypeExtension on FaceFilterType {
|
||||
FaceFilterType goRight() {
|
||||
final nextIndex = (index + 1) % FaceFilterType.values.length;
|
||||
return FaceFilterType.values[nextIndex];
|
||||
}
|
||||
|
||||
FaceFilterType goLeft() {
|
||||
final prevIndex = (index - 1 + FaceFilterType.values.length) %
|
||||
FaceFilterType.values.length;
|
||||
return FaceFilterType.values[prevIndex];
|
||||
}
|
||||
|
||||
Widget get preview {
|
||||
switch (this) {
|
||||
case FaceFilterType.none:
|
||||
return Container();
|
||||
case FaceFilterType.dogBrown:
|
||||
return DogFilterPainter.getPreview();
|
||||
case FaceFilterType.beardUpperLip:
|
||||
return BeardFilterPainter.getPreview(this);
|
||||
case FaceFilterType.beardUpperLipGreen:
|
||||
return BeardFilterPainter.getPreview(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import 'package:drift/drift.dart' show Value;
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
|
||||
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
|
|
@ -18,26 +17,16 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/utils/qr.dart';
|
||||
import 'package:twonly/src/utils/screenshot.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/camera_preview_controller_view.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/face_filters.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/barcode_detector_painter.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/beard_filter_painter.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/dog_filter_painter.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/face_filter_painter.dart';
|
||||
|
||||
class ScannedVerifiedContact {
|
||||
ScannedVerifiedContact({
|
||||
required this.contact,
|
||||
required this.verificationOk,
|
||||
});
|
||||
ScannedVerifiedContact({required this.contact, required this.verificationOk});
|
||||
Contact contact;
|
||||
bool verificationOk;
|
||||
}
|
||||
|
||||
class ScannedNewProfile {
|
||||
ScannedNewProfile({
|
||||
required this.profile,
|
||||
this.isLoading = false,
|
||||
});
|
||||
ScannedNewProfile({required this.profile, this.isLoading = false});
|
||||
PublicProfile profile;
|
||||
bool isLoading;
|
||||
}
|
||||
|
|
@ -53,7 +42,6 @@ class MainCameraController {
|
|||
String? scannedUrl;
|
||||
GlobalKey zoomButtonKey = GlobalKey();
|
||||
GlobalKey cameraPreviewKey = GlobalKey();
|
||||
bool isSelectingFaceFilters = false;
|
||||
|
||||
bool isSharePreviewIsShown = false;
|
||||
bool isVideoRecording = false;
|
||||
|
|
@ -71,21 +59,10 @@ class MainCameraController {
|
|||
}
|
||||
|
||||
final BarcodeScanner _barcodeScanner = BarcodeScanner();
|
||||
final FaceDetector _faceDetector = FaceDetector(
|
||||
options: FaceDetectorOptions(
|
||||
enableContours: true,
|
||||
enableLandmarks: true,
|
||||
),
|
||||
);
|
||||
bool _isBusy = false;
|
||||
bool _isBusyFaces = false;
|
||||
CustomPaint? customPaint;
|
||||
CustomPaint? facePaint;
|
||||
Offset? focusPointOffset;
|
||||
|
||||
FaceFilterType _currentFilterType = FaceFilterType.none;
|
||||
FaceFilterType get currentFilterType => _currentFilterType;
|
||||
|
||||
Future<void> closeCamera() async {
|
||||
contactsVerified = {};
|
||||
scannedNewProfiles = {};
|
||||
|
|
@ -159,8 +136,9 @@ class MainCameraController {
|
|||
}
|
||||
}
|
||||
|
||||
await cameraController
|
||||
?.lockCaptureOrientation(DeviceOrientation.portraitUp);
|
||||
await cameraController?.lockCaptureOrientation(
|
||||
DeviceOrientation.portraitUp,
|
||||
);
|
||||
await cameraController?.setFlashMode(
|
||||
selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off,
|
||||
);
|
||||
|
|
@ -174,10 +152,7 @@ class MainCameraController {
|
|||
..cameraLoaded = true
|
||||
..cameraId = cameraId;
|
||||
|
||||
facePaint = null;
|
||||
customPaint = null;
|
||||
isSelectingFaceFilters = false;
|
||||
setFilter(FaceFilterType.none);
|
||||
zoomButtonKey = GlobalKey();
|
||||
setState();
|
||||
}
|
||||
|
|
@ -214,18 +189,6 @@ class MainCameraController {
|
|||
setState();
|
||||
}
|
||||
|
||||
void setFilter(FaceFilterType type) {
|
||||
_currentFilterType = type;
|
||||
if (_currentFilterType == FaceFilterType.none) {
|
||||
faceFilterPainter = null;
|
||||
facePaint = null;
|
||||
_isBusyFaces = false;
|
||||
}
|
||||
setState();
|
||||
}
|
||||
|
||||
FaceFilterPainter? faceFilterPainter;
|
||||
|
||||
final Map<DeviceOrientation, int> _orientations = {
|
||||
DeviceOrientation.portraitUp: 0,
|
||||
DeviceOrientation.landscapeLeft: 90,
|
||||
|
|
@ -240,15 +203,6 @@ class MainCameraController {
|
|||
final inputImage = _inputImageFromCameraImage(image);
|
||||
if (inputImage == null) return;
|
||||
_processBarcode(inputImage);
|
||||
// check if front camera is selected
|
||||
if (cameraController?.description.lensDirection ==
|
||||
CameraLensDirection.front) {
|
||||
if (_currentFilterType != FaceFilterType.none) {
|
||||
_processFaces(inputImage);
|
||||
}
|
||||
} else {
|
||||
_processBarcode(inputImage);
|
||||
}
|
||||
}
|
||||
|
||||
InputImage? _inputImageFromCameraImage(CameraImage image) {
|
||||
|
|
@ -338,16 +292,19 @@ class MainCameraController {
|
|||
|
||||
if (profile == null) continue;
|
||||
|
||||
final contact =
|
||||
await twonlyDB.contactsDao.getContactById(profile.userId.toInt());
|
||||
final contact = await twonlyDB.contactsDao.getContactById(
|
||||
profile.userId.toInt(),
|
||||
);
|
||||
|
||||
if (contact != null && contact.accepted) {
|
||||
if (contactsVerified[contact.userId] == null) {
|
||||
final storedPublicKey =
|
||||
await getPublicKeyFromContact(contact.userId);
|
||||
final storedPublicKey = await getPublicKeyFromContact(
|
||||
contact.userId,
|
||||
);
|
||||
if (storedPublicKey != null) {
|
||||
final verificationOk =
|
||||
profile.publicIdentityKey.equals(storedPublicKey.toList());
|
||||
final verificationOk = profile.publicIdentityKey.equals(
|
||||
storedPublicKey.toList(),
|
||||
);
|
||||
contactsVerified[contact.userId] = ScannedVerifiedContact(
|
||||
contact: contact,
|
||||
verificationOk: verificationOk,
|
||||
|
|
@ -390,53 +347,4 @@ class MainCameraController {
|
|||
_isBusy = false;
|
||||
setState();
|
||||
}
|
||||
|
||||
Future<void> _processFaces(InputImage inputImage) async {
|
||||
if (_isBusyFaces) return;
|
||||
_isBusyFaces = true;
|
||||
final faces = await _faceDetector.processImage(inputImage);
|
||||
if (inputImage.metadata?.size != null &&
|
||||
inputImage.metadata?.rotation != null &&
|
||||
cameraController != null) {
|
||||
if (faces.isNotEmpty) {
|
||||
CustomPainter? painter;
|
||||
switch (_currentFilterType) {
|
||||
case FaceFilterType.dogBrown:
|
||||
painter = DogFilterPainter(
|
||||
faces,
|
||||
inputImage.metadata!.size,
|
||||
inputImage.metadata!.rotation,
|
||||
cameraController!.description.lensDirection,
|
||||
);
|
||||
case FaceFilterType.beardUpperLip:
|
||||
case FaceFilterType.beardUpperLipGreen:
|
||||
painter = BeardFilterPainter(
|
||||
_currentFilterType,
|
||||
faces,
|
||||
inputImage.metadata!.size,
|
||||
inputImage.metadata!.rotation,
|
||||
cameraController!.description.lensDirection,
|
||||
);
|
||||
case FaceFilterType.none:
|
||||
break;
|
||||
}
|
||||
|
||||
if (painter != null) {
|
||||
facePaint = CustomPaint(painter: painter);
|
||||
// Also set the correct FaceFilterPainter reference if needed for other logic,
|
||||
// though currently facePaint is what's used for display.
|
||||
if (painter is FaceFilterPainter) {
|
||||
faceFilterPainter = painter;
|
||||
}
|
||||
} else {
|
||||
facePaint = null;
|
||||
faceFilterPainter = null;
|
||||
}
|
||||
} else {
|
||||
facePaint = null;
|
||||
}
|
||||
}
|
||||
_isBusyFaces = false;
|
||||
setState();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,193 +0,0 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/face_filters.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/coordinates_translator.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/face_filter_painter.dart';
|
||||
|
||||
class BeardFilterPainter extends FaceFilterPainter {
|
||||
BeardFilterPainter(
|
||||
FaceFilterType beardType,
|
||||
super.faces,
|
||||
super.imageSize,
|
||||
super.rotation,
|
||||
super.cameraLensDirection,
|
||||
) {
|
||||
_loadAssets(beardType);
|
||||
}
|
||||
|
||||
static FaceFilterType? _lastLoadedBeardType;
|
||||
static ui.Image? _beardImage;
|
||||
static bool _loading = false;
|
||||
|
||||
static String getAssetPath(FaceFilterType beardType) {
|
||||
switch (beardType) {
|
||||
case FaceFilterType.beardUpperLip:
|
||||
return 'assets/filters/beard_upper_lip.webp';
|
||||
case FaceFilterType.beardUpperLipGreen:
|
||||
return 'assets/filters/beard_upper_lip_green.webp';
|
||||
case FaceFilterType.dogBrown:
|
||||
case FaceFilterType.none:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _loadAssets(FaceFilterType beardType) async {
|
||||
if ((_loading || _beardImage != null) &&
|
||||
_lastLoadedBeardType == beardType) {
|
||||
return;
|
||||
}
|
||||
_loading = true;
|
||||
try {
|
||||
_beardImage = await _loadImage(getAssetPath(beardType));
|
||||
} catch (e) {
|
||||
Log.error('Failed to load filter assets: $e');
|
||||
} finally {
|
||||
_loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<ui.Image> _loadImage(String assetPath) async {
|
||||
final data = await rootBundle.load(assetPath);
|
||||
final list = Uint8List.view(data.buffer);
|
||||
final completer = Completer<ui.Image>();
|
||||
ui.decodeImageFromList(list, completer.complete);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
if (_beardImage == null) return;
|
||||
|
||||
for (final face in faces) {
|
||||
final noseBase = face.landmarks[FaceLandmarkType.noseBase];
|
||||
final mouthLeft = face.landmarks[FaceLandmarkType.leftMouth];
|
||||
final mouthRight = face.landmarks[FaceLandmarkType.rightMouth];
|
||||
final bottomMouth = face.landmarks[FaceLandmarkType.bottomMouth];
|
||||
|
||||
if (noseBase != null &&
|
||||
mouthLeft != null &&
|
||||
mouthRight != null &&
|
||||
bottomMouth != null) {
|
||||
final noseX = translateX(
|
||||
noseBase.position.x.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
final noseY = translateY(
|
||||
noseBase.position.y.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
|
||||
final mouthLeftX = translateX(
|
||||
mouthLeft.position.x.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
final mouthLeftY = translateY(
|
||||
mouthLeft.position.y.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
|
||||
final mouthRightX = translateX(
|
||||
mouthRight.position.x.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
final mouthRightY = translateY(
|
||||
mouthRight.position.y.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
|
||||
final mouthCenterX = (mouthLeftX + mouthRightX) / 2;
|
||||
final mouthCenterY = (mouthLeftY + mouthRightY) / 2;
|
||||
|
||||
final beardCenterX = (noseX + mouthCenterX) / 2;
|
||||
final beardCenterY = (noseY + mouthCenterY) / 2;
|
||||
|
||||
final dx = mouthRightX - mouthLeftX;
|
||||
final dy = mouthRightY - mouthLeftY;
|
||||
final angle = atan2(dy, dx);
|
||||
|
||||
final mouthWidth = sqrt(dx * dx + dy * dy);
|
||||
final beardWidth = mouthWidth * 1.5;
|
||||
|
||||
final yaw = face.headEulerAngleY ?? 0;
|
||||
final scaleX = cos(yaw * pi / 180).abs();
|
||||
|
||||
_drawImage(
|
||||
canvas,
|
||||
_beardImage!,
|
||||
Offset(beardCenterX, beardCenterY),
|
||||
beardWidth,
|
||||
angle,
|
||||
scaleX,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _drawImage(
|
||||
Canvas canvas,
|
||||
ui.Image image,
|
||||
Offset position,
|
||||
double width,
|
||||
double rotation,
|
||||
double scaleX,
|
||||
) {
|
||||
canvas
|
||||
..save()
|
||||
..translate(position.dx, position.dy)
|
||||
..rotate(rotation)
|
||||
..scale(scaleX, Platform.isAndroid ? -1 : 1);
|
||||
|
||||
final srcRect =
|
||||
Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble());
|
||||
|
||||
final aspectRatio = image.width / image.height;
|
||||
final dstWidth = width;
|
||||
final dstHeight = width / aspectRatio;
|
||||
|
||||
final dstRect = Rect.fromCenter(
|
||||
center: Offset.zero,
|
||||
width: dstWidth,
|
||||
height: dstHeight,
|
||||
);
|
||||
|
||||
canvas
|
||||
..drawImageRect(image, srcRect, dstRect, Paint())
|
||||
..restore();
|
||||
}
|
||||
|
||||
static Widget getPreview(FaceFilterType beardType) {
|
||||
return Preview(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Image.asset(
|
||||
getAssetPath(beardType),
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/coordinates_translator.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/painters/face_filters/face_filter_painter.dart';
|
||||
|
||||
class DogFilterPainter extends FaceFilterPainter {
|
||||
DogFilterPainter(
|
||||
super.faces,
|
||||
super.imageSize,
|
||||
super.rotation,
|
||||
super.cameraLensDirection,
|
||||
) {
|
||||
_loadAssets();
|
||||
}
|
||||
|
||||
static ui.Image? _earImage;
|
||||
static ui.Image? _noseImage;
|
||||
static bool _loading = false;
|
||||
|
||||
static Future<void> _loadAssets() async {
|
||||
if (_loading || (_earImage != null && _noseImage != null)) return;
|
||||
_loading = true;
|
||||
try {
|
||||
_earImage = await _loadImage('assets/filters/dog_brown_ear.webp');
|
||||
_noseImage = await _loadImage('assets/filters/dog_brown_nose.webp');
|
||||
} catch (e) {
|
||||
Log.error('Failed to load filter assets: $e');
|
||||
} finally {
|
||||
_loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<ui.Image> _loadImage(String assetPath) async {
|
||||
final data = await rootBundle.load(assetPath);
|
||||
final list = Uint8List.view(data.buffer);
|
||||
final completer = Completer<ui.Image>();
|
||||
ui.decodeImageFromList(list, completer.complete);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
if (_earImage == null || _noseImage == null) return;
|
||||
|
||||
for (final face in faces) {
|
||||
final faceContour = face.contours[FaceContourType.face];
|
||||
final noseBase = face.landmarks[FaceLandmarkType.noseBase];
|
||||
|
||||
if (faceContour != null && noseBase != null) {
|
||||
final points = faceContour.points;
|
||||
if (points.isEmpty) continue;
|
||||
|
||||
final upperPoints =
|
||||
points.where((p) => p.y < noseBase.position.y).toList();
|
||||
|
||||
if (upperPoints.isEmpty) continue;
|
||||
|
||||
Point<int>? leftMost;
|
||||
Point<int>? rightMost;
|
||||
Point<int>? topMost;
|
||||
|
||||
for (final point in upperPoints) {
|
||||
if (leftMost == null || point.x < leftMost.x) {
|
||||
leftMost = point;
|
||||
}
|
||||
if (rightMost == null || point.x > rightMost.x) {
|
||||
rightMost = point;
|
||||
}
|
||||
if (topMost == null || point.y < topMost.y) {
|
||||
topMost = point;
|
||||
}
|
||||
}
|
||||
|
||||
if (leftMost == null || rightMost == null || topMost == null) continue;
|
||||
|
||||
final leftEarX = translateX(
|
||||
leftMost.x.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
final leftEarY = translateY(
|
||||
topMost.y.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
|
||||
final rightEarX = translateX(
|
||||
rightMost.x.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
final rightEarY = translateY(
|
||||
topMost.y.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
|
||||
final noseX = translateX(
|
||||
noseBase.position.x.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
final noseY = translateY(
|
||||
noseBase.position.y.toDouble(),
|
||||
size,
|
||||
imageSize,
|
||||
rotation,
|
||||
cameraLensDirection,
|
||||
);
|
||||
|
||||
final dx = rightEarX - leftEarX;
|
||||
final dy = rightEarY - leftEarY;
|
||||
|
||||
final faceWidth = sqrt(dx * dx + dy * dy) * 1.5;
|
||||
final angle = atan2(dy, dx);
|
||||
|
||||
final yaw = face.headEulerAngleY ?? 0;
|
||||
final scaleX = cos(yaw * pi / 180).abs();
|
||||
|
||||
final earSize = faceWidth / 2.5;
|
||||
|
||||
_drawImage(
|
||||
canvas,
|
||||
_earImage!,
|
||||
Offset(leftEarX, leftEarY + earSize * 0.3),
|
||||
earSize,
|
||||
angle,
|
||||
scaleX,
|
||||
);
|
||||
|
||||
_drawImage(
|
||||
canvas,
|
||||
_earImage!,
|
||||
Offset(rightEarX, rightEarY + earSize * 0.3),
|
||||
earSize,
|
||||
angle,
|
||||
scaleX,
|
||||
isFlipped: true,
|
||||
);
|
||||
|
||||
final noseSize = faceWidth * 0.4;
|
||||
_drawImage(
|
||||
canvas,
|
||||
_noseImage!,
|
||||
Offset(noseX, noseY + noseSize * 0.1),
|
||||
noseSize,
|
||||
angle,
|
||||
scaleX,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _drawImage(
|
||||
Canvas canvas,
|
||||
ui.Image image,
|
||||
Offset position,
|
||||
double size,
|
||||
double rotation,
|
||||
double scaleX, {
|
||||
bool isFlipped = false,
|
||||
}) {
|
||||
canvas
|
||||
..save()
|
||||
..translate(position.dx, position.dy)
|
||||
..rotate(rotation);
|
||||
if (isFlipped) {
|
||||
canvas.scale(-scaleX, Platform.isAndroid ? -1 : 1);
|
||||
} else {
|
||||
canvas.scale(scaleX, Platform.isAndroid ? -1 : 1);
|
||||
}
|
||||
|
||||
final srcRect =
|
||||
Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble());
|
||||
final aspectRatio = image.width / image.height;
|
||||
final dstWidth = size;
|
||||
final dstHeight = size / aspectRatio;
|
||||
|
||||
final dstRect = Rect.fromCenter(
|
||||
center: Offset.zero,
|
||||
width: dstWidth,
|
||||
height: dstHeight,
|
||||
);
|
||||
|
||||
canvas
|
||||
..drawImageRect(image, srcRect, dstRect, Paint())
|
||||
..restore();
|
||||
}
|
||||
|
||||
static Widget getPreview() {
|
||||
return Preview(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 25),
|
||||
child: Image.asset(
|
||||
'assets/filters/dog_brown_nose.webp',
|
||||
width: 25,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/filters/dog_brown_ear.webp',
|
||||
width: 20,
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
Transform.scale(
|
||||
scaleX: -1,
|
||||
child: Image.asset(
|
||||
'assets/filters/dog_brown_ear.webp',
|
||||
width: 20,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import 'package:camera/camera.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
|
||||
|
||||
abstract class FaceFilterPainter extends CustomPainter {
|
||||
FaceFilterPainter(
|
||||
this.faces,
|
||||
this.imageSize,
|
||||
this.rotation,
|
||||
this.cameraLensDirection,
|
||||
);
|
||||
|
||||
final List<Face> faces;
|
||||
final Size imageSize;
|
||||
final InputImageRotation rotation;
|
||||
final CameraLensDirection cameraLensDirection;
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant FaceFilterPainter oldDelegate) {
|
||||
return oldDelegate.imageSize != imageSize ||
|
||||
oldDelegate.faces != faces ||
|
||||
oldDelegate.rotation != rotation ||
|
||||
oldDelegate.cameraLensDirection != cameraLensDirection;
|
||||
}
|
||||
}
|
||||
|
||||
class Preview extends StatelessWidget {
|
||||
const Preview({required this.child, super.key});
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.grey.withValues(alpha: 0.2),
|
||||
),
|
||||
child: Center(
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -67,6 +67,16 @@ class _FlameCounterWidgetState extends State<FlameCounterWidget> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (flameCounter < 1) return Container();
|
||||
|
||||
var flameEmoji = '🔥';
|
||||
|
||||
if (isBestFriend) flameEmoji = '❤️🔥';
|
||||
if (flameCounter == 100) flameEmoji = '💯';
|
||||
|
||||
if (flameCounter >= 365 && flameCounter % 365 == 0) {
|
||||
flameEmoji = '🎂';
|
||||
}
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
if (widget.prefix) const SizedBox(width: 5),
|
||||
|
|
@ -79,7 +89,7 @@ class _FlameCounterWidgetState extends State<FlameCounterWidget> {
|
|||
SizedBox(
|
||||
height: 15,
|
||||
child: EmojiAnimation(
|
||||
emoji: isBestFriend ? '❤️🔥' : '🔥',
|
||||
emoji: flameEmoji,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
206
pubspec.lock
206
pubspec.lock
|
|
@ -13,10 +13,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: cd83f7d6bd4e4c0b0b4fef802e8796784032e1cc23d7b0e982cf5d05d9bbe182
|
||||
sha256: afe15ce18a287d2f89da95566e62892df339b1936bbe9b83587df45b944ee72a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.66"
|
||||
version: "1.3.67"
|
||||
adaptive_number:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
|
|
@ -68,10 +68,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: archive
|
||||
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
|
||||
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.7"
|
||||
version: "4.0.9"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -108,10 +108,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: background_downloader
|
||||
sha256: "2ea5322fe836c0aaf96aefd29ef1936771c71927f687cf18168dcc119666a45f"
|
||||
sha256: "4cb23d9ad4f5060944f38164e7b90d4bf99b57b2472a3bd4676e59b2db4afd06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.5.2"
|
||||
version: "9.5.4"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -164,10 +164,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: "7931c90b84bc573fef103548e354258ae4c9d28d140e41961df6843c5d60d4d8"
|
||||
sha256: "6ae8a6435a8c6520c7077b107e77f1fb4ba7009633259a4d49a8afd8e7efc5e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.12.3"
|
||||
version: "8.12.4"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -196,10 +196,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: camera
|
||||
sha256: a005c6b9783d895a3a9808d65d06773d13587e22a186b6fe8ef3801b0d12f8cf
|
||||
sha256: "4142a19a38e388d3bab444227636610ba88982e36dff4552d5191a86f65dc437"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.3+1"
|
||||
version: "0.11.4"
|
||||
camera_android_camerax:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
|
|
@ -365,10 +365,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "15a7db352c8fc6a4d2bc475ba901c25b39fe7157541da4c16eacce6f8be83e49"
|
||||
sha256: "6f6b30cba0301e7b38f32bdc9a6bdae6f5921a55f0a1eb9450e1e6515645dbb2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.5"
|
||||
version: "3.1.6"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -508,10 +508,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "923085c881663ef685269b013e241b428e1fb03cdd0ebde265d9b40ff18abf80"
|
||||
sha256: f0997fee80fbb6d2c658c5b88ae87ba1f9506b5b37126db64fc2e75d8e977fbb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
version: "4.5.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -524,34 +524,34 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: "83e7356c704131ca4d8d8dd57e360d8acecbca38b1a3705c7ae46cc34c708084"
|
||||
sha256: "856ca92bf2d75a63761286ab8e791bda3a85184c2b641764433b619647acfca6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.0"
|
||||
version: "3.5.0"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
sha256: "06fad40ea14771e969a8f2bbce1944aa20ee2f4f57f4eca5b3ba346b65f3f644"
|
||||
sha256: bd17823b70e629877904d384841cda72ed2cc197517404c0c90da5c0ba786a8c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "16.1.1"
|
||||
version: "16.1.2"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
sha256: "6c49e901c77e6e10e86d98e32056a087eb1ca1b93acdf58524f1961e617657b7"
|
||||
sha256: "550435235cc7d53683f32bf0762c28ef8cfc20a8d36318a033676ae09526d7fb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.7.6"
|
||||
version: "4.7.7"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
sha256: "2756f8fea583ffb9d294d15ddecb3a9ad429b023b70c9990c151fc92c54a32b3"
|
||||
sha256: "6b1b93ed90309fbce91c219e3cd32aa831e8eccaf4a61f3afaea1625479275d2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
version: "4.1.3"
|
||||
fixnum:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -868,14 +868,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
google_mlkit_face_detection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_mlkit_face_detection
|
||||
sha256: "7b6ddcc69dbd6fbfa313fb2d974ad0f0c3a0d1657560f0da6be465baf1889687"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.2"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -957,10 +949,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: image
|
||||
sha256: "492bd52f6c4fbb6ee41f781ff27765ce5f627910e1e0cbecfa3d9add5562604c"
|
||||
sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.7.2"
|
||||
version: "4.8.0"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -973,10 +965,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "518a16108529fc18657a3e6dde4a043dc465d16596d20ab2abd49a4cac2e703d"
|
||||
sha256: eda9b91b7e266d9041084a42d605a74937d996b87083395c5e47835916a86156
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.13+13"
|
||||
version: "0.8.13+14"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1053,10 +1045,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: in_app_purchase_storekit
|
||||
sha256: f7cbbd7fb47ab5a4fb736fc3f20ae81a4f6def0af9297b3c525ca727761e2589
|
||||
sha256: "2f1a1db44798158076ced07d401b349880dd24a29c7c50a1b1a0de230b7f2f62"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.7"
|
||||
version: "0.4.8"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1100,26 +1092,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: json_annotation
|
||||
sha256: "805fa86df56383000f640384b282ce0cb8431f1a7a2396de92fb66186d8c57df"
|
||||
sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
json_schema:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_schema
|
||||
sha256: f37d9c3fdfe8c9aae55fdfd5af815d24ce63c3a0f6a2c1f0982c30f43643fa1a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.2"
|
||||
version: "4.11.0"
|
||||
json_serializable:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
sha256: "93fba3ad139dab2b1ce59ecc6fdce6da46a42cdb6c4399ecda30f1e7e725760d"
|
||||
sha256: "44729f5c45748e6748f6b9a57ab8f7e4336edc8ae41fc295070e3814e616a6c0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.12.0"
|
||||
version: "6.13.0"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1163,26 +1147,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: local_auth
|
||||
sha256: a4f1bf57f0236a4aeb5e8f0ec180e197f4b112a3456baa6c1e73b546630b0422
|
||||
sha256: ae6f382f638108c6becd134318d7c3f0a93875383a54010f61d7c97ac05d5137
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.0.1"
|
||||
local_auth_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: local_auth_android
|
||||
sha256: "162b8e177fd9978c4620da2a8002a5c6bed4d20f0c6daf5137e72e9a8b767d2e"
|
||||
sha256: dc9663a7bc8ac33d7d988e63901974f63d527ebef260eabd19c479447cc9c911
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
local_auth_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: local_auth_darwin
|
||||
sha256: "176480aa855ebedeed195e26ac7d6601a45e6b255dfc7433f353e0c1aeafa9a2"
|
||||
sha256: a8c3d4e17454111f7fd31ff72a31222359f6059f7fe956c2dcfe0f88f49826d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.0.3"
|
||||
local_auth_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1447,10 +1431,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1"
|
||||
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
version: "7.0.2"
|
||||
photo_view:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1493,18 +1477,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: posix
|
||||
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
|
||||
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.3"
|
||||
version: "6.5.0"
|
||||
pro_video_editor:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pro_video_editor
|
||||
sha256: "0d985f7653c59e2b521d19db49351476eb74eb4001689b33fb8112ab1a9c4330"
|
||||
sha256: "5aa37aed1399333a3ac4b78ce00c7dcba77c5e407b6420960bba43751895fa22"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.1"
|
||||
version: "1.6.2"
|
||||
protobuf:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1551,14 +1535,6 @@ packages:
|
|||
relative: true
|
||||
source: path
|
||||
version: "4.1.0"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
recase:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1571,18 +1547,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: restart_app
|
||||
sha256: "00d5ec3e9de871cedbe552fc41e615b042b5ec654385e090e0983f6d02f655ed"
|
||||
sha256: "0fd0a14cedfcd65d429588c204de44493866438391a9ee97ecf910ce591323ae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
rfc_6901:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rfc_6901
|
||||
sha256: "6a43b1858dca2febaf93e15639aa6b0c49ccdfd7647775f15a499f872b018154"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1"
|
||||
version: "1.7.2"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1603,18 +1571,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: sentry
|
||||
sha256: e57e57123968b673c8ca19892eecf93113b4811b8e5cd5d165749ca7f7319fdb
|
||||
sha256: "605ad1f6f1ae5b72018cbe8fc20f490fa3bd53e58882e5579566776030d8c8c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.13.0"
|
||||
version: "9.14.0"
|
||||
sentry_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry_flutter
|
||||
sha256: c8f5b805c0346cd0c93b09e584675af7ed8c3ef36c3589181ad19b4adce35954
|
||||
sha256: "7fd0fb80050c1f6a77ae185bda997a76d384326d6777cf5137a6c38952c4ac7d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.13.0"
|
||||
version: "9.14.0"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1643,10 +1611,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f
|
||||
sha256: "8374d6200ab33ac99031a852eba4c8eb2170c4bf20778b3e2c9eccb45384fb41"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.20"
|
||||
version: "2.4.21"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1848,10 +1816,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8"
|
||||
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
version: "0.7.9"
|
||||
timezone:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1868,14 +1836,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uri:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uri
|
||||
sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1896,10 +1856,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: b1aca26728b7cc7a3af971bb6f601554a8ae9df2e0a006de8450ba06a17ad36a
|
||||
sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.4.0"
|
||||
version: "6.4.1"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1944,10 +1904,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
|
||||
sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.2"
|
||||
version: "4.5.3"
|
||||
vector_graphics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1968,10 +1928,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_compiler
|
||||
sha256: "201e876b5d52753626af64b6359cd13ac6011b80728731428fd34bc840f71c9b"
|
||||
sha256: "5a88dd14c0954a5398af544651c7fb51b457a2a556949bfb25369b210ef73a74"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.20"
|
||||
version: "1.2.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1984,10 +1944,10 @@ packages:
|
|||
dependency: "direct dev"
|
||||
description:
|
||||
name: very_good_analysis
|
||||
sha256: "27927d1140ce1b140f998b6340f730a626faa5b95110b3e34a238ff254d731d0"
|
||||
sha256: d1cb1d66a5aae2c702d68caca6c8347306d35e728fd94555fa21fa0448a972e0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.1.0"
|
||||
version: "10.2.0"
|
||||
video_compress:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -2000,18 +1960,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: video_player
|
||||
sha256: "096bc28ce10d131be80dfb00c223024eb0fba301315a406728ab43dd99c45bdf"
|
||||
sha256: "08bfba72e311d48219acad4e191b1f9c27ff8cf928f2c7234874592d9c9d7341"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.1"
|
||||
version: "2.11.0"
|
||||
video_player_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
sha256: ee4fd520b0cafa02e4a867a0f882092e727cdaa1a2d24762171e787f8a502b0a
|
||||
sha256: "9862c67c4661c98f30fe707bc1a4f97d6a0faa76784f485d282668e4651a7ac3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.1"
|
||||
version: "2.9.4"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -2092,6 +2052,38 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
workmanager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: workmanager
|
||||
sha256: "065673b2a465865183093806925419d311a9a5e0995aa74ccf8920fd695e2d10"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.0+3"
|
||||
workmanager_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: workmanager_android
|
||||
sha256: "9ae744db4ef891f5fcd2fb8671fccc712f4f96489a487a1411e0c8675e5e8cb7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.0+2"
|
||||
workmanager_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: workmanager_apple
|
||||
sha256: "1cc12ae3cbf5535e72f7ba4fde0c12dd11b757caf493a28e22d684052701f2ca"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1+2"
|
||||
workmanager_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: workmanager_platform_interface
|
||||
sha256: f40422f10b970c67abb84230b44da22b075147637532ac501729256fcea10a47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1+1"
|
||||
x25519:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
|
|
@ -2124,5 +2116,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.10.3 <4.0.0"
|
||||
dart: ">=3.11.0 <4.0.0"
|
||||
flutter: ">=3.38.4"
|
||||
|
|
|
|||
48
pubspec.yaml
48
pubspec.yaml
|
|
@ -48,6 +48,7 @@ dependencies:
|
|||
font_awesome_flutter: ^10.10.0
|
||||
share_plus: ^12.0.0
|
||||
package_info_plus: ^9.0.0
|
||||
workmanager: ^0.9.0+3
|
||||
|
||||
|
||||
# Trustworthy publishers
|
||||
|
|
@ -63,10 +64,27 @@ dependencies:
|
|||
drift: ^2.25.1
|
||||
drift_flutter: ^0.2.4
|
||||
flutter_local_notifications: ^19.1.0
|
||||
sentry_flutter: ^9.8.0
|
||||
sentry_flutter: ^9.14.0
|
||||
|
||||
|
||||
# With high download
|
||||
# Overwritten by self-controlled repository
|
||||
emoji_picker_flutter: ^4.3.0
|
||||
|
||||
# Packages which got overwritten using the twonly-app-dependencies repository
|
||||
# Idea: Every change goes though a git commit, where every change can be reviewed.
|
||||
restart_app: ^1.3.2
|
||||
photo_view: ^0.15.0
|
||||
hashlib: ^2.0.0
|
||||
libsignal_protocol_dart: ^0.7.4
|
||||
lottie: ^3.3.1
|
||||
mutex: ^3.1.0
|
||||
introduction_screen: ^4.0.0
|
||||
qr_flutter: ^4.1.0
|
||||
hand_signature: ^3.0.3
|
||||
flutter_sharing_intent: ^2.0.4
|
||||
no_screenshot: ^0.3.1
|
||||
|
||||
# With high download. (But should be checked nonetheless.)
|
||||
app_links: ^7.0.0 # 1.6 mio
|
||||
image: ^4.3.0 # 3.3 mio
|
||||
archive: ^4.0.7 # 6.5 mio
|
||||
|
|
@ -75,7 +93,6 @@ dependencies:
|
|||
flutter_secure_storage: ^10.0.0 # 1.85 mio
|
||||
permission_handler: ^12.0.0+1 # 2 mio
|
||||
|
||||
|
||||
# Not yet checked
|
||||
audio_waveforms: ^2.0.0
|
||||
avatar_maker: ^0.4.0
|
||||
|
|
@ -88,30 +105,6 @@ dependencies:
|
|||
flutter_volume_controller: ^1.3.4
|
||||
gal: ^2.3.1
|
||||
google_mlkit_barcode_scanning: ^0.14.1
|
||||
|
||||
# flutter_secure_storage:
|
||||
# git:
|
||||
# url: https://github.com/juliansteenbakker/flutter_secure_storage.git
|
||||
# ref: a06ead81809c900e7fc421a30db0adf3b5919139 # from develop
|
||||
# path: flutter_secure_storage/
|
||||
|
||||
|
||||
# Overwritten by self-controlled repository
|
||||
emoji_picker_flutter: ^4.3.0
|
||||
|
||||
# Packages which got overwritten using the twonly-app-dependencies repository
|
||||
restart_app: ^1.3.2
|
||||
photo_view: ^0.15.0
|
||||
hashlib: ^2.0.0
|
||||
libsignal_protocol_dart: ^0.7.4
|
||||
lottie: ^3.3.1
|
||||
mutex: ^3.1.0
|
||||
introduction_screen: ^4.0.0
|
||||
qr_flutter: ^4.1.0
|
||||
hand_signature: ^3.0.3
|
||||
flutter_sharing_intent: ^2.0.4
|
||||
no_screenshot: ^0.3.1
|
||||
google_mlkit_face_detection: ^0.13.1
|
||||
pro_video_editor: ^1.6.1
|
||||
video_compress: ^3.1.4
|
||||
|
||||
|
|
@ -208,6 +201,5 @@ flutter:
|
|||
- assets/animated_icons/
|
||||
- assets/animations/
|
||||
- assets/passwords/
|
||||
- assets/filters/
|
||||
- CHANGELOG.md
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue