Skip to content

Commit e1e9d2f

Browse files
committed
feat(demo): enhance demo mode with exchange rate updates and inactivity detection
1 parent 62bc0f1 commit e1e9d2f

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/main-demo.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import VueVirtualScroller from 'vue-virtual-scroller';
55
import { setAssetPublicPath as setVueComponentsAssetPath } from '@nimiq/vue-components';
66
// @ts-expect-error missing types for this package
77
import VuePortal from '@linusborg/vue-simple-portal';
8+
import { init as initOasisApi } from '@nimiq/oasis-api';
89
import { init as initFastspotApi } from '@nimiq/fastspot-api';
910

1011
import App from './App.vue';
12+
import { serviceWorkerHasUpdate } from './registerServiceWorker';
1113
import { launchNetwork } from './network';
1214
import { useAccountStore } from './stores/Account';
1315
import { dangerouslyInitializeDemo } from './lib/Demo';
@@ -26,6 +28,8 @@ import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
2628
import '@/scss/themes.scss';
2729
import { launchPolygon } from './ethers';
2830
import { launchElectrum } from './electrum';
31+
import { useInactivityDetection } from './composables/useInactivityDetection';
32+
import { useFiatStore } from './stores/Fiat';
2933

3034
// Set asset path relative to the public path defined in vue.config.json,
3135
// see https://cli.vuejs.org/guide/mode-and-env.html#using-env-variables-in-client-side-code
@@ -40,6 +44,41 @@ Vue.use(VuePortal, { name: 'Portal' });
4044
async function start() {
4145
dangerouslyInitializeDemo(router);
4246

47+
serviceWorkerHasUpdate.then((hasUpdate) => useSettingsStore().state.updateAvailable = hasUpdate);
48+
49+
// Update exchange rates every 2 minutes or every 10 minutes, depending on whether the Wallet is currently actively
50+
// used. If an update takes longer than that time due to a provider's rate limit, wait until the update succeeds
51+
// before queueing the next update. If the last update before page load was less than 2 minutes ago, wait the
52+
// remaining time first.
53+
const { timestamp: lastSuccessfulExchangeRateUpdate, updateExchangeRates } = useFiatStore();
54+
const { isUserInactive } = useInactivityDetection();
55+
let lastTriedExchangeRateUpdate = lastSuccessfulExchangeRateUpdate.value;
56+
const TWO_MINUTES = 2 * 60 * 1000;
57+
const TEN_MINUTES = 5 * TWO_MINUTES;
58+
let exchangeRateUpdateTimer = -1;
59+
function queueExchangeRateUpdate() {
60+
const interval = isUserInactive.value ? TEN_MINUTES : TWO_MINUTES;
61+
// Update lastTriedExchangeRateUpdate as there might have been other exchange rate updates in the meantime, for
62+
// example on currency change.
63+
lastTriedExchangeRateUpdate = Math.max(lastTriedExchangeRateUpdate, lastSuccessfulExchangeRateUpdate.value);
64+
// Also set interval as upper bound to be immune to the user's system clock being wrong.
65+
const remainingTime = Math.max(0, Math.min(lastTriedExchangeRateUpdate + interval - Date.now(), interval));
66+
clearTimeout(exchangeRateUpdateTimer);
67+
exchangeRateUpdateTimer = window.setTimeout(async () => {
68+
// Silently ignore errors. If successful, this updates fiatStore.timestamp, which then also triggers price
69+
// chart updates in PriceChart.vue.
70+
await updateExchangeRates(/* failGracefully */ true);
71+
// In contrast to lastSuccessfulExchangeRateUpdate also update lastTriedExchangeRateUpdate on failed
72+
// attempts, to avoid repeated rescheduling on failure. Instead, simply skip the failed attempt and try
73+
// again at the regular interval. We update the time after the update attempt, instead of before it, because
74+
// exchange rates are up-to-date at the time an update successfully finishes, and get old from that point,
75+
// and not from the time the update was started.
76+
lastTriedExchangeRateUpdate = Date.now();
77+
queueExchangeRateUpdate();
78+
}, remainingTime);
79+
}
80+
watch(isUserInactive, queueExchangeRateUpdate); // (Re)schedule exchange rate updates at the desired interval.
81+
4382
// Fetch language file
4483
const { language } = useSettingsStore();
4584
loadLanguage(language.value);
@@ -52,6 +91,11 @@ async function start() {
5291
initFastspotApi(config.fastspot.apiEndpoint, config.fastspot.apiKey);
5392
});
5493

94+
watch(() => {
95+
if (!config.oasis.apiEndpoint) return;
96+
initOasisApi(config.oasis.apiEndpoint);
97+
});
98+
5599
config.demo.enabled = true;
56100
// Make reactive config accessible in components
57101
Vue.prototype.$config = config;

0 commit comments

Comments
 (0)