rxjs#takeUntil TypeScript Examples

The following examples show how to use rxjs#takeUntil. 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: webview.component.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
public ngAfterViewInit(): void {
    this.initWebview(this.webviewContainer).catch((e) => console.error(e));
    this._electronService.on("webview-new-window", this.onWebviewNewWindow);
    this._uiMessageService.message$
      .pipe(
        takeUntil(this.destroy$),
        filter((msg) => msg.action === "ad-frame-reload")
      )
      .subscribe(() => {
        if (this._webviewReady) {
          this._tag?.reloadIgnoringCache();
        }
      });
  }
Example #2
Source File: tree-select.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
ngAfterViewInit() {
    const hasVisibleChildNodes$ = this.childNodes.changes.pipe(
      startWith(this.childNodes),
      switchMap((nodes: QueryList<TreeNodeComponent<T>>) =>
        nodes.length > 0
          ? combineLatest(nodes.map(node => node.visible$))
          : of([false]),
      ),
      map(visible => visible.some(Boolean)),
      tap(hasVisibleChildren => (this.isLeaf = !hasVisibleChildren)),
    );
    this.visible$ = combineLatest([
      this.selfVisible$,
      hasVisibleChildNodes$,
    ]).pipe(
      map(visible => visible.some(Boolean)),
      publishRef(),
    );

    this.visible$.pipe(takeUntil(this.destroy$$)).subscribe(visible => {
      this.visible = visible;
      this.cdr.markForCheck();
    });
    this.selected$.pipe(takeUntil(this.destroy$$)).subscribe(selected => {
      this.selected = selected;
      this.cdr.markForCheck();
    });

    if (this.selected) {
      requestAnimationFrame(() => {
        this.scrollToNode(this);
      });
    }
  }
Example #3
Source File: tab-header.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
/**
   * Aligns the ink bar to the selected tab on load.
   */
  ngAfterContentInit() {
    const resize = this._viewportRuler.change(150);
    const realign = () => {
      this._updatePagination();
      this._alignActiveIndicatorToSelectedTab();
    };

    this._keyManager = new FocusKeyManager(this._labelWrappers)
      .withHorizontalOrientation('ltr')
      .withWrap();
    this._keyManager.updateActiveItem(0);

    // Defer the first call in order to allow for slower browsers to lay out the elements.
    // This helps in cases where the user lands directly on a page with paginated tabs.
    typeof requestAnimationFrame !== 'undefined'
      ? requestAnimationFrame(realign)
      : realign();

    // On window resize, realign the ink bar and update the orientation of
    // the key manager if the direction has changed.
    resize.pipe(takeUntil(this._destroyed)).subscribe(() => {
      realign();
    });

    // If there is a change in the focus key manager we need to emit the `indexFocused`
    // event in order to provide a public event that notifies about focus changes. Also we realign
    // the tabs container by scrolling the new focused tab into the visible section.
    this._keyManager.change
      .pipe(takeUntil(this._destroyed))
      .subscribe(newFocusIndex => {
        this.indexFocused.emit(newFocusIndex);
        this._setTabFocus(newFocusIndex);
      });
  }
Example #4
Source File: table-scroll.directive.ts    From alauda-ui with MIT License 6 votes vote down vote up
viewMutation() {
    merge(
      observeResizeOn(this.containerEl),
      fromEvent(this.containerEl, 'scroll'),
    )
      .pipe(startWith(null), takeUntil(this.destroy$$))
      .subscribe(() => {
        this.mutateVerticalScroll();
        this.mutateHorizontalScroll();
      });
  }
Example #5
Source File: steps.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
ngOnInit() {
    this.currentIndexChange$$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(index => {
        if (this.type === 'step') {
          this.setCurrentIndex(index);
        }
      });
    this.stepsChange$$.pipe(takeUntil(this.destroy$$)).subscribe(steps => {
      if (this.type === 'progress') {
        this.getProgressCurrentIndex(steps);
      }
    });
  }
Example #6
Source File: fixed-size-table-virtual-scroll.directive.ts    From alauda-ui with MIT License 6 votes vote down vote up
ngAfterContentInit() {
    this.scrollStrategy.stickyChange
      .pipe(
        filter(() => this.isStickyEnabled()),
        tap(() => {
          if (!this.stickyPositions) {
            this.initStickyPositions();
          }
        }),
        takeUntil(this.onDestroy$),
      )
      .subscribe(stickyOffset => {
        this.setSticky(stickyOffset);
      });
    combineLatest([this.scrollStrategy.renderedRangeStream, this._dataSource$$])
      .pipe(
        map(([{ start, end }, dataSource]) =>
          typeof start !== 'number' || typeof end !== 'number'
            ? dataSource
            : dataSource?.slice(start, end),
        ),
        takeUntil(this.onDestroy$),
      )
      .subscribe(data => {
        this.table.dataSource = data;
      });
  }
Example #7
Source File: radio-button.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
override ngOnInit() {
    super.ngOnInit();
    this.radioGroup.size$.pipe(takeUntil(this.destroy$$)).subscribe(size => {
      this.size = size;
      this.cdr.markForCheck();
    });
    this.radioGroup.isPlain$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(isPlain => {
        this.isPlain = isPlain;
        this.cdr.markForCheck();
      });
  }
Example #8
Source File: base-radio.ts    From alauda-ui with MIT License 6 votes vote down vote up
ngOnInit() {
    this.radioGroup.name$.pipe(takeUntil(this.destroy$$)).subscribe(name => {
      this.name = name;
      this.cdr.markForCheck();
    });

    combineLatest([this.radioGroup.model$, this.value$$])
      .pipe(
        takeUntil(this.destroy$$),
        map(([groupValue, selfValue]) => groupValue === selfValue),
      )
      .subscribe(checked => {
        this.checked = checked;
        this.cdr.markForCheck();
      });
  }
Example #9
Source File: form-item.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
subscribeInputsFromParent() {
    this.auiForm.labelWidth$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(width => {
        this.labelWidth = width;
        this.cdr.markForCheck();
      });
    this.auiForm.labelPosition$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(position => {
        this.labelPosition = position;
        this.cdr.markForCheck();
      });
    this.auiForm.emptyAddon$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(emptyAddon => {
        this.emptyAddon = emptyAddon;
        this.cdr.markForCheck();
      });
  }
Example #10
Source File: drawer.service.ts    From alauda-ui with MIT License 6 votes vote down vote up
private createDrawer(): void {
    this.overlayRef = this.overlay.create();
    this.drawerRef = this.overlayRef.attach(
      new ComponentPortal(DrawerComponent),
    );
    this.drawerRef.instance.drawerViewInit
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(() => {
        this.drawerRef.instance.open();
      });

    this.drawerRef.instance.afterClosed
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(() => {
        this.overlayRef.dispose();
        this.drawerRef = null;
        this.unsubscribe$.next();
        this.unsubscribe$.complete();
      });
  }
Example #11
Source File: drawer.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
private attachOverlay() {
    if (!this.overlayRef) {
      this.portal = new TemplatePortal(
        this.drawerTemplate,
        this.viewContainerRef,
      );
      this.overlayRef = this.overlay.create(this.getOverlayConfig());
    }
    if (this.overlayRef) {
      this.overlayRef.attach(this.portal);
      this.overlayRef
        .outsidePointerEvents()
        .pipe(takeUntil(this.onDestroy$))
        .subscribe(event => {
          // 判断鼠标点击事件的 target 是否为 overlay-container 的子节点,如果是,则不关闭 drawer。
          // 为了避免点击 drawer 里的 tooltip 后 drawer 被关闭。
          if (
            this.visible &&
            this.hideOnClickOutside &&
            event.target instanceof Node &&
            !this.overlayRef.hostElement?.parentNode?.contains(event.target)
          ) {
            event.stopPropagation();
            event.preventDefault();
            this.dispose();
          }
        });
    }
  }
Example #12
Source File: checkbox.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
constructor(
    cdr: ChangeDetectorRef,
    @Optional()
    @Inject(forwardRef(() => CheckboxGroupComponent))
    checkboxGroup: CheckboxGroupComponent<T>,
    private readonly focusMonitor: FocusMonitor,
  ) {
    super(cdr);
    this.checkboxGroup = checkboxGroup;
    if (this.checkboxGroup) {
      combineLatest([this.checkboxGroup.model$, this.label$$])
        .pipe(
          takeUntil(this.destroy$$),
          map(([values, label]) => {
            if (this.checkboxGroup.trackFn) {
              return values?.some(
                v =>
                  this.checkboxGroup.trackFn(v) ===
                  this.checkboxGroup.trackFn(label),
              );
            }
            return values?.includes(label);
          }),
        )
        .subscribe(checked => {
          this.writeValue(!!checked);
        });
    }
  }
Example #13
Source File: autocomplete.directive.ts    From alauda-ui with MIT License 6 votes vote down vote up
override ngAfterViewInit() {
    const input = this.input;

    merge(
      fromEvent(this.elRef.nativeElement, 'click'),
      fromEvent(input, 'focus'),
    )
      .pipe(debounceTime(0), takeUntil(this.unsubscribe$))
      .subscribe(() => this.onFocus());

    fromEvent(input, 'blur')
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(() => this.onBlur());

    fromEvent(input, 'input')
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(ev => this.onInput(ev));

    fromEvent<KeyboardEvent>(input, 'keydown')
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(ev => this.onKeyDown(ev));
  }
Example #14
Source File: autocomplete.directive.ts    From alauda-ui with MIT License 6 votes vote down vote up
ngOnInit() {
    this.show.subscribe(() => {
      this.updateSuggestionsContext();
    });
    this.hide.subscribe(() => {
      this.resetFocusedSuggestion();
    });

    if (this.ngControl) {
      this.ngControl.valueChanges
        .pipe(takeUntil(this.unsubscribe$))
        .subscribe((value: string | string[]) => {
          if (!Array.isArray(value)) {
            this.inputValue$$.next(value);
          }
        });

      this.ngControl.statusChanges
        .pipe(startWith(this.ngControl.status), takeUntil(this.unsubscribe$))
        .subscribe(status => {
          this.disabled = status === 'DISABLED';
        });
    }
  }
Example #15
Source File: anchor.directive.ts    From alauda-ui with MIT License 6 votes vote down vote up
adaptAnchorPosition(containerEl: HTMLElement, anchorEl: HTMLElement) {
    const pageContentEl = containerEl.closest('.aui-page__content');
    const anchorContentEl = anchorEl.querySelector('.aui-anchor');

    merge(observeResizeOn(containerEl), fromEvent(window, 'scroll'))
      .pipe(startWith(null as void), takeUntil(this.destroy$$))
      .subscribe(() => {
        const containerRect = containerEl.getBoundingClientRect();
        Object.assign(anchorEl.style, {
          display: !containerRect.width || !containerRect.height ? 'none' : '',
          left:
            containerRect.right -
            anchorContentEl.getBoundingClientRect().width +
            'px',
          top:
            Math.max(
              containerRect.top,
              (this.minTop ??
                (pageContentEl &&
                  +getComputedStyle(pageContentEl).paddingTop.slice(0, -2))) ||
                0,
            ) + 'px',
        });
      });

    if (this.adaptPosition) {
      observeResizeOn(anchorContentEl)
        .pipe(takeUntil(this.destroy$$))
        .subscribe(el => {
          const width = el.getBoundingClientRect().width;
          const padding = width + this.padding;
          containerEl.style.paddingRight = padding + 'px';
        });
    }
  }
Example #16
Source File: anchor.directive.ts    From alauda-ui with MIT License 6 votes vote down vote up
ngAfterContentInit() {
    const containerEl = this.containerEl;
    this.anchorPortal = new ComponentPortal(AnchorComponent);
    const portalOutlet = new DomPortalOutlet(
      document.body,
      this.cfr,
      this.appRef,
      this.injector,
    );
    const anchorComponentRef = this.anchorPortal.attach(portalOutlet);
    const anchorEl = anchorComponentRef.injector.get(ElementRef)
      .nativeElement as HTMLElement;

    requestAnimationFrame(() =>
      this.adaptAnchorPosition(containerEl, anchorEl),
    );

    this.anchorLabels.changes
      .pipe(startWith(this.anchorLabels), takeUntil(this.destroy$$))
      .subscribe((anchorLabels: QueryList<AnchorLabelDirective>) => {
        Object.assign(anchorComponentRef.instance, {
          items: anchorLabels.toArray(),
        });
      });
  }
Example #17
Source File: anchor.component.ts    From alauda-ui with MIT License 6 votes vote down vote up
watchLabelsChange() {
    this.depose$$.next();
    const cdr = this.injector.get(ChangeDetectorRef);
    // FIXME: Is there any better way to achieve this?
    combineLatest(
      this.treeItems.map(({ labelChange }) => labelChange).filter(Boolean),
    )
      .pipe(debounceTime(0), takeUntil(this.depose$$))
      .subscribe(() => cdr.markForCheck());
  }
Example #18
Source File: options-addon-section.component.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
public constructor(
    private _addonProviderService: AddonProviderFactory,
    private _sensitiveStorageService: SensitiveStorageService,
    private _translateService: TranslateService,
    private _dialogFactory: DialogFactory,
    private _linkService: LinkService
  ) {
    this._addonProviderService.addonProviderChange$.subscribe(() => {
      this.loadProviderStates();
    });

    this.preferenceForm.valueChanges
      .pipe(
        takeUntil(this.destroy$),
        debounceTime(300),
        switchMap((ch) => {
          const tasks: Observable<any>[] = [];
          if (typeof ch?.cfV2ApiKey === "string") {
            tasks.push(from(this._sensitiveStorageService.setAsync(PREF_CF2_API_KEY, ch.cfV2ApiKey)));
          }
          if (typeof ch?.ghPersonalAccessToken === "string") {
            tasks.push(
              from(this._sensitiveStorageService.setAsync(PREF_GITHUB_PERSONAL_ACCESS_TOKEN, ch.ghPersonalAccessToken))
            );
          }
          return combineLatest(tasks);
        }),
        catchError((e) => {
          console.error(e);
          return of(undefined);
        })
      )
      .subscribe();
  }
Example #19
Source File: webview.component.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
private onWebviewReady = () => {
    console.debug("onWebviewReady", this._tag);

    this._webviewReady = true;

    this._sessionService.debugAdFrame$.pipe(takeUntil(this.destroy$)).subscribe(() => {
      if (!this._tag.isDevToolsOpened()) {
        this._tag?.openDevTools();
      }
    });

    this._tag.removeEventListener("dom-ready", this.onWebviewReady);
    // this._tag.openDevTools();
  };
Example #20
Source File: date-tooltip-cell.component.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
public agInit(params: ICellRendererParams): void {
    this.params = params;

    this.time$.next(this.params.value as string);

    combineLatest([this._electronService.windowFocused$, timer(0, 30000)])
      .pipe(takeUntil(this._destroy$))
      .subscribe(([focused]) => {
        if (!focused && this.relativeTime$.value.length > 0) {
          return;
        }

        const [fmt, val] = getRelativeDateFormat(this.params.value as string);
        if (!fmt) {
          return this.relativeTime$.next("ERR");
        }
        this.relativeTime$.next(this._translateService.instant(fmt, val) as string);
      });
  }
Example #21
Source File: autosize.directive.ts    From alauda-ui with MIT License 5 votes vote down vote up
ngAfterViewInit() {
    this.ngControl.valueChanges
      .pipe(startWith(null as void), takeUntil(this.destroy$$))
      .subscribe(() => this.resizeTextarea());
  }
Example #22
Source File: anchor.component.ts    From alauda-ui with MIT License 5 votes vote down vote up
ngAfterViewInit() {
    const { injectId, containerEl, scrollableEl } = this.parent;
    const pageContentEl = containerEl.closest('.aui-page__content');
    const paddingTop = pageContentEl
      ? +getComputedStyle(pageContentEl).paddingTop.slice(0, -2)
      : 0;
    fromEvent(scrollableEl, 'scroll')
      .pipe(
        debounceTime(100),
        switchMap(() => {
          const { scrollTop } =
            scrollableEl === window
              ? document.documentElement
              : (scrollableEl as HTMLElement);
          const activedItem =
            this.items.find(
              ({ target }) =>
                target.offsetTop +
                  target.offsetHeight / 2 +
                  ((scrollableEl === window &&
                    (target.offsetParent as HTMLElement)?.offsetTop) ||
                    0) >
                scrollTop + paddingTop,
            ) || last(this.items);
          return activedItem ? of(activedItem) : EMPTY;
        }),
        tap(activedItem => {
          if (activedItem.id) {
            this.activeId = activedItem.id;
            this.cdr.markForCheck();
          }
        }),
        debounceTime(100),
        tap(activedItem => {
          if (injectId && activedItem.id) {
            history.replaceState(
              null,
              null,
              location.pathname + location.search + '#' + activedItem.id,
            );
          }
        }),
        takeUntil(this.destroy$$),
      )
      .subscribe();
  }
Example #23
Source File: base-select.ts    From alauda-ui with MIT License 5 votes vote down vote up
ngAfterViewInit() {
    this.allOptions$ = combineLatest([
      this.customOptions.changes.pipe(startWith(this.customOptions)),
      this.contentOptions.changes.pipe(startWith(this.contentOptions)),
    ]).pipe(
      map(
        ([customOptions, contentOptions]: [
          QueryList<OptionComponent<T>>,
          QueryList<OptionComponent<T>>,
        ]) => [...customOptions.toArray(), ...contentOptions.toArray()],
      ),
      publishRef(),
    );

    // support dynamic options loading on filtering
    this.allOptions$.pipe(takeUntil(this.destroy$$)).subscribe(() => {
      if (this.opened) {
        requestAnimationFrame(() => {
          this.autoFocusFirstOption();
        });
      }
    });

    this.hasMatchedOption$ = combineLatest([
      this.allOptions$.pipe(
        map(customOptions =>
          customOptions.filter(option => option !== this.inputtingOption),
        ),
        // eslint-disable-next-line sonarjs/no-identical-functions
        switchMap(options =>
          options.length > 0
            ? combineLatest(options.map(option => option.value$))
            : of([] as T[]),
        ),
      ),
      this.filterString$,
    ]).pipe(
      map(([values, filterString]) =>
        values.some(value => this.trackFn(value) === filterString),
      ),
      publishRef(),
    );

    this.hasVisibleOption$ = (
      this.contentOptions.changes as Observable<QueryList<OptionComponent<T>>>
    ).pipe(
      startWith(this.contentOptions),
      switchMap((options: QueryList<OptionComponent<T>>) =>
        options.length > 0
          ? combineLatest(options.map(option => option.visible$))
          : of([] as boolean[]),
      ),
      map(visible => visible.some(Boolean)),
      publishRef(),
    );
  }
Example #24
Source File: toc-container.directive.ts    From alauda-ui with MIT License 5 votes vote down vote up
ngAfterContentInit() {
    const actived$ = this._scrollTop$
      .pipe(
        startWith(this.scrollTop),
        debounceTime(200),
        map(scrollTop =>
          this._contents.reduce(
            this.isScrollEnd
              ? this.getMaxContent.bind(this)
              : this.getMinContent(scrollTop),
          ),
        ),
        map(actived => actived.auiTocContent),
      )
      .pipe(
        tap(actived => {
          this._contents.forEach(content => {
            content.active = actived === content.auiTocContent;
          });
          this.cdr.detectChanges();
        }),
      );

    const scrollTween$ = this._scrollTo$.pipe(
      switchMap(name => {
        const target = this._contents.find(
          content => content.auiTocContent === name,
        );

        if (!target) {
          return EMPTY;
        }
        const destination = this.getOffsetTop(target.nativeElement);

        const start = performance.now();
        const source = this.scrollTop;
        const duration = 500;

        return of(0).pipe(
          observeOn(animationFrameScheduler),
          repeat(),
          map(() => (performance.now() - start) / duration),
          takeWhile(t => t < 1),
          endWith(1),
          map(t => t * t * t),
          map(t => source * (1 - t) + destination * t),
        );
      }),
      takeUntil(this._onDestroy$),
    );

    this._subs.push(
      actived$.subscribe(this.activedChange),
      scrollTween$.subscribe(tweenValue => {
        this.scrollTop = tweenValue;
      }),
    );
  }
Example #25
Source File: theme.pipe.ts    From alauda-ui with MIT License 5 votes vote down vote up
constructor(themeService: ThemeService, cdr: ChangeDetectorRef) {
    themeService.currentTheme$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(theme => {
        this.currentTheme = theme;
        cdr.markForCheck();
      });
  }
Example #26
Source File: active-test.component.ts    From alauda-ui with MIT License 5 votes vote down vote up
ngOnInit() {
    this.tabContext.active$
      .pipe(takeUntil(this.destroy$$))
      .subscribe(active => {
        console.log(this.tabComponent.textLabel, active);
      });
  }