| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2025-07-08 20:11:58 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2025-07-08 20:27:59 UTC |
| parent | 27f20093a6027f3d0719eb1d1521f3828f13c129 |
| Makefile | +2 | -0 |
| npm/index.ts | +5 | -1 |
| snikket/Chat.hx | +2 | -2 |
| snikket/Client.hx | +12 | -0 |
| snikket/jingle/Session.hx | +22 | -4 |
diff --git a/Makefile b/Makefile index edc53a6..59db28c 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,7 @@ npm/snikket-browser.js: sed -i 's/snikket\.UserState/enums.UserState/g' npm/snikket-browser.d.ts sed -i 's/snikket\.ChatMessageEvent/enums.ChatMessageEvent/g' npm/snikket-browser.d.ts sed -i 's/snikket\.ReactionUpdateKind/enums.ReactionUpdateKind/g' npm/snikket-browser.d.ts + sed -i 's/snikket\.jingle\.CallStatus/enums.jingle.CallStatus/g' npm/snikket-browser.d.ts sed -i '1ivar exports = {};' npm/snikket-browser.js echo "export const snikket = exports.snikket;" >> npm/snikket-browser.js @@ -45,6 +46,7 @@ npm/snikket.js: sed -i 's/snikket\.UserState/enums.UserState/g' npm/snikket.d.ts sed -i 's/snikket\.ChatMessageEvent/enums.ChatMessageEvent/g' npm/snikket.d.ts sed -i 's/snikket\.ReactionUpdateKind/enums.ReactionUpdateKind/g' npm/snikket.d.ts + sed -i 's/snikket\.jingle\.CallStatus/enums.jingle.CallStatus/g' npm/snikket.d.ts sed -i '1iimport { createRequire } from "module";' npm/snikket.js sed -i '1iglobal.require = createRequire(import.meta.url);' npm/snikket.js sed -i '1ivar exports = {};' npm/snikket.js diff --git a/npm/index.ts b/npm/index.ts index 05db77a..c1d8609 100644 --- a/npm/index.ts +++ b/npm/index.ts @@ -23,9 +23,13 @@ export import Participant = snikket.Participant; export import Push = snikket.Push; export import Reaction = snikket.Reaction; export import SerializedChat = snikket.SerializedChat; -export import jingle = snikket.jingle; export const VERSION = snikket.Version.HUMAN; +export import jingle = snikket.jingle; +namespace jingle { + export import CallStatus = enums.jingle.CallStatus; +} + export import ChatMessageEvent = enums.ChatMessageEvent; export import MessageDirection = enums.MessageDirection; export import MessageStatus = enums.MessageStatus; diff --git a/snikket/Chat.hx b/snikket/Chat.hx index ce22088..d6d4f8a 100644 --- a/snikket/Chat.hx +++ b/snikket/Chat.hx @@ -583,7 +583,7 @@ abstract class Chat { @HaxeCBridge.noemit public function addMedia(streams: Array<MediaStream>) { - if (callStatus() != "ongoing") throw "cannot add media when no call ongoing"; + if (callStatus() != Ongoing) throw "cannot add media when no call ongoing"; jingleSessions.iterator().next().addMedia(streams); } @@ -614,7 +614,7 @@ abstract class Chat { return session.callStatus(); } - return "none"; + return NoCall; } /** diff --git a/snikket/Client.hx b/snikket/Client.hx index 98d6ed7..eeead42 100644 --- a/snikket/Client.hx +++ b/snikket/Client.hx @@ -1165,6 +1165,18 @@ class Client extends EventEmitter { }); } + /** + Event fired when an existing call changes status (connecting, failed, etc) + + @param handler takes one argument, the associated Session + **/ + public function addCallUpdateStatusListener(handler:(InitiatedSession)->Void):Void { + this.on("call/updateStatus", (data) -> { + handler(data.session); + return EventHandled; + }); + } + /** Event fired when a call is asking for media to send diff --git a/snikket/jingle/Session.hx b/snikket/jingle/Session.hx index 8ead549..f2ef059 100644 --- a/snikket/jingle/Session.hx +++ b/snikket/jingle/Session.hx @@ -12,6 +12,15 @@ using thenshim.PromiseTools; import HaxeCBridge; #end +enum abstract CallStatus(Int) { + var NoCall; + var Incoming; + var Outgoing; + var Connecting; + var Ongoing; + var Failed; +} + #if cpp @:build(HaxeSwiftBridge.expose()) #end @@ -33,7 +42,7 @@ interface Session { @:allow(snikket) private function transportInfo(stanza: Stanza): Promise<Any>; public function addMedia(streams: Array<MediaStream>): Void; - public function callStatus():String; + public function callStatus():CallStatus; public function videoTracks():Array<MediaStreamTrack>; public function dtmf():Null<DTMFSender>; } @@ -139,6 +148,7 @@ class IncomingProposedSession implements Session { if (session.sid != sid) throw "id mismatch"; if (!accepted) throw "trying to initiate unaccepted session"; session.accept(); + client.trigger("call/updateStatus", { session: session }); return session; } @@ -147,7 +157,7 @@ class IncomingProposedSession implements Session { } public function callStatus() { - return "incoming"; + return Incoming; } public function videoTracks() { @@ -254,6 +264,7 @@ class OutgoingProposedSession implements Session { client.sendPresence(to.asString()); final session = new OutgoingSession(client, JID.parse(stanza.attr.get("from")), sid); client.trigger("call/media", { session: session, audio: audio, video: video }); + client.trigger("call/updateStatus", { session: session }); return session; } @@ -262,7 +273,7 @@ class OutgoingProposedSession implements Session { } public function callStatus() { - return "outgoing"; + return Outgoing; } public function videoTracks() { @@ -475,7 +486,13 @@ class InitiatedSession implements Session { } public function callStatus() { - return "ongoing"; + return if (pc == null || pc.connectionState == "connecting") { + Connecting; + } else if (pc.connectionState == "failed" || pc.connectionState == "closed") { + Failed; + } else { + Ongoing; + } } public function videoTracks(): Array<MediaStreamTrack> { @@ -560,6 +577,7 @@ class InitiatedSession implements Session { sendIceCandidate(event.candidate); }); pc.addEventListener("connectionstatechange", (event) -> { + if (pc != null) client.trigger("call/updateStatus", { session: this }); if (pc != null && (pc.connectionState == "closed" || pc.connectionState == "failed")) { client.sendStanza( new Stanza("iq", { to: counterpart.asString(), type: "set", id: ID.medium() })