@v4fire/client
Version:
V4Fire client core library
165 lines (143 loc) • 3.93 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
import symbolGenerator from 'core/symbol';
import type { AsyncOptions } from 'core/async';
import Friend from 'super/i-block/modules/friend';
import type bVirtualScrollNew from 'base/b-virtual-scroll-new/b-virtual-scroll-new';
import type { SlotsStateObj } from 'base/b-virtual-scroll-new/modules/slots/interface';
export * from 'base/b-virtual-scroll-new/modules/slots/interface';
export const
$$ = symbolGenerator(),
slotsStateControllerAsyncGroup = 'slotsStateController';
/**
* A class that manages the visibility of slots based on different states.
*/
export class SlotsStateController extends Friend {
override readonly C!: bVirtualScrollNew;
/**
* Options for the asynchronous operations.
*/
protected readonly asyncUpdateLabel: AsyncOptions = {
label: $$.updateSlotsVisibility,
group: slotsStateControllerAsyncGroup
};
/**
* The last state of the slots.
*/
protected lastState?: SlotsStateObj;
/**
* Displays the slots that should be shown when the data state is empty
*/
emptyState(): void {
this.setSlotsVisibility({
container: true,
done: true,
empty: true,
loader: false,
renderNext: false,
retry: false,
tombstones: false
});
}
/**
* Displays the slots that should be shown when the lifecycle is done
*/
doneState(): void {
this.setSlotsVisibility({
container: true,
done: true,
empty: this.lastState?.empty ?? false,
loader: false,
renderNext: false,
retry: false,
tombstones: false
});
}
/**
* Displays the slots that should be shown during data loading progress
* @param [immediate] - if set to true, {@link requestAnimationFrame} will not be used to switch the state.
*/
loadingProgressState(immediate: boolean = false): void {
this.setSlotsVisibility({
container: true,
loader: true,
tombstones: true,
done: false,
empty: false,
renderNext: false,
retry: false
}, immediate);
}
/**
* Displays the slots that should be shown when data loading fails
*/
loadingFailedState(): void {
this.setSlotsVisibility({
container: true,
retry: true,
done: false,
empty: false,
loader: false,
renderNext: false,
tombstones: false
});
}
/**
* Displays the slots that should be shown when data loading is successful
* @param immediate
*/
loadingSuccessState(immediate: boolean = false): void {
this.setSlotsVisibility({
container: true,
done: false,
empty: false,
loader: false,
renderNext: true,
retry: false,
tombstones: false
}, immediate);
}
/**
* Resets the state of the module
*/
reset(): void {
this.async.clearAll({group: new RegExp(slotsStateControllerAsyncGroup)});
this.lastState = undefined;
}
/**
* Sets the visibility state of the slots.
*
* @param stateObj - an object specifying the visibility state of each slot.
* @param [immediate] - if set to true, {@link requestAnimationFrame} will not be used to switch the state.
*/
protected setSlotsVisibility(stateObj: Required<SlotsStateObj>, immediate: boolean = false): void {
this.lastState = stateObj;
this.async.cancelAnimationFrame(this.asyncUpdateLabel);
const update = () => {
for (const [name, state] of Object.entries(stateObj)) {
this.setDisplayState(<keyof SlotsStateObj>name, state);
}
};
if (immediate) {
return update();
}
this.async.requestAnimationFrame(update, this.asyncUpdateLabel);
}
/**
* Sets the display state of a slot.
*
* @param name - the name of the slot.
* @param state - the visibility state of the slot.
*/
protected setDisplayState(name: keyof SlotsStateObj, state: boolean): void {
const ref = this.ctx.$refs[name];
if (ref instanceof HTMLElement) {
ref.style.display = state ? '' : 'none';
}
}
}