[FIX] web_editor, web_unsplash: use preset colors on illustrations

Since [1] when the media dialog was rewritten, the illustrations
thumbnails were not using the preset colors.

[2] did partially implement the solution: the updated images with the
right colors were not replaced in the DOM.

This commit continues what [2] started and displays the illustration
thumbnails with the preset colors.
It also assigns a media type to all fetched images.

[1]: https://github.com/odoo/odoo/commit/7fd0698cf765a79959566b51e33cb76bff83d344
[2]: https://github.com/odoo/odoo/commit/f2111cb37a572fe1ffd9b303c4abcbb7fe1d67cd

task-3060679

closes odoo/odoo#118556

X-original-commit: 75cc46c4f784edb1fb7404956e1cfdf6fae6a83c
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Benoit Socias
2023-04-14 11:49:25 +02:00
committed by qsm-odoo
parent 23b2486666
commit f9435feb39
3 changed files with 22 additions and 4 deletions
@@ -209,6 +209,7 @@ export class FileSelector extends Component {
offset,
}
);
attachments.forEach(attachment => attachment.mediaType = 'attachment');
} catch (e) {
// Reading attachments as a portal user is not permitted and will raise
// an access error so we catch the error silently and don't return any
@@ -31,6 +31,11 @@ export class AutoResizeImage extends Attachment {
}
if (this.props.onLoaded) {
await this.props.onLoaded(this.image.el);
if (!this.image.el) {
// If replaced by colored version, aspect ratio will be
// computed on it instead.
return;
}
}
const aspectRatio = this.image.el.offsetWidth / this.image.el.offsetHeight;
const width = aspectRatio * this.props.minRowHeight;
@@ -170,6 +175,7 @@ export class ImageSelector extends FileSelector {
);
this.state.isFetchingLibrary = false;
const media = (response.media || []).slice(0, this.NUMBER_OF_MEDIA_TO_DISPLAY);
media.forEach(record => record.mediaType = 'libraryMedia');
return { media, results: response.results };
} catch {
// Either API endpoint doesn't exist or is misconfigured.
@@ -276,8 +282,12 @@ export class ImageSelector extends FileSelector {
async onImageLoaded(imgEl, attachment) {
this.debouncedScroll();
if (attachment.mediaType === 'libraryMedia') {
if (attachment.mediaType === 'libraryMedia' && !imgEl.src.startsWith('blob')) {
// This call applies the theme's color palette to the
// loaded illustration. Upon replacement of the image,
// `onImageLoad` is called again, but the replacement image
// has an URL that starts with 'blob'. The condition above
// uses this to avoid an infinite loop.
await this.onLibraryImageLoaded(imgEl, attachment);
}
}
@@ -295,14 +305,20 @@ export class ImageSelector extends FileSelector {
try {
const response = await fetch(mediaUrl);
if (response.headers.get('content-type') === 'image/svg+xml') {
const svg = await response.text();
let svg = await response.text();
const dynamicColors = {};
const combinedColorsRegex = new RegExp(Object.values(DEFAULT_PALETTE).join('|'), 'gi');
svg.replace(combinedColorsRegex, match => {
svg = svg.replace(combinedColorsRegex, match => {
const colorId = Object.keys(DEFAULT_PALETTE).find(key => DEFAULT_PALETTE[key] === match.toUpperCase());
const colorKey = 'c' + colorId
dynamicColors[colorKey] = getCSSVariableValue('o-color-' + colorId);
return dynamicColors[colorKey];
});
const fileName = mediaUrl.split('/').pop();
const file = new File([svg], fileName, {
type: "image/svg+xml",
});
imgEl.src = URL.createObjectURL(file);
if (Object.keys(dynamicColors).length) {
media.isDynamicSVG = true;
media.dynamicColors = dynamicColors;
@@ -134,6 +134,7 @@ patch(ImageSelector.prototype, 'image_selector_unsplash', {
url.searchParams.delete('w');
return Object.assign({}, record, {
url: url.toString(),
mediaType: 'unsplashRecord',
});
});
return { isMaxed, records };