diff --git a/lib/ui/app_update_dialog.dart b/lib/ui/app_update_dialog.dart index db0c8efef..c019ca325 100644 --- a/lib/ui/app_update_dialog.dart +++ b/lib/ui/app_update_dialog.dart @@ -140,8 +140,8 @@ class _ApkDownloaderDialogState extends State { } catch (e) { Logger("ApkDownloader").severe(e); AlertDialog alert = AlertDialog( - title: Text("sorry"), - content: Text("the download could not be completed"), + title: Text("Sorry"), + content: Text("The download could not be completed"), actions: [ TextButton( child: Text( diff --git a/lib/ui/blurred_file_backdrop.dart b/lib/ui/blurred_file_backdrop.dart deleted file mode 100644 index 9e4ba89f1..000000000 --- a/lib/ui/blurred_file_backdrop.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:photos/models/file.dart'; -import 'package:photos/ui/thumbnail_widget.dart'; - -class BlurredFileBackdrop extends StatelessWidget { - final File file; - - BlurredFileBackdrop(this.file, {Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ImageFiltered( - imageFilter: ImageFilter.blur(sigmaX: 64.0, sigmaY: 64.0), - child: ThumbnailWidget( - file, - fit: BoxFit.cover, - key: Key("memory_backdrop" + file.tag()), - ), - ); - } -} diff --git a/lib/ui/detail_page.dart b/lib/ui/detail_page.dart index a5abdf450..531f6a577 100644 --- a/lib/ui/detail_page.dart +++ b/lib/ui/detail_page.dart @@ -1,5 +1,4 @@ import 'package:extended_image/extended_image.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:logging/logging.dart'; @@ -265,7 +264,7 @@ class _DetailPageState extends State { file.ownerID != Configuration.instance.getUserID()) { _logger.severe("Attempt to edit unowned file", UnauthorizedEditError(), StackTrace.current); - showErrorDialog(context, "sorry", + showErrorDialog(context, "Sorry", "we don't support editing photos and albums that you don't own yet"); return; } diff --git a/lib/ui/email_entry_page.dart b/lib/ui/email_entry_page.dart index 9a60e8931..64eff34ee 100644 --- a/lib/ui/email_entry_page.dart +++ b/lib/ui/email_entry_page.dart @@ -11,13 +11,9 @@ import 'package:photos/models/billing_plan.dart'; import 'package:photos/services/billing_service.dart'; import 'package:photos/services/user_service.dart'; import 'package:photos/ui/common/dynamicFAB.dart'; -//import 'package:photos/ui/common/report_bug_popup.dart'; -//import 'package:photos/ui/common_elements.dart'; import 'package:photos/ui/loading_widget.dart'; import 'package:photos/ui/web_page.dart'; import 'package:photos/utils/data_util.dart'; -//import 'package:photos/utils/dialog_util.dart'; -//import 'package:photos/utils/email_util.dart'; import 'package:step_progress_indicator/step_progress_indicator.dart'; class EmailEntryPage extends StatefulWidget { diff --git a/lib/ui/fading_app_bar.dart b/lib/ui/fading_app_bar.dart index c8b9d4d08..3e4676aa7 100644 --- a/lib/ui/fading_app_bar.dart +++ b/lib/ui/fading_app_bar.dart @@ -215,7 +215,7 @@ class FadingAppBarState extends State { } catch (e, s) { _logger.severe(e, s); hasError = true; - showToast("sorry, could not add this to favorites!"); + showToast("Sorry, could not add this to favorites!"); } finally { if (shouldBlockUser) { await dialog.hide(); @@ -227,7 +227,7 @@ class FadingAppBarState extends State { } catch (e, s) { _logger.severe(e, s); hasError = true; - showToast("sorry, could not remove this from favorites!"); + showToast("Sorry, could not remove this from favorites!"); } } return hasError ? oldValue : isLiked; diff --git a/lib/ui/memories_widget.dart b/lib/ui/memories_widget.dart index a8cc3219f..bbb9695ef 100644 --- a/lib/ui/memories_widget.dart +++ b/lib/ui/memories_widget.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:photos/models/memory.dart'; import 'package:photos/services/memories_service.dart'; -import 'package:photos/ui/blurred_file_backdrop.dart'; import 'package:photos/ui/extents_page_view.dart'; import 'package:photos/ui/file_widget.dart'; import 'package:photos/ui/thumbnail_widget.dart'; @@ -10,6 +8,7 @@ import 'package:photos/utils/date_time_util.dart'; import 'package:photos/utils/file_util.dart'; import 'package:photos/utils/navigation_util.dart'; import 'package:photos/utils/share_util.dart'; +import 'package:step_progress_indicator/step_progress_indicator.dart'; class MemoriesWidget extends StatelessWidget { const MemoriesWidget({Key key}) : super(key: key); @@ -22,9 +21,14 @@ class MemoriesWidget extends StatelessWidget { if (snapshot.hasError || !snapshot.hasData || snapshot.data.isEmpty) { return Container(); } else { - return Padding( - padding: const EdgeInsets.all(8.0), - child: _buildMemories(snapshot.data), + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildMemories(snapshot.data), + Divider( + thickness: 1, + ) + ], ); } }, @@ -96,7 +100,7 @@ class _MemoryWidgetState extends State { }, child: SizedBox( width: 100, - height: 120, + height: 100, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -109,10 +113,10 @@ class _MemoryWidgetState extends State { type: MaterialType.transparency, child: Text( title, - style: TextStyle( - fontSize: 12, - color: Colors.white60, - ), + style: Theme.of(context) + .textTheme + .subtitle1 + .copyWith(fontSize: 12), textAlign: TextAlign.center, ), ), @@ -139,8 +143,8 @@ class _MemoryWidgetState extends State { ), child: ClipOval( child: SizedBox( - width: isSeen ? 76 : 72, - height: isSeen ? 76 : 72, + width: isSeen ? 60 : 56, + height: isSeen ? 60 : 56, child: Hero( tag: "memories" + memory.file.tag(), child: ThumbnailWidget( @@ -225,27 +229,69 @@ class _FullScreenMemoryState extends State { final file = widget.memories[_index].file; return Scaffold( appBar: AppBar( - title: Text(getFormattedDate( - DateTime.fromMicrosecondsSinceEpoch(file.creationTime))), + toolbarHeight: 84, + automaticallyImplyLeading: false, + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + StepProgressIndicator( + totalSteps: widget.memories.length, + currentStep: _index + 1, + size: 2, + selectedColor: Colors.white, //same for both themes + unselectedColor: Colors.white.withOpacity(0.4), + ), + SizedBox( + height: 18, + ), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 16), + child: InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Icon( + Icons.close, + color: Colors.white, //same for both themes + ), + ), + ), + Text( + getFormattedDate( + DateTime.fromMicrosecondsSinceEpoch(file.creationTime)), + style: Theme.of(context).textTheme.subtitle1.copyWith( + fontSize: 14, color: Colors.white), //same for both themes + ), + ], + ), + ], + ), + flexibleSpace: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.black.withOpacity(0.6), + Colors.black.withOpacity(0.5), + Colors.transparent, + ], + stops: const [0, 0.6, 1], + )), + ), backgroundColor: Color(0x00000000), elevation: 0, - actions: [ - IconButton( - icon: Icon(Icons.share), - onPressed: () { - share(context, [file]); - }, - ), - ], ), extendBodyBehindAppBar: true, body: Container( color: Colors.black, - child: Stack(children: [ - BlurredFileBackdrop(file), + child: Stack(alignment: Alignment.bottomCenter, children: [ _buildSwiper(), + bottomGradient(), _buildTitleText(), - _buildIndexText(), + _buildBottomIcons(), ]), ), ); @@ -256,37 +302,50 @@ class _FullScreenMemoryState extends State { tag: widget.title, child: Container( alignment: Alignment.bottomCenter, - padding: EdgeInsets.fromLTRB(0, 0, 0, 160), + padding: EdgeInsets.fromLTRB(0, 0, 0, 28), child: AnimatedOpacity( opacity: _opacity, duration: Duration(milliseconds: 500), - child: Material( - type: MaterialType.transparency, - child: Text( - widget.title, - style: TextStyle( - fontSize: 40, - fontWeight: FontWeight.bold, - decoration: TextDecoration.none), - ), - ), + child: Text(widget.title, + style: Theme.of(context) + .textTheme + .headline4 + .copyWith(color: Colors.white)), ), ), ); } - Widget _buildIndexText() { + Widget _buildBottomIcons() { + final file = widget.memories[_index].file; return Container( - alignment: Alignment.bottomCenter, - padding: EdgeInsets.fromLTRB(0, 0, 0, 20), - child: Text( - (_index + 1).toString() + " / " + widget.memories.length.toString(), - style: TextStyle( - fontSize: 24, - decoration: TextDecoration.none, - color: Colors.white60, - ), - ), + alignment: Alignment.bottomRight, + padding: EdgeInsets.fromLTRB(0, 0, 26, 20), + child: IconButton( + icon: Icon( + Icons.adaptive.share, + color: Colors.white, + ), //same for both themes + onPressed: () { + share(context, [file]); + }, + )); + } + + Widget bottomGradient() { + return Container( + height: 124, + width: double.infinity, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [ + Colors.black.withOpacity(0.5), //same for both themes + Colors.transparent, + ], + stops: const [0, 0.8], + )), ); } diff --git a/lib/ui/password_entry_page.dart b/lib/ui/password_entry_page.dart index d2e2c7d51..010ca5b38 100644 --- a/lib/ui/password_entry_page.dart +++ b/lib/ui/password_entry_page.dart @@ -701,7 +701,7 @@ class _PasswordEntryPageState extends State { await dialog.hide(); if (e is UnsupportedError) { showErrorDialog(context, "insecure device", - "sorry, we could not generate secure keys on this device.\n\nplease sign up from a different device."); + "Sorry, we could not generate secure keys on this device.\n\nplease sign up from a different device."); } else { showGenericErrorDialog(context); } diff --git a/lib/ui/payment/stripe_subscription_page.dart b/lib/ui/payment/stripe_subscription_page.dart index 96a46c12f..4aab8f3b1 100644 --- a/lib/ui/payment/stripe_subscription_page.dart +++ b/lib/ui/payment/stripe_subscription_page.dart @@ -304,7 +304,7 @@ class _StripeSubscriptionPageState extends State { if (!_isStripeSubscriber && _hasActiveSubscription && _currentSubscription.productID != kFreeProductID) { - showErrorDialog(context, "sorry", + showErrorDialog(context, "Sorry", "please cancel your existing subscription from ${_currentSubscription.paymentProvider} first"); return; } @@ -314,7 +314,7 @@ class _StripeSubscriptionPageState extends State { await _dialog.hide(); if (usage > plan.storage) { showErrorDialog( - context, "sorry", "you cannot downgrade to this plan"); + context, "Sorry", "you cannot downgrade to this plan"); return; } } diff --git a/lib/ui/payment/subscription_page.dart b/lib/ui/payment/subscription_page.dart index 730c49d7a..5c3e5a716 100644 --- a/lib/ui/payment/subscription_page.dart +++ b/lib/ui/payment/subscription_page.dart @@ -29,7 +29,7 @@ class SubscriptionPage extends StatefulWidget { }) : super(key: key); @override - State createState() => _SubscriptionPageState(); + State createState() => _SubscriptionPageState(); } class _SubscriptionPageState extends State { @@ -59,8 +59,8 @@ class _SubscriptionPageState extends State { final productID = _isActiveStripeSubscriber ? plan.stripeID : Platform.isAndroid - ? plan.androidID - : plan.iosID; + ? plan.androidID + : plan.iosID; return productID != null && productID.isNotEmpty; }).toList(); _freePlan = billingPlans.freePlan; @@ -177,7 +177,7 @@ class _SubscriptionPageState extends State { widgets.add(ValidityWidget(currentSubscription: _currentSubscription)); } - if ( _currentSubscription.productID == kFreeProductID) { + if (_currentSubscription.productID == kFreeProductID) { if (widget.isOnboarding) { widgets.add(SkipSubscriptionWidget(freePlan: _freePlan)); } @@ -257,7 +257,7 @@ class _SubscriptionPageState extends State { if (isActive) { return; } - showErrorDialog(context, "sorry", + showErrorDialog(context, "Sorry", "please visit web.ente.io to manage your subscription"); }, child: SubscriptionPlanWidget( @@ -311,13 +311,13 @@ class _SubscriptionPageState extends State { if (usage > plan.storage) { await _dialog.hide(); showErrorDialog( - context, "sorry", "you cannot downgrade to this plan"); + context, "Sorry", "you cannot downgrade to this plan"); return; } } final ProductDetailsResponse response = - await InAppPurchaseConnection.instance - .queryProductDetails({productID}); + await InAppPurchaseConnection.instance + .queryProductDetails({productID}); if (response.notFoundIDs.isNotEmpty) { _logger.severe("Could not find products: " + response.notFoundIDs.toString()); @@ -331,8 +331,8 @@ class _SubscriptionPageState extends State { _currentSubscription.productID != plan.androidID; if (isCrossGradingOnAndroid) { final existingProductDetailsResponse = - await InAppPurchaseConnection.instance - .queryProductDetails({_currentSubscription.productID}); + await InAppPurchaseConnection.instance + .queryProductDetails({_currentSubscription.productID}); if (existingProductDetailsResponse.notFoundIDs.isNotEmpty) { _logger.severe("Could not find existing products: " + response.notFoundIDs.toString()); @@ -401,4 +401,3 @@ class _SubscriptionPageState extends State { ); } } - diff --git a/lib/ui/recovery_page.dart b/lib/ui/recovery_page.dart index 057b9f5ba..697075cb5 100644 --- a/lib/ui/recovery_page.dart +++ b/lib/ui/recovery_page.dart @@ -113,8 +113,8 @@ class _RecoveryPageState extends State { onTap: () { showErrorDialog( context, - "sorry", - "due to the nature of our end-to-end encryption protocol, your data cannot be decrypted without your password or recovery key", + "Sorry", + "Due to the nature of our end-to-end encryption protocol, your data cannot be decrypted without your password or recovery key", ); }, child: Container( diff --git a/lib/ui/share_collection_widget.dart b/lib/ui/share_collection_widget.dart index 4e4f0d149..86d02b8e6 100644 --- a/lib/ui/share_collection_widget.dart +++ b/lib/ui/share_collection_widget.dart @@ -397,9 +397,9 @@ class _SharingDialogState extends State { void _showUnSupportedAlert() { AlertDialog alert = AlertDialog( - title: Text("sorry"), + title: Text("Sorry"), content: - Text("sharing is not permitted for free accounts, please subscribe"), + Text("Sharing is not permitted for free accounts, please subscribe"), actions: [ TextButton( child: Text( diff --git a/lib/utils/date_time_util.dart b/lib/utils/date_time_util.dart index b9d225c6d..3ec52a572 100644 --- a/lib/utils/date_time_util.dart +++ b/lib/utils/date_time_util.dart @@ -72,6 +72,10 @@ String getFullMonth(DateTime dateTime) { return _fullMonths[dateTime.month]; } +String getAbbreviationOfYear(DateTime dateTime) { + return (dateTime.year % 100).toString(); +} + String getTime(DateTime dateTime) { final hours = dateTime.hour > 9 ? dateTime.hour.toString() @@ -95,13 +99,11 @@ String getFormattedTime(DateTime dateTime) { } String getFormattedDate(DateTime dateTime) { - return getDay(dateTime) + - ", " + - getMonth(dateTime) + + return dateTime.day.toString() + " " + - dateTime.day.toString() + - ", " + - dateTime.year.toString(); + getMonth(dateTime) + + "'" + + getAbbreviationOfYear(dateTime); } String daysLeft(int futureTime) {