Skip to content

Commit

Permalink
[MIG] fs_image: Migration to 17.0
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyenminhchien committed Apr 9, 2024
1 parent 733d32e commit 2f19161
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 53 deletions.
1 change: 1 addition & 0 deletions fs_image/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ Contributors
------------

- Laurent Mignon <laurent.mignon@acsone.eu>
- Nguyen Minh Chien <chien@trobz.com>

Maintainers
-----------
Expand Down
4 changes: 2 additions & 2 deletions fs_image/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"name": "Fs Image",
"summary": """
Field to store images into filesystem storages""",
"version": "16.0.1.0.3",
"version": "17.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/storage",
"depends": ["fs_file"],
"depends": ["fs_file", "web"],
"data": [],
"demo": [],
"maintainers": ["lmignon"],
Expand Down
4 changes: 2 additions & 2 deletions fs_image/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,15 @@ def _set_image_process_mode(self):
finally:
self._image_process_mode = False

def _process_related(self, value: FSImageValue):
def _process_related(self, value: FSImageValue, env):
"""Override to resize the related value before saving it on self."""
if not value:
return None

Check warning on line 208 in fs_image/fields.py

View check run for this annotation

Codecov / codecov/patch

fs_image/fields.py#L208

Added line #L208 was not covered by tests
if self.readonly and not self.max_width and not self.max_height:
# no need to process images for computed fields, or related fields
# without max_width/max_height
return value

Check warning on line 212 in fs_image/fields.py

View check run for this annotation

Codecov / codecov/patch

fs_image/fields.py#L212

Added line #L212 was not covered by tests
value = super()._process_related(value)
value = super()._process_related(value, env)
new_value = BytesIO(self._image_process(value))
return FSImageValue(value=new_value, alt_text=value.alt_text, name=value.name)

Expand Down
1 change: 1 addition & 0 deletions fs_image/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- Laurent Mignon \<<laurent.mignon@acsone.eu>\>
- Nguyen Minh Chien \<<chien@trobz.com>\>
2 changes: 1 addition & 1 deletion fs_image/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down Expand Up @@ -582,6 +581,7 @@ <h2><a class="toc-backref" href="#toc-entry-8">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-9">Contributors</a></h2>
<ul class="simple">
<li>Laurent Mignon &lt;<a class="reference external" href="mailto:laurent.mignon&#64;acsone.eu">laurent.mignon&#64;acsone.eu</a>&gt;</li>
<li>Nguyen Minh Chien &lt;<a class="reference external" href="mailto:chien&#64;trobz.com">chien&#64;trobz.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
4 changes: 2 additions & 2 deletions fs_image/static/src/views/dialogs/alttext_dialog.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="fs_image.AltTextDialog" owl="1">
<t t-name="fs_image.AltTextDialog">
<Dialog size="'md'" title="props.title">
<div class="form-group row">
<t t-if="props.readonly">
Expand All @@ -16,7 +16,7 @@
/>
</div>
</div>
<t t-set-slot="footer" owl="1">
<t t-set-slot="footer">
<button
class="btn btn-primary"
t-ref="btn-confirm"
Expand Down
75 changes: 36 additions & 39 deletions fs_image/static/src/views/fields/fsimage_field.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,83 +7,74 @@ import {
ImageField,
fileTypeMagicWordMap,
imageCacheKey,
imageField,
} from "@web/views/fields/image/image_field";
import {onWillUpdateProps, useState} from "@odoo/owl";

import {AltTextDialog} from "../dialogs/alttext_dialog.esm";
import {_t} from "@web/core/l10n/translation";
import {registry} from "@web/core/registry";
import {url} from "@web/core/utils/urls";
import {useService} from "@web/core/utils/hooks";
import {url as utilUrl} from "@web/core/utils/urls";

const placeholder = "/web/static/img/placeholder.png";

export class FSImageField extends ImageField {
setup() {
// Call super.setup() to initialize the state
super.setup();
this.state = useState({
...this.props.value,
...this.state,
});
onWillUpdateProps((nextProps) => {
this.state.isUploading = false;
const {filename, mimetype, alt_text, url} = nextProps.value || {};
this.state.filename = filename;
this.state.mimetype = mimetype;
this.state.url = url;
this.state.alt_text = alt_text;
});
super.setup(...arguments);
this.dialogService = useService("dialog");
}

getUrl(previewFieldName) {
if (
this.state.isValid &&
this.props.value &&
typeof this.props.value === "object"
this.props.record.data[this.props.name] &&
typeof this.props.record.data[this.props.name] === "object"
) {
// Check if value is a dict
if (this.props.value.content) {
if (this.props.record.data[this.props.name].content) {
// We use the binary content of the value
// Use magic-word technique for detecting image type
const magic =
fileTypeMagicWordMap[this.props.value.content[0]] || "png";
return `data:image/${magic};base64,${this.props.value.content}`;
fileTypeMagicWordMap[
this.props.record.data[this.props.name].content[0]
] || "png";
return `data:image/${magic};base64,${
this.props.record.data[this.props.name].content
}`;
}
const model = this.props.record.resModel;
const id = this.props.record.resId;
let base_url = this.props.value.url;
let base_url = this.props.record.data[this.props.name].url;
if (id !== undefined && id !== null && id !== false) {
const field = previewFieldName;
const filename = this.props.value.filename;
const filename = this.props.record.data[this.props.name].filename;
base_url = `/web/image/${model}/${id}/${field}/${filename}`;
}
return url(base_url, {unique: imageCacheKey(this.rawCacheKey)});
return utilUrl(base_url, {unique: imageCacheKey(this.rawCacheKey)});
}
return placeholder;
}

get hasTooltip() {
return this.props.enableZoom && !this.props.isDebugMode && this.props.value;
}

onFileUploaded(info) {
this.state.isValid = true;
this.props.update({
filename: info.name,
content: info.data,
async onFileUploaded(info) {
this.props.record.update({
[this.props.name]: {
filename: info.name,
content: info.data,
},
});
}
onAltTextEdit() {
const self = this;
const altText = this.props.value.alt_text || "";
const altText = this.props.record.data[this.props.name].alt_text || "";
const dialogProps = {
title: this.env._t("Alt Text"),
title: _t("Alt Text"),
altText: altText,
confirm: (value) => {
self.props.update({
...self.props.value,
alt_text: value,
self.props.record.update({
[self.props.name]: {
...this.props.record.data[this.props.name],
alt_text: value,
},
});
},
};
Expand All @@ -92,4 +83,10 @@ export class FSImageField extends ImageField {
}

FSImageField.template = "fs_image.FSImageField";
registry.category("fields").add("fs_image", FSImageField);

export const fSImageField = {
...imageField,
component: FSImageField,
};

registry.category("fields").add("fs_image", fSImageField);
14 changes: 7 additions & 7 deletions fs_image/static/src/views/fields/fsimage_field.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="fs_image.FSImageField" owl="1">
<t t-name="fs_image.FSImageField">
<div class="d-inline-block position-relative opacity-trigger-hover">
<div
t-attf-class="position-absolute d-flex justify-content-between w-100 bottom-0 opacity-0 opacity-100-hover {{isMobile ? 'o_mobile_controls' : ''}}"
Expand All @@ -13,7 +13,6 @@
acceptedFileExtensions="props.acceptedFileExtensions"
t-key="props.record.resId"
onUploaded.bind="onFileUploaded"
type="'image'"
>
<t t-set-slot="toggler">
<button
Expand All @@ -25,16 +24,16 @@
</button>
</t>
<button
t-if="props.value and state.isValid"
class="o_clear_file_button btn btn-light border-0 rounded-circle m-1 p-1"
t-if="props.record.data[props.name] and state.isValid"
class="o_add_alter_text_button btn btn-light border-0 rounded-circle m-1 p-1"
data-tooltip="Alt Text"
aria-label="Set Alt Text"
t-on-click="onAltTextEdit"
>
<i class="fa fa-blind fa-fw" />
</button>
<button
t-if="props.value and state.isValid"
t-if="props.record.data[props.name] and state.isValid"
class="o_clear_file_button btn btn-light border-0 rounded-circle m-1 p-1"
data-tooltip="Clear"
aria-label="Clear"
Expand All @@ -46,7 +45,8 @@
</t>
</div>
<img
class="img img-fluid w-100"
loading="lazy"
class="img img-fluid"
alt="Binary file"
t-att-src="this.getUrl(props.previewImage or props.name)"
t-att-name="props.name"
Expand All @@ -55,7 +55,7 @@
t-att-style="sizeStyle"
t-att-alt="props.alt"
t-on-error.stop="onLoadFailed"
t-att-data-tooltip-template="hasTooltip and tooltipAttributes.template"
t-att-data-tooltip-template="hasTooltip and tooltipAttributes.template or ''"
t-att-data-tooltip-info="hasTooltip and tooltipAttributes.info"
t-att-data-tooltip-delay="hasTooltip and props.zoomDelay"
/>
Expand Down

0 comments on commit 2f19161

Please sign in to comment.