xmpp: RECEIVE MESSAGES!

This commit is contained in:
2022-01-01 21:24:27 +01:00
parent f22d042255
commit 1acc2630b4
17 changed files with 250 additions and 113 deletions

View File

@@ -1,3 +1,6 @@
import "package:moxxyv2/models/message.dart";
import "package:moxxyv2/xmpp/jid.dart";
class SetShowSendButtonAction {
final bool show;
@@ -20,6 +23,21 @@ class SendMessageAction {
SendMessageAction({ required this.from, required this.body, required this.timestamp, required this.jid, required this.cid });
}
class ReceiveMessageAction {
final String body;
final int timestamp;
final FullJID from;
final String jid;
ReceiveMessageAction({ required this.from, required this.body, required this.timestamp, required this.jid });
}
class AddMessageAction {
final Message message;
AddMessageAction({ required this.message });
}
class CloseConversationAction {
final String jid;
final int id;

View File

@@ -5,24 +5,14 @@ import "package:moxxyv2/redux/conversation/state.dart";
import "package:moxxyv2/redux/conversation/actions.dart";
HashMap<String, List<Message>> messageReducer(HashMap<String, List<Message>> state, dynamic action) {
if (action is SendMessageAction) {
HashMap<String, List<Message>> map = HashMap<String, List<Message>>()..addAll(state);
Message msg = Message(
from: action.from,
body: action.body,
timestamp: action.timestamp,
sent: true
);
String jid = action.jid;
if (!map.containsKey(jid)) {
map[jid] = [ msg ];
return map;
if (action is AddMessageAction) {
if (!state.containsKey(action.message.from)) {
state[action.message.from] = List.from([ action.message ]);
} else {
state[action.message.from] = state[action.message.from]!..add(action.message);
}
map[jid]!.add(msg);
return map;
return state;
}
return state;

View File

@@ -1,16 +1,13 @@
import "dart:collection";
import "package:moxxyv2/models/conversation.dart";
class AddConversationAction {
final String title;
final String lastMessageBody;
final String avatarUrl;
final String jid;
final int id;
final int unreadCounter;
final List<String> sharedMediaPaths;
final int lastChangeTimestamp;
final bool triggeredByDatabase;
final bool open;
Conversation conversation;
AddConversationAction({ required this.title, required this.lastMessageBody, required this.avatarUrl, required this.jid, required this.sharedMediaPaths, required this.lastChangeTimestamp, required this.id, this.unreadCounter = 0, this.triggeredByDatabase = false, required this.open });
AddConversationAction({ required this.conversation });
}
class UpdateConversationAction {
Conversation conversation;
UpdateConversationAction({ required this.conversation });
}

View File

@@ -2,29 +2,13 @@ import "package:moxxyv2/redux/state.dart";
import "package:moxxyv2/redux/conversations/actions.dart";
import "package:moxxyv2/redux/conversation/actions.dart";
import "package:moxxyv2/repositories/conversation.dart";
import "package:moxxyv2/models/conversation.dart";
import "package:redux/redux.dart";
import "package:flutter_redux_navigation/flutter_redux_navigation.dart";
import "package:get_it/get_it.dart";
void conversationsMiddleware(Store<MoxxyState> store, action, NextDispatcher next) {
var repo = GetIt.I.get<DatabaseRepository>();
if (action is AddConversationAction && !action.triggeredByDatabase) {
if (repo.hasConversation(action.id)) {
// TODO
} else {
repo.addConversationFromAction(action);
}
} else if (action is SendMessageAction) {
if (repo.hasConversation(action.cid)) {
repo.updateConversation(id: action.cid, lastMessageBody: action.body, lastChangeTimestamp: action.timestamp);
} else {
// TODO
}
} else if (action is CloseConversationAction) {
store.dispatch(NavigateToAction.replace("/conversations"));
}
void conversationsMiddleware(Store<MoxxyState> store, action, NextDispatcher next) async {
next(action);
}

View File

@@ -5,30 +5,16 @@ import "package:moxxyv2/redux/conversation/actions.dart";
List<Conversation> conversationReducer(List<Conversation> state, dynamic action) {
if (action is AddConversationAction) {
state.add(Conversation(
title: action.title,
lastMessageBody: action.lastMessageBody,
avatarUrl: action.avatarUrl,
jid: action.jid,
// TODO: Correct?
unreadCounter: 0,
sharedMediaPaths: action.sharedMediaPaths,
lastChangeTimestamp: action.lastChangeTimestamp,
open: action.open,
id: action.id
));
} else if (action is SendMessageAction) {
return state.map((element) {
if (element.jid == action.jid) {
return element.copyWith(lastMessageBody: action.body, lastChangeTimestamp: action.timestamp);
return state..add(action.conversation);
} else if (action is UpdateConversationAction) {
return state.map((c) {
if (c.id == action.conversation.id) {
return action.conversation;
}
return element;
return c;
}).toList();
} else if (action is CloseConversationAction) {
// TODO: Yikes.
return state.map((element) => element.jid == action.jid ? element.copyWith(open: false) : element).toList().where((element) => element.open).toList();
}
return state;
}

View File

@@ -0,0 +1,5 @@
class LoadMessagesAction {
final String jid;
LoadMessagesAction({ required this.jid });
}

View File

@@ -0,0 +1,65 @@
import "package:moxxyv2/redux/state.dart";
import "package:moxxyv2/redux/conversations/actions.dart";
import "package:moxxyv2/redux/conversation/actions.dart";
import "package:moxxyv2/repositories/conversation.dart";
import "package:moxxyv2/models/conversation.dart";
import "package:moxxyv2/models/message.dart";
import "package:moxxyv2/redux/messages/actions.dart";
import "package:moxxyv2/helpers.dart";
import "package:redux/redux.dart";
import "package:flutter_redux_navigation/flutter_redux_navigation.dart";
import "package:get_it/get_it.dart";
void messageMiddleware(Store<MoxxyState> store, action, NextDispatcher next) async {
if (action is ReceiveMessageAction) {
// TODO: Check if the conversation already exists
final repo = GetIt.I.get<DatabaseRepository>();
final now = DateTime.now().millisecondsSinceEpoch;
final bareJidString = action.from.toBare().toString();
final message = await repo.addMessageFromData(
action.body,
now,
bareJidString,
false
);
final existantConversation = firstWhereOrNull(store.state.conversations, (Conversation c) => c.jid == bareJidString);
if (existantConversation == null) {
final conversation = await repo.addConversationFromData(
action.from.local,
action.body,
"",
bareJidString,
1,
now,
[],
true
);
repo.loadedConversations.add(bareJidString);
store.dispatch(AddConversationAction(conversation: conversation));
} else {
await repo.updateConversation(
id: existantConversation.id,
lastMessageBody: action.body,
lastChangeTimestamp: now,
unreadCounter: existantConversation.unreadCounter + 1
);
store.dispatch(UpdateConversationAction(
conversation: existantConversation.copyWith(
lastMessageBody: action.body,
lastChangeTimestamp: now,
unreadCounter: existantConversation.unreadCounter + 1
)
));
}
store.dispatch(AddMessageAction(message: message));
} else if (action is LoadMessagesAction) {
GetIt.I.get<DatabaseRepository>().loadMessagesForJid(action.jid);
}
next(action);
}