From cdd1353bb21e5220407d65d9043d2e237f1bd544 Mon Sep 17 00:00:00 2001 From: ashilkn Date: Sat, 26 Jul 2025 17:31:09 +0530 Subject: [PATCH] Delete old gallery files --- .../ui/huge_listview/draggable_scrollbar.dart | 217 -------------- .../lib/ui/huge_listview/huge_listview.dart | 201 ------------- .../ui/huge_listview/scroll_bar_thumb.dart | 159 ----------- .../grid/gallery_grid_view_widget.dart | 52 ---- .../component/grid/lazy_grid_view.dart | 113 -------- .../grid/non_recyclable_grid_view_widget.dart | 73 ----- .../grid/place_holder_grid_view_widget.dart | 49 ---- .../grid/recyclable_grid_view_widget.dart | 71 ----- .../component/group/group_gallery.dart | 56 ---- .../component/group/lazy_group_gallery.dart | 267 ------------------ .../multiple_groups_gallery_view.dart | 160 ----------- .../photos/lib/ui/viewer/gallery/gallery.dart | 23 -- 12 files changed, 1441 deletions(-) delete mode 100644 mobile/apps/photos/lib/ui/huge_listview/draggable_scrollbar.dart delete mode 100644 mobile/apps/photos/lib/ui/huge_listview/huge_listview.dart delete mode 100644 mobile/apps/photos/lib/ui/huge_listview/scroll_bar_thumb.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/grid/lazy_grid_view.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/grid/non_recyclable_grid_view_widget.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/grid/recyclable_grid_view_widget.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/group/group_gallery.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart delete mode 100644 mobile/apps/photos/lib/ui/viewer/gallery/component/multiple_groups_gallery_view.dart diff --git a/mobile/apps/photos/lib/ui/huge_listview/draggable_scrollbar.dart b/mobile/apps/photos/lib/ui/huge_listview/draggable_scrollbar.dart deleted file mode 100644 index 0770d6bd0d..0000000000 --- a/mobile/apps/photos/lib/ui/huge_listview/draggable_scrollbar.dart +++ /dev/null @@ -1,217 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:photos/ui/huge_listview/scroll_bar_thumb.dart'; - -class DraggableScrollbar extends StatefulWidget { - final Widget child; - final Color backgroundColor; - final Color drawColor; - final double heightScrollThumb; - final EdgeInsetsGeometry? padding; - final int totalCount; - final int initialScrollIndex; - final double bottomSafeArea; - final int currentFirstIndex; - final ValueChanged? onChange; - final String Function(int) labelTextBuilder; - final bool isEnabled; - - const DraggableScrollbar({ - super.key, - required this.child, - this.backgroundColor = Colors.white, - this.drawColor = Colors.grey, - this.heightScrollThumb = 80.0, - this.bottomSafeArea = 120, - this.padding, - this.totalCount = 1, - this.initialScrollIndex = 0, - this.currentFirstIndex = 0, - required this.labelTextBuilder, - this.onChange, - this.isEnabled = true, - }); - - @override - DraggableScrollbarState createState() => DraggableScrollbarState(); -} - -class DraggableScrollbarState extends State - with TickerProviderStateMixin { - static const thumbAnimationDuration = Duration(milliseconds: 1000); - static const labelAnimationDuration = Duration(milliseconds: 1000); - double thumbOffset = 0.0; - bool isDragging = false; - late int currentFirstIndex; - - double get thumbMin => 0.0; - - double get thumbMax => - context.size!.height - widget.heightScrollThumb - widget.bottomSafeArea; - - late AnimationController _thumbAnimationController; - Animation? _thumbAnimation; - late AnimationController _labelAnimationController; - Animation? _labelAnimation; - Timer? _fadeoutTimer; - - @override - void initState() { - super.initState(); - currentFirstIndex = widget.currentFirstIndex; - - ///Where will this be true on init? - if (widget.initialScrollIndex > 0 && widget.totalCount > 1) { - WidgetsBinding.instance.addPostFrameCallback((_) { - setState( - () => thumbOffset = (widget.initialScrollIndex / widget.totalCount) * - (thumbMax - thumbMin), - ); - }); - } - - _thumbAnimationController = AnimationController( - vsync: this, - duration: thumbAnimationDuration, - animationBehavior: AnimationBehavior.preserve, - ); - - _thumbAnimation = CurvedAnimation( - parent: _thumbAnimationController, - curve: Curves.fastOutSlowIn, - ); - - _labelAnimationController = AnimationController( - vsync: this, - duration: labelAnimationDuration, - animationBehavior: AnimationBehavior.preserve, - ); - - _labelAnimation = CurvedAnimation( - parent: _labelAnimationController, - curve: Curves.fastOutSlowIn, - ); - } - - @override - void dispose() { - _thumbAnimationController.dispose(); - _labelAnimationController.dispose(); - _fadeoutTimer?.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - children: [ - RepaintBoundary(child: widget.child), - widget.isEnabled - ? RepaintBoundary(child: buildThumb()) - : const SizedBox.shrink(), - ], - ); - } - - Widget buildThumb() => Padding( - padding: widget.padding!, - child: Container( - alignment: Alignment.topRight, - margin: EdgeInsets.only(top: thumbOffset), - child: ScrollBarThumb( - widget.backgroundColor, - widget.drawColor, - widget.heightScrollThumb, - widget.labelTextBuilder.call(currentFirstIndex), - _labelAnimation, - _thumbAnimation, - onDragStart, - onDragUpdate, - onDragEnd, - ), - ), - ); - - void setPosition(double position, int currentFirstIndex) { - setState(() { - this.currentFirstIndex = currentFirstIndex; - thumbOffset = position * (thumbMax - thumbMin); - if (_thumbAnimationController.status != AnimationStatus.forward) { - _thumbAnimationController.forward(); - } - _fadeoutTimer?.cancel(); - _fadeoutTimer = Timer(thumbAnimationDuration, () { - _thumbAnimationController.reverse(); - _labelAnimationController.reverse(); - _fadeoutTimer = null; - }); - }); - } - - void onDragStart(DragStartDetails details) { - setState(() { - isDragging = true; - _labelAnimationController.forward(); - _fadeoutTimer?.cancel(); - }); - } - - void onDragUpdate(DragUpdateDetails details) { - setState(() { - if (_thumbAnimationController.status != AnimationStatus.forward) { - _thumbAnimationController.forward(); - } - if (isDragging && details.delta.dy != 0) { - thumbOffset += details.delta.dy; - thumbOffset = thumbOffset.clamp(thumbMin, thumbMax); - final double position = thumbOffset / (thumbMax - thumbMin); - widget.onChange?.call(position); - } - }); - } - - void onDragEnd(DragEndDetails details) { - _fadeoutTimer = Timer(thumbAnimationDuration, () { - _thumbAnimationController.reverse(); - _labelAnimationController.reverse(); - _fadeoutTimer = null; - }); - setState(() => isDragging = false); - } - - void keyHandler(KeyEvent value) { - if (value.runtimeType == KeyDownEvent) { - if (value.logicalKey == LogicalKeyboardKey.arrowDown) { - onDragUpdate( - DragUpdateDetails( - globalPosition: Offset.zero, - delta: const Offset(0, 2), - ), - ); - } else if (value.logicalKey == LogicalKeyboardKey.arrowUp) { - onDragUpdate( - DragUpdateDetails( - globalPosition: Offset.zero, - delta: const Offset(0, -2), - ), - ); - } else if (value.logicalKey == LogicalKeyboardKey.pageDown) { - onDragUpdate( - DragUpdateDetails( - globalPosition: Offset.zero, - delta: const Offset(0, 25), - ), - ); - } else if (value.logicalKey == LogicalKeyboardKey.pageUp) { - onDragUpdate( - DragUpdateDetails( - globalPosition: Offset.zero, - delta: const Offset(0, -25), - ), - ); - } - } - } -} diff --git a/mobile/apps/photos/lib/ui/huge_listview/huge_listview.dart b/mobile/apps/photos/lib/ui/huge_listview/huge_listview.dart deleted file mode 100644 index c4a8f343ee..0000000000 --- a/mobile/apps/photos/lib/ui/huge_listview/huge_listview.dart +++ /dev/null @@ -1,201 +0,0 @@ -import 'dart:math' show max; - -import 'package:flutter/material.dart'; -import 'package:photos/ui/huge_listview/draggable_scrollbar.dart'; -import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; - -typedef HugeListViewItemBuilder = Widget Function( - BuildContext context, - int index, -); -typedef HugeListViewErrorBuilder = Widget Function( - BuildContext context, - dynamic error, -); - -class HugeListView extends StatefulWidget { - /// A [ScrollablePositionedList] controller for jumping or scrolling to an item. - final ItemScrollController? controller; - - /// Index of an item to initially align within the viewport. - final int startIndex; - - /// Total number of items in the list. - final int totalCount; - - /// Called to build the thumb. One of [DraggableScrollbarThumbs.RoundedRectThumb], [DraggableScrollbarThumbs.ArrowThumb] - /// or [DraggableScrollbarThumbs.SemicircleThumb], or build your own. - final String Function(int) labelTextBuilder; - - /// Background color of scroll thumb, defaults to white. - final Color thumbBackgroundColor; - - /// Drawing color of scroll thumb, defaults to gray. - final Color thumbDrawColor; - - /// Height of scroll thumb, defaults to 48. - final double thumbHeight; - - /// Height of bottomSafeArea so that scroll thumb does not become hidden - /// or un-clickable due to footer elements. Default value is 120 - final double bottomSafeArea; - - /// Called to build an individual item with the specified [index]. - final HugeListViewItemBuilder itemBuilder; - - /// Called to build a progress widget while the whole list is initialized. - final WidgetBuilder? waitBuilder; - - /// Called to build a widget when the list is empty. - final WidgetBuilder? emptyResultBuilder; - - /// Called to build a widget when there is an error. - final HugeListViewErrorBuilder? errorBuilder; - - /// Event to call with the index of the topmost visible item in the viewport while scrolling. - /// Can be used to display the current letter of an alphabetically sorted list, for instance. - final ValueChanged? firstShown; - - final bool isDraggableScrollbarEnabled; - - final EdgeInsetsGeometry? thumbPadding; - - final bool disableScroll; - - final bool isScrollablePositionedList; - - const HugeListView({ - super.key, - this.controller, - required this.startIndex, - required this.totalCount, - required this.labelTextBuilder, - required this.itemBuilder, - this.waitBuilder, - this.emptyResultBuilder, - this.errorBuilder, - this.firstShown, - this.thumbBackgroundColor = Colors.red, // Colors.white, - this.thumbDrawColor = Colors.yellow, //Colors.grey, - this.thumbHeight = 48.0, - this.bottomSafeArea = 120.0, - this.isDraggableScrollbarEnabled = true, - this.thumbPadding, - this.disableScroll = false, - this.isScrollablePositionedList = true, - }); - - @override - HugeListViewState createState() => HugeListViewState(); -} - -class HugeListViewState extends State> { - final scrollKey = GlobalKey(); - final listener = ItemPositionsListener.create(); - int lastIndexJump = -1; - dynamic error; - - @override - void initState() { - super.initState(); - - widget.isScrollablePositionedList - ? listener.itemPositions.addListener(_sendScroll) - : null; - } - - @override - void dispose() { - listener.itemPositions.removeListener(_sendScroll); - super.dispose(); - } - - void _sendScroll() { - final int current = _currentFirst(); - widget.firstShown?.call(current); - scrollKey.currentState?.setPosition(current / widget.totalCount, current); - } - - int _currentFirst() { - try { - return listener.itemPositions.value.first.index; - } catch (e) { - return 0; - } - } - - @override - Widget build(BuildContext context) { - if (error != null && widget.errorBuilder != null) { - return widget.errorBuilder!(context, error); - } - if (widget.totalCount == -1 && widget.waitBuilder != null) { - return widget.waitBuilder!(context); - } - if (widget.totalCount == 0 && widget.emptyResultBuilder != null) { - return widget.emptyResultBuilder!(context); - } - - return widget.isScrollablePositionedList - ? DraggableScrollbar( - key: scrollKey, - totalCount: widget.totalCount, - initialScrollIndex: widget.startIndex, - onChange: (position) { - final int currentIndex = _currentFirst(); - final int floorIndex = (position * widget.totalCount).floor(); - final int cielIndex = (position * widget.totalCount).ceil(); - int nextIndexToJump; - if (floorIndex != currentIndex && floorIndex > currentIndex) { - nextIndexToJump = floorIndex; - } else if (cielIndex != currentIndex && - cielIndex < currentIndex) { - nextIndexToJump = floorIndex; - } else { - return; - } - if (lastIndexJump != nextIndexToJump) { - lastIndexJump = nextIndexToJump; - widget.controller?.jumpTo(index: nextIndexToJump); - } - }, - labelTextBuilder: widget.labelTextBuilder, - backgroundColor: widget.thumbBackgroundColor, - drawColor: widget.thumbDrawColor, - heightScrollThumb: widget.thumbHeight, - bottomSafeArea: widget.bottomSafeArea, - currentFirstIndex: _currentFirst(), - isEnabled: widget.isDraggableScrollbarEnabled, - padding: widget.thumbPadding, - child: ScrollablePositionedList.builder( - physics: widget.disableScroll - ? const NeverScrollableScrollPhysics() - : const BouncingScrollPhysics(), - itemScrollController: widget.controller, - itemPositionsListener: listener, - initialScrollIndex: widget.startIndex, - itemCount: max(widget.totalCount, 0), - itemBuilder: (context, index) { - return ExcludeSemantics( - child: widget.itemBuilder(context, index), - ); - }, - ), - ) - : ListView.builder( - physics: const BouncingScrollPhysics(), - itemCount: max(widget.totalCount, 0), - itemBuilder: (context, index) { - return ExcludeSemantics( - child: widget.itemBuilder(context, index), - ); - }, - ); - } - - /// Jump to the [position] in the list. [position] is between 0.0 (first item) and 1.0 (last item), practically currentIndex / totalCount. - /// To jump to a specific item, use [ItemScrollController.jumpTo] or [ItemScrollController.scrollTo]. - void setPosition(double position) { - scrollKey.currentState?.setPosition(position, _currentFirst()); - } -} diff --git a/mobile/apps/photos/lib/ui/huge_listview/scroll_bar_thumb.dart b/mobile/apps/photos/lib/ui/huge_listview/scroll_bar_thumb.dart deleted file mode 100644 index 11714f1f6a..0000000000 --- a/mobile/apps/photos/lib/ui/huge_listview/scroll_bar_thumb.dart +++ /dev/null @@ -1,159 +0,0 @@ -import 'package:flutter/material.dart'; - -class ScrollBarThumb extends StatelessWidget { - final Color backgroundColor; - final Color drawColor; - final double height; - final String title; - final Animation? labelAnimation; - final Animation? thumbAnimation; - final Function(DragStartDetails details) onDragStart; - final Function(DragUpdateDetails details) onDragUpdate; - final Function(DragEndDetails details) onDragEnd; - - const ScrollBarThumb( - this.backgroundColor, - this.drawColor, - this.height, - this.title, - this.labelAnimation, - this.thumbAnimation, - this.onDragStart, - this.onDragUpdate, - this.onDragEnd, { - super.key, - }); - - @override - Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - IgnorePointer( - child: FadeTransition( - opacity: labelAnimation as Animation, - child: Container( - padding: const EdgeInsets.fromLTRB(20, 12, 20, 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: backgroundColor, - ), - child: Text( - title, - style: TextStyle( - color: drawColor, - fontWeight: FontWeight.bold, - backgroundColor: Colors.transparent, - fontSize: 14, - ), - ), - ), - ), - ), - const Padding( - padding: EdgeInsets.all(12), - ), - GestureDetector( - onVerticalDragStart: onDragStart, - onVerticalDragUpdate: onDragUpdate, - onVerticalDragEnd: onDragEnd, - child: SlideFadeTransition( - animation: thumbAnimation as Animation?, - child: CustomPaint( - foregroundPainter: _ArrowCustomPainter(drawColor), - child: Material( - elevation: 4.0, - color: backgroundColor, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(height), - bottomLeft: Radius.circular(height), - topRight: const Radius.circular(4.0), - bottomRight: const Radius.circular(4.0), - ), - child: Container( - constraints: BoxConstraints.tight(Size(height * 0.6, height)), - ), - ), - ), - ), - ), - ], - ); - } -} - -class _ArrowCustomPainter extends CustomPainter { - final Color drawColor; - - _ArrowCustomPainter(this.drawColor); - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) => false; - - @override - void paint(Canvas canvas, Size size) { - final paint = Paint() - ..isAntiAlias = true - ..style = PaintingStyle.fill - ..color = drawColor; - const width = 10.0; - const height = 8.0; - final baseX = size.width / 2; - final baseY = size.height / 2; - - canvas.drawPath( - trianglePath(Offset(baseX - 2.0, baseY - 2.0), width, height, true), - paint, - ); - canvas.drawPath( - trianglePath(Offset(baseX - 2.0, baseY + 2.0), width, height, false), - paint, - ); - } - - static Path trianglePath( - Offset offset, - double width, - double height, - bool isUp, - ) { - return Path() - ..moveTo(offset.dx, offset.dy) - ..lineTo(offset.dx + width, offset.dy) - ..lineTo( - offset.dx + (width / 2), - isUp ? offset.dy - height : offset.dy + height, - ) - ..close(); - } -} - -class SlideFadeTransition extends StatelessWidget { - final Animation? animation; - final Widget child; - - const SlideFadeTransition({ - super.key, - required this.animation, - required this.child, - }); - - @override - Widget build(BuildContext context) { - return AnimatedBuilder( - animation: animation!, - builder: (context, child) => - animation!.value == 0.0 ? const SizedBox.shrink() : child!, - child: SlideTransition( - position: Tween( - begin: const Offset(0.3, 0.0), - end: const Offset(0.0, 0.0), - ).animate(animation!), - child: FadeTransition( - opacity: animation!, - child: child, - ), - ), - ); - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart deleted file mode 100644 index d0b7776be4..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart +++ /dev/null @@ -1,52 +0,0 @@ -import "package:flutter/widgets.dart"; -import "package:photos/core/constants.dart"; -import 'package:photos/models/file/file.dart'; -import "package:photos/models/selected_files.dart"; -import "package:photos/ui/viewer/gallery/component/gallery_file_widget.dart"; -import "package:photos/ui/viewer/gallery/gallery.dart"; - -class GalleryGridViewWidget extends StatelessWidget { - final List filesInGroup; - final int photoGridSize; - final SelectedFiles? selectedFiles; - final bool limitSelectionToOne; - final String tag; - final int? currentUserID; - final GalleryLoader asyncLoader; - const GalleryGridViewWidget({ - required this.filesInGroup, - required this.photoGridSize, - this.selectedFiles, - required this.limitSelectionToOne, - required this.tag, - super.key, - this.currentUserID, - required this.asyncLoader, - }); - - @override - Widget build(BuildContext context) { - return GridView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - // to disable GridView's scrolling - itemBuilder: (context, index) { - return GalleryFileWidget( - file: filesInGroup[index], - selectedFiles: selectedFiles, - limitSelectionToOne: limitSelectionToOne, - tag: tag, - photoGridSize: photoGridSize, - currentUserID: currentUserID, - ); - }, - itemCount: filesInGroup.length, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisSpacing: 2, - mainAxisSpacing: 2, - crossAxisCount: photoGridSize, - ), - padding: const EdgeInsets.symmetric(vertical: (galleryGridSpacing / 2)), - ); - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/lazy_grid_view.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/lazy_grid_view.dart deleted file mode 100644 index 54323fbfd4..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/lazy_grid_view.dart +++ /dev/null @@ -1,113 +0,0 @@ -import "dart:async"; - -import "package:flutter/foundation.dart"; -import "package:flutter/material.dart"; -import "package:photos/core/configuration.dart"; -import "package:photos/core/event_bus.dart"; -import "package:photos/events/clear_selections_event.dart"; -import 'package:photos/models/file/file.dart'; -import "package:photos/models/selected_files.dart"; -import "package:photos/ui/viewer/gallery/component/grid/non_recyclable_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/component/grid/recyclable_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/gallery.dart"; - -class LazyGridView extends StatefulWidget { - final String tag; - final List filesInGroup; - final GalleryLoader asyncLoader; - final SelectedFiles? selectedFiles; - final bool shouldRender; - final bool shouldRecycle; - final int? photoGridSize; - final bool limitSelectionToOne; - - const LazyGridView( - this.tag, - this.filesInGroup, - this.asyncLoader, - this.selectedFiles, - this.shouldRender, - this.shouldRecycle, - this.photoGridSize, { - this.limitSelectionToOne = false, - super.key, - }); - - @override - State createState() => _LazyGridViewState(); -} - -class _LazyGridViewState extends State { - late bool _shouldRender; - int? _currentUserID; - late StreamSubscription _clearSelectionsEvent; - - @override - void initState() { - _shouldRender = widget.shouldRender; - _currentUserID = Configuration.instance.getUserID(); - widget.selectedFiles?.addListener(_selectedFilesListener); - _clearSelectionsEvent = - Bus.instance.on().listen((event) { - if (mounted) { - setState(() {}); - } - }); - super.initState(); - } - - @override - void dispose() { - widget.selectedFiles?.removeListener(_selectedFilesListener); - _clearSelectionsEvent.cancel(); - - super.dispose(); - } - - @override - void didUpdateWidget(LazyGridView oldWidget) { - super.didUpdateWidget(oldWidget); - if (!listEquals(widget.filesInGroup, oldWidget.filesInGroup)) { - _shouldRender = widget.shouldRender; - } - } - - @override - Widget build(BuildContext context) { - if (widget.shouldRecycle) { - return RecyclableGridViewWidget( - shouldRender: _shouldRender, - filesInGroup: widget.filesInGroup, - photoGridSize: widget.photoGridSize!, - limitSelectionToOne: widget.limitSelectionToOne, - tag: widget.tag, - asyncLoader: widget.asyncLoader, - selectedFiles: widget.selectedFiles, - currentUserID: _currentUserID, - ); - } else { - return NonRecyclableGridViewWidget( - shouldRender: _shouldRender, - filesInGroup: widget.filesInGroup, - photoGridSize: widget.photoGridSize!, - limitSelectionToOne: widget.limitSelectionToOne, - tag: widget.tag, - asyncLoader: widget.asyncLoader, - selectedFiles: widget.selectedFiles, - currentUserID: _currentUserID, - ); - } - } - - void _selectedFilesListener() { - bool shouldRefresh = false; - for (final file in widget.filesInGroup) { - if (widget.selectedFiles!.isPartOfLastSelected(file)) { - shouldRefresh = true; - } - } - if (shouldRefresh && mounted) { - setState(() {}); - } - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/non_recyclable_grid_view_widget.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/non_recyclable_grid_view_widget.dart deleted file mode 100644 index 80e136af58..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/non_recyclable_grid_view_widget.dart +++ /dev/null @@ -1,73 +0,0 @@ -import "package:flutter/material.dart"; -import 'package:photos/models/file/file.dart'; -import "package:photos/models/selected_files.dart"; -import "package:photos/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/gallery.dart"; -import "package:visibility_detector/visibility_detector.dart"; - -class NonRecyclableGridViewWidget extends StatefulWidget { - final bool shouldRender; - final List filesInGroup; - final int photoGridSize; - final bool limitSelectionToOne; - final String tag; - final GalleryLoader asyncLoader; - final int? currentUserID; - final SelectedFiles? selectedFiles; - const NonRecyclableGridViewWidget({ - required this.shouldRender, - required this.filesInGroup, - required this.photoGridSize, - required this.limitSelectionToOne, - required this.tag, - required this.asyncLoader, - this.currentUserID, - this.selectedFiles, - super.key, - }); - - @override - State createState() => - _NonRecyclableGridViewWidgetState(); -} - -class _NonRecyclableGridViewWidgetState - extends State { - late bool _shouldRender; - @override - void initState() { - _shouldRender = widget.shouldRender; - super.initState(); - } - - @override - Widget build(BuildContext context) { - if (!_shouldRender) { - return VisibilityDetector( - key: Key("gallery" + widget.filesInGroup.first.tag), - onVisibilityChanged: (visibility) { - if (mounted && visibility.visibleFraction > 0 && !_shouldRender) { - setState(() { - _shouldRender = true; - }); - } - }, - child: PlaceHolderGridViewWidget( - widget.filesInGroup.length, - widget.photoGridSize, - ), - ); - } else { - return GalleryGridViewWidget( - filesInGroup: widget.filesInGroup, - photoGridSize: widget.photoGridSize, - limitSelectionToOne: widget.limitSelectionToOne, - tag: widget.tag, - asyncLoader: widget.asyncLoader, - selectedFiles: widget.selectedFiles, - currentUserID: widget.currentUserID, - ); - } - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart deleted file mode 100644 index c29d817ab3..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart +++ /dev/null @@ -1,49 +0,0 @@ -import "dart:math"; - -import "package:flutter/foundation.dart"; -import 'package:flutter/material.dart'; -import "package:photos/theme/ente_theme.dart"; - -class PlaceHolderGridViewWidget extends StatelessWidget { - const PlaceHolderGridViewWidget( - this.count, - this.columns, { - super.key, - }); - - final int count, columns; - - static Widget? _placeHolderCache; - static final _gridViewCache = {}; - static const crossAxisSpacing = 2.0; // as per your code - static const mainAxisSpacing = 2.0; // as per your code - - @override - Widget build(BuildContext context) { - final Color faintColor = getEnteColorScheme(context).fillFaint; - int limitCount = count; - if (kDebugMode) { - limitCount = min(count, columns * 5); - } - - final key = '$limitCount:$columns'; - if (!_gridViewCache.containsKey(key)) { - _gridViewCache[key] = GridView.builder( - padding: const EdgeInsets.only(top: 2), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return PlaceHolderGridViewWidget._placeHolderCache ??= - Container(color: faintColor); - }, - itemCount: limitCount, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: columns, - crossAxisSpacing: crossAxisSpacing, - mainAxisSpacing: mainAxisSpacing, - ), - ); - } - return _gridViewCache[key]!; - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/recyclable_grid_view_widget.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/recyclable_grid_view_widget.dart deleted file mode 100644 index 0e5f264f3d..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/grid/recyclable_grid_view_widget.dart +++ /dev/null @@ -1,71 +0,0 @@ -import "package:flutter/material.dart"; -import 'package:photos/models/file/file.dart'; -import "package:photos/models/selected_files.dart"; -import "package:photos/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/gallery.dart"; -import "package:visibility_detector/visibility_detector.dart"; - -class RecyclableGridViewWidget extends StatefulWidget { - final bool shouldRender; - final List filesInGroup; - final int photoGridSize; - final bool limitSelectionToOne; - final String tag; - final GalleryLoader asyncLoader; - final int? currentUserID; - final SelectedFiles? selectedFiles; - const RecyclableGridViewWidget({ - required this.shouldRender, - required this.filesInGroup, - required this.photoGridSize, - required this.limitSelectionToOne, - required this.tag, - required this.asyncLoader, - this.currentUserID, - this.selectedFiles, - super.key, - }); - - @override - State createState() => - _RecyclableGridViewWidgetState(); -} - -class _RecyclableGridViewWidgetState extends State { - late bool _shouldRender; - @override - void initState() { - _shouldRender = widget.shouldRender; - super.initState(); - } - - @override - Widget build(BuildContext context) { - return VisibilityDetector( - key: Key("gallery" + widget.filesInGroup.first.tag), - onVisibilityChanged: (visibility) { - final shouldRender = visibility.visibleFraction > 0; - if (mounted && shouldRender != _shouldRender) { - setState(() { - _shouldRender = shouldRender; - }); - } - }, - child: _shouldRender - ? GalleryGridViewWidget( - filesInGroup: widget.filesInGroup, - photoGridSize: widget.photoGridSize, - limitSelectionToOne: widget.limitSelectionToOne, - tag: widget.tag, - asyncLoader: widget.asyncLoader, - selectedFiles: widget.selectedFiles, - currentUserID: widget.currentUserID, - ) - : PlaceHolderGridViewWidget( - widget.filesInGroup.length, - widget.photoGridSize, - ), - ); - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/group/group_gallery.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/group/group_gallery.dart deleted file mode 100644 index 5a54407fe6..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/group/group_gallery.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:photos/core/constants.dart'; -import 'package:photos/models/file/file.dart'; -import 'package:photos/models/selected_files.dart'; -import "package:photos/ui/viewer/gallery/component/grid/lazy_grid_view.dart"; -import 'package:photos/ui/viewer/gallery/gallery.dart'; - -class GroupGallery extends StatelessWidget { - final int photoGridSize; - final List files; - final String tag; - final GalleryLoader asyncLoader; - final SelectedFiles? selectedFiles; - final bool limitSelectionToOne; - - const GroupGallery({ - required this.photoGridSize, - required this.files, - required this.tag, - required this.asyncLoader, - required this.selectedFiles, - required this.limitSelectionToOne, - super.key, - }); - - @override - Widget build(BuildContext context) { - const kRecycleLimit = 400; - final List childGalleries = []; - final subGalleryItemLimit = photoGridSize * subGalleryMultiplier; - - for (int index = 0; index < files.length; index += subGalleryItemLimit) { - childGalleries.add( - LazyGridView( - tag, - files.sublist( - index, - min(index + subGalleryItemLimit, files.length), - ), - asyncLoader, - selectedFiles, - index == 0, - files.length > kRecycleLimit, - photoGridSize, - limitSelectionToOne: limitSelectionToOne, - ), - ); - } - - return Column( - children: childGalleries, - ); - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart deleted file mode 100644 index 19ac9a0b7c..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart +++ /dev/null @@ -1,267 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:logging/logging.dart'; -import 'package:photos/core/constants.dart'; -import 'package:photos/events/files_updated_event.dart'; -import 'package:photos/models/file/file.dart'; -import 'package:photos/models/selected_files.dart'; -import 'package:photos/theme/ente_theme.dart'; -import "package:photos/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart"; -import "package:photos/ui/viewer/gallery/component/group/group_gallery.dart"; -import "package:photos/ui/viewer/gallery/component/group/group_header_widget.dart"; -import "package:photos/ui/viewer/gallery/component/group/type.dart"; -import 'package:photos/ui/viewer/gallery/gallery.dart'; -import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart"; - -class LazyGroupGallery extends StatefulWidget { - final List files; - final int index; - final Stream? reloadEvent; - final Set removalEventTypes; - final GalleryLoader asyncLoader; - final SelectedFiles? selectedFiles; - final String tag; - final String? logTag; - final Stream currentIndexStream; - final int photoGridSize; - final bool enableFileGrouping; - final bool limitSelectionToOne; - final bool showSelectAllByDefault; - const LazyGroupGallery( - this.files, - this.index, - this.reloadEvent, - this.removalEventTypes, - this.asyncLoader, - this.selectedFiles, - this.tag, - this.currentIndexStream, - this.enableFileGrouping, - this.showSelectAllByDefault, { - this.logTag = "", - this.photoGridSize = photoGridSizeDefault, - this.limitSelectionToOne = false, - super.key, - }); - - @override - State createState() => _LazyGroupGalleryState(); -} - -class _LazyGroupGalleryState extends State { - static const numberOfGroupsToRenderBeforeAndAfter = 8; - late final ValueNotifier _showSelectAllButtonNotifier; - late final ValueNotifier _areAllFromGroupSelectedNotifier; - - late Logger _logger; - - late List _filesInGroup; - late StreamSubscription? _reloadEventSubscription; - late StreamSubscription _currentIndexSubscription; - bool? _shouldRender; - - @override - void initState() { - super.initState(); - _areAllFromGroupSelectedNotifier = - ValueNotifier(_areAllFromGroupSelected()); - - widget.selectedFiles?.addListener(_selectedFilesListener); - _showSelectAllButtonNotifier = ValueNotifier(widget.showSelectAllByDefault); - _init(); - } - - void _init() { - _logger = Logger("LazyLoading_${widget.logTag}"); - _shouldRender = true; - _filesInGroup = widget.files; - _areAllFromGroupSelectedNotifier.value = _areAllFromGroupSelected(); - _reloadEventSubscription = widget.reloadEvent?.listen((e) => _onReload(e)); - - _currentIndexSubscription = - widget.currentIndexStream.listen((currentIndex) { - final bool shouldRender = (currentIndex - widget.index).abs() < - numberOfGroupsToRenderBeforeAndAfter; - if (mounted && shouldRender != _shouldRender) { - setState(() { - _shouldRender = shouldRender; - }); - } - }); - } - - bool _areAllFromGroupSelected() { - if (widget.selectedFiles != null && - widget.selectedFiles!.files.length >= widget.files.length) { - return widget.selectedFiles!.files.containsAll(widget.files); - } else { - return false; - } - } - - Future _onReload(FilesUpdatedEvent event) async { - if (_filesInGroup.isEmpty) { - return; - } - final galleryState = context.findAncestorStateOfType(); - final groupType = GalleryContextState.of(context)!.type; - - // iterate over files and check if any of the belongs to this group - final anyCandidateForGroup = groupType.areModifiedFilesPartOfGroup( - event.updatedFiles, - _filesInGroup[0], - lastFile: _filesInGroup.last, - ); - if (anyCandidateForGroup) { - late int startRange, endRange; - (startRange, endRange) = groupType.getGroupRange(_filesInGroup[0]); - if (kDebugMode) { - _logger.info( - " files were updated due to ${event.reason} on type ${groupType.name} from ${DateTime.fromMicrosecondsSinceEpoch(startRange).toIso8601String()}" - " to ${DateTime.fromMicrosecondsSinceEpoch(endRange).toIso8601String()}", - ); - } - if (event.type == EventType.addedOrUpdated || - widget.removalEventTypes.contains(event.type)) { - // We are reloading the whole group - final result = await widget.asyncLoader( - startRange, - endRange, - asc: GalleryContextState.of(context)!.sortOrderAsc, - ); - - //When items are updated in a LazyGroupGallery, only it rebuilds with the - //new state of _files which is a state variable in it's state object. - //widget.files is not updated. Calling setState from it's ancestor - //state object 'Gallery' creates a new LazyLoadingGallery widget with - //updated widget.files - - //If widget.files is kept in it's old state, the old state will come - //up when scrolled down and back up to the group. - - //[galleryState] will never be null except when LazyLoadingGallery is - //used without Gallery as an ancestor. - - if (galleryState?.mounted ?? false) { - galleryState!.setState(() {}); - _filesInGroup = result.files; - } - } else if (kDebugMode) { - debugPrint("Unexpected event ${event.type.name}"); - } - } - } - - @override - void dispose() { - _reloadEventSubscription?.cancel(); - _currentIndexSubscription.cancel(); - _areAllFromGroupSelectedNotifier.dispose(); - widget.selectedFiles?.removeListener(_selectedFilesListener); - super.dispose(); - } - - @override - void didUpdateWidget(LazyGroupGallery oldWidget) { - super.didUpdateWidget(oldWidget); - if (!listEquals(_filesInGroup, widget.files)) { - _reloadEventSubscription?.cancel(); - _init(); - } - } - - @override - Widget build(BuildContext context) { - if (_filesInGroup.isEmpty) { - return const SizedBox.shrink(); - } - final groupType = GalleryContextState.of(context)!.type; - return Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if (widget.enableFileGrouping) - GroupHeaderWidget( - title: groupType.getTitle( - context, - _filesInGroup[0], - lastFile: _filesInGroup.last, - ), - gridSize: widget.photoGridSize, - ), - Expanded(child: Container()), - widget.limitSelectionToOne - ? const SizedBox.shrink() - : ValueListenableBuilder( - valueListenable: _showSelectAllButtonNotifier, - builder: (context, dynamic value, _) { - return !value - ? const SizedBox.shrink() - : GestureDetector( - behavior: HitTestBehavior.translucent, - child: SizedBox( - width: 48, - height: 44, - child: ValueListenableBuilder( - valueListenable: - _areAllFromGroupSelectedNotifier, - builder: (context, dynamic value, _) { - return value - ? const Icon( - Icons.check_circle, - size: 18, - ) - : Icon( - Icons.check_circle_outlined, - color: getEnteColorScheme(context) - .strokeMuted, - size: 18, - ); - }, - ), - ), - onTap: () { - widget.selectedFiles?.toggleGroupSelection( - _filesInGroup.toSet(), - ); - }, - ); - }, - ), - ], - ), - _shouldRender! - ? GroupGallery( - photoGridSize: widget.photoGridSize, - files: _filesInGroup, - tag: widget.tag, - asyncLoader: widget.asyncLoader, - selectedFiles: widget.selectedFiles, - limitSelectionToOne: widget.limitSelectionToOne, - ) - // todo: perf eval should we have separate PlaceHolder for Groups - // instead of creating a large cached view - : PlaceHolderGridViewWidget( - _filesInGroup.length, - widget.photoGridSize, - ), - ], - ); - } - - void _selectedFilesListener() { - if (widget.selectedFiles == null) return; - _areAllFromGroupSelectedNotifier.value = - widget.selectedFiles!.files.containsAll(_filesInGroup.toSet()); - - //Can remove this if we decide to show select all by default for all galleries - if (widget.selectedFiles!.files.isEmpty && !widget.showSelectAllByDefault) { - _showSelectAllButtonNotifier.value = false; - } else { - _showSelectAllButtonNotifier.value = true; - } - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/component/multiple_groups_gallery_view.dart b/mobile/apps/photos/lib/ui/viewer/gallery/component/multiple_groups_gallery_view.dart deleted file mode 100644 index de38d22fda..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/gallery/component/multiple_groups_gallery_view.dart +++ /dev/null @@ -1,160 +0,0 @@ -import "package:flutter/material.dart"; -import "package:intl/intl.dart"; -import "package:logging/logging.dart"; -import "package:photos/core/event_bus.dart"; -import "package:photos/ente_theme_data.dart"; -import "package:photos/events/files_updated_event.dart"; -import 'package:photos/models/file/file.dart'; -import "package:photos/models/selected_files.dart"; -import "package:photos/service_locator.dart"; -import "package:photos/ui/common/loading_widget.dart"; -import "package:photos/ui/huge_listview/huge_listview.dart"; -import 'package:photos/ui/viewer/gallery/component/group/lazy_group_gallery.dart'; -import "package:photos/ui/viewer/gallery/component/group/type.dart"; -import "package:photos/ui/viewer/gallery/gallery.dart"; -import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart"; -import "package:photos/utils/standalone/data.dart"; -import "package:scrollable_positioned_list/scrollable_positioned_list.dart"; - -/* -MultipleGroupsGalleryView is a widget that displays a list of grouped/collated -files when grouping is enabled. -For each group, it displays a header and use LazyGroupGallery to display a -particular group of files. -If a group has more than 400 files, LazyGroupGallery internally divides the -group into multiple grid views during rendering. - */ -class MultipleGroupsGalleryView extends StatelessWidget { - final ItemScrollController itemScroller; - final List> groupedFiles; - final bool disableScroll; - final Widget? header; - final Widget? footer; - final Widget emptyState; - final GalleryLoader asyncLoader; - final Stream? reloadEvent; - final Set removalEventTypes; - final String tagPrefix; - final double scrollBottomSafeArea; - final bool limitSelectionToOne; - final SelectedFiles? selectedFiles; - final bool enableFileGrouping; - final String logTag; - final Logger logger; - final bool showSelectAllByDefault; - final bool isScrollablePositionedList; - - const MultipleGroupsGalleryView({ - required this.itemScroller, - required this.groupedFiles, - required this.disableScroll, - this.header, - this.footer, - required this.emptyState, - required this.asyncLoader, - this.reloadEvent, - required this.removalEventTypes, - required this.tagPrefix, - required this.scrollBottomSafeArea, - required this.limitSelectionToOne, - this.selectedFiles, - required this.enableFileGrouping, - required this.logTag, - required this.logger, - required this.showSelectAllByDefault, - required this.isScrollablePositionedList, - super.key, - }); - - @override - Widget build(BuildContext context) { - final gType = GalleryContextState.of(context)!.type; - return HugeListView>( - controller: itemScroller, - startIndex: 0, - totalCount: groupedFiles.length, - isDraggableScrollbarEnabled: groupedFiles.length > 10, - disableScroll: disableScroll, - isScrollablePositionedList: isScrollablePositionedList, - waitBuilder: (_) { - return const EnteLoadingWidget(); - }, - emptyResultBuilder: (_) { - final List children = []; - if (header != null) { - children.add(header!); - } - children.add( - Expanded( - child: emptyState, - ), - ); - if (footer != null) { - children.add(footer!); - } - return Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: children, - ); - }, - itemBuilder: (context, index) { - Widget gallery; - gallery = LazyGroupGallery( - groupedFiles[index], - index, - reloadEvent, - removalEventTypes, - asyncLoader, - selectedFiles, - tagPrefix, - Bus.instance - .on() - .where((event) => event.tag == tagPrefix) - .map((event) => event.index), - enableFileGrouping, - showSelectAllByDefault, - logTag: logTag, - photoGridSize: localSettings.getPhotoGridSize(), - limitSelectionToOne: limitSelectionToOne, - ); - if (header != null && index == 0) { - gallery = Column(children: [header!, gallery]); - } - if (footer != null && index == groupedFiles.length - 1) { - gallery = Column(children: [gallery, footer!]); - } - return gallery; - }, - labelTextBuilder: (int index) { - try { - final EnteFile file = groupedFiles[index][0]; - if (gType == GroupType.size) { - return file.fileSize != null - ? convertBytesToReadableFormat(file.fileSize!) - : ""; - } - - return DateFormat.yMMM(Localizations.localeOf(context).languageCode) - .format( - DateTime.fromMicrosecondsSinceEpoch( - file.creationTime!, - ), - ); - } catch (e) { - logger.severe("label text builder failed", e); - return ""; - } - }, - thumbBackgroundColor: - Theme.of(context).colorScheme.galleryThumbBackgroundColor, - thumbDrawColor: Theme.of(context).colorScheme.galleryThumbDrawColor, - thumbPadding: header != null - ? const EdgeInsets.only(top: 60) - : const EdgeInsets.all(0), - bottomSafeArea: scrollBottomSafeArea, - firstShown: (int firstIndex) { - Bus.instance.fire(GalleryIndexUpdatedEvent(tagPrefix, firstIndex)); - }, - ); - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/gallery/gallery.dart b/mobile/apps/photos/lib/ui/viewer/gallery/gallery.dart index 73f6566535..43d1e018f3 100644 --- a/mobile/apps/photos/lib/ui/viewer/gallery/gallery.dart +++ b/mobile/apps/photos/lib/ui/viewer/gallery/gallery.dart @@ -555,29 +555,6 @@ class GalleryState extends State { sortOrderAsc: _sortOrderAsc, inSelectionMode: widget.inSelectionMode, type: _groupType, - // Replace this with the new gallery and use `_allGalleryFiles` - // child: MultipleGroupsGalleryView( - // groupedFiles: currentGroupedFiles, - // disableScroll: widget.disableScroll, - // emptyState: widget.emptyState, - // asyncLoader: widget.asyncLoader, - // removalEventTypes: widget.removalEventTypes, - // tagPrefix: widget.tagPrefix, - // scrollBottomSafeArea: widget.scrollBottomSafeArea, - // limitSelectionToOne: widget.limitSelectionToOne, - // enableFileGrouping: - // widget.enableFileGrouping && widget.groupType.showGroupHeader(), - // logTag: _logTag, - // logger: _logger, - // reloadEvent: widget.reloadEvent, - // header: widget.header, - // footer: widget.footer, - // selectedFiles: widget.selectedFiles, - // showSelectAllByDefault: - // widget.showSelectAllByDefault && widget.groupType.showGroupHeader(), - // isScrollablePositionedList: widget.isScrollablePositionedList, - // ), - child: _allGalleryFiles.isEmpty ? Column( mainAxisAlignment: MainAxisAlignment.spaceBetween,