feat: option for mobile smooth timeline scrubbing (#32552)
* feat(mobile): add smooth timeline scrubbing setting * refactor: read smooth scrubbing setting where the scrubber is built (cherry picked from commit 222d9276d31e890d3d9beb6dae5d96a6f6ab52f0)
This commit is contained in:
@@ -2204,6 +2204,8 @@
|
|||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
"theme_selection": "Theme selection",
|
"theme_selection": "Theme selection",
|
||||||
"theme_selection_description": "Automatically set the theme to light or dark based on your browser's system preference",
|
"theme_selection_description": "Automatically set the theme to light or dark based on your browser's system preference",
|
||||||
|
"theme_setting_asset_list_smooth_scrubbing_subtitle": "Scroll continuously when dragging the scrollbar instead of snapping to months",
|
||||||
|
"theme_setting_asset_list_smooth_scrubbing_title": "Smooth timeline scrubbing",
|
||||||
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
|
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
|
||||||
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({count})",
|
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({count})",
|
||||||
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ abstract class AppConfig with _$AppConfig {
|
|||||||
.timelineTilesPerRow => timeline.tilesPerRow,
|
.timelineTilesPerRow => timeline.tilesPerRow,
|
||||||
.timelineGroupAssetsBy => timeline.groupAssetsBy,
|
.timelineGroupAssetsBy => timeline.groupAssetsBy,
|
||||||
.timelineStorageIndicator => timeline.storageIndicator,
|
.timelineStorageIndicator => timeline.storageIndicator,
|
||||||
|
.timelineSmoothScrubbing => timeline.smoothScrubbing,
|
||||||
.mapShowFavoriteOnly => map.favoritesOnly,
|
.mapShowFavoriteOnly => map.favoritesOnly,
|
||||||
.mapRelativeDate => map.relativeDays,
|
.mapRelativeDate => map.relativeDays,
|
||||||
.mapCustomFrom => map.customFrom,
|
.mapCustomFrom => map.customFrom,
|
||||||
@@ -131,6 +132,7 @@ abstract class AppConfig with _$AppConfig {
|
|||||||
.timelineTilesPerRow => copyWith(timeline: timeline.copyWith(tilesPerRow: value as int)),
|
.timelineTilesPerRow => copyWith(timeline: timeline.copyWith(tilesPerRow: value as int)),
|
||||||
.timelineGroupAssetsBy => copyWith(timeline: timeline.copyWith(groupAssetsBy: value as GroupAssetsBy)),
|
.timelineGroupAssetsBy => copyWith(timeline: timeline.copyWith(groupAssetsBy: value as GroupAssetsBy)),
|
||||||
.timelineStorageIndicator => copyWith(timeline: timeline.copyWith(storageIndicator: value as bool)),
|
.timelineStorageIndicator => copyWith(timeline: timeline.copyWith(storageIndicator: value as bool)),
|
||||||
|
.timelineSmoothScrubbing => copyWith(timeline: timeline.copyWith(smoothScrubbing: value as bool)),
|
||||||
.mapShowFavoriteOnly => copyWith(map: map.copyWith(favoritesOnly: value as bool)),
|
.mapShowFavoriteOnly => copyWith(map: map.copyWith(favoritesOnly: value as bool)),
|
||||||
.mapRelativeDate => copyWith(map: map.copyWith(relativeDays: value as int)),
|
.mapRelativeDate => copyWith(map: map.copyWith(relativeDays: value as int)),
|
||||||
.mapCustomFrom => copyWith(map: map.copyWith(customFrom: .fromNullable(value as DateTime?))),
|
.mapCustomFrom => copyWith(map: map.copyWith(customFrom: .fromNullable(value as DateTime?))),
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ abstract class TimelineConfig with _$TimelineConfig {
|
|||||||
@Default(4) int tilesPerRow,
|
@Default(4) int tilesPerRow,
|
||||||
@Default(GroupAssetsBy.day) GroupAssetsBy groupAssetsBy,
|
@Default(GroupAssetsBy.day) GroupAssetsBy groupAssetsBy,
|
||||||
@Default(true) bool storageIndicator,
|
@Default(true) bool storageIndicator,
|
||||||
|
@Default(false) bool smoothScrubbing,
|
||||||
}) = _TimelineConfig;
|
}) = _TimelineConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ enum SettingsKey<T> {
|
|||||||
timelineTilesPerRow<int>(),
|
timelineTilesPerRow<int>(),
|
||||||
timelineGroupAssetsBy<GroupAssetsBy>(codec: EnumCodec(GroupAssetsBy.values)),
|
timelineGroupAssetsBy<GroupAssetsBy>(codec: EnumCodec(GroupAssetsBy.values)),
|
||||||
timelineStorageIndicator<bool>(),
|
timelineStorageIndicator<bool>(),
|
||||||
|
timelineSmoothScrubbing<bool>(),
|
||||||
|
|
||||||
// Log
|
// Log
|
||||||
logLevel<LogLevel>(codec: EnumCodec(LogLevel.values)),
|
logLevel<LogLevel>(codec: EnumCodec(LogLevel.values)),
|
||||||
|
|||||||
@@ -328,6 +328,8 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
|||||||
final isMultiSelectStatusVisible = !isSelectionMode && isMultiSelectEnabled;
|
final isMultiSelectStatusVisible = !isSelectionMode && isMultiSelectEnabled;
|
||||||
final isBottomWidgetVisible =
|
final isBottomWidgetVisible =
|
||||||
widget.bottomSheet != null && (isMultiSelectStatusVisible || widget.persistentBottomBar);
|
widget.bottomSheet != null && (isMultiSelectStatusVisible || widget.persistentBottomBar);
|
||||||
|
final smoothScrubbing = ref.watch(appConfigProvider.select((config) => config.timeline.smoothScrubbing));
|
||||||
|
final snapToMonth = widget.snapToMonth && !smoothScrubbing;
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: !isMultiSelectEnabled,
|
canPop: !isMultiSelectEnabled,
|
||||||
@@ -409,7 +411,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
|||||||
final Widget timeline;
|
final Widget timeline;
|
||||||
if (widget.withScrubber) {
|
if (widget.withScrubber) {
|
||||||
timeline = Scrubber(
|
timeline = Scrubber(
|
||||||
snapToMonth: widget.snapToMonth,
|
snapToMonth: snapToMonth,
|
||||||
layoutSegments: segments,
|
layoutSegments: segments,
|
||||||
timelineHeight: maxHeight,
|
timelineHeight: maxHeight,
|
||||||
topPadding: topPadding,
|
topPadding: topPadding,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class AssetListSettings extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final storageIndicator = useValueNotifier(ref.watch(appConfigProvider.select((s) => s.timeline.storageIndicator)));
|
final storageIndicator = useValueNotifier(ref.watch(appConfigProvider.select((s) => s.timeline.storageIndicator)));
|
||||||
|
final smoothScrubbing = useValueNotifier(ref.watch(appConfigProvider.select((s) => s.timeline.smoothScrubbing)));
|
||||||
|
|
||||||
final assetListSetting = [
|
final assetListSetting = [
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
@@ -27,6 +28,16 @@ class AssetListSettings extends HookConsumerWidget {
|
|||||||
ref.invalidate(settingsProvider);
|
ref.invalidate(settingsProvider);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SettingsSwitchListTile(
|
||||||
|
valueNotifier: smoothScrubbing,
|
||||||
|
title: context.t.theme_setting_asset_list_smooth_scrubbing_title,
|
||||||
|
subtitle: context.t.theme_setting_asset_list_smooth_scrubbing_subtitle,
|
||||||
|
onChanged: (value) {
|
||||||
|
unawaited(ref.read(settingsProvider).write(.timelineSmoothScrubbing, value));
|
||||||
|
ref.invalidate(appSettingsServiceProvider);
|
||||||
|
ref.invalidate(settingsProvider);
|
||||||
|
},
|
||||||
|
),
|
||||||
const LayoutSettings(),
|
const LayoutSettings(),
|
||||||
const GroupSettings(),
|
const GroupSettings(),
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user