[mob][photos] Use GalleryAppBar widget on location screen

This commit is contained in:
ashilkn
2024-10-07 20:05:46 +05:30
parent 2611cdc480
commit af8d630060
3 changed files with 101 additions and 169 deletions

View File

@@ -4,13 +4,17 @@ class EntePopupMenuItem<T> extends PopupMenuItem<T> {
final String label;
final IconData? icon;
final Widget? iconWidget;
final Color? iconColor;
final Color? labelColor;
EntePopupMenuItem(
this.label, {
required T value,
required T super.value,
this.icon,
this.iconWidget,
Key? key,
this.iconColor,
this.labelColor,
super.key,
}) : assert(
icon != null || iconWidget != null,
'Either icon or iconWidget must be provided.',
@@ -20,18 +24,19 @@ class EntePopupMenuItem<T> extends PopupMenuItem<T> {
'Only one of icon or iconWidget can be provided.',
),
super(
value: value,
key: key,
child: Row(
children: [
if (iconWidget != null)
iconWidget
else if (icon != null)
Icon(icon),
Icon(icon, color: iconColor),
const Padding(
padding: EdgeInsets.all(8),
),
Text(label),
Text(
label,
style: TextStyle(color: labelColor),
),
],
), // Initially empty, will be populated in build
);

View File

@@ -23,8 +23,11 @@ import "package:photos/models/metadata/common_keys.dart";
import 'package:photos/models/selected_files.dart';
import 'package:photos/service_locator.dart';
import 'package:photos/services/collections_service.dart';
import "package:photos/services/location_service.dart";
import 'package:photos/services/sync_service.dart';
import 'package:photos/services/update_service.dart';
import "package:photos/states/location_screen_state.dart";
import "package:photos/theme/colors.dart";
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
import "package:photos/ui/cast/auto.dart";
import "package:photos/ui/cast/choose.dart";
@@ -42,6 +45,7 @@ import "package:photos/ui/viewer/gallery/hooks/add_photos_sheet.dart";
import 'package:photos/ui/viewer/gallery/hooks/pick_cover_photo.dart';
import "package:photos/ui/viewer/hierarchicial_search/applied_filters.dart";
import "package:photos/ui/viewer/hierarchicial_search/recommended_filters.dart";
import "package:photos/ui/viewer/location/edit_location_sheet.dart";
import 'package:photos/utils/data_util.dart';
import 'package:photos/utils/dialog_util.dart';
import 'package:photos/utils/magic_util.dart';
@@ -88,7 +92,9 @@ enum AlbumPopupAction {
removeLink,
cleanUncategorized,
sortByMostRecent,
sortByMostRelevant
sortByMostRelevant,
editLocation,
deleteLocation,
}
class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
@@ -452,6 +458,20 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
child: const Icon(CupertinoIcons.pin),
),
),
if (galleryType == GalleryType.locationTag)
EntePopupMenuItem(
S.of(context).editLocation,
value: AlbumPopupAction.editLocation,
icon: Icons.edit_outlined,
),
if (galleryType == GalleryType.locationTag)
EntePopupMenuItem(
S.of(context).deleteLocation,
value: AlbumPopupAction.deleteLocation,
icon: Icons.delete_outline,
iconColor: warning500,
labelColor: warning500,
),
]);
final bool isArchived = widget.collection?.isArchived() ?? false;
final bool isHidden = widget.collection?.isHidden() ?? false;
@@ -571,6 +591,10 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
await showOnMap();
} else if (value == AlbumPopupAction.cleanUncategorized) {
await onCleanUncategorizedClick(context);
} else if (value == AlbumPopupAction.editLocation) {
editLocation();
} else if (value == AlbumPopupAction.deleteLocation) {
await deleteLocation();
} else {
showToast(context, S.of(context).somethingWentWrong);
}
@@ -582,6 +606,24 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
return actions;
}
void editLocation() {
showEditLocationSheet(
context,
InheritedLocationScreenState.of(context).locationTagEntity,
);
}
Future<void> deleteLocation() async {
try {
await LocationService.instance.deleteLocationTag(
InheritedLocationScreenState.of(context).locationTagEntity.id,
);
Navigator.of(context).pop();
} catch (e) {
await showGenericErrorDialog(context: context, error: e);
}
}
Future<void> onCleanUncategorizedClick(BuildContext buildContext) async {
final actionResult = await showChoiceActionSheet(
context,

View File

@@ -2,131 +2,79 @@ import "dart:async";
import 'dart:developer' as dev;
import "package:flutter/material.dart";
import "package:intl/intl.dart";
import "package:photos/core/constants.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/db/files_db.dart";
import "package:photos/events/files_updated_event.dart";
import "package:photos/events/local_photos_updated_event.dart";
import "package:photos/generated/l10n.dart";
import 'package:photos/models/file/file.dart';
import "package:photos/models/file_load_result.dart";
import "package:photos/models/gallery_type.dart";
import "package:photos/models/search/hierarchical/hierarchical_search_filter.dart";
import "package:photos/models/search/hierarchical/location_filter.dart";
import "package:photos/models/selected_files.dart";
import "package:photos/services/collections_service.dart";
import "package:photos/services/filter/db_filters.dart";
import "package:photos/services/location_service.dart";
import "package:photos/states/location_screen_state.dart";
import "package:photos/theme/colors.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/common/loading_widget.dart";
import "package:photos/ui/components/buttons/icon_button_widget.dart";
import "package:photos/ui/components/title_bar_title_widget.dart";
import "package:photos/ui/components/title_bar_widget.dart";
import "package:photos/ui/viewer/actions/file_selection_overlay_bar.dart";
import "package:photos/ui/viewer/gallery/gallery.dart";
import "package:photos/ui/viewer/gallery/gallery_app_bar_widget.dart";
import "package:photos/ui/viewer/gallery/state/gallery_files_inherited_widget.dart";
import "package:photos/ui/viewer/gallery/state/inherited_search_filter_data.dart";
import "package:photos/ui/viewer/gallery/state/search_filter_data_provider.dart";
import "package:photos/ui/viewer/gallery/state/selection_state.dart";
import "package:photos/ui/viewer/location/edit_location_sheet.dart";
import "package:photos/utils/dialog_util.dart";
class LocationScreen extends StatelessWidget {
class LocationScreen extends StatefulWidget {
final String tagPrefix;
const LocationScreen({this.tagPrefix = "", super.key});
@override
State<LocationScreen> createState() => _LocationScreenState();
}
class _LocationScreenState extends State<LocationScreen> {
final selectedFiles = SelectedFiles();
@override
Widget build(BuildContext context) {
final heightOfStatusBar = MediaQuery.of(context).viewPadding.top;
const heightOfAppBar = 48.0;
final locationTag =
InheritedLocationScreenState.of(context).locationTagEntity.item;
return GalleryFilesState(
child: Scaffold(
appBar: const PreferredSize(
preferredSize: Size(double.infinity, heightOfAppBar),
child: TitleBarWidget(
isSliver: false,
isFlexibleSpaceDisabled: true,
actionIcons: [LocationScreenPopUpMenu()],
child: InheritedSearchFilterData(
searchFilterDataProvider: SearchFilterDataProvider(
initialGalleryFilter: LocationFilter(
locationTag: locationTag,
occurrence: kMostRelevantFilter,
),
),
body: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height -
(heightOfAppBar + heightOfStatusBar),
width: double.infinity,
child: LocationGalleryWidget(
tagPrefix: tagPrefix,
),
child: Scaffold(
appBar: PreferredSize(
preferredSize: const Size(double.infinity, heightOfAppBar),
child: GalleryAppBarWidget(
GalleryType.locationTag,
locationTag.name,
selectedFiles,
),
],
),
),
);
}
}
class LocationScreenPopUpMenu extends StatelessWidget {
const LocationScreenPopUpMenu({super.key});
@override
Widget build(BuildContext context) {
final textTheme = getEnteTextTheme(context);
final colorScheme = getEnteColorScheme(context);
return Padding(
padding: const EdgeInsets.only(right: 4),
child: Theme(
data: Theme.of(context).copyWith(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
),
child: PopupMenuButton(
elevation: 2,
offset: const Offset(10, 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
color: colorScheme.backgroundElevated2,
child: const IconButtonWidget(
icon: Icons.more_horiz,
iconButtonType: IconButtonType.primary,
disableGestureDetector: true,
),
itemBuilder: (context) {
return [
PopupMenuItem(
value: "edit",
child: Text(
S.of(context).edit,
style: textTheme.bodyBold,
body: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height -
(heightOfAppBar + heightOfStatusBar),
width: double.infinity,
child: LocationGalleryWidget(
tagPrefix: widget.tagPrefix,
selectedFiles: selectedFiles,
),
),
PopupMenuItem(
onTap: () {},
value: "delete",
child: Text(
S.of(context).deleteLocation,
style: textTheme.bodyBold.copyWith(color: warning500),
),
),
];
},
onSelected: (value) async {
if (value == "edit") {
showEditLocationSheet(
context,
InheritedLocationScreenState.of(context).locationTagEntity,
);
} else if (value == "delete") {
try {
await LocationService.instance.deleteLocationTag(
InheritedLocationScreenState.of(context).locationTagEntity.id,
);
Navigator.of(context).pop();
} catch (e) {
await showGenericErrorDialog(context: context, error: e);
}
}
},
],
),
),
),
);
@@ -135,7 +83,12 @@ class LocationScreenPopUpMenu extends StatelessWidget {
class LocationGalleryWidget extends StatefulWidget {
final String tagPrefix;
const LocationGalleryWidget({required this.tagPrefix, super.key});
final SelectedFiles selectedFiles;
const LocationGalleryWidget({
required this.tagPrefix,
required this.selectedFiles,
super.key,
});
@override
State<LocationGalleryWidget> createState() => _LocationGalleryWidgetState();
@@ -145,7 +98,6 @@ class _LocationGalleryWidgetState extends State<LocationGalleryWidget> {
late final Future<FileLoadResult> fileLoadResult;
late final List<EnteFile> allFilesWithLocation;
late Widget galleryHeaderWidget;
final _selectedFiles = SelectedFiles();
late final StreamSubscription<LocalPhotosUpdatedEvent> _filesUpdateEvent;
@override
@@ -183,8 +135,6 @@ class _LocationGalleryWidgetState extends State<LocationGalleryWidget> {
});
return value;
});
galleryHeaderWidget = const GalleryHeaderWidget();
}
@override
@@ -243,13 +193,11 @@ class _LocationGalleryWidgetState extends State<LocationGalleryWidget> {
Gallery(
loadingWidget: Column(
children: [
galleryHeaderWidget,
EnteLoadingWidget(
color: getEnteColorScheme(context).strokeMuted,
),
],
),
header: galleryHeaderWidget,
asyncLoader: (
creationStartTime,
creationEndTime, {
@@ -274,10 +222,9 @@ class _LocationGalleryWidgetState extends State<LocationGalleryWidget> {
),
);
} else {
return Column(
return const Column(
children: [
galleryHeaderWidget,
const Expanded(
Expanded(
child: EnteLoadingWidget(),
),
],
@@ -288,65 +235,3 @@ class _LocationGalleryWidgetState extends State<LocationGalleryWidget> {
);
}
}
class GalleryHeaderWidget extends StatefulWidget {
const GalleryHeaderWidget({super.key});
@override
State<GalleryHeaderWidget> createState() => _GalleryHeaderWidgetState();
}
class _GalleryHeaderWidgetState extends State<GalleryHeaderWidget> {
@override
Widget build(BuildContext context) {
final locationName =
InheritedLocationScreenState.of(context).locationTagEntity.item.name;
return Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
key: ValueKey(locationName),
width: double.infinity,
child: TitleBarTitleWidget(
title: locationName,
onTap: () {
showEditLocationSheet(
context,
InheritedLocationScreenState.of(context).locationTagEntity,
);
},
),
),
ValueListenableBuilder(
valueListenable: InheritedLocationScreenState.memoryCountNotifier,
builder: (context, int? value, _) {
if (value == null) {
return RepaintBoundary(
child: EnteLoadingWidget(
size: 12,
color: getEnteColorScheme(context).strokeMuted,
alignment: Alignment.centerLeft,
padding: 2.5,
),
);
} else {
return Text(
S
.of(context)
.memoryCount(value, NumberFormat().format(value)),
style: getEnteTextTheme(context).smallMuted,
);
}
},
),
],
),
),
);
}
}