Browse Source

Render parsed objects within file info to internal users

vishnukvmd 2 years ago
parent
commit
07fd3420bb

+ 12 - 0
lib/ui/viewer/file/file_info_widget.dart

@@ -9,6 +9,7 @@ import "package:photos/ente_theme_data.dart";
 import "package:photos/models/file.dart";
 import "package:photos/models/file_type.dart";
 import 'package:photos/services/collections_service.dart';
+import "package:photos/services/feature_flag_service.dart";
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/components/divider_widget.dart';
 import 'package:photos/ui/components/icon_button_widget.dart';
@@ -16,6 +17,7 @@ import 'package:photos/ui/components/title_bar_widget.dart';
 import 'package:photos/ui/viewer/file/collections_list_of_file_widget.dart';
 import 'package:photos/ui/viewer/file/device_folders_list_of_file_widget.dart';
 import 'package:photos/ui/viewer/file/file_caption_widget.dart';
+import "package:photos/ui/viewer/file/object_tags_widget.dart";
 import 'package:photos/ui/viewer/file/raw_exif_list_tile_widget.dart';
 import "package:photos/utils/date_time_util.dart";
 import "package:photos/utils/exif_util.dart";
@@ -233,6 +235,16 @@ class _FileInfoWidgetState extends State<FileInfoWidget> {
               : DeviceFoldersListOfFileWidget(allDeviceFoldersOfFile),
         ),
       ),
+      FeatureFlagService.instance.isInternalUserOrDebugBuild()
+          ? SizedBox(
+              height: 62,
+              child: ListTile(
+                horizontalTitleGap: 0,
+                leading: const Icon(Icons.image_search),
+                title: ObjectTagsWidget(file),
+              ),
+            )
+          : null,
       (file.uploadedFileID != null && file.updationTime != null)
           ? ListTile(
               horizontalTitleGap: 2,

+ 77 - 0
lib/ui/viewer/file/object_tags_widget.dart

@@ -0,0 +1,77 @@
+import "package:flutter/material.dart";
+import "package:logging/logging.dart";
+import "package:photos/ente_theme_data.dart";
+import "package:photos/models/file.dart";
+import "package:photos/services/object_detection/object_detection_service.dart";
+import "package:photos/ui/common/loading_widget.dart";
+import "package:photos/utils/thumbnail_util.dart";
+
+class ObjectTagsWidget extends StatelessWidget {
+  final File file;
+
+  const ObjectTagsWidget(this.file, {Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return FutureBuilder<List<String>>(
+      future: getThumbnailFromServer(file).then((data) {
+        return ObjectDetectionService.instance.predict(data);
+      }),
+      builder: (context, snapshot) {
+        if (snapshot.hasData) {
+          final List<String> tags = snapshot.data!;
+          if (tags.isEmpty) {
+            return const ObjectTagWidget("No Results");
+          }
+          return ListView.builder(
+            itemCount: tags.length,
+            scrollDirection: Axis.horizontal,
+            itemBuilder: (context, index) {
+              return ObjectTagWidget(tags[index]);
+            },
+          );
+        } else if (snapshot.hasError) {
+          Logger("ObjectTagsWidget").severe(snapshot.error);
+          return const Icon(Icons.error);
+        } else {
+          return const EnteLoadingWidget();
+        }
+      },
+    );
+  }
+}
+
+class ObjectTagWidget extends StatelessWidget {
+  final String name;
+  const ObjectTagWidget(this.name, {Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      margin: const EdgeInsets.only(
+        top: 10,
+        bottom: 18,
+        right: 8,
+      ),
+      decoration: BoxDecoration(
+        color: Theme.of(context)
+            .colorScheme
+            .inverseBackgroundColor
+            .withOpacity(0.025),
+        borderRadius: const BorderRadius.all(
+          Radius.circular(8),
+        ),
+      ),
+      child: Center(
+        child: Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 8),
+          child: Text(
+            name!,
+            style: Theme.of(context).textTheme.subtitle2,
+            overflow: TextOverflow.ellipsis,
+          ),
+        ),
+      ),
+    );
+  }
+}