-
-
Notifications
You must be signed in to change notification settings - Fork 809
Description
Is your feature request related to a problem? Please describe.
Converse.js could be a nice installable web app (PWA-style) or a browser extension. A service worker running in the background could deliver notifications to the user. Multiple tabs could share one BOSH/websockets connection / session.
By itself, this is not that interesting, but it opens some possibilities that are separate contribution opportunities / feature requests. If the session itself is detached from the UI, while the UI remains consistent between tabs etc, some options on reworking it become possible.
- In context of a browser extension, multiple browser windows (
browser.windows.create/chrome.windows.create) could attach to the same session (one for contacts, a few windows tabbed or untabbed for chats). - In the extension, a popup displayed from clicking the extension icon in the addressbar could spawn the roster, and choosing a user to talk to could open a tab or a window.
- Maintaining a single session (with synced windows and UI states) between tabs is easy
- Sidebar panels are now a thing in browsers: continuously open -- but collapsible -- sidebar seems like a good place to put a small roster and one chat (possibly tabbed). Especially if it is resumable.
- In an installable webapp, at the very least notifications to users become interesting
- Custom specialized UIs attachable to the same session as a chat session become easy (e.g. PEP or pubsub microblog viewer independent of the chats)
Some reasons why this FR might be already resolved (which I thought about after I already wrote the rest of the FR text):
-
Documentation for
connection_optionsdoes say:Newer versions of Strophe.js, support the ability to run the XMPP Connection inside a shared worker that’s shared between open tabs in the browser in which Converse is running (and which have the same domain).
Note: This feature is experimental and there currently is no way to synchronize actions between tabs. For example, sent 1-on-1 messages aren’t reflected by the server, so you if you send such a message in one tab, it won’t appear in another.
converse.initialize({ connection_options: { worker: '/dist/shared-connection-worker.js' } });I have not tried this out yet nor is it clear to me what this depends on. It sounds like this is solely a Strophe.js change where an instance of Strophe.js will run in a different worker, a stub repeater instance of Strophe.js will be running in the same context as Converse.js, and Converse.js will be mostly unaware that Strophe is doing this under the hood?
Random thought: Would Converse.js be retrofittable to use some sort of bindings (reminiscent of ideas behind Cocoa Bindings) to bind itself to some model object with "current chat history" instead and other things?
Or would a hack to reflect outgoing messages to blast into other 'tabs' be better hacked into Strophe.js?
Should this be better documented + tested + supported? Is this worth focusing on at this point, if trying to get a simple extension running just for my "can't really install extra non-browser software" situation?
-
I didn't quite get Pade to work reliably for me as a Chrome extension, and it has a tendency to create a lot of popups etc. It also goes beyond just XMPP chats. However, I think it has an option to run the session as a worker. Perhaps it is the same
shared-connection-worker.jsworker code mentioned above?
Describe the solution you'd like
Split critical comms session (set of IQs in flight with their deadlines, roster state received, known service discovery results) and other UI-relevant state (last transmitted presence, etc) away from UI, and not dependent on UI.
Get UI to be able to spawn the session, or attach to it, and preferably get multiple tabs to talk to one state (keyed e.g. by 'connection ID' so more connections can still be maintained even with one origin).
Preferably get UI state across tabs to be (optionally) synced (which chats are open, which adhoc command lists are open, etc). Or at least things like messages inside 1:1s and MUCs.
If this is already possible and I completely missed it -- at least I would love to see some clearer tips in documentation on how I could start working on something resembling this:
- put minimal converse.js into a browser extension (manifest.json, background.js as service worker, the usual)
- when my browser starts, user's saved credentials are used to log in without any UI interaction
- extension icon shows 'available' status badge
- when user clicks the extension icon to show popup.html (or equivalent), the roster is populated in there
- when user chooses a user, the chat continues in a new tab without reconnecting and renegotiating the session
This is because I sometimes work in environments that are browser-only, and I lack a decent desktop-integrated XMPP client.
Describe alternatives you've considered
Roll an XMPP library into a service worker -- e.g. in an extension, background.js (either a well known one, like strophe, or my own in which -- albeit hacky and barely maintainable -- I know where I've done serialization and I can be sure of how I'm persisting state when the session drops).
Then write my own UI library -- something that's a bad idea since I am very poorly informed about frontend development practices (including basics such as how to correctly do model<->view bindings in modern web). While this would be a nice learning project, it'd be a large effort I am not best suited for, and likely would not be maintainable by myself or anyone else, if I could even release it.
Additional context
If this (maintain XMPP session in one JS context, construct UI DOM in another and keep it attached) is already possible and well documented, please accept my apologies.
I don't recall if session resumption on page reload is a thing in Converse.js+Strophe.js; it's not clear from the doc (it might be doing a page reload) or whether detached state works.
The shared-connection-worker.js is news to me, and it might be nice to share a few words on how this works and how it interacts with Converse.js itself.