Use optional chaining instead of lodash.get

This commit is contained in:
JC Brand 2020-03-24 12:26:34 +01:00
parent 7812d4e7b6
commit 967154d314
22 changed files with 122 additions and 126 deletions

View File

@ -5,14 +5,15 @@
* @license Mozilla Public License (MPLv2)
*/
import "@converse/headless/converse-muc";
import { Model } from 'skeletor.js/src/model.js';
import { View } from 'skeletor.js/src/view.js';
import { __ } from '@converse/headless/i18n';
import converse from "@converse/headless/converse-core";
import tpl_bookmarks_list from "templates/bookmarks_list.js"
import tpl_muc_bookmark_form from "templates/muc_bookmark_form.js";
import { Model } from 'skeletor.js/src/model.js';
import { View } from 'skeletor.js/src/view.js';
import { __ } from '@converse/headless/i18n';
import { invokeMap } from 'lodash';
const { Strophe, _ } = converse.env;
const { Strophe } = converse.env;
const u = converse.env.utils;
@ -85,7 +86,7 @@ converse.plugins.add('converse-bookmark-views', {
const name = ev.target.getAttribute('data-bookmark-name');
const jid = ev.target.getAttribute('data-room-jid');
if (confirm(__("Are you sure you want to remove the bookmark \"%1$s\"?", name))) {
_.invokeMap(_converse.bookmarks.where({'jid': jid}), Model.prototype.destroy);
invokeMap(_converse.bookmarks.where({'jid': jid}), Model.prototype.destroy);
}
},
@ -166,9 +167,9 @@ converse.plugins.add('converse-bookmark-views', {
ev.preventDefault();
_converse.bookmarks.createBookmark({
'jid': this.model.get('jid'),
'autojoin': _.get(ev.target.querySelector('input[name="autojoin"]'), 'checked') || false,
'name': _.get(ev.target.querySelector('input[name=name]'), 'value'),
'nick': _.get(ev.target.querySelector('input[name=nick]'), 'value')
'autojoin': ev.target.querySelector('input[name="autojoin"]')?.checked || false,
'name': ev.target.querySelector('input[name=name]')?.value,
'nick': ev.target.querySelector('input[name=nick]')?.value
});
this.closeBookmarkForm(ev);
},

View File

@ -8,7 +8,7 @@ import "converse-message-view";
import "converse-modal";
import { BootstrapModal } from "./converse-modal.js";
import { Overview } from "skeletor.js/src/overview";
import { debounce, get, isString } from "lodash";
import { debounce, isString } from "lodash";
import { html, render } from "lit-html";
import converse from "@converse/headless/converse-core";
import log from "@converse/headless/log";
@ -96,7 +96,7 @@ converse.plugins.add('converse-chatview', {
},
toHTML () {
const vcard = get(this.model, 'vcard'),
const vcard = this.model?.vcard,
vcard_json = vcard ? vcard.toJSON() : {};
return tpl_user_details_modal(Object.assign(
this.model.toJSON(),
@ -295,10 +295,10 @@ converse.plugins.add('converse-chatview', {
Object.assign(this.model.toJSON(), {
'__': __,
'message_limit': _converse.message_limit,
'hint_value': get(this.el.querySelector('.spoiler-hint'), 'value'),
'hint_value': this.el.querySelector('.spoiler-hint')?.value,
'label_message': this.model.get('composing_spoiler') ? __('Hidden message') : __('Message'),
'label_spoiler_hint': __('Optional hint'),
'message_value': get(this.el.querySelector('.chat-textarea'), 'value'),
'message_value': this.el.querySelector('.chat-textarea')?.value,
'show_send_button': _converse.show_send_button,
'show_toolbar': _converse.show_toolbar,
'unread_msgs': __('You have unread messages')
@ -403,7 +403,7 @@ converse.plugins.add('converse-chatview', {
},
generateHeadingTemplate () {
const vcard = get(this.model, 'vcard');
const vcard = this.model?.vcard;
const vcard_json = vcard ? vcard.toJSON() : {};
const heading_btns = this.getHeadingButtons();
const standalone_btns = heading_btns.filter(b => b.standalone);

View File

@ -4,7 +4,6 @@
* @license Mozilla Public License (MPLv2)
*/
import "converse-chatview";
import { get } from "lodash";
import { Model } from 'skeletor.js/src/model.js';
import { View } from "skeletor.js/src/view";
import bootstrap from "bootstrap.native";
@ -209,7 +208,7 @@ converse.plugins.add('converse-controlbox', {
this.hide();
}
const connection = get(_converse, 'connection', {});
const connection = _converse?.connection || {};
if (!connection.connected || !connection.authenticated || connection.disconnecting) {
this.renderLoginPanel();
} else if (this.model.get('connected')) {
@ -284,7 +283,7 @@ converse.plugins.add('converse-controlbox', {
async close (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (get(ev, 'name') === 'closeAllChatBoxes' &&
if (ev?.name === 'closeAllChatBoxes' &&
(_converse.disconnection_cause !== _converse.LOGOUT ||
_converse.show_controlbox_by_default)) {
return;
@ -292,7 +291,7 @@ converse.plugins.add('converse-controlbox', {
if (_converse.sticky_controlbox) {
return;
}
const connection = get(_converse, 'connection', {});
const connection = _converse?.connection || {};
if (connection.connected && !connection.disconnecting) {
await new Promise((resolve, reject) => {
return this.model.save(
@ -574,11 +573,11 @@ converse.plugins.add('converse-controlbox', {
});
_converse.api.listen.on('clearSession', () => {
const chatboxviews = get(_converse, 'chatboxviews', null);
const chatboxviews = _converse?.chatboxviews;
const view = chatboxviews && chatboxviews.get('controlbox');
if (view) {
u.safeSave(view.model, {'connected': false});
if (get(view, 'controlbox_pane')) {
if (view?.controlbox_pane) {
view.controlbox_pane.remove();
delete view.controlbox_pane;
}

View File

@ -5,7 +5,7 @@
*/
import "converse-chatview";
import "converse-controlbox";
import { debounce, get } from "lodash";
import { debounce } from "lodash";
import converse from "@converse/headless/converse-core";
import tpl_dragresize from "templates/dragresize.html";
@ -168,7 +168,7 @@ converse.plugins.add('converse-dragresize', {
// Initialize last known mouse position
this.prev_pageY = 0;
this.prev_pageX = 0;
if (get(_converse.connection, 'connected')) {
if (_converse.connection?.connected) {
this.height = this.model.get('height');
this.width = this.model.get('width');
}

View File

@ -5,7 +5,7 @@
*/
import "@converse/headless/converse-emoji";
import { View } from "skeletor.js/src/view";
import { debounce, find, get } from "lodash";
import { debounce, find } from "lodash";
import DOMNavigator from "./dom-navigator";
import bootstrap from "bootstrap.native";
import emoji_picker from "templates/emoji_picker.js";
@ -255,7 +255,7 @@ converse.plugins.add('converse-emoji-views', {
if (intersection_with_selected) {
current = intersection_with_selected;
} else {
current = ev.reduce((p, c) => c.intersectionRatio >= get(p, 'intersectionRatio', 0) ? c : p, null);
current = ev.reduce((p, c) => c.intersectionRatio >= (p?.intersectionRatio || 0) ? c : p, null);
}
current && current.isIntersecting && this.setCategoryForElement(current.target);
},

View File

@ -8,12 +8,13 @@ import { Model } from 'skeletor.js/src/model.js';
import { Overview } from "skeletor.js/src/overview";
import { View } from "skeletor.js/src/view";
import { __ } from '@converse/headless/i18n';
import { debounce, sum } from 'lodash';
import converse from "@converse/headless/converse-core";
import tpl_chats_panel from "templates/chats_panel.html";
import tpl_toggle_chats from "templates/toggle_chats.html";
import tpl_trimmed_chat from "templates/trimmed_chat.html";
const { _ , dayjs } = converse.env;
const { dayjs } = converse.env;
const u = converse.env.utils;
@ -292,7 +293,7 @@ converse.plugins.add('converse-minimize', {
},
getMinimizedWidth () {
const minimized_el = _.get(_converse.minimized_chats, 'el');
const minimized_el = _converse.minimized_chats?.el;
return this.model.pluck('minimized').includes(true) ? u.getOuterWidth(minimized_el, true) : 0;
},
@ -328,7 +329,7 @@ converse.plugins.add('converse-minimize', {
return;
}
await _converse.api.waitUntil('minimizedChatsInitialized');
const minimized_el = _.get(_converse.minimized_chats, 'el');
const minimized_el = _converse.minimized_chats?.el;
if (minimized_el) {
while ((this.getMinimizedWidth() + this.getBoxesWidth(newchat)) > body_width) {
const new_id = newchat ? newchat.model.get('id') : null;
@ -417,7 +418,7 @@ converse.plugins.add('converse-minimize', {
return this;
},
restore: _.debounce(function (ev) {
restore: debounce(function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.model.off('change:num_unread', null, this);
this.remove();
@ -513,7 +514,7 @@ converse.plugins.add('converse-minimize', {
},
updateUnreadMessagesCounter () {
this.toggleview.model.save({'num_unread': _.sum(this.model.pluck('num_unread'))});
this.toggleview.model.save({'num_unread': sum(this.model.pluck('num_unread'))});
this.render();
}
});
@ -569,7 +570,7 @@ converse.plugins.add('converse-minimize', {
_converse.api.listen.on('chatBoxInsertedIntoDOM', view => _converse.chatboxviews.trimChats(view));
_converse.api.listen.on('controlBoxOpened', view => _converse.chatboxviews.trimChats(view));
const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250);
const debouncedTrimChats = debounce(() => _converse.chatboxviews.trimChats(), 250);
_converse.api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", debouncedTrimChats));
_converse.api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", debouncedTrimChats));
/************************ END Event Handlers ************************/

View File

@ -8,7 +8,7 @@ import "converse-modal";
import "@converse/headless/utils/muc";
import { Model } from 'skeletor.js/src/model.js';
import { View } from 'skeletor.js/src/view.js';
import { get, head, isString, isUndefined } from "lodash";
import { head, isString, isUndefined } from "lodash";
import { BootstrapModal } from "./converse-modal.js";
import { render } from "lit-html";
import { __ } from '@converse/headless/i18n';
@ -172,8 +172,8 @@ converse.plugins.add('converse-muc-views', {
'beforeEnd',
tpl_room_description({
'jid': stanza.getAttribute('from'),
'desc': get(head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'),
'occ': get(head(sizzle('field[var="muc#roominfo_occupants"] value', stanza)), 'textContent'),
'desc': head(sizzle('field[var="muc#roominfo_description"] value', stanza))?.textContent,
'occ': head(sizzle('field[var="muc#roominfo_occupants"] value', stanza))?.textContent,
'hidden': sizzle('feature[var="muc_hidden"]', stanza).length,
'membersonly': sizzle('feature[var="muc_membersonly"]', stanza).length,
'moderated': sizzle('feature[var="muc_moderated"]', stanza).length,
@ -764,11 +764,7 @@ converse.plugins.add('converse-muc-views', {
if (!(existing_actors?.length)) {
return result;
}
const actors = existing_actors
.map(a => this.model.getOccupant(a))
.filter(a => a)
.map(a => a.getDisplayName());
const actors = existing_actors.map(a => this.model.getOccupant(a)?.getDisplayName() || a.nick);
if (actors.length === 1) {
if (state === 'composing') {
return `${result} ${__('%1$s is typing', actors[0])}\n`;
@ -1941,7 +1937,7 @@ converse.plugins.add('converse-muc-views', {
if (date && date.split('T')[0] !== today) {
return;
}
const data = get(el, 'dataset', {});
const data = el?.dataset || {};
if (data.join === nick ||
data.leave === nick ||
data.leavejoin === nick ||
@ -1960,7 +1956,7 @@ converse.plugins.add('converse-muc-views', {
const nick = occupant.get('nick'),
stat = _converse.muc_show_join_leave_status ? occupant.get('status') : null,
prev_info_el = this.getPreviousJoinOrLeaveNotification(this.content.lastElementChild, nick),
data = get(prev_info_el, 'dataset', {});
data = prev_info_el?.dataset || {};
if (data.leave === nick) {
let message;
@ -2015,7 +2011,7 @@ converse.plugins.add('converse-muc-views', {
const nick = occupant.get('nick'),
stat = _converse.muc_show_join_leave_status ? occupant.get('status') : null,
prev_info_el = this.getPreviousJoinOrLeaveNotification(this.content.lastElementChild, nick),
dataset = get(prev_info_el, 'dataset', {});
dataset = prev_info_el?.dataset || {};
if (dataset.join === nick) {
let message;
@ -2192,9 +2188,9 @@ converse.plugins.add('converse-muc-views', {
return tpl_muc_config_form({
'closeConfigForm': ev => this.closeConfigForm(ev),
'fields': fields.map(f => u.xForm2webForm(f, stanza, options)),
'instructions': get(stanza.querySelector('instructions'), 'textContent'),
'instructions': stanza.querySelector('instructions')?.textContent,
'submitConfigForm': ev => this.submitConfigForm(ev),
'title': get(stanza.querySelector('title'), 'textContent')
'title': stanza.querySelector('title')?.textContent
});
},

View File

@ -4,7 +4,6 @@
* @license Mozilla Public License (MPLv2)
*/
import converse from "@converse/headless/converse-core";
import { get } from "lodash";
import log from "@converse/headless/log";
const { Strophe, sizzle } = converse.env;
@ -166,7 +165,7 @@ converse.plugins.add('converse-notification', {
// the message...
const body = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, message).length ?
__('OMEMO Message received') :
get(message.querySelector('body'), 'textContent');
message.querySelector('body')?.textContent;
if (!body) {
return;
}

View File

@ -8,7 +8,7 @@
import "converse-profile";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import { concat, debounce, difference, get, invokeMap, range, omit } from "lodash";
import { concat, debounce, difference, invokeMap, range, omit } from "lodash";
import converse from "@converse/headless/converse-core";
import log from "@converse/headless/log";
import tpl_toolbar_omemo from "templates/toolbar_omemo.html";
@ -377,7 +377,7 @@ converse.plugins.add('converse-omemo', {
'device_id': header.getAttribute('sid'),
'iv': header.querySelector('iv').textContent,
'key': key.textContent,
'payload': get(encrypted.querySelector('payload'), 'textContent', null),
'payload': encrypted.querySelector('payload')?.textContent || null,
'prekey': ['true', '1'].includes(key.getAttribute('prekey'))
}
return this.decrypt(attrs);
@ -481,7 +481,7 @@ converse.plugins.add('converse-omemo', {
async function generateFingerprint (device) {
if (get(device.get('bundle'), 'fingerprint')) {
if (device.get('bundle')?.fingerprint) {
return;
}
const bundle = await device.getBundle();

View File

@ -7,9 +7,10 @@
* @license Mozilla Public License (MPLv2)
*/
import converse from "@converse/headless/converse-core";
import { filter, reject } from 'lodash';
import log from "@converse/headless/log";
const { Strophe, $iq, _ } = converse.env;
const { Strophe, $iq } = converse.env;
Strophe.addNamespace('PUSH', 'urn:xmpp:push:0');
@ -96,10 +97,10 @@ converse.plugins.add('converse-push', {
if (push_enabled.includes(domain)) {
return;
}
const enabled_services = _.reject(_converse.push_app_servers, 'disable');
const disabled_services = _.filter(_converse.push_app_servers, 'disable');
const enabled = _.map(enabled_services, _.partial(enablePushAppServer, domain));
const disabled = _.map(disabled_services, _.partial(disablePushAppServer, domain));
const enabled_services = reject(_converse.push_app_servers, 'disable');
const disabled_services = filter(_converse.push_app_servers, 'disable');
const enabled = enabled_services.map(s => enablePushAppServer(domain, s));
const disabled = disabled_services.map(s => disablePushAppServer(domain, s));
try {
await Promise.all(enabled.concat(disabled));
} catch (e) {

View File

@ -8,7 +8,7 @@
*/
import "converse-controlbox";
import { View } from "skeletor.js/src/view";
import { get, pick } from "lodash";
import { pick } from "lodash";
import converse from "@converse/headless/converse-core";
import log from "@converse/headless/log";
import tpl_form_input from "templates/form_input.html";
@ -287,7 +287,7 @@ converse.plugins.add('converse-register', {
*/
onProviderChosen (form) {
const domain_input = form.querySelector('input[name=domain]'),
domain = get(domain_input, 'value');
domain = domain_input?.value;
if (!domain) {
// TODO: add validation message
domain_input.classList.add('error');
@ -597,12 +597,12 @@ converse.plugins.add('converse-register', {
},
_setFieldsFromXForm (xform) {
this.title = get(xform.querySelector('title'), 'textContent');
this.instructions = get(xform.querySelector('instructions'), 'textContent');
this.title = xform.querySelector('title')?.textContent;
this.instructions = xform.querySelector('instructions')?.textContent;
xform.querySelectorAll('field').forEach(field => {
const _var = field.getAttribute('var');
if (_var) {
this.fields[_var.toLowerCase()] = get(field.querySelector('value'), 'textContent', '');
this.fields[_var.toLowerCase()] = field.querySelector('value')?.textContent ?? '';
} else {
// TODO: other option seems to be type="fixed"
log.warn("Found field we couldn't parse");

View File

@ -9,7 +9,6 @@ import "@converse/headless/converse-muc";
import converse from "@converse/headless/converse-core";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import { get } from "lodash";
import log from "./log";
const { Strophe, $iq, sizzle } = converse.env;
@ -215,7 +214,7 @@ converse.plugins.add('converse-bookmarks', {
'jid': jid,
'name': bookmark.getAttribute('name') || jid,
'autojoin': bookmark.getAttribute('autojoin') === 'true',
'nick': get(bookmark.querySelector('nick'), 'textContent')
'nick': bookmark.querySelector('nick')?.textContent
});
});
},

View File

@ -3,7 +3,7 @@
* @copyright 2020, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import { find, get, isMatch, isObject, isString, pick } from "lodash";
import { find, isMatch, isObject, isString, pick } from "lodash";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import converse from "./converse-core";
@ -1033,8 +1033,8 @@ converse.plugins.add('converse-chat', {
return;
}
const data = item.dataforms.where({'FORM_TYPE': {'value': Strophe.NS.HTTPUPLOAD, 'type': "hidden"}}).pop(),
max_file_size = window.parseInt(get(data, 'attributes.max-file-size.value')),
slot_request_url = get(item, 'id');
max_file_size = window.parseInt((data?.attributes || {})['max-file-size']?.value),
slot_request_url = item?.id;
if (!slot_request_url) {
this.createMessage({
@ -1224,7 +1224,7 @@ converse.plugins.add('converse-chat', {
}
// Get chat box, but only create when the message has something to show to the user
const has_body = sizzle(`body, encrypted[xmlns="${Strophe.NS.OMEMO}"]`, stanza).length > 0;
const roster_nick = get(contact, 'attributes.nickname');
const roster_nick = contact?.attributes?.nickname;
const chatbox = await _converse.api.chats.get(contact_jid, {'nickname': roster_nick}, has_body);
chatbox && await chatbox.queueMessage(stanza, original_stanza, from_jid);
/**
@ -1336,9 +1336,9 @@ converse.plugins.add('converse-chat', {
*/
async create (jids, attrs) {
if (isString(jids)) {
if (attrs && !get(attrs, 'fullname')) {
if (attrs && !attrs?.fullname) {
const contact = await _converse.api.contacts.get(jids);
attrs.fullname = get(contact, 'attributes.fullname');
attrs.fullname = contact?.attributes?.fullname;
}
const chatbox = _converse.api.chats.get(jids, attrs, true);
if (!chatbox) {
@ -1350,7 +1350,7 @@ converse.plugins.add('converse-chat', {
if (Array.isArray(jids)) {
return Promise.all(jids.forEach(async jid => {
const contact = await _converse.api.contacts.get(jids);
attrs.fullname = get(contact, 'attributes.fullname');
attrs.fullname = contact?.attributes?.fullname;
return _converse.api.chats.get(jid, attrs, true).maybeShow();
}));
}

View File

@ -4,7 +4,7 @@
* @license Mozilla Public License (MPLv2)
*/
import { __, i18n } from './i18n';
import { assignIn, debounce, get, invoke, isFunction, isObject, isString, pick } from 'lodash';
import { assignIn, debounce, invoke, isFunction, isObject, isString, pick } from 'lodash';
import { Collection } from "skeletor.js/src/collection";
import { Events } from 'skeletor.js/src/events.js';
import { Model } from 'skeletor.js/src/model.js';
@ -486,7 +486,7 @@ function connect (credentials) {
BOSH_WAIT
);
} else if (_converse.authentication === _converse.LOGIN) {
const password = credentials ? credentials.password : (get(_converse.connection, 'pass') || _converse.password);
const password = credentials ? credentials.password : (_converse.connection?.pass || _converse.password);
if (!password) {
if (_converse.auto_login) {
throw new Error("autoLogin: If you use auto_login and "+
@ -1063,7 +1063,7 @@ _converse.initialize = async function (settings, callback) {
return finishDisconnection();
}
} else if (_converse.disconnection_cause === _converse.LOGOUT ||
(reason !== undefined && reason === get(Strophe, 'ErrorCondition.NO_AUTH_MECH')) ||
(reason !== undefined && reason === Strophe?.ErrorCondition.NO_AUTH_MECH) ||
reason === "host-unknown" ||
reason === "remote-connection-failed" ||
!_converse.auto_reconnect) {
@ -1139,7 +1139,7 @@ _converse.initialize = async function (settings, callback) {
if (message === "host-unknown" || message == "remote-connection-failed") {
feedback = __("Sorry, we could not connect to the XMPP host with domain: %1$s",
`\"${Strophe.getDomainFromJid(_converse.connection.jid)}\"`);
} else if (message !== undefined && message === get(Strophe, 'ErrorCondition.NO_AUTH_MECH')) {
} else if (message !== undefined && message === Strophe?.ErrorCondition?.NO_AUTH_MECH) {
feedback = __("The XMPP server did not offer a supported authentication mechanism");
}
_converse.setConnectionStatus(status, feedback);
@ -1206,7 +1206,7 @@ _converse.api = {
* @returns {boolean} Whether there is an established connection or not.
*/
connected () {
return get(_converse, 'connection', {}).connected && true;
return _converse?.connection?.connected && true;
},
/**

View File

@ -4,7 +4,7 @@
* @license Mozilla Public License (MPLv2)
* @description Converse plugin which add support for XEP-0030: Service Discovery
*/
import { get, isEmpty, isObject } from "lodash";
import { isEmpty, isObject } from "lodash";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import converse from "./converse-core";
@ -195,7 +195,7 @@ converse.plugins.add('converse-disco', {
const data = {};
sizzle('field', form).forEach(field => {
data[field.getAttribute('var')] = {
'value': get(field.querySelector('value'), 'textContent'),
'value': field.querySelector('value')?.textContent,
'type': field.getAttribute('type')
};
});
@ -216,7 +216,7 @@ converse.plugins.add('converse-disco', {
sizzle('x[type="result"][xmlns="jabber:x:data"] field', stanza).forEach(field => {
this.fields.create({
'var': field.getAttribute('var'),
'value': get(field.querySelector('value'), 'textContent'),
'value': field.querySelector('value')?.textContent,
'from': stanza.getAttribute('from')
});
});

View File

@ -9,7 +9,7 @@ import "./converse-disco";
import "./converse-emoji";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import { clone, debounce, get, intersection, invoke, isElement, isObject, isString, pick, uniq, zipObject } from "lodash";
import { clone, debounce, intersection, invoke, isElement, isObject, isString, pick, uniq, zipObject } from "lodash";
import converse from "./converse-core";
import log from "./log";
import muc_utils from "./utils/muc";
@ -259,7 +259,7 @@ converse.plugins.add('converse-muc', {
onOccupantRemoved () {
this.stopListening(this.occupant);
delete this.occupant;
const chatbox = get(this, 'collection.chatbox');
const chatbox = this?.collection?.chatbox;
if (!chatbox) {
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
}
@ -270,7 +270,7 @@ converse.plugins.add('converse-muc', {
if (occupant.get('nick') === Strophe.getResourceFromJid(this.get('from'))) {
this.occupant = occupant;
this.listenTo(this.occupant, 'destroy', this.onOccupantRemoved);
const chatbox = get(this, 'collection.chatbox');
const chatbox = this?.collection?.chatbox;
if (!chatbox) {
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
}
@ -280,7 +280,7 @@ converse.plugins.add('converse-muc', {
setOccupant () {
if (this.get('type') !== 'groupchat') { return; }
const chatbox = get(this, 'collection.chatbox');
const chatbox = this?.collection?.chatbox;
if (!chatbox) {
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
}
@ -1210,7 +1210,7 @@ converse.plugins.add('converse-muc', {
* @returns { ('none'|'visitor'|'participant'|'moderator') }
*/
getOwnRole () {
return get(this.getOwnOccupant(), 'attributes.role');
return this.getOwnOccupant()?.attributes?.role;
},
/**
@ -1220,7 +1220,7 @@ converse.plugins.add('converse-muc', {
* @returns { ('none'|'outcast'|'member'|'admin'|'owner') }
*/
getOwnAffiliation () {
return get(this.getOwnOccupant(), 'attributes.affiliation');
return this.getOwnOccupant()?.attributes?.affiliation;
},
/**
@ -1534,8 +1534,8 @@ converse.plugins.add('converse-muc', {
}
const jid = data.jid || '';
const attributes = Object.assign(data, {
'jid': Strophe.getBareJidFromJid(jid) || get(occupant, 'attributes.jid'),
'resource': Strophe.getResourceFromJid(jid) || get(occupant, 'attributes.resource')
'jid': Strophe.getBareJidFromJid(jid) || occupant?.attributes?.jid,
'resource': Strophe.getResourceFromJid(jid) || occupant?.attributes?.resource
});
if (occupant) {
occupant.save(attributes);
@ -1580,7 +1580,7 @@ converse.plugins.add('converse-muc', {
}
});
} else if (child.getAttribute("xmlns") === Strophe.NS.VCARDUPDATE) {
data.image_hash = get(child.querySelector('photo'), 'textContent');
data.image_hash = child.querySelector('photo')?.textContent;
}
}
});
@ -1959,7 +1959,7 @@ converse.plugins.add('converse-muc', {
},
handleModifyError(pres) {
const text = get(pres.querySelector('error text'), 'textContent');
const text = pres.querySelector('error text')?.textContent;
if (text) {
if (this.session.get('connection_status') === converse.ROOMSTATUS.CONNECTING) {
this.setDisconnectionMessage(text);
@ -1991,7 +1991,7 @@ converse.plugins.add('converse-muc', {
// element. This appears to be a safe assumption, since
// each <x/> element pertains to a single user.
const item = x.querySelector('item');
const reason = item ? get(item.querySelector('reason'), 'textContent') : undefined;
const reason = item ? item.querySelector('reason')?.textContent : undefined;
const actor = item ? invoke(item.querySelector('actor'), 'getAttribute', 'nick') : undefined;
const message = _converse.muc.disconnect_messages[disconnection_codes[0]];
this.setDisconnectionMessage(message, reason, actor);
@ -2038,7 +2038,7 @@ converse.plugins.add('converse-muc', {
const nick = Strophe.getResourceFromJid(stanza.getAttribute('from'));
const item = x.querySelector('item');
data.actor = item ? invoke(item.querySelector('actor'), 'getAttribute', 'nick') : undefined;
data.reason = item ? get(item.querySelector('reason'), 'textContent') : undefined;
data.reason = item ? item.querySelector('reason')?.textContent : undefined;
data.message = this.getActionInfoMessage(code, nick, data.actor);
} else if (is_self && (code in _converse.muc.new_nickname_messages)) {
let nick;
@ -2107,7 +2107,7 @@ converse.plugins.add('converse-muc', {
onErrorPresence (stanza) {
const error = stanza.querySelector('error');
const error_type = error.getAttribute('type');
const reason = get(sizzle(`text[xmlns="${Strophe.NS.STANZAS}"]`, error).pop(), 'textContent');
const reason = sizzle(`text[xmlns="${Strophe.NS.STANZAS}"]`, error).pop()?.textContent;
if (error_type === 'modify') {
this.handleModifyError(stanza);
@ -2131,7 +2131,7 @@ converse.plugins.add('converse-muc', {
const message = __("Your nickname doesn't conform to this groupchat's policies.");
this.setDisconnectionMessage(message, reason);
} else if (sizzle(`gone[xmlns="${Strophe.NS.STANZAS}"]`, error).length) {
const moved_jid = get(sizzle(`gone[xmlns="${Strophe.NS.STANZAS}"]`, error).pop(), 'textContent')
const moved_jid = sizzle(`gone[xmlns="${Strophe.NS.STANZAS}"]`, error).pop()?.textContent
.replace(/^xmpp:/, '')
.replace(/\?join$/, '');
this.save({ moved_jid, 'destroyed_reason': reason});

View File

@ -6,7 +6,7 @@
import "@converse/headless/converse-status";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import { get, invoke, isEmpty, isNaN, isString, propertyOf, sum } from "lodash";
import { invoke, isEmpty, isNaN, isString, propertyOf, sum } from "lodash";
import converse from "@converse/headless/converse-core";
import log from "./log";
@ -136,7 +136,7 @@ converse.plugins.add('converse-roster', {
onResourcesChanged () {
const hpr = this.getHighestPriorityResource();
const show = get(hpr, 'attributes.show', 'offline');
const show = hpr?.attributes?.show || 'offline';
if (this.get('show') !== show) {
this.save({'show': show});
}
@ -538,7 +538,7 @@ converse.plugins.add('converse-roster', {
contact.authorize().subscribe();
} else {
// Can happen when a subscription is retried or roster was deleted
const nickname = get(sizzle(`nick[xmlns="${Strophe.NS.NICK}"]`, presence).pop(), 'textContent', null);
const nickname = sizzle(`nick[xmlns="${Strophe.NS.NICK}"]`, presence).pop()?.textContent || null;
const contact = await this.addContactToRoster(bare_jid, nickname, [], {'subscription': 'from'});
if (contact instanceof _converse.RosterContact) {
contact.authorize().subscribe();
@ -686,8 +686,8 @@ converse.plugins.add('converse-roster', {
},
createRequestingContact (presence) {
const bare_jid = Strophe.getBareJidFromJid(presence.getAttribute('from')),
nickname = get(sizzle(`nick[xmlns="${Strophe.NS.NICK}"]`, presence).pop(), 'textContent', null);
const bare_jid = Strophe.getBareJidFromJid(presence.getAttribute('from'));
const nickname = sizzle(`nick[xmlns="${Strophe.NS.NICK}"]`, presence).pop()?.textContent || null;
const user_data = {
'jid': bare_jid,
'subscription': 'none',

View File

@ -3,7 +3,7 @@
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import { get, isNaN, isObject, isString } from "lodash";
import { isNaN, isObject, isString } from "lodash";
import { Model } from 'skeletor.js/src/model.js';
import converse from "@converse/headless/converse-core";
@ -97,7 +97,7 @@ converse.plugins.add('converse-status', {
if (_converse.idle_seconds > 0) {
_converse.idle_seconds = 0;
}
if (!get(_converse.connection, 'authenticated')) {
if (!_converse.connection?.authenticated) {
// We can't send out any stanzas when there's no authenticated connection.
// This can happen when the connection reconnects.
return;
@ -121,7 +121,7 @@ converse.plugins.add('converse-status', {
/* An interval handler running every second.
* Used for CSI and the auto_away and auto_xa features.
*/
if (!get(_converse.connection, 'authenticated')) {
if (!_converse.connection?.authenticated) {
// We can't send out any stanzas when there's no authenticated connection.
// This can happen when the connection reconnects.
return;

View File

@ -6,7 +6,7 @@
import "./converse-status";
import { Collection } from "skeletor.js/src/collection";
import { Model } from 'skeletor.js/src/model.js';
import { get, has, isString } from "lodash";
import { has, isString } from "lodash";
import converse from "./converse-core";
import log from "@converse/headless/log";
import tpl_vcard from "./templates/vcard.html";
@ -117,13 +117,13 @@ converse.plugins.add('converse-vcard', {
if (vcard !== null) {
result = {
'stanza': iq,
'fullname': get(vcard.querySelector('FN'), 'textContent'),
'nickname': get(vcard.querySelector('NICKNAME'), 'textContent'),
'image': get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
'image_type': get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
'url': get(vcard.querySelector('URL'), 'textContent'),
'role': get(vcard.querySelector('ROLE'), 'textContent'),
'email': get(vcard.querySelector('EMAIL USERID'), 'textContent'),
'fullname': vcard.querySelector('FN')?.textConte?.t,
'nickname': vcard.querySelector('NICKNAME')?.textConte?.t,
'image': vcard.querySelector('PHOTO BINVAL')?.textConte?.t,
'image_type': vcard.querySelector('PHOTO TYPE')?.textConte?.t,
'url': vcard.querySelector('URL')?.textConte?.t,
'role': vcard.querySelector('ROLE')?.textConte?.t,
'email': vcard.querySelector('EMAIL USERID')?.textConte?.t,
'vcard_updated': (new Date()).toISOString(),
'vcard_error': undefined
};
@ -184,7 +184,7 @@ converse.plugins.add('converse-vcard', {
function getVCardForChatroomOccupant (message) {
const chatbox = get(message, 'collection.chatbox');
const chatbox = message?.collection?.chatbox;
const nick = Strophe.getResourceFromJid(message.get('from'));
if (chatbox && chatbox.get('nick') === nick) {

View File

@ -1,4 +1,4 @@
import { get, isElement } from 'lodash';
import { isElement } from 'lodash';
const LEVELS = {
'debug': 0,
@ -9,10 +9,10 @@ const LEVELS = {
}
const logger = Object.assign({
'debug': get(console, 'log') ? console.log.bind(console) : function noop () {},
'error': get(console, 'log') ? console.log.bind(console) : function noop () {},
'info': get(console, 'log') ? console.log.bind(console) : function noop () {},
'warn': get(console, 'log') ? console.log.bind(console) : function noop () {}
'debug': console?.log ? console.log.bind(console) : function noop () {},
'error': console?.log ? console.log.bind(console) : function noop () {},
'info': console?.log ? console.log.bind(console) : function noop () {},
'warn': console?.log ? console.log.bind(console) : function noop () {}
}, console);

View File

@ -1,5 +1,5 @@
import * as strophe from 'strophe.js/src/core';
import { get, propertyOf } from "lodash";
import { propertyOf } from "lodash";
import dayjs from 'dayjs';
import log from '@converse/headless/log';
import sizzle from 'sizzle';
@ -95,7 +95,7 @@ const stanza_utils = {
'moderated': 'retracted',
'moderated_by': moderated.getAttribute('by'),
'moderated_id': applies_to_id,
'moderation_reason': get(moderated.querySelector('reason'), 'textContent')
'moderation_reason': moderated.querySelector('reason')?.textContent
}
}
}
@ -109,7 +109,7 @@ const stanza_utils = {
'is_tombstone': true,
'moderated_by': tombstone.getAttribute('by'),
'retracted': tombstone.getAttribute('stamp'),
'moderation_reason': get(tombstone.querySelector('reason'), 'textContent')
'moderation_reason': tombstone.querySelector('reason')?.textContent
}
}
@ -202,7 +202,7 @@ const stanza_utils = {
const spoiler = sizzle(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`, stanza).pop();
return {
'is_spoiler': !!spoiler,
'spoiler_hint': get(spoiler, 'textContent')
'spoiler_hint': spoiler?.textContent
}
},
@ -210,8 +210,8 @@ const stanza_utils = {
const xform = sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, stanza).pop();
if (xform) {
return {
'oob_url': get(xform.querySelector('url'), 'textContent'),
'oob_desc': get(xform.querySelector('desc'), 'textContent')
'oob_url': xform.querySelector('url')?.textContent,
'oob_desc': xform.querySelector('desc')?.textContent
}
}
return {};

View File

@ -4,7 +4,7 @@
* @description This is the DOM/HTML utilities module.
*/
import URI from "urijs";
import { get, isFunction } from "lodash";
import { isFunction } from "lodash";
import log from '@converse/headless/log';
import sizzle from "sizzle";
import tpl_audio from "../templates/audio.js";
@ -588,9 +588,9 @@ u.xForm2webForm = function (field, stanza, options) {
if (field.getAttribute('type') === 'list-single' ||
field.getAttribute('type') === 'list-multi') {
const values = u.queryChildren(field, 'value').map(el => get(el, 'textContent'));
const values = u.queryChildren(field, 'value').map(el => el?.textContent);
const options = u.queryChildren(field, 'option').map(option => {
const value = get(option.querySelector('value'), 'textContent');
const value = option.querySelector('value')?.textContent;
return tpl_select_option({
'value': value,
'label': option.getAttribute('label'),
@ -607,13 +607,13 @@ u.xForm2webForm = function (field, stanza, options) {
'required': !!field.querySelector('required')
});
} else if (field.getAttribute('type') === 'fixed') {
const text = get(field.querySelector('value'), 'textContent');
const text = field.querySelector('value')?.textContent;
return '<p class="form-help">'+text+'</p>';
} else if (field.getAttribute('type') === 'jid-multi') {
return tpl_form_textarea({
'name': field.getAttribute('var'),
'label': field.getAttribute('label') || '',
'value': get(field.querySelector('value'), 'textContent'),
'value': field.querySelector('value')?.textContent,
'required': !!field.querySelector('required')
});
} else if (field.getAttribute('type') === 'boolean') {
@ -621,13 +621,13 @@ u.xForm2webForm = function (field, stanza, options) {
'id': u.getUniqueId(),
'name': field.getAttribute('var'),
'label': field.getAttribute('label') || '',
'checked': get(field.querySelector('value'), 'textContent') === "1" && 'checked="1"' || '',
'checked': field.querySelector('value')?.textContent === "1" && 'checked="1"' || '',
'required': !!field.querySelector('required')
});
} else if (field.getAttribute('var') === 'url') {
return tpl_form_url({
'label': field.getAttribute('label') || '',
'value': get(field.querySelector('value'), 'textContent')
'value': field.querySelector('value')?.textContent
});
} else if (field.getAttribute('var') === 'username') {
return tpl_form_username({
@ -635,7 +635,7 @@ u.xForm2webForm = function (field, stanza, options) {
'name': field.getAttribute('var'),
'type': XFORM_TYPE_MAP[field.getAttribute('type')],
'label': field.getAttribute('label') || '',
'value': get(field.querySelector('value'), 'textContent'),
'value': field.querySelector('value')?.textContent,
'required': !!field.querySelector('required')
});
} else if (field.getAttribute('var') === 'ocr') { // Captcha
@ -644,7 +644,7 @@ u.xForm2webForm = function (field, stanza, options) {
return tpl_form_captcha({
'label': field.getAttribute('label'),
'name': field.getAttribute('var'),
'data': get(el, 'textContent'),
'data': el?.textContent,
'type': uri.getAttribute('type'),
'required': !!field.querySelector('required')
});
@ -659,7 +659,7 @@ u.xForm2webForm = function (field, stanza, options) {
'placeholder': null,
'required': !!field.querySelector('required'),
'type': XFORM_TYPE_MAP[field.getAttribute('type')],
'value': get(field.querySelector('value'), 'textContent')
'value': field.querySelector('value')?.textContent
});
}
}