more refactors and logs page handling

This commit is contained in:
shenlong-tanwen
2024-10-23 02:30:46 +05:30
parent 8f47645cdb
commit a0afea04d8
90 changed files with 2386 additions and 584 deletions
@@ -98,11 +98,11 @@ class DraggableScrollbar extends StatefulWidget {
required BoxConstraints? labelConstraints,
required bool alwaysVisibleScrollThumb,
}) {
var scrollThumbAndLabel = labelText == null
Widget scrollThumbAndLabel = labelText == null
? scrollThumb
: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
_ScrollLabel(
animation: labelAnimation,
@@ -145,8 +145,8 @@ class DraggableScrollbar extends StatefulWidget {
color: backgroundColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(height),
bottomLeft: Radius.circular(height),
topRight: const Radius.circular(4.0),
bottomLeft: Radius.circular(height),
bottomRight: const Radius.circular(4.0),
),
child: Container(
@@ -195,9 +195,9 @@ class _ScrollLabel extends StatelessWidget {
color: backgroundColor,
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
child: Container(
constraints: constraints ?? _defaultConstraints,
padding: const EdgeInsets.symmetric(horizontal: 15),
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 15),
constraints: constraints ?? _defaultConstraints,
child: child,
),
),
@@ -231,8 +231,8 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
_currentItem = 0;
_thumbAnimationController = AnimationController(
vsync: this,
duration: widget.scrollbarAnimationDuration,
vsync: this,
);
_thumbAnimation = CurvedAnimation(
@@ -241,8 +241,8 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
);
_labelAnimationController = AnimationController(
vsync: this,
duration: widget.scrollbarAnimationDuration,
vsync: this,
);
_labelAnimation = CurvedAnimation(
@@ -291,16 +291,16 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
onVerticalDragEnd: _onVerticalDragEnd,
child: Container(
alignment: Alignment.topRight,
margin: EdgeInsets.only(top: _barOffset),
padding: widget.padding,
margin: EdgeInsets.only(top: _barOffset),
child: widget.scrollThumbBuilder(
widget.backgroundColor,
widget.foregroundColor,
_thumbAnimation,
_labelAnimation,
widget.heightScrollThumb,
labelText: labelText,
labelConstraints: widget.labelConstraints,
labelText: labelText,
),
),
),
@@ -356,7 +356,7 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
_thumbAnimationController.forward();
}
final lastItemPos = itemPos;
final lastItemPos = _itemPos;
if (lastItemPos < widget.maxItemCount) {
_currentItem = lastItemPos;
}
@@ -378,7 +378,7 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
widget.scrollStateListener(true);
}
int get itemIndex {
int get _itemIndex {
int index = 0;
double minDiff = 1000;
for (final pos in _positions) {
@@ -391,21 +391,21 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
return index;
}
int get itemPos =>
int get _itemPos =>
((_barOffset / (_barMaxScrollExtent)) * widget.maxItemCount).toInt();
void _jumpToBarPos() {
final lastItemPos = itemPos;
final lastItemPos = _itemPos;
if (lastItemPos > widget.maxItemCount - 1) {
return;
}
_currentItem = itemIndex;
_currentItem = _itemIndex;
widget.controller.sliverController.jumpToIndex(lastItemPos);
}
Timer? _dragHaltTimer;
int lastTimerPos = 0;
int _lastTimerPos = 0;
void _onVerticalDragUpdate(DragUpdateDetails details) {
setState(() {
@@ -418,9 +418,9 @@ class _DraggableScrollbarState extends State<DraggableScrollbar>
_barOffset =
clampDouble(_barOffset, _barMinScrollExtent, _barMaxScrollExtent);
final lastItemPos = itemPos;
if (lastItemPos != lastTimerPos) {
lastTimerPos = lastItemPos;
final lastItemPos = _itemPos;
if (lastItemPos != _lastTimerPos) {
_lastTimerPos = lastItemPos;
_dragHaltTimer?.cancel();
widget.scrollStateListener(true);
@@ -26,6 +26,17 @@ class AssetGridState {
renderList: renderList ?? this.renderList,
);
}
@override
bool operator ==(covariant AssetGridState other) {
if (identical(this, other)) return true;
return other.renderList == renderList &&
other.isDragScrolling == isDragScrolling;
}
@override
int get hashCode => renderList.hashCode ^ isDragScrolling.hashCode;
}
class AssetGridCubit extends Cubit<AssetGridState> {
@@ -43,6 +54,9 @@ class AssetGridCubit extends Cubit<AssetGridState> {
super(AssetGridState.empty()) {
_renderListSubscription =
_renderListProvider.renderStreamProvider().listen((renderList) {
if (renderList == state.renderList) {
return;
}
_bufOffset = 0;
_buf = [];
emit(state.copyWith(renderList: renderList));
@@ -87,8 +101,8 @@ class AssetGridCubit extends Cubit<AssetGridState> {
// load the calculated batch (start:start+len) from the DB and put it into the buffer
_buf = await _renderListProvider.renderAssetProvider(
offset: start,
limit: len,
offset: start,
);
_bufOffset = start;
@@ -13,6 +13,7 @@ import 'package:intl/intl.dart';
import 'package:material_symbols_icons/symbols.dart';
part 'immich_asset_grid_header.widget.dart';
part 'immich_asset_render_grid.widget.dart';
class ImAssetGrid extends StatefulWidget {
/// The padding for the grid
@@ -76,7 +77,6 @@ class _ImAssetGridState extends State<ImAssetGrid> {
}
final grid = FlutterListView(
controller: _controller,
delegate: FlutterListViewDelegate(
(_, sectionIndex) {
// ignore: avoid-unsafe-collection-methods
@@ -89,70 +89,46 @@ class _ImAssetGridState extends State<ImAssetGrid> {
RenderListMonthHeaderElement() =>
_MonthHeader(text: section.header),
RenderListDayHeaderElement() => Text(section.header),
RenderListAssetElement() => FutureBuilder(
future: context.read<AssetGridCubit>().loadAssets(
section.assetOffset,
section.assetCount,
),
builder: (_, assetsSnap) {
final assets = assetsSnap.data;
return GridView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
addAutomaticKeepAlives: false,
cacheExtent: 100,
padding: const EdgeInsets.all(0),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 3,
crossAxisSpacing: 3,
),
itemBuilder: (_, i) {
final asset = assetsSnap.isWaiting || assets == null
? null
: assets.elementAtOrNull(i);
return SizedBox.square(
dimension: 200,
// Show Placeholder when drag scrolled
child: asset == null || state.isDragScrolling
? const ImImagePlaceholder()
: ImThumbnail(asset),
);
},
itemCount: section.assetCount,
);
},
RenderListAssetElement() => _StaticGrid(
section: section,
isDragging: state.isDragScrolling,
),
};
},
childCount: elements.length,
addAutomaticKeepAlives: false,
),
controller: _controller,
);
final EdgeInsetsGeometry? padding;
if (widget.topPadding != null) {
padding = EdgeInsets.only(top: widget.topPadding!);
} else {
if (widget.topPadding == null) {
padding = null;
} else {
padding = EdgeInsets.only(top: widget.topPadding!);
}
return DraggableScrollbar(
foregroundColor: context.colorScheme.onSurface,
backgroundColor: context.colorScheme.surfaceContainerHighest,
scrollStateListener:
context.read<AssetGridCubit>().setDragScrolling,
controller: _controller,
maxItemCount: elements.length,
scrollStateListener:
context.read<AssetGridCubit>().setDragScrolling,
backgroundColor: context.colorScheme.surfaceContainerHighest,
foregroundColor: context.colorScheme.onSurface,
padding: padding,
scrollbarAnimationDuration: Durations.medium2,
scrollbarTimeToFade: Durations.extralong4,
labelTextBuilder: (int position) =>
_labelBuilder(elements, position),
labelConstraints: const BoxConstraints(maxHeight: 36),
scrollbarAnimationDuration: Durations.medium2,
scrollbarTimeToFade: Durations.extralong4,
padding: padding,
child: grid,
);
},
// no.of elements are not equal or is modified
buildWhen: (previous, current) =>
(previous.renderList.elements.length !=
current.renderList.elements.length) ||
!previous.renderList.modifiedTime
.isAtSameMomentAs(current.renderList.modifiedTime),
);
}
@@ -10,8 +10,8 @@ class _HeaderText extends StatelessWidget {
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
top: 32.0,
left: 16.0,
top: 32.0,
right: 24.0,
bottom: 16.0,
),
@@ -40,9 +40,9 @@ class _MonthHeader extends StatelessWidget {
return _HeaderText(
text: text,
style: context.textTheme.bodyLarge?.copyWith(
color: context.colorScheme.onSurface,
fontSize: 24.0,
fontWeight: FontWeight.w500,
color: context.colorScheme.onSurface,
),
);
}
@@ -0,0 +1,46 @@
part of 'immich_asset_grid.widget.dart';
class _StaticGrid extends StatelessWidget {
final RenderListAssetElement section;
final bool isDragging;
const _StaticGrid({required this.section, required this.isDragging});
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: context.read<AssetGridCubit>().loadAssets(
section.assetOffset,
section.assetCount,
),
builder: (_, assetsSnap) {
final assets = assetsSnap.data;
return GridView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 3,
crossAxisSpacing: 3,
),
itemBuilder: (_, i) {
final asset = assetsSnap.isWaiting || assets == null
? null
: assets.elementAtOrNull(i);
return SizedBox.square(
dimension: 200,
// Show Placeholder when drag scrolled
child: asset == null || isDragging
? const ImImagePlaceholder()
: ImThumbnail(asset),
);
},
itemCount: section.assetCount,
addAutomaticKeepAlives: false,
cacheExtent: 100,
);
},
);
}
}