diff options
| author | Sébastien Theys <seb@odoo.com> | 2020-06-15 18:12:21 +0000 |
|---|---|---|
| committer | Sébastien Theys <seb@odoo.com> | 2020-06-15 18:12:21 +0000 |
| commit | 3fea5b2136627c1d7e83b2a5e111952fe3eb10a1 (patch) | |
| tree | 5eefad07972a87ce4689b83260f981bc87aadad4 /addons/mail/static/src/components/drop_zone | |
| parent | 0a82848606151ef60eb6523e9c4c161171f214e7 (diff) | |
[REF] mail, *: refactor messaging with OWL
This commit is a significant rewriting of client-side discuss, chatter,
chat window, and messaging menu using OWL. The behavior should be broadly
the same, with some slight functional changes here and there.
From a technical standpoint, the code of messaging is mainly organized in 2
main groups of modules:
- models, which are logical entities that depict the client-side state of
messaging as a whole.
- components, which are in charge of displaying information from models.
This refactoring also introduces new JS guidelines regarding folder structure
(/static) and naming rules for JS modules.
Community PR: https://github.com/odoo/odoo/pull/39023
Enterprise PR: https://github.com/odoo/enterprise/pull/6249
Task-1914207
This PR is a collaborative work by Alexandre, Julien, Sébastien and Xavier,
with the precious help of Lucas to speed it up towards the end.
closes odoo/odoo#39023
Related: odoo/enterprise#6249
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Co-authored-by: Alexandre Kühn <aku@odoo.com>
Co-authored-by: Julien Giannone <jgi@odoo.com>
Co-authored-by: Lucas Perais <lpe@odoo.com>
Co-authored-by: Sébastien Theys <seb@odoo.com>
Co-authored-by: Xavier Dubuc <xdu@odoo.com>
Diffstat (limited to 'addons/mail/static/src/components/drop_zone')
3 files changed, 177 insertions, 0 deletions
diff --git a/addons/mail/static/src/components/drop_zone/drop_zone.js b/addons/mail/static/src/components/drop_zone/drop_zone.js new file mode 100644 index 00000000000..2eb4dc8ef74 --- /dev/null +++ b/addons/mail/static/src/components/drop_zone/drop_zone.js @@ -0,0 +1,136 @@ +odoo.define('mail/static/src/components/drop_zone/drop_zone.js', function (require) { +'use strict'; + +const { Component, useState } = owl; + +class DropZone extends Component { + + /** + * @override + */ + constructor(...args) { + super(...args); + this.state = useState({ + /** + * Determine whether the user is dragging files over the dropzone. + * Useful to provide visual feedback in that case. + */ + isDraggingInside: false, + }); + /** + * Counts how many drag enter/leave happened on self and children. This + * ensures the drop effect stays active when dragging over a child. + */ + this._dragCount = 0; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Returns whether the given node is self or a children of self. + * + * @param {Node} node + * @returns {boolean} + */ + contains(node) { + return this.el.contains(node); + } + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Making sure that dragging content is external files. + * Ignoring other content dragging like text. + * + * @private + * @param {DataTransfer} dataTransfer + * @returns {boolean} + */ + _isDragSourceExternalFile(dataTransfer) { + const dragDataType = dataTransfer.types; + if (dragDataType.constructor === window.DOMStringList) { + return dragDataType.contains('Files'); + } + if (dragDataType.constructor === Array) { + return dragDataType.includes('Files'); + } + return false; + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Shows a visual drop effect when dragging inside the dropzone. + * + * @private + * @param {DragEvent} ev + */ + _onDragenter(ev) { + ev.preventDefault(); + if (this._dragCount === 0) { + this.state.isDraggingInside = true; + } + this._dragCount++; + } + + /** + * Hides the visual drop effect when dragging outside the dropzone. + * + * @private + * @param {DragEvent} ev + */ + _onDragleave(ev) { + this._dragCount--; + if (this._dragCount === 0) { + this.state.isDraggingInside = false; + } + } + + /** + * Prevents default (from the template) in order to receive the drop event. + * The drop effect cursor works only when set on dragover. + * + * @private + * @param {DragEvent} ev + */ + _onDragover(ev) { + ev.preventDefault(); + ev.dataTransfer.dropEffect = 'copy'; + } + + /** + * Triggers the `o-dropzone-files-dropped` event when new files are dropped + * on the dropzone, and then removes the visual drop effect. + * + * The parents should handle this event to process the files as they wish, + * such as uploading them. + * + * @private + * @param {DragEvent} ev + */ + _onDrop(ev) { + ev.preventDefault(); + if (this._isDragSourceExternalFile(ev.dataTransfer)) { + this.trigger('o-dropzone-files-dropped', { + files: ev.dataTransfer.files, + }); + } + this.state.isDraggingInside = false; + } + +} + +Object.assign(DropZone, { + props: {}, + template: 'mail.DropZone', +}); + +return DropZone; + +}); diff --git a/addons/mail/static/src/components/drop_zone/drop_zone.scss b/addons/mail/static/src/components/drop_zone/drop_zone.scss new file mode 100644 index 00000000000..e1a901cb12e --- /dev/null +++ b/addons/mail/static/src/components/drop_zone/drop_zone.scss @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------ +// Layout +// ------------------------------------------------------------------ + +.o_DropZone { + display: flex; + position: absolute; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + z-index: 1; + align-items: center; + justify-content: center; +} + +// ------------------------------------------------------------------ +// Style +// ------------------------------------------------------------------ + +.o_DropZone { + color: $o-enterprise-primary-color; + background: rgba(255, 255, 255, 0.9); + border: 2px dashed $o-enterprise-primary-color; + + &.o-dragging-inside { + border-width: 5px; + } +} diff --git a/addons/mail/static/src/components/drop_zone/drop_zone.xml b/addons/mail/static/src/components/drop_zone/drop_zone.xml new file mode 100644 index 00000000000..b3db940fde9 --- /dev/null +++ b/addons/mail/static/src/components/drop_zone/drop_zone.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates xml:space="preserve"> + + <t t-name="mail.DropZone" owl="1"> + <div class="o_DropZone" t-att-class="{ 'o-dragging-inside': state.isDraggingInside }" t-on-dragenter="_onDragenter" t-on-dragleave="_onDragleave" t-on-dragover="_onDragover" t-on-drop="_onDrop"> + <h4> + Drag Files Here <i class="fa fa-download"/> + </h4> + </div> + </t> + +</templates> |
