diff options
Diffstat (limited to 'roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components')
5 files changed, 195 insertions, 0 deletions
diff --git a/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/bookmark-form.js b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/bookmark-form.js new file mode 100644 index 0000000..a550aa1 --- /dev/null +++ b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/bookmark-form.js @@ -0,0 +1,51 @@ +import tplMUCBookmarkForm from './templates/form.js'; +import { CustomElement } from 'shared/components/element'; +import { _converse, api } from "@converse/headless/core"; + + +class MUCBookmarkForm extends CustomElement { + + static get properties () { + return { + 'jid': { type: String } + } + } + + willUpdate (changed_properties) { + if (changed_properties.has('jid')) { + this.model = _converse.chatboxes.get(this.jid); + this.bookmark = _converse.bookmarks.get(this.jid); + } + } + + render () { + return tplMUCBookmarkForm(this) + } + + onBookmarkFormSubmitted (ev) { + ev.preventDefault(); + _converse.bookmarks.createBookmark({ + 'jid': this.jid, + '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); + } + + removeBookmark (ev) { + this.bookmark?.destroy(); + this.closeBookmarkForm(ev); + } + + closeBookmarkForm (ev) { + ev.preventDefault(); + const evt = document.createEvent('Event'); + evt.initEvent('hide.bs.modal', true, true); + this.dispatchEvent(evt); + } +} + +api.elements.define('converse-muc-bookmark-form', MUCBookmarkForm); + +export default MUCBookmarkForm; diff --git a/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/bookmarks-list.js b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/bookmarks-list.js new file mode 100644 index 0000000..8c981d9 --- /dev/null +++ b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/bookmarks-list.js @@ -0,0 +1,48 @@ +import debounce from "lodash-es/debounce"; +import tplBookmarksList from './templates/list.js'; +import tplSpinner from "templates/spinner.js"; +import { CustomElement } from 'shared/components/element.js'; +import { Model } from '@converse/skeletor/src/model.js'; +import { _converse, api } from '@converse/headless/core.js'; +import { initStorage } from '@converse/headless/utils/storage.js'; + +import '../styles/bookmarks.scss'; + + +export default class BookmarksView extends CustomElement { + + async initialize () { + await api.waitUntil('bookmarksInitialized'); + const { bookmarks, chatboxes } = _converse; + + this.liveFilter = debounce((ev) => this.model.set({'filter_text': ev.target.value}), 100); + + this.listenTo(bookmarks, 'add', () => this.requestUpdate()); + this.listenTo(bookmarks, 'remove', () => this.requestUpdate()); + + this.listenTo(chatboxes, 'add', () => this.requestUpdate()); + this.listenTo(chatboxes, 'remove', () => this.requestUpdate()); + + const id = `converse.bookmarks-list-model-${_converse.bare_jid}`; + this.model = new Model({ id }); + initStorage(this.model, id); + + this.listenTo(this.model, 'change', () => this.requestUpdate()); + + this.model.fetch({ + 'success': () => this.requestUpdate(), + 'error': () => this.requestUpdate(), + }); + } + + render () { + return _converse.bookmarks && this.model ? tplBookmarksList(this) : tplSpinner(); + } + + clearFilter (ev) { + ev?.stopPropagation?.(); + this.model.set('filter_text', ''); + } +} + +api.elements.define('converse-bookmarks', BookmarksView); diff --git a/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/form.js b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/form.js new file mode 100644 index 0000000..39f2066 --- /dev/null +++ b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/form.js @@ -0,0 +1,37 @@ +import { html } from "lit"; +import { __ } from 'i18n'; + + +export default (el) => { + const name = el.model.getDisplayName(); + const nick = el.bookmark?.get('nick') ?? el.model.get('nick'); + + const i18n_heading = __('Bookmark for "%1$s"', name); + const i18n_autojoin = __('Would you like this groupchat to be automatically joined upon startup?'); + const i18n_remove = __('Remove'); + const i18n_name = __('The name for this bookmark:'); + const i18n_nick = __('What should your nickname for this groupchat be?'); + const i18n_submit = el.bookmark ? __('Update') : __('Save'); + + return html` + <form class="converse-form chatroom-form" @submit=${(ev) => el.onBookmarkFormSubmitted(ev)}> + <legend>${i18n_heading}</legend> + <fieldset class="form-group"> + <label for="converse_muc_bookmark_name">${i18n_name}</label> + <input class="form-control" type="text" value="${name}" name="name" required="required" id="converse_muc_bookmark_name"/> + </fieldset> + <fieldset class="form-group"> + <label for="converse_muc_bookmark_nick">${i18n_nick}</label> + <input class="form-control" type="text" name="nick" value="${nick || ''}" id="converse_muc_bookmark_nick"/> + </fieldset> + <fieldset class="form-group form-check"> + <input class="form-check-input" id="converse_muc_bookmark_autojoin" type="checkbox" ?checked=${el.bookmark?.get('autojoin')} name="autojoin"/> + <label class="form-check-label" for="converse_muc_bookmark_autojoin">${i18n_autojoin}</label> + </fieldset> + <fieldset class="form-group"> + <input class="btn btn-primary" type="submit" value="${i18n_submit}"> + ${el.bookmark ? html`<input class="btn btn-secondary button-remove" type="button" value="${i18n_remove}" @click=${(ev) => el.removeBookmark(ev)}>` : '' } + </fieldset> + </form> + `; +} diff --git a/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/item.js b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/item.js new file mode 100644 index 0000000..35cb566 --- /dev/null +++ b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/item.js @@ -0,0 +1,24 @@ +import { __ } from 'i18n'; +import { html } from "lit"; +import { openRoomViaEvent, removeBookmarkViaEvent } from '../../utils.js'; + +export default (bm) => { + const jid = bm.get('jid'); + const info_remove_bookmark = __('Unbookmark this groupchat'); + const open_title = __('Click to open this groupchat'); + return html` + <div class="list-item room-item available-chatroom d-flex flex-row" data-room-jid="${jid}"> + <a class="list-item-link open-room w-100" data-room-jid="${jid}" + title="${open_title}" + @click=${openRoomViaEvent}>${bm.getDisplayName()}</a> + + <a class="list-item-action remove-bookmark align-self-center ${ bm.get('bookmarked') ? 'button-on' : '' }" + data-room-jid="${jid}" + data-bookmark-name="${bm.getDisplayName()}" + title="${info_remove_bookmark}" + @click=${removeBookmarkViaEvent}> + <converse-icon class="fa fa-bookmark" size="1em"></converse-icon> + </a> + </div> + `; +} diff --git a/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/list.js b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/list.js new file mode 100644 index 0000000..94e42db --- /dev/null +++ b/roles/reverseproxy/files/conversejs/src/plugins/bookmark-views/components/templates/list.js @@ -0,0 +1,35 @@ +import bookmark_item from './item.js'; +import { __ } from 'i18n'; +import { _converse } from '@converse/headless/core.js'; +import { html } from "lit"; + +const filterBookmark = (b, text) => b.get('name')?.includes(text) || b.get('jid')?.includes(text); + +export default (el) => { + const i18n_placeholder = __('Filter'); + const filter_text = el.model.get('filter_text'); + const { bookmarks } = _converse; + const shown_bookmarks = filter_text ? bookmarks.filter(b => filterBookmark(b, filter_text)) : bookmarks; + + return html` + <form class="converse-form bookmarks-filter"> + <div class="btn-group w-100"> + <input + .value=${filter_text ?? ''} + @keydown="${ev => el.liveFilter(ev)}" + class="form-control" + placeholder="${i18n_placeholder}"/> + + <converse-icon size="1em" class="fa fa-times clear-input ${ !filter_text ? 'hidden' : '' }" + @click=${el.clearFilter}> + </converse-icon> + </div> + </form> + + <div class="list-container list-container--bookmarks"> + <div class="items-list bookmarks rooms-list"> + ${ shown_bookmarks.map(bm => bookmark_item(bm)) } + </div> + </div> + `; +} |