Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata details #28

Merged
merged 2 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/assets/images/icons/google-drive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 0 additions & 6 deletions app/assets/images/icons/google_photos.svg

This file was deleted.

18 changes: 15 additions & 3 deletions app/assets/locales/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"common_delete_from_google_drive": "Delete from Google Drive",
"common_delete_from_device": "Delete from Device",
"common_cancel": "Cancel",

"common_not_available": "N/A",

"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.",
Expand Down Expand Up @@ -71,6 +71,18 @@
"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."

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

"name_text": "Name",
"size_text": "Size",
"created_at_text": "Created at",
"modified_at_text": "Modified at",
"mimetype_text": "MIME Type",
"duration_text": "Duration",
"location_text": "Location",
"resolution_text": "Resolution",
"orientation_text": "Orientation",
"path_text": "Path",
"display_size_text": "Display Size",
"source_text": "Source"
}
119 changes: 119 additions & 0 deletions app/lib/components/thumbnail_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import 'dart:typed_data';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:data/models/media/media.dart';
import 'package:flutter/cupertino.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicators/circular_progress_indicator.dart';

class AppMediaThumbnail extends StatelessWidget {
final Object? heroTag;
final AppMedia media;
final Size size;
final double radius;
final Future<Uint8List?>? thumbnailByte;

const AppMediaThumbnail({
super.key,
required this.size,
this.heroTag,
this.radius = 4,
required this.thumbnailByte,
required this.media,
});

@override
Widget build(BuildContext context) {
if (media.sources.contains(AppMediaSource.local)) {
return FutureBuilder(
future: thumbnailByte,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
return ClipRRect(
borderRadius: BorderRadius.circular(radius),
child: Hero(
tag: heroTag ?? '',
child: Image.memory(
snapshot.data!,
height: size.height,
width: size.width,
fit: BoxFit.cover,
),
),
);
} else if (snapshot.hasError) {
return AppMediaErrorPlaceHolder(
size: size,
);
} else {
return AppMediaPlaceHolder(
showLoader: false,
size: size,
);
}
},
);
} else {
return Hero(
tag: heroTag ?? '',
child: ClipRRect(
borderRadius: BorderRadius.circular(radius),
child: CachedNetworkImage(
imageUrl: media.thumbnailLink ?? '',
width: size.width,
height: size.height,
fit: BoxFit.cover,
errorWidget: (context, url, error) => AppMediaErrorPlaceHolder(
size: size,
),
progressIndicatorBuilder: (context, url, progress) =>
AppMediaPlaceHolder(
size: size,
value: progress.progress,
)),
),
);
}
}
}

class AppMediaPlaceHolder extends StatelessWidget {
final double? value;
final Size? size;
final bool showLoader;

const AppMediaPlaceHolder(
{super.key, this.value, this.showLoader = true, this.size});

@override
Widget build(BuildContext context) {
return Container(
height: size?.height,
width: size?.width,
color: context.colorScheme.containerHighOnSurface,
alignment: Alignment.center,
child: showLoader ? AppCircularProgressIndicator(value: value) : null,
);
}
}

class AppMediaErrorPlaceHolder extends StatelessWidget {
final Size? size;

const AppMediaErrorPlaceHolder({super.key, this.size});

@override
Widget build(BuildContext context) {
return Container(
height: size?.height,
width: size?.width,
color: context.colorScheme.containerNormalOnSurface,
alignment: Alignment.center,
child: Icon(
CupertinoIcons.exclamationmark_circle,
color: context.colorScheme.onPrimary,
size: 32,
),
);
}
}
2 changes: 1 addition & 1 deletion app/lib/domain/assets/assets_paths.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ class PathImages {
}

class PathIcons {
String get googlePhotos => 'assets/images/icons/google_photos.svg';
String get googleDrive => 'assets/images/icons/google-drive.svg';
}
69 changes: 9 additions & 60 deletions app/lib/ui/flow/home/components/app_media_item.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_gallery/components/thumbnail_builder.dart';
import 'package:cloud_gallery/domain/formatter/duration_formatter.dart';
import 'package:data/models/app_process/app_process.dart';
import 'package:data/models/media/media.dart';
Expand Down Expand Up @@ -35,7 +34,7 @@ class AppMediaItem extends StatefulWidget {

class _AppMediaItemState extends State<AppMediaItem>
with AutomaticKeepAliveClientMixin {
late Future<Uint8List?> thumbnailByte;
Future<Uint8List?>? thumbnailByte;

@override
void initState() {
Expand Down Expand Up @@ -93,64 +92,14 @@ class _AppMediaItemState extends State<AppMediaItem>

Widget _buildMediaView(
{required BuildContext context, required BoxConstraints constraints}) {
if (widget.media.sources.contains(AppMediaSource.local)) {
return FutureBuilder(
future: thumbnailByte,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
return Hero(
tag: widget.media,
child: Image.memory(
snapshot.data!,
width: constraints.maxWidth,
height: constraints.maxHeight,
fit: BoxFit.cover,
),
);
} else {
return _buildPlaceholder(context: context, showLoader: false);
}
},
);
} else {
return Hero(
tag: widget.media,
child: CachedNetworkImage(
imageUrl: widget.media.thumbnailLink ?? '',
width: constraints.maxWidth,
height: constraints.maxHeight,
fit: BoxFit.cover,
errorWidget: (context, url, error) => _buildErrorWidget(context),
progressIndicatorBuilder: (context, url, progress) =>
_buildPlaceholder(
context: context,
value: progress.progress,
)),
);
}
return AppMediaThumbnail(
size: constraints.biggest,
thumbnailByte: thumbnailByte,
media: widget.media,
heroTag: widget.media,
);
}

Widget _buildPlaceholder(
{required BuildContext context,
double? value,
bool showLoader = true}) =>
Container(
color: context.colorScheme.containerHighOnSurface,
alignment: Alignment.center,
child: showLoader ? AppCircularProgressIndicator(value: value) : null,
);

Widget _buildErrorWidget(BuildContext context) => Container(
color: context.colorScheme.containerNormalOnSurface,
alignment: Alignment.center,
child: Icon(
CupertinoIcons.exclamationmark_circle,
color: context.colorScheme.onPrimary,
size: 32,
),
);

Widget _sourceIndicators({required BuildContext context}) {
return Row(
children: [
Expand All @@ -161,7 +110,7 @@ class _AppMediaItemState extends State<AppMediaItem>
children: [
if (widget.media.sources.contains(AppMediaSource.googleDrive))
SvgPicture.asset(
Assets.images.icons.googlePhotos,
Assets.images.icons.googleDrive,
height: 14,
width: 14,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MultiSelectionDoneButton extends ConsumerWidget {
if (showUploadToDriveButton)
AppSheetAction(
icon: SvgPicture.asset(
Assets.images.icons.googlePhotos,
Assets.images.icons.googleDrive,
height: 24,
width: 24,
),
Expand Down
5 changes: 3 additions & 2 deletions app/lib/ui/flow/home/home_screen_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:cloud_gallery/domain/extensions/map_extensions.dart';
import 'package:cloud_gallery/domain/extensions/media_list_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';
import 'package:data/repositories/google_drive_process_repo.dart';
import 'package:data/services/auth_service.dart';
import 'package:data/services/google_drive_service.dart';
Expand Down Expand Up @@ -211,7 +210,9 @@ class HomeViewStateNotifier extends StateNotifier<HomeViewState>
List<AppMedia> googleDriveMedia = [];
List<AppMedia> uploadedMedia = [];
for (var media in driveMedias) {
if (await media.isExist) {
if (media.path.trim().isNotEmpty &&
await _localMediaService.isLocalFileExist(
type: media.type, id: media.path)) {
uploadedMedia.add(media);
} else {
googleDriveMedia.add(media);
Expand Down
9 changes: 6 additions & 3 deletions app/lib/ui/flow/home/home_view_model_helper_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mixin HomeViewModelHelperMixin {
// Add common media to mergedMedias and remove them from the lists.
for (AppMedia localMedia in localMedias.toList()) {
googleDriveMedias
.where((googleDriveMedia) => googleDriveMedia.path == localMedia.path)
.where((googleDriveMedia) => googleDriveMedia.path == localMedia.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the comparison from path to id for media items to ensure consistency with new logic.

- .where((googleDriveMedia) => googleDriveMedia.path == localMedia.id)
+ .where((googleDriveMedia) => googleDriveMedia.id == localMedia.id)

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
.where((googleDriveMedia) => googleDriveMedia.path == localMedia.id)
.where((googleDriveMedia) => googleDriveMedia.id == localMedia.id)

.forEach((googleDriveMedia) {
localMedias.removeWhere((media) => media.id == localMedia.id);

Expand Down Expand Up @@ -73,8 +73,11 @@ mixin HomeViewModelHelperMixin {
}) {
final processIds = process.map((e) => e.id).toList();
return medias.map((key, value) {
return MapEntry(key,
value..replaceMediaRefInMedias(process: process, processIds: processIds));
return MapEntry(
key,
value
..replaceMediaRefInMedias(
process: process, processIds: processIds));
});
}
}
Loading
Loading