[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
This commit is contained in:
@@ -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.<number, import("models").Attachment>} */
|
||||
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();
|
||||
|
||||
@@ -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) {}
|
||||
Reference in New Issue
Block a user