diff --git a/src/runtime/includes/loaderQueue.ts b/src/runtime/includes/loaderQueue.ts index 5b1aade..8ca1d36 100644 --- a/src/runtime/includes/loaderQueue.ts +++ b/src/runtime/includes/loaderQueue.ts @@ -5,8 +5,6 @@ import { addMessages, } from '../stores/dictionary' import { getRelatedLocalesOf } from '../stores/locale' -import { $isLoading } from '../stores/loading' -import { getOptions } from '../configs' type Queue = Set const loaderQueue: Record = {} @@ -55,11 +53,6 @@ export function flush(locale: string) { // istanbul ignore if if (queues.length === 0) return - const loadingDelay = setTimeout( - () => $isLoading.set(true), - getOptions().loadingDelay - ) - // TODO what happens if some loader fails activeLocaleFlushes[locale] = Promise.all( queues.map(([locale, queue]) => { @@ -70,8 +63,6 @@ export function flush(locale: string) { }) }) ).then(() => { - clearTimeout(loadingDelay) - $isLoading.set(false) delete activeLocaleFlushes[locale] }) diff --git a/src/runtime/stores/locale.ts b/src/runtime/stores/locale.ts index 50cf267..7094f3e 100644 --- a/src/runtime/stores/locale.ts +++ b/src/runtime/stores/locale.ts @@ -4,6 +4,7 @@ import { flush, hasLocaleQueue } from '../includes/loaderQueue' import { getOptions } from '../configs' import { getClosestAvailableLocale } from './dictionary' +import { $isLoading } from './loading' let current: string const $locale = writable(null) @@ -59,7 +60,26 @@ $locale.subscribe((newLocale: string) => { const localeSet = $locale.set $locale.set = (newLocale: string): void | Promise => { if (getClosestAvailableLocale(newLocale) && hasLocaleQueue(newLocale)) { - return flush(newLocale).then(() => localeSet(newLocale)) + const loadingDelay = getOptions().loadingDelay + + let loadingTimer: number + + // if there's no current locale, we don't wait to set isLoading to true + // because it would break pages when loading the initial locale + if (getCurrentLocale() != null && loadingDelay) { + loadingTimer = window.setTimeout(() => $isLoading.set(true), loadingDelay) + } else { + $isLoading.set(true) + } + + return flush(newLocale) + .then(() => { + localeSet(newLocale) + }) + .finally(() => { + clearTimeout(loadingTimer) + $isLoading.set(false) + }) } return localeSet(newLocale) } diff --git a/test/runtime/includes/loaderQueue.test.ts b/test/runtime/includes/loaderQueue.test.ts index e3f2eff..10e5679 100644 --- a/test/runtime/includes/loaderQueue.test.ts +++ b/test/runtime/includes/loaderQueue.test.ts @@ -1,5 +1,3 @@ -import { get } from 'svelte/store' - import { hasLocaleQueue, flush, @@ -7,8 +5,6 @@ import { resetQueues, } from '../../../src/runtime/includes/loaderQueue' import { getMessageFromDictionary } from '../../../src/runtime/stores/dictionary' -import { $isLoading } from '../../../src/runtime/stores/loading' -import { getOptions } from '../../../src/runtime/configs' beforeEach(() => { resetQueues() @@ -54,30 +50,3 @@ test('consecutive flushes return the same promise', async () => { expect(flushB).toStrictEqual(flushA) expect(flushC).toStrictEqual(flushA) }) - -test('should set loading to true if passed min delay and false after loading', () => { - registerLocaleLoader( - 'en', - () => - new Promise(res => - setTimeout(() => res({}), getOptions().loadingDelay * 2) - ) - ) - - const flushPromise = flush('en') - - return new Promise((res, rej) => { - setTimeout(() => { - if (get($isLoading) === true) return res() - return rej('$isLoading should be "true"') - }, getOptions().loadingDelay) - }).then(() => { - flushPromise.then( - () => - new Promise((res, rej) => { - if (get($isLoading) === false) return res() - return rej('$isLoading should be "false" after loading') - }) - ) - }) -}) diff --git a/test/runtime/stores/locale.test.ts b/test/runtime/stores/locale.test.ts index 416dcc4..e656a14 100644 --- a/test/runtime/stores/locale.test.ts +++ b/test/runtime/stores/locale.test.ts @@ -10,7 +10,7 @@ import { isRelatedLocale, } from '../../../src/runtime/stores/locale' import { getOptions, init } from '../../../src/runtime/configs' -import { register } from '../../../src/runtime' +import { register, isLoading } from '../../../src/runtime' import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue' beforeEach(() => { @@ -132,3 +132,38 @@ test('should flush the queue of the locale when changing the store value', async expect(hasLocaleQueue('en')).toBe(false) expect(lookup('foo', 'en')).toBe('Foo') }) + +test('if no locale is set, ignore the loading delay', async () => { + register( + 'en', + () => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) + ) + + const promise = $locale.set('en') + + expect(get(isLoading)).toBe(true) + + await promise + + expect(get(isLoading)).toBe(false) +}) + +test("if a locale is set, don't ignore the loading delay", async () => { + register( + 'en', + () => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) + ) + register( + 'pt', + () => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) + ) + + await $locale.set('en') + const promise = $locale.set('pt') + + expect(get(isLoading)).toBe(false) + + await promise + + expect(get(isLoading)).toBe(false) +})