From c5bc817efe84518d11b80d788e42ff45b2402458 Mon Sep 17 00:00:00 2001 From: chatenium Date: Thu, 9 Apr 2026 08:47:56 +0200 Subject: [PATCH] Start implementing direct messaging and continued developing the chatnav --- public/Onest-SemiBold.ttf | Bin 0 -> 64444 bytes public/i18n/en.json | 12 ++++ src/app/app.routes.ts | 11 +++- src/app/chat/chat.html | 7 ++- src/app/chat/chat.scss | 16 +++-- src/app/chat/chat.ts | 10 +++- src/app/chat/dm-list/dm-list.html | 25 +++++++- src/app/chat/dm-list/dm-list.scss | 24 ++++++++ src/app/chat/dm-list/dm-list.ts | 25 ++++---- src/app/chat/dm/dm.html | 27 +++++++++ src/app/chat/dm/dm.scss | 33 +++++++++++ src/app/chat/dm/dm.spec.ts | 22 +++++++ src/app/chat/dm/dm.ts | 56 ++++++++++++++++++ .../elements/message-box/message-box.html | 7 +++ .../elements/message-box/message-box.scss | 29 +++++++++ .../elements/message-box/message-box.spec.ts | 22 +++++++ .../chat/elements/message-box/message-box.ts | 12 ++++ src/app/chat/elements/navbar/navbar.html | 3 + src/app/chat/elements/navbar/navbar.scss | 15 +++++ src/app/chat/elements/navbar/navbar.spec.ts | 22 +++++++ src/app/chat/elements/navbar/navbar.ts | 9 +++ src/app/chat/elements/oimg/oimg.html | 1 + src/app/chat/elements/oimg/oimg.scss | 0 src/app/chat/elements/oimg/oimg.spec.ts | 22 +++++++ src/app/chat/elements/oimg/oimg.ts | 18 ++++++ src/app/service-manager.ts | 21 +++++++ src/styles.scss | 6 ++ 27 files changed, 428 insertions(+), 27 deletions(-) create mode 100644 public/Onest-SemiBold.ttf create mode 100644 src/app/chat/dm/dm.html create mode 100644 src/app/chat/dm/dm.scss create mode 100644 src/app/chat/dm/dm.spec.ts create mode 100644 src/app/chat/dm/dm.ts create mode 100644 src/app/chat/elements/message-box/message-box.html create mode 100644 src/app/chat/elements/message-box/message-box.scss create mode 100644 src/app/chat/elements/message-box/message-box.spec.ts create mode 100644 src/app/chat/elements/message-box/message-box.ts create mode 100644 src/app/chat/elements/navbar/navbar.html create mode 100644 src/app/chat/elements/navbar/navbar.scss create mode 100644 src/app/chat/elements/navbar/navbar.spec.ts create mode 100644 src/app/chat/elements/navbar/navbar.ts create mode 100644 src/app/chat/elements/oimg/oimg.html create mode 100644 src/app/chat/elements/oimg/oimg.scss create mode 100644 src/app/chat/elements/oimg/oimg.spec.ts create mode 100644 src/app/chat/elements/oimg/oimg.ts diff --git a/public/Onest-SemiBold.ttf b/public/Onest-SemiBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c7e8a3d2e9826744baaba6373d3474366459c5ea GIT binary patch literal 64444 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 literal 0 HcmV?d00001 diff --git a/public/i18n/en.json b/public/i18n/en.json index e41de95..293fdee 100644 --- a/public/i18n/en.json +++ b/public/i18n/en.json @@ -16,5 +16,17 @@ "passwordRequired": "Password is required", "passwordIncorrect": "Password is incorrect" } + }, + "chat": { + "chatnav": { + "dmList": { + "newChat": "Start new chat", + "messageBox": { + "latestMessage": { + "you": "You: " + } + } + } + } } } diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index efb39d8..29b9d27 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,8 +1,13 @@ -import { Routes } from '@angular/router'; +import {Routes} from '@angular/router'; import {SignIn} from './signin/signin'; import {Chat} from './chat/chat'; +import {Dm} from './chat/dm/dm'; export const routes: Routes = [ - { path: 'signin', component: SignIn }, - { path: 'chat', component: Chat }, + {path: 'signin', component: SignIn}, + { + path: 'chat', component: Chat, children: [ + {path: 'dm/:chatid', component: Dm}, + ] + }, ]; diff --git a/src/app/chat/chat.html b/src/app/chat/chat.html index 903faf6..083e3a7 100644 --- a/src/app/chat/chat.html +++ b/src/app/chat/chat.html @@ -3,7 +3,7 @@ } @else { -
+
diff --git a/src/app/chat/chat.scss b/src/app/chat/chat.scss index a314cdb..9ef4735 100644 --- a/src/app/chat/chat.scss +++ b/src/app/chat/chat.scss @@ -1,11 +1,11 @@ #layout { display: grid; - grid-template-columns: 20% 80%; + grid-template-columns: 350px minmax(0, 1fr); height: 100svh; #chatnav { display: grid; - grid-template-columns: 25% 75%; + grid-template-columns: 70px minmax(0, 1fr); aside { padding: 15px; @@ -36,18 +36,22 @@ } main { - padding: 25px; + padding-top: 65px; + background: var(--tui-background-base-alt); + border-radius: 20px 0 0 20px; + margin: 10px 0 10px 10px; + padding: 15px; } } #content { width: 100%; - padding: 10px; + padding: 10px 10px 10px 0; #content_tint { + border-radius: 0 20px 20px 0; height: 100%; - border-radius: 20px; - background: var(--tui-background-base-alt); + background: var(--tui-background-neutral-2); padding: 15px; } } diff --git a/src/app/chat/chat.ts b/src/app/chat/chat.ts index 3184b5e..275f7e5 100644 --- a/src/app/chat/chat.ts +++ b/src/app/chat/chat.ts @@ -1,9 +1,9 @@ import {Component, inject, OnInit} from '@angular/core'; import {RouterOutlet} from '@angular/router'; import {TuiSegmented} from '@taiga-ui/kit'; -import {TuiButton, TuiIcon, TuiLoader} from '@taiga-ui/core'; +import {TuiAppearance, TuiButton, TuiGroup, TuiIcon, TuiLoader} from '@taiga-ui/core'; import {SessionManager} from '@chatenium/chatenium-sdk/services/sessionManager'; -import {ServiceManager} from '../service-manager'; +import {LoadStatus, ServiceManager} from '../service-manager'; import {IndexedDB} from '../storage/indexed-db'; import {DmList} from './dm-list/dm-list'; import {JsonPipe} from '@angular/common'; @@ -17,7 +17,9 @@ import {JsonPipe} from '@angular/common'; TuiButton, TuiLoader, DmList, - JsonPipe + JsonPipe, + TuiAppearance, + TuiGroup ], templateUrl: './chat.html', styleUrl: './chat.scss', @@ -31,4 +33,6 @@ export class Chat implements OnInit { this.serviceManager.currentSession.set(await this.serviceManager.sessionManager.loadPreferredSession()) }) } + + protected readonly LoadStatus = LoadStatus; } diff --git a/src/app/chat/dm-list/dm-list.html b/src/app/chat/dm-list/dm-list.html index de3073c..06ae07a 100644 --- a/src/app/chat/dm-list/dm-list.html +++ b/src/app/chat/dm-list/dm-list.html @@ -1,3 +1,24 @@ -@for (chat of chats(); track chat.chatid) { - {{chat.chatid}} + + +@for (chat of serviceManager.chats(); track chat.chatid) { + } diff --git a/src/app/chat/dm-list/dm-list.scss b/src/app/chat/dm-list/dm-list.scss index e69de29..c04f676 100644 --- a/src/app/chat/dm-list/dm-list.scss +++ b/src/app/chat/dm-list/dm-list.scss @@ -0,0 +1,24 @@ +:host { + display: flex; + flex-direction: column; + gap: 5px; + + button { + width: 100%; + display: flex; + justify-content: start; + font-weight: 600; + + .info { + display: flex; + flex-direction: column; + text-align: start; + + .latest_message { + margin-top: -5px; + font-size: 12px; + opacity: 50%; + } + } + } +} diff --git a/src/app/chat/dm-list/dm-list.ts b/src/app/chat/dm-list/dm-list.ts index d6d0c05..43a4191 100644 --- a/src/app/chat/dm-list/dm-list.ts +++ b/src/app/chat/dm-list/dm-list.ts @@ -2,12 +2,19 @@ import {Component, inject, input, OnInit, signal} from '@angular/core'; import {ChatService} from '@chatenium/chatenium-sdk/services/chatService'; import {IndexedDB} from '../../storage/indexed-db'; import {Chat} from '@chatenium/chatenium-sdk/domain/chatService.schema'; -import {JsonPipe} from '@angular/common'; +import {TuiButton} from '@taiga-ui/core'; +import {Oimg} from '../elements/oimg/oimg'; +import {Router, RouterLink} from '@angular/router'; +import {TranslatePipe} from '@ngx-translate/core'; +import {LoadStatus, ServiceManager} from '../../service-manager'; @Component({ selector: 'app-dm-list', imports: [ - JsonPipe + TuiButton, + Oimg, + RouterLink, + TranslatePipe ], templateUrl: './dm-list.html', styleUrl: './dm-list.scss', @@ -17,19 +24,17 @@ export class DmList implements OnInit { token = input("") indexedDb = inject(IndexedDB) - - service: ChatService | null = null - chats = signal([]) - chatsStatus = 0 + router = inject(Router) + serviceManager = inject(ServiceManager) async ngOnInit() { - this.service = new ChatService(this.userid(), this.token(), this.indexedDb.getApi(), () => {}) + this.serviceManager.chatService = new ChatService(this.userid(), this.token(), this.indexedDb.getApi(), () => {}) try { - this.chats.set(await this.service.get()) - this.chatsStatus = 1 + this.serviceManager.chats.set(await this.serviceManager.chatService.get()) + this.serviceManager.chatsStatus.set(LoadStatus.loaded) } catch (e) { console.error(e) - this.chatsStatus = 2 + this.serviceManager.chatsStatus.set(LoadStatus.error) } } } diff --git a/src/app/chat/dm/dm.html b/src/app/chat/dm/dm.html new file mode 100644 index 0000000..8745cd8 --- /dev/null +++ b/src/app/chat/dm/dm.html @@ -0,0 +1,27 @@ +@defer (when store) { + +
+ +
+ @if (store.chatData.displayName == "") { + {{'@'+store.chatData.username}} + } @else { + {{store.chatData.displayName}} + {{'@'+store.chatData.username}} + } +
+
+ +
+ +
+
+ +
+ +
+ + +} diff --git a/src/app/chat/dm/dm.scss b/src/app/chat/dm/dm.scss new file mode 100644 index 0000000..970c1fd --- /dev/null +++ b/src/app/chat/dm/dm.scss @@ -0,0 +1,33 @@ +:host { + height: 100%; + display: grid; + grid-template-rows: 70px minmax(0, 1fr) auto; + + navbar { + .chat-data { + display: flex; + flex-direction: column; + + .main-name { + font-size: 18px; + font-weight: bold; + } + + .alt-name { + margin-top: -5px; + color: gray; + font-size: 12px; + } + } + + .items-right { + margin-top: -10px; + + button { + width: 35px; + height: 35px; + } + } + } + +} diff --git a/src/app/chat/dm/dm.spec.ts b/src/app/chat/dm/dm.spec.ts new file mode 100644 index 0000000..2ddf08a --- /dev/null +++ b/src/app/chat/dm/dm.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Dm } from './dm'; + +describe('Dm', () => { + let component: Dm; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Dm], + }).compileComponents(); + + fixture = TestBed.createComponent(Dm); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chat/dm/dm.ts b/src/app/chat/dm/dm.ts new file mode 100644 index 0000000..a852efa --- /dev/null +++ b/src/app/chat/dm/dm.ts @@ -0,0 +1,56 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {DmStorage, ServiceManager} from '../../service-manager'; +import {ActivatedRoute} from '@angular/router'; +import {DMService} from '@chatenium/chatenium-sdk/services/dmService'; +import {IndexedDB} from '../../storage/indexed-db'; +import {Navbar} from '../elements/navbar/navbar'; +import {Oimg} from '../elements/oimg/oimg'; +import {TuiButton, TuiIcon} from '@taiga-ui/core'; +import {MessageBox} from '../elements/message-box/message-box'; + +@Component({ + selector: 'app-dm', + imports: [ + Navbar, + Oimg, + TuiButton, + TuiIcon, + MessageBox + ], + templateUrl: './dm.html', + styleUrl: './dm.scss', +}) +export class Dm implements OnInit { + serviceManager = inject(ServiceManager) + route = inject(ActivatedRoute) + indexedDb = inject(IndexedDB) + + chatid = "" + + get store(): DmStorage { + return this.serviceManager.dmServices()[this.chatid] + } + + ngOnInit() { + this.route.params.subscribe(params => { + const chatid = params['chatid'] + this.chatid = chatid + console.log(this.serviceManager.chats()) + const session = this.serviceManager.currentSession(); + const chatData = this.serviceManager.chats().find(chat => chat.chatid == chatid) + + if (!this.serviceManager.dmServices()[chatid] && session != null && chatData != null) { + this.serviceManager.dmServices()[chatid] = { + service: new DMService( + session.userData.userid, + session.token, + chatid, + this.indexedDb.getApi(), + () => {} + ), + chatData: chatData + } + } + }) + } +} diff --git a/src/app/chat/elements/message-box/message-box.html b/src/app/chat/elements/message-box/message-box.html new file mode 100644 index 0000000..9dbb25a --- /dev/null +++ b/src/app/chat/elements/message-box/message-box.html @@ -0,0 +1,7 @@ +
+
+
+ +
+
+
diff --git a/src/app/chat/elements/message-box/message-box.scss b/src/app/chat/elements/message-box/message-box.scss new file mode 100644 index 0000000..94b515d --- /dev/null +++ b/src/app/chat/elements/message-box/message-box.scss @@ -0,0 +1,29 @@ +:host { + width: 100%; + display: flex; + justify-content: center; + + #message-box { + width: 60%; + background: var(--tui-background-base-alt); + height: 75px; + border-radius: 200px; + border: 2px solid var(--tui-border-normal); + display: grid; + grid-template-columns: 10% 80% 10%; + align-items: center; + padding: 0 10px; + + .items-middle { + textarea { + width: 100%; + height: 100%; + background: transparent; + border: none; + outline: none; + resize: none; + color: var(--tui-text-01); + } + } + } +} diff --git a/src/app/chat/elements/message-box/message-box.spec.ts b/src/app/chat/elements/message-box/message-box.spec.ts new file mode 100644 index 0000000..2c25206 --- /dev/null +++ b/src/app/chat/elements/message-box/message-box.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MessageBox } from './message-box'; + +describe('MessageBox', () => { + let component: MessageBox; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MessageBox], + }).compileComponents(); + + fixture = TestBed.createComponent(MessageBox); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chat/elements/message-box/message-box.ts b/src/app/chat/elements/message-box/message-box.ts new file mode 100644 index 0000000..f4d17a4 --- /dev/null +++ b/src/app/chat/elements/message-box/message-box.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import {TuiAppearance} from '@taiga-ui/core'; + +@Component({ + selector: 'message-box', + imports: [ + TuiAppearance + ], + templateUrl: './message-box.html', + styleUrl: './message-box.scss', +}) +export class MessageBox {} diff --git a/src/app/chat/elements/navbar/navbar.html b/src/app/chat/elements/navbar/navbar.html new file mode 100644 index 0000000..74b1ac3 --- /dev/null +++ b/src/app/chat/elements/navbar/navbar.html @@ -0,0 +1,3 @@ + diff --git a/src/app/chat/elements/navbar/navbar.scss b/src/app/chat/elements/navbar/navbar.scss new file mode 100644 index 0000000..d9bdd95 --- /dev/null +++ b/src/app/chat/elements/navbar/navbar.scss @@ -0,0 +1,15 @@ +nav { + display: grid; + grid-template-columns: 1fr 1fr; + + ::ng-deep .items-right, ::ng-deep .items-left { + display: flex; + gap: 10px; + align-items: center; + } + + ::ng-deep .items-right { + display: flex; + justify-content: end; + } +} diff --git a/src/app/chat/elements/navbar/navbar.spec.ts b/src/app/chat/elements/navbar/navbar.spec.ts new file mode 100644 index 0000000..ea91146 --- /dev/null +++ b/src/app/chat/elements/navbar/navbar.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Navbar } from './navbar'; + +describe('Navbar', () => { + let component: Navbar; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Navbar], + }).compileComponents(); + + fixture = TestBed.createComponent(Navbar); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chat/elements/navbar/navbar.ts b/src/app/chat/elements/navbar/navbar.ts new file mode 100644 index 0000000..b4512cb --- /dev/null +++ b/src/app/chat/elements/navbar/navbar.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'navbar', + imports: [], + templateUrl: './navbar.html', + styleUrl: './navbar.scss', +}) +export class Navbar {} diff --git a/src/app/chat/elements/oimg/oimg.html b/src/app/chat/elements/oimg/oimg.html new file mode 100644 index 0000000..37bf80b --- /dev/null +++ b/src/app/chat/elements/oimg/oimg.html @@ -0,0 +1 @@ + diff --git a/src/app/chat/elements/oimg/oimg.scss b/src/app/chat/elements/oimg/oimg.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/chat/elements/oimg/oimg.spec.ts b/src/app/chat/elements/oimg/oimg.spec.ts new file mode 100644 index 0000000..a2b6932 --- /dev/null +++ b/src/app/chat/elements/oimg/oimg.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Oimg } from './oimg'; + +describe('Oimg', () => { + let component: Oimg; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Oimg], + }).compileComponents(); + + fixture = TestBed.createComponent(Oimg); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chat/elements/oimg/oimg.ts b/src/app/chat/elements/oimg/oimg.ts new file mode 100644 index 0000000..91a4858 --- /dev/null +++ b/src/app/chat/elements/oimg/oimg.ts @@ -0,0 +1,18 @@ +import {Component, input, Input, signal} from '@angular/core'; + +@Component({ + selector: 'oimg', + imports: [], + templateUrl: './oimg.html', + styleUrl: './oimg.scss', + host: { + "[style.height]": "height()", + "[style.width]": "width()", + } +}) +export class Oimg { + height = input("") + width = input("") + src = input("") + radius = input(15) +} diff --git a/src/app/service-manager.ts b/src/app/service-manager.ts index c2cc209..63cfd8a 100644 --- a/src/app/service-manager.ts +++ b/src/app/service-manager.ts @@ -4,6 +4,9 @@ import {Keyring} from './storage/keyring'; import {KeyValue} from './storage/key-value'; import {SessionManager} from '@chatenium/chatenium-sdk/services/sessionManager'; import {Session} from '@chatenium/chatenium-sdk/domain/sessionManager.schema'; +import {ChatService} from '@chatenium/chatenium-sdk/services/chatService'; +import {Chat} from '@chatenium/chatenium-sdk/domain/chatService.schema'; +import {DMService} from '@chatenium/chatenium-sdk/services/dmService'; @Injectable({ providedIn: 'root', @@ -15,4 +18,22 @@ export class ServiceManager { sessionManager = new SessionManager(this.database.getApi(), this.keyring.getApi(), this.keyValue.getApi()) currentSession = signal(null) + + chatService: ChatService | null = null // Initialized in dm-list.ts + chatsStatus = signal(LoadStatus.loading) + chats = signal([]) + + dmServices = signal>({}) +} + +export enum LoadStatus { + loading = 0, + loaded = 1, + error = 2, + updating = 3, +} + +export interface DmStorage { + service: DMService + chatData: Chat } diff --git a/src/styles.scss b/src/styles.scss index b51f3d6..bb60e14 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -20,3 +20,9 @@ body { src: url("/Onest-ExtraBold.ttf"); font-weight: bold; } + +@font-face { + font-family: "Onest"; + src: url("/Onest-SemiBold.ttf"); + font-weight: 600; +}