Add updatePost to get all comments on post

codemagic-setup
Hank Grabowski 2022-11-18 18:31:28 -05:00
rodzic 1524cc217a
commit 37857a96d6
6 zmienionych plików z 102 dodań i 23 usunięć

Wyświetl plik

@ -1,6 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_portal/services/entry_manager_service.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:result_monad/result_monad.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../globals.dart';
@ -15,12 +17,24 @@ import '../../utils/snackbar_builder.dart';
import '../padding.dart';
import 'interactions_bar_control.dart';
class StatusControl extends StatelessWidget {
final EntryTreeItem item;
class StatusControl extends StatefulWidget {
final EntryTreeItem originalItem;
const StatusControl({super.key, required this.originalItem});
@override
State<StatusControl> createState() => _StatusControlState();
}
class _StatusControlState extends State<StatusControl> {
late EntryTreeItem item;
TimelineEntry get entry => item.entry;
const StatusControl({super.key, required this.item});
@override
void initState() {
super.initState();
item = widget.originalItem;
}
@override
Widget build(BuildContext context) {
@ -166,7 +180,7 @@ class StatusControl extends StatelessWidget {
}
Widget buildChildComments(BuildContext context) {
final comments = item.children;
final comments = widget.originalItem.children;
if (comments.isEmpty) {
return Text('No comments');
}
@ -176,10 +190,26 @@ class StatusControl extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (entry.parentId.isEmpty)
ElevatedButton(
onPressed: () async {
await getIt<EntryManagerService>()
.refreshPost(widget.originalItem)
.andThenSuccessAsync((newItem) async => setState(() {
print('Updated item');
item = newItem;
}));
},
child: Center(
child: Text('Load All'),
),
),
Icon(Icons.subdirectory_arrow_right),
Expanded(
child: Column(
children: comments.map((c) => StatusControl(item: c)).toList(),
children: comments
.map((c) => StatusControl(originalItem: c))
.toList(),
),
),
],

Wyświetl plik

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

Wyświetl plik

@ -8,6 +8,8 @@ class Timeline {
int _lowestStatusId = 0;
int _highestStatusId = 0;
int get highestStatusId => _highestStatusId;
Timeline(this.id, {List<EntryTreeItem>? initialPosts}) {
if (initialPosts != null) {
addPosts(initialPosts);

Wyświetl plik

@ -75,7 +75,7 @@ class _HomeScreenState extends State<HomeScreen> {
child: ListView.separated(
itemBuilder: (context, index) {
print('Building item: $index');
return StatusControl(item: items[index]);
return StatusControl(originalItem: items[index]);
},
separatorBuilder: (context, index) => Divider(),
itemCount: items.length,

Wyświetl plik

@ -17,7 +17,7 @@ class EntryManagerService extends ChangeNotifier {
final Map<String, EntryTreeItem> _allComments = {};
FutureResult<List<EntryTreeItem>, ExecError> updateTimeline(
TimelineIdentifiers type) async {
TimelineIdentifiers type, int highestId) async {
_logger.fine(() => 'Updating timeline');
final auth = getIt<AuthService>();
final clientResult = auth.currentClient;
@ -27,7 +27,8 @@ class EntryManagerService extends ChangeNotifier {
}
final client = clientResult.value;
final itemsResult = await client.getTimeline(type: type);
final itemsResult =
await client.getTimeline(type: type, sinceId: highestId);
final myHandle = client.credentials.username;
if (itemsResult.isFailure) {
_logger.severe('Error getting timeline: ${itemsResult.error}');
@ -50,21 +51,30 @@ class EntryManagerService extends ChangeNotifier {
FriendicaClient? client,
) async {
final updatedPosts = <EntryTreeItem>[];
for (final t in items) {
for (final item in items) {
late EntryTreeItem entry;
final isMine = t.author == myHandle;
if (t.parentAuthor.isEmpty) {
entry = _posts.putIfAbsent(
t.id, () => EntryTreeItem(t, isMine: isMine, isOrphaned: false));
final isMine = item.author == myHandle;
if (item.parentAuthor.isEmpty) {
entry = _posts.putIfAbsent(item.id,
() => EntryTreeItem(item, isMine: isMine, isOrphaned: false));
updatedPosts.add(entry);
} else {
final parent = _posts[t.parentId];
final parentPost = _posts[item.parentId];
bool newEntry = false;
entry = _allComments.putIfAbsent(t.id, () {
entry = _allComments.putIfAbsent(item.id, () {
newEntry = true;
return EntryTreeItem(t, isMine: isMine, isOrphaned: parent == null);
return EntryTreeItem(
item,
isMine: isMine,
isOrphaned: parentPost == null,
);
});
parent?.addChild(entry);
if (parentPost != null) {
parentPost.addChild(entry);
updatedPosts.add(parentPost);
}
if (newEntry && entry.isOrphaned) {
_orphanedComments.add(entry);
}
@ -77,6 +87,7 @@ class EntryManagerService extends ChangeNotifier {
if (post != null) {
c.isOrphaned = false;
post.addChild(c);
updatedPosts.add(post);
continue;
}
@ -105,6 +116,37 @@ class EntryManagerService extends ChangeNotifier {
return updatedPosts;
}
FutureResult<EntryTreeItem, ExecError> refreshPost(EntryTreeItem item) async {
_logger.finest('Refreshing post: ${item.id}');
final auth = getIt<AuthService>();
final clientResult = auth.currentClient;
if (clientResult.isFailure) {
_logger.severe('Error getting Friendica client: ${clientResult.error}');
return clientResult.errorCast();
}
final client = clientResult.value;
final result = await client
.getPostOrComment(item.id, fullContext: true)
.andThenSuccessAsync((items) async {
await processNewItems(items, client.credentials.username, null);
});
return result.mapValue((_) {
_logger.finest('${item.id} post updated');
notifyListeners();
return _posts[item.id]!;
}).mapError(
(error) {
_logger.finest('${item.id} error updating: $error');
return ExecError(
type: ErrorType.localError,
message: error.toString(),
);
},
);
}
FutureResult<EntryTreeItem, ExecError> toggleFavorited(
String id, bool newStatus,
{bool notify = false}) async {

Wyświetl plik

@ -27,9 +27,10 @@ class TimelineManager extends ChangeNotifier {
}
Future<void> refreshTimeline(TimelineIdentifiers type) async {
(await getIt<EntryManagerService>().updateTimeline(type)).match(
onSuccess: (posts) {
final timeline = cachedTimelines.putIfAbsent(type, () => Timeline(type));
final timeline = cachedTimelines.putIfAbsent(type, () => Timeline(type));
(await getIt<EntryManagerService>()
.updateTimeline(type, timeline.highestStatusId))
.match(onSuccess: (posts) {
_logger.finest('Posts returned for adding to $type: ${posts.length}');
timeline.addPosts(posts);
notifyListeners();