Make it so posts only load unless requested and add getting older posts

This commit is contained in:
Hank Grabowski 2022-11-22 09:54:10 -05:00
parent 9d8f914df0
commit 0c420593c5
7 changed files with 74 additions and 20 deletions

View file

@ -52,7 +52,10 @@ class _InteractionsBarControlState extends State<InteractionsBarControl> {
IconButton(
onPressed: () async => await toggleFavorited(),
icon: isFavorited
? Icon(Icons.thumb_up)
? Icon(
Icons.thumb_up,
semanticLabel: 'Like',
)
: Icon(Icons.thumb_up_outlined)),
],
);

View file

@ -85,16 +85,24 @@ class FriendicaClient {
FutureResult<List<TimelineEntry>, ExecError> getTimeline(
{required TimelineIdentifiers type,
int sinceId = 0,
int maxId = 0,
int limit = 20}) async {
final String timelinePath = _typeToTimelinePath(type);
final String timelineQPs = _typeToTimelineQueryParameters(type);
final baseUrl = 'https://$serverName/api/v1/timelines/$timelinePath';
final pagingData =
sinceId == 0 ? 'limit=$limit' : 'since_id=$sinceId&limit=$limit';
final url = '$baseUrl?$pagingData&$timelineQPs';
var pagingData = 'limit=$limit';
if (maxId > 0) {
pagingData = '$pagingData&max_id=$maxId';
}
if (sinceId > 0) {
pagingData = '&since_id=$sinceId';
}
final url = '$baseUrl?exclude_replies=true&$pagingData&$timelineQPs';
final request = Uri.parse(url);
_logger.finest(
() => 'Getting home timeline limit $limit since $sinceId : $url');
_logger.finest(() =>
'Getting home timeline limit $limit sinceId: $sinceId maxId: $maxId : $url');
return (await _getApiListRequest(request).andThenSuccessAsync(
(postsJson) async => postsJson
.map((json) => TimelineEntryMastodonExtensions.fromJson(json))

View file

@ -48,7 +48,8 @@ void main() async {
print('Startup login result: $result');
if (result.isSuccess) {
print('Getting timeline for ${result.value.credentials.handle}');
timelineManager.getTimeline(TimelineIdentifiers.home());
timelineManager.updateTimeline(
TimelineIdentifiers.home(), TimelineRefreshType.loadOlder);
}
} else {
print('Was not logged in');

View file

@ -10,6 +10,8 @@ class Timeline {
int get highestStatusId => _highestStatusId;
int get lowestStatusId => _lowestStatusId;
Timeline(this.id, {List<EntryTreeItem>? initialPosts}) {
if (initialPosts != null) {
addOrUpdate(initialPosts);
@ -42,7 +44,7 @@ class Timeline {
final parentId = comment.entry.parentId;
for (final p in _posts) {
final parent =
p.id == parentId ? p : p.getChildById(comment.entry.parentId);
p.id == parentId ? p : p.getChildById(comment.entry.parentId);
if (parent != null) {
parent.addOrUpdate(comment);
changed = true;
@ -62,7 +64,8 @@ class Timeline {
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Timeline && runtimeType == other.runtimeType && id == other.id;
other is Timeline && runtimeType == other.runtimeType &&
id == other.id;
@override
int get hashCode => id.hashCode;

View file

@ -76,15 +76,23 @@ class _HomeScreenState extends State<HomeScreen> {
print('items count = ${items.length}');
return RefreshIndicator(
onRefresh: () async {
await manager.refreshTimeline(TimelineIdentifiers.home(), true);
await manager.updateTimeline(
TimelineIdentifiers.home(), TimelineRefreshType.refresh);
},
child: ListView.separated(
itemBuilder: (context, index) {
if (index == 0) {
return ElevatedButton(
onPressed: () async => await manager.refreshTimeline(
TimelineIdentifiers.home(), false),
child: Text('Load newer posts'));
return TextButton(
onPressed: () async => await manager.updateTimeline(
TimelineIdentifiers.home(), TimelineRefreshType.loadNewer),
child: const Text('Load newer posts'));
}
if (index == items.length + 1) {
return TextButton(
onPressed: () async => await manager.updateTimeline(
TimelineIdentifiers.home(), TimelineRefreshType.loadOlder),
child: const Text('Load older posts'));
}
final itemIndex = index - 1;
final item = items[itemIndex];
@ -93,7 +101,7 @@ class _HomeScreenState extends State<HomeScreen> {
return StatusControl(originalItem: item);
},
separatorBuilder: (context, index) => Divider(),
itemCount: items.length + 1,
itemCount: items.length + 2,
),
);
}

View file

@ -22,7 +22,7 @@ class EntryManagerService extends ChangeNotifier {
}
FutureResult<List<EntryTreeItem>, ExecError> updateTimeline(
TimelineIdentifiers type, int highestId) async {
TimelineIdentifiers type, int maxId, int sinceId) async {
_logger.fine(() => 'Updating timeline');
final auth = getIt<AuthService>();
final clientResult = auth.currentClient;
@ -33,7 +33,7 @@ class EntryManagerService extends ChangeNotifier {
final client = clientResult.value;
final itemsResult =
await client.getTimeline(type: type, sinceId: highestId);
await client.getTimeline(type: type, maxId: maxId, sinceId: sinceId);
final myHandle = client.credentials.username;
if (itemsResult.isFailure) {
_logger.severe('Error getting timeline: ${itemsResult.error}');
@ -67,6 +67,10 @@ class EntryManagerService extends ChangeNotifier {
final orphans = <TimelineEntry>[];
for (final item in items) {
if (item.parentId.isEmpty) {
continue;
}
final parent = _entries[item.parentId];
if (parent == null) {
orphans.add(item);

View file

@ -9,6 +9,12 @@ import '../models/exec_error.dart';
import '../models/timeline.dart';
import 'entry_manager_service.dart';
enum TimelineRefreshType {
refresh,
loadOlder,
loadNewer,
}
class TimelineManager extends ChangeNotifier {
static final _logger = Logger('$TimelineManager');
@ -28,12 +34,13 @@ class TimelineManager extends ChangeNotifier {
return Result.ok(posts);
}
refreshTimeline(type, true);
updateTimeline(type, TimelineRefreshType.refresh);
return Result.ok([]);
}
FutureResult<EntryTreeItem, ExecError> refreshPost(String id) async {
_logger.finest('Refreshing post $id');
final result = await getIt<EntryManagerService>().refreshPost(id);
if (result.isSuccess) {
for (final t in cachedTimelines.values) {
@ -44,10 +51,30 @@ class TimelineManager extends ChangeNotifier {
return result;
}
Future<void> refreshTimeline(TimelineIdentifiers type, bool reload) async {
Future<void> updateTimeline(
TimelineIdentifiers type,
TimelineRefreshType refreshType,
) async {
_logger.finest('Updating w/$refreshType for timeline $type ');
final timeline = cachedTimelines.putIfAbsent(type, () => Timeline(type));
late final int lowestId;
late final int highestId;
switch (refreshType) {
case TimelineRefreshType.refresh:
lowestId = timeline.highestStatusId;
highestId = 0;
break;
case TimelineRefreshType.loadOlder:
lowestId = timeline.lowestStatusId;
highestId = 0;
break;
case TimelineRefreshType.loadNewer:
lowestId = 0;
highestId = timeline.highestStatusId;
break;
}
(await getIt<EntryManagerService>()
.updateTimeline(type, reload ? 0 : timeline.highestStatusId))
.updateTimeline(type, lowestId, highestId))
.match(onSuccess: (posts) {
_logger.finest('Posts returned for adding to $type: ${posts.length}');
timeline.addOrUpdate(posts);