Add resharing of posts (only posts RN)

merge-requests/67/merge
Hank Grabowski 2022-11-22 11:43:16 -05:00
rodzic 0c420593c5
commit 5f1e8809e1
5 zmienionych plików z 176 dodań i 12 usunięć

Wyświetl plik

@ -18,8 +18,12 @@ class InteractionsBarControl extends StatefulWidget {
class _InteractionsBarControlState extends State<InteractionsBarControl> {
static final _logger = Logger('$InteractionsBarControl');
bool get isPost => widget.entry.parentId.isEmpty;
bool get isFavorited => widget.entry.isFavorited;
bool get isReshared => widget.entry.isReshare;
int get reshares => widget.entry.engagementSummary.rebloggedCount;
int get comments => widget.entry.engagementSummary.repliesCount;
@ -41,6 +45,33 @@ class _InteractionsBarControlState extends State<InteractionsBarControl> {
});
}
Future<void> resharePost() async {
final id = widget.entry.id;
_logger.finest('Trying to reshare $id');
final result = await getIt<TimelineManager>().resharePost(id);
result.match(onSuccess: (update) {
setState(() {
_logger.finest('Success resharing post by ${widget.entry.author}');
});
}, onError: (error) {
buildSnackbar(context, 'Error resharing post by ${widget.entry.author}');
});
}
Future<void> unResharePost() async {
final id = widget.entry.id;
_logger.finest('Trying to un-reshare $id');
final result = await getIt<TimelineManager>().unResharePost(id);
result.match(onSuccess: (update) {
setState(() {
_logger.finest('Success un-resharing post by ${widget.entry.author}');
});
}, onError: (error) {
buildSnackbar(
context, 'Error un-resharing post by ${widget.entry.author}');
});
}
@override
Widget build(BuildContext context) {
_logger.finest('Building: ${widget.entry.toShortString()}');
@ -49,14 +80,22 @@ class _InteractionsBarControlState extends State<InteractionsBarControl> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('$likes likes, $reshares reshares, $comments comments'),
IconButton(
onPressed: () async => await toggleFavorited(),
icon: isFavorited
? Icon(
Icons.thumb_up,
semanticLabel: 'Like',
)
: Icon(Icons.thumb_up_outlined)),
Row(children: [
IconButton(
onPressed: () async => await toggleFavorited(),
icon: isFavorited
? const Icon(
Icons.thumb_up,
semanticLabel: 'Like',
)
: Icon(Icons.thumb_up_outlined)),
if (isPost)
IconButton(
onPressed: () async =>
isReshared ? await unResharePost() : await resharePost(),
icon:
Icon(isReshared ? Icons.repeat_on_outlined : Icons.repeat))
]),
],
);
}

Wyświetl plik

@ -34,6 +34,10 @@ class _StatusControlState extends State<StatusControl> {
TimelineEntry get entry => item.entry;
bool get isPost => item.entry.parentId.isEmpty;
bool get hasComments => entry.engagementSummary.repliesCount > 0;
@override
Widget build(BuildContext context) {
final manager = context.watch<TimelineManager>();
@ -60,8 +64,7 @@ class _StatusControlState extends State<StatusControl> {
const VerticalPadding(
height: 5,
),
if (entry.parentId.isEmpty &&
entry.engagementSummary.repliesCount > 0)
if (isPost && hasComments)
TextButton(
onPressed: () async => await manager.refreshPost(item.id),
child: Text('Load Comments'),
@ -91,11 +94,17 @@ class _StatusControlState extends State<StatusControl> {
children: [
Text(
author.name,
style: Theme.of(context).textTheme.bodyText1,
style: Theme
.of(context)
.textTheme
.bodyText1,
),
Text(
ElapsedDateUtils.epochSecondsToString(entry.backdatedTimestamp),
style: Theme.of(context).textTheme.caption,
style: Theme
.of(context)
.textTheme
.caption,
),
// Text(
// item.id,

Wyświetl plik

@ -160,6 +160,42 @@ class FriendicaClient {
});
}
FutureResult<TimelineEntry, ExecError> resharePost(String id) async {
_logger.finest(() => 'Reshare post $id');
final url = Uri.parse('https://$serverName/api/v1/statuses/$id/reblog');
final result = await _postUrl(url, {});
if (result.isFailure) {
return result.errorCast();
}
final responseText = result.value;
return runCatching<TimelineEntry>(() {
final json = jsonDecode(responseText);
return Result.ok(TimelineEntryMastodonExtensions.fromJson(json));
}).mapError((error) {
return ExecError(type: ErrorType.parsingError, message: error.toString());
});
}
FutureResult<TimelineEntry, ExecError> unResharePost(String id) async {
_logger.finest(() => 'Reshare post $id');
final url = Uri.parse('https://$serverName/api/v1/statuses/$id/unreblog');
final result = await _postUrl(url, {});
if (result.isFailure) {
return result.errorCast();
}
final responseText = result.value;
return runCatching<TimelineEntry>(() {
final json = jsonDecode(responseText);
return Result.ok(TimelineEntryMastodonExtensions.fromJson(json));
}).mapError((error) {
return ExecError(type: ErrorType.parsingError, message: error.toString());
});
}
FutureResult<TimelineEntry, ExecError> changeFavoriteStatus(
String id, bool status) async {
final action = status ? 'favourite' : 'unfavourite';

Wyświetl plik

@ -158,6 +158,64 @@ class EntryManagerService extends ChangeNotifier {
);
}
FutureResult<EntryTreeItem, ExecError> resharePost(String id) async {
_logger.finest('Resharing post: $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.resharePost(id).andThenSuccessAsync((item) async {
await processNewItems([item], client.credentials.username, null);
});
return result.mapValue((_) {
_logger.finest('$id post updated after reshare');
return _nodeToTreeItem(_postNodes[id]!);
}).mapError(
(error) {
_logger.finest('$id error updating: $error');
return ExecError(
type: ErrorType.localError,
message: error.toString(),
);
},
);
}
FutureResult<EntryTreeItem, ExecError> unResharePost(String id) async {
_logger.finest('Unresharing post: $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.unResharePost(id).andThenSuccessAsync((item) async {
await processNewItems([item], client.credentials.username, null);
});
return result.mapValue((_) {
_logger.finest('$id post updated after unreshare');
return _nodeToTreeItem(_postNodes[id]!);
}).mapError(
(error) {
_logger.finest('$id error updating: $error');
return ExecError(
type: ErrorType.localError,
message: error.toString(),
);
},
);
}
FutureResult<EntryTreeItem, ExecError> toggleFavorited(
String id, bool newStatus) async {
final auth = getIt<AuthService>();

Wyświetl plik

@ -51,6 +51,28 @@ class TimelineManager extends ChangeNotifier {
return result;
}
FutureResult<EntryTreeItem, ExecError> resharePost(String id) async {
final result = await getIt<EntryManagerService>().resharePost(id);
if (result.isSuccess) {
for (final t in cachedTimelines.values) {
t.addOrUpdate([result.value]);
}
notifyListeners();
}
return result;
}
FutureResult<EntryTreeItem, ExecError> unResharePost(String id) async {
final result = await getIt<EntryManagerService>().unResharePost(id);
if (result.isSuccess) {
for (final t in cachedTimelines.values) {
t.addOrUpdate([result.value]);
}
notifyListeners();
}
return result;
}
Future<void> updateTimeline(
TimelineIdentifiers type,
TimelineRefreshType refreshType,