[mob][photos] In-app public link fixes (#4495)
## Description Fixed these issues: - Unrelated files coming up (these are local device files) in public link when opened in-app. - Max number of files in link capped to 2000. - Sort order not working.
This commit is contained in:
@@ -1067,6 +1067,24 @@ class CollectionsService {
|
||||
_cachedPublicAlbumToken[collection.id] = authToken!;
|
||||
_cachedPublicCollectionID.add(collection.id);
|
||||
_cachedPublicAlbumKey[collection.id] = albumKey;
|
||||
|
||||
if (collectionData['pubMagicMetadata'] != null) {
|
||||
final utfEncodedMmd = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(collectionData['pubMagicMetadata']['data']),
|
||||
collectionKey,
|
||||
CryptoUtil.base642bin(
|
||||
collectionData['pubMagicMetadata']['header'],
|
||||
),
|
||||
);
|
||||
collection.mMdPubEncodedJson = utf8.decode(utfEncodedMmd);
|
||||
collection.mMbPubVersion =
|
||||
collectionData['pubMagicMetadata']['version'];
|
||||
collection.pubMagicMetadata =
|
||||
CollectionPubMagicMetadata.fromEncodedJson(
|
||||
collection.mMdPubEncodedJson ?? '{}',
|
||||
);
|
||||
}
|
||||
|
||||
collection.setName(_getDecryptedCollectionName(collection));
|
||||
return collection;
|
||||
} catch (e, s) {
|
||||
|
||||
@@ -306,8 +306,12 @@ class _HomeWidgetState extends State<HomeWidget> {
|
||||
if (result) {
|
||||
await dialog.show();
|
||||
|
||||
final List<EnteFile> sharedFiles = await _diffFetcher
|
||||
.getPublicFiles(context, collection.id);
|
||||
final List<EnteFile> sharedFiles =
|
||||
await _diffFetcher.getPublicFiles(
|
||||
context,
|
||||
collection.id,
|
||||
collection.pubMagicMetadata.asc ?? false,
|
||||
);
|
||||
await dialog.hide();
|
||||
Navigator.of(context).pop();
|
||||
|
||||
@@ -334,8 +338,11 @@ class _HomeWidgetState extends State<HomeWidget> {
|
||||
} else {
|
||||
await dialog.show();
|
||||
|
||||
final List<EnteFile> sharedFiles =
|
||||
await _diffFetcher.getPublicFiles(context, collection.id);
|
||||
final List<EnteFile> sharedFiles = await _diffFetcher.getPublicFiles(
|
||||
context,
|
||||
collection.id,
|
||||
collection.pubMagicMetadata.asc ?? false,
|
||||
);
|
||||
await dialog.hide();
|
||||
|
||||
await routeToPage(
|
||||
|
||||
@@ -27,7 +27,9 @@ class FileWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
// Specify key to ensure that the widget is rebuilt when the file changes
|
||||
// Before changing this, ensure that file deletes are handled properly
|
||||
final String fileKey = "file_${file.generatedID}";
|
||||
|
||||
final String fileKey =
|
||||
"file_genID_${file.generatedID}___file_id_${file.uploadedFileID}";
|
||||
if (file.fileType == FileType.livePhoto ||
|
||||
file.fileType == FileType.image) {
|
||||
return ZoomableLiveImageNew(
|
||||
|
||||
@@ -51,6 +51,8 @@ class _ZoomableLiveImageNewState extends State<ZoomableLiveImageNew>
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_enteFile = widget.enteFile;
|
||||
_logger.info(
|
||||
'initState for ${_enteFile.generatedID} with tag ${_enteFile.tag} and name ${_enteFile.displayName}',
|
||||
@@ -64,7 +66,6 @@ class _ZoomableLiveImageNewState extends State<ZoomableLiveImageNew>
|
||||
isGuestView = event.isGuestView;
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _onLongPressEvent(bool isPressed) {
|
||||
|
||||
@@ -21,69 +21,84 @@ class DiffFetcher {
|
||||
Future<List<EnteFile>> getPublicFiles(
|
||||
BuildContext context,
|
||||
int collectionID,
|
||||
bool sortAsc,
|
||||
) async {
|
||||
try {
|
||||
final authToken = await CollectionsService.instance
|
||||
.getSharedPublicAlbumToken(collectionID);
|
||||
final authJWTToken = await CollectionsService.instance
|
||||
.getSharedPublicAlbumTokenJWT(collectionID);
|
||||
bool hasMore = false;
|
||||
final sharedFiles = <EnteFile>[];
|
||||
|
||||
final headers = {
|
||||
"X-Auth-Access-Token": authToken,
|
||||
if (authJWTToken != null) "X-Auth-Access-Token-JWT": authJWTToken,
|
||||
};
|
||||
|
||||
final response = await _enteDio.get(
|
||||
"/public-collection/diff",
|
||||
options: Options(headers: headers),
|
||||
queryParameters: {"sinceTime": 0},
|
||||
);
|
||||
int sinceTime = 0;
|
||||
|
||||
final diff = response.data["diff"] as List;
|
||||
final startTime = DateTime.now();
|
||||
final sharedFiles = <EnteFile>[];
|
||||
|
||||
for (final item in diff) {
|
||||
final file = EnteFile();
|
||||
if (item["isDeleted"]) {
|
||||
continue;
|
||||
}
|
||||
file.uploadedFileID = item["id"];
|
||||
file.collectionID = item["collectionID"];
|
||||
file.ownerID = item["ownerID"];
|
||||
file.encryptedKey = item["encryptedKey"];
|
||||
file.keyDecryptionNonce = item["keyDecryptionNonce"];
|
||||
file.fileDecryptionHeader = item["file"]["decryptionHeader"];
|
||||
file.thumbnailDecryptionHeader = item["thumbnail"]["decryptionHeader"];
|
||||
file.metadataDecryptionHeader = item["metadata"]["decryptionHeader"];
|
||||
if (item["info"] != null) {
|
||||
file.fileSize = item["info"]["fileSize"];
|
||||
}
|
||||
final fileKey = getFileKey(file);
|
||||
final encodedMetadata = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(item["metadata"]["encryptedData"]),
|
||||
fileKey,
|
||||
CryptoUtil.base642bin(file.metadataDecryptionHeader!),
|
||||
do {
|
||||
final response = await _enteDio.get(
|
||||
"/public-collection/diff",
|
||||
options: Options(headers: headers),
|
||||
queryParameters: {"sinceTime": sinceTime},
|
||||
);
|
||||
final Map<String, dynamic> metadata =
|
||||
jsonDecode(utf8.decode(encodedMetadata));
|
||||
file.applyMetadata(metadata);
|
||||
if (item['pubMagicMetadata'] != null) {
|
||||
final utfEncodedMmd = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(item['pubMagicMetadata']['data']),
|
||||
fileKey,
|
||||
CryptoUtil.base642bin(item['pubMagicMetadata']['header']),
|
||||
);
|
||||
file.pubMmdEncodedJson = utf8.decode(utfEncodedMmd);
|
||||
file.pubMmdVersion = item['pubMagicMetadata']['version'];
|
||||
file.pubMagicMetadata =
|
||||
PubMagicMetadata.fromEncodedJson(file.pubMmdEncodedJson!);
|
||||
}
|
||||
sharedFiles.add(file);
|
||||
}
|
||||
|
||||
_logger.info('[Collection-$collectionID] parsed ${diff.length} '
|
||||
'diff items ( ${sharedFiles.length} updated) in ${DateTime.now().difference(startTime).inMilliseconds}ms');
|
||||
final diff = response.data["diff"] as List;
|
||||
hasMore = response.data["hasMore"] as bool;
|
||||
|
||||
for (final item in diff) {
|
||||
final file = EnteFile();
|
||||
if (item["isDeleted"]) {
|
||||
continue;
|
||||
}
|
||||
file.uploadedFileID = item["id"];
|
||||
file.collectionID = item["collectionID"];
|
||||
file.ownerID = item["ownerID"];
|
||||
file.encryptedKey = item["encryptedKey"];
|
||||
file.keyDecryptionNonce = item["keyDecryptionNonce"];
|
||||
file.fileDecryptionHeader = item["file"]["decryptionHeader"];
|
||||
file.thumbnailDecryptionHeader =
|
||||
item["thumbnail"]["decryptionHeader"];
|
||||
file.metadataDecryptionHeader = item["metadata"]["decryptionHeader"];
|
||||
if (item["info"] != null) {
|
||||
file.fileSize = item["info"]["fileSize"];
|
||||
}
|
||||
final fileKey = getFileKey(file);
|
||||
final encodedMetadata = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(item["metadata"]["encryptedData"]),
|
||||
fileKey,
|
||||
CryptoUtil.base642bin(file.metadataDecryptionHeader!),
|
||||
);
|
||||
final Map<String, dynamic> metadata =
|
||||
jsonDecode(utf8.decode(encodedMetadata));
|
||||
file.applyMetadata(metadata);
|
||||
if (item['pubMagicMetadata'] != null) {
|
||||
final utfEncodedMmd = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(item['pubMagicMetadata']['data']),
|
||||
fileKey,
|
||||
CryptoUtil.base642bin(item['pubMagicMetadata']['header']),
|
||||
);
|
||||
file.pubMmdEncodedJson = utf8.decode(utfEncodedMmd);
|
||||
file.pubMmdVersion = item['pubMagicMetadata']['version'];
|
||||
file.pubMagicMetadata =
|
||||
PubMagicMetadata.fromEncodedJson(file.pubMmdEncodedJson!);
|
||||
}
|
||||
|
||||
// To avoid local file to be used as thumbnail or full file.
|
||||
file.localID = null;
|
||||
|
||||
sharedFiles.add(file);
|
||||
}
|
||||
|
||||
if (diff.isNotEmpty) {
|
||||
sinceTime = diff.last["updationTime"];
|
||||
}
|
||||
} while (hasMore);
|
||||
if (sortAsc) {
|
||||
sharedFiles.sort((a, b) => a.creationTime!.compareTo(b.creationTime!));
|
||||
}
|
||||
return sharedFiles;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Failed to decrypt collection ", e, s);
|
||||
|
||||
Reference in New Issue
Block a user