Add scaling ux to collecton browser

This commit is contained in:
Ming Ming 2023-06-18 22:26:19 +08:00
parent ebd593e5be
commit e8b3c6e0a4
5 changed files with 83 additions and 6 deletions

View file

@ -1,5 +1,7 @@
abstract class BlocTag {
String get tag;
abstract class BlocLogger {
String? get tag => null;
bool Function(dynamic currentState, dynamic nextState)? get shouldLog => null;
}
/// Wrap around a string such that two strings with the same value will fail

View file

@ -36,7 +36,14 @@ class _BlocObserver extends BlocObserver {
@override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
final tag = bloc is BlocTag ? (bloc as BlocTag).tag : bloc.runtimeType;
_log.finer("$tag $change");
if (bloc is BlocLogger) {
final bl = bloc as BlocLogger;
final tag = bl.tag ?? bloc.runtimeType;
if (bl.shouldLog?.call(change.currentState, change.nextState) ?? true) {
_log.finer("$tag newState: ${change.nextState}");
}
} else {
_log.finer("${bloc.runtimeType} newState: ${change.nextState}");
}
}
}

View file

@ -62,6 +62,7 @@ import 'package:nc_photos/widget/shared_album_info_dialog.dart';
import 'package:nc_photos/widget/simple_input_dialog.dart';
import 'package:nc_photos/widget/viewer.dart';
import 'package:np_codegen/np_codegen.dart';
import 'package:sliver_tools/sliver_tools.dart';
import 'package:to_string/to_string.dart';
part 'collection_browser.g.dart';
@ -277,10 +278,26 @@ class _WrappedCollectionBrowserState extends State<_WrappedCollectionBrowser>
),
_BlocBuilder(
buildWhen: (previous, current) =>
previous.isEditMode != current.isEditMode,
previous.isEditMode != current.isEditMode ||
previous.scale != current.scale,
builder: (context, state) {
if (!state.isEditMode) {
return const _ContentList();
return SliverStack(
children: [
SliverOpacity(
opacity: state.scale == null
? 1
: _scaleToCurrentOpacity(state.scale!),
sliver: const _ContentList(),
),
if (state.scale != null)
SliverOpacity(
opacity: 1 -
_scaleToCurrentOpacity(state.scale!),
sliver: const _ScalingList(),
),
],
);
} else {
if (context
.read<_Bloc>()
@ -373,6 +390,22 @@ class _WrappedCollectionBrowserState extends State<_WrappedCollectionBrowser>
}
}
static double _scaleToCurrentOpacity(double scale) {
if (scale < 1) {
if (scale <= .3) {
return 0;
} else {
return ((scale - .3) / .7).clamp(0, 1);
}
} else {
if (scale >= 1.9) {
return 0;
} else {
return (1 - (scale - 1) / .9).clamp(0, 1);
}
}
}
late final _bloc = context.read<_Bloc>();
final _scrollController = ScrollController();
bool? _isDragScrollingDown;
@ -392,6 +425,32 @@ class _ContentList extends StatelessWidget {
}
}
class _ScalingList extends StatelessWidget {
const _ScalingList();
@override
Widget build(BuildContext context) {
return _BlocBuilder(
buildWhen: (previous, current) => previous.scale != current.scale,
builder: (context, state) {
if (state.scale == null) {
return const SizedBox.shrink();
}
int nextZoom;
if (state.scale! > 1) {
nextZoom = state.zoom + 1;
} else {
nextZoom = state.zoom - 1;
}
nextZoom = nextZoom.clamp(-1, 2);
return _ContentListBody(
maxCrossAxisExtent: photo_list_util.getThumbSize(nextZoom).toDouble(),
);
},
);
}
}
class _ContentListBody extends StatelessWidget {
const _ContentListBody({
required this.maxCrossAxisExtent,

View file

@ -1294,6 +1294,14 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
sliver_tools:
dependency: "direct main"
description:
name: sliver_tools
sha256: ccdc502098a8bfa07b3ec582c282620031481300035584e1bb3aca296a505e8c
url: "https://pub.dev"
source: hosted
version: "0.2.10"
smooth_corner:
dependency: "direct main"
description:

View file

@ -110,6 +110,7 @@ dependencies:
rxdart: ^0.27.7
screen_brightness: ^0.2.2
shared_preferences: ^2.0.8
sliver_tools: ^0.2.10
smooth_corner: ^1.1.0
sqlite3: any
sqlite3_flutter_libs: ^0.5.15