feat(xep): Allow ignoring the discussion history
Also allow specifying the amount of stanzas of discussion history we want.
This commit is contained in:
parent
d4416c8a47
commit
d7c13abde6
@ -58,7 +58,11 @@ void main(List<String> args) async {
|
||||
Logger.root.info('Connected.');
|
||||
|
||||
// Join room
|
||||
await connection.getManagerById<MUCManager>(mucManager)!.joinRoom(muc, nick);
|
||||
await connection.getManagerById<MUCManager>(mucManager)!.joinRoom(
|
||||
muc,
|
||||
nick,
|
||||
maxHistoryStanzas: 0,
|
||||
);
|
||||
|
||||
final repl = Repl(prompt: '> ');
|
||||
await for (final line in repl.runAsync()) {
|
||||
|
@ -34,10 +34,25 @@ class RoomInformation {
|
||||
}
|
||||
|
||||
class RoomState {
|
||||
RoomState({
|
||||
required this.roomJid,
|
||||
this.nick,
|
||||
});
|
||||
RoomState({required this.roomJid, this.nick, required this.joined});
|
||||
|
||||
/// The JID of the room.
|
||||
final JID roomJid;
|
||||
|
||||
/// The nick we're joined with.
|
||||
String? nick;
|
||||
|
||||
/// Flag whether we're joined and can process messages
|
||||
bool joined;
|
||||
|
||||
RoomState copyWith({
|
||||
bool? joined,
|
||||
String? nick,
|
||||
}) {
|
||||
return RoomState(
|
||||
roomJid: roomJid,
|
||||
joined: joined ?? this.joined,
|
||||
nick: nick ?? this.nick,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:moxlib/moxlib.dart';
|
||||
import 'package:moxxmpp/src/jid.dart';
|
||||
import 'package:moxxmpp/src/managers/base.dart';
|
||||
import 'package:moxxmpp/src/managers/data.dart';
|
||||
import 'package:moxxmpp/src/managers/handlers.dart';
|
||||
import 'package:moxxmpp/src/managers/namespaces.dart';
|
||||
import 'package:moxxmpp/src/namespaces.dart';
|
||||
import 'package:moxxmpp/src/stanza.dart';
|
||||
@ -9,6 +11,7 @@ import 'package:moxxmpp/src/xeps/xep_0030/types.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0045/errors.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0045/types.dart';
|
||||
import 'package:synchronized/extension.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
|
||||
class MUCManager extends XmppManagerBase {
|
||||
@ -23,6 +26,16 @@ class MUCManager extends XmppManagerBase {
|
||||
/// Cache lock
|
||||
final Lock _cacheLock = Lock();
|
||||
|
||||
@override
|
||||
List<StanzaHandler> getIncomingStanzaHandlers() => [
|
||||
StanzaHandler(
|
||||
stanzaTag: 'message',
|
||||
callback: _onMessage,
|
||||
// Before the message handler
|
||||
priority: -99,
|
||||
)
|
||||
];
|
||||
|
||||
/// Queries the information of a Multi-User Chat room.
|
||||
///
|
||||
/// Retrieves the information about the specified MUC room by performing a
|
||||
@ -55,11 +68,23 @@ class MUCManager extends XmppManagerBase {
|
||||
/// if applicable.
|
||||
Future<Result<bool, MUCError>> joinRoom(
|
||||
JID roomJid,
|
||||
String nick,
|
||||
) async {
|
||||
String nick, {
|
||||
int? maxHistoryStanzas,
|
||||
}) async {
|
||||
if (nick.isEmpty) {
|
||||
return Result(NoNicknameSpecified());
|
||||
}
|
||||
|
||||
await _cacheLock.synchronized(
|
||||
() {
|
||||
_mucRoomCache[roomJid] = RoomState(
|
||||
roomJid: roomJid,
|
||||
nick: nick,
|
||||
joined: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
await getAttributes().sendStanza(
|
||||
StanzaDetails(
|
||||
Stanza.presence(
|
||||
@ -68,16 +93,20 @@ class MUCManager extends XmppManagerBase {
|
||||
XMLNode.xmlns(
|
||||
tag: 'x',
|
||||
xmlns: mucXmlns,
|
||||
)
|
||||
children: [
|
||||
if (maxHistoryStanzas != null)
|
||||
XMLNode(
|
||||
tag: 'history',
|
||||
attributes: {
|
||||
'maxstanzas': maxHistoryStanzas.toString(),
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await _cacheLock.synchronized(
|
||||
() {
|
||||
_mucRoomCache[roomJid] = RoomState(roomJid: roomJid, nick: nick);
|
||||
},
|
||||
);
|
||||
return const Result(true);
|
||||
}
|
||||
|
||||
@ -108,4 +137,48 @@ class MUCManager extends XmppManagerBase {
|
||||
);
|
||||
return const Result(true);
|
||||
}
|
||||
|
||||
Future<StanzaHandlerData> _onMessage(
|
||||
Stanza message,
|
||||
StanzaHandlerData state,
|
||||
) async {
|
||||
final roomJid = JID.fromString(message.from!).toBare();
|
||||
return _mucRoomCache.synchronized(() {
|
||||
final roomState = _mucRoomCache[roomJid];
|
||||
if (roomState == null) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (message.type == 'groupchat' && message.firstTag('subject') != null) {
|
||||
// The room subject marks the end of the join flow.
|
||||
if (!roomState.joined) {
|
||||
// Mark the room as joined.
|
||||
_mucRoomCache[roomJid] = roomState.copyWith(joined: true);
|
||||
logger.finest('$roomJid is now joined');
|
||||
}
|
||||
|
||||
// TODO(Unknown): Signal the subject?
|
||||
|
||||
return StanzaHandlerData(
|
||||
true,
|
||||
false,
|
||||
message,
|
||||
state.extensions,
|
||||
);
|
||||
} else {
|
||||
if (!roomState.joined) {
|
||||
// Ignore the discussion history.
|
||||
// TODO: Implement a copyWith method
|
||||
return StanzaHandlerData(
|
||||
true,
|
||||
false,
|
||||
message,
|
||||
state.extensions,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user