diff --git a/src/modals/templates/add-contact.js b/src/modals/templates/add-contact.js
new file mode 100644
index 0000000000..48d4180527
--- /dev/null
+++ b/src/modals/templates/add-contact.js
@@ -0,0 +1,58 @@
+import { __ } from 'i18n';
+import { api } from '@converse/headless/core.js';
+import { html } from "lit";
+import { modal_header_close_button } from "plugins/modal/templates/buttons.js"
+import { getServerList } from "../../plugins/rosterview/utils"
+
+
+export default (el) => {
+ const i18n_add = __('Add');
+ const i18n_contact_placeholder = __('name@example.org');
+ const i18n_error_message = __('Please enter a valid XMPP address');
+ const i18n_group = __('Group');
+ const i18n_new_contact = __('Add a Contact');
+ const i18n_nickname = __('Name');
+ const i18n_xmpp_address = __('XMPP Address');
+ return html`
+
+ `;
+}
diff --git a/src/plugins/rosterview/modals/add-contact.js b/src/plugins/rosterview/modals/add-contact.js
index 8f9cb31dd7..4ca8bb466a 100644
--- a/src/plugins/rosterview/modals/add-contact.js
+++ b/src/plugins/rosterview/modals/add-contact.js
@@ -27,12 +27,14 @@ export default class AddContactModal extends BaseModal {
}
afterRender () {
- if (typeof api.settings.get('xhr_user_search_url') === 'string') {
- this.initXHRAutoComplete();
- } else {
- this.initJIDAutoComplete();
- }
- }
+ const jid_input = this.el.querySelector('input[name="jid"]');
+ this.el.addEventListener('shown.bs.modal', () => jid_input.focus(), false);
+ },
+
+ getGroupsAutoCompleteList () {
+ return ['apple', 'pear', 'banana'];
+ // return [...new Set(_converse.roster.map(i => i.get('gruop')).filter(i => i))];
+ },
initJIDAutoComplete () {
if (!api.settings.get('autocomplete_add_contact')) {
diff --git a/src/plugins/rosterview/utils.js b/src/plugins/rosterview/utils.js
index 8b5c69429a..12510237ad 100644
--- a/src/plugins/rosterview/utils.js
+++ b/src/plugins/rosterview/utils.js
@@ -1,6 +1,4 @@
-import log from "@converse/headless/log";
-import { __ } from 'i18n';
-import { _converse, api } from "@converse/headless/core";
+import { _converse, api, converse } from "@converse/headless/core";
export function removeContact (contact) {
contact.removeFromRoster(
@@ -112,3 +110,29 @@ export function populateContactsMap (contacts_map, contact) {
}
return contacts_map;
}
+
+let final_list = [];
+let timestamp = null;
+
+async function getServerList() {
+ const responseA = await fetch('https://data.xmpp.net/providers/v1/providers-A.json');
+ const dataA = await responseA.json();
+ const popular_mucsA = dataA.items.map(item => item.jid);
+ const responseB = await fetch('https://data.xmpp.net/providers/v1/providers-B.json');
+ const dataB = await responseB.json();
+ const popular_mucsB = dataB.items.map(item => item.jid);
+ const responseC = await fetch('https://data.xmpp.net/providers/v1/providers-C.json');
+ const dataC = await responseC.json();
+ const popular_mucsC = dataC.items.map(item => item.jid);
+ const response = [...popular_mucsA, ...popular_mucsB, ...popular_mucsC];
+ console.log(response)
+ final_list = [...new Set(response)];
+}
+
+export async function getXMPPList() {
+ if (!timestamp || converse.env.dayjs().isAfter(timestamp, 'day')) {
+ await getServerList();
+ timestamp = (new Date()).toISOString();
+ }
+ return final_list;
+}
diff --git a/src/shared/autocomplete/component.js b/src/shared/autocomplete/component.js
index ce9a4f4189..10d7d7b0c1 100644
--- a/src/shared/autocomplete/component.js
+++ b/src/shared/autocomplete/component.js
@@ -48,7 +48,8 @@ export default class AutoCompleteComponent extends CustomElement {
'getAutoCompleteList': { type: Function },
'list': { type: Array },
'auto_evaluate': { type: Boolean },
- 'auto_first': { type: Boolean },
+ 'dataMap': { type: Function },
+ 'auto_first': { type: Boolean }, // Should the first element be automatically selected?
'filter': { type: String },
'include_triggers': { type: String },
'min_chars': { type: Number },
@@ -65,7 +66,8 @@ export default class AutoCompleteComponent extends CustomElement {
this.auto_evaluate = true;
this.auto_first = false;
this.filter = 'contains';
- this.include_triggers = '';
+ this.dataMap = a => a; // Function that maps user provided input to a suggestion value
+ this.include_triggers = ''; // Space separated chars which should be included in the returned value
this.match_current_word = false; // Match only the current word, otherwise all input is matched
this.max_items = 10;
this.min_chars = 1;
@@ -105,7 +107,8 @@ export default class AutoCompleteComponent extends CustomElement {
'auto_first': this.auto_first,
'filter': this.filter == 'contains' ? FILTER_CONTAINS : FILTER_STARTSWITH,
'include_triggers': [],
- 'list': this.list ?? ((q) => this.getAutoCompleteList(q)),
+ 'list': () => this.getAutoCompleteList(),
+ 'data': (a) => this.dataMap(a),
'match_current_word': true,
'max_items': this.max_items,
'min_chars': this.min_chars,