@arthakosh/chat-widget 0.2.25 → 0.2.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,7 @@ export class ChatService {
11
11
  this.currentUser = signal(null);
12
12
  this.userList = signal([]);
13
13
  this.archiveRoomId = signal('');
14
+ this.notifications = signal([]);
14
15
  }
15
16
  get baseUrl() {
16
17
  return this.config.apiBaseUrl;
@@ -86,4 +87,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
86
87
  type: Inject,
87
88
  args: [CHAT_CONFIG]
88
89
  }] }] });
89
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2hhdC13aWRnZXQvc3JjL2xpYi9jb3JlL3NlcnZpY2VzL2NoYXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFekQsT0FBTyxFQUFDLEdBQUcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR25DLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBSWxELE1BQU0sT0FBTyxXQUFXO0lBT3BCLFlBQW9CLElBQWdCLEVBQStCLE1BQWtCO1FBQWpFLFNBQUksR0FBSixJQUFJLENBQVk7UUFBK0IsV0FBTSxHQUFOLE1BQU0sQ0FBWTtRQU5yRiwwREFBMEQ7UUFFMUQsZ0JBQVcsR0FBRyxNQUFNLENBQWEsSUFBSSxDQUFDLENBQUM7UUFDdkMsYUFBUSxHQUFHLE1BQU0sQ0FBUSxFQUFFLENBQUMsQ0FBQztRQUM3QixrQkFBYSxHQUFHLE1BQU0sQ0FBUyxFQUFFLENBQUMsQ0FBQztJQUduQyxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsa0RBQWtEO0lBQ2xELFVBQVUsQ0FBQyxNQUFjLEVBQUUsSUFBWSxFQUFFLFFBQWdCLEVBQUUsU0FBaUIsRUFBRSxRQUFnQixFQUFFLFNBQWM7UUFDMUcsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLDhCQUE4QixNQUFNLEdBQUcsRUFBRTtZQUMxRSxJQUFJO1lBQ0osUUFBUTtZQUNSLFNBQVM7WUFDVCxRQUFRO1lBQ1IsU0FBUztTQUNaLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxZQUFZLENBQUMsTUFBYztR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RCxXQUFXLENBQUMsTUFBYztRQUN0QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sK0JBQStCLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDNUYsQ0FBQzsrR0FwR1EsV0FBVyw0Q0FPMEIsV0FBVzttSEFQaEQsV0FBVyxjQURDLE1BQU07OzRGQUNsQixXQUFXO2tCQUR2QixVQUFVO21CQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQzs7MEJBUVcsTUFBTTsyQkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGUsIHNpZ25hbH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7SHR0cENsaWVudH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQge21hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQge09ic2VydmFibGV9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQge0NoYXRNZXNzYWdlfSBmcm9tICcuLi9tb2RlbHMvY2hhdC5tb2RlbHMnO1xyXG5pbXBvcnQge0NIQVRfQ09ORklHfSBmcm9tIFwiLi4vY29uZmlnL2NoYXQudG9rZW5zXCI7XHJcbmltcG9ydCB7Q2hhdENvbmZpZ30gZnJvbSBcIi4uL2NvbmZpZy9jaGF0LWNvbmZpZ1wiO1xyXG5cclxuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXHJcbmV4cG9ydCBjbGFzcyBDaGF0U2VydmljZSB7XHJcbiAgICAvLyBwcml2YXRlIGJhc2VVcmwgPSBgaHR0cHM6Ly9jb3JldWF0YXJ0aGtvc2guc2FyamFrLmNvbWA7XHJcblxyXG4gICAgY3VycmVudFVzZXIgPSBzaWduYWw8YW55IHwgbnVsbD4obnVsbCk7XHJcbiAgICB1c2VyTGlzdCA9IHNpZ25hbDxhbnlbXT4oW10pO1xyXG4gICAgYXJjaGl2ZVJvb21JZCA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsIEBJbmplY3QoQ0hBVF9DT05GSUcpIHByaXZhdGUgY29uZmlnOiBDaGF0Q29uZmlnKSB7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGJhc2VVcmwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmFwaUJhc2VVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgLyogLS0tLS0tLS0tLS0tLS0tLSBDSEFUIFJPT01TIC0tLS0tLS0tLS0tLS0tLS0gKi9cclxuICAgIGNyZWF0ZVJvb20ocm9vbUlkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgbWV0YWRhdGE6IHN0cmluZywgY3JlYXRlZEJ5OiBzdHJpbmcsIHVzZXJuYW1lOiBzdHJpbmcsIGNoYXRVc2VyczogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoYCR7dGhpcy5iYXNlVXJsfS9hcGkvY2hhdC9jaGF0cm9vbXMvY3JlYXRlLyR7cm9vbUlkfS9gLCB7XHJcbiAgICAgICAgICAgIG5hbWUsXHJcbiAgICAgICAgICAgIG1ldGFkYXRhLFxyXG4gICAgICAgICAgICBjcmVhdGVkQnksXHJcbiAgICAgICAgICAgIHVzZXJuYW1lLFxyXG4gICAgICAgICAgICBjaGF0VXNlcnNcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRSb29tVXNlcnMocm9vbUlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueVtdPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55W10+KGAke3RoaXMuYmFzZVVybH0vYXBpL2NoYXQvY2hhdHJvb21zL2dldF91c2VyLyR7cm9vbUlkfS91c2Vycy9gKS5waXBlKFxyXG4gICAgICAgICAgICBtYXAobGlzdCA9PlxyXG4gICAgICAgICAgICAgICAgbGlzdC5tYXAodSA9PiAoe1xyXG4gICAgICAgICAgICAgICAgICAgIGlkOiB1LlVzZXJJZCxcclxuICAgICAgICAgICAgICAgICAgICB1c2VybmFtZTogdS5Vc2VyTmFtZVxyXG4gICAgICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFVzZXJUb1Jvb20ocm9vbUlkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nLCB1c2VyTmFtZTogc3RyaW5nLCBjcmVhdGVkQnk6IHN0cmluZykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucG9zdChgJHt0aGlzLmJhc2VVcmx9L2FwaS9jaGF0L2NoYXRyb29tcy9hZGRfdXNlci8ke3Jvb21JZH0vdXNlcnMvYWRkL2AsIHtcclxuICAgICAgICAgICAgdXNlcklkLFxyXG4gICAgICAgICAgICB1c2VyTmFtZSxcclxuICAgICAgICAgICAgY3JlYXRlZEJ5XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyogLS0tLS0tLS0tLS0tLS0tLSBNRVNTQUdFUyAtLS0tLS0tLS0tLS0tLS0tICovXHJcbiAgICBnZXRNZXNzYWdlcyhyb29tSWQ6IHN0cmluZywgc2luY2U/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPENoYXRNZXNzYWdlW10+IHtcclxuICAgICAgICBjb25zdCBwYXJhbXM6IGFueSA9IHt9O1xyXG4gICAgICAgIGlmIChzaW5jZSkgcGFyYW1zLnNpbmNlID0gc2luY2U7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueVtdPihgJHt0aGlzLmJhc2VVcmx9L2FwaS9jaGF0L21lc3NhZ2VzL3Jvb21zL2FsbF9tZXNzYWdlcy8ke3Jvb21JZH0vYCwge3BhcmFtc30pLnBpcGUoXHJcbiAgICAgICAgICAgIG1hcChsaXN0ID0+XHJcbiAgICAgICAgICAgICAgICBsaXN0Lm1hcChtID0+ICh7XHJcbiAgICAgICAgICAgICAgICAgICAgaWQ6IG0uaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgY2hhdFJvb21JZDogbS5jaGF0Um9vbUlkLFxyXG4gICAgICAgICAgICAgICAgICAgIHNlbmRlcklkOiBtLnNlbmRlcklkLFxyXG4gICAgICAgICAgICAgICAgICAgIHNlbmRlck5hbWU6IG0uc2VuZGVyTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBtLmNvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVwbHlUb01lc3NhZ2VJZDogbS5yZXBseVRvTWVzc2FnZUlkLFxyXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWRBdDogbS5jcmVhdGVkQXQsXHJcbiAgICAgICAgICAgICAgICAgICAgaGFzQXR0YWNobWVudDogbS5oYXNBdHRhY2htZW50ID8/IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHNlbmRNZXNzYWdlKFxyXG4gICAgICAgIHJvb21JZDogc3RyaW5nLFxyXG4gICAgICAgIHBheWxvYWQ6IHtcclxuICAgICAgICAgICAgc2VuZGVySWQ6IHN0cmluZztcclxuICAgICAgICAgICAgc2VuZGVyTmFtZTogc3RyaW5nLFxyXG4gICAgICAgICAgICBjb250ZW50OiBzdHJpbmc7XHJcbiAgICAgICAgICAgIHJlcGx5VG9NZXNzYWdlSWQ/OiBzdHJpbmcgfCBudWxsLFxyXG4gICAgICAgICAgICBjcmVhdGVkQnk6IHN0cmluZ1xyXG4gICAgICAgIH1cclxuICAgICk6IE9ic2VydmFibGU8Q2hhdE1lc3NhZ2U+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8YW55PihgJHt0aGlzLmJhc2VVcmx9L2FwaS9jaGF0L21lc3NhZ2VzL3Jvb21zL3NlbmQvJHtyb29tSWR9L2AsIHBheWxvYWQpLnBpcGUoXHJcbiAgICAgICAgICAgIG1hcChtID0+ICh7XHJcbiAgICAgICAgICAgICAgICBpZDogbS5pZCxcclxuICAgICAgICAgICAgICAgIGNoYXRSb29tSWQ6IG0uY2hhdFJvb21JZCxcclxuICAgICAgICAgICAgICAgIHNlbmRlcklkOiBtLnNlbmRlcklkLFxyXG4gICAgICAgICAgICAgICAgc2VuZGVyTmFtZTogbS5zZW5kZXJOYW1lLFxyXG4gICAgICAgICAgICAgICAgY29udGVudDogbS5jb250ZW50LFxyXG4gICAgICAgICAgICAgICAgcmVwbHlUb01lc3NhZ2VJZDogbS5yZXBseVRvTWVzc2FnZUlkLFxyXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBtLmNyZWF0ZWRBdCxcclxuICAgICAgICAgICAgICAgIGhhc0F0dGFjaG1lbnQ6IG0uaGFzQXR0YWNobWVudCA/PyBmYWxzZSxcclxuICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRSb29tcyhsb2dnZWRJblVzZXJJZDogc3RyaW5nLCBjaGF0Um9vbUlkPzogc3RyaW5nKSB7XHJcbiAgICAgICAgbGV0IHVybCA9IGAke3RoaXMuYmFzZVVybH0vYXBpL2NoYXQvY2hhdHJvb21zLyR7bG9nZ2VkSW5Vc2VySWR9YDtcclxuICAgICAgICBpZiAoY2hhdFJvb21JZCkge1xyXG4gICAgICAgICAgICB1cmwgKz0gYC8ke2NoYXRSb29tSWR9YDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55W10+KGAke3VybH0vYCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGFyY2hpdmVSb29tKHJvb21JZDogc3RyaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5kZWxldGU8YW55W10+KGAke3RoaXMuYmFzZVVybH0vYXBpL2NoYXQvY2hhdHJvb21zL2FyY2hpdmUvJHtyb29tSWR9L2ApO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2hhdC13aWRnZXQvc3JjL2xpYi9jb3JlL3NlcnZpY2VzL2NoYXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFekQsT0FBTyxFQUFDLEdBQUcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR25DLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBS2xELE1BQU0sT0FBTyxXQUFXO0lBUXBCLFlBQW9CLElBQWdCLEVBQStCLE1BQWtCO1FBQWpFLFNBQUksR0FBSixJQUFJLENBQVk7UUFBK0IsV0FBTSxHQUFOLE1BQU0sQ0FBWTtRQVByRiwwREFBMEQ7UUFFMUQsZ0JBQVcsR0FBRyxNQUFNLENBQWEsSUFBSSxDQUFDLENBQUM7UUFDdkMsYUFBUSxHQUFHLE1BQU0sQ0FBUSxFQUFFLENBQUMsQ0FBQztRQUM3QixrQkFBYSxHQUFHLE1BQU0sQ0FBUyxFQUFFLENBQUMsQ0FBQztRQUNuQyxrQkFBYSxHQUFHLE1BQU0sQ0FBcUIsRUFBRSxDQUFDLENBQUM7SUFHL0MsQ0FBQztJQUVELElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7SUFDbEMsQ0FBQztJQUVELGtEQUFrRDtJQUNsRCxVQUFVLENBQUMsTUFBYyxFQUFFLElBQVksRUFBRSxRQUFnQixFQUFFLFNBQWlCLEVBQUUsUUFBZ0IsRUFBRSxTQUFjO1FBQzFHLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyw4QkFBOEIsTUFBTSxHQUFHLEVBQUU7WUFDMUUsSUFBSTtZQUNKLFFBQVE7WUFDUixTQUFTO1lBQ1QsUUFBUTtZQUNSLFNBQVM7U0FD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QUFRLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBR0QsV0FBVyxDQUFDLE1BQWM7UUFDdEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBUSxHQUFHLElBQUksQ0FBQyxPQUFPLCtCQUErQixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzVGLENBQUM7K0dBckdRLFdBQVcsNENBUTBCLFdBQVc7bUhBUmhELFdBQVcsY0FEQyxNQUFNOzs0RkFDbEIsV0FBVztrQkFEdkIsVUFBVTttQkFBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUM7OzBCQVNXLE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlLCBzaWduYWx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0h0dHBDbGllbnR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHttYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHtPYnNlcnZhYmxlfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtDaGF0TWVzc2FnZX0gZnJvbSAnLi4vbW9kZWxzL2NoYXQubW9kZWxzJztcclxuaW1wb3J0IHtDSEFUX0NPTkZJR30gZnJvbSBcIi4uL2NvbmZpZy9jaGF0LnRva2Vuc1wiO1xyXG5pbXBvcnQge0NoYXRDb25maWd9IGZyb20gXCIuLi9jb25maWcvY2hhdC1jb25maWdcIjtcclxuaW1wb3J0IHtDaGF0Tm90aWZpY2F0aW9ufSBmcm9tIFwiLi4vbW9kZWxzL25vdGlmaWNhdGlvbi5tb2RlbFwiO1xyXG5cclxuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXHJcbmV4cG9ydCBjbGFzcyBDaGF0U2VydmljZSB7XHJcbiAgICAvLyBwcml2YXRlIGJhc2VVcmwgPSBgaHR0cHM6Ly9jb3JldWF0YXJ0aGtvc2guc2FyamFrLmNvbWA7XHJcblxyXG4gICAgY3VycmVudFVzZXIgPSBzaWduYWw8YW55IHwgbnVsbD4obnVsbCk7XHJcbiAgICB1c2VyTGlzdCA9IHNpZ25hbDxhbnlbXT4oW10pO1xyXG4gICAgYXJjaGl2ZVJvb21JZCA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcclxuICAgIG5vdGlmaWNhdGlvbnMgPSBzaWduYWw8Q2hhdE5vdGlmaWNhdGlvbltdPihbXSk7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LCBASW5qZWN0KENIQVRfQ09ORklHKSBwcml2YXRlIGNvbmZpZzogQ2hhdENvbmZpZykge1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBiYXNlVXJsKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5hcGlCYXNlVXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gQ0hBVCBST09NUyAtLS0tLS0tLS0tLS0tLS0tICovXHJcbiAgICBjcmVhdGVSb29tKHJvb21JZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIG1ldGFkYXRhOiBzdHJpbmcsIGNyZWF0ZWRCeTogc3RyaW5nLCB1c2VybmFtZTogc3RyaW5nLCBjaGF0VXNlcnM6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KGAke3RoaXMuYmFzZVVybH0vYXBpL2NoYXQvY2hhdHJvb21zL2NyZWF0ZS8ke3Jvb21JZH0vYCwge1xyXG4gICAgICAgICAgICBuYW1lLFxyXG4gICAgICAgICAgICBtZXRhZGF0YSxcclxuICAgICAgICAgICAgY3JlYXRlZEJ5LFxyXG4gICAgICAgICAgICB1c2VybmFtZSxcclxuICAgICAgICAgICAgY2hhdFVzZXJzXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Um9vbVVzZXJzKHJvb21JZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnlbXT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueVtdPihgJHt0aGlzLmJhc2VVcmx9L2FwaS9jaGF0L2NoYXRyb29tcy9nZXRfdXNlci8ke3Jvb21JZH0vdXNlcnMvYCkucGlwZShcclxuICAgICAgICAgICAgbWFwKGxpc3QgPT5cclxuICAgICAgICAgICAgICAgIGxpc3QubWFwKHUgPT4gKHtcclxuICAgICAgICAgICAgICAgICAgICBpZDogdS5Vc2VySWQsXHJcbiAgICAgICAgICAgICAgICAgICAgdXNlcm5hbWU6IHUuVXNlck5hbWVcclxuICAgICAgICAgICAgICAgIH0pKVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyVG9Sb29tKHJvb21JZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZywgdXNlck5hbWU6IHN0cmluZywgY3JlYXRlZEJ5OiBzdHJpbmcpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoYCR7dGhpcy5iYXNlVXJsfS9hcGkvY2hhdC9jaGF0cm9vbXMvYWRkX3VzZXIvJHtyb29tSWR9L3VzZXJzL2FkZC9gLCB7XHJcbiAgICAgICAgICAgIHVzZXJJZCxcclxuICAgICAgICAgICAgdXNlck5hbWUsXHJcbiAgICAgICAgICAgIGNyZWF0ZWRCeVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gTUVTU0FHRVMgLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG4gICAgZ2V0TWVzc2FnZXMocm9vbUlkOiBzdHJpbmcsIHNpbmNlPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxDaGF0TWVzc2FnZVtdPiB7XHJcbiAgICAgICAgY29uc3QgcGFyYW1zOiBhbnkgPSB7fTtcclxuICAgICAgICBpZiAoc2luY2UpIHBhcmFtcy5zaW5jZSA9IHNpbmNlO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxhbnlbXT4oYCR7dGhpcy5iYXNlVXJsfS9hcGkvY2hhdC9tZXNzYWdlcy9yb29tcy9hbGxfbWVzc2FnZXMvJHtyb29tSWR9L2AsIHtwYXJhbXN9KS5waXBlKFxyXG4gICAgICAgICAgICBtYXAobGlzdCA9PlxyXG4gICAgICAgICAgICAgICAgbGlzdC5tYXAobSA9PiAoe1xyXG4gICAgICAgICAgICAgICAgICAgIGlkOiBtLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgIGNoYXRSb29tSWQ6IG0uY2hhdFJvb21JZCxcclxuICAgICAgICAgICAgICAgICAgICBzZW5kZXJJZDogbS5zZW5kZXJJZCxcclxuICAgICAgICAgICAgICAgICAgICBzZW5kZXJOYW1lOiBtLnNlbmRlck5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogbS5jb250ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgIHJlcGx5VG9NZXNzYWdlSWQ6IG0ucmVwbHlUb01lc3NhZ2VJZCxcclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6IG0uY3JlYXRlZEF0LFxyXG4gICAgICAgICAgICAgICAgICAgIGhhc0F0dGFjaG1lbnQ6IG0uaGFzQXR0YWNobWVudCA/PyBmYWxzZSxcclxuICAgICAgICAgICAgICAgIH0pKVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBzZW5kTWVzc2FnZShcclxuICAgICAgICByb29tSWQ6IHN0cmluZyxcclxuICAgICAgICBwYXlsb2FkOiB7XHJcbiAgICAgICAgICAgIHNlbmRlcklkOiBzdHJpbmc7XHJcbiAgICAgICAgICAgIHNlbmRlck5hbWU6IHN0cmluZyxcclxuICAgICAgICAgICAgY29udGVudDogc3RyaW5nO1xyXG4gICAgICAgICAgICByZXBseVRvTWVzc2FnZUlkPzogc3RyaW5nIHwgbnVsbCxcclxuICAgICAgICAgICAgY3JlYXRlZEJ5OiBzdHJpbmdcclxuICAgICAgICB9XHJcbiAgICApOiBPYnNlcnZhYmxlPENoYXRNZXNzYWdlPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PGFueT4oYCR7dGhpcy5iYXNlVXJsfS9hcGkvY2hhdC9tZXNzYWdlcy9yb29tcy9zZW5kLyR7cm9vbUlkfS9gLCBwYXlsb2FkKS5waXBlKFxyXG4gICAgICAgICAgICBtYXAobSA9PiAoe1xyXG4gICAgICAgICAgICAgICAgaWQ6IG0uaWQsXHJcbiAgICAgICAgICAgICAgICBjaGF0Um9vbUlkOiBtLmNoYXRSb29tSWQsXHJcbiAgICAgICAgICAgICAgICBzZW5kZXJJZDogbS5zZW5kZXJJZCxcclxuICAgICAgICAgICAgICAgIHNlbmRlck5hbWU6IG0uc2VuZGVyTmFtZSxcclxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IG0uY29udGVudCxcclxuICAgICAgICAgICAgICAgIHJlcGx5VG9NZXNzYWdlSWQ6IG0ucmVwbHlUb01lc3NhZ2VJZCxcclxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdDogbS5jcmVhdGVkQXQsXHJcbiAgICAgICAgICAgICAgICBoYXNBdHRhY2htZW50OiBtLmhhc0F0dGFjaG1lbnQgPz8gZmFsc2UsXHJcbiAgICAgICAgICAgIH0pKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Um9vbXMobG9nZ2VkSW5Vc2VySWQ6IHN0cmluZywgY2hhdFJvb21JZD86IHN0cmluZykge1xyXG4gICAgICAgIGxldCB1cmwgPSBgJHt0aGlzLmJhc2VVcmx9L2FwaS9jaGF0L2NoYXRyb29tcy8ke2xvZ2dlZEluVXNlcklkfWA7XHJcbiAgICAgICAgaWYgKGNoYXRSb29tSWQpIHtcclxuICAgICAgICAgICAgdXJsICs9IGAvJHtjaGF0Um9vbUlkfWA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueVtdPihgJHt1cmx9L2ApO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBhcmNoaXZlUm9vbShyb29tSWQ6IHN0cmluZykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlPGFueVtdPihgJHt0aGlzLmJhc2VVcmx9L2FwaS9jaGF0L2NoYXRyb29tcy9hcmNoaXZlLyR7cm9vbUlkfS9gKTtcclxuICAgIH1cclxufVxyXG4iXX0=
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, signal, Inject, Injectable, EventEmitter, input, inject, ViewChild, Output, Input, Component, effect, ViewEncapsulation, NgModule } from '@angular/core';
2
+ import { InjectionToken, signal, Inject, Injectable, EventEmitter, input, inject, ViewChild, Output, Input, Component, effect, ViewEncapsulation, computed, NgModule } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i2 from '@angular/forms';
@@ -38,6 +38,7 @@ class ChatService {
38
38
  this.currentUser = signal(null);
39
39
  this.userList = signal([]);
40
40
  this.archiveRoomId = signal('');
41
+ this.notifications = signal([]);
41
42
  }
42
43
  get baseUrl() {
43
44
  return this.config.apiBaseUrl;
@@ -256,6 +257,12 @@ class ChatWindowComponent {
256
257
  this.socket.on('newMessage').subscribe(msg => {
257
258
  if (msg.chatRoomId === this.chatRoomId) {
258
259
  this.messages.update(list => [...list, msg]);
260
+ this.upsertNotification({
261
+ roomId: msg.chatRoomId,
262
+ // roomName: msg.roomName,
263
+ type: 'message',
264
+ // lastMessage: msg.message
265
+ });
259
266
  }
260
267
  // if (msg.senderId !== this.chatService.currentUser().userId) {
261
268
  // this.messageService.add({
@@ -280,6 +287,12 @@ class ChatWindowComponent {
280
287
  this.socket.on('addedToRoom').subscribe((msg) => {
281
288
  if (msg.chatRoomId === this.chatRoomId) {
282
289
  this.loadUsers();
290
+ console.log('addedToRoom', msg);
291
+ this.upsertNotification({
292
+ roomId: msg.chatRoomId,
293
+ roomName: msg.roomName,
294
+ type: 'added'
295
+ });
283
296
  }
284
297
  });
285
298
  this.socket.on('userAlreadyInRoom').subscribe((msg) => {
@@ -355,8 +368,40 @@ class ChatWindowComponent {
355
368
  closeChat() {
356
369
  this.onClose.emit();
357
370
  }
371
+ upsertNotification(data) {
372
+ this.chatService.notifications.update(list => {
373
+ const index = list.findIndex(n => n.roomId === data.roomId);
374
+ if (index !== -1) {
375
+ const n = list[index];
376
+ list[index] = {
377
+ ...n,
378
+ unreadCount: n.unreadCount + 1,
379
+ lastMessage: data.lastMessage ?? n.lastMessage,
380
+ timestamp: Date.now()
381
+ };
382
+ return [...list];
383
+ }
384
+ return [
385
+ ...list,
386
+ {
387
+ roomId: data.roomId,
388
+ roomName: data.roomName,
389
+ type: data.type,
390
+ unreadCount: 1,
391
+ lastMessage: data.lastMessage,
392
+ timestamp: Date.now()
393
+ }
394
+ ];
395
+ });
396
+ }
397
+ clearRoom(roomId) {
398
+ this.chatService.notifications.update(list => list.filter(n => n.roomId !== roomId));
399
+ }
400
+ clearAll() {
401
+ this.chatService.notifications.set([]);
402
+ }
358
403
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatWindowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
359
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ChatWindowComponent, isStandalone: true, selector: "app-chat-window", inputs: { chatRoomId: { classPropertyName: "chatRoomId", publicName: "chatRoomId", isSignal: false, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: false, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: false, isRequired: false, transformFunction: null }, chatUsers: { classPropertyName: "chatUsers", publicName: "chatUsers", isSignal: false, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: false, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: false, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: false, isRequired: false, transformFunction: null }, refreshRoom: { classPropertyName: "refreshRoom", publicName: "refreshRoom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onArchive: "onArchive", onClose: "onClose" }, providers: [MessageService], viewQueries: [{ propertyName: "messagesContainer", first: true, predicate: ["messagesContainer"], descendants: true }, { propertyName: "reactionOverlay", first: true, predicate: ["reactionOverlay"], descendants: true }], ngImport: i0, template: "<p-toast></p-toast>\r\n\r\n<div [class.dark]=\"theme === 'dark'\" [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\"\r\n [class.minimized]=\"minimized\" class=\"chat-window\">\r\n <div class=\"chat-header\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"title\">\r\n <span>{{ header }}</span>\r\n <span *ngIf=\"users().length\">({{ users().length }} {{\r\n users().length == 1 ? 'participant' :\r\n 'participants'\r\n }})</span>\r\n </div>\r\n <div>\r\n <span>{{ metadata }}</span>\r\n </div>\r\n </div>\r\n <div class=\"header-actions\">\r\n <button (click)=\"toggleUsers()\" appendTo=\"body\" icon=\"pi pi-users\" pButton pTooltip=\"Toogle Users\"\r\n style=\"font-size: 0.5rem\"></button>\r\n @if (showActions) {\r\n <button (click)=\"toggleMinimize()\" [icon]=\"minimized ? 'pi pi-plus' : 'pi pi-minus'\" appendTo=\"body\"\r\n pButton pTooltip=\"Hide/Show\" style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"archiveChat()\" appendTo=\"body\" icon=\"pi pi-trash\" pButton pTooltip=\"Archive\"\r\n style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"closeChat()\" appendTo=\"body\" icon=\"pi pi-times\" pButton pTooltip=\"Close\"\r\n style=\"font-size: 0.5rem\"></button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!minimized\" class=\"chat-body\">\r\n <div [class.users-hidden]=\"!showUsers\" class=\"chat-layout\">\r\n <div [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\" class=\"chat-main\">\r\n <div #messagesContainer [class.loading]=\"loading\" class=\"messages\">\r\n <div *ngFor=\"let msg of messages(); trackBy: trackById\"\r\n [ngClass]=\"{ outgoing: msg.senderId === chatService.currentUser().userId, incoming: msg.senderId !== chatService.currentUser().userId }\"\r\n class=\"message-row\">\r\n <div class=\"message-bubble\">\r\n <div class=\"message-meta\">\r\n <span class=\"sender\">\r\n <!-- *ngIf=\"msg.senderId !== chatService.currentUser().userId\" -->\r\n {{ msg.senderName }}\r\n </span>\r\n <!-- <span class=\"time\">\r\n {{ msg.createdAt | date: 'shortTime' }}\r\n </span> -->\r\n </div>\r\n\r\n <!-- MESSAGE TEXT -->\r\n <div class=\"message-content\">\r\n {{ msg.content }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"input-area\">\r\n <div *ngIf=\"replyTo\" class=\"reply-banner\">\r\n <span>Replying to: {{ replyTo.content | slice: 0:50 }}</span>\r\n <button (click)=\"clearReply()\" class=\"p-button-text p-button-sm\" icon=\"pi pi-times\"\r\n pButton></button>\r\n </div>\r\n\r\n <textarea (keyup.enter)=\"send()\" [(ngModel)]=\"newMessage\" autoResize=\"true\" pInputTextarea\r\n placeholder=\"Type a message\"\r\n rows=\"2\">\r\n </textarea>\r\n\r\n <div class=\"input-actions\">\r\n <button (click)=\"send()\" icon=\"pi pi-send\" label=\"Send\" pButton></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"chat-sidebar\">\r\n <div class=\"section-title\">Users</div>\r\n <div class=\"user-list\">\r\n <div *ngFor=\"let u of users()\" class=\"user-row\">\r\n <p-avatar [label]=\"u.username[0]\"></p-avatar>\r\n <span>{{ u.username }}</span>\r\n </div>\r\n </div>\r\n @if (showActions) {\r\n <div class=\"user-list-add\">\r\n <p-dropdown [(ngModel)]=\"selectedUser\" [options]=\"chatService.userList()\"\r\n optionLabel=\"full_name\"\r\n placeholder=\"Select User\"/>\r\n <div style=\"margin-top: 2em;\">\r\n <button (click)=\"addUserToRoom()\" icon=\"pi pi-plus\" label=\"Add\" pButton></button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".chat-window{width:35vw;max-width:95vw;display:flex;flex-direction:column;background:#fff;border-radius:16px;box-shadow:0 8px 30px #0000001f;overflow:visible;font-size:14px;font-family:Inter,system-ui,sans-serif}.chat-window.minimized{height:auto}.chat-header{display:flex;align-items:center;justify-content:space-between;background:#4f6ef7;color:#fff;padding:10px 14px}.chat-header .title{display:flex;flex-direction:row;gap:6px}.chat-header .title span{font-weight:600;font-size:14px}.chat-header .title small{font-size:11px;opacity:.85}.chat-body{display:flex;flex:1;background:#f5f7fb}.chat-layout{display:flex;flex:1;width:100%;overflow:hidden}.chat-layout.users-hidden .chat-sidebar{transform:translate(100%);opacity:0;pointer-events:none;width:0!important}.chat-layout.users-hidden .chat-main{flex:1 1 100%}.chat-main{flex:1;display:flex;flex-direction:column;background:#f5f7fb;height:70vh}.messages{flex:1;padding:16px 14px;overflow-y:auto;scroll-behavior:smooth}.message-row{display:flex;margin-bottom:14px;animation:messageIn .25s ease-out;position:relative;overflow:visible;padding-top:28px}@keyframes messageIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.message-row.incoming{justify-content:flex-start}.message-row.incoming .reaction-bar{left:12px}.message-row.outgoing{justify-content:flex-end}.message-row.outgoing .reaction-bar{right:12px;left:auto}.message-bubble{position:relative;max-width:72%;padding:10px 14px;border-radius:16px;font-size:14px;line-height:1.45;word-break:break-word;overflow:visible}.message-row.incoming .message-bubble{background:#fff;color:#111;border-top-left-radius:6px;box-shadow:0 3px 10px #0000000f;overflow:visible}.message-bubble:after{content:\"\";position:absolute;bottom:-6px;right:8px}.message-row.incoming .message-bubble:after{content:\"\";position:absolute;left:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-right:6px solid #ffffff}.message-row.outgoing .message-bubble{background:#4f6ef7;color:#fff;border-top-right-radius:6px;overflow:visible}.message-row.outgoing .message-bubble:after{content:\"\";position:absolute;right:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:6px solid #4f6ef7}.message-meta{display:flex;justify-content:flex-end;font-size:10px;opacity:.6;margin-bottom:4px}.typing-indicator{display:inline-flex;align-items:center;gap:4px;padding:8px 12px;background:#fff;border-radius:14px;box-shadow:0 2px 6px #00000014}.typing-indicator span{width:6px;height:6px;background:#999;border-radius:50%;animation:typingDots 1.4s infinite ease-in-out both}.typing-indicator span:nth-child(1){animation-delay:0s}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes typingDots{0%{transform:translateY(0);opacity:.4}50%{transform:translateY(-4px);opacity:1}to{transform:translateY(0);opacity:.4}}.input-area{background:#fff;padding:10px;border:1px solid #e5e7eb;display:flex;flex-direction:row;justify-content:space-between;gap:5px}.input-area textarea{max-height:60px;overflow:hidden;width:-webkit-fill-available}.reply-banner{background:#eef2ff;border-left:3px solid #4f6ef7;padding:6px 8px;font-size:12px;border-radius:8px;margin-bottom:6px;display:flex;justify-content:space-between}.input-actions{display:flex;justify-content:flex-end;margin-top:6px}.input-actions button{background:#4f6ef7;color:#fff;border-radius:999px;padding:0 16px}.chat-sidebar{background:#fff;border-left:1px solid #e5e7eb;box-shadow:-4px 0 10px #0000000d;display:flex;flex-direction:column}.section-title{font-weight:600;font-size:13px;padding:10px;border-bottom:1px solid #e5e7eb}.user-list{flex:1;overflow-y:auto;padding:8px;max-height:20em}.user-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px}.user-row:hover{background:#f1f5f9}.user-list-add{padding:10px;border-top:1px solid #e5e7eb}.header-actions{display:flex;align-items:center;gap:6px}.header-actions .p-button{width:32px;height:32px;padding:0;border-radius:50%;background:#ffffff26}.header-actions .p-button:hover{background:#ffffff40}.chat-header{min-height:48px}.header-actions{flex-shrink:0}.header-actions .p-button{transition:background .2s ease,transform .1s ease}.header-actions .p-button:active{transform:scale(.92)}.reaction-bar{position:absolute;top:0;left:12px;transform:translateY(-100%);background:#fff;border-radius:20px;padding:4px 8px;display:none;box-shadow:0 2px 8px #0003;z-index:9999}.message-bubble:hover .reaction-bar{display:flex}.reaction-bar span{cursor:pointer;font-size:16px}.reaction-summary{margin-top:4px;display:flex;gap:6px}.reaction-chip{background:#f1f1f1;padding:2px 6px;border-radius:12px;font-size:12px;position:relative}.reaction-users-tooltip{position:absolute;bottom:130%;left:50%;transform:translate(-50%);white-space:nowrap;background:#222;color:#fff;padding:4px 8px;border-radius:6px;z-index:10000;bottom:calc(100% + 6px)}.message-row,.message-bubble,.reaction-summary{overflow:visible!important}.p-tooltip{z-index:9999!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$1.SlicePipe, name: "slice" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i3.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: InputTextareaModule }, { kind: "directive", type: i7.InputTextarea, selector: "[pInputTextarea]", inputs: ["autoResize", "variant"], outputs: ["onResize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i8.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: OverlayPanelModule }] }); }
404
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ChatWindowComponent, isStandalone: true, selector: "app-chat-window", inputs: { chatRoomId: { classPropertyName: "chatRoomId", publicName: "chatRoomId", isSignal: false, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: false, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: false, isRequired: false, transformFunction: null }, chatUsers: { classPropertyName: "chatUsers", publicName: "chatUsers", isSignal: false, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: false, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: false, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: false, isRequired: false, transformFunction: null }, refreshRoom: { classPropertyName: "refreshRoom", publicName: "refreshRoom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onArchive: "onArchive", onClose: "onClose" }, providers: [MessageService], viewQueries: [{ propertyName: "messagesContainer", first: true, predicate: ["messagesContainer"], descendants: true }, { propertyName: "reactionOverlay", first: true, predicate: ["reactionOverlay"], descendants: true }], ngImport: i0, template: "<p-toast></p-toast>\r\n\r\n<div [class.dark]=\"theme === 'dark'\" [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\"\r\n [class.minimized]=\"minimized\" class=\"chat-window\">\r\n <div class=\"chat-header\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"title\">\r\n <span>{{ header }}</span>\r\n <span *ngIf=\"users().length\">({{ users().length }} {{\r\n users().length == 1 ? 'participant' :\r\n 'participants'\r\n }})</span>\r\n </div>\r\n <div>\r\n <span>{{ metadata }}</span>\r\n </div>\r\n </div>\r\n <div class=\"header-actions\">\r\n <button (click)=\"toggleUsers()\" icon=\"pi pi-users\" pButton pTooltip=\"Toogle Users\"\r\n style=\"font-size: 0.5rem\"></button>\r\n @if (showActions) {\r\n <button (click)=\"toggleMinimize()\" [icon]=\"minimized ? 'pi pi-plus' : 'pi pi-minus'\" pButton\r\n pTooltip=\"Hide/Show\" style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"archiveChat()\" icon=\"pi pi-trash\" pButton pTooltip=\"Archive\"\r\n style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"closeChat()\" icon=\"pi pi-times\" pButton pTooltip=\"Close\"\r\n style=\"font-size: 0.5rem\"></button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!minimized\" class=\"chat-body\">\r\n <div [class.users-hidden]=\"!showUsers\" class=\"chat-layout\">\r\n <div [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\" class=\"chat-main\">\r\n <div #messagesContainer [class.loading]=\"loading\" class=\"messages\">\r\n <div *ngFor=\"let msg of messages(); trackBy: trackById\" [ngClass]=\"{ outgoing: msg.senderId === chatService.currentUser().userId, incoming: msg.senderId !== chatService.currentUser().userId }\"\r\n class=\"message-row\">\r\n <div class=\"message-bubble\">\r\n <div class=\"message-meta\">\r\n <span class=\"sender\">\r\n <!-- *ngIf=\"msg.senderId !== chatService.currentUser().userId\" -->\r\n {{ msg.senderName }}\r\n </span>\r\n <!-- <span class=\"time\">\r\n {{ msg.createdAt | date: 'shortTime' }}\r\n </span> -->\r\n </div>\r\n\r\n <!-- MESSAGE TEXT -->\r\n <div class=\"message-content\">\r\n {{ msg.content }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"input-area\">\r\n <div *ngIf=\"replyTo\" class=\"reply-banner\">\r\n <span>Replying to: {{ replyTo.content | slice: 0:50 }}</span>\r\n <button (click)=\"clearReply()\" class=\"p-button-text p-button-sm\" icon=\"pi pi-times\"\r\n pButton></button>\r\n </div>\r\n\r\n <textarea (keyup.enter)=\"send()\" [(ngModel)]=\"newMessage\" autoResize=\"true\" pInputTextarea\r\n placeholder=\"Type a message\"\r\n rows=\"2\">\r\n </textarea>\r\n\r\n <div class=\"input-actions\">\r\n <button (click)=\"send()\" icon=\"pi pi-send\" label=\"Send\" pButton></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"chat-sidebar\">\r\n <div class=\"section-title\">Users</div>\r\n <div class=\"user-list\">\r\n <div *ngFor=\"let u of users()\" class=\"user-row\">\r\n <p-avatar [label]=\"u.username[0]\"></p-avatar>\r\n <span>{{ u.username }}</span>\r\n </div>\r\n </div>\r\n @if (showActions) {\r\n <div class=\"user-list-add\">\r\n <p-dropdown [(ngModel)]=\"selectedUser\" [options]=\"chatService.userList()\"\r\n optionLabel=\"full_name\"\r\n placeholder=\"Select User\"/>\r\n <div style=\"margin-top: 2em;\">\r\n <button (click)=\"addUserToRoom()\" icon=\"pi pi-plus\" label=\"Add\" pButton></button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".chat-window{width:35vw;max-width:95vw;display:flex;flex-direction:column;background:#fff;border-radius:16px;box-shadow:0 8px 30px #0000001f;overflow:visible;font-size:14px;font-family:Inter,system-ui,sans-serif}.chat-window.minimized{height:auto}.chat-header{display:flex;align-items:center;justify-content:space-between;background:#4f6ef7;color:#fff;padding:10px 14px}.chat-header .title{display:flex;flex-direction:row;gap:6px}.chat-header .title span{font-weight:600;font-size:14px}.chat-header .title small{font-size:11px;opacity:.85}.chat-body{display:flex;flex:1;background:#f5f7fb}.chat-layout{display:flex;flex:1;width:100%;overflow:hidden}.chat-layout.users-hidden .chat-sidebar{transform:translate(100%);opacity:0;pointer-events:none;width:0!important}.chat-layout.users-hidden .chat-main{flex:1 1 100%}.chat-main{flex:1;display:flex;flex-direction:column;background:#f5f7fb;height:70vh}.messages{flex:1;padding:16px 14px;overflow-y:auto;scroll-behavior:smooth}.message-row{display:flex;margin-bottom:14px;animation:messageIn .25s ease-out;position:relative;overflow:visible;padding-top:28px}@keyframes messageIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.message-row.incoming{justify-content:flex-start}.message-row.incoming .reaction-bar{left:12px}.message-row.outgoing{justify-content:flex-end}.message-row.outgoing .reaction-bar{right:12px;left:auto}.message-bubble{position:relative;max-width:72%;padding:10px 14px;border-radius:16px;font-size:14px;line-height:1.45;word-break:break-word;overflow:visible}.message-row.incoming .message-bubble{background:#fff;color:#111;border-top-left-radius:6px;box-shadow:0 3px 10px #0000000f;overflow:visible}.message-bubble:after{content:\"\";position:absolute;bottom:-6px;right:8px}.message-row.incoming .message-bubble:after{content:\"\";position:absolute;left:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-right:6px solid #ffffff}.message-row.outgoing .message-bubble{background:#4f6ef7;color:#fff;border-top-right-radius:6px;overflow:visible}.message-row.outgoing .message-bubble:after{content:\"\";position:absolute;right:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:6px solid #4f6ef7}.message-meta{display:flex;justify-content:flex-end;font-size:10px;opacity:.6;margin-bottom:4px}.typing-indicator{display:inline-flex;align-items:center;gap:4px;padding:8px 12px;background:#fff;border-radius:14px;box-shadow:0 2px 6px #00000014}.typing-indicator span{width:6px;height:6px;background:#999;border-radius:50%;animation:typingDots 1.4s infinite ease-in-out both}.typing-indicator span:nth-child(1){animation-delay:0s}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes typingDots{0%{transform:translateY(0);opacity:.4}50%{transform:translateY(-4px);opacity:1}to{transform:translateY(0);opacity:.4}}.input-area{background:#fff;padding:10px;border:1px solid #e5e7eb;display:flex;flex-direction:row;justify-content:space-between;gap:5px}.input-area textarea{max-height:60px;overflow:hidden;width:-webkit-fill-available}.reply-banner{background:#eef2ff;border-left:3px solid #4f6ef7;padding:6px 8px;font-size:12px;border-radius:8px;margin-bottom:6px;display:flex;justify-content:space-between}.input-actions{display:flex;justify-content:flex-end;margin-top:6px}.input-actions button{background:#4f6ef7;color:#fff;border-radius:999px;padding:0 16px}.chat-sidebar{background:#fff;border-left:1px solid #e5e7eb;box-shadow:-4px 0 10px #0000000d;display:flex;flex-direction:column}.section-title{font-weight:600;font-size:13px;padding:10px;border-bottom:1px solid #e5e7eb}.user-list{flex:1;overflow-y:auto;padding:8px;max-height:20em}.user-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px}.user-row:hover{background:#f1f5f9}.user-list-add{padding:10px;border-top:1px solid #e5e7eb}.header-actions{display:flex;align-items:center;gap:6px}.header-actions .p-button{width:32px;height:32px;padding:0;border-radius:50%;background:#ffffff26}.header-actions .p-button:hover{background:#ffffff40}.chat-header{min-height:48px}.header-actions{flex-shrink:0}.header-actions .p-button{transition:background .2s ease,transform .1s ease}.header-actions .p-button:active{transform:scale(.92)}.reaction-bar{position:absolute;top:0;left:12px;transform:translateY(-100%);background:#fff;border-radius:20px;padding:4px 8px;display:none;box-shadow:0 2px 8px #0003;z-index:9999}.message-bubble:hover .reaction-bar{display:flex}.reaction-bar span{cursor:pointer;font-size:16px}.reaction-summary{margin-top:4px;display:flex;gap:6px}.reaction-chip{background:#f1f1f1;padding:2px 6px;border-radius:12px;font-size:12px;position:relative}.reaction-users-tooltip{position:absolute;bottom:130%;left:50%;transform:translate(-50%);white-space:nowrap;background:#222;color:#fff;padding:4px 8px;border-radius:6px;z-index:10000;bottom:calc(100% + 6px)}.message-row,.message-bubble,.reaction-summary{overflow:visible!important}.p-tooltip{z-index:9999!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$1.SlicePipe, name: "slice" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i3.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: InputTextareaModule }, { kind: "directive", type: i7.InputTextarea, selector: "[pInputTextarea]", inputs: ["autoResize", "variant"], outputs: ["onResize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i8.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: OverlayPanelModule }] }); }
360
405
  }
361
406
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatWindowComponent, decorators: [{
362
407
  type: Component,
@@ -371,7 +416,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
371
416
  ChipModule,
372
417
  DropdownModule,
373
418
  OverlayPanelModule
374
- ], providers: [MessageService], template: "<p-toast></p-toast>\r\n\r\n<div [class.dark]=\"theme === 'dark'\" [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\"\r\n [class.minimized]=\"minimized\" class=\"chat-window\">\r\n <div class=\"chat-header\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"title\">\r\n <span>{{ header }}</span>\r\n <span *ngIf=\"users().length\">({{ users().length }} {{\r\n users().length == 1 ? 'participant' :\r\n 'participants'\r\n }})</span>\r\n </div>\r\n <div>\r\n <span>{{ metadata }}</span>\r\n </div>\r\n </div>\r\n <div class=\"header-actions\">\r\n <button (click)=\"toggleUsers()\" appendTo=\"body\" icon=\"pi pi-users\" pButton pTooltip=\"Toogle Users\"\r\n style=\"font-size: 0.5rem\"></button>\r\n @if (showActions) {\r\n <button (click)=\"toggleMinimize()\" [icon]=\"minimized ? 'pi pi-plus' : 'pi pi-minus'\" appendTo=\"body\"\r\n pButton pTooltip=\"Hide/Show\" style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"archiveChat()\" appendTo=\"body\" icon=\"pi pi-trash\" pButton pTooltip=\"Archive\"\r\n style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"closeChat()\" appendTo=\"body\" icon=\"pi pi-times\" pButton pTooltip=\"Close\"\r\n style=\"font-size: 0.5rem\"></button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!minimized\" class=\"chat-body\">\r\n <div [class.users-hidden]=\"!showUsers\" class=\"chat-layout\">\r\n <div [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\" class=\"chat-main\">\r\n <div #messagesContainer [class.loading]=\"loading\" class=\"messages\">\r\n <div *ngFor=\"let msg of messages(); trackBy: trackById\"\r\n [ngClass]=\"{ outgoing: msg.senderId === chatService.currentUser().userId, incoming: msg.senderId !== chatService.currentUser().userId }\"\r\n class=\"message-row\">\r\n <div class=\"message-bubble\">\r\n <div class=\"message-meta\">\r\n <span class=\"sender\">\r\n <!-- *ngIf=\"msg.senderId !== chatService.currentUser().userId\" -->\r\n {{ msg.senderName }}\r\n </span>\r\n <!-- <span class=\"time\">\r\n {{ msg.createdAt | date: 'shortTime' }}\r\n </span> -->\r\n </div>\r\n\r\n <!-- MESSAGE TEXT -->\r\n <div class=\"message-content\">\r\n {{ msg.content }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"input-area\">\r\n <div *ngIf=\"replyTo\" class=\"reply-banner\">\r\n <span>Replying to: {{ replyTo.content | slice: 0:50 }}</span>\r\n <button (click)=\"clearReply()\" class=\"p-button-text p-button-sm\" icon=\"pi pi-times\"\r\n pButton></button>\r\n </div>\r\n\r\n <textarea (keyup.enter)=\"send()\" [(ngModel)]=\"newMessage\" autoResize=\"true\" pInputTextarea\r\n placeholder=\"Type a message\"\r\n rows=\"2\">\r\n </textarea>\r\n\r\n <div class=\"input-actions\">\r\n <button (click)=\"send()\" icon=\"pi pi-send\" label=\"Send\" pButton></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"chat-sidebar\">\r\n <div class=\"section-title\">Users</div>\r\n <div class=\"user-list\">\r\n <div *ngFor=\"let u of users()\" class=\"user-row\">\r\n <p-avatar [label]=\"u.username[0]\"></p-avatar>\r\n <span>{{ u.username }}</span>\r\n </div>\r\n </div>\r\n @if (showActions) {\r\n <div class=\"user-list-add\">\r\n <p-dropdown [(ngModel)]=\"selectedUser\" [options]=\"chatService.userList()\"\r\n optionLabel=\"full_name\"\r\n placeholder=\"Select User\"/>\r\n <div style=\"margin-top: 2em;\">\r\n <button (click)=\"addUserToRoom()\" icon=\"pi pi-plus\" label=\"Add\" pButton></button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".chat-window{width:35vw;max-width:95vw;display:flex;flex-direction:column;background:#fff;border-radius:16px;box-shadow:0 8px 30px #0000001f;overflow:visible;font-size:14px;font-family:Inter,system-ui,sans-serif}.chat-window.minimized{height:auto}.chat-header{display:flex;align-items:center;justify-content:space-between;background:#4f6ef7;color:#fff;padding:10px 14px}.chat-header .title{display:flex;flex-direction:row;gap:6px}.chat-header .title span{font-weight:600;font-size:14px}.chat-header .title small{font-size:11px;opacity:.85}.chat-body{display:flex;flex:1;background:#f5f7fb}.chat-layout{display:flex;flex:1;width:100%;overflow:hidden}.chat-layout.users-hidden .chat-sidebar{transform:translate(100%);opacity:0;pointer-events:none;width:0!important}.chat-layout.users-hidden .chat-main{flex:1 1 100%}.chat-main{flex:1;display:flex;flex-direction:column;background:#f5f7fb;height:70vh}.messages{flex:1;padding:16px 14px;overflow-y:auto;scroll-behavior:smooth}.message-row{display:flex;margin-bottom:14px;animation:messageIn .25s ease-out;position:relative;overflow:visible;padding-top:28px}@keyframes messageIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.message-row.incoming{justify-content:flex-start}.message-row.incoming .reaction-bar{left:12px}.message-row.outgoing{justify-content:flex-end}.message-row.outgoing .reaction-bar{right:12px;left:auto}.message-bubble{position:relative;max-width:72%;padding:10px 14px;border-radius:16px;font-size:14px;line-height:1.45;word-break:break-word;overflow:visible}.message-row.incoming .message-bubble{background:#fff;color:#111;border-top-left-radius:6px;box-shadow:0 3px 10px #0000000f;overflow:visible}.message-bubble:after{content:\"\";position:absolute;bottom:-6px;right:8px}.message-row.incoming .message-bubble:after{content:\"\";position:absolute;left:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-right:6px solid #ffffff}.message-row.outgoing .message-bubble{background:#4f6ef7;color:#fff;border-top-right-radius:6px;overflow:visible}.message-row.outgoing .message-bubble:after{content:\"\";position:absolute;right:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:6px solid #4f6ef7}.message-meta{display:flex;justify-content:flex-end;font-size:10px;opacity:.6;margin-bottom:4px}.typing-indicator{display:inline-flex;align-items:center;gap:4px;padding:8px 12px;background:#fff;border-radius:14px;box-shadow:0 2px 6px #00000014}.typing-indicator span{width:6px;height:6px;background:#999;border-radius:50%;animation:typingDots 1.4s infinite ease-in-out both}.typing-indicator span:nth-child(1){animation-delay:0s}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes typingDots{0%{transform:translateY(0);opacity:.4}50%{transform:translateY(-4px);opacity:1}to{transform:translateY(0);opacity:.4}}.input-area{background:#fff;padding:10px;border:1px solid #e5e7eb;display:flex;flex-direction:row;justify-content:space-between;gap:5px}.input-area textarea{max-height:60px;overflow:hidden;width:-webkit-fill-available}.reply-banner{background:#eef2ff;border-left:3px solid #4f6ef7;padding:6px 8px;font-size:12px;border-radius:8px;margin-bottom:6px;display:flex;justify-content:space-between}.input-actions{display:flex;justify-content:flex-end;margin-top:6px}.input-actions button{background:#4f6ef7;color:#fff;border-radius:999px;padding:0 16px}.chat-sidebar{background:#fff;border-left:1px solid #e5e7eb;box-shadow:-4px 0 10px #0000000d;display:flex;flex-direction:column}.section-title{font-weight:600;font-size:13px;padding:10px;border-bottom:1px solid #e5e7eb}.user-list{flex:1;overflow-y:auto;padding:8px;max-height:20em}.user-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px}.user-row:hover{background:#f1f5f9}.user-list-add{padding:10px;border-top:1px solid #e5e7eb}.header-actions{display:flex;align-items:center;gap:6px}.header-actions .p-button{width:32px;height:32px;padding:0;border-radius:50%;background:#ffffff26}.header-actions .p-button:hover{background:#ffffff40}.chat-header{min-height:48px}.header-actions{flex-shrink:0}.header-actions .p-button{transition:background .2s ease,transform .1s ease}.header-actions .p-button:active{transform:scale(.92)}.reaction-bar{position:absolute;top:0;left:12px;transform:translateY(-100%);background:#fff;border-radius:20px;padding:4px 8px;display:none;box-shadow:0 2px 8px #0003;z-index:9999}.message-bubble:hover .reaction-bar{display:flex}.reaction-bar span{cursor:pointer;font-size:16px}.reaction-summary{margin-top:4px;display:flex;gap:6px}.reaction-chip{background:#f1f1f1;padding:2px 6px;border-radius:12px;font-size:12px;position:relative}.reaction-users-tooltip{position:absolute;bottom:130%;left:50%;transform:translate(-50%);white-space:nowrap;background:#222;color:#fff;padding:4px 8px;border-radius:6px;z-index:10000;bottom:calc(100% + 6px)}.message-row,.message-bubble,.reaction-summary{overflow:visible!important}.p-tooltip{z-index:9999!important}\n"] }]
419
+ ], providers: [MessageService], template: "<p-toast></p-toast>\r\n\r\n<div [class.dark]=\"theme === 'dark'\" [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\"\r\n [class.minimized]=\"minimized\" class=\"chat-window\">\r\n <div class=\"chat-header\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"title\">\r\n <span>{{ header }}</span>\r\n <span *ngIf=\"users().length\">({{ users().length }} {{\r\n users().length == 1 ? 'participant' :\r\n 'participants'\r\n }})</span>\r\n </div>\r\n <div>\r\n <span>{{ metadata }}</span>\r\n </div>\r\n </div>\r\n <div class=\"header-actions\">\r\n <button (click)=\"toggleUsers()\" icon=\"pi pi-users\" pButton pTooltip=\"Toogle Users\"\r\n style=\"font-size: 0.5rem\"></button>\r\n @if (showActions) {\r\n <button (click)=\"toggleMinimize()\" [icon]=\"minimized ? 'pi pi-plus' : 'pi pi-minus'\" pButton\r\n pTooltip=\"Hide/Show\" style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"archiveChat()\" icon=\"pi pi-trash\" pButton pTooltip=\"Archive\"\r\n style=\"font-size: 0.5rem\"></button>\r\n <button (click)=\"closeChat()\" icon=\"pi pi-times\" pButton pTooltip=\"Close\"\r\n style=\"font-size: 0.5rem\"></button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!minimized\" class=\"chat-body\">\r\n <div [class.users-hidden]=\"!showUsers\" class=\"chat-layout\">\r\n <div [class.floating]=\"mode === 'floating'\" [class.fullscreen]=\"mode === 'fullscreen'\" class=\"chat-main\">\r\n <div #messagesContainer [class.loading]=\"loading\" class=\"messages\">\r\n <div *ngFor=\"let msg of messages(); trackBy: trackById\" [ngClass]=\"{ outgoing: msg.senderId === chatService.currentUser().userId, incoming: msg.senderId !== chatService.currentUser().userId }\"\r\n class=\"message-row\">\r\n <div class=\"message-bubble\">\r\n <div class=\"message-meta\">\r\n <span class=\"sender\">\r\n <!-- *ngIf=\"msg.senderId !== chatService.currentUser().userId\" -->\r\n {{ msg.senderName }}\r\n </span>\r\n <!-- <span class=\"time\">\r\n {{ msg.createdAt | date: 'shortTime' }}\r\n </span> -->\r\n </div>\r\n\r\n <!-- MESSAGE TEXT -->\r\n <div class=\"message-content\">\r\n {{ msg.content }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"input-area\">\r\n <div *ngIf=\"replyTo\" class=\"reply-banner\">\r\n <span>Replying to: {{ replyTo.content | slice: 0:50 }}</span>\r\n <button (click)=\"clearReply()\" class=\"p-button-text p-button-sm\" icon=\"pi pi-times\"\r\n pButton></button>\r\n </div>\r\n\r\n <textarea (keyup.enter)=\"send()\" [(ngModel)]=\"newMessage\" autoResize=\"true\" pInputTextarea\r\n placeholder=\"Type a message\"\r\n rows=\"2\">\r\n </textarea>\r\n\r\n <div class=\"input-actions\">\r\n <button (click)=\"send()\" icon=\"pi pi-send\" label=\"Send\" pButton></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"chat-sidebar\">\r\n <div class=\"section-title\">Users</div>\r\n <div class=\"user-list\">\r\n <div *ngFor=\"let u of users()\" class=\"user-row\">\r\n <p-avatar [label]=\"u.username[0]\"></p-avatar>\r\n <span>{{ u.username }}</span>\r\n </div>\r\n </div>\r\n @if (showActions) {\r\n <div class=\"user-list-add\">\r\n <p-dropdown [(ngModel)]=\"selectedUser\" [options]=\"chatService.userList()\"\r\n optionLabel=\"full_name\"\r\n placeholder=\"Select User\"/>\r\n <div style=\"margin-top: 2em;\">\r\n <button (click)=\"addUserToRoom()\" icon=\"pi pi-plus\" label=\"Add\" pButton></button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".chat-window{width:35vw;max-width:95vw;display:flex;flex-direction:column;background:#fff;border-radius:16px;box-shadow:0 8px 30px #0000001f;overflow:visible;font-size:14px;font-family:Inter,system-ui,sans-serif}.chat-window.minimized{height:auto}.chat-header{display:flex;align-items:center;justify-content:space-between;background:#4f6ef7;color:#fff;padding:10px 14px}.chat-header .title{display:flex;flex-direction:row;gap:6px}.chat-header .title span{font-weight:600;font-size:14px}.chat-header .title small{font-size:11px;opacity:.85}.chat-body{display:flex;flex:1;background:#f5f7fb}.chat-layout{display:flex;flex:1;width:100%;overflow:hidden}.chat-layout.users-hidden .chat-sidebar{transform:translate(100%);opacity:0;pointer-events:none;width:0!important}.chat-layout.users-hidden .chat-main{flex:1 1 100%}.chat-main{flex:1;display:flex;flex-direction:column;background:#f5f7fb;height:70vh}.messages{flex:1;padding:16px 14px;overflow-y:auto;scroll-behavior:smooth}.message-row{display:flex;margin-bottom:14px;animation:messageIn .25s ease-out;position:relative;overflow:visible;padding-top:28px}@keyframes messageIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.message-row.incoming{justify-content:flex-start}.message-row.incoming .reaction-bar{left:12px}.message-row.outgoing{justify-content:flex-end}.message-row.outgoing .reaction-bar{right:12px;left:auto}.message-bubble{position:relative;max-width:72%;padding:10px 14px;border-radius:16px;font-size:14px;line-height:1.45;word-break:break-word;overflow:visible}.message-row.incoming .message-bubble{background:#fff;color:#111;border-top-left-radius:6px;box-shadow:0 3px 10px #0000000f;overflow:visible}.message-bubble:after{content:\"\";position:absolute;bottom:-6px;right:8px}.message-row.incoming .message-bubble:after{content:\"\";position:absolute;left:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-right:6px solid #ffffff}.message-row.outgoing .message-bubble{background:#4f6ef7;color:#fff;border-top-right-radius:6px;overflow:visible}.message-row.outgoing .message-bubble:after{content:\"\";position:absolute;right:-6px;top:12px;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:6px solid #4f6ef7}.message-meta{display:flex;justify-content:flex-end;font-size:10px;opacity:.6;margin-bottom:4px}.typing-indicator{display:inline-flex;align-items:center;gap:4px;padding:8px 12px;background:#fff;border-radius:14px;box-shadow:0 2px 6px #00000014}.typing-indicator span{width:6px;height:6px;background:#999;border-radius:50%;animation:typingDots 1.4s infinite ease-in-out both}.typing-indicator span:nth-child(1){animation-delay:0s}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes typingDots{0%{transform:translateY(0);opacity:.4}50%{transform:translateY(-4px);opacity:1}to{transform:translateY(0);opacity:.4}}.input-area{background:#fff;padding:10px;border:1px solid #e5e7eb;display:flex;flex-direction:row;justify-content:space-between;gap:5px}.input-area textarea{max-height:60px;overflow:hidden;width:-webkit-fill-available}.reply-banner{background:#eef2ff;border-left:3px solid #4f6ef7;padding:6px 8px;font-size:12px;border-radius:8px;margin-bottom:6px;display:flex;justify-content:space-between}.input-actions{display:flex;justify-content:flex-end;margin-top:6px}.input-actions button{background:#4f6ef7;color:#fff;border-radius:999px;padding:0 16px}.chat-sidebar{background:#fff;border-left:1px solid #e5e7eb;box-shadow:-4px 0 10px #0000000d;display:flex;flex-direction:column}.section-title{font-weight:600;font-size:13px;padding:10px;border-bottom:1px solid #e5e7eb}.user-list{flex:1;overflow-y:auto;padding:8px;max-height:20em}.user-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px}.user-row:hover{background:#f1f5f9}.user-list-add{padding:10px;border-top:1px solid #e5e7eb}.header-actions{display:flex;align-items:center;gap:6px}.header-actions .p-button{width:32px;height:32px;padding:0;border-radius:50%;background:#ffffff26}.header-actions .p-button:hover{background:#ffffff40}.chat-header{min-height:48px}.header-actions{flex-shrink:0}.header-actions .p-button{transition:background .2s ease,transform .1s ease}.header-actions .p-button:active{transform:scale(.92)}.reaction-bar{position:absolute;top:0;left:12px;transform:translateY(-100%);background:#fff;border-radius:20px;padding:4px 8px;display:none;box-shadow:0 2px 8px #0003;z-index:9999}.message-bubble:hover .reaction-bar{display:flex}.reaction-bar span{cursor:pointer;font-size:16px}.reaction-summary{margin-top:4px;display:flex;gap:6px}.reaction-chip{background:#f1f1f1;padding:2px 6px;border-radius:12px;font-size:12px;position:relative}.reaction-users-tooltip{position:absolute;bottom:130%;left:50%;transform:translate(-50%);white-space:nowrap;background:#222;color:#fff;padding:4px 8px;border-radius:6px;z-index:10000;bottom:calc(100% + 6px)}.message-row,.message-bubble,.reaction-summary{overflow:visible!important}.p-tooltip{z-index:9999!important}\n"] }]
375
420
  }], ctorParameters: () => [], propDecorators: { chatRoomId: [{
376
421
  type: Input
377
422
  }], header: [{
@@ -461,7 +506,9 @@ class ChatLauncherComponent {
461
506
  this.activeIndex.set(i);
462
507
  }
463
508
  closeAll() {
464
- this.openWindows.set([]);
509
+ this.openWindows.update(() => []);
510
+ this.lastOpenedRoom.set(null);
511
+ this.activeIndex.set(0);
465
512
  }
466
513
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatLauncherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
467
514
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: ChatLauncherComponent, isStandalone: true, selector: "app-chat-launcher", inputs: { roomId: { classPropertyName: "roomId", publicName: "roomId", isSignal: true, isRequired: false, transformFunction: null }, roomHeader: { classPropertyName: "roomHeader", publicName: "roomHeader", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null }, userList: { classPropertyName: "userList", publicName: "userList", isSignal: true, isRequired: false, transformFunction: null }, chatUsers: { classPropertyName: "chatUsers", publicName: "chatUsers", isSignal: true, isRequired: false, transformFunction: null } }, providers: [MessageService], ngImport: i0, template: "<div class=\"chat-float-wrapper\">\r\n <p-tabView [activeIndex]=\"activeIndex()\" (activeIndexChange)=\"setActive($event)\" [scrollable]=\"true\"\r\n class=\"chat-tabview\">\r\n <p-tabPanel *ngFor=\"let w of openWindows(); let i = index\" [header]=\"w.header\">\r\n <ng-template pTemplate=\"content\">\r\n <app-chat-window mode=\"floating\" theme=\"light\" [chatRoomId]=\"w.roomId\" [header]=\"w.header\"\r\n [metadata]=\"w.metadata\" (onArchive)=\"closeWindow($event)\" (close)=\"closeAll()\">\r\n </app-chat-window>\r\n </ng-template>\r\n </p-tabPanel>\r\n </p-tabView>\r\n</div>", styles: ["@charset \"UTF-8\";.chat-float-wrapper{position:fixed!important;bottom:16px!important;right:16px!important;z-index:99999;pointer-events:auto}:host{position:fixed;right:16px;bottom:16px;z-index:2147483647;font-family:Arial,sans-serif}:host,:host *{box-sizing:border-box}:host{isolation:isolate}.chat-tabview{width:100%;height:100%}:host ::ng-deep .p-tabview{height:100%;display:flex;flex-direction:column}:host ::ng-deep .p-tabview-nav{flex-shrink:0}:host ::ng-deep .p-tabview-panels{flex:1;overflow:hidden}:host ::ng-deep .p-tabview-panel{height:100%}:host ::ng-deep app-chat-window{display:block;height:100%}.chat-tabview ::ng-deep .p-tabview-nav{background:transparent;border:none;display:flex;gap:8px;padding:6px 4px}.chat-tabview ::ng-deep .p-tabview-nav li{border:none}.chat-tabview ::ng-deep .p-tabview-nav li .p-tabview-nav-link{border:none;border-radius:18px;padding:6px 14px;font-size:13px;font-weight:500;color:#555;box-shadow:0 1px 4px #00000014;transition:all .2s ease}.chat-tabview ::ng-deep .p-tabview-nav li .p-tabview-nav-link:hover{color:#1a73e8}.chat-tabview ::ng-deep .p-tabview-nav li.p-highlight .p-tabview-nav-link{background:#1a73e8;color:#fff;box-shadow:0 4px 10px #1a73e859}.chat-tabview ::ng-deep .p-tabview-ink-bar{display:none}.chat-tabview ::ng-deep .p-tabview-panels{padding:0;border:none;background:transparent}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ChatWindowComponent, selector: "app-chat-window", inputs: ["chatRoomId", "header", "metadata", "chatUsers", "showActions", "mode", "theme", "refreshRoom"], outputs: ["onArchive", "onClose"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: ToastModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TabViewModule }, { kind: "component", type: i3$1.TabView, selector: "p-tabView", inputs: ["style", "styleClass", "controlClose", "scrollable", "activeIndex", "selectOnFocus", "nextButtonAriaLabel", "prevButtonAriaLabel", "autoHideButtons", "tabindex"], outputs: ["onChange", "onClose", "activeIndexChange"] }, { kind: "component", type: i3$1.TabPanel, selector: "p-tabPanel", inputs: ["closable", "headerStyle", "headerStyleClass", "cache", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "selected", "disabled", "header", "leftIcon", "rightIcon"] }] }); }
@@ -533,7 +580,7 @@ class AllChatsComponent {
533
580
  this.activeRoomMetadata.set(room.Metadata);
534
581
  setTimeout(() => {
535
582
  this.showMessages = true;
536
- }, 500);
583
+ }, 800);
537
584
  }
538
585
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AllChatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
539
586
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AllChatsComponent, isStandalone: true, selector: "app-all-chats", inputs: { user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null }, roomId: { classPropertyName: "roomId", publicName: "roomId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { newRoomLoaded: "newRoomLoaded" }, ngImport: i0, template: "<div class=\"chat-page\">\r\n <!-- LEFT SIDEBAR : CHAT ROOMS -->\r\n <aside class=\"chat-sidebar glass\">\r\n <div class=\"sidebar-header\">\r\n <h3>Chat Rooms</h3>\r\n </div>\r\n <ul class=\"room-list\">\r\n <li (click)=\"selectRoom(room)\" *ngFor=\"let room of rooms;\" [class.active]=\"activeRoomId() === room.ChatRoomId\"\r\n class=\"room-item\">\r\n <div class=\"room-avatar\">\r\n <p-avatar [label]=\"room.ChatRoomName[0]\"></p-avatar>\r\n </div>\r\n <div class=\"room-info\">\r\n <span class=\"room-name\">{{ room.ChatRoomName }}</span>\r\n <span class=\"room-name\">{{ room.Metadata }}</span>\r\n </div>\r\n </li>\r\n </ul>\r\n </aside>\r\n <!-- RIGHT PANEL : CHAT WINDOW -->\r\n @if (showMessages) {\r\n <section *ngIf=\"showMessages\" @roomSwitch class=\"chat-main glass\">\r\n <app-chat-window [chatRoomId]=\"activeRoomId()\" [header]=\"activeRoomHeader()\" [metadata]=\"activeRoomMetadata()\" [showActions]=\"false\"\r\n mode=\"fullscreen\" theme=\"light\">\r\n </app-chat-window>\r\n </section>\r\n } @else {\r\n <section class=\"chat-main glass loading-container\">\r\n <div class=\"spinner\"></div>\r\n <p>Loading messages\u2026</p>\r\n </section>\r\n }\r\n\r\n</div>", styles: [":root{--glass-bg: rgba(255, 255, 255, .75);--glass-border: rgba(255, 255, 255, .25);--primary: #5b6dff;--text-dark: #1c1e21;--text-muted: #65676b}*{box-sizing:border-box;font-family:Segoe UI,system-ui,-apple-system,BlinkMacSystemFont}.chat-page{display:flex;height:100vh;padding:16px;gap:16px;background:linear-gradient(135deg,#e9efff,#f6f7fb)}.glass{background:var(--glass-bg);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-radius:18px;border:1px solid var(--glass-border);box-shadow:0 20px 40px #00000014,inset 0 1px #fff6}.chat-sidebar{width:300px;display:flex;flex-direction:column;overflow:hidden}.sidebar-header{padding:18px 20px;font-size:18px;font-weight:700;color:var(--text-dark);border-bottom:1px solid rgba(0,0,0,.06)}.room-list{list-style:none;overflow-y:auto;padding:6px}.room-item{display:flex;align-items:center;gap:14px;padding:12px 14px;border-radius:14px;cursor:pointer;transition:all .25s ease;margin-bottom:6px}.room-item:hover{background:#5b6dff14}.room-item.active{background:#5b6dff26;box-shadow:inset 0 0 0 1px #5b6dff40}.room-avatar p-avatar{width:44px;height:44px;border-radius:50%;background:linear-gradient(135deg,#5b6dff,#7a89ff);color:#fff;font-weight:700;display:flex;align-items:center;justify-content:center}.room-info{display:flex;flex-direction:column;overflow:hidden}.room-name{font-size:14px;font-weight:600;color:var(--text-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.room-info span:last-child{font-size:12px;color:var(--text-muted)}.chat-main{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.chat-main:after{content:\"\";position:absolute;inset:0;border-radius:18px;pointer-events:none;box-shadow:inset 0 0 0 1px #fff3}.room-item:hover{transform:translateY(-1px)}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}.spinner{width:40px;height:40px;border:4px solid rgba(0,0,0,.1);border-top-color:#4f46e5;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ToastModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: InputTextareaModule }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: ChatWindowComponent, selector: "app-chat-window", inputs: ["chatRoomId", "header", "metadata", "chatUsers", "showActions", "mode", "theme", "refreshRoom"], outputs: ["onArchive", "onClose"] }], animations: [
@@ -577,6 +624,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
577
624
  type: Output
578
625
  }] } });
579
626
 
627
+ class ChatWidgetNotificationComponent {
628
+ constructor() {
629
+ this.open = false;
630
+ this.chatService = inject(ChatService);
631
+ this.notifications = this.chatService.notifications;
632
+ this.totalCount = computed(() => this.notifications().reduce((a, b) => a + b.unreadCount, 0));
633
+ }
634
+ toggle() {
635
+ this.open = !this.open;
636
+ }
637
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatWidgetNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
638
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ChatWidgetNotificationComponent, isStandalone: true, selector: "lib-chat-widget-notification", ngImport: i0, template: "<div (click)=\"toggle()\" class=\"notif-icon\">\r\n \uD83D\uDD14\r\n @if (totalCount() > 0) {\r\n <span class=\"badge\">\r\n {{ totalCount() }}\r\n </span>\r\n }\r\n</div>\r\n\r\n@if (open) {\r\n <div class=\"notif-panel\">\r\n @for (n of notifications(); track n.roomId) {\r\n <div class=\"notif-item\">\r\n <strong>{{ n.roomName }}</strong>\r\n <p>{{ n.lastMessage || 'You were added to this room' }}</p>\r\n <span class=\"count\">{{ n.unreadCount }}</span>\r\n </div>\r\n }\r\n </div>\r\n}", styles: [""] }); }
639
+ }
640
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatWidgetNotificationComponent, decorators: [{
641
+ type: Component,
642
+ args: [{ selector: 'lib-chat-widget-notification', standalone: true, imports: [], template: "<div (click)=\"toggle()\" class=\"notif-icon\">\r\n \uD83D\uDD14\r\n @if (totalCount() > 0) {\r\n <span class=\"badge\">\r\n {{ totalCount() }}\r\n </span>\r\n }\r\n</div>\r\n\r\n@if (open) {\r\n <div class=\"notif-panel\">\r\n @for (n of notifications(); track n.roomId) {\r\n <div class=\"notif-item\">\r\n <strong>{{ n.roomName }}</strong>\r\n <p>{{ n.lastMessage || 'You were added to this room' }}</p>\r\n <span class=\"count\">{{ n.unreadCount }}</span>\r\n </div>\r\n }\r\n </div>\r\n}" }]
643
+ }], ctorParameters: () => [] });
644
+
580
645
  class ChatWidgetModule {
581
646
  static forRoot(config) {
582
647
  return {
@@ -593,7 +658,8 @@ class ChatWidgetModule {
593
658
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: ChatWidgetModule, imports: [CommonModule,
594
659
  ChatLauncherComponent,
595
660
  ChatWindowComponent,
596
- AllChatsComponent], exports: [ChatLauncherComponent] }); }
661
+ AllChatsComponent,
662
+ ChatWidgetNotificationComponent], exports: [ChatLauncherComponent] }); }
597
663
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatWidgetModule, imports: [CommonModule,
598
664
  ChatLauncherComponent,
599
665
  ChatWindowComponent,
@@ -607,7 +673,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
607
673
  CommonModule,
608
674
  ChatLauncherComponent,
609
675
  ChatWindowComponent,
610
- AllChatsComponent
676
+ AllChatsComponent,
677
+ ChatWidgetNotificationComponent
611
678
  ],
612
679
  exports: [ChatLauncherComponent]
613
680
  }]