From 62ca95f0fdfa0c5ff7921334b684d3e199cf41c7 Mon Sep 17 00:00:00 2001 From: abd-msyukyu-odoo Date: Fri, 15 Sep 2023 12:17:31 +0200 Subject: [PATCH] [IMP] mail, web: create FileModelMixin for FileViewer Extract basic props needed by the `FileViewer` for `files` instances in a reusable `Mixin`. task-3172056 Part-of: odoo/odoo#127021 --- .../src/core/common/attachment_model.js | 123 +--------------- .../static/src/core/file_viewer/file_model.js | 133 ++++++++++++++++++ 2 files changed, 135 insertions(+), 121 deletions(-) create mode 100644 addons/web/static/src/core/file_viewer/file_model.js diff --git a/addons/mail/static/src/core/common/attachment_model.js b/addons/mail/static/src/core/common/attachment_model.js index d5483d5c249..fbff4c4df68 100644 --- a/addons/mail/static/src/core/common/attachment_model.js +++ b/addons/mail/static/src/core/common/attachment_model.js @@ -4,9 +4,9 @@ import { Record } from "@mail/core/common/record"; import { assignDefined } from "@mail/utils/common/misc"; import { deserializeDateTime } from "@web/core/l10n/dates"; -import { url } from "@web/core/utils/urls"; +import { FileModelMixin } from "@web/core/file_viewer/file_model"; -export class Attachment extends Record { +export class Attachment extends FileModelMixin(Record) { static id = "id"; /** @type {Object.} */ static records = {}; @@ -61,22 +61,8 @@ export class Attachment extends Record { } } - accessToken; - checksum; - extension; - filename; - id; - mimetype; - name; originThread = Record.one("Thread"); res_name; - type; - /** @type {string} */ - tmpUrl; - /** @type {string} */ - url; - /** @type {boolean} */ - uploading; message = Record.one("Message"); /** @type {string} */ create_date; @@ -85,25 +71,6 @@ export class Attachment extends Record { return true; } - get displayName() { - return this.name || this.filename; - } - - get isText() { - const textMimeType = [ - "application/javascript", - "application/json", - "text/css", - "text/html", - "text/plain", - ]; - return textMimeType.includes(this.mimetype); - } - - get isPdf() { - return this.mimetype && this.mimetype.startsWith("application/pdf"); - } - get monthYear() { if (!this.create_date) { return undefined; @@ -111,92 +78,6 @@ export class Attachment extends Record { const datetime = deserializeDateTime(this.create_date); return `${datetime.monthLong}, ${datetime.year}`; } - - get isImage() { - const imageMimetypes = [ - "image/bmp", - "image/gif", - "image/jpeg", - "image/png", - "image/svg+xml", - "image/tiff", - "image/x-icon", - "image/webp", - ]; - return imageMimetypes.includes(this.mimetype); - } - - get isUrl() { - return this.type === "url" && this.url; - } - - get isUrlYoutube() { - return !!this.url && this.url.includes("youtu"); - } - - get isVideo() { - const videoMimeTypes = ["audio/mpeg", "video/x-matroska", "video/mp4", "video/webm"]; - return videoMimeTypes.includes(this.mimetype); - } - - get isViewable() { - return ( - (this.isText || this.isImage || this.isVideo || this.isPdf || this.isUrlYoutube) && - !this.uploading - ); - } - - get defaultSource() { - const route = url(this.urlRoute, this.urlQueryParams); - const encodedRoute = encodeURIComponent(route); - if (this.isPdf) { - return `/web/static/lib/pdfjs/web/viewer.html?file=${encodedRoute}#pagemode=none`; - } - if (this.isUrlYoutube) { - const urlArr = this.url.split("/"); - let token = urlArr[urlArr.length - 1]; - if (token.includes("watch")) { - token = token.split("v=")[1]; - const amp = token.indexOf("&"); - if (amp !== -1) { - token = token.substring(0, amp); - } - } - return `https://www.youtube.com/embed/${token}`; - } - return route; - } - - get downloadUrl() { - return url(this.urlRoute, { ...this.urlQueryParams, download: true }); - } - - /** - * @returns {string} - */ - get urlRoute() { - if (this.uploading && this.tmpUrl) { - return this.tmpUrl; - } - return this.isImage ? `/web/image/${this.id}` : `/web/content/${this.id}`; - } - - /** - * @returns {Object} - */ - get urlQueryParams() { - if (this.uploading && this.tmpUrl) { - return {}; - } - return assignDefined( - {}, - { - access_token: this.accessToken || undefined, - filename: this.name || undefined, - unique: this.checksum || undefined, - } - ); - } } Attachment.register(); diff --git a/addons/web/static/src/core/file_viewer/file_model.js b/addons/web/static/src/core/file_viewer/file_model.js new file mode 100644 index 00000000000..058ecfea517 --- /dev/null +++ b/addons/web/static/src/core/file_viewer/file_model.js @@ -0,0 +1,133 @@ +/* @odoo-module */ + +import { url } from "@web/core/utils/urls"; + +export const FileModelMixin = T => class extends T { + accessToken; + checksum; + extension; + filename; + id; + mimetype; + name; + type; + /** @type {string} */ + tmpUrl; + /** @type {string} */ + url; + /** @type {boolean} */ + uploading; + + get defaultSource() { + const route = url(this.urlRoute, this.urlQueryParams); + const encodedRoute = encodeURIComponent(route); + if (this.isPdf) { + return `/web/static/lib/pdfjs/web/viewer.html?file=${encodedRoute}#pagemode=none`; + } + if (this.isUrlYoutube) { + const urlArr = this.url.split("/"); + let token = urlArr[urlArr.length - 1]; + if (token.includes("watch")) { + token = token.split("v=")[1]; + const amp = token.indexOf("&"); + if (amp !== -1) { + token = token.substring(0, amp); + } + } + return `https://www.youtube.com/embed/${token}`; + } + return route; + } + + get displayName() { + return this.name || this.filename; + } + + get downloadUrl() { + return url(this.urlRoute, { ...this.urlQueryParams, download: true }); + } + + get isImage() { + const imageMimetypes = [ + "image/bmp", + "image/gif", + "image/jpeg", + "image/png", + "image/svg+xml", + "image/tiff", + "image/x-icon", + "image/webp", + ]; + return imageMimetypes.includes(this.mimetype); + } + + get isPdf() { + return this.mimetype && this.mimetype.startsWith("application/pdf"); + } + + get isText() { + const textMimeType = [ + "application/javascript", + "application/json", + "text/css", + "text/html", + "text/plain", + ]; + return textMimeType.includes(this.mimetype); + } + + get isUrl() { + return this.type === "url" && this.url; + } + + get isUrlYoutube() { + return !!this.url && this.url.includes("youtu"); + } + + get isVideo() { + const videoMimeTypes = ["audio/mpeg", "video/x-matroska", "video/mp4", "video/webm"]; + return videoMimeTypes.includes(this.mimetype); + } + + get isViewable() { + return ( + (this.isText || this.isImage || this.isVideo || this.isPdf || this.isUrlYoutube) && + !this.uploading + ); + } + + /** + * @returns {Object} + */ + get urlQueryParams() { + if (this.uploading && this.tmpUrl) { + return {}; + } + const params = { + access_token: this.accessToken, + filename: this.name, + unique: this.checksum, + }; + for (const prop in params) { + if (!params[prop]) { + delete params[prop]; + } + } + return params; + } + + /** + * @returns {string} + */ + get urlRoute() { + if (this.isUrl) { + return this.url; + } + if (this.uploading && this.tmpUrl) { + return this.tmpUrl; + } + return this.isImage ? `/web/image/${this.id}` : `/web/content/${this.id}`; + } +} + +export class FileModel extends FileModelMixin(Object) {}