mirror of
https://gitlab.com/mysocialportal/relatica
synced 2024-10-19 18:43:32 +00:00
221 lines
7 KiB
Dart
221 lines
7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:logging/logging.dart';
|
|
import 'package:relatica/models/exec_error.dart';
|
|
import 'package:relatica/services/auth_service.dart';
|
|
import 'package:result_monad/result_monad.dart';
|
|
|
|
import '../../globals.dart';
|
|
import '../../models/timeline_entry.dart';
|
|
import '../../services/feature_version_checker.dart';
|
|
import '../../services/fediverse_server_validator.dart';
|
|
import '../../services/timeline_manager.dart';
|
|
import '../../utils/active_profile_selector.dart';
|
|
import '../../utils/snackbar_builder.dart';
|
|
|
|
class InteractionsBarControl extends StatefulWidget {
|
|
final TimelineEntry entry;
|
|
final bool showOpenControl;
|
|
final bool isMine;
|
|
|
|
const InteractionsBarControl({
|
|
super.key,
|
|
required this.entry,
|
|
required this.isMine,
|
|
required this.showOpenControl,
|
|
});
|
|
|
|
@override
|
|
State<InteractionsBarControl> createState() => _InteractionsBarControlState();
|
|
}
|
|
|
|
class _InteractionsBarControlState extends State<InteractionsBarControl> {
|
|
static final _logger = Logger('$InteractionsBarControl');
|
|
|
|
var isProcessing = false;
|
|
|
|
bool get isPost => widget.entry.parentId.isEmpty;
|
|
|
|
bool get isFavorited => widget.entry.isFavorited;
|
|
|
|
bool get youReshared => widget.entry.youReshared;
|
|
|
|
int get reshares => widget.entry.engagementSummary.rebloggedCount;
|
|
|
|
int get comments => widget.entry.engagementSummary.repliesCount;
|
|
|
|
int get likes => widget.entry.engagementSummary.favoritesCount;
|
|
|
|
Future<void> toggleFavorited() async {
|
|
setState(() {
|
|
isProcessing = true;
|
|
});
|
|
final newState = !isFavorited;
|
|
_logger.finest('Trying to toggle favorite from $isFavorited to $newState');
|
|
final result = await getIt<ActiveProfileSelector<TimelineManager>>()
|
|
.activeEntry
|
|
.andThenAsync(
|
|
(tm) async => await tm.toggleFavorited(widget.entry.id, newState));
|
|
result.match(onSuccess: (update) {
|
|
setState(() {
|
|
_logger.finest(
|
|
'Success toggling! $isFavorited -> ${update.entry.isFavorited}');
|
|
});
|
|
}, onError: (error) {
|
|
buildSnackbar(context, 'Error toggling like status: $error');
|
|
});
|
|
setState(() {
|
|
isProcessing = false;
|
|
});
|
|
}
|
|
|
|
Future<void> resharePost() async {
|
|
setState(() {
|
|
isProcessing = true;
|
|
});
|
|
|
|
final fvc = getIt<FriendicaVersionChecker>();
|
|
if (!fvc.canUseFeature(RelaticaFeatures.diasporaReshare)) {
|
|
final serverTypeEstimate = await getIt<FediverseServiceValidator>()
|
|
.getServerData(widget.entry.externalLink)
|
|
.fold(onSuccess: (d) => d.softwareName, onError: (_) => '');
|
|
if (serverTypeEstimate ==
|
|
FediverseServiceValidator.softwareTypeDiaspora) {
|
|
if (mounted) {
|
|
final error =
|
|
fvc.versionErrorString(RelaticaFeatures.diasporaReshare);
|
|
await showConfirmDialog(context, error);
|
|
}
|
|
setState(() {
|
|
isProcessing = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
final id = widget.entry.id;
|
|
_logger.finest('Trying to reshare $id');
|
|
final result = await getIt<ActiveProfileSelector<TimelineManager>>()
|
|
.activeEntry
|
|
.andThenAsync((tm) async => await tm.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}');
|
|
logError(error, _logger);
|
|
});
|
|
setState(() {
|
|
isProcessing = false;
|
|
});
|
|
}
|
|
|
|
Future<void> addComment() async {
|
|
final needingReshareIdFix = getIt<FriendicaVersionChecker>()
|
|
.canUseFeature(RelaticaFeatures.reshareIdFix);
|
|
final myId = getIt<AccountsService>().currentProfile.userId;
|
|
|
|
if (needingReshareIdFix &&
|
|
widget.entry.reshareOriginalPostId.isNotEmpty &&
|
|
widget.entry.reshareAuthorId != myId) {
|
|
await showConfirmDialog(context,
|
|
'Unable to comment on reshared posts with your current version of Friendica server.');
|
|
return;
|
|
}
|
|
|
|
if (mounted) {
|
|
context.push('/comment/new?parent_id=${widget.entry.id}');
|
|
}
|
|
}
|
|
|
|
Future<void> unResharePost() async {
|
|
setState(() {
|
|
isProcessing = true;
|
|
});
|
|
final id = widget.entry.id;
|
|
_logger.finest('Trying to un-reshare $id');
|
|
final result = await getIt<ActiveProfileSelector<TimelineManager>>()
|
|
.activeEntry
|
|
.andThenAsync((tm) async => await tm.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}');
|
|
logError(error, _logger);
|
|
});
|
|
setState(() {
|
|
isProcessing = false;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
_logger.finest('Building: ${widget.entry.toShortString()}');
|
|
return Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
TextButton(
|
|
onPressed: likes == 0
|
|
? null
|
|
: () {
|
|
context.push('/likes/${widget.entry.id}');
|
|
},
|
|
child: Text('$likes Likes'),
|
|
),
|
|
TextButton(
|
|
onPressed: reshares == 0
|
|
? null
|
|
: () {
|
|
context.push('/reshares/${widget.entry.id}');
|
|
},
|
|
child: Text('$reshares Reshares'),
|
|
),
|
|
widget.showOpenControl
|
|
? TextButton(
|
|
onPressed: comments == 0
|
|
? null
|
|
: () {
|
|
context.push(
|
|
'/post/view/${widget.entry.id}/${widget.entry.id}');
|
|
},
|
|
child: Text('$comments Comments'),
|
|
)
|
|
: Text('$comments Comments'),
|
|
],
|
|
),
|
|
Row(children: [
|
|
IconButton(
|
|
onPressed:
|
|
isProcessing ? null : () async => await toggleFavorited(),
|
|
icon: isFavorited
|
|
? const Icon(
|
|
Icons.thumb_up,
|
|
semanticLabel: 'Like',
|
|
)
|
|
: Icon(Icons.thumb_up_outlined)),
|
|
if (isPost)
|
|
IconButton(
|
|
onPressed: widget.isMine && !widget.entry.youReshared
|
|
? null
|
|
: isProcessing
|
|
? null
|
|
: () async => youReshared
|
|
? await unResharePost()
|
|
: await resharePost(),
|
|
icon: Icon(
|
|
youReshared ? Icons.repeat_on_outlined : Icons.repeat)),
|
|
IconButton(
|
|
onPressed: isProcessing ? null : addComment,
|
|
icon: Icon(Icons.add_comment)),
|
|
]),
|
|
],
|
|
);
|
|
}
|
|
}
|