fix(mobile): keep header image when starting selection (#32356)
* fix(mobile): keep header image when starting selection * fix(mobile): fade out header actions during selection Hide the back button and person options menu with the same fade as the timeline app bar, and block taps on the person name and birthday while assets are selected. --------- Co-authored-by: Santo Shakil <santoshakil@users.noreply.github.com> (cherry picked from commit 745bdd2edf72ce0f75e748e2d68c37b6ea196cc5)
This commit is contained in:
@@ -36,64 +36,63 @@ class _MesmerizingSliverAppBarState extends ConsumerState<MesmerizingSliverAppBa
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isMultiSelectEnabled = ref.watch(multiSelectProvider.select((s) => s.isEnabled));
|
||||
Widget hideWhenSelecting(Widget child) => IgnorePointer(
|
||||
ignoring: isMultiSelectEnabled,
|
||||
child: AnimatedOpacity(duration: Durations.medium1, opacity: isMultiSelectEnabled ? 0 : 1, child: child),
|
||||
);
|
||||
|
||||
return isMultiSelectEnabled
|
||||
? SliverToBoxAdapter(
|
||||
child: switch (_scrollProgress) {
|
||||
< 0.8 => const SizedBox(height: 120),
|
||||
_ => const SizedBox(height: 352),
|
||||
},
|
||||
)
|
||||
: SliverAppBar(
|
||||
expandedHeight: 300.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
snap: false,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(
|
||||
Platform.isIOS ? Icons.arrow_back_ios_new_rounded : Icons.arrow_back,
|
||||
color: Color.lerp(Colors.white, context.primaryColor, _scrollProgress),
|
||||
shadows: [
|
||||
_scrollProgress < 0.95
|
||||
? Shadow(offset: const Offset(0, 2), blurRadius: 5, color: Colors.black.withValues(alpha: 0.5))
|
||||
: const Shadow(offset: Offset(0, 2), blurRadius: 0, color: Colors.transparent),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
flexibleSpace: Builder(
|
||||
builder: (context) {
|
||||
final settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
|
||||
final scrollProgress = _calculateScrollProgress(settings);
|
||||
return SliverAppBar(
|
||||
expandedHeight: 300.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
snap: false,
|
||||
elevation: 0,
|
||||
leading: hideWhenSelecting(
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Platform.isIOS ? Icons.arrow_back_ios_new_rounded : Icons.arrow_back,
|
||||
color: Color.lerp(Colors.white, context.primaryColor, _scrollProgress),
|
||||
shadows: [
|
||||
_scrollProgress < 0.95
|
||||
? Shadow(offset: const Offset(0, 2), blurRadius: 5, color: Colors.black.withValues(alpha: 0.5))
|
||||
: const Shadow(offset: Offset(0, 2), blurRadius: 0, color: Colors.transparent),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
flexibleSpace: Builder(
|
||||
builder: (context) {
|
||||
final settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
|
||||
final scrollProgress = _calculateScrollProgress(settings);
|
||||
|
||||
// Update scroll progress for the leading button
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted && _scrollProgress != scrollProgress) {
|
||||
setState(() {
|
||||
_scrollProgress = scrollProgress;
|
||||
});
|
||||
}
|
||||
});
|
||||
// Update scroll progress for the leading button
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted && _scrollProgress != scrollProgress) {
|
||||
setState(() {
|
||||
_scrollProgress = scrollProgress;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return FlexibleSpaceBar(
|
||||
centerTitle: true,
|
||||
title: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: scrollProgress > 0.95
|
||||
? Text(
|
||||
widget.title,
|
||||
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.w600, fontSize: 18),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
background: _ExpandedBackground(scrollProgress: scrollProgress, title: widget.title),
|
||||
);
|
||||
},
|
||||
return FlexibleSpaceBar(
|
||||
centerTitle: true,
|
||||
title: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: scrollProgress > 0.95
|
||||
? Text(
|
||||
widget.title,
|
||||
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.w600, fontSize: 18),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
background: _ExpandedBackground(scrollProgress: scrollProgress, title: widget.title),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,10 @@ class _MesmerizingSliverAppBarState extends ConsumerState<PersonSliverAppBar> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isMultiSelectEnabled = ref.watch(multiSelectProvider.select((s) => s.isEnabled));
|
||||
Widget hideWhenSelecting(Widget child) => IgnorePointer(
|
||||
ignoring: isMultiSelectEnabled,
|
||||
child: AnimatedOpacity(duration: Durations.medium1, opacity: isMultiSelectEnabled ? 0 : 1, child: child),
|
||||
);
|
||||
final Color? actionIconColor = Color.lerp(Colors.white, context.primaryColor, _scrollProgress);
|
||||
final List<Shadow> actionIconShadows = [
|
||||
if (_scrollProgress < 0.95)
|
||||
@@ -62,74 +66,74 @@ class _MesmerizingSliverAppBarState extends ConsumerState<PersonSliverAppBar> {
|
||||
const Shadow(offset: Offset(0, 2), blurRadius: 0, color: Colors.transparent),
|
||||
];
|
||||
|
||||
return isMultiSelectEnabled
|
||||
? SliverToBoxAdapter(
|
||||
child: switch (_scrollProgress) {
|
||||
< 0.8 => const SizedBox(height: 120),
|
||||
_ => const SizedBox(height: 352),
|
||||
},
|
||||
)
|
||||
: SliverAppBar(
|
||||
expandedHeight: 300.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
snap: false,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(
|
||||
Platform.isIOS ? Icons.arrow_back_ios_new_rounded : Icons.arrow_back,
|
||||
color: Color.lerp(Colors.white, context.primaryColor, _scrollProgress),
|
||||
shadows: [
|
||||
_scrollProgress < 0.95
|
||||
? Shadow(offset: const Offset(0, 2), blurRadius: 5, color: Colors.black.withValues(alpha: 0.5))
|
||||
: const Shadow(offset: Offset(0, 2), blurRadius: 0, color: Colors.transparent),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.more_vert, color: actionIconColor, shadows: actionIconShadows),
|
||||
onPressed: widget.onShowOptions,
|
||||
),
|
||||
return SliverAppBar(
|
||||
expandedHeight: 300.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
snap: false,
|
||||
elevation: 0,
|
||||
leading: hideWhenSelecting(
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Platform.isIOS ? Icons.arrow_back_ios_new_rounded : Icons.arrow_back,
|
||||
color: Color.lerp(Colors.white, context.primaryColor, _scrollProgress),
|
||||
shadows: [
|
||||
_scrollProgress < 0.95
|
||||
? Shadow(offset: const Offset(0, 2), blurRadius: 5, color: Colors.black.withValues(alpha: 0.5))
|
||||
: const Shadow(offset: Offset(0, 2), blurRadius: 0, color: Colors.transparent),
|
||||
],
|
||||
flexibleSpace: Builder(
|
||||
builder: (context) {
|
||||
final settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
|
||||
final scrollProgress = _calculateScrollProgress(settings);
|
||||
),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
hideWhenSelecting(
|
||||
IconButton(
|
||||
icon: Icon(Icons.more_vert, color: actionIconColor, shadows: actionIconShadows),
|
||||
onPressed: widget.onShowOptions,
|
||||
),
|
||||
),
|
||||
],
|
||||
flexibleSpace: Builder(
|
||||
builder: (context) {
|
||||
final settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
|
||||
final scrollProgress = _calculateScrollProgress(settings);
|
||||
|
||||
// Update scroll progress for the leading button
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted && _scrollProgress != scrollProgress) {
|
||||
setState(() {
|
||||
_scrollProgress = scrollProgress;
|
||||
});
|
||||
}
|
||||
});
|
||||
// Update scroll progress for the leading button
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted && _scrollProgress != scrollProgress) {
|
||||
setState(() {
|
||||
_scrollProgress = scrollProgress;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return FlexibleSpaceBar(
|
||||
centerTitle: true,
|
||||
title: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: scrollProgress > 0.95
|
||||
? Text(
|
||||
widget.person.name,
|
||||
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.w600, fontSize: 18),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
background: _ExpandedBackground(
|
||||
scrollProgress: scrollProgress,
|
||||
person: widget.person,
|
||||
onNameTap: widget.onNameTap,
|
||||
onBirthdayTap: widget.onBirthdayTap,
|
||||
),
|
||||
);
|
||||
},
|
||||
return FlexibleSpaceBar(
|
||||
centerTitle: true,
|
||||
title: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: scrollProgress > 0.95
|
||||
? Text(
|
||||
widget.person.name,
|
||||
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.w600, fontSize: 18),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
background: IgnorePointer(
|
||||
ignoring: isMultiSelectEnabled,
|
||||
child: _ExpandedBackground(
|
||||
scrollProgress: scrollProgress,
|
||||
person: widget.person,
|
||||
onNameTap: widget.onNameTap,
|
||||
onBirthdayTap: widget.onBirthdayTap,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user