store group creation action

This commit is contained in:
otsmr 2025-11-02 14:29:09 +01:00
parent 8cf57224ce
commit d616e08dec
4 changed files with 40 additions and 14 deletions

View file

@ -30,6 +30,7 @@ import 'package:twonly/src/services/api/server_messages.dart';
import 'package:twonly/src/services/api/utils.dart';
import 'package:twonly/src/services/fcm.service.dart';
import 'package:twonly/src/services/flame.service.dart';
import 'package:twonly/src/services/group.services.dart';
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
import 'package:twonly/src/services/signal/identity.signal.dart';
import 'package:twonly/src/services/signal/prekeys.signal.dart';
@ -99,6 +100,7 @@ class ApiService {
unawaited(syncFlameCounters());
unawaited(setupNotificationWithUsers());
unawaited(signalHandleNewServerConnection());
unawaited(fetchGroupStatesForUnjoinedGroups());
}
}

View file

@ -14,6 +14,17 @@ Future<void> handleGroupCreate(
String groupId,
EncryptedContent_GroupCreate newGroup,
) async {
final user = await twonlyDB.contactsDao
.getContactByUserId(fromUserId)
.getSingleOrNull();
if (user == null) {
// Only contacts can invite other contacts, so this can (via the UI) not happen.
Log.error(
'User is not a contact. Aborting.',
);
return;
}
// 1. Store the new group -> e.g. store the stateKey and groupPublicKey
// 2. Call function that should fetch all jobs
// 1. This function is also called in the main function, in case the state stored on the server could not be loaded
@ -41,16 +52,14 @@ Future<void> handleGroupCreate(
return;
}
final user = await twonlyDB.contactsDao
.getContactByUserId(fromUserId)
.getSingleOrNull();
if (user == null) {
// Only contacts can invite other contacts, so this can (via the UI) not happen.
Log.error(
'User is not a contact. Aborting.',
);
return;
}
await twonlyDB.groupsDao.insertGroupAction(
GroupHistoriesCompanion(
groupId: Value(groupId),
contactId: Value(fromUserId),
affectedContactId: const Value(null),
type: const Value(GroupActionType.addMember),
),
);
await twonlyDB.groupsDao.insertGroupMember(
GroupMembersCompanion(

View file

@ -381,7 +381,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
}).toList(),
);
} else if (messages[i].isGroupAction) {
return ChatGroupAction(action: messages[i].groupAction!);
return ChatGroupAction(
key: Key(messages[i].groupAction!.groupHistoryId),
action: messages[i].groupAction!,
);
} else {
final chatMessage = messages[i].message!;
return Transform.translate(

View file

@ -44,6 +44,7 @@ class _ChatGroupActionState extends State<ChatGroupAction> {
@override
Widget build(BuildContext context) {
var text = '';
IconData? icon;
final affected = (affectedContact == null)
? 'you'
@ -56,22 +57,33 @@ class _ChatGroupActionState extends State<ChatGroupAction> {
text = (contact == null)
? 'You have changed the group name to "${widget.action.newGroupName}".'
: '$maker has changed the group name to "${widget.action.newGroupName}".';
icon = FontAwesomeIcons.pencil;
case GroupActionType.createdGroup:
icon = FontAwesomeIcons.penToSquare;
text = (contact == null)
? 'You have created the group.'
: '$maker has created the group.';
case GroupActionType.removedMember:
case GroupActionType.addMember:
icon = FontAwesomeIcons.userPlus;
text = (contact == null)
? 'You have added $affected to the group.'
: '$maker has added $affected to the group.';
case GroupActionType.leftGroup:
break;
case GroupActionType.promoteToAdmin:
icon = FontAwesomeIcons.key;
text = (contact == null)
? 'You made $affected an admin.'
: '$maker made $affected an admin.';
case GroupActionType.demoteToMember:
icon = FontAwesomeIcons.key;
text = (contact == null)
? 'You revoked $affected admin rights.'
: '$maker revoked $affectedR admin rights.';
}
if (text == '') return Container();
if (text == '' || icon == null) return Container();
return Padding(
padding: const EdgeInsets.all(8),
@ -80,10 +92,10 @@ class _ChatGroupActionState extends State<ChatGroupAction> {
textAlign: TextAlign.center,
text: TextSpan(
children: [
const WidgetSpan(
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: FaIcon(
FontAwesomeIcons.pencil,
icon,
size: 10,
color: Colors.grey,
),