[FIX] website: add support for svg logo in configurator
The configurator's palette selection screen didn't support SVG logo. On SVG upload primary and secondary colors couldn't be extracted and no palette was recommended. It comes from the fact that Python PIL library does not support SVG. We therefore had to convert SVG to PNG before trying to extract primary and secondary colors. A file format checking has been added. If the uplodad file is not an image, a notification is displayed to the user. task-2602521 closes odoo/odoo#76400 X-original-commit: 33f43618f727bdc1239c52c66b73f0f436035774 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -307,7 +307,7 @@ class Website(models.Model):
|
||||
@api.model
|
||||
def configurator_init(self):
|
||||
r = dict()
|
||||
company_id = self.get_current_website().company_id
|
||||
company = self.get_current_website().company_id
|
||||
configurator_features = self.env['website.configurator.feature'].search([])
|
||||
r['features'] = [{
|
||||
'id': feature.id,
|
||||
@@ -319,8 +319,8 @@ class Website(models.Model):
|
||||
'module_state': feature.module_id.state,
|
||||
} for feature in configurator_features]
|
||||
r['logo'] = False
|
||||
if company_id.logo and company_id.logo != company_id._get_logo():
|
||||
r['logo'] = company_id.logo.decode('utf-8')
|
||||
if company.logo and company.logo != company._get_logo():
|
||||
r['logo'] = company.logo.decode('utf-8')
|
||||
try:
|
||||
result = self._website_api_rpc('/api/website/1/configurator/industries', {'lang': self.env.user.lang})
|
||||
r['industries'] = result['industries']
|
||||
@@ -470,10 +470,18 @@ class Website(models.Model):
|
||||
tour_asset_id = self.env.ref('website.configurator_tour')
|
||||
tour_asset_id.copy({'key': tour_asset_id.key, 'website_id': website.id, 'active': True})
|
||||
|
||||
# logo was generated as base64 url
|
||||
logo = kwargs.get('logo')
|
||||
if logo:
|
||||
website.logo = logo.split(',', 1)[1]
|
||||
# Set logo from generated attachment or from company's logo
|
||||
logo_attachment_id = kwargs.get('logo_attachment_id')
|
||||
company = website.company_id
|
||||
if logo_attachment_id:
|
||||
attachment = self.env['ir.attachment'].browse(logo_attachment_id)
|
||||
attachment.write({
|
||||
'res_model': 'website',
|
||||
'res_field': 'logo',
|
||||
'res_id': website.id,
|
||||
})
|
||||
elif not logo_attachment_id and company.logo and company.logo != company._get_logo():
|
||||
website.logo = company.logo.decode('utf-8')
|
||||
|
||||
# palette
|
||||
palette = kwargs.get('selected_palette')
|
||||
|
||||
@@ -6,6 +6,8 @@ import weUtils from 'web_editor.utils';
|
||||
import session from 'web.session';
|
||||
import {ColorpickerWidget} from 'web.Colorpicker';
|
||||
import {_t, _lt} from 'web.core';
|
||||
import {svgToPNG} from 'website.utils';
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
|
||||
const {Component, Store, mount, QWeb} = owl;
|
||||
const {useDispatch, useStore, useGetters, useRef} = owl.hooks;
|
||||
@@ -189,6 +191,7 @@ class PaletteSelectionScreen extends Component {
|
||||
this.getters = useGetters();
|
||||
this.dispatch = useDispatch();
|
||||
this.logoInputRef = useRef('logoSelectionInput');
|
||||
this.notification = useService("notification");
|
||||
}
|
||||
|
||||
mounted() {
|
||||
@@ -206,13 +209,32 @@ class PaletteSelectionScreen extends Component {
|
||||
if (logoSelectInput.files.length === 1) {
|
||||
const file = logoSelectInput.files[0];
|
||||
const data = await utils.getDataURLFromFile(file);
|
||||
this.dispatch('changeLogo', data);
|
||||
this.updatePalettes();
|
||||
const attachment = await this.rpc({
|
||||
route: '/web_editor/attachment/add_data',
|
||||
params: {
|
||||
name: 'logo',
|
||||
data: data.split(',')[1],
|
||||
is_image: true,
|
||||
}
|
||||
});
|
||||
if (!attachment.error) {
|
||||
this.dispatch('changeLogo', data, attachment.id);
|
||||
this.updatePalettes();
|
||||
} else {
|
||||
this.notification.notify({
|
||||
title: file.name,
|
||||
message: attachment.error,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async updatePalettes() {
|
||||
let img = this.state.logo.split(',', 2)[1];
|
||||
let img = this.state.logo;
|
||||
if (img.startsWith('data:image/svg+xml')) {
|
||||
img = await svgToPNG(img);
|
||||
}
|
||||
img = img.split(',')[1];
|
||||
const [color1, color2] = await rpc.query({
|
||||
model: 'base.document.layout',
|
||||
method: 'extract_image_primary_secondary_colors',
|
||||
@@ -376,8 +398,9 @@ const actions = {
|
||||
state.selectedIndustry = {id, label};
|
||||
}
|
||||
},
|
||||
changeLogo({state}, data) {
|
||||
changeLogo({state}, data, attachmentId) {
|
||||
state.logo = data;
|
||||
state.logoAttachmentId = attachmentId;
|
||||
},
|
||||
selectPalette({state}, paletteName) {
|
||||
if (paletteName === 'recommendedPalette') {
|
||||
@@ -472,6 +495,7 @@ async function getInitialState() {
|
||||
palettes: palettes,
|
||||
features: features,
|
||||
themes: [],
|
||||
logoAttachmentId: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -508,12 +532,12 @@ async function applyConfigurator(self, themeName) {
|
||||
}
|
||||
const data = {
|
||||
selected_features: selectedFeatures,
|
||||
logo: self.state.logo,
|
||||
industry_id: self.state.selectedIndustry.id,
|
||||
selected_palette: selectedPalette,
|
||||
theme_name: themeName,
|
||||
website_purpose: WEBSITE_PURPOSES[self.state.selectedPurpose].name,
|
||||
website_type: WEBSITE_TYPES[self.state.selectedType].name,
|
||||
logo_attachment_id: self.state.logoAttachmentId,
|
||||
};
|
||||
const resp = await rpc.query({
|
||||
model: 'website',
|
||||
@@ -540,6 +564,7 @@ async function makeEnvironment() {
|
||||
recommendedPalette: store.state.recommendedPalette,
|
||||
features: store.state.features,
|
||||
logo: store.state.logo,
|
||||
logoAttachmentId: store.state.logoAttachmentId,
|
||||
};
|
||||
window.sessionStorage.setItem(SESSION_STORAGE_ITEM_NAME, JSON.stringify(newState));
|
||||
});
|
||||
@@ -553,7 +578,8 @@ async function makeEnvironment() {
|
||||
env.loader = qweb.renderToString('website.ThemePreview.Loader', {
|
||||
showTips: true
|
||||
});
|
||||
return Object.assign(env, {router, store, qweb});
|
||||
const services = Component.env.services;
|
||||
return Object.assign(env, {router, store, qweb, services});
|
||||
}
|
||||
|
||||
async function setup() {
|
||||
|
||||
Reference in New Issue
Block a user