@applicaster/zapp-react-native-ui-components
Version:
Applicaster Zapp React Native ui components for the Quick Brick App
75 lines (61 loc) • 2.26 kB
text/typescript
import { ReplaySubject } from "rxjs";
import { map } from "rxjs/operators";
export class MasterCellAsyncRenderManager {
readonly asyncElementRegistrate$: ReplaySubject<any>;
readonly asyncElementLayout$: ReplaySubject<any>;
private asyncElementRegistrationCount: number;
readonly notifyAllAsyncElementsRendered: () => void;
constructor(notifyAllAsyncElementsRendered: () => void) {
this.asyncElementRegistrate$ = new ReplaySubject();
this.asyncElementLayout$ = new ReplaySubject();
this.asyncElementRegistrationCount = 0;
this.notifyAllAsyncElementsRendered = notifyAllAsyncElementsRendered;
}
public emitAsyncElementRegistrate = () => {
this.asyncElementRegistrate$.next(null);
return this.decrementAsyncElementRegistrationCount;
};
public emitAsyncElementLayout = () => {
this.asyncElementLayout$.next(null);
};
public decrementAsyncElementRegistrationCount = () => {
if (this.asyncElementRegistrationCount > 0) {
this.asyncElementRegistrationCount -= 1;
}
};
public onCellLayout = () => {
if (this.asyncElementRegistrationCount === 0) {
// cell was rendered but no async registrations were occured
// it means that we have none async elements inside this cell
this.finishAsyncRendering();
}
};
public start = () => {
const registrationSubscription = this.asyncElementRegistrate$.subscribe({
next: () => {
// count how many registration of async rendering occured
this.asyncElementRegistrationCount += 1;
},
});
const layoutSubscription = this.asyncElementLayout$
.pipe(map((_, index) => index + 1))
.subscribe({
next: (layoutCount) => {
if (layoutCount >= this.asyncElementRegistrationCount) {
// when number of onLayout was reached registration count we could stop
this.finishAsyncRendering();
}
},
});
return () => {
registrationSubscription.unsubscribe();
layoutSubscription.unsubscribe();
};
};
private finishAsyncRendering() {
this.notifyAllAsyncElementsRendered();
// stop waiting async elements
this.asyncElementRegistrate$.complete();
this.asyncElementLayout$.complete();
}
}