websocket debounce block

This commit is contained in:
Yuri Kuznetsov
2025-06-29 16:40:12 +03:00
parent e5c4baef9e
commit 36f7ffaaa1
2 changed files with 98 additions and 17 deletions
@@ -67,9 +67,9 @@ class CalendarPage extends View {
/**
* @private
* @type {DebounceHelper}
* @type {DebounceHelper|null}
*/
webSocketDebounceHelper
webSocketDebounceHelper = null
/**
* @private
@@ -77,6 +77,12 @@ class CalendarPage extends View {
*/
webSocketDebounceInterval = 500
/**
* @private
* @type {number}
*/
webSocketBlockInterval = 1000
/**
* A shortcut-key => action map.
*
@@ -228,6 +234,7 @@ class CalendarPage extends View {
this.webSocketDebounceHelper = new DebounceHelper({
interval: this.webSocketDebounceInterval,
blockInterval: this.webSocketBlockInterval,
handler: () => this.handleWebSocketUpdate(),
});
@@ -254,6 +261,17 @@ class CalendarPage extends View {
this.getCalendarView()?.actionRefresh({suppressLoadingAlert: true});
}
/**
* @private
*/
onSave() {
if (!this.webSocketDebounceHelper) {
return;
}
this.webSocketDebounceHelper.block()
}
afterRender() {
this.$el.focus();
}
@@ -284,6 +302,9 @@ class CalendarPage extends View {
this.getRouter().navigate(url, {trigger: trigger});
}
/**
* @private
*/
setupCalendar() {
const viewName = this.getMetadata().get(['clientDefs', 'Calendar', 'calendarView']) ||
'crm:views/calendar/calendar';
@@ -294,6 +315,7 @@ class CalendarPage extends View {
userName: this.options.userName,
mode: this.mode,
fullSelector: '#main > .calendar-container',
onSave: () => this.onSave(),
}, view => {
let initial = true;
@@ -330,6 +352,9 @@ class CalendarPage extends View {
});
}
/**
* @private
*/
setupTimeline() {
const viewName = this.getMetadata().get(['clientDefs', 'Calendar', 'timelineView']) ||
'crm:views/calendar/timeline';
@@ -339,6 +364,7 @@ class CalendarPage extends View {
userId: this.options.userId,
userName: this.options.userName,
fullSelector: '#main > .calendar-container',
onSave: () => this.onSave(),
}, view => {
let initial = true;
+70 -15
View File
@@ -37,20 +37,49 @@ export default class DebounceHelper {
* @type {boolean}
* @private
*/
_blocked = false
blocked = false
/**
*
* @type {boolean}
* @private
*/
_calledWhenBlocked = false
blockedInProcess = false
/**
* @type {boolean}
* @private
*/
calledWhenProcessBlocked = false
/**
* @type {number}
* @private
*/
interval = 500
/**
* @type {number}
* @private
*/
blockInterval = 1000
/**
* @type {number}
* @private
*/
blockedCallCount = 0
/**
* @type {number|null}
* @private
*/
blockTimeoutId = null
/**
* @param {{
* handler: function(...*),
* interval: number,
* interval?: number,
* blockInterval?: number,
* }} options
* @param options
*/
@@ -61,11 +90,8 @@ export default class DebounceHelper {
*/
this.handler = options.handler;
/**
* @private
* @type {number}
*/
this.interval = options.interval;
this.interval = options.interval ?? this.interval;
this.blockInterval = options.blockInterval ?? this.blockInterval;
}
/**
@@ -75,21 +101,27 @@ export default class DebounceHelper {
*/
process() {
const handle = () => {
if (this._blocked) {
this._calledWhenBlocked = true;
if (this.blocked) {
this.blockedCallCount ++;
return;
}
if (this.blockedInProcess) {
this.calledWhenProcessBlocked = true;
return;
}
this.handler(arguments);
this._blocked = true;
this.blockedInProcess = true;
setTimeout(() => {
const reRun = this._calledWhenBlocked;
const reRun = this.calledWhenProcessBlocked;
this._blocked = false;
this._calledWhenBlocked = false;
this.blockedInProcess = false;
this.calledWhenProcessBlocked = false;
if (reRun) {
handle();
@@ -99,4 +131,27 @@ export default class DebounceHelper {
handle();
}
/**
* Block for a while.
*
* @since 9.2.0
*/
block() {
this.blocked = true;
if (this.blockTimeoutId) {
clearTimeout(this.blockTimeoutId);
}
this.blockTimeoutId = setTimeout(() => {
this.blocked = false;
const toProcess = this.blockedCallCount > 1;
this.blockedCallCount = 0;
if (toProcess) {
this.process();
}
}, this.blockInterval)
}
}