Skip to content

Commit

Permalink
Implement google drive video preview
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-pratik-k committed Apr 11, 2024
1 parent a351a6e commit 3be95d2
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 44 deletions.
60 changes: 60 additions & 0 deletions app/lib/domain/extensions/media_list_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:data/extensions/iterable_extension.dart';
import 'package:data/models/app_process/app_process.dart';
import 'package:data/models/media/media.dart';

extension MediaListHelper 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 addGoogleDriveRefInMedia(
{required List<AppProcess> process, required List<String> processIds}) {
updateWhere(
where: (media) => processIds.contains(media.id),
update: (media) {
final res = process
.where((element) => element.id == media.id)
.first
.response as AppMedia?;
return media.copyWith(
thumbnailLink: res?.thumbnailLink,
driveMediaRefId: res?.id,
sources: media.sources.toList()..add(AppMediaSource.googleDrive),
);
},
);
}

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

if (res == null) return media;
return res.copyWith(
thumbnailLink: media.thumbnailLink,
driveMediaRefId: media.id,
sources: res.sources.toList()..add(AppMediaSource.googleDrive),
);
},
);
}
}
28 changes: 2 additions & 26 deletions data/lib/models/media/media.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' show Size;
import 'dart:async';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:googleapis/drive/v3.dart' as drive show File;
import 'package:photo_manager/photo_manager.dart'
show AssetEntity, ThumbnailFormat, ThumbnailSize;
show AssetEntity;

part 'media.freezed.dart';

Expand Down Expand Up @@ -174,25 +172,3 @@ class AppMedia with _$AppMedia {
}
}

extension AppMediaExtension on AppMedia {
Future<bool> get isExist async {
return await File(path).exists();
}

Future<Uint8List?> thumbnailDataWithSize(Size size) async {
return await AssetEntity(id: id, typeInt: type.index, width: 0, height: 0)
.thumbnailDataWithSize(
ThumbnailSize(size.width.toInt(), size.height.toInt()),
format: ThumbnailFormat.png,
quality: 70,
);
}

bool get isGoogleDriveStored =>
sources.contains(AppMediaSource.googleDrive) && sources.length == 1;

bool get isLocalStored =>
sources.contains(AppMediaSource.local) && sources.length == 1;

bool get isCommonStored => sources.length > 1;
}
63 changes: 63 additions & 0 deletions data/lib/models/media/media_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:photo_manager/photo_manager.dart';
import 'media.dart';

extension AppMediaExtension on AppMedia {
Future<bool> get isExist async {
return await File(path).exists();
}

Future<Uint8List?> loadThumbnail({Size size = const Size(300, 300)}) async {
var rootToken = RootIsolateToken.instance!;
final ThumbNailParameter thumbNailParameter =
ThumbNailParameter(rootToken, size, id, type);
final bytes = await compute(_loadThumbnailInBackground, thumbNailParameter);
return bytes;
}

FutureOr<Uint8List?> _loadThumbnailInBackground(
ThumbNailParameter parameters) async {
BackgroundIsolateBinaryMessenger.ensureInitialized(parameters.token);
return await AssetEntity(
id: parameters.id,
typeInt: parameters.type.index,
width: 0,
height: 0,
).thumbnailDataWithSize(
ThumbnailSize(
parameters.size.width.toInt(),
parameters.size.height.toInt(),
),
format: ThumbnailFormat.png,
quality: 70,
);
}

AppMedia margeGoogleDriveMedia(AppMedia media){
return copyWith(
thumbnailLink: media.thumbnailLink,
driveMediaRefId: media.driveMediaRefId,
sources: sources.toList()..add(AppMediaSource.googleDrive),
);
}

bool get isGoogleDriveStored =>
sources.contains(AppMediaSource.googleDrive) && sources.length == 1;

bool get isLocalStored =>
sources.contains(AppMediaSource.local) && sources.length == 1;

bool get isCommonStored => sources.length > 1;
}

class ThumbNailParameter {
final RootIsolateToken token;
final Size size;
final String id;
final AppMediaType type;

ThumbNailParameter(this.token, this.size, this.id, this.type);
}
29 changes: 18 additions & 11 deletions data/lib/repositories/google_drive_process_repo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:typed_data';
import 'package:collection/collection.dart';
import 'package:data/extensions/iterable_extension.dart';
import 'package:data/models/app_process/app_process.dart';
import 'package:data/models/media/media_extension.dart';
import 'package:data/services/google_drive_service.dart';
import 'package:data/services/local_media_service.dart';
import 'package:flutter/cupertino.dart';
Expand Down Expand Up @@ -186,17 +187,6 @@ class GoogleDriveProcessRepo extends ChangeNotifier {
total: mediaContent.length ?? 0, chunk: bytes.length)),
);
notifyListeners();
}, onDone: () async {
final res = await _localMediaService.saveMedia(
process.media, Uint8List.fromList(bytes));

_downloadQueue.updateWhere(
where: (element) => element.id == process.id,
update: (element) =>
element.copyWith(status: AppProcessStatus.success, response: res),
);
notifyListeners();
subscription?.cancel();
}, onError: (error) {
_downloadQueue.updateWhere(
where: (element) => element.id == process.id,
Expand All @@ -206,6 +196,23 @@ class GoogleDriveProcessRepo extends ChangeNotifier {
notifyListeners();
subscription?.cancel();
});
await subscription.asFuture();

final localMedia = await _localMediaService.saveMedia(
process.media, Uint8List.fromList(bytes));

final updatedMedia = await _googleDriveService.updateMediaDescription(
process.media.id, localMedia?.path ?? "");

_downloadQueue.updateWhere(
where: (element) => element.id == process.id,
update: (element) => element.copyWith(
status: AppProcessStatus.success,
response: localMedia?.margeGoogleDriveMedia(updatedMedia)),
);

notifyListeners();
subscription.cancel();
} catch (error) {
_downloadQueue.updateWhere(
where: (element) => element.id == process.id,
Expand Down
11 changes: 11 additions & 0 deletions data/lib/services/google_drive_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ class GoogleDriveService {
}
}

Future<AppMedia> updateMediaDescription(String id, String description) async {
try {
final driveApi = await _getGoogleDriveAPI();
final file = drive.File(description: description);
final updatedFile = await driveApi.files.update(file, id);
return AppMedia.fromGoogleDriveFile(updatedFile);
} catch (e) {
throw AppError.fromError(e);
}
}

Future<void> deleteMedia(String id) async {
try {
final driveApi = await _getGoogleDriveAPI();
Expand Down
22 changes: 15 additions & 7 deletions data/lib/services/local_media_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,25 @@ class LocalMediaService {
}
}

Future<AssetEntity?> saveMedia(AppMedia media, Uint8List bytes) async {
Future<AppMedia?> saveMedia(AppMedia media, Uint8List bytes) async {
final extension = media.mimeType?.trim().isNotEmpty ?? false
? media.mimeType!.split('/').last
: media.type.isVideo
? 'mp4'
: 'jpg';
AssetEntity? asset;
if (media.type.isVideo) {
final tempDir = await getTemporaryDirectory();
final tempVideoFile = File('${tempDir.path}/temp_video.mp4');
final tempVideoFile = File('${tempDir.path}/temp_video');
await tempVideoFile.writeAsBytes(bytes);
return await PhotoManager.editor.saveVideo(tempVideoFile,
title: media.name ?? "${DateTime.now()}_cloud_gallery");
asset = await PhotoManager.editor.saveVideo(
tempVideoFile,
title: "${media.name ?? DateTime.now()}_gd_cloud_gallery.$extension",
);
} else if (media.type.isImage) {
return await PhotoManager.editor.saveImage(bytes,
title: media.name ?? "${DateTime.now()}_cloud_gallery");
asset = await PhotoManager.editor.saveImage(bytes,
title: "${media.name ?? DateTime.now()}_gd_cloud_gallery.$extension");
}
return null;
return asset != null ? AppMedia.fromAssetEntity(asset) : null;
}
}

0 comments on commit 3be95d2

Please sign in to comment.