Skip to content

Commit

Permalink
Preview (#27)
Browse files Browse the repository at this point in the history
* Implement local media preview

* Implement local media preview

* Use mixin for helper class

* Use mixin for helper class

* Improve progress

* Improve progress

* Improve app process flow

* Manage video with one controller

* Resolve some minor issues

* Resolve some minor issues

* Implement download video

* Add drag down to dispose

* Implement dismissible page

* Show progress

* Implement media transfer screen

* Process Media item on background thread

* Implement google drive video preview

* Implement google drive video preview

* Implement google drive preview

* Rename func

---------

Co-authored-by: cp-sneha-s <[email protected]>
  • Loading branch information
cp-pratik-k and cp-sneha-s authored Apr 11, 2024
1 parent b00c0ab commit f53be94
Show file tree
Hide file tree
Showing 56 changed files with 3,935 additions and 594 deletions.
18 changes: 9 additions & 9 deletions .idea/libraries/Flutter_Plugins.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 32 additions & 2 deletions app/assets/locales/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,22 @@
"common_yesterday": "Yesterday",
"common_tomorrow": "Tomorrow",

"common_upload":"Upload",
"common_download":"Download",
"common_delete": "Delete",
"common_delete_from_google_drive": "Delete from Google Drive",
"common_delete_from_device": "Delete from Device",
"common_cancel": "Cancel",


"no_internet_connection_error": "No internet connection! Please check your network and try again.",
"something_went_wrong_error": "Something went wrong! Please try again later.",
"user_google_sign_in_account_not_found_error": "You haven't signed in with Google account yet. Please sign in with Google account and try again.",
"back_up_folder_not_found_error": "Back up folder not found!",
"unable_to_open_attachment_error": "Unable to open attachment!",

"unable_to_load_media_error": "Unable to load media!",

"unable_to_load_media_message": "Oops! It looks like we're having trouble loading the media right now. Please try again later.",

"on_board_description": "Effortlessly move, share, and organize your photos and videos in a breeze. Access all your clouds in one friendly place. Your moments, your way, simplified for you! 🚀",

Expand All @@ -41,6 +52,25 @@

"hint_google_sign_in_message": "Sign in with Google and effortlessly link your Google Drive to your Cloud Gallery. Enjoy quick access to all your awesome content in one spot",
"hint_google_auto_backup_message": "Enable Auto Back Up to Google Drive and never lose your precious memories. Your photos and videos will be automatically backed up to your Google Drive",
"hint_action_auto_backup": "Enable Auto Back Up"
"hint_action_auto_backup": "Enable Auto Back Up",

"delete_media_from_device_confirmation_message": "Are you sure you want to delete this media? It will be permanently deleted from your device.",
"delete_media_from_google_drive_confirmation_message": "Are you sure you want to delete this media? It will be permanently deleted from your Google Drive.",

"waiting_in_queue_text": "Waiting in Queue...",
"waiting_in_download_queue_message": "Your video download is in queue. We appreciate your patience!",

"transfer_screen_title": "Transfer",

"empty_upload_title":"No Files Being Uploads",
"empty_upload_message": "No uploads are happening right now. If you have files to upload, go ahead and start uploading.",

"empty_download_title":"No Files Being Downloads",
"empty_download_message": "No downloads are happening right now. If you have files to download, go ahead and start downloading.",

"download_in_progress_text": "Download in progress",

"download_require_text": "Download required",
"download_require_message": "To watch the video, simply download it first. Tap the download button to begin downloading the video."

}
2 changes: 1 addition & 1 deletion app/lib/components/action_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class AppSheetAction extends StatelessWidget {
return OnTapScale(
onTap: onPressed,
child: SizedBox(
height: 45,
height: 50,
width: double.infinity,
child: Row(
children: [
Expand Down
83 changes: 83 additions & 0 deletions app/lib/components/app_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/text/app_text_style.dart';

class AppAlertAction {
final String title;
final bool isDestructiveAction;
final VoidCallback onPressed;

const AppAlertAction({
required this.title,
this.isDestructiveAction = false,
required this.onPressed,
});
}

Future<T?> showAppAlertDialog<T>({
required BuildContext context,
required String title,
required String message,
required List<AppAlertAction> actions,
}) {
return showAdaptiveDialog<T>(
context: context,
builder: (context) {
if (Platform.isIOS || Platform.isMacOS) {
return CupertinoAlertDialog(
title: Text(title,
style: AppTextStyles.body
.copyWith(color: context.colorScheme.textPrimary)),
content: Text(
message,
style: AppTextStyles.caption
.copyWith(color: context.colorScheme.textSecondary),
),
actions: [
for (final action in actions)
CupertinoDialogAction(
onPressed: action.onPressed,
child: Text(
action.title,
style: AppTextStyles.button.copyWith(
color: action.isDestructiveAction
? context.colorScheme.alert
: context.colorScheme.textPrimary),
),
),
],
);
}

return AlertDialog(
backgroundColor: context.colorScheme.containerNormalOnSurface,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(22),
),
title: Text(title,
style: AppTextStyles.body
.copyWith(color: context.colorScheme.textPrimary)),
content: Text(
message,
style: AppTextStyles.caption
.copyWith(color: context.colorScheme.textSecondary),
),
actions: [
for (final action in actions)
TextButton(
onPressed: action.onPressed,
child: Text(
action.title,
style: AppTextStyles.button.copyWith(
color: action.isDestructiveAction
? context.colorScheme.alert
: context.colorScheme.textPrimary),
),
),
],
);
},
);
}
18 changes: 12 additions & 6 deletions app/lib/components/app_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:style/extensions/context_extensions.dart';

class AppPage extends StatelessWidget {
final String? title;
Expand Down Expand Up @@ -145,11 +146,16 @@ class AdaptiveAppBar extends StatelessWidget {
children: actions!,
),
)
: AppBar(
leading: leading,
actions: actions,
automaticallyImplyLeading: automaticallyImplyLeading,
title: Text(text),
);
: Column(
children: [
AppBar(
backgroundColor: context.colorScheme.barColor,
leading: leading,
actions: actions,
automaticallyImplyLeading: automaticallyImplyLeading,
title: Text(text),
),
],
);
}
}
70 changes: 70 additions & 0 deletions app/lib/components/error_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:flutter/cupertino.dart';
import 'package:style/buttons/primary_button.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/text/app_text_style.dart';

class ErrorViewAction {
final String title;
final VoidCallback onPressed;

const ErrorViewAction({required this.title, required this.onPressed});
}

class ErrorView extends StatelessWidget {
final Widget? icon;
final String title;
final String message;
final Color? foregroundColor;
final ErrorViewAction? action;

const ErrorView({
super.key,
this.icon,
required this.title,
this.foregroundColor,
this.message = '',
this.action,
});

@override
Widget build(BuildContext context) {
return SafeArea(
child: Padding(
padding: const EdgeInsets.all(30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(width: double.infinity),
icon ??
Icon(
CupertinoIcons.exclamationmark_circle,
color: context.colorScheme.containerHighOnSurface,
size: 100,
),
const SizedBox(height: 40),
Text(title,
style: AppTextStyles.subtitle1.copyWith(
color: foregroundColor?? context.colorScheme.textPrimary,
)),
const SizedBox(height: 20),
Text(
message,
style: AppTextStyles.subtitle2.copyWith(
color: foregroundColor ??context.colorScheme.textSecondary,
),
textAlign: TextAlign.center,
),
if (action != null) ...[
const SizedBox(height: 20),
PrimaryButton(
onPressed: action!.onPressed,
child: Text(action!.title, style: AppTextStyles.button,),
),
],
],
),
),
);
}
}
56 changes: 56 additions & 0 deletions app/lib/domain/extensions/media_list_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:data/extensions/iterable_extension.dart';
import 'package:data/models/app_process/app_process.dart';
import 'package:data/models/media/media.dart';
import 'package:data/models/media/media_extension.dart';

extension MediaListExtension on List<AppMedia> {
void removeGoogleDriveRefFromMedias({List<String>? removeFromIds}) {
for (int index = 0; index < length; index++) {
if (this[index].isGoogleDriveStored &&
(removeFromIds?.contains(this[index].id) ?? true)) {
removeAt(index);
} else if (this[index].isCommonStored &&
(removeFromIds?.contains(this[index].id) ?? true)) {
this[index] = this[index].copyWith(
sources: this[index].sources.toList()
..remove(AppMediaSource.googleDrive),
thumbnailLink: null,
driveMediaRefId: null,
);
}
}
}

void addGoogleDriveRefInMedias(
{required List<AppProcess> process, List<String>? processIds}) {
processIds ??= process.map((e) => e.id).toList();
updateWhere(
where: (media) => processIds?.contains(media.id) ?? false,
update: (media) {
final res = process
.where((element) => element.id == media.id)
.first
.response as AppMedia?;
if (res == null) return media;
return media.mergeGoogleDriveMedia(res);
},
);
}

void replaceMediaRefInMedias(
{required List<AppProcess> process, List<String>? processIds}) {
processIds ??= process.map((e) => e.id).toList();
updateWhere(
where: (media) => processIds?.contains(media.id) ?? false,
update: (media) {
final res = process
.where((element) => element.id == media.id)
.first
.response as AppMedia?;

if (res == null) return media;
return res;
},
);
}
}
11 changes: 11 additions & 0 deletions app/lib/domain/formatter/byte_formatter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'dart:math';

extension BytesFormatter on int {
String get formatBytes {
const List<String> suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
if (this == 0) return '0 ${suffixes[0]}';
final i = (this == 0) ? 0 : (log(this) / log(1024)).floor();
final formattedValue = (this / pow(1024, i)).toStringAsFixed(2);
return '${formattedValue.endsWith('.00') ? formattedValue.substring(0, formattedValue.length - 3) : formattedValue} ${suffixes[i]}';
}
}
12 changes: 11 additions & 1 deletion app/lib/ui/flow/accounts/accounts_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:style/text/app_text_style.dart';
import 'package:style/theme/colors.dart';
import 'package:style/buttons/buttons_list.dart';
import 'package:style/buttons/switch.dart';
import '../../../components/snack_bar.dart';
import 'components/account_tab.dart';

class AccountsScreen extends ConsumerStatefulWidget {
Expand All @@ -32,11 +33,20 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
runPostFrame(() => notifier.init());
}

void _errorObserver() {
ref.listen(accountsStateNotifierProvider.select((value) => value.error),
(previous, next) {
if (next != null) {
showErrorSnackBar(context: context, error: next);
}
});
}

@override
Widget build(BuildContext context) {
_errorObserver();
final googleAccount = ref.watch(
accountsStateNotifierProvider.select((value) => value.googleAccount));

return AppPage(
title: context.l10n.common_accounts,
bodyBuilder: (context) {
Expand Down
Loading

0 comments on commit f53be94

Please sign in to comment.