summaryrefslogtreecommitdiff
path: root/addons/web_unsplash/static
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2018-11-29 18:24:11 +0000
committerqsm-odoo <qsm@odoo.com>2018-12-04 11:17:23 +0000
commit78a30d44cf8f1ce0d4d3fc53481a87eebeaea088 (patch)
tree998def9a2fa63f84167501960dca2c30d2c3ec44 /addons/web_unsplash/static
parent1f847a1e2eed63086448ceb451bd1a2f87c8c641 (diff)
[REF] web_editor, web_unsplash: review load more feature
* Simplify the code * Make the feature mork without unsplash * Handle corner cases task-1896705
Diffstat (limited to 'addons/web_unsplash/static')
-rw-r--r--addons/web_unsplash/static/src/js/unsplash_image_widget.js236
-rw-r--r--addons/web_unsplash/static/src/js/unsplashapi.js7
-rw-r--r--addons/web_unsplash/static/src/xml/unsplash_image_widget.xml28
3 files changed, 135 insertions, 136 deletions
diff --git a/addons/web_unsplash/static/src/js/unsplash_image_widget.js b/addons/web_unsplash/static/src/js/unsplash_image_widget.js
index afd0e1ebad5..4338b7d6dd0 100644
--- a/addons/web_unsplash/static/src/js/unsplash_image_widget.js
+++ b/addons/web_unsplash/static/src/js/unsplash_image_widget.js
@@ -4,7 +4,6 @@ odoo.define('web_unsplash.image_widgets', function (require) {
var core = require('web.core');
var UnsplashAPI = require('unsplash.api');
var weWidgets = require('web_editor.widget');
-var QWeb = core.qweb;
var unsplashAPI = null;
@@ -16,32 +15,35 @@ weWidgets.ImageWidget.include({
'dblclick .unsplash_img_container [data-imgid]': '_onUnsplashImgDblClick',
'click .unsplash_img_container [data-imgid]': '_onUnsplashImgClick',
'click button.save_unsplash': '_onSaveUnsplash',
- 'click button.access_key': '_onSetAccessKey',
- 'click .o_load_more': '_onLoadMore',
- 'click .o_search_from_unsplash': '_onSearchFromUnsplash',
- 'click .o_search_an_image': '_onSearchImage',
- 'keyup input#icon-search, .o_dropdown_search': '_onPressKeySearch',
+ 'click .o_search_an_image, .o_search_from_unsplash': '_onSourceSwitchClick',
+ 'keyup .o_we_search, .o_search_an_image, .o_search_from_unsplash': '_onPressKeySearch',
}),
/**
* @override
*/
init: function () {
+ this._super.apply(this, arguments);
+
this._unsplash = {
+ isActive: false,
selectedImages: {},
isMaxed: false,
query: false,
+ error: false,
};
- // TODO This is a `hack` to prevent the UnsplashAPI to be destroyed every time
- // the media dialog is closed.
- // Indeed, UnsplashAPI has a cache system to recude unsplash call, it is
- // then better to keep its state to benefic from it from one media dialog
- // call to another.
- // Unsplash API will either be (it's still being discussed):
- // * a service (ideally coming with an improvement to not auto load the service)
- // * initialized in the website_root (trigger_up)
- var def = this._super.apply(this, arguments);
+ // TODO improve this
+ //
+ // This is a `hack` to prevent the UnsplashAPI to be destroyed every
+ // time the media dialog is closed. Indeed, UnsplashAPI has a cache
+ // system to recude unsplash call, it is then better to keep its state
+ // to take advantage from it from one media dialog call to another.
+ //
+ // Unsplash API will either be (it's still being discussed):
+ // * a service (ideally coming with an improvement to not auto load
+ // the service)
+ // * initialized in the website_root (trigger_up)
if (unsplashAPI === null) {
this.unsplashAPI = new UnsplashAPI(this);
unsplashAPI = this.unsplashAPI;
@@ -49,8 +51,19 @@ weWidgets.ImageWidget.include({
this.unsplashAPI = unsplashAPI;
this.unsplashAPI.setParent(this);
}
- return def;
},
+ /**
+ * @override
+ */
+ start: function () {
+ if (!this.options.document) {
+ this.$('.o_we_search_icon').replaceWith(core.qweb.render('web_unsplash.dialog.media.search_icon'));
+ }
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
destroy: function () {
// TODO See `hack` explained in `init`. This prevent the media dialog destroy
// to destroy unsplashAPI when destroying the children
@@ -65,19 +78,6 @@ weWidgets.ImageWidget.include({
/**
* @override
*/
- getControlPanelConfig: function () {
- var config = this._super.apply(this, arguments);
- if (this._unsplash.query) {
- _.extend(config, {
- pagerLeftEnabled: this.page > 1,
- pagerRightEnabled: !this._unsplash.isMaxed,
- });
- }
- return config;
- },
- /**
- * @override
- */
save: function () {
if (!this._unsplash.query) {
return this._super.apply(this, arguments);
@@ -102,74 +102,102 @@ weWidgets.ImageWidget.include({
return _super.apply(self, args);
});
},
+ /**
+ * @override
+ */
+ search: function (needle, noRender) {
+ var self = this;
+ if (!this._unsplash.isActive) {
+ return this._super.apply(this, arguments);
+ }
+
+ this._unsplash.query = needle;
+ return this.unsplashAPI.getImages(needle, this.IMAGES_DISPLAYED_TOTAL).then(function (res) {
+ self._unsplash.isMaxed = res.isMaxed;
+ self._unsplash.records = res.images;
+ self._unsplash.error = false;
+ }, function (err) {
+ self._unsplash.error = err;
+ }).always(function () {
+ if (!noRender) {
+ self._renderImages();
+ self._adaptLoadMore();
+ }
+ });
+ },
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
- * Highlights selected image, when an image is clicked and when pager change
- *
* @private
*/
- _highlightSelectedImages: function () {
- var self = this;
- if (!this._unsplash.query) {
+ _adaptLoadMore: function () {
+ if (!this._unsplash.isActive) {
return this._super.apply(this, arguments);
}
- this.$('.o_unsplash_img_cell.o_selected').removeClass("o_selected");
- var $select = this.$('.o_unsplash_img_cell [data-imgid]').filter(function () {
- return $(this).data('imgid') in self._unsplash.selectedImages;
- });
- $select.closest('.o_unsplash_img_cell').addClass("o_selected");
- return $select;
+
+ this.$('.o_load_more').toggleClass('d-none', !!this._unsplash.error || this._unsplash.isMaxed);
+ this.$('.o_load_done_msg').toggleClass('d-none', !!this._unsplash.error || !this._unsplash.isMaxed);
},
/**
* @override
*/
- _renderImages: function () {
+ _highlightSelectedImages: function () {
var self = this;
- if (!this._unsplash.query) {
+ if (!this._unsplash.isActive) {
return this._super.apply(this, arguments);
}
- this.unsplashAPI.getImages(this._unsplash.query, this.IMAGES_PER_PAGE, this.page).then(function (res) {
- self._unsplash.isMaxed = res.isMaxed;
- var rows = _(res.images).chain()
- .groupBy(function (a, index) { return Math.floor(index / self.IMAGES_PER_ROW); })
- .values()
- .value();
- self.$('.unsplash_img_container').html(QWeb.render('web_unsplash.dialog.image.content', {rows: rows}));
- self._highlightSelectedImages();
- }).fail(function (err) {
- self.$('.unsplash_img_container').html(QWeb.render('web_unsplash.dialog.error.content', { status: err }));
- }).always(function () {
- self._toggleAttachmentContaines(false);
+ this.$('.o_unsplash_img_cell.o_selected').removeClass('o_selected');
+ var $select = this.$('.o_unsplash_img_cell [data-imgid]').filter(function () {
+ return $(this).data('imgid') in self._unsplash.selectedImages;
});
+ $select.closest('.o_unsplash_img_cell').addClass('o_selected');
+ return $select;
},
/**
* @private
*/
- _toggleAttachmentContaines: function (hideUnsplash) {
- this.$('.existing-attachments').toggleClass('d-none', !hideUnsplash);
- this.$('.unsplash_img_container').toggleClass('d-none', hideUnsplash);
- this.$('.o_load_more').toggleClass('d-none', hideUnsplash);
- this.$('.o_load_done_msg').toggleClass('d-none', !hideUnsplash);
- this.trigger_up('update_control_panel');
+ _loadMoreImages: function (forceSearch) {
+ this._super(this._unsplash.isActive || forceSearch);
},
/**
- * @private
+ * @override
*/
- _toggleLoadMoreBtnUnsplash: function (display) {
- this.$('.o_load_done_msg').toggleClass('d-none', display);
+ _renderImages: function () {
+ var self = this;
+ if (!this._unsplash.isActive) {
+ return this._super.apply(this, arguments);
+ }
+
+ if (this._unsplash.error) {
+ this.$('.unsplash_img_container').html(
+ core.qweb.render('web_unsplash.dialog.error.content', {
+ status: this._unsplash.error,
+ })
+ );
+ return;
+ }
+
+ var rows = _(this._unsplash.records).chain()
+ .groupBy(function (a, index) { return Math.floor(index / self.IMAGES_PER_ROW); })
+ .values()
+ .value();
+
+ this.$('.unsplash_img_container').html(core.qweb.render('web_unsplash.dialog.image.content', {rows: rows}));
+ this._highlightSelectedImages();
},
/**
* @private
+ * @param {boolean} show
*/
- _toggleSearchDropdown: function (show) {
- var inputValue = this.$('#icon-search').val();
- this.$('.o_search_value_input').text(inputValue);
- this.$('.o_dropdown_search').toggleClass('show', show);
+ _toggleUnsplashContainer: function (show) {
+ this._unsplash.isActive = show;
+ this.$('.existing-attachments').toggleClass('d-none', show);
+ this.$('.unsplash_img_container').toggleClass('d-none', !show);
+ this.$('.o_we_search_icon > span').text(show ? "Unsplash" : "");
},
//--------------------------------------------------------------------------
@@ -207,34 +235,17 @@ weWidgets.ImageWidget.include({
/**
* @private
*/
- _onChangeUnsplashSearch: _.debounce(function () {
- // oldPage saves the original image widget pager.
- // Emptying the unsplash search will set the pager to its previous state
- this._unsplash.query = this.$('#icon-search').val().trim();
- if (this._unsplash.query) {
- this.oldPage = this.page;
- this.page = 1;
- this._renderImages();
- } else {
- this.page = this.oldPage || 1;
- this._toggleAttachmentContaines(true);
- }
- this._toggleLoadMoreBtnUnsplash(true);
- }, 1000),
- /**
- * @private
- */
_onUnsplashImgClick: function (ev) {
var imgid = $(ev.currentTarget).data('imgid');
var url = $(ev.currentTarget).data('url');
- var downloadUrl = $(ev.currentTarget).data('download-url');
+ var downloadURL = $(ev.currentTarget).data('download-url');
if (!this.multiImages) {
this._unsplash.selectedImages = {};
}
if (imgid in this._unsplash.selectedImages) {
delete this._unsplash.selectedImages[imgid];
} else {
- this._unsplash.selectedImages[imgid] = {url: url, downloadUrl: downloadUrl};
+ this._unsplash.selectedImages[imgid] = {url: url, download_url: downloadURL};
}
this._highlightSelectedImages();
},
@@ -246,46 +257,25 @@ weWidgets.ImageWidget.include({
},
/**
* @private
+ * @param {Event} ev
*/
- _onLoadMore: function () {
- this._unsplash.query = this.$('#icon-search').val().trim();
- this._loadMoreImages();
- },
- /**
- * @private
- */
- _onSearchFromUnsplash: function () {
- this.$('.o_dropdown_search').removeClass('show');
- this._toggleAttachmentContaines(false);
- this._onChangeUnsplashSearch();
- },
- /**
- * @private
- */
- _onSearchImage: function () {
- var searchText = this.$('#icon-search').val().trim();
- this._unsplash.query = false;
- this.search(searchText);
- this.$('.o_dropdown_search').removeClass('show');
- this._toggleAttachmentContaines(true);
- this._renderImages();
+ _onSourceSwitchClick: function (ev) {
+ this._toggleUnsplashContainer(!$(ev.currentTarget).is('.o_search_an_image'));
+ this.search(this.$('.o_we_search').val() || '');
},
/**
* @private
*/
_onPressKeySearch: function (ev) {
- var $searchAnImage = this.$('button.dropdown-item.o_search_an_image');
switch (ev.which) {
- case $.ui.keyCode.ENTER:
- $searchAnImage.focus();
- break;
case $.ui.keyCode.UP:
- $searchAnImage.focus();
+ this.$('.o_search_an_image').focus();
break;
case $.ui.keyCode.DOWN:
- $searchAnImage.next().focus();
+ this.$('.o_search_from_unsplash').focus();
break;
- default: return;
+ default:
+ return;
}
ev.preventDefault();
},
@@ -294,11 +284,19 @@ weWidgets.ImageWidget.include({
*/
_onSearchInput: function (ev) {
if (!this.options.document) {
- this._toggleSearchDropdown(true);
- } else {
- this.search($(ev.currentTarget).val() || '');
+ var $input = $(ev.currentTarget);
+ var inputValue = $input.val();
+ this.$('.o_search_value_input').text(inputValue);
+
+ var $icon = this.$('.o_we_search_icon');
+ if ($icon.parent().is('.show')) {
+ $icon.dropdown('update');
+ } else if (!this.hasSearched) {
+ $icon.dropdown('toggle');
+ $input.focus();
+ }
}
+ this._super.apply(this, arguments);
},
});
-
});
diff --git a/addons/web_unsplash/static/src/js/unsplashapi.js b/addons/web_unsplash/static/src/js/unsplashapi.js
index a6ec5b75324..3055ec306e8 100644
--- a/addons/web_unsplash/static/src/js/unsplashapi.js
+++ b/addons/web_unsplash/static/src/js/unsplashapi.js
@@ -27,12 +27,11 @@ var UnsplashCore = Class.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
*
* @param {String} query search terms
* @param {Integer} pageSize number of image to display per page
- * @param {Integer} pageNumber page number to retrieve
*/
- getImages: function (query, pageSize, pageNumber) {
+ getImages: function (query, pageSize) {
var self = this;
- var to = pageSize * pageNumber;
- var from = to - pageSize;
+ var from = 0;
+ var to = pageSize;
var cachedData = this._cache[query];
if (cachedData && (cachedData.images.length >= to || (cachedData.totalImages !== 0 && cachedData.totalImages < to))) {
diff --git a/addons/web_unsplash/static/src/xml/unsplash_image_widget.xml b/addons/web_unsplash/static/src/xml/unsplash_image_widget.xml
index cc826a17aa2..9a474e6041a 100644
--- a/addons/web_unsplash/static/src/xml/unsplash_image_widget.xml
+++ b/addons/web_unsplash/static/src/xml/unsplash_image_widget.xml
@@ -7,19 +7,23 @@
</t>
</t>
-<t t-extend="web_editor.dialog.files.submenu">
- <t t-jquery=".o_search_div" t-operation="append">
- <div class="dropdown-menu o_dropdown_search w-100" style="background-color:#efefef;">
- <button class="dropdown-item o_search_an_image o_size_dropdown_item" type="button">
+<t t-name="web_unsplash.dialog.media.search_icon" t-extend="">
+ <div class="dropdown">
+ <button type="button" class="btn btn-primary dropdown-toggle o_we_search_icon" data-toggle="dropdown">
+ <i class="fa fa-search"/>
+ <span/>
+ </button>
+ <div class="dropdown-menu dropdown-menu-right">
+ <button class="dropdown-item o_search_an_image" type="button">
Search among my images for:
<div class="font-weight-bold o_search_value_input"></div>
</button>
- <button class="dropdown-item o_search_from_unsplash o_size_dropdown_item" type="button">
+ <button class="dropdown-item o_search_from_unsplash" type="button">
Search from Unsplash for:
<div class="font-weight-bold o_search_value_input"></div>
</button>
</div>
- </t>
+ </div>
</t>
<t t-name="web_unsplash.dialog.image.content">
@@ -39,16 +43,14 @@
</t>
<t t-name="web_unsplash.dialog.error.credentials">
- <h4 class="text-muted">
- <t t-esc="title"/>
- </h4>
+ <h4><t t-esc="title"/></h4>
<div class="details">
<t t-esc="subtitle"/>
- <div class="form-group btn-group mt-4 access_key_box">
+ <div class="form-group mt-4 access_key_box">
<input type="text" class="form-control w-100" id="accessKeyInput" placeholder="Paste your access key here"/>
</div>
<a href="https://www.odoo.com/documentation/user/general/unsplash/unsplash_access_key.html" target="_blank"><i class="fa fa-arrow-right"/> Generate an access key</a>
- <div class="form-group btn-group mt-4 access_key_box">
+ <div class="form-group mt-4 access_key_box">
<input type="text" class="form-control w-100" id="appIdInput" placeholder="Paste your application ID here"/>
</div>
<a href="https://www.odoo.com/documentation/user/general/unsplash/unsplash_application_id.html" target="_blank"><i class="fa fa-arrow-right"/> How to find my Unsplash Application ID?</a>
@@ -57,8 +59,8 @@
</t>
<t t-name="web_unsplash.dialog.error.content">
- <div class="row mt16 text-muted unsplash_error">
- <div class="m-auto text-center">
+ <div class="d-flex mt-2 unsplash_error">
+ <div class="mx-auto text-center">
<t t-if="status == 'key_not_found'">
<t t-call="web_unsplash.dialog.error.credentials">
<t t-set="title">