rxjs#iif TypeScript Examples

The following examples show how to use rxjs#iif. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From rubic-app with GNU General Public License v3.0 7 votes vote down vote up
/**
 * Combination of switchMap and iif.
 * @param condition Condition which Observable should be chosen.
 * @param trueResultFn An Observable that will be subscribed if condition is true.
 * @param falseResultFn An Observable that will be subscribed if condition is false.
 */
export function switchIif<A = void, T = never, F = never>(
  condition: (args: A) => boolean,
  trueResultFn: (args: A) => Observable<T>,
  falseResultFn: (args: A) => Observable<F>
): OperatorFunction<A, T | F> {
  return switchMap((args: A) =>
    iif(
      () => condition(args),
      defer(() => trueResultFn(args)),
      defer(() => falseResultFn(args))
    )
  );
}
Example #2
Source File: my-expenses.page.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
async onDeleteExpenseClick(etxn: Expense, index?: number) {
    const popupResults = await this.popupService.showPopup({
      header: 'Delete Expense',
      message: 'Are you sure you want to delete this expense?',
      primaryCta: {
        text: 'Delete',
      },
    });

    if (popupResults === 'primary') {
      from(this.loaderService.showLoader('Deleting Expense', 2500))
        .pipe(
          switchMap(() =>
            iif(
              () => !etxn.tx_id,
              of(this.transactionOutboxService.deleteOfflineExpense(index)),
              this.transactionService.delete(etxn.tx_id)
            )
          ),
          tap(() => this.trackingService.deleteExpense()),
          finalize(async () => {
            await this.loaderService.hideLoader();
            this.doRefresh();
          })
        )
        .subscribe(noop);
    }
  }
Example #3
Source File: cache-flow.ts    From RcloneNg with MIT License 6 votes vote down vote up
protected request(pre: CombErr<Tin>): Observable<CombErr<Tout>> {
		return iif(
			() => this.cacheEnabled() && this.isCached(),
			of(this.getCache()),
			this.requestCache(pre).pipe(
				take(1),
				tap(x => {
					if (this.cacheEnabled()) this.setCache(x);
				})
			)
		);
	}
Example #4
Source File: my-view-report.page.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
saveReport() {
    const report = {
      purpose: this.reportName,
      id: this.activatedRoute.snapshot.params.id,
    };

    this.reportService
      .createDraft(report)
      .pipe(
        switchMap((res) =>
          iif(
            () => this.addedExpensesIdList.length > 0,
            this.reportService
              .addTransactions(this.activatedRoute.snapshot.params.id, this.addedExpensesIdList)
              .pipe(tap(() => this.trackingService.addToExistingReport())),
            of(false)
          )
        ),
        switchMap((res) => iif(() => this.deleteExpensesIdList.length > 0, this.removeTxnFromReport(), of(false))),
        finalize(() => {
          this.addedExpensesIdList = [];
          this.deleteExpensesIdList = [];
          this.router.navigate(['/', 'enterprise', 'my_view_report', { id: this.reportId }]);
        })
      )
      .subscribe(noop);
  }
Example #5
Source File: publication-status.guard.ts    From geonetwork-ui with GNU General Public License v2.0 6 votes vote down vote up
canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot // eslint-disable-line
  ): Observable<boolean> {
    const id = route.params.id

    return this.facade.publication$.pipe(
      take(1),
      mergeMap((statePublication) =>
        iif(
          () =>
            statePublication &&
            statePublication.status !== PublishStatusEnumApiModel.Pending,
          of(true),
          this.publishService.getPublishingStatus(id).pipe(
            tap((publication) => this.facade.setPublication(publication)),
            tap((publication: PublishJobStatusApiModel) => {
              if (publication.status === PublishStatusEnumApiModel.Error) {
                throw new Error('api error')
              }
            }),
            mapTo(true),
            catchError(() => {
              this.router.navigate(['/'])
              return of(false)
            })
          )
        )
      )
    )
  }
Example #6
Source File: capture-item.component.ts    From capture-lite with GNU General Public License v3.0 6 votes vote down vote up
@HostListener('click')
  onClick() {
    return this.isCollecting$
      .pipe(
        first(),
        switchMap(isCollecting =>
          iif(
            () => !isCollecting,
            this.oldProofHash$.pipe(
              first(),
              concatMap(oldProofHash =>
                this.router.navigate(
                  ['details', { type: 'capture', hash: oldProofHash }],
                  {
                    relativeTo: this.route,
                  }
                )
              )
            )
          )
        ),
        untilDestroyed(this)
      )
      .subscribe();
  }
Example #7
Source File: trade-logs.effects.ts    From zorro-fire-log with MIT License 6 votes vote down vote up
onTradeLogUpdate$ = createEffect(() =>
    iif(
      () => this.useMockData,
      of(
        addTradeLogs({
          tradeLogs: mockTradeLogs,
        })
      ).pipe(
        delay(500),
        tap(() => console.warn('Using MOCKED data'))
      ),
      this.store.select(selectLatestEntryTime).pipe(
        map(
          (latest) =>
            latest && new Timestamp(latest.seconds, latest.nanoseconds).toDate()
        ),
        take(1),
        switchMap((latest) =>
          merge(
            ...environment.tradeLogs.map((tl) =>
              this.firestore
                .collection<TradeLogEntry>(tl, (ref) =>
                  (latest ? ref.where('close', '>', latest) : ref).orderBy(
                    'close'
                  )
                )
                .valueChanges({ idField: 'id' })
                .pipe(
                  map((entries) => entries.map((e) => ({ ...e, alias: tl })))
                )
            )
          ).pipe(
            tap(() => console.warn('Using LIVE data')),
            map((tradeLogs) => addTradeLogs({ tradeLogs }))
          )
        )
      )
    )
  );
Example #8
Source File: camera.page.ts    From ionic-pwa-example-moment with MIT License 6 votes vote down vote up
presentError$(error: unknown) {
    return iif(
      () => error instanceof DOMException && error.name === 'NotAllowedError',
      this.dialogsService.presentAlert$({
        headerKey: `error.${(error as DOMException).name}`,
        messageKey: 'message.cameraPermissionDenied',
      }),
      this.dialogsService.presentError$(error)
    );
  }
Example #9
Source File: datasource.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
/**
   * Runs live queries which in this case means creating a websocket and listening on it for new logs.
   * This returns a bit different dataFrame than runQueries as it returns single dataframe even if there are multiple
   * Loki streams, sets only common labels on dataframe.labels and has additional dataframe.fields.labels for unique
   * labels per row.
   */
  runLiveQuery = (target: LokiQuery, options: { maxDataPoints?: number }): Observable<DataQueryResponse> => {
    const liveTarget = this.createLiveTarget(target, options);

    return from(this.getVersion()).pipe(
      mergeMap(version =>
        iif(
          () => version === 'v1',
          defer(() => this.streams.getStream(liveTarget)),
          defer(() => {
            const legacyTarget = this.createLegacyLiveTarget(target, options);
            return this.streams.getLegacyStream(legacyTarget);
          })
        )
      ),
      map(data => ({
        data,
        key: `loki-${liveTarget.refId}`,
        state: LoadingState.Streaming,
      }))
    );
  };
Example #10
Source File: auth.service.ts    From auth0-angular with MIT License 6 votes vote down vote up
constructor(
    @Inject(Auth0ClientService) private auth0Client: Auth0Client,
    private configFactory: AuthClientConfig,
    private navigator: AbstractNavigator,
    private authState: AuthState
  ) {
    const checkSessionOrCallback$ = (isCallback: boolean) =>
      iif(
        () => isCallback,
        this.handleRedirectCallback(),
        defer(() => this.auth0Client.checkSession())
      );

    this.shouldHandleCallback()
      .pipe(
        switchMap((isCallback) =>
          checkSessionOrCallback$(isCallback).pipe(
            catchError((error) => {
              const config = this.configFactory.get();
              this.authState.setError(error);
              this.navigator.navigateByUrl(config.errorPath || '/');
              return of(undefined);
            })
          )
        ),
        tap(() => {
          this.authState.setIsLoading(false);
        }),
        takeUntil(this.ngUnsubscribe$)
      )
      .subscribe();
  }
Example #11
Source File: push-notification.service.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
updateNotificationStatusAndRedirect(notificationData, wasTapped?: boolean) {
    return this.updateDeliveryStatus(notificationData.notification_id).pipe(
      concatMap(() =>
        iif(
          () => wasTapped,
          this.updateReadStatus(notificationData.notification_id),
          of(null).pipe(map(() => notificationData))
        )
      )
    );
  }
Example #12
Source File: app.component.ts    From auth0-angular with MIT License 6 votes vote down vote up
updateAccessToken(): void {
    const usePopup = this.accessTokenOptionsForm.value.usePopup === true;
    const ignoreCache = this.accessTokenOptionsForm.value.ignoreCache === true;
    iif(
      () => usePopup,
      this.auth.getAccessTokenWithPopup(),
      this.auth.getAccessTokenSilently({ ignoreCache })
    )
      .pipe(first())
      .subscribe((token) => {
        this.accessToken = token;
      });
  }
Example #13
Source File: add-edit-per-diem.page.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
checkForDuplicates() {
    const customFields$ = this.customInputs$.pipe(
      take(1),
      map((customInputs) =>
        customInputs.map((customInput, i) => ({
          id: customInput.id,
          mandatory: customInput.mandatory,
          name: customInput.name,
          options: customInput.options,
          placeholder: customInput.placeholder,
          prefix: customInput.prefix,
          type: customInput.type,
          value: this.fg.value.custom_inputs[i].value,
        }))
      )
    );

    return this.canGetDuplicates().pipe(
      switchMap((canGetDuplicates) =>
        iif(
          () => canGetDuplicates,
          this.generateEtxnFromFg(this.etxn$, customFields$).pipe(
            switchMap((etxn) => this.duplicateDetectionService.getPossibleDuplicates(etxn.tx))
          ),
          of(null)
        )
      )
    );
  }
Example #14
Source File: emote.structure.ts    From App with MIT License 6 votes vote down vote up
/**
	 * Whether a given user can edit this emote
	 */
	canEdit(user: UserStructure): Observable<boolean> {
		return this.getOwner().pipe(
			take(1),
			map(owner => (!!owner?.id && !!user?.id) ? owner.id === user.id : false),
			switchMap(ok => iif(() => ok,
				of(true),
				user.hasPermission('EDIT_EMOTE_ALL')
			))
		);
	}
Example #15
Source File: auth.interceptor.ts    From auth0-angular with MIT License 5 votes vote down vote up
intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const config = this.configFactory.get();
    if (!config.httpInterceptor?.allowedList) {
      return next.handle(req);
    }

    return this.findMatchingRoute(req, config.httpInterceptor).pipe(
      concatMap((route) =>
        iif(
          // Check if a route was matched
          () => route !== null,
          // If we have a matching route, call getTokenSilently and attach the token to the
          // outgoing request
          of(route).pipe(
            pluck('tokenOptions'),
            concatMap<GetTokenSilentlyOptions, Observable<string>>(
              (options) => {
                return this.getAccessTokenSilently(options).pipe(
                  catchError((err) => {
                    if (this.allowAnonymous(route, err)) {
                      return of('');
                    }

                    this.authState.setError(err);
                    return throwError(err);
                  })
                );
              }
            ),
            switchMap((token: string) => {
              // Clone the request and attach the bearer token
              const clone = token
                ? req.clone({
                    headers: req.headers.set(
                      'Authorization',
                      `Bearer ${token}`
                    ),
                  })
                : req;

              return next.handle(clone);
            })
          ),
          // If the URI being called was not found in our httpInterceptor config, simply
          // pass the request through without attaching a token
          next.handle(req)
        )
      )
    );
  }
Example #16
Source File: add-edit-advance-request.page.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
async showPolicyModal(
    violatedPolicyRules: string[],
    policyViolationActionDescription: string,
    event: string,
    advanceRequest
  ) {
    return iif(
      () => advanceRequest && advanceRequest.id && advanceRequest.org_user_id,
      this.statusService.findLatestComment(advanceRequest.id, 'advance_requests', advanceRequest.org_user_id),
      of(null)
    ).subscribe(async (latestComment) => {
      const policyViolationModal = await this.modalController.create({
        component: PolicyViolationDialogComponent,
        componentProps: {
          latestComment,
          violatedPolicyRules,
          policyViolationActionDescription,
        },
        mode: 'ios',
        presentingElement: await this.modalController.getTop(),
        ...this.modalProperties.getModalDefaultProperties(),
      });

      await policyViolationModal.present();

      const { data } = await policyViolationModal.onWillDismiss();
      if (data) {
        return this.saveAndSubmit(event, advanceRequest)
          .pipe(
            switchMap((res) =>
              iif(
                () => data.reason && data.reason !== latestComment,
                this.statusService.post('advance_requests', res.advanceReq.id, { comment: data.reason }, true),
                of(null)
              )
            ),
            finalize(() => {
              this.fg.reset();
              if (event === 'draft') {
                this.saveDraftAdvanceLoading = false;
              } else {
                this.saveAdvanceLoading = false;
              }
              if (this.from === 'TEAM_ADVANCE') {
                return this.router.navigate(['/', 'enterprise', 'team_advance']);
              } else {
                return this.router.navigate(['/', 'enterprise', 'my_advances']);
              }
            })
          )
          .subscribe(noop);
      } else {
        if (event === 'draft') {
          this.saveDraftAdvanceLoading = false;
        } else {
          this.saveAdvanceLoading = false;
        }
      }
    });
  }
Example #17
Source File: datasource.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
testDatasource() {
    // Consider only last 10 minutes otherwise request takes too long
    const startMs = Date.now() - 10 * 60 * 1000;
    const start = `${startMs}000000`; // API expects nanoseconds
    return this._request('/loki/api/v1/label', { start })
      .pipe(
        catchError((err: any) => {
          if (err.status === 404) {
            return of(err);
          }

          throw err;
        }),
        switchMap((response: { data: { values: string[] }; status: number }) =>
          iif<DataQueryResponse, any>(
            () => response.status === 404,
            defer(() => this._request('/api/prom/label', { start })),
            defer(() => of(response))
          )
        ),
        map(res => {
          const values: any[] = res?.data?.data || res?.data?.values || [];
          const testResult =
            values.length > 0
              ? { status: 'success', message: 'Data source connected and labels found.' }
              : {
                  status: 'error',
                  message:
                    'Data source connected, but no labels received. Verify that Loki and Promtail is configured properly.',
                };
          return testResult;
        }),
        catchError((err: any) => {
          let message = 'Loki: ';
          if (err.statusText) {
            message += err.statusText;
          } else {
            message += 'Cannot connect to Loki';
          }

          if (err.status) {
            message += `. ${err.status}`;
          }

          if (err.data && err.data.message) {
            message += `. ${err.data.message}`;
          } else if (err.data) {
            message += `. ${err.data}`;
          }
          return of({ status: 'error', message: message });
        })
      )
      .toPromise();
  }
Example #18
Source File: add-edit-mileage.page.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
getCustomInputs() {
    this.initialFetch = true;
    return this.fg.controls.sub_category.valueChanges.pipe(
      startWith({}),
      switchMap((category) => {
        let selectedCategory$;
        if (this.initialFetch) {
          selectedCategory$ = this.etxn$.pipe(
            switchMap((etxn) =>
              iif(
                () => etxn.tx.org_category_id,
                this.offlineService
                  .getAllEnabledCategories()
                  .pipe(
                    map((categories) =>
                      categories.find((innerCategory) => innerCategory.id === etxn.tx.org_category_id)
                    )
                  ),
                of(null)
              )
            )
          );
        }

        if (category && !isEmpty(category)) {
          return of(category);
        } else {
          return this.getMileageCategories().pipe(map((mileageContainer) => mileageContainer.defaultMileageCategory));
        }
      }),
      switchMap((category) => {
        const formValue = this.fg.value;
        return this.offlineService
          .getCustomInputs()
          .pipe(
            map((customFields) =>
              this.customFieldsService.standardizeCustomFields(
                formValue.custom_inputs || [],
                this.customInputsService.filterByCategory(customFields, category && category.id)
              )
            )
          );
      }),
      map((customFields) =>
        customFields.map((customField) => {
          if (customField.options) {
            customField.options = customField.options.map((option) => ({ label: option, value: option }));
          }
          return customField;
        })
      ),
      switchMap((customFields: any[]) =>
        this.isConnected$.pipe(
          take(1),
          map((isConnected) => {
            const customFieldsFormArray = this.fg.controls.custom_inputs as FormArray;
            customFieldsFormArray.clear();
            for (const customField of customFields) {
              customFieldsFormArray.push(
                this.fb.group({
                  name: [customField.name],
                  value: [
                    customField.type !== 'DATE' ? customField.value : moment(customField.value).format('y-MM-DD'),
                    isConnected &&
                      customField.type !== 'BOOLEAN' &&
                      customField.type !== 'USER_LIST' &&
                      customField.mandatory &&
                      Validators.required,
                  ],
                })
              );
            }
            customFieldsFormArray.updateValueAndValidity();
            return customFields.map((customField, i) => ({ ...customField, control: customFieldsFormArray.at(i) }));
          })
        )
      ),
      shareReplay(1)
    );
  }
Example #19
Source File: actions.page.ts    From capture-lite with GNU General Public License v3.0 5 votes vote down vote up
doAction(action: Action) {
    this.blockingActionService
      .run$(this.canPerformAction$(action))
      .pipe(
        catchError((err: unknown) => {
          return this.errorService.toastError$(err);
        }),
        concatMap(() => this.openActionDialog$(action)),
        concatMap(createOrderInput =>
          this.blockingActionService.run$(
            forkJoin([
              this.createOrder$(
                createOrderInput.networkApp,
                createOrderInput.actionArgs
              ),
              // To display "Insufficient NUM" in order confirmation dialog,
              // we need to sync asset wallet balance if the action cost NUM.
              iif(
                () => action.action_cost_number > 0,
                this.diaBackendWalletService.syncAssetWalletBalance$(),
                VOID$
              ),
            ])
          )
        ),
        concatMap(([orderStatus, _]) => this.openOrderDialog$(orderStatus)),
        concatMap(orderId =>
          this.blockingActionService.run$(this.confirmOrder$(orderId))
        ),
        tap(networkAppOrder => {
          /*
            Workaround:
            Create a order history record only if the total cost is > 0 to prevent race condition 
            between app creating the order history record v.s. bubble workflow checking whether a 
            record already exists and if not create a new one, especially for network actions that 
            don't require any cost (and hence backend calls the webhook immediately). See 
            https://dt42-numbers.slack.com/archives/C0323488MEJ/p1648006014291339
          */
          if (Number(networkAppOrder.total_cost) !== 0) {
            this.createOrderHistory$(networkAppOrder).subscribe();
          }
        }),
        tap(() => {
          this.snackBar.open(
            this.translocoService.translate('message.sentSuccessfully')
          );
        }),
        tap(networkAppOrder => {
          if (action.ext_action_destination_text) {
            this.redirectToExternalUrl(
              action.ext_action_destination_text,
              networkAppOrder.id
            );
          }
        }),
        tap(() => {
          if (action.hide_capture_after_execution_boolean ?? false)
            this.removeCapture();
        }),
        untilDestroyed(this)
      )
      .subscribe();
  }
Example #20
Source File: api-subscription-from-web-socket.ts    From js-client with MIT License 5 votes vote down vote up
apiSubscriptionFromWebSocket = <MessageReceived, MessageSent>(
	socket: WebSocket,
): APISubscription<MessageReceived, MessageSent> => {
	const _received$ = new Subject<MessageReceived>();
	const _sent$ = new Subject<MessageSent>();
	const _toSend$ = new Subject<MessageSent>();

	const received: Array<MessageReceived> = [];
	const sent: Array<MessageSent> = [];

	_received$.subscribe(receivedMessage => received.push(receivedMessage));
	_sent$.subscribe(sentMessage => sent.push(sentMessage));

	socket.onmessage = message => {
		_received$.next(JSON.parse(message.data.toString()));
	};

	socket.onerror = err => {
		_received$.error(err);
		_sent$.error(err);
	};

	socket.onclose = () => {
		_received$.complete();
		_sent$.complete();
		_toSend$.complete();
	};

	_toSend$
		.pipe(
			// If the socket is still connecting, buffer until the socket is open. Once open, send the buffer through.
			// If the socket is already open, buffer until _toSend$ emits. Since _toSend$ is the source, each buffer contains exactly one item.
			bufferWhen(() => iif(() => getWebSocketState(socket) === 'connecting', fromEvent(socket, 'open'), _toSend$)),

			// Flatten the arrays of messages, so that the Observer gets one message at a time
			concatMap(messages => from(messages)),
		)
		.subscribe(message => {
			if (getWebSocketState(socket) !== 'open') {
				return;
			}

			if (message === undefined) {
				return;
			}
			const stringMessage = typeof message === 'string' ? message : JSON.stringify(message);
			socket.send(stringMessage);
			_sent$.next(message);
		});

	return {
		send: async message => void _toSend$.next(message),
		close: () => socket.close(),
		received,
		received$: _received$.asObservable(),
		sent,
		sent$: _sent$.asObservable(),
	};
}
Example #21
Source File: rxjsResourceStub.ts    From slickgrid-universal with MIT License 5 votes vote down vote up
iif<T = never, F = never>(condition: () => boolean, trueResult?: any, falseResult?: any): Observable<T | F> {
    return iif<T, F>(condition, trueResult, falseResult);
  }
Example #22
Source File: add-edit-per-diem.page.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
getCustomInputs() {
    this.initialFetch = true;
    return this.fg.controls.sub_category.valueChanges.pipe(
      startWith({}),
      switchMap(() => {
        const category = this.fg.controls.sub_category.value;
        if (this.initialFetch) {
          return this.etxn$.pipe(
            switchMap((etxn) =>
              iif(
                () => etxn.tx.org_category_id,
                this.offlineService
                  .getAllEnabledCategories()
                  .pipe(map((categories) => categories.find((category) => category.id === etxn.tx.org_category_id))),
                this.getPerDiemCategories().pipe(map((perDiemContainer) => perDiemContainer.defaultPerDiemCategory))
              )
            )
          );
        }

        if (category && !isEmpty(category)) {
          return of(category);
        } else {
          return this.getPerDiemCategories().pipe(map((perDiemContainer) => perDiemContainer.defaultPerDiemCategory));
        }
      }),
      switchMap((category: any) => {
        const formValue = this.fg.value;
        return this.offlineService
          .getCustomInputs()
          .pipe(
            map((customFields: any) =>
              this.customFieldsService.standardizeCustomFields(
                formValue.custom_inputs || [],
                this.customInputsService.filterByCategory(customFields, category && category.id)
              )
            )
          );
      }),
      map((customFields) =>
        customFields.map((customField) => {
          if (customField.options) {
            customField.options = customField.options.map((option) => ({ label: option, value: option }));
          }
          return customField;
        })
      ),
      switchMap((customFields: any[]) =>
        this.isConnected$.pipe(
          take(1),
          map((isConnected) => {
            const customFieldsFormArray = this.fg.controls.custom_inputs as FormArray;
            customFieldsFormArray.clear();
            for (const customField of customFields) {
              customFieldsFormArray.push(
                this.fb.group({
                  name: [customField.name],
                  value: [
                    customField.type !== 'DATE' ? customField.value : moment(customField.value).format('y-MM-DD'),
                    isConnected &&
                      customField.type !== 'BOOLEAN' &&
                      customField.type !== 'USER_LIST' &&
                      customField.mandatory &&
                      Validators.required,
                  ],
                })
              );
            }
            return customFields.map((customField, i) => ({ ...customField, control: customFieldsFormArray.at(i) }));
          })
        )
      ),
      shareReplay(1)
    );
  }
Example #23
Source File: emote.component.ts    From App with MIT License 4 votes vote down vote up
ngOnInit(): void {
		const emoteGetter = this.route.snapshot.paramMap.has('emote')
			? this.restService.awaitAuth().pipe(
				switchMap(() => this.restService.v2.GetEmote(this.route.snapshot.paramMap.get('emote') as string, true)),
				catchError(err => throwError(this.restService.formatError(err))),
				filter(res => res.emote !== null), // Initiate a new emote structure instance

				tap(res => this.appService.pageTitleAttr.next([ // Update page title
					{ name: 'EmoteName', value: res.emote?.name ?? '' },
					{ name: 'OwnerName', value: `by ${res.emote?.owner?.display_name ?? ''}` }
				])),
				map(res => this.emote = this.dataService.add('emote', res.emote)[0]),
				switchMap(emote => this.readChannels().pipe(mapTo(emote)))
			)
			: !!this.emote ? of(this.emote) : throwError(Error('Unknown Emote'));
		// Look up requested emote from route uri

		emoteGetter.pipe(
			// Update meta
			// Show this emote in discord etc!
			switchMap(emote => emote.getURL(4).pipe(
				tap(url => {
					const appURL = this.document.location.host + this.router.serializeUrl(this.router.createUrlTree(['/emotes', String(emote.getID())]));
					const emoteData = emote.getSnapshot();
					this.metaService.addTags([
						// { name: 'og:title', content: this.appService.pageTitle },
						// { name: 'og:site_name', content: this.appService.pageTitle },
						{ name: 'og:description', content: `uploaded by ${emoteData?.owner?.display_name}` },
						{ name: 'og:image', content: url ?? '' },
						{ name: 'og:image:type', content: emote.getSnapshot()?.mime ?? 'image/png' },
						{ name: 'theme-color', content: this.themingService.primary.hex() }
					]);

					// Discord OEmbed
					// TODO: Make this a proper service so it can be applied to other pages
					if (AppComponent.isBrowser.getValue() !== true) {
						const link = this.document.createElement('link');
						link.setAttribute('type', 'application/json+oembed');

						const query = new URLSearchParams();
						query.append('object', Buffer.from(JSON.stringify({
							title: this.appService.pageTitle ?? 'Unknown Page',
							author_name: ''.concat(
								`${emoteData?.name} by ${emoteData?.owner?.display_name ?? 'Unknown User'} `,
								`${BitField.HasBits(emoteData?.visibility ?? 0, DataStructure.Emote.Visibility.GLOBAL) ? '(Global Emote)' : `(${emote.getSnapshot()?.channel_count ?? 0} Channels)`}`
							),
							author_url: `https://${appURL}`,
							provider_name: `7TV.APP - It's like a third party thing`,
							provider_url: 'https://7tv.app',
							type: 'photo',
							url
						})).toString('base64'));
						link.setAttribute('href', `https://${environment.origin}/services/oembed?` + query.toString());
						this.document.head.appendChild(link);
					}
					return undefined;
				})
			)),

			// Set emote sizes
			switchMap(() => this.getSizes().pipe(
				tap(result => this.sizes.next(result))
			)),

			// Add audit logs
			switchMap(() => this.readAuditActivity().pipe(
				tap(entries => this.audit.next(entries)),
				catchError(err => of(undefined))
			)),

			tap(() => this.cdr.markForCheck()),

			// Show warning dialog for hidden emote?
			switchMap(() => (this.emote as EmoteStructure).hasVisibility('HIDDEN').pipe(
				switchMap(isHidden => iif(() => !isHidden || this.disableNotices,
					of(true),
					new Observable<boolean>(observer => {
						const dialogRef = this.dialog.open(EmoteWarningDialogComponent, {
							maxWidth: 300,
							disableClose: true
						});

						dialogRef.afterClosed().subscribe({
							next(ok): void {
								observer.next(ok);
								observer.complete();
							} // Send the result of the user either going ahead or going back
						});
					})
				)),
				tap(canShow => this.blurred.next(!canShow))
			))
		).subscribe({
			error: (err: HttpErrorResponse) => {
				this.dialog.open(ErrorDialogComponent, {
					data: {
						errorName: 'Cannot View Emote',
						errorMessage: err.error?.error ?? err.error ?? err,
						errorCode: String(err.status)
					} as ErrorDialogComponent.Data
				});
				this.router.navigate(['/emotes'], {replaceUrl: true});
			}
		});
	}
Example #24
Source File: team-reports.page.ts    From fyle-mobile-app with MIT License 4 votes vote down vote up
ionViewWillEnter() {
    this.isLoading = true;
    this.navigateBack = !!this.activatedRoute.snapshot.params.navigate_back;

    this.tasksService.getTeamReportsTaskCount().subscribe((teamReportsTaskCount) => {
      this.teamReportsTaskCount = teamReportsTaskCount;
    });

    this.loadData$ = new BehaviorSubject({
      pageNumber: 1,
      queryParams: {
        rp_approval_state: 'in.(APPROVAL_PENDING)',
        rp_state: 'in.(APPROVER_PENDING)',
        sequential_approval_turn: 'in.(true)',
      },
    });

    // Applying default filter for approvers to view approver pending reports by default
    if (!this.activatedRoute.snapshot.queryParams.filters) {
      this.activatedRoute.snapshot.queryParams = {
        filters: JSON.stringify({ state: ['APPROVER_PENDING'] }),
      };
    }

    this.homeCurrency$ = this.currencyService.getHomeCurrency();

    this.simpleSearchInput.nativeElement.value = '';
    fromEvent(this.simpleSearchInput.nativeElement, 'keyup')
      .pipe(
        map((event: any) => event.srcElement.value as string),
        debounceTime(1000),
        distinctUntilChanged()
      )
      .subscribe((searchString) => {
        const currentParams = this.loadData$.getValue();
        currentParams.searchString = searchString;
        this.currentPageNumber = 1;
        currentParams.pageNumber = this.currentPageNumber;
        this.loadData$.next(currentParams);
      });

    const paginatedPipe = this.loadData$.pipe(
      switchMap((params) => {
        let queryParams = params.queryParams;
        const orderByParams = params.sortParam && params.sortDir ? `${params.sortParam}.${params.sortDir}` : null;
        queryParams = this.apiV2Service.extendQueryParamsForTextSearch(queryParams, params.searchString);
        this.isLoadingDataInInfiniteScroll = true;
        return this.reportService.getTeamReports({
          offset: (params.pageNumber - 1) * 10,
          limit: 10,
          queryParams,
          order: orderByParams,
        });
      }),
      map((res) => {
        this.isLoadingDataInInfiniteScroll = false;
        if (this.currentPageNumber === 1) {
          this.acc = [];
        }
        this.acc = this.acc.concat(res.data);
        return this.acc;
      })
    );

    this.teamReports$ = paginatedPipe.pipe(shareReplay(1));

    this.count$ = this.loadData$.pipe(
      switchMap((params) => {
        let queryParams = params.queryParams;
        queryParams = this.apiV2Service.extendQueryParamsForTextSearch(queryParams, params.searchString);
        return this.reportService.getTeamReportsCount(queryParams);
      }),
      shareReplay(1)
    );

    const paginatedScroll$ = this.teamReports$.pipe(
      switchMap((erpts) => this.count$.pipe(map((count) => count > erpts.length)))
    );

    this.isInfiniteScrollRequired$ = this.loadData$.pipe(
      switchMap((params) => iif(() => params.searchString && params.searchString !== '', of(false), paginatedScroll$))
    );

    this.loadData$.subscribe(noop);
    this.teamReports$.subscribe(noop);
    this.count$.subscribe(noop);
    this.isInfiniteScrollRequired$.subscribe(noop);

    this.loadData$.subscribe((params) => {
      const queryParams: Params = { filters: JSON.stringify(this.filters) };
      this.router.navigate([], {
        relativeTo: this.activatedRoute,
        queryParams,
        replaceUrl: true,
      });
    });

    if (this.activatedRoute.snapshot.queryParams.filters) {
      this.filters = Object.assign({}, this.filters, JSON.parse(this.activatedRoute.snapshot.queryParams.filters));
      this.currentPageNumber = 1;
      const params = this.addNewFiltersToParams();
      this.loadData$.next(params);
      this.filterPills = this.generateFilterPills(this.filters);
    } else if (this.activatedRoute.snapshot.params.state) {
      const filters = {
        rp_state: `in.(${this.activatedRoute.snapshot.params.state.toLowerCase()})`,
        state: this.activatedRoute.snapshot.params.state.toUpperCase(),
      };

      this.filters = Object.assign({}, this.filters, filters);
      this.currentPageNumber = 1;
      const params = this.addNewFiltersToParams();
      this.loadData$.next(params);
      this.filterPills = this.generateFilterPills(this.filters);
    } else {
      this.clearFilters();
    }

    setTimeout(() => {
      this.isLoading = false;
    }, 500);
  }