import { FeedobellElement } from "../FeedobellElement"; import { html, type PropertyValueMap } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { useFeedobell, type TContent, type IError } from "@feedobell/client"; import bellIcon from "../assets/bell.svg"; import "../sidebar/sidebar.ts"; import Store from "../GlobalStore.ts"; const TEST_PROJECT_ID = "68f763a363747c622a4975fa"; @customElement("feedobell-widget") export class FeedobellWidget extends FeedobellElement { @property({ attribute: "project-id" }) projectId: string = TEST_PROJECT_ID; @property({ attribute: "user-id" }) userId: string = ""; @state() private _errorMessage: string | null = null; @state() private _content: TContent[] = []; @state() private _notificationCount: number = 0; @state() private _isSidebarOpen: boolean = false; @state() private _isContentLoading = false; protected updated(_changedProperties: PropertyValueMap | Map): void { super.updated(_changedProperties); if (_changedProperties.has("projectId")) { Store.setProjectId(this.projectId) } if(_changedProperties.has("userId")) { Store.setUserId(this.userId) } } private _onIconClick = () => { this._isSidebarOpen = !this._isSidebarOpen; this._notificationCount = 0; }; private _fetchAllCallback = ( error: string | null, content: TContent[] | null ) => { if (error) { this._errorMessage = error; } if (content) { this._content = content; } }; private _onNewContentCallback = ( error: IError | null, newData: TContent | null ) => { if (newData) { if(error?.error?.message){ this._errorMessage = error.error.message } this._content = [newData, ...this._content]; if (!this._isSidebarOpen) { this._notificationCount = this._notificationCount + 1; } } }; private _onErrorCallback = (error: string) => { if (typeof error !== "string") { return; } this._errorMessage = error; }; private _disconnectedFeedobell: Function | null = null; private _handleOutsideClick = (event: MouseEvent) => { const path = event.composedPath(); if (!path.includes(this)) { this._isSidebarOpen = false; } }; async connectedCallback(): Promise { super.connectedCallback(); const { connect, disconnect } = useFeedobell({ projectId: this.projectId, userId: this.userId, fetchAllCallback: this._fetchAllCallback, onErrorCallback: this._onErrorCallback, onNewContentCallback: this._onNewContentCallback, }); this._disconnectedFeedobell = disconnect; this._isContentLoading = true; await connect(); this._isContentLoading = false; document.addEventListener("click", this._handleOutsideClick); window.addEventListener('beforeunload', () => { disconnect(); }); } disconnectedCallback(): void { super.disconnectedCallback(); if (this._disconnectedFeedobell) { this._disconnectedFeedobell(); } document.removeEventListener("click", this._handleOutsideClick); } render() { return html` (this._isSidebarOpen = false)} .content=${this._content} .errorMessage=${this._errorMessage} .onErrorClear=${() => (this._errorMessage = null)} .isContentLoading=${this._isContentLoading} > `; } } declare global { interface HTMLElementTagNameMap { "feedobell-widget": FeedobellWidget; } }