Odoo18-Base/addons/website_mail/static/src/js/follow.js
2025-01-06 10:57:38 +07:00

148 lines
5.0 KiB
JavaScript

/** @odoo-module **/
import publicWidget from "@web/legacy/js/public/public_widget";
import { rpc } from "@web/core/network/rpc";
import { ReCaptcha } from "@google_recaptcha/js/recaptcha";
import { _t } from "@web/core/l10n/translation";
publicWidget.registry.follow = publicWidget.Widget.extend({
selector: '#wrapwrap',
selectorHas: '.js_follow',
disabledInEditableMode: false,
init() {
this._super(...arguments);
this._recaptcha = new ReCaptcha();
this.notification = this.bindService("notification");
},
async willStart() {
return this._recaptcha.loadLibs();
},
/**
* @override
*/
start: function () {
var self = this;
this.isUser = false;
var $jsFollowEls = this.$el.find('.js_follow');
var always = function (data) {
self.isUser = data[0].is_user;
const $jsFollowToEnable = $jsFollowEls.filter(function () {
const model = this.dataset.object;
return model in data[1] && data[1][model].includes(parseInt(this.dataset.id));
});
self._toggleSubscription(true, data[0].email, $jsFollowToEnable);
self._toggleSubscription(false, data[0].email, $jsFollowEls.not($jsFollowToEnable));
$jsFollowEls.removeClass('d-none');
};
const records = {};
for (const el of $jsFollowEls) {
const model = el.dataset.object;
if (!(model in records)) {
records[model] = [];
}
records[model].push(parseInt(el.dataset.id));
}
rpc('/website_mail/is_follower', {
records: records,
}).then(always, always);
// not if editable mode to allow designer to edit
if (!this.editableMode) {
$('.js_follow > .d-none').removeClass('d-none');
this.$el.find('.js_follow_btn, .js_unfollow_btn').on('click', function (event) {
event.preventDefault();
self._onClick(event);
});
}
return this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Toggles subscription state for every given records.
*
* @private
* @param {boolean} follow
* @param {string} email
* @param {jQuery} $jsFollowEls
*/
_toggleSubscription: function (follow, email, $jsFollowEls) {
if (follow) {
this._updateSubscriptionDOM(follow, email, $jsFollowEls);
} else {
for (const el of $jsFollowEls) {
const follow = !email && el.getAttribute('data-unsubscribe');
this._updateSubscriptionDOM(follow, email, $(el));
}
}
},
/**
* Updates subscription DOM for every given records.
* This should not be called directly, use `_toggleSubscription`.
*
* @private
* @param {boolean} follow
* @param {string} email
* @param {jQuery} $jsFollowEls
*/
_updateSubscriptionDOM: function (follow, email, $jsFollowEls) {
$jsFollowEls.find('input.js_follow_email')
.val(email || "")
.attr("disabled", email && (follow || this.isUser) ? "disabled" : false);
$jsFollowEls.attr("data-follow", follow ? 'on' : 'off');
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {Event} ev
*/
async _onClick(ev) {
var self = this;
var $jsFollow = $(ev.currentTarget).closest('.js_follow');
var $email = $jsFollow.find(".js_follow_email");
if ($email.length && !$email.val().match(/.+@.+/)) {
$jsFollow.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');
return false;
}
$jsFollow.removeClass('o_has_error').find('.form-control, .form-select').removeClass('is-invalid');
var email = $email.length ? $email.val() : false;
if (email || this.isUser) {
const tokenCaptcha = await this._recaptcha.getToken("website_mail_follow");
const token = tokenCaptcha.token;
if (tokenCaptcha.error) {
self.notification.add(tokenCaptcha.error, {
type: "danger",
title: _t("Error"),
sticky: true
});
return false;
}
rpc("/website_mail/follow", {
"id": +$jsFollow.data("id"),
"object": $jsFollow.data("object"),
"message_is_follower": $jsFollow.attr("data-follow") || "off",
"email": email,
"recaptcha_token_response": token
}).then(function(follow) {
self._toggleSubscription(follow, email, $jsFollow);
});
}
},
});