import { animate, state, style, transition, trigger, } from "@angular/animations"; import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { CapableWidget, WIDGET_API_VERSION_OPENID } from "../capable-widget"; import { fromEvent } from "rxjs"; import { distinctUntilChanged, filter, map, pairwise, share, throttleTime, } from "rxjs/operators"; import { Subscription } from "rxjs/Subscription"; import { ScalarWidgetApi } from "../../shared/services/scalar/scalar-widget.api"; import { StickerApiService } from "../../shared/services/integrations/sticker-api.service"; import { SessionStorage } from "../../shared/SessionStorage"; import { ScalarServerApiService } from "../../shared/services/scalar/scalar-server-api.service"; import { FE_Sticker, FE_UserStickerPack, } from "../../shared/models/integration"; import { MediaService } from "../../shared/services/media.service"; import { WIDGET_STICKER_PICKER } from "../../shared/models/widget"; @Component({ selector: "my-generic-widget-wrapper", templateUrl: "sticker-picker.component.html", styleUrls: ["sticker-picker.component.scss"], animations: [ trigger("hideList", [ state("hidden", style({ opacity: 0, transform: "translateY(100%)" })), state("visible", style({ opacity: 1, transform: "translateY(0)" })), transition("* => *", animate("200ms ease-in")), ]), ], }) export class StickerPickerWidgetWrapperComponent extends CapableWidget implements OnInit, OnDestroy, AfterViewInit { public isLoading = true; public isListVisible = true; public authError = false; public packs: FE_UserStickerPack[]; private stickerWidgetApiSubscription: Subscription; constructor( activatedRoute: ActivatedRoute, private media: MediaService, private scalarApi: ScalarServerApiService, private stickerApi: StickerApiService, private changeDetector: ChangeDetectorRef ) { super(); this.supportsStickers = true; const params: any = activatedRoute.snapshot.queryParams; let token = params.scalar_token; if (!token) token = localStorage.getItem("dim-scalar-token"); else localStorage.setItem("dim-scalar-token", token); if (!params.widgetId) { console.error("No widgetId query parameter"); this.authError = true; this.isLoading = false; } else { ScalarWidgetApi.widgetId = params.widgetId; } if (!this.authError) { SessionStorage.scalarToken = token; this.authError = !token; this.isLoading = !this.authError; } } public ngOnInit() { super.ngOnInit(); this.stickerWidgetApiSubscription = ScalarWidgetApi.requestReceived.subscribe((request) => { if (request.action === "visibility") { if ((request).visible) this.loadStickers(); ScalarWidgetApi.replyAcknowledge(request); } }); this.loadStickers(); } public ngOnDestroy() { super.ngOnDestroy(); if (this.stickerWidgetApiSubscription) this.stickerWidgetApiSubscription.unsubscribe(); } public ngAfterViewInit() { const scroll$ = fromEvent(window, "scroll").pipe( throttleTime(10), map(() => window.pageYOffset), pairwise(), map(([y1, y2]): string => (y2 < y1 ? "up" : "down")), distinctUntilChanged(), share() ); const scrollUp$ = scroll$.pipe(filter((direction) => direction === "up")); const scrollDown = scroll$.pipe( filter((direction) => direction === "down") ); scrollUp$.subscribe(() => (this.isListVisible = true)); scrollDown.subscribe(() => (this.isListVisible = false)); } protected onSupportedVersionsFound(): void { super.onSupportedVersionsFound(); if ( this.authError && this.doesSupportAtLeastVersion(WIDGET_API_VERSION_OPENID) ) { this.isLoading = true; this.changeDetector.detectChanges(); this.getOpenIdInfo().then(async (response) => { if (response.blocked) { this.isLoading = false; this.authError = true; this.changeDetector.detectChanges(); return; } try { const registerResponse = await this.scalarApi.register( response.openId ); localStorage.setItem( "dim-scalar-token", registerResponse.scalar_token ); SessionStorage.scalarToken = registerResponse.scalar_token; this.authError = !SessionStorage.scalarToken; this.isLoading = false; this.loadStickers(); } catch (e) { console.error(e); this.isLoading = false; this.authError = true; } this.changeDetector.detectChanges(); }); } } public getThumbnailUrl( mxc: string, width: number, height: number, method: "crop" | "scale" = "scale" ): string { return this.media.getThumbnailUrl(mxc, width, height, method, true); } private async loadStickers() { if (this.authError) return; // Don't bother if (!SessionStorage.userId) { try { const info = await this.scalarApi.getAccount(); SessionStorage.userId = info.user_id; console.log( "Dimension scalar_token belongs to " + SessionStorage.userId ); } catch (e) { console.error(e); this.authError = true; this.isLoading = false; return; } } console.log("Attempting to load available stickers..."); try { const packs = await this.stickerApi.getPacks(); this.packs = packs.filter((p) => p.isSelected); console.log( "User has " + this.packs.length + "/" + packs.length + " sticker packs selected" ); this.isLoading = false; this.changeDetector.markForCheck(); } catch (e) { console.error(e); } } public scrollHorizontal(event: WheelEvent): void { document.getElementsByClassName("sticker-pack-list")[0].scrollLeft += event.deltaY; event.preventDefault(); } public scrollToPack(id: string) { const el = document.getElementById(id); el.scrollIntoView({ behavior: "smooth" }); } public sendSticker(sticker: FE_Sticker, pack: FE_UserStickerPack) { ScalarWidgetApi.sendSticker(sticker, pack); } public openIntegrationManager() { ScalarWidgetApi.openIntegrationManager( WIDGET_STICKER_PICKER[0], ScalarWidgetApi.widgetId ); } }