Merge branch 'main' into keychain_migration
This commit is contained in:
commit
18f4731eb3
|
@ -2,8 +2,9 @@
|
|||
# This git hook fails if a user is trying to add a new file which is
|
||||
# not null safe.
|
||||
|
||||
# Check the contents of each file that is being added or modified
|
||||
for file in `git diff --name-only --cached`; do
|
||||
# Check the contents of each file that is being added(A) or modified(N) or
|
||||
# copied (C)
|
||||
for file in `git diff --name-only --diff-filter=ACM --cached`; do
|
||||
# Ignore the hooks from any pre-commit check
|
||||
if echo "$file" | grep -q 'hooks/'; then
|
||||
continue
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// @dart=2.9
|
||||
import 'package:photos/models/file.dart';
|
||||
|
||||
class GalleryItemsFilter {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart';
|
||||
|
@ -15,7 +13,10 @@ class ImportantItemsFilter implements GalleryItemsFilter {
|
|||
if (file.uploadedFileID != null) {
|
||||
return true;
|
||||
}
|
||||
final String folder = basename(file.deviceFolder);
|
||||
if (file.deviceFolder == null) {
|
||||
return false;
|
||||
}
|
||||
final String folder = basename(file.deviceFolder!);
|
||||
if (_importantPaths.isEmpty && Platform.isAndroid) {
|
||||
return folder == "Camera" ||
|
||||
folder == "Recents" ||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
|
@ -15,7 +13,6 @@ import 'package:photos/models/subscription.dart';
|
|||
import 'package:photos/models/user_details.dart';
|
||||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/ui/common/web_page.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
||||
const kWebPaymentRedirectUrl = "https://payments.ente.io/frameRedirect";
|
||||
|
@ -39,7 +36,7 @@ class BillingService {
|
|||
|
||||
bool _isOnSubscriptionPage = false;
|
||||
|
||||
Future<BillingPlans> _future;
|
||||
Future<BillingPlans>? _future;
|
||||
|
||||
void init() {
|
||||
// if (Platform.isIOS && kDebugMode) {
|
||||
|
@ -75,7 +72,7 @@ class BillingService {
|
|||
_future ??= _fetchBillingPlans().then((response) {
|
||||
return BillingPlans.fromMap(response.data);
|
||||
});
|
||||
return _future;
|
||||
return _future!;
|
||||
}
|
||||
|
||||
Future<Response<dynamic>> _fetchBillingPlans() {
|
||||
|
@ -99,7 +96,7 @@ class BillingService {
|
|||
);
|
||||
return Subscription.fromMap(response.data["subscription"]);
|
||||
} on DioError catch (e) {
|
||||
if (e.response != null && e.response.statusCode == 409) {
|
||||
if (e.response != null && e.response!.statusCode == 409) {
|
||||
throw SubscriptionAlreadyClaimedError();
|
||||
} else {
|
||||
rethrow;
|
||||
|
|
|
@ -14,7 +14,6 @@ import 'package:photos/models/file.dart';
|
|||
import 'package:photos/models/magic_metadata.dart';
|
||||
import 'package:photos/services/collections_service.dart';
|
||||
import 'package:photos/services/file_magic_service.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/crypto_util.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import 'package:photos/ui/account/password_reentry_page.dart';
|
|||
import 'package:photos/ui/account/two_factor_authentication_page.dart';
|
||||
import 'package:photos/ui/account/two_factor_recovery_page.dart';
|
||||
import 'package:photos/ui/account/two_factor_setup_page.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/crypto_util.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/navigation_util.dart';
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/email_util.dart';
|
||||
|
||||
class ChangeEmailDialog extends StatefulWidget {
|
||||
const ChangeEmailDialog({Key key}) : super(key: key);
|
||||
const ChangeEmailDialog({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ChangeEmailDialog> createState() => _ChangeEmailDialogState();
|
||||
}
|
||||
|
||||
class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
||||
String _email;
|
||||
String? _email;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -10,9 +10,9 @@ import 'package:photos/services/local_authentication_service.dart';
|
|||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/theme/ente_theme.dart';
|
||||
import 'package:photos/ui/components/button_widget.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/components/models/button_type.dart';
|
||||
import 'package:photos/utils/crypto_util.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/email_util.dart';
|
||||
|
||||
class DeleteAccountPage extends StatelessWidget {
|
||||
|
|
|
@ -12,7 +12,6 @@ import 'package:photos/services/user_service.dart';
|
|||
import 'package:photos/ui/account/recovery_key_page.dart';
|
||||
import 'package:photos/ui/common/dynamic_fab.dart';
|
||||
import 'package:photos/ui/common/web_page.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/payment/subscription.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/navigation_util.dart';
|
||||
|
|
|
@ -65,6 +65,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
|
|||
return Scaffold(
|
||||
appBar: widget.showProgressBar
|
||||
? AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
elevation: 0,
|
||||
title: Hero(
|
||||
tag: "recovery_key",
|
||||
|
@ -97,6 +98,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
|
|||
child: IntrinsicHeight(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
widget.showAppBar
|
||||
? const SizedBox.shrink()
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
|
@ -12,14 +10,14 @@ import 'package:photos/utils/dialog_util.dart';
|
|||
import 'package:photos/utils/toast_util.dart';
|
||||
|
||||
class SessionsPage extends StatefulWidget {
|
||||
const SessionsPage({Key key}) : super(key: key);
|
||||
const SessionsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SessionsPage> createState() => _SessionsPageState();
|
||||
}
|
||||
|
||||
class _SessionsPageState extends State<SessionsPage> {
|
||||
Sessions _sessions;
|
||||
Sessions? _sessions;
|
||||
final Logger _logger = Logger("SessionsPageState");
|
||||
|
||||
@override
|
||||
|
@ -45,7 +43,7 @@ class _SessionsPageState extends State<SessionsPage> {
|
|||
}
|
||||
final List<Widget> rows = [];
|
||||
rows.add(const Padding(padding: EdgeInsets.all(4)));
|
||||
for (final session in _sessions.sessions) {
|
||||
for (final session in _sessions!.sessions) {
|
||||
rows.add(_getSessionWidget(session));
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
|
@ -133,12 +131,14 @@ class _SessionsPageState extends State<SessionsPage> {
|
|||
.getActiveSessions()
|
||||
.onError((error, stackTrace) {
|
||||
showToast(context, "Failed to fetch active sessions");
|
||||
throw error;
|
||||
throw error!;
|
||||
});
|
||||
_sessions.sessions.sort((first, second) {
|
||||
return second.lastUsedTime.compareTo(first.lastUsedTime);
|
||||
});
|
||||
setState(() {});
|
||||
if (_sessions != null) {
|
||||
_sessions!.sessions.sort((first, second) {
|
||||
return second.lastUsedTime.compareTo(first.lastUsedTime);
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void _showSessionTerminationDialog(Session session) {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:photos/services/user_service.dart';
|
||||
|
@ -9,7 +7,7 @@ import 'package:pinput/pin_put/pin_put.dart';
|
|||
class TwoFactorAuthenticationPage extends StatefulWidget {
|
||||
final String sessionID;
|
||||
|
||||
const TwoFactorAuthenticationPage(this.sessionID, {Key key})
|
||||
const TwoFactorAuthenticationPage(this.sessionID, {Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -25,7 +23,7 @@ class _TwoFactorAuthenticationPageState
|
|||
borderRadius: BorderRadius.circular(15.0),
|
||||
);
|
||||
String _code = "";
|
||||
LifecycleEventHandler _lifecycleEventHandler;
|
||||
late LifecycleEventHandler _lifecycleEventHandler;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -33,8 +31,8 @@ class _TwoFactorAuthenticationPageState
|
|||
resumeCallBack: () async {
|
||||
if (mounted) {
|
||||
final data = await Clipboard.getData(Clipboard.kTextPlain);
|
||||
if (data != null && data.text != null && data.text.length == 6) {
|
||||
_pinController.text = data.text;
|
||||
if (data != null && data.text != null && data.text!.length == 6) {
|
||||
_pinController.text = data.text!;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -15,7 +13,7 @@ class TwoFactorRecoveryPage extends StatefulWidget {
|
|||
this.sessionID,
|
||||
this.encryptedSecret,
|
||||
this.secretDecryptionNonce, {
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:ui';
|
||||
|
||||
|
@ -24,7 +22,7 @@ class TwoFactorSetupPage extends StatefulWidget {
|
|||
this.secretCode,
|
||||
this.qrCode,
|
||||
this.completer, {
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -33,15 +31,15 @@ class TwoFactorSetupPage extends StatefulWidget {
|
|||
|
||||
class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
TabController _tabController;
|
||||
late TabController _tabController;
|
||||
final _pinController = TextEditingController();
|
||||
final _pinPutDecoration = BoxDecoration(
|
||||
border: Border.all(color: const Color.fromRGBO(45, 194, 98, 1.0)),
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
);
|
||||
String _code = "";
|
||||
ImageProvider _imageProvider;
|
||||
LifecycleEventHandler _lifecycleEventHandler;
|
||||
late ImageProvider _imageProvider;
|
||||
late LifecycleEventHandler _lifecycleEventHandler;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -55,8 +53,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
|
|||
resumeCallBack: () async {
|
||||
if (mounted) {
|
||||
final data = await Clipboard.getData(Clipboard.kTextPlain);
|
||||
if (data != null && data.text != null && data.text.length == 6) {
|
||||
_pinController.text = data.text;
|
||||
if (data != null && data.text != null && data.text!.length == 6) {
|
||||
_pinController.text = data.text!;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -14,7 +14,6 @@ import 'package:photos/services/user_service.dart';
|
|||
import 'package:photos/ui/account/recovery_key_page.dart';
|
||||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/common/gradient_button.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/navigation_util.dart';
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import 'package:photos/services/favorites_service.dart';
|
|||
import 'package:photos/theme/ente_theme.dart';
|
||||
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
|
||||
import 'package:photos/ui/common/progress_dialog.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/toast_util.dart';
|
||||
|
||||
|
@ -21,7 +20,9 @@ extension CollectionFileActions on CollectionActions {
|
|||
final count = selectedFiles.files.length;
|
||||
final textTheme = getEnteTextTheme(context);
|
||||
final showDeletePrompt = await _anyItemPresentOnlyInCurrentAlbum(
|
||||
selectedFiles.files, collection.id);
|
||||
selectedFiles.files,
|
||||
collection.id,
|
||||
);
|
||||
final String title =
|
||||
showDeletePrompt ? "Delete items?" : "Remove from album?";
|
||||
final String message1 = showDeletePrompt
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'package:photos/services/hidden_service.dart';
|
|||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/theme/ente_theme.dart';
|
||||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/payment/subscription.dart';
|
||||
import 'package:photos/utils/date_time_util.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:photos/models/device_collection.dart';
|
|||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/services/remote_sync_service.dart';
|
||||
import 'package:photos/ui/common/loading_widget.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
|
@ -12,7 +10,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
|
|||
|
||||
const ArchivedCollectionsButtonWidget(
|
||||
this.textStyle, {
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -26,7 +24,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(0),
|
||||
side: BorderSide(
|
||||
width: 0.5,
|
||||
color: Theme.of(context).iconTheme.color.withOpacity(0.24),
|
||||
color: Theme.of(context).iconTheme.color!.withOpacity(0.24),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
|
@ -50,7 +48,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
|
|||
Configuration.instance.getUserID(),
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData && snapshot.data > 0) {
|
||||
if (snapshot.hasData && snapshot.data! > 0) {
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
style: textStyle,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:photos/core/event_bus.dart';
|
||||
|
@ -7,9 +5,7 @@ import 'package:photos/events/tab_changed_event.dart';
|
|||
import 'package:photos/utils/toast_util.dart';
|
||||
|
||||
class CreateNewAlbumWidget extends StatelessWidget {
|
||||
const CreateNewAlbumWidget({
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
const CreateNewAlbumWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -23,14 +19,14 @@ class CreateNewAlbumWidget extends StatelessWidget {
|
|||
blurRadius: 2,
|
||||
spreadRadius: 0,
|
||||
offset: const Offset(0, 0),
|
||||
color: Theme.of(context).iconTheme.color.withOpacity(0.3),
|
||||
color: Theme.of(context).iconTheme.color!.withOpacity(0.3),
|
||||
)
|
||||
],
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Theme.of(context).iconTheme.color.withOpacity(0.25),
|
||||
color: Theme.of(context).iconTheme.color!.withOpacity(0.25),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
import 'package:photos/models/device_collection.dart';
|
||||
|
@ -12,7 +10,7 @@ class DeviceFolderIcon extends StatelessWidget {
|
|||
final DeviceCollection deviceCollection;
|
||||
const DeviceFolderIcon(
|
||||
this.deviceCollection, {
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -35,7 +33,7 @@ class DeviceFolderIcon extends StatelessWidget {
|
|||
child: Hero(
|
||||
tag: "device_folder:" +
|
||||
deviceCollection.name +
|
||||
deviceCollection.thumbnail.tag,
|
||||
deviceCollection.thumbnail!.tag,
|
||||
child: Stack(
|
||||
children: [
|
||||
ThumbnailWidget(
|
||||
|
@ -44,7 +42,7 @@ class DeviceFolderIcon extends StatelessWidget {
|
|||
key: Key(
|
||||
"device_folder:" +
|
||||
deviceCollection.name +
|
||||
deviceCollection.thumbnail.tag,
|
||||
deviceCollection.thumbnail!.tag,
|
||||
),
|
||||
),
|
||||
isBackedUp ? Container() : const UnSyncedIcon(),
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -12,7 +10,7 @@ import 'package:photos/utils/navigation_util.dart';
|
|||
class TrashButtonWidget extends StatefulWidget {
|
||||
const TrashButtonWidget(
|
||||
this.textStyle, {
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextStyle textStyle;
|
||||
|
@ -22,7 +20,7 @@ class TrashButtonWidget extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _TrashButtonWidgetState extends State<TrashButtonWidget> {
|
||||
StreamSubscription<TrashUpdatedEvent> _trashUpdatedEventSubscription;
|
||||
late StreamSubscription<TrashUpdatedEvent> _trashUpdatedEventSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -37,7 +35,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
_trashUpdatedEventSubscription?.cancel();
|
||||
_trashUpdatedEventSubscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -52,7 +50,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
|
|||
padding: const EdgeInsets.all(0),
|
||||
side: BorderSide(
|
||||
width: 0.5,
|
||||
color: Theme.of(context).iconTheme.color.withOpacity(0.24),
|
||||
color: Theme.of(context).iconTheme.color!.withOpacity(0.24),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
|
@ -73,7 +71,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
|
|||
FutureBuilder<int>(
|
||||
future: TrashDB.instance.count(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData && snapshot.data > 0) {
|
||||
if (snapshot.hasData && snapshot.data! > 0) {
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
style: widget.textStyle,
|
||||
|
|
|
@ -14,37 +14,13 @@ enum ActionSheetType {
|
|||
iconOnly,
|
||||
}
|
||||
|
||||
Future<ButtonAction?> showCommonActionSheet({
|
||||
required BuildContext context,
|
||||
required List<ButtonWidget> buttons,
|
||||
required ActionSheetType actionSheetType,
|
||||
bool isCheckIconGreen = false,
|
||||
String? title,
|
||||
String? body,
|
||||
}) {
|
||||
return showMaterialModalBottomSheet(
|
||||
backgroundColor: Colors.transparent,
|
||||
barrierColor: backdropFaintDark,
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return ActionSheetWidget(
|
||||
title: title,
|
||||
body: body,
|
||||
actionButtons: buttons,
|
||||
actionSheetType: actionSheetType,
|
||||
isCheckIconGreen: isCheckIconGreen,
|
||||
);
|
||||
},
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
);
|
||||
}
|
||||
|
||||
///Returns null if dismissed
|
||||
Future<ButtonAction?> showActionSheet({
|
||||
required BuildContext context,
|
||||
required List<ButtonWidget> buttons,
|
||||
required ActionSheetType actionSheetType,
|
||||
bool enableDrag = true,
|
||||
bool isDismissible = true,
|
||||
bool isCheckIconGreen = false,
|
||||
String? title,
|
||||
String? body,
|
||||
|
@ -54,6 +30,8 @@ Future<ButtonAction?> showActionSheet({
|
|||
barrierColor: backdropFaintDark,
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
isDismissible: isDismissible,
|
||||
enableDrag: enableDrag,
|
||||
builder: (_) {
|
||||
return ActionSheetWidget(
|
||||
title: title,
|
||||
|
@ -63,8 +41,6 @@ Future<ButtonAction?> showActionSheet({
|
|||
isCheckIconGreen: isCheckIconGreen,
|
||||
);
|
||||
},
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,76 +6,19 @@ import 'package:photos/theme/colors.dart';
|
|||
import 'package:photos/theme/effects.dart';
|
||||
import 'package:photos/theme/ente_theme.dart';
|
||||
import 'package:photos/ui/components/button_widget.dart';
|
||||
import 'package:photos/ui/components/models/button_type.dart';
|
||||
import 'package:photos/utils/separators_util.dart';
|
||||
|
||||
Future<ButtonAction?> showGenericErrorDialog({
|
||||
required BuildContext context,
|
||||
}) async {
|
||||
return showDialogWidget(
|
||||
context: context,
|
||||
title: "Error",
|
||||
icon: Icons.error_outline_outlined,
|
||||
body: "It looks like something went wrong. Please try again.",
|
||||
buttons: const [
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.secondary,
|
||||
labelText: "OK",
|
||||
isInAlert: true,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<ButtonAction?> showNewChoiceDialog({
|
||||
required BuildContext context,
|
||||
required String title,
|
||||
String? body,
|
||||
required String firstButtonLabel,
|
||||
String secondButtonLabel = "Cancel",
|
||||
ButtonType firstButtonType = ButtonType.neutral,
|
||||
ButtonType secondButtonType = ButtonType.secondary,
|
||||
ButtonAction firstButtonAction = ButtonAction.first,
|
||||
ButtonAction secondButtonAction = ButtonAction.cancel,
|
||||
FutureVoidCallback? firstButtonOnTap,
|
||||
FutureVoidCallback? secondButtonOnTap,
|
||||
bool isCritical = false,
|
||||
IconData? icon,
|
||||
}) async {
|
||||
final buttons = [
|
||||
ButtonWidget(
|
||||
buttonType: isCritical ? ButtonType.critical : firstButtonType,
|
||||
labelText: firstButtonLabel,
|
||||
isInAlert: true,
|
||||
onTap: firstButtonOnTap,
|
||||
buttonAction: firstButtonAction,
|
||||
),
|
||||
ButtonWidget(
|
||||
buttonType: secondButtonType,
|
||||
labelText: secondButtonLabel,
|
||||
isInAlert: true,
|
||||
onTap: secondButtonOnTap,
|
||||
buttonAction: secondButtonAction,
|
||||
),
|
||||
];
|
||||
return showDialogWidget(
|
||||
context: context,
|
||||
title: title,
|
||||
body: body,
|
||||
buttons: buttons,
|
||||
icon: icon,
|
||||
);
|
||||
}
|
||||
|
||||
///Will return null if dismissed by tapping outside
|
||||
Future<ButtonAction?> showDialogWidget({
|
||||
required BuildContext context,
|
||||
required String title,
|
||||
String? body,
|
||||
required List<ButtonWidget> buttons,
|
||||
IconData? icon,
|
||||
bool isDismissible = true,
|
||||
}) {
|
||||
return showDialog(
|
||||
barrierDismissible: false,
|
||||
barrierDismissible: isDismissible,
|
||||
barrierColor: backdropFaintDark,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
|
@ -89,7 +32,6 @@ Future<ButtonAction?> showDialogWidget({
|
|||
title: title,
|
||||
body: body,
|
||||
buttons: buttons,
|
||||
isMobileSmall: isMobileSmall,
|
||||
icon: icon,
|
||||
),
|
||||
),
|
||||
|
@ -103,12 +45,10 @@ class DialogWidget extends StatelessWidget {
|
|||
final String? body;
|
||||
final List<ButtonWidget> buttons;
|
||||
final IconData? icon;
|
||||
final bool isMobileSmall;
|
||||
const DialogWidget({
|
||||
required this.title,
|
||||
this.body,
|
||||
required this.buttons,
|
||||
required this.isMobileSmall,
|
||||
this.icon,
|
||||
super.key,
|
||||
});
|
||||
|
@ -116,6 +56,7 @@ class DialogWidget extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final widthOfScreen = MediaQuery.of(context).size.width;
|
||||
final isMobileSmall = widthOfScreen <= mobileSmallThreshold;
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
return Container(
|
||||
width: min(widthOfScreen, 320),
|
||||
|
|
|
@ -14,7 +14,6 @@ import 'package:photos/services/ignored_files_service.dart';
|
|||
import 'package:photos/services/remote_sync_service.dart';
|
||||
import 'package:photos/ui/common/gradient_button.dart';
|
||||
import 'package:photos/ui/common/loading_widget.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
|
||||
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
|
||||
import 'package:photos/ui/viewer/gallery/collection_page.dart';
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -7,7 +5,7 @@ import 'package:photo_manager/photo_manager.dart';
|
|||
import 'package:photos/services/sync_service.dart';
|
||||
|
||||
class GrantPermissionsWidget extends StatelessWidget {
|
||||
const GrantPermissionsWidget({Key key}) : super(key: key);
|
||||
const GrantPermissionsWidget({Key? key}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isLightMode =
|
||||
|
@ -55,7 +53,7 @@ class GrantPermissionsWidget extends StatelessWidget {
|
|||
text: TextSpan(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline5
|
||||
.headline5!
|
||||
.copyWith(fontWeight: FontWeight.w700),
|
||||
children: [
|
||||
const TextSpan(text: 'ente '),
|
||||
|
@ -63,7 +61,7 @@ class GrantPermissionsWidget extends StatelessWidget {
|
|||
text: "needs permission to ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline5
|
||||
.headline5!
|
||||
.copyWith(fontWeight: FontWeight.w400),
|
||||
),
|
||||
const TextSpan(text: 'preserve your photos'),
|
||||
|
@ -109,7 +107,7 @@ class GrantPermissionsWidget extends StatelessWidget {
|
|||
TextButton(
|
||||
child: Text(
|
||||
"OK",
|
||||
style: Theme.of(context).textTheme.subtitle1.copyWith(
|
||||
style: Theme.of(context).textTheme.subtitle1!.copyWith(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PlaceHolderWidget extends StatelessWidget {
|
||||
const PlaceHolderWidget(
|
||||
this.count,
|
||||
this.columns, {
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final int count, columns;
|
||||
|
@ -33,7 +31,7 @@ class PlaceHolderWidget extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
return _gridViewCache[key];
|
||||
return _gridViewCache[key]!;
|
||||
}
|
||||
|
||||
String _getCacheKey(int totalCount, int columns) {
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'package:photos/theme/colors.dart';
|
|||
import 'package:photos/theme/ente_theme.dart';
|
||||
import 'package:photos/ui/account/password_entry_page.dart';
|
||||
import 'package:photos/ui/common/gradient_button.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/home_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/navigation_util.dart';
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
import 'package:photos/models/user_details.dart';
|
||||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
||||
class ChildSubscriptionWidget extends StatelessWidget {
|
||||
const ChildSubscriptionWidget({
|
||||
Key key,
|
||||
@required this.userDetails,
|
||||
Key? key,
|
||||
required this.userDetails,
|
||||
}) : super(key: key);
|
||||
|
||||
final UserDetails userDetails;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String familyAdmin = userDetails.familyData.members
|
||||
final String familyAdmin = userDetails.familyData!.members!
|
||||
.firstWhere((element) => element.isAdmin)
|
||||
.email;
|
||||
return Padding(
|
||||
|
@ -102,7 +99,7 @@ class ChildSubscriptionWidget extends StatelessWidget {
|
|||
),
|
||||
TextSpan(
|
||||
text: "support@ente.io",
|
||||
style: Theme.of(context).textTheme.bodyText2.copyWith(
|
||||
style: Theme.of(context).textTheme.bodyText2?.copyWith(
|
||||
color: const Color.fromRGBO(29, 185, 84, 1),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -12,7 +12,6 @@ import 'package:photos/services/billing_service.dart';
|
|||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/ui/common/loading_widget.dart';
|
||||
import 'package:photos/ui/common/progress_dialog.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
||||
class PaymentWebPage extends StatefulWidget {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/events/subscription_purchased_event.dart';
|
||||
|
@ -10,8 +8,8 @@ import 'package:photos/ui/home_widget.dart';
|
|||
|
||||
class SkipSubscriptionWidget extends StatelessWidget {
|
||||
const SkipSubscriptionWidget({
|
||||
Key key,
|
||||
@required this.freePlan,
|
||||
Key? key,
|
||||
required this.freePlan,
|
||||
}) : super(key: key);
|
||||
|
||||
final FreePlan freePlan;
|
||||
|
@ -24,10 +22,10 @@ class SkipSubscriptionWidget extends StatelessWidget {
|
|||
margin: const EdgeInsets.fromLTRB(0, 30, 0, 0),
|
||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
|
||||
child: OutlinedButton(
|
||||
style: Theme.of(context).outlinedButtonTheme.style.copyWith(
|
||||
style: Theme.of(context).outlinedButtonTheme.style?.copyWith(
|
||||
textStyle: MaterialStateProperty.resolveWith<TextStyle>(
|
||||
(Set<MaterialState> states) {
|
||||
return Theme.of(context).textTheme.subtitle1;
|
||||
return Theme.of(context).textTheme.subtitle1!;
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -15,7 +15,6 @@ import 'package:photos/ui/common/dialogs.dart';
|
|||
import 'package:photos/ui/common/loading_widget.dart';
|
||||
import 'package:photos/ui/common/progress_dialog.dart';
|
||||
import 'package:photos/ui/common/web_page.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/payment/child_subscription_widget.dart';
|
||||
import 'package:photos/ui/payment/payment_web_page.dart';
|
||||
import 'package:photos/ui/payment/skip_subscription_widget.dart';
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/services/feature_flag_service.dart';
|
||||
|
@ -24,5 +22,5 @@ StatefulWidget getSubscriptionPage({bool isOnBoarding = false}) {
|
|||
// users who might have paid via playStore. This method should be removed once
|
||||
// we have better handling for active play/app store subscription & stripe plans.
|
||||
bool _isUserCreatedPostStripeSupport() {
|
||||
return Configuration.instance.getUserID() > 1580559962386460;
|
||||
return Configuration.instance.getUserID()! > 1580559962386460;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:photos/services/billing_service.dart';
|
|||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/ui/common/loading_widget.dart';
|
||||
import 'package:photos/ui/common/progress_dialog.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/payment/child_subscription_widget.dart';
|
||||
import 'package:photos/ui/payment/skip_subscription_widget.dart';
|
||||
import 'package:photos/ui/payment/subscription_common_widgets.dart';
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/services/update_service.dart';
|
||||
import 'package:photos/theme/ente_theme.dart';
|
||||
|
@ -14,7 +12,7 @@ import 'package:photos/utils/toast_util.dart';
|
|||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class AboutSectionWidget extends StatelessWidget {
|
||||
const AboutSectionWidget({Key key}) : super(key: key);
|
||||
const AboutSectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -96,12 +94,12 @@ class AboutSectionWidget extends StatelessWidget {
|
|||
class AboutMenuItemWidget extends StatelessWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final String webPageTitle;
|
||||
final String? webPageTitle;
|
||||
const AboutMenuItemWidget({
|
||||
@required this.title,
|
||||
@required this.url,
|
||||
required this.title,
|
||||
required this.url,
|
||||
this.webPageTitle,
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -13,14 +11,14 @@ import 'package:photos/ui/account/delete_account_page.dart';
|
|||
import 'package:photos/ui/account/password_entry_page.dart';
|
||||
import 'package:photos/ui/account/recovery_key_page.dart';
|
||||
import 'package:photos/ui/components/captioned_text_widget.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/components/expandable_menu_item_widget.dart';
|
||||
import 'package:photos/ui/components/menu_item_widget.dart';
|
||||
import 'package:photos/ui/settings/common_settings.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/navigation_util.dart';
|
||||
|
||||
class AccountSectionWidget extends StatelessWidget {
|
||||
const AccountSectionWidget({Key key}) : super(key: key);
|
||||
const AccountSectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
class AppVersionWidget extends StatefulWidget {
|
||||
const AppVersionWidget({
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -16,7 +14,7 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
|
|||
static const kTapThresholdForInspector = 5;
|
||||
static const kConsecutiveTapTimeWindowInMilliseconds = 2000;
|
||||
|
||||
int _lastTap;
|
||||
int? _lastTap;
|
||||
int _consecutiveTaps = 0;
|
||||
|
||||
@override
|
||||
|
@ -35,14 +33,14 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
|
|||
}
|
||||
_lastTap = now;
|
||||
},
|
||||
child: FutureBuilder(
|
||||
child: FutureBuilder<String>(
|
||||
future: _getAppVersion(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Text(
|
||||
"Version: " + snapshot.data,
|
||||
"Version: " + snapshot.data!,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
import 'package:photos/models/backup_status.dart';
|
||||
import 'package:photos/models/duplicate_files.dart';
|
||||
import 'package:photos/services/deduplication_service.dart';
|
||||
|
@ -16,6 +15,7 @@ import 'package:photos/ui/components/captioned_text_widget.dart';
|
|||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/components/expandable_menu_item_widget.dart';
|
||||
import 'package:photos/ui/components/menu_item_widget.dart';
|
||||
import 'package:photos/ui/components/models/button_type.dart';
|
||||
import 'package:photos/ui/settings/common_settings.dart';
|
||||
import 'package:photos/ui/tools/deduplicate_page.dart';
|
||||
import 'package:photos/ui/tools/free_space_page.dart';
|
||||
|
@ -162,45 +162,30 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
|
|||
}
|
||||
|
||||
void _showSpaceFreedDialog(BackupStatus status) {
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text("Success"),
|
||||
content: Text(
|
||||
"You have successfully freed up " + formatBytes(status.size) + "!",
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Rate us",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.greenAlternative,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
final url = UpdateService.instance.getRateDetails().item2;
|
||||
launchUrlString(url);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Ok",
|
||||
),
|
||||
onPressed: () {
|
||||
if (Platform.isIOS) {
|
||||
showToast(
|
||||
context,
|
||||
"Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
|
||||
);
|
||||
}
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
},
|
||||
),
|
||||
],
|
||||
final DialogWidget dialog = choiceDialog(
|
||||
title: "Success",
|
||||
body: "You have successfully freed up " + formatBytes(status.size) + "!",
|
||||
firstButtonLabel: "Rate us",
|
||||
firstButtonOnTap: () async {
|
||||
final url = UpdateService.instance.getRateDetails().item2;
|
||||
launchUrlString(url);
|
||||
},
|
||||
firstButtonType: ButtonType.primary,
|
||||
secondButtonLabel: "OK",
|
||||
secondButtonOnTap: () async {
|
||||
if (Platform.isIOS) {
|
||||
showToast(
|
||||
context,
|
||||
"Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
showConfettiDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
dialogBuilder: (BuildContext context) {
|
||||
return dialog;
|
||||
},
|
||||
barrierColor: Colors.black87,
|
||||
confettiAlignment: Alignment.topCenter,
|
||||
|
@ -212,48 +197,33 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
|
|||
final String countText = result.count.toString() +
|
||||
" duplicate file" +
|
||||
(result.count == 1 ? "" : "s");
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text("✨ Success"),
|
||||
content: Text(
|
||||
"You have cleaned up " +
|
||||
countText +
|
||||
", saving " +
|
||||
formatBytes(result.size) +
|
||||
"!",
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Rate us",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.greenAlternative,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
// TODO: Replace with https://pub.dev/packages/in_app_review
|
||||
final url = UpdateService.instance.getRateDetails().item2;
|
||||
launchUrlString(url);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Ok",
|
||||
),
|
||||
onPressed: () {
|
||||
showShortToast(
|
||||
context,
|
||||
"Also empty your \"Trash\" to claim the freed up space",
|
||||
);
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
},
|
||||
),
|
||||
],
|
||||
final DialogWidget dialog = choiceDialog(
|
||||
title: "✨ Success",
|
||||
body: "You have cleaned up " +
|
||||
countText +
|
||||
", saving " +
|
||||
formatBytes(result.size) +
|
||||
"!",
|
||||
firstButtonLabel: "Rate us",
|
||||
firstButtonOnTap: () async {
|
||||
// TODO: Replace with https://pub.dev/packages/in_app_review
|
||||
final url = UpdateService.instance.getRateDetails().item2;
|
||||
launchUrlString(url);
|
||||
},
|
||||
firstButtonType: ButtonType.primary,
|
||||
secondButtonLabel: "OK",
|
||||
secondButtonOnTap: () async {
|
||||
showShortToast(
|
||||
context,
|
||||
"Also empty your \"Trash\" to claim the freed up space",
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
showConfettiDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
dialogBuilder: (BuildContext context) {
|
||||
return dialog;
|
||||
},
|
||||
barrierColor: Colors.black87,
|
||||
confettiAlignment: Alignment.topCenter,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_sodium/flutter_sodium.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
|
@ -15,7 +13,7 @@ import 'package:photos/ui/settings/common_settings.dart';
|
|||
import 'package:photos/utils/toast_util.dart';
|
||||
|
||||
class DebugSectionWidget extends StatelessWidget {
|
||||
const DebugSectionWidget({Key key}) : super(key: key);
|
||||
const DebugSectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -75,7 +73,7 @@ class DebugSectionWidget extends StatelessWidget {
|
|||
}
|
||||
|
||||
void _showKeyAttributesDialog(BuildContext context) {
|
||||
final keyAttributes = Configuration.instance.getKeyAttributes();
|
||||
final keyAttributes = Configuration.instance.getKeyAttributes()!;
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text("key attributes"),
|
||||
content: SingleChildScrollView(
|
||||
|
@ -85,7 +83,7 @@ class DebugSectionWidget extends StatelessWidget {
|
|||
"Key",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(Sodium.bin2base64(Configuration.instance.getKey())),
|
||||
Text(Sodium.bin2base64(Configuration.instance.getKey()!)),
|
||||
const Padding(padding: EdgeInsets.all(12)),
|
||||
const Text(
|
||||
"Encrypted Key",
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/services/billing_service.dart';
|
||||
import 'package:photos/services/user_service.dart';
|
||||
|
@ -14,7 +12,7 @@ import 'package:photos/utils/dialog_util.dart';
|
|||
import 'package:photos/utils/navigation_util.dart';
|
||||
|
||||
class GeneralSectionWidget extends StatelessWidget {
|
||||
const GeneralSectionWidget({Key key}) : super(key: key);
|
||||
const GeneralSectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
|
@ -20,7 +18,7 @@ import 'package:photos/ui/components/toggle_switch_widget.dart';
|
|||
import 'package:photos/ui/settings/common_settings.dart';
|
||||
|
||||
class SecuritySectionWidget extends StatefulWidget {
|
||||
const SecuritySectionWidget({Key key}) : super(key: key);
|
||||
const SecuritySectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SecuritySectionWidget> createState() => _SecuritySectionWidgetState();
|
||||
|
@ -29,7 +27,8 @@ class SecuritySectionWidget extends StatefulWidget {
|
|||
class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
||||
final _config = Configuration.instance;
|
||||
|
||||
StreamSubscription<TwoFactorStatusChangeEvent> _twoFactorStatusChangeEvent;
|
||||
late StreamSubscription<TwoFactorStatusChangeEvent>
|
||||
_twoFactorStatusChangeEvent;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingsTextItem extends StatelessWidget {
|
||||
final String text;
|
||||
final IconData icon;
|
||||
const SettingsTextItem({
|
||||
Key key,
|
||||
@required this.text,
|
||||
@required this.icon,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.all(Platform.isIOS ? 4 : 6)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(text, style: Theme.of(context).textTheme.subtitle1),
|
||||
),
|
||||
Icon(icon),
|
||||
],
|
||||
),
|
||||
Padding(padding: EdgeInsets.all(Platform.isIOS ? 4 : 6)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/services/update_service.dart';
|
||||
import 'package:photos/theme/ente_theme.dart';
|
||||
|
@ -10,7 +8,7 @@ import 'package:photos/ui/settings/common_settings.dart';
|
|||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class SocialSectionWidget extends StatelessWidget {
|
||||
const SocialSectionWidget({Key key}) : super(key: key);
|
||||
const SocialSectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -60,7 +58,7 @@ class SocialSectionWidget extends StatelessWidget {
|
|||
class SocialsMenuItemWidget extends StatelessWidget {
|
||||
final String text;
|
||||
final String urlSring;
|
||||
const SocialsMenuItemWidget(this.text, this.urlSring, {Key key})
|
||||
const SocialsMenuItemWidget(this.text, this.urlSring, {Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -15,7 +13,7 @@ import 'package:photos/ui/settings/common_settings.dart';
|
|||
import 'package:photos/utils/email_util.dart';
|
||||
|
||||
class SupportSectionWidget extends StatelessWidget {
|
||||
const SupportSectionWidget({Key key}) : super(key: key);
|
||||
const SupportSectionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -63,7 +61,9 @@ class SupportSectionWidget extends StatelessWidget {
|
|||
final endpoint = Configuration.instance.getHttpEndpoint() +
|
||||
"/users/roadmap";
|
||||
final url = Configuration.instance.isLoggedIn()
|
||||
? endpoint + "?token=" + Configuration.instance.getToken()
|
||||
? endpoint +
|
||||
"?token=" +
|
||||
Configuration.instance.getToken()!
|
||||
: roadmapURL;
|
||||
return WebPage("Suggest features", url);
|
||||
},
|
||||
|
|
|
@ -15,7 +15,6 @@ import 'package:photos/theme/ente_theme.dart';
|
|||
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
|
||||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/components/captioned_text_widget.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/components/divider_widget.dart';
|
||||
import 'package:photos/ui/components/menu_item_widget.dart';
|
||||
import 'package:photos/ui/components/menu_section_description_widget.dart';
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fast_base58/fast_base58.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -25,14 +23,14 @@ import 'package:photos/utils/toast_util.dart';
|
|||
class ShareCollectionPage extends StatefulWidget {
|
||||
final Collection collection;
|
||||
|
||||
const ShareCollectionPage(this.collection, {Key key}) : super(key: key);
|
||||
const ShareCollectionPage(this.collection, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ShareCollectionPage> createState() => _ShareCollectionPageState();
|
||||
}
|
||||
|
||||
class _ShareCollectionPageState extends State<ShareCollectionPage> {
|
||||
List<User> _sharees;
|
||||
late List<User?> _sharees;
|
||||
final Logger _logger = Logger("SharingDialogState");
|
||||
final CollectionActions collectionActions =
|
||||
CollectionActions(CollectionsService.instance);
|
||||
|
@ -132,7 +130,7 @@ class _ShareCollectionPageState extends State<ShareCollectionPage> {
|
|||
CollectionsService.instance.getCollectionKey(widget.collection.id),
|
||||
);
|
||||
final String url =
|
||||
"${widget.collection.publicURLs.first.url}#$collectionKey";
|
||||
"${widget.collection.publicURLs!.first!.url}#$collectionKey";
|
||||
children.addAll(
|
||||
[
|
||||
MenuItemWidget(
|
||||
|
@ -235,8 +233,8 @@ class _ShareCollectionPageState extends State<ShareCollectionPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
widget.collection.name,
|
||||
style: Theme.of(context).textTheme.headline5.copyWith(fontSize: 16),
|
||||
widget.collection.name ?? "Unnamed",
|
||||
style: Theme.of(context).textTheme.headline5?.copyWith(fontSize: 16),
|
||||
),
|
||||
elevation: 0,
|
||||
centerTitle: false,
|
||||
|
@ -260,12 +258,12 @@ class _ShareCollectionPageState extends State<ShareCollectionPage> {
|
|||
|
||||
class EmailItemWidget extends StatelessWidget {
|
||||
final Collection collection;
|
||||
final Function onTap;
|
||||
final Function? onTap;
|
||||
|
||||
const EmailItemWidget(
|
||||
this.collection, {
|
||||
this.onTap,
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -291,7 +289,7 @@ class EmailItemWidget extends StatelessWidget {
|
|||
trailingIcon: Icons.chevron_right,
|
||||
onTap: () async {
|
||||
if (onTap != null) {
|
||||
onTap();
|
||||
onTap!();
|
||||
}
|
||||
},
|
||||
isBottomBorderRadiusRemoved: true,
|
||||
|
@ -317,7 +315,7 @@ class EmailItemWidget extends StatelessWidget {
|
|||
trailingIcon: Icons.chevron_right,
|
||||
onTap: () async {
|
||||
if (onTap != null) {
|
||||
onTap();
|
||||
onTap!();
|
||||
}
|
||||
},
|
||||
isBottomBorderRadiusRemoved: true,
|
||||
|
|
|
@ -158,6 +158,8 @@ class _AppStorageViewerState extends State<AppStorageViewer> {
|
|||
),
|
||||
menuItemColor:
|
||||
getEnteColorScheme(context).fillFaint,
|
||||
pressedColor:
|
||||
getEnteColorScheme(context).fillFaintPressed,
|
||||
borderRadius: 8,
|
||||
onTap: () async {
|
||||
for (var pathItem in paths) {
|
||||
|
|
|
@ -25,7 +25,6 @@ import 'package:photos/services/hidden_service.dart';
|
|||
import 'package:photos/services/ignored_files_service.dart';
|
||||
import 'package:photos/services/local_sync_service.dart';
|
||||
import 'package:photos/ui/common/progress_dialog.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/create_collection_page.dart';
|
||||
import 'package:photos/ui/viewer/file/custom_app_bar.dart';
|
||||
import 'package:photos/utils/delete_file_util.dart';
|
||||
|
|
|
@ -22,6 +22,7 @@ import 'package:photos/services/update_service.dart';
|
|||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/common/rename_dialog.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/components/models/button_type.dart';
|
||||
import 'package:photos/ui/sharing/album_participants_page.dart';
|
||||
import 'package:photos/ui/sharing/share_collection_page.dart';
|
||||
import 'package:photos/ui/tools/free_space_page.dart';
|
||||
|
@ -200,46 +201,31 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
|
|||
}
|
||||
|
||||
void _showSpaceFreedDialog(BackupStatus status) {
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text("Success"),
|
||||
content: Text(
|
||||
"You have successfully freed up " + formatBytes(status.size) + "!",
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Rate us",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.greenAlternative,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
// TODO: Replace with https://pub.dev/packages/in_app_review
|
||||
final url = UpdateService.instance.getRateDetails().item2;
|
||||
launchUrlString(url);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Ok",
|
||||
),
|
||||
onPressed: () {
|
||||
if (Platform.isIOS) {
|
||||
showToast(
|
||||
context,
|
||||
"Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
|
||||
);
|
||||
}
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
},
|
||||
),
|
||||
],
|
||||
final DialogWidget dialog = choiceDialog(
|
||||
title: "Success",
|
||||
body: "You have successfully freed up " + formatBytes(status.size) + "!",
|
||||
firstButtonLabel: "Rate us",
|
||||
firstButtonOnTap: () async {
|
||||
// TODO: Replace with https://pub.dev/packages/in_app_review
|
||||
final url = UpdateService.instance.getRateDetails().item2;
|
||||
launchUrlString(url);
|
||||
},
|
||||
firstButtonType: ButtonType.primary,
|
||||
secondButtonLabel: "OK",
|
||||
secondButtonOnTap: () async {
|
||||
if (Platform.isIOS) {
|
||||
showToast(
|
||||
context,
|
||||
"Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
showConfettiDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
dialogBuilder: (BuildContext context) {
|
||||
return dialog;
|
||||
},
|
||||
barrierColor: Colors.black87,
|
||||
confettiAlignment: Alignment.topCenter,
|
||||
|
|
|
@ -18,7 +18,6 @@ import 'package:photos/models/magic_metadata.dart';
|
|||
import 'package:photos/models/selected_files.dart';
|
||||
import 'package:photos/services/collections_service.dart';
|
||||
import 'package:photos/services/hidden_service.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/create_collection_page.dart';
|
||||
import 'package:photos/utils/delete_file_util.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
|
||||
class NoResultWidget extends StatelessWidget {
|
||||
const NoResultWidget({Key key}) : super(key: key);
|
||||
const NoResultWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -24,7 +24,6 @@ import 'package:photos/services/sync_service.dart';
|
|||
import 'package:photos/services/trash_sync_service.dart';
|
||||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/common/linear_progress_dialog.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/file_util.dart';
|
||||
import 'package:photos/utils/toast_util.dart';
|
||||
|
|
|
@ -1,11 +1,136 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:confetti/confetti.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/core/constants.dart';
|
||||
import 'package:photos/ui/common/loading_widget.dart';
|
||||
import 'package:photos/ui/common/progress_dialog.dart';
|
||||
import 'package:photos/ui/components/button_widget.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/components/models/button_type.dart';
|
||||
|
||||
typedef DialogBuilder = DialogWidget Function(BuildContext context);
|
||||
|
||||
///Will return null if dismissed by tapping outside
|
||||
Future<ButtonAction?> showErrorDialog(
|
||||
BuildContext context,
|
||||
String title,
|
||||
String? body, {
|
||||
bool isDismissable = true,
|
||||
}) async {
|
||||
return showDialogWidget(
|
||||
context: context,
|
||||
title: title,
|
||||
body: body,
|
||||
isDismissible: isDismissable,
|
||||
buttons: const [
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.secondary,
|
||||
labelText: "OK",
|
||||
isInAlert: true,
|
||||
buttonAction: ButtonAction.first,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
///Will return null if dismissed by tapping outside
|
||||
Future<ButtonAction?> showGenericErrorDialog({
|
||||
required BuildContext context,
|
||||
bool isDismissible = true,
|
||||
}) async {
|
||||
return showDialogWidget(
|
||||
context: context,
|
||||
title: "Error",
|
||||
icon: Icons.error_outline_outlined,
|
||||
body: "It looks like something went wrong. Please try again.",
|
||||
isDismissible: isDismissible,
|
||||
buttons: const [
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.secondary,
|
||||
labelText: "OK",
|
||||
isInAlert: true,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
DialogWidget choiceDialog({
|
||||
required String title,
|
||||
String? body,
|
||||
required String firstButtonLabel,
|
||||
String secondButtonLabel = "Cancel",
|
||||
ButtonType firstButtonType = ButtonType.neutral,
|
||||
ButtonType secondButtonType = ButtonType.secondary,
|
||||
ButtonAction firstButtonAction = ButtonAction.first,
|
||||
ButtonAction secondButtonAction = ButtonAction.cancel,
|
||||
FutureVoidCallback? firstButtonOnTap,
|
||||
FutureVoidCallback? secondButtonOnTap,
|
||||
bool isCritical = false,
|
||||
IconData? icon,
|
||||
}) {
|
||||
final buttons = [
|
||||
ButtonWidget(
|
||||
buttonType: isCritical ? ButtonType.critical : firstButtonType,
|
||||
labelText: firstButtonLabel,
|
||||
isInAlert: true,
|
||||
onTap: firstButtonOnTap,
|
||||
buttonAction: firstButtonAction,
|
||||
),
|
||||
ButtonWidget(
|
||||
buttonType: secondButtonType,
|
||||
labelText: secondButtonLabel,
|
||||
isInAlert: true,
|
||||
onTap: secondButtonOnTap,
|
||||
buttonAction: secondButtonAction,
|
||||
),
|
||||
];
|
||||
|
||||
return DialogWidget(title: title, body: body, buttons: buttons, icon: icon);
|
||||
}
|
||||
|
||||
///Will return null if dismissed by tapping outside
|
||||
Future<ButtonAction?> showNewChoiceDialog({
|
||||
required BuildContext context,
|
||||
required String title,
|
||||
String? body,
|
||||
required String firstButtonLabel,
|
||||
String secondButtonLabel = "Cancel",
|
||||
ButtonType firstButtonType = ButtonType.neutral,
|
||||
ButtonType secondButtonType = ButtonType.secondary,
|
||||
ButtonAction firstButtonAction = ButtonAction.first,
|
||||
ButtonAction secondButtonAction = ButtonAction.cancel,
|
||||
FutureVoidCallback? firstButtonOnTap,
|
||||
FutureVoidCallback? secondButtonOnTap,
|
||||
bool isCritical = false,
|
||||
IconData? icon,
|
||||
bool isDismissible = true,
|
||||
}) async {
|
||||
final buttons = [
|
||||
ButtonWidget(
|
||||
buttonType: isCritical ? ButtonType.critical : firstButtonType,
|
||||
labelText: firstButtonLabel,
|
||||
isInAlert: true,
|
||||
onTap: firstButtonOnTap,
|
||||
buttonAction: firstButtonAction,
|
||||
),
|
||||
ButtonWidget(
|
||||
buttonType: secondButtonType,
|
||||
labelText: secondButtonLabel,
|
||||
isInAlert: true,
|
||||
onTap: secondButtonOnTap,
|
||||
buttonAction: secondButtonAction,
|
||||
),
|
||||
];
|
||||
return showDialogWidget(
|
||||
context: context,
|
||||
title: title,
|
||||
body: body,
|
||||
buttons: buttons,
|
||||
icon: icon,
|
||||
isDismissible: isDismissible,
|
||||
);
|
||||
}
|
||||
|
||||
ProgressDialog createProgressDialog(
|
||||
BuildContext context,
|
||||
|
@ -30,56 +155,20 @@ ProgressDialog createProgressDialog(
|
|||
return dialog;
|
||||
}
|
||||
|
||||
Future<dynamic> showErrorDialog(
|
||||
BuildContext context,
|
||||
String title,
|
||||
String content,
|
||||
) {
|
||||
final AlertDialog alert = AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
title: title.isEmpty
|
||||
? const SizedBox.shrink()
|
||||
: Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
content: Text(content),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Ok",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
},
|
||||
barrierColor: Colors.black12,
|
||||
);
|
||||
}
|
||||
|
||||
Future<T> showConfettiDialog<T>({
|
||||
@required BuildContext context,
|
||||
WidgetBuilder builder,
|
||||
Future<ButtonAction?> showConfettiDialog<T>({
|
||||
required BuildContext context,
|
||||
required DialogBuilder dialogBuilder,
|
||||
bool barrierDismissible = true,
|
||||
Color barrierColor,
|
||||
Color? barrierColor,
|
||||
bool useSafeArea = true,
|
||||
bool useRootNavigator = true,
|
||||
RouteSettings routeSettings,
|
||||
RouteSettings? routeSettings,
|
||||
Alignment confettiAlignment = Alignment.center,
|
||||
}) {
|
||||
final widthOfScreen = MediaQuery.of(context).size.width;
|
||||
final isMobileSmall = widthOfScreen <= mobileSmallThreshold;
|
||||
final pageBuilder = Builder(
|
||||
builder: builder,
|
||||
builder: dialogBuilder,
|
||||
);
|
||||
final ConfettiController confettiController =
|
||||
ConfettiController(duration: const Duration(seconds: 1));
|
||||
|
@ -87,22 +176,25 @@ Future<T> showConfettiDialog<T>({
|
|||
return showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext buildContext) {
|
||||
return Stack(
|
||||
children: [
|
||||
pageBuilder,
|
||||
Align(
|
||||
alignment: confettiAlignment,
|
||||
child: ConfettiWidget(
|
||||
confettiController: confettiController,
|
||||
blastDirection: pi / 2,
|
||||
emissionFrequency: 0,
|
||||
numberOfParticles: 100,
|
||||
// a lot of particles at once
|
||||
gravity: 1,
|
||||
blastDirectionality: BlastDirectionality.explosive,
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: isMobileSmall ? 8 : 0),
|
||||
child: Stack(
|
||||
children: [
|
||||
Align(alignment: Alignment.center, child: pageBuilder),
|
||||
Align(
|
||||
alignment: confettiAlignment,
|
||||
child: ConfettiWidget(
|
||||
confettiController: confettiController,
|
||||
blastDirection: pi / 2,
|
||||
emissionFrequency: 0,
|
||||
numberOfParticles: 100,
|
||||
// a lot of particles at once
|
||||
gravity: 1,
|
||||
blastDirectionality: BlastDirectionality.explosive,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
barrierDismissible: barrierDismissible,
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:photos/core/configuration.dart';
|
|||
import 'package:photos/core/error-reporting/super_logging.dart';
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
import 'package:photos/ui/common/dialogs.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/ui/tools/debug/log_file_viewer.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/toast_util.dart';
|
||||
|
|
|
@ -10,7 +10,6 @@ import 'package:photos/core/configuration.dart';
|
|||
import 'package:photos/core/constants.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/models/file_type.dart';
|
||||
import 'package:photos/ui/components/dialog_widget.dart';
|
||||
import 'package:photos/utils/date_time_util.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/exif_util.dart';
|
||||
|
|
Loading…
Reference in a new issue