Skip to content

Commit

Permalink
Fixes for MUC sync status
Browse files Browse the repository at this point in the history
  • Loading branch information
singpolyma committed Nov 19, 2024
1 parent 0a826dd commit e6518cc
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 28 deletions.
55 changes: 38 additions & 17 deletions snikket/Chat.hx
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,8 @@ class Channel extends Chat {
@:allow(snikket)
private var disco: Caps = new Caps("", [], ["http://jabber.org/protocol/muc"]);
private var inSync = true;
private var sync = null;
private var forceLive = false;

@:allow(snikket)
private function new(client:Client, stream:GenericStream, persistence:Persistence, chatId:String, uiState = Open, isBlocked = false, extensions = null, readUpToId = null, readUpToBy = null, ?disco: Caps) {
Expand All @@ -912,16 +914,21 @@ class Channel extends Chat {
return;
}

stream.sendIq(
new Stanza("iq", { type: "get", to: getFullJid().asString() })
.tag("ping", { xmlns: "urn:xmpp:ping" }).up(),
(response) -> {
if (response.attr.get("type") == "error") {
final err = response.getChild("error")?.getChild(null, "urn:ietf:params:xml:ns:xmpp-stanzas");
if (err.name == "service-unavailable" || err.name == "feature-not-implemented") return checkRename(); // Error, success!
if (err.name == "remote-server-not-found" || err.name == "remote-server-timeout") return checkRename(); // Timeout, retry later
if (err.name == "item-not-found") return checkRename(); // Nick was changed?
(shouldRefreshDisco ? refreshDisco : (cb)->cb())(() -> {
(refresh ? refreshDisco : (cb)->cb())(() -> {
if (!disco.features.contains("http://jabber.org/protocol/muc")) {
// Not a MUC, owhat kind of channel is this?
forceLive = true;
return;
}
stream.sendIq(
new Stanza("iq", { type: "get", to: getFullJid().asString() })
.tag("ping", { xmlns: "urn:xmpp:ping" }).up(),
(response) -> {
if (response.attr.get("type") == "error") {
final err = response.getChild("error")?.getChild(null, "urn:ietf:params:xml:ns:xmpp-stanzas");
if (err.name == "service-unavailable" || err.name == "feature-not-implemented") return checkRename(); // Error, success!
if (err.name == "remote-server-not-found" || err.name == "remote-server-timeout") return checkRename(); // Timeout, retry later
if (err.name == "item-not-found") return checkRename(); // Nick was changed?
presence = []; // About to ask for a fresh set
inSync = false;
client.trigger("chats/update", [this]);
Expand All @@ -936,12 +943,14 @@ class Channel extends Chat {
return stanza;
}
);
});
} else {
checkRename();
} else {
inSync = false;
persistence.lastId(client.accountId(), chatId, doSync);
checkRename();
}
}
}
);
);
});
}

private function checkRename() {
Expand All @@ -967,15 +976,21 @@ class Channel extends Chat {
persistence.lastId(client.accountId(), chatId, doSync);
}
if (oneTen != null && tripleThree != null) {
selfPing();
selfPing(true);
}
}

private function doSync(lastId: Null<String>) {
if (!disco.features.contains("urn:xmpp:mam:2")) {
inSync = true;
return;
}
if (sync != null) return;

var threeDaysAgo = Date.format(
DateTools.delta(std.Date.now(), DateTools.days(-3))
);
var sync = new MessageSync(
sync = new MessageSync(
client,
stream,
lastId == null ? { startTime: threeDaysAgo } : { page: { after: lastId } },
Expand Down Expand Up @@ -1008,6 +1023,7 @@ class Channel extends Chat {
sync.fetchNext();
} else {
inSync = true;
sync = null;
final lastFromSync = chatMessages[chatMessages.length - 1];
if (lastFromSync != null && (lastMessageTimestamp() == null || Reflect.compare(lastFromSync.timestamp, lastMessageTimestamp()) > 0)) {
setLastMessage(lastFromSync);
Expand All @@ -1024,9 +1040,12 @@ class Channel extends Chat {
});
});
sync.onError((stanza) -> {
sync = null;
if (lastId != null) {
// Gap in sync, out newest message has expired from server
doSync(null);
} else {
trace("SYNC failed", chatId, stanza);
}
});
sync.fetchNext();
Expand Down Expand Up @@ -1054,6 +1073,8 @@ class Channel extends Chat {

@:allow(snikket)
override private function livePresence() {
if (forceLive) return true;

for (nick => p in presence) {
for (status in p?.mucUser?.allTags("status") ?? []) {
if (status.attr.get("code") == "110") {
Expand Down
14 changes: 7 additions & 7 deletions snikket/Client.hx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class Client extends EventEmitter {
});

stream.on("sm/update", (data) -> {
final anySyncHappening = chats.exists(chat -> chat.syncing());
final anySyncHappening = chats.exists(chat -> chat.uiState != Closed && chat.syncing());
persistence.storeStreamManagement(accountId(), anySyncHappening ? null : data.sm);
return EventHandled;
});
Expand Down Expand Up @@ -147,7 +147,7 @@ class Client extends EventEmitter {
if (stanza.attr.get("type") == "error" && from != null) {
final chat = getChat(from.asBare().asString());
final channel = Std.downcast(chat, Channel);
if (channel != null) channel.selfPing();
if (channel != null) channel.selfPing(true);
}

var fwd = null;
Expand Down Expand Up @@ -650,7 +650,7 @@ class Client extends EventEmitter {
if (fn == null || fn == "" || fn == displayName()) return false;
_displayName = fn;
persistence.storeLogin(jid.asBare().asString(), stream.clientId ?? jid.resource, fn, null);
pingAllChannels();
pingAllChannels(false);
return true;
}

Expand Down Expand Up @@ -706,7 +706,7 @@ class Client extends EventEmitter {
// Set self to online
if (sendAvailable) {
sendPresence();
pingAllChannels();
pingAllChannels(true);
}
this.trigger("status/online", {});
trace("SYNC: done");
Expand Down Expand Up @@ -854,7 +854,7 @@ class Client extends EventEmitter {
chats = chats.filter((chat) -> chat.chatId != availableChat.chatId);
} else {
if (existingChat.uiState == Closed) existingChat.uiState = Open;
channel?.selfPing();
channel?.selfPing(true);
this.trigger("chats/update", [existingChat]);
return existingChat;
}
Expand Down Expand Up @@ -1410,10 +1410,10 @@ class Client extends EventEmitter {
sync.fetchNext();
}

private function pingAllChannels() {
private function pingAllChannels(refresh: Bool) {
for (chat in getChats()) {
final channel = Std.downcast(chat, Channel);
channel?.selfPing(channel?.disco == null);
channel?.selfPing(refresh || channel?.disco == null);
}
}
}
2 changes: 1 addition & 1 deletion snikket/Persistence.hx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface Persistence {
public function storeLogin(login:String, clientId:String, displayName:String, token:Null<String>):Void;
public function getLogin(login:String, callback:(clientId:Null<String>, token:Null<String>, fastCount: Int, displayName:Null<String>)->Void):Void;
public function removeAccount(accountId: String, completely:Bool):Void;
public function storeStreamManagement(accountId:String, data:BytesData):Void;
public function storeStreamManagement(accountId:String, data:Null<BytesData>):Void;
public function getStreamManagement(accountId:String, callback: (Null<BytesData>)->Void):Void;
public function storeService(accountId:String, serviceId:String, name:Null<String>, node:Null<String>, caps:Caps):Void;
@HaxeCBridge.noemit
Expand Down
2 changes: 1 addition & 1 deletion snikket/Stanza.hx
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class Stanza implements NodeInterface {
return allText().join("");
}

public function find(path:String):Node {
public function find(path:String): Null<Node> {
var pos = 0;
var len = path.length;
var cursor = this;
Expand Down
2 changes: 1 addition & 1 deletion snikket/persistence/Dummy.hx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class Dummy implements Persistence {
public function removeAccount(accountId:String, completely:Bool) { }

@HaxeCBridge.noemit
public function storeStreamManagement(accountId:String, sm:BytesData) { }
public function storeStreamManagement(accountId:String, sm:Null<BytesData>) { }

@HaxeCBridge.noemit
public function getStreamManagement(accountId:String, callback: (Null<BytesData>)->Void) {
Expand Down
2 changes: 1 addition & 1 deletion snikket/persistence/Sqlite.hx
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ class Sqlite implements Persistence {
}

@HaxeCBridge.noemit
public function storeStreamManagement(accountId:String, sm:BytesData) {
public function storeStreamManagement(accountId:String, sm:Null<BytesData>) {
// TODO
}

Expand Down

0 comments on commit e6518cc

Please sign in to comment.