Skip to content

Commit

Permalink
feat: improved list reload behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasn committed May 5, 2024
1 parent 33e80ba commit c8a1720
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 93 deletions.
57 changes: 18 additions & 39 deletions lib/blocs/journal/journal_page_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import 'dart:async';
import 'dart:convert';

import 'package:bloc/bloc.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:lotti/blocs/journal/journal_page_state.dart';
import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/database/database.dart';
import 'package:lotti/database/fts5_db.dart';
import 'package:lotti/database/settings_db.dart';
Expand All @@ -29,7 +29,10 @@ class JournalPageCubit extends Cubit<JournalPageState> {
fullTextMatches: {},
showTasks: showTasks,
taskAsListView: true,
pagingController: PagingController<int, String>(firstPageKey: 0),
pagingController: PagingController<int, JournalEntity>(
firstPageKey: 0,
invisibleItemsThreshold: 10,
),
taskStatuses: [
'OPEN',
'GROOMED',
Expand Down Expand Up @@ -90,9 +93,15 @@ class JournalPageCubit extends Cubit<JournalPageState> {
leading: false,
trailing: true,
)
.listen((_) {
.listen((event) {
if (_isVisible) {
refreshQuery();
final displayedIds =
state.pagingController.itemList?.map((e) => e.meta.id).toSet() ??
{};

if (displayedIds.contains(event.id)) {
refreshQuery();
}
}
});
}
Expand All @@ -113,8 +122,6 @@ class JournalPageCubit extends Cubit<JournalPageState> {
bool taskAsListView = true;

Set<String> _fullTextMatches = {};
Set<String> _lastIds = {};

Set<String> _selectedTaskStatuses = {
'OPEN',
'GROOMED',
Expand Down Expand Up @@ -238,13 +245,8 @@ class JournalPageCubit extends Cubit<JournalPageState> {
}

Future<void> refreshQuery() async {
final newIds = (await _runQuery(0)).toSet();
if (!setEquals(_lastIds, newIds)) {
_lastIds = newIds;

emitState();
state.pagingController.refresh();
}
emitState();
state.pagingController.refresh();
}

void updateVisibility(VisibilityInfo visibilityInfo) {
Expand Down Expand Up @@ -276,7 +278,7 @@ class JournalPageCubit extends Cubit<JournalPageState> {
}
}

Future<List<String>> _runQuery(int pageKey) async {
Future<List<JournalEntity>> _runQuery(int pageKey) async {
final types = state.selectedEntryTypes.toList();
await _fts5Search();
final fullTextMatches = _fullTextMatches.toList();
Expand All @@ -290,14 +292,14 @@ class JournalPageCubit extends Cubit<JournalPageState> {
_filters.contains(DisplayFilter.flaggedEntriesOnly);

return showTasks
? await _db.getTasksIds(
? await _db.getTasks(
ids: ids,
starredStatuses: starredEntriesOnly ? [true] : [true, false],
taskStatuses: _selectedTaskStatuses.toList(),
limit: _pageSize,
offset: pageKey,
)
: await _db.getJournalEntityIds(
: await _db.getJournalEntities(
types: types,
ids: ids,
starredStatuses: starredEntriesOnly ? [true] : [true, false],
Expand Down Expand Up @@ -326,26 +328,3 @@ final List<String> entryTypes = [
'HabitCompletionEntry',
'QuantitativeEntry',
];

// This function returns a stateful stream filter
// function that compares the previous event on
// the stream with the latest, and filters those
// that are found equal using deep collection
// equality. This allows exactly once deliver on
// a stream instead of at least once previously,
// which lead to plenty of costly re-renders.
bool Function(T next) makeDuplicateFilter<T>() {
final deepEq = const DeepCollectionEquality().equals;
T? prev;

bool duplicateFilter(T next) {
if (deepEq(prev, next)) {
return false;
} else {
prev = next;
return true;
}
}

return duplicateFilter;
}
3 changes: 2 additions & 1 deletion lib/blocs/journal/journal_page_state.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:lotti/classes/journal_entities.dart';

part 'journal_page_state.freezed.dart';

Expand All @@ -20,7 +21,7 @@ class JournalPageState with _$JournalPageState {
required bool taskAsListView,
required List<String> selectedEntryTypes,
required Set<String> fullTextMatches,
required PagingController<int, String> pagingController,
required PagingController<int, JournalEntity> pagingController,
required List<String> taskStatuses,
required Set<String> selectedTaskStatuses,
}) = _JournalPageState;
Expand Down
16 changes: 8 additions & 8 deletions lib/blocs/journal/journal_page_state.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mixin _$JournalPageState {
bool get taskAsListView => throw _privateConstructorUsedError;
List<String> get selectedEntryTypes => throw _privateConstructorUsedError;
Set<String> get fullTextMatches => throw _privateConstructorUsedError;
PagingController<int, String> get pagingController =>
PagingController<int, JournalEntity> get pagingController =>
throw _privateConstructorUsedError;
List<String> get taskStatuses => throw _privateConstructorUsedError;
Set<String> get selectedTaskStatuses => throw _privateConstructorUsedError;
Expand All @@ -49,7 +49,7 @@ abstract class $JournalPageStateCopyWith<$Res> {
bool taskAsListView,
List<String> selectedEntryTypes,
Set<String> fullTextMatches,
PagingController<int, String> pagingController,
PagingController<int, JournalEntity> pagingController,
List<String> taskStatuses,
Set<String> selectedTaskStatuses});
}
Expand Down Expand Up @@ -115,7 +115,7 @@ class _$JournalPageStateCopyWithImpl<$Res, $Val extends JournalPageState>
pagingController: null == pagingController
? _value.pagingController
: pagingController // ignore: cast_nullable_to_non_nullable
as PagingController<int, String>,
as PagingController<int, JournalEntity>,
taskStatuses: null == taskStatuses
? _value.taskStatuses
: taskStatuses // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -145,7 +145,7 @@ abstract class _$$JournalPageStateImplCopyWith<$Res>
bool taskAsListView,
List<String> selectedEntryTypes,
Set<String> fullTextMatches,
PagingController<int, String> pagingController,
PagingController<int, JournalEntity> pagingController,
List<String> taskStatuses,
Set<String> selectedTaskStatuses});
}
Expand Down Expand Up @@ -209,7 +209,7 @@ class __$$JournalPageStateImplCopyWithImpl<$Res>
pagingController: null == pagingController
? _value.pagingController
: pagingController // ignore: cast_nullable_to_non_nullable
as PagingController<int, String>,
as PagingController<int, JournalEntity>,
taskStatuses: null == taskStatuses
? _value._taskStatuses
: taskStatuses // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -286,7 +286,7 @@ class _$JournalPageStateImpl implements _JournalPageState {
}

@override
final PagingController<int, String> pagingController;
final PagingController<int, JournalEntity> pagingController;
final List<String> _taskStatuses;
@override
List<String> get taskStatuses {
Expand Down Expand Up @@ -368,7 +368,7 @@ abstract class _JournalPageState implements JournalPageState {
required final bool taskAsListView,
required final List<String> selectedEntryTypes,
required final Set<String> fullTextMatches,
required final PagingController<int, String> pagingController,
required final PagingController<int, JournalEntity> pagingController,
required final List<String> taskStatuses,
required final Set<String> selectedTaskStatuses}) =
_$JournalPageStateImpl;
Expand All @@ -390,7 +390,7 @@ abstract class _JournalPageState implements JournalPageState {
@override
Set<String> get fullTextMatches;
@override
PagingController<int, String> get pagingController;
PagingController<int, JournalEntity> get pagingController;
@override
List<String> get taskStatuses;
@override
Expand Down
18 changes: 18 additions & 0 deletions lib/database/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,24 @@ class JournalDb extends _$JournalDb {
).watch().map(entityStreamMapper);
}

Future<List<JournalEntity>> getTasks({
required List<bool> starredStatuses,
required List<String> taskStatuses,
List<String>? ids,
int limit = 500,
int offset = 0,
}) async {
final res = await _selectTasks(
starredStatuses: starredStatuses,
taskStatuses: taskStatuses,
ids: ids,
limit: limit,
offset: offset,
).get();

return res.map(fromDbEntity).toList();
}

Future<List<String>> getTasksIds({
required List<bool> starredStatuses,
required List<String> taskStatuses,
Expand Down
12 changes: 7 additions & 5 deletions lib/pages/journal/infinite_journal_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:lotti/blocs/journal/journal_page_cubit.dart';
import 'package:lotti/blocs/journal/journal_page_state.dart';
import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/get_it.dart';
import 'package:lotti/l10n/app_localizations_context.dart';
import 'package:lotti/logic/create/create_entry.dart';
Expand Down Expand Up @@ -77,14 +78,15 @@ class InfiniteJournalPageBody extends StatelessWidget {
child: CustomScrollView(
slivers: <Widget>[
const JournalSliverAppBar(),
PagedSliverList<int, String>(
PagedSliverList<int, JournalEntity>(
pagingController: snapshot.pagingController,
builderDelegate: PagedChildBuilderDelegate<String>(
itemBuilder: (context, id, index) {
builderDelegate: PagedChildBuilderDelegate<JournalEntity>(
animateTransitions: true,
itemBuilder: (context, item, index) {
return EntryWrapperWidget(
id: id,
item: item,
taskAsListView: snapshot.taskAsListView,
key: ValueKey(id),
key: ValueKey(item.meta.id),
);
},
),
Expand Down
30 changes: 27 additions & 3 deletions lib/widgets/journal/journal_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,34 @@ class TaskListCard extends StatelessWidget {
}
}

class EntryWrapperWidget extends ConsumerWidget {
class EntryWrapperWidget extends StatelessWidget {
const EntryWrapperWidget({
required this.item,
required this.taskAsListView,
super.key,
});

final JournalEntity item;
final bool taskAsListView;

@override
Widget build(BuildContext context) {
return item.maybeMap(
journalImage: (JournalImage image) => JournalImageCard(item: image),
task: (Task task) {
if (taskAsListView) {
return TaskListCard(task: task);
} else {
return JournalCard(item: task);
}
},
orElse: () => JournalCard(item: item),
);
}
}

class EntryWrapperConsumerWidget extends ConsumerWidget {
const EntryWrapperConsumerWidget({
required this.id,
required this.taskAsListView,
super.key,
Expand All @@ -343,8 +369,6 @@ class EntryWrapperWidget extends ConsumerWidget {
final String id;
final bool taskAsListView;

void onTap() => beamToNamed('/tasks/$id');

@override
Widget build(
BuildContext context,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: lotti
description: Achieve your goals and keep your data private with Lotti.
publish_to: 'none'
version: 0.9.459+2503
version: 0.9.459+2504

msix_config:
display_name: LottiApp
Expand Down
Loading

0 comments on commit c8a1720

Please sign in to comment.