Use normal AppBar instead of SliverAppBar to make gallery work

This commit is contained in:
ashilkn 2023-03-28 17:15:26 +05:30
parent 93935374e1
commit 3a3aaa1035
2 changed files with 288 additions and 169 deletions

View file

@ -13,6 +13,7 @@ class TitleBarWidget extends StatelessWidget {
final bool isFlexibleSpaceDisabled;
final bool isOnTopOfScreen;
final Color? backgroundColor;
final bool isSliver;
const TitleBarWidget({
this.leading,
this.title,
@ -24,103 +25,96 @@ class TitleBarWidget extends StatelessWidget {
this.isFlexibleSpaceDisabled = false,
this.isOnTopOfScreen = true,
this.backgroundColor,
this.isSliver = true,
super.key,
});
@override
Widget build(BuildContext context) {
const toolbarHeight = 48.0;
final textTheme = getEnteTextTheme(context);
final colorTheme = getEnteColorScheme(context);
return SliverAppBar(
backgroundColor: backgroundColor,
primary: isOnTopOfScreen ? true : false,
toolbarHeight: toolbarHeight,
leadingWidth: 48,
automaticallyImplyLeading: false,
pinned: true,
expandedHeight: isFlexibleSpaceDisabled ? toolbarHeight : 102,
centerTitle: false,
titleSpacing: 4,
title: Padding(
padding: EdgeInsets.only(left: isTitleH2WithoutLeading ? 16 : 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
title == null
? const SizedBox.shrink()
: Text(
title!,
style: isTitleH2WithoutLeading
? textTheme.h2Bold
: textTheme.largeBold,
),
caption == null || isTitleH2WithoutLeading
? const SizedBox.shrink()
: Text(
caption!,
style: textTheme.mini.copyWith(color: colorTheme.textMuted),
)
],
if (isSliver) {
return SliverAppBar(
backgroundColor: backgroundColor,
primary: isOnTopOfScreen ? true : false,
toolbarHeight: toolbarHeight,
leadingWidth: 48,
automaticallyImplyLeading: false,
pinned: true,
expandedHeight: isFlexibleSpaceDisabled ? toolbarHeight : 102,
centerTitle: false,
titleSpacing: 4,
title: TitleWidget(
title: title,
caption: caption,
isTitleH2WithoutLeading: isTitleH2WithoutLeading,
),
),
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Row(
children: _actionsWithPaddingInBetween(),
),
),
],
leading: isTitleH2WithoutLeading
? null
: leading ??
IconButtonWidget(
icon: Icons.arrow_back_outlined,
iconButtonType: IconButtonType.primary,
onTap: () {
Navigator.pop(context);
},
),
flexibleSpace: isFlexibleSpaceDisabled
? null
: FlexibleSpaceBar(
background: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(height: toolbarHeight),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 4,
horizontal: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
flexibleSpaceTitle == null
? const SizedBox.shrink()
: flexibleSpaceTitle!,
flexibleSpaceCaption == null
? const SizedBox.shrink()
: Text(
flexibleSpaceCaption!,
style: textTheme.small.copyWith(
color: colorTheme.textMuted,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
)
],
),
),
],
),
),
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Row(
children: _actionsWithPaddingInBetween(),
),
);
),
],
leading: isTitleH2WithoutLeading
? null
: leading ??
IconButtonWidget(
icon: Icons.arrow_back_outlined,
iconButtonType: IconButtonType.primary,
onTap: () {
Navigator.pop(context);
},
),
flexibleSpace: isFlexibleSpaceDisabled
? null
: FlexibleSpaceBarWidget(
flexibleSpaceTitle,
flexibleSpaceCaption,
toolbarHeight,
),
);
} else {
return AppBar(
backgroundColor: backgroundColor,
primary: isOnTopOfScreen ? true : false,
toolbarHeight: toolbarHeight,
leadingWidth: 48,
automaticallyImplyLeading: false,
centerTitle: false,
titleSpacing: 4,
title: TitleWidget(
title: title,
caption: caption,
isTitleH2WithoutLeading: isTitleH2WithoutLeading,
),
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Row(
children: _actionsWithPaddingInBetween(),
),
),
],
leading: isTitleH2WithoutLeading
? null
: leading ??
IconButtonWidget(
icon: Icons.arrow_back_outlined,
iconButtonType: IconButtonType.primary,
onTap: () {
Navigator.pop(context);
},
),
flexibleSpace: isFlexibleSpaceDisabled
? null
: FlexibleSpaceBarWidget(
flexibleSpaceTitle,
flexibleSpaceCaption,
toolbarHeight,
),
);
}
}
_actionsWithPaddingInBetween() {
@ -150,3 +144,89 @@ class TitleBarWidget extends StatelessWidget {
return actions;
}
}
class TitleWidget extends StatelessWidget {
final String? title;
final String? caption;
final bool isTitleH2WithoutLeading;
const TitleWidget(
{this.title,
this.caption,
required this.isTitleH2WithoutLeading,
super.key});
@override
Widget build(BuildContext context) {
final textTheme = getEnteTextTheme(context);
return Padding(
padding: EdgeInsets.only(left: isTitleH2WithoutLeading ? 16 : 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
title == null
? const SizedBox.shrink()
: Text(
title!,
style: isTitleH2WithoutLeading
? textTheme.h2Bold
: textTheme.largeBold,
),
caption == null || isTitleH2WithoutLeading
? const SizedBox.shrink()
: Text(
caption!,
style: textTheme.miniMuted,
)
],
),
);
}
}
class FlexibleSpaceBarWidget extends StatelessWidget {
final Widget? flexibleSpaceTitle;
final String? flexibleSpaceCaption;
final double toolbarHeight;
const FlexibleSpaceBarWidget(
this.flexibleSpaceTitle, this.flexibleSpaceCaption, this.toolbarHeight,
{super.key});
@override
Widget build(BuildContext context) {
final textTheme = getEnteTextTheme(context);
return FlexibleSpaceBar(
background: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(height: toolbarHeight),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 4,
horizontal: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
flexibleSpaceTitle == null
? const SizedBox.shrink()
: flexibleSpaceTitle!,
flexibleSpaceCaption == null
? const SizedBox.shrink()
: Text(
flexibleSpaceCaption!,
style: textTheme.smallMuted,
overflow: TextOverflow.ellipsis,
maxLines: 1,
)
],
),
),
],
),
),
);
}
}

View file

@ -1,9 +1,15 @@
import "package:flutter/material.dart";
import "package:photos/core/configuration.dart";
import "package:photos/core/constants.dart";
import "package:photos/db/files_db.dart";
import "package:photos/models/file_load_result.dart";
import "package:photos/services/collections_service.dart";
import "package:photos/services/ignored_files_service.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/components/text_input_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/gallery/gallery.dart";
import "package:photos/ui/viewer/location/radius_picker_widget.dart";
class LocationScreen extends StatelessWidget {
@ -13,94 +19,80 @@ class LocationScreen extends StatelessWidget {
Widget build(BuildContext context) {
final editNotifier = ValueNotifier(false);
return Scaffold(
body: CustomScrollView(
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
ValueListenableBuilder(
valueListenable: editNotifier,
builder: (context, value, _) {
Widget child;
if (value as bool) {
child = SizedBox(
key: ValueKey(value),
width: double.infinity,
child: const TitleBarTitleWidget(
title: "Edit location",
),
);
} else {
child = SizedBox(
key: ValueKey(value),
width: double.infinity,
child: const TitleBarTitleWidget(
title: "Location name",
),
);
}
return AnimatedSwitcher(
switchInCurve: Curves.easeInExpo,
switchOutCurve: Curves.easeOutExpo,
duration: const Duration(milliseconds: 200),
child: child,
);
},
),
Text(
"51 memories",
style: getEnteTextTheme(context).smallMuted,
),
],
),
actionIcons: [
IconButton(
onPressed: () {
editNotifier.value = !editNotifier.value;
},
icon: const Icon(Icons.edit_rounded),
)
],
),
SliverList(
delegate: SliverChildListDelegate([
appBar: PreferredSize(
preferredSize: const Size(double.infinity, 102),
child: TitleBarWidget(
isSliver: false,
isFlexibleSpaceDisabled: false,
flexibleSpaceTitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
ValueListenableBuilder(
valueListenable: editNotifier,
builder: (context, value, _) {
return AnimatedCrossFade(
firstCurve: Curves.easeInOutExpo,
secondCurve: Curves.easeInOutExpo,
sizeCurve: Curves.easeInOutExpo,
firstChild: const LocationEditingWidget(),
secondChild: const SizedBox.shrink(),
crossFadeState: editNotifier.value
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 300),
Widget child;
if (value as bool) {
child = SizedBox(
key: ValueKey(value),
width: double.infinity,
child: const TitleBarTitleWidget(
title: "Edit location",
),
);
} else {
child = SizedBox(
key: ValueKey(value),
width: double.infinity,
child: const TitleBarTitleWidget(
title: "Location name",
),
);
}
return AnimatedSwitcher(
switchInCurve: Curves.easeInExpo,
switchOutCurve: Curves.easeOutExpo,
duration: const Duration(milliseconds: 200),
child: child,
);
},
),
//Gallery here
Container(
width: double.infinity,
height: 300,
color: Colors.teal,
Text(
"51 memories",
style: getEnteTextTheme(context).smallMuted,
),
Container(
width: double.infinity,
height: 300,
color: Colors.red,
),
Container(
width: double.infinity,
height: 300,
color: Colors.orange,
),
]),
],
),
actionIcons: [
IconButton(
onPressed: () {
editNotifier.value = !editNotifier.value;
},
icon: const Icon(Icons.edit_rounded),
)
],
),
),
body: Column(
children: <Widget>[
ValueListenableBuilder(
valueListenable: editNotifier,
builder: (context, value, _) {
return AnimatedCrossFade(
firstCurve: Curves.easeInOutExpo,
secondCurve: Curves.easeInOutExpo,
sizeCurve: Curves.easeInOutExpo,
firstChild: const LocationEditingWidget(),
secondChild: const SizedBox(width: double.infinity),
crossFadeState: editNotifier.value
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 300),
);
},
),
const SizedBox(
height: 1500, width: 320, child: LocationGalleryWidget()),
],
),
);
@ -163,3 +155,50 @@ class LocationEditingWidget extends StatelessWidget {
);
}
}
class LocationGalleryWidget extends StatelessWidget {
const LocationGalleryWidget({super.key});
@override
Widget build(BuildContext context) {
return Gallery(
asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) async {
final ownerID = Configuration.instance.getUserID();
final hasSelectedAllForBackup =
Configuration.instance.hasSelectedAllFoldersForBackup();
final collectionsToHide =
CollectionsService.instance.collectionsHiddenFromTimeline();
FileLoadResult result;
if (hasSelectedAllForBackup) {
result = await FilesDB.instance.getAllLocalAndUploadedFiles(
creationStartTime,
creationEndTime,
ownerID!,
limit: limit,
asc: asc,
ignoredCollectionIDs: collectionsToHide,
);
} else {
result = await FilesDB.instance.getAllPendingOrUploadedFiles(
creationStartTime,
creationEndTime,
ownerID!,
limit: limit,
asc: asc,
ignoredCollectionIDs: collectionsToHide,
);
}
// hide ignored files from home page UI
final ignoredIDs = await IgnoredFilesService.instance.ignoredIDs;
result.files.removeWhere(
(f) =>
f.uploadedFileID == null &&
IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, f),
);
return result;
},
tagPrefix: "location_gallery",
);
}
}