Skip to content

Commit 5ccbb00

Browse files
committed
Allow the user to choose one of multiple pubsub services
1 parent 5810f01 commit 5ccbb00

File tree

11 files changed

+69
-42
lines changed

11 files changed

+69
-42
lines changed

src/headless/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import './plugins/bosh/index.js'; // XEP-0206 BOSH
3030
import './plugins/caps/index.js'; // XEP-0115 Entity Capabilities
3131
export { ChatBox, Message, Messages } from './plugins/chat/index.js'; // RFC-6121 Instant messaging
3232
import './plugins/chatboxes/index.js';
33-
import './plugins/disco/index.js'; // XEP-0030 Service discovery
33+
export { DiscoEntity, DiscoEntities } from './plugins/disco/index.js'; // XEP-0030 Service discovery
3434
import './plugins/adhoc/index.js'; // XEP-0050 Ad Hoc Commands
3535
import './plugins/headlines/index.js'; // Support for headline messages
3636
export { Device, Devices, DeviceList, DeviceLists } from './plugins/omemo/index.js'; // Support for headline messages

src/headless/plugins/disco/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919

2020
const { Strophe } = converse.env;
2121

22+
export { DiscoEntity, DiscoEntities };
23+
2224
/**
2325
* @typedef {Object} DiscoState
2426
* @property {Array} _identities

src/headless/types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export { Collection, EventEmitter, Model } from "@converse/skeletor";
2121
export { Builder, Stanza } from "strophe.js";
2222
export { Bookmark, Bookmarks } from "./plugins/bookmarks/index.js";
2323
export { ChatBox, Message, Messages } from "./plugins/chat/index.js";
24+
export { DiscoEntity, DiscoEntities } from "./plugins/disco/index.js";
2425
export { Device, Devices, DeviceList, DeviceLists } from "./plugins/omemo/index.js";
2526
export { MUCMessage, MUCMessages, MUC, MUCOccupant, MUCOccupants } from "./plugins/muc/index.js";
2627
export { RosterContact, RosterContacts, RosterFilter, Presence, Presences } from "./plugins/roster/index.js";

src/headless/types/plugins/disco/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ export type DiscoState = {
22
_identities: any[];
33
_features: any[];
44
};
5+
import DiscoEntity from './entity.js';
6+
import DiscoEntities from './entities.js';
7+
export { DiscoEntity, DiscoEntities };
58
//# sourceMappingURL=index.d.ts.map

src/headless/types/plugins/pubsub/api.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ declare namespace _default {
3434
* @returns {Promise<void|Element>}
3535
*/
3636
function publish(jid: string, node: string, item: import("strophe.js").Builder | import("strophe.js").Stanza | (import("strophe.js").Builder | import("strophe.js").Stanza)[], options: import("./types").PubSubConfigOptions, strict_options?: boolean): Promise<void | Element>;
37+
/**
38+
* Creates a PubSub node at a given service
39+
* @param {string} jid - The PubSub service JID
40+
* @param {string} node - The node to create
41+
* @param {PubSubConfigOptions} [config] The configuration options
42+
* @returns {Promise<void>}
43+
*/
44+
function create(jid: string, node: string, config?: import("./types").PubSubConfigOptions): Promise<void>;
3745
/**
3846
* Subscribes the local user to a PubSub node.
3947
*

src/headless/types/shared/_converse.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export class ConversePrivateGlobal extends ConversePrivateGlobal_base {
7979
*/
8080
state: any;
8181
initSession(): void;
82-
session: Model;
82+
session: any;
8383
/**
8484
* Translate the given string based on the current locale.
8585
* @method __

src/headless/types/shared/connection/index.d.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ declare const Connection_base: typeof import("strophe.js/src/types/connection").
55
* via BOSH or websocket inside a shared worker).
66
*/
77
export class Connection extends Connection_base {
8-
constructor(service: any, options: any);
8+
/**
9+
* @param {string} service - The BOSH or WebSocket service URL.
10+
* @param {import('strophe.js/src/types/connection').ConnectionOptions} options
11+
*/
12+
constructor(service: string, options: import("strophe.js/src/types/connection").ConnectionOptions);
913
send_initial_presence: boolean;
1014
debouncedReconnect: import("lodash").DebouncedFunc<() => Promise<any>>;
1115
/** @param {Element} body */
@@ -111,11 +115,6 @@ export class Connection extends Connection_base {
111115
* The MockConnection class is used during testing, to mock an XMPP connection.
112116
*/
113117
export class MockConnection extends Connection {
114-
/**
115-
* @param {string} service - The BOSH or WebSocket service URL.
116-
* @param {import('strophe.js/src/types/connection').ConnectionOptions} options - The configuration options
117-
*/
118-
constructor(service: string, options: import("strophe.js/src/types/connection").ConnectionOptions);
119118
sent_stanzas: any[];
120119
IQ_stanzas: any[];
121120
IQ_ids: any[];

src/plugins/todo/modals/add-todo-modal.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import { _converse, api, converse, parsers } from '@converse/headless';
22
import BaseModal from 'plugins/modal/modal.js';
3-
import tplAddTodo from './templates/add-todo-modal.js';
43
import { __ } from 'i18n';
4+
import tplAddTodo from './templates/add-todo-modal.js';
55

66
const { Strophe } = converse.env;
77

88
export default class AddTodoModal extends BaseModal {
9+
10+
static get properties() {
11+
return {
12+
...super.properties,
13+
_manual_jid: { state: true, type: Boolean },
14+
_entities: { state: true, type: Array },
15+
};
16+
}
17+
918
initialize() {
1019
super.initialize();
1120
this.requestUpdate();
@@ -36,19 +45,21 @@ export default class AddTodoModal extends BaseModal {
3645
const name = data.get('name');
3746
const jid = data.get('jid') ?? _converse.state.session.get('domain');
3847

39-
const service_jids = await api.disco.entities.find(Strophe.NS.PUBSUB, jid);
40-
if (service_jids.length === 0) {
48+
const entities = await api.disco.entities.find(Strophe.NS.PUBSUB, jid);
49+
if (entities.length === 0) {
4150
this.alert(__('Could not find a PubSub service to host your todo list'), 'danger');
42-
this.state.set({ manual_jid: true });
51+
this._manual_jid = true;
4352
return;
44-
} else if (service_jids.length > 1) {
53+
} else if (entities.length > 1) {
4554
this.alert(__('Found multiple possible PubSub services to host your todo list, please choose one.'));
46-
this.state.set({ services: service_jids, manual_jid: true });
55+
56+
this._entities = entities;
57+
this._manual_jid = true;
4758
return;
4859
}
4960

5061
try {
51-
await api.pubsub.create(service_jids[0].get('jid'), name);
62+
await api.pubsub.create(entities[0].get('jid'), name);
5263
} catch (e) {
5364
const err = await parsers.parseErrorStanza(e);
5465
this.alert(__('Sorry, an error occurred: %s', err.message), 'danger');

src/plugins/todo/modals/templates/add-todo-modal.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,42 @@ export default (el) => {
1010
const label_name = __('Todo name');
1111
const label_service = __('PubSub service (XMPP Address) for your todo list');
1212

13-
const pubsub_services = el.state.get('services') ?? [];
14-
1513
return html`<form class="converse-form" @submit=${(ev) => el.createTodo(ev)}>
1614
<div class="mb-3">
1715
<label for="todo-name" class="form-label">${label_name}:</label>
1816
<input type="text" id="todo-name" name="name" class="form-control" placeholder="${label_name}" required />
1917
</div>
2018
21-
${el.state.get('manual_jid')
22-
? html`<div class="mb-3">
23-
${pubsub_services.length > 1
24-
? html`${__('Available PubSub services')}
25-
<ul class="list-group">
26-
${(pubsub_services ?? []).map((jid) => html`<li class="list-group-item">${jid}</li>`)}
27-
</ul>`
28-
: ''}
29-
30-
<label for="todo-jid" class="form-label">${label_service}:</label>
31-
<input
32-
type="text"
33-
id="todo-jid"
34-
name="jid"
35-
class="form-control"
36-
required
37-
/>
38-
</div>`
19+
${el._manual_jid
20+
? html` ${(el._entities?.length ?? 0) > 1
21+
? html`<div class="mb-3">
22+
<label class="form-label">${__('Available PubSub services:')}</label>
23+
<div class="list-group">
24+
${el._entities.map(/** @param {import('@converse/headless').DiscoEntity} entity */(entity) => {
25+
const jid = entity.get('jid');
26+
const features = entity.features
27+
.map((f) => f.get('var'))
28+
.filter((f) => f.includes('pubsub'));
29+
return html`<div class="form-check">
30+
<input
31+
class="form-check-input"
32+
type="radio"
33+
name="pubsub_service"
34+
id="${jid}"
35+
value="${jid}"
36+
/>
37+
<label class="form-check-label fw-bold" for="${jid}">${jid}</label>
38+
<ul class="list-unstyled mt-2 text-muted small">
39+
${features.map((feature) => html`<li>${feature}</li>`)}
40+
</ul>
41+
</div>`;
42+
})}
43+
</div>
44+
</div>`
45+
: html`<div class="mb-3">
46+
<label for="todo-jid" class="form-label">${label_service}:</label>
47+
<input type="text" id="todo-jid" name="jid" class="form-control" required />
48+
</div>`}`
3949
: ''}
4050
4151
<input type="submit" class="btn btn-primary mt-3" value="${i18n_create || ''}" />

src/types/plugins/rootview/app-switcher.d.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
export default class AppSwitcher extends CustomElement {
2-
static get properties(): {
3-
_activeApp: {
4-
type: StringConstructor;
5-
};
6-
};
7-
_activeApp: string;
82
initialize(): void;
93
render(): import("lit-html").TemplateResult<1>;
104
/**

0 commit comments

Comments
 (0)