Skip to content

Commit f0f19d2

Browse files
akhenryjvigliottaozyx
committed
cherry-pick(#6885): Synchronize timers between multiple users
* created a throttle util and using it in timer plugin to throttle refreshing the timer domain object * Simplify timer logic * Clarify code a little * refactor: lint:fix * Fix linting issue --------- Co-authored-by: Jamie V <[email protected]> Co-authored-by: Jesse Mazzella <[email protected]> Co-authored-by: Jesse Mazzella <[email protected]>
1 parent 796616f commit f0f19d2

File tree

2 files changed

+52
-40
lines changed

2 files changed

+52
-40
lines changed

src/plugins/timer/components/Timer.vue

+18-40
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@
4343

4444
<script>
4545
import raf from 'utils/raf';
46+
import throttle from '../../../utils/throttle';
4647

4748
const moment = require('moment-timezone');
4849
const momentDurationFormatSetup = require('moment-duration-format');
50+
const refreshRateSeconds = 2;
4951

5052
momentDurationFormatSetup(moment);
5153

@@ -68,38 +70,21 @@ export default {
6870
};
6971
},
7072
computed: {
71-
relativeTimestamp() {
72-
let relativeTimestamp;
73-
if (this.configuration && this.configuration.timestamp) {
74-
relativeTimestamp = moment(this.configuration.timestamp).toDate();
75-
} else if (this.configuration && this.configuration.timestamp === undefined) {
76-
relativeTimestamp = undefined;
73+
timeDelta() {
74+
if (this.configuration.pausedTime) {
75+
return Date.parse(this.configuration.pausedTime) - this.startTimeMs;
76+
} else {
77+
return this.lastTimestamp - this.startTimeMs;
7778
}
78-
79-
return relativeTimestamp;
8079
},
81-
timeDelta() {
82-
return this.lastTimestamp - this.relativeTimestamp;
80+
startTimeMs() {
81+
return Date.parse(this.configuration.timestamp);
8382
},
8483
timeTextValue() {
85-
if (isNaN(this.timeDelta)) {
86-
return null;
87-
}
88-
8984
const toWholeSeconds = Math.abs(Math.floor(this.timeDelta / 1000) * 1000);
9085

9186
return moment.duration(toWholeSeconds, 'ms').format(this.format, { trim: false });
9287
},
93-
pausedTime() {
94-
let pausedTime;
95-
if (this.configuration && this.configuration.pausedTime) {
96-
pausedTime = moment(this.configuration.pausedTime).toDate();
97-
} else if (this.configuration && this.configuration.pausedTime === undefined) {
98-
pausedTime = undefined;
99-
}
100-
101-
return pausedTime;
102-
},
10388
timerState() {
10489
let timerState = 'started';
10590
if (this.configuration && this.configuration.timerState) {
@@ -179,20 +164,17 @@ export default {
179164
}
180165
},
181166
mounted() {
182-
this.unobserve = this.openmct.objects.observe(
183-
this.domainObject,
184-
'configuration',
185-
(configuration) => {
186-
this.configuration = configuration;
187-
}
188-
);
167+
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', (domainObject) => {
168+
this.configuration = domainObject.configuration;
169+
});
189170
this.$nextTick(() => {
190171
if (!this.configuration?.timerState) {
191172
const timerAction = !this.relativeTimestamp ? 'stop' : 'start';
192173
this.triggerAction(`timer.${timerAction}`);
193174
}
194175

195176
this.handleTick = raf(this.handleTick);
177+
this.refreshTimerObject = throttle(this.refreshTimerObject, refreshRateSeconds * 1000);
196178
this.openmct.time.on('tick', this.handleTick);
197179

198180
this.viewActionsCollection = this.openmct.actions.getActionsCollection(
@@ -210,15 +192,11 @@ export default {
210192
},
211193
methods: {
212194
handleTick() {
213-
const isTimerRunning = !['paused', 'stopped'].includes(this.timerState);
214-
215-
if (isTimerRunning) {
216-
this.lastTimestamp = new Date(this.openmct.time.now());
217-
}
218-
219-
if (this.timerState === 'paused' && !this.lastTimestamp) {
220-
this.lastTimestamp = this.pausedTime;
221-
}
195+
this.lastTimestamp = new Date(this.openmct.time.now());
196+
this.refreshTimerObject();
197+
},
198+
refreshTimerObject() {
199+
this.openmct.objects.refresh(this.domainObject);
222200
},
223201
restartTimer() {
224202
this.triggerAction('timer.restart');

src/utils/throttle.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Creates a throttled function that only invokes the provided function at most once every
3+
* specified number of milliseconds. Subsequent calls within the waiting period will be ignored.
4+
* @param {Function} func The function to throttle.
5+
* @param {number} wait The number of milliseconds to wait between successive calls to the function.
6+
* @return {Function} Returns the new throttled function.
7+
*/
8+
export default function throttle(func, wait) {
9+
let timeout;
10+
let result;
11+
let previous = 0;
12+
13+
return function (...args) {
14+
const now = new Date().getTime();
15+
const remaining = wait - (now - previous);
16+
17+
if (remaining <= 0 || remaining > wait) {
18+
if (timeout) {
19+
clearTimeout(timeout);
20+
timeout = null;
21+
}
22+
23+
previous = now;
24+
result = func(...args);
25+
} else if (!timeout) {
26+
timeout = setTimeout(() => {
27+
previous = new Date().getTime();
28+
timeout = null;
29+
result = func(...args);
30+
}, remaining);
31+
}
32+
return result;
33+
};
34+
}

0 commit comments

Comments
 (0)