Merge pull request #1473 from SergeyMosin/compact-composer-plugin-v1.0.1

Compact composer plugin v1.0.1
This commit is contained in:
Maarten 2024-03-01 19:10:10 +01:00 committed by GitHub
commit 380eae6669
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 50 additions and 63 deletions

View file

@ -39,6 +39,7 @@
.squire-toolbar-svg-icon { .squire-toolbar-svg-icon {
display: block; display: block;
fill: var(--dialog-clr, #333);
} }
.squire2-mode-wysiwyg .squire-plain, .squire2-mode-wysiwyg .squire-plain,

View file

@ -6,7 +6,7 @@ class CompactComposerPlugin extends \RainLoop\Plugins\AbstractPlugin
NAME = 'Compact Composer', NAME = 'Compact Composer',
AUTHOR = 'Sergey Mosin', AUTHOR = 'Sergey Mosin',
URL = 'https://github.com/the-djmaze/snappymail/pull/1466', URL = 'https://github.com/the-djmaze/snappymail/pull/1466',
VERSION = '1.0.0', VERSION = '1.0.1',
RELEASE = '2024-02-23', RELEASE = '2024-02-23',
REQUIRED = '2.34.0', REQUIRED = '2.34.0',
LICENSE = 'AGPL v3', LICENSE = 'AGPL v3',
@ -14,7 +14,7 @@ class CompactComposerPlugin extends \RainLoop\Plugins\AbstractPlugin
public function Init(): void public function Init(): void
{ {
$this->addTemplate('templates/PopupsCompose.html'); $this->addTemplate('templates/PopupsCompactCompose.html');
$this->addCss('css/composer.css'); $this->addCss('css/composer.css');
$this->addJs('js/squire-raw.js'); $this->addJs('js/squire-raw.js');
$this->addJs('js/parsel.js'); $this->addJs('js/parsel.js');

View file

@ -1,16 +1,47 @@
/* eslint max-len: 0 */ /* eslint max-len: 0 */
(win => { (win => {
addEventListener('rl-view-model.create', e => { const rl = win.rl;
if (e.detail.viewModelTemplateID === 'PopupsCompose') {
// There is a better way to do this probably, if (!rl) {
// but we need this for drag and drop to work return;
e.detail.attachmentsArea = e.detail.bodyArea; }
}
rl.registerWYSIWYG('CompactComposer', (owner, container, onReady) => {
const editor = new CompactComposer(container);
onReady(editor);
}); });
const doc = win.document; const doc = win.document;
const rl = win.rl;
// If a user (or admin) selected the CompactComposer we need to
// replace PopupsCompose template with PopupsCompactCompose template.
// --
// This might break some plugins if they query/change PopupsCompose template
// before this code is called. They should instead listen for
// 'rl-view-model.create' to work properly.
if (rl.settings.get('editorWysiwyg') === 'CompactComposer') {
const compactTemplate = doc.getElementById('PopupsCompactCompose');
if (!compactTemplate) {
console.error('CompactComposer: PopupsCompactCompose template not found');
return;
}
const originalTemplate = doc.getElementById('PopupsCompose');
if (originalTemplate) {
originalTemplate.id = 'PopupsCompose_replaced';
} else {
console.warn('CompactComposer: PopupsCompose template not found');
}
compactTemplate.id = 'PopupsCompose';
addEventListener('rl-view-model.create', e => {
if (e.detail.viewModelTemplateID === 'PopupsCompose') {
// There is a better way to do this probably,
// but we need this for drag and drop to work
e.detail.attachmentsArea = e.detail.bodyArea;
}
});
}
const const
removeElements = 'HEAD,LINK,META,NOSCRIPT,SCRIPT,TEMPLATE,TITLE', removeElements = 'HEAD,LINK,META,NOSCRIPT,SCRIPT,TEMPLATE,TITLE',
@ -114,9 +145,6 @@
this.container = container; this.container = container;
toolbar.className = 'squire-toolbar btn-toolbar';
const actions = this.#makeActions(squire, toolbar);
plain.className = 'squire-plain'; plain.className = 'squire-plain';
wysiwyg.className = 'squire-wysiwyg'; wysiwyg.className = 'squire-wysiwyg';
wysiwyg.dir = 'auto'; wysiwyg.dir = 'auto';
@ -126,6 +154,9 @@
this.wysiwyg = wysiwyg; this.wysiwyg = wysiwyg;
this.toolbar = toolbar; this.toolbar = toolbar;
toolbar.className = 'squire-toolbar btn-toolbar';
const actions = this.#makeActions(squire, toolbar);
this.squire.addEventListener('willPaste', pasteSanitizer); this.squire.addEventListener('willPaste', pasteSanitizer);
this.squire.addEventListener('pasteImage', (e) => { this.squire.addEventListener('pasteImage', (e) => {
pasteImageHandler(e, squire); pasteImageHandler(e, squire);
@ -663,13 +694,13 @@
return indicators; return indicators;
case 'menu': case 'menu':
case 'menu_more': case 'menu_more':
const menuWrap = document.createElement('div'); const menuWrap = createElement('div');
menuWrap.className = 'btn-group dropdown squire-toolbar-menu-wrap'; menuWrap.className = 'btn-group dropdown squire-toolbar-menu-wrap';
menuWrap.title = item.label; menuWrap.title = item.label;
if (!item.showInPlainMode) { if (!item.showInPlainMode) {
menuWrap.className += ' squire-html-mode-item'; menuWrap.className += ' squire-html-mode-item';
} }
const menuBtn = document.createElement('a'); const menuBtn = createElement('button');
menuBtn.className = 'btn dropdown-toggle'; menuBtn.className = 'btn dropdown-toggle';
if (item.icon !== '') { if (item.icon !== '') {
menuBtn.innerHTML = item.icon; menuBtn.innerHTML = item.icon;
@ -680,7 +711,7 @@
} }
menuWrap.appendChild(menuBtn); menuWrap.appendChild(menuBtn);
const menu = document.createElement('ul'); const menu = createElement('ul');
menu.className = 'dropdown-menu squire-toolbar-menu'; menu.className = 'dropdown-menu squire-toolbar-menu';
if (item.rightEdge) { if (item.rightEdge) {
menu.className += ' right-edge'; menu.className += ' right-edge';
@ -956,12 +987,4 @@
} }
} }
} }
if (rl) {
rl.registerWYSIWYG('CompactComposer', (owner, container, onReady) => {
const editor = new CompactComposer(container);
onReady(editor);
});
}
})(window); })(window);

View file

@ -145,10 +145,10 @@
</a> </a>
</div> </div>
<div class="btn-group"> <div class="btn-group">
<a class="btn fontastic" style="padding-left: 10px; padding-right: 10px;" id="composeUploadButton" <button class="btn fontastic" id="composeUploadButton"
data-bind="visible: addAttachmentEnabled()" data-i18n="[title]COMPOSE/ATTACH_FILES"> data-bind="visible: addAttachmentEnabled()" data-i18n="[title]COMPOSE/ATTACH_FILES">
⁺📎 ⁺📎
</a> </button>
</div> </div>
</div> </div>
</div> </div>
@ -167,41 +167,6 @@
<div class="tab-content" role="tabpanel" aria-hidden="false" style="grid-column-end:3"> <div class="tab-content" role="tabpanel" aria-hidden="false" style="grid-column-end:3">
<div class="textAreaParent" data-bind="initDom: editorArea, attr:{spellcheck:allowSpellcheck()?'true':'false'}"></div> <div class="textAreaParent" data-bind="initDom: editorArea, attr:{spellcheck:allowSpellcheck()?'true':'false'}"></div>
</div> </div>
<!-- <input type="radio" name="tabs" value="attachments" id="tab-attachments" data-bind="checked: viewArea">-->
<!-- <label for="tab-attachments"-->
<!-- role="tab"-->
<!-- aria-selected="false"-->
<!-- aria-controls="panel2"-->
<!-- tabindex="0"-->
<!-- data-bind="-->
<!-- css: { 'btn-danger': attachmentsInErrorCount() },-->
<!-- tooltipErrorTip: attachmentsErrorTooltip">-->
<!-- <b data-bind="visible: attachmentsCount, text: attachmentsCount"></b>-->
<!-- <i data-bind="css: { 'icon-attachment': !attachmentsInProcessCount(), 'icon-spinner': attachmentsInProcessCount()}"></i>-->
<!-- <span data-i18n="GLOBAL/ATTACHMENTS"></span>-->
<!-- </label>-->
<!-- <div class="tab-content attachmentAreaParent" role="tabpanel" aria-hidden="true" style="grid-column-end:4">-->
<!-- <div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropVisible(), css: {dragAndDropOver: dragAndDropOver}"-->
<!-- data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></div>-->
<!-- <ul class="attachmentList" data-bind="foreach: attachments">-->
<!-- <li class="attachmentItem" data-bind="attr: { title: title }, css: { waiting: waiting, error: '' !== error() }">-->
<!-- <div class="attachmentIcon">-->
<!-- <i class="iconMain" data-bind="css: iconClass, visible: !uploading() || 0 === progress()"></i>-->
<!-- <div class="iconProgress" data-bind="attr: { style: progressStyle }, visible: uploading"></div>-->
<!-- <div class="iconBG" data-bind="text: progressText, visible: uploading"></div>-->
<!-- </div>-->
<!-- <div class="attachmentNameParent">-->
<!-- <a href="#" class="close pull-right" style="margin-top:-4px;" data-bind="click: cancel">×</a>-->
<!-- <div class="attachmentName" data-bind="text: fileName"></div>-->
<!-- <span class="attachmentSize" data-bind="text: friendlySize"></span>-->
<!-- </div>-->
<!-- </li>-->
<!-- </ul>-->
<!-- <div class="no-attachments-desc" data-bind="visible: 0 === attachments().length"-->
<!-- data-i18n="COMPOSE/NO_ATTACHMENTS_HERE_DESC"></div>-->
<!-- </div>-->
<input type="radio" name="tabs" value="mailvelope" id="tab-mailvelope" data-bind="checked: viewArea"> <input type="radio" name="tabs" value="mailvelope" id="tab-mailvelope" data-bind="checked: viewArea">
<label for="tab-mailvelope" <label for="tab-mailvelope"
role="tab" role="tab"
@ -219,8 +184,6 @@
<div class="attachmentAreaParent compact"> <div class="attachmentAreaParent compact">
<div class="b-attachment-place" data-bind="visible: addAttachmentEnabled(), css: {dragAndDropOver: dragAndDropVisible}" <div class="b-attachment-place" data-bind="visible: addAttachmentEnabled(), css: {dragAndDropOver: dragAndDropVisible}"
data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></div> data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></div>
<!-- <div class="b-attachment-place dragAndDropOver"-->
<!-- data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></div>-->
<ul class="attachmentList" data-bind="foreach: attachments"> <ul class="attachmentList" data-bind="foreach: attachments">
<li class="attachmentItem" data-bind="attr: { title: title }, css: { waiting: waiting, error: '' !== error() }"> <li class="attachmentItem" data-bind="attr: { title: title }, css: { waiting: waiting, error: '' !== error() }">
<div class="attachmentIcon"> <div class="attachmentIcon">