3.0 Beta 3

This commit is contained in:
2026-04-11 13:22:56 +02:00
parent a01b5347d6
commit 7e5ea20409
24 changed files with 569 additions and 327 deletions

View File

@@ -1,10 +1,11 @@
import {provideTaiga} from '@taiga-ui/core';
import {ApplicationConfig, provideBrowserGlobalErrorListeners} from '@angular/core';
import {ApplicationConfig, provideBrowserGlobalErrorListeners, isDevMode} from '@angular/core';
import {provideRouter} from '@angular/router';
import {routes} from './app.routes';
import {provideTranslateService} from '@ngx-translate/core';
import {provideTranslateHttpLoader} from '@ngx-translate/http-loader';
import { provideServiceWorker } from '@angular/service-worker';
export const appConfig: ApplicationConfig = {
providers: [
@@ -18,6 +19,9 @@ export const appConfig: ApplicationConfig = {
prefix: "/i18n/",
suffix: ".json"
})
})
}), provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000'
})
],
};

View File

@@ -1,11 +1,15 @@
<ng-template [(tuiDialog)]="changeLogOpen" [tuiDialogOptions]="{closable: false, dismissible: false, label: 'chat.changeLogDialog.label'|translate}">
<h3>{{"version"|translate}}</h3>
<ng-template [(tuiDialog)]="changeLogOpen"
[tuiDialogOptions]="{closable: false, dismissible: false, label: 'chat.changeLogDialog.label'|translate}">
<h3>{{ "version"|translate }}</h3>
<ul>
<li>{{"chat.changeLogDialog.changeLog.1"|translate}}</li>
<li>{{"chat.changeLogDialog.changeLog.2"|translate}}</li>
<li>{{ "chat.changeLogDialog.changeLog.1"|translate }}</li>
<li>{{ "chat.changeLogDialog.changeLog.2"|translate }}</li>
<li>{{ "chat.changeLogDialog.changeLog.3"|translate }}</li>
</ul>
<button tuiButton iconStart="@tui.check" (click)="localStorage.setItem('changeLogLastRead', environment.version); changeLogOpen.set(false)">{{"ok"|translate}}</button>
<button tuiButton iconStart="@tui.check"
(click)="localStorage.setItem('changeLogLastRead', environment.version); changeLogOpen.set(false)">{{ "ok"|translate }}
</button>
</ng-template>
@if (serviceManager.currentSession() == null) {
@@ -13,37 +17,74 @@
<tui-loader size="xl"/>
</main>
} @else {
<main id="layout" tuiGroup [collapsed]="true">
<aside id="chatnav">
<aside>
<tui-segmented id="mode_switcher">
<button>
<tui-icon icon="@tui.message-circle"/>
</button>
<button disabled style="pointer-events: none; opacity: 0.5">
<tui-icon icon="@tui.network"/>
</button>
<button disabled style="pointer-events: none; opacity: 0.5">
<tui-icon icon="@tui.image"/>
</button>
</tui-segmented>
@if (breakpoint() != "mobile") {
<main id="layout" tuiGroup [collapsed]="true">
<aside id="chatnav">
<aside>
<tui-segmented id="mode_switcher">
<button>
<tui-icon icon="@tui.message-circle"/>
</button>
<button disabled style="pointer-events: none; opacity: 0.5">
<tui-icon icon="@tui.network"/>
</button>
<button disabled style="pointer-events: none; opacity: 0.5">
<tui-icon icon="@tui.image"/>
</button>
</tui-segmented>
<button id="bottom_btn" tuiButton appearance="flat" disabled>
<tui-icon icon="@tui.cog"/>
</button>
<button id="bottom_btn" tuiButton appearance="flat" disabled>
<tui-icon icon="@tui.cog"/>
</button>
</aside>
<main>
<app-dm-list [token]="serviceManager.currentSession()!.token"
[userid]="serviceManager.currentSession()!.userData.userid"></app-dm-list>
</main>
</aside>
<main>
<app-dm-list [token]="serviceManager.currentSession()!.token" [userid]="serviceManager.currentSession()!.userData.userid"></app-dm-list>
<main id="content">
<div id="content_tint">
@defer (when serviceManager.chatsStatus() != LoadStatus.loading) {
<router-outlet/>
}
</div>
</main>
</aside>
<main id="content">
<div id="content_tint">
@defer (when serviceManager.chatsStatus() != LoadStatus.loading) {
<router-outlet/>
}
</div>
</main>
</main>
} @else {
<main id="layout_mobile">
@if (!routerOutletActive()) {
<div id="navigation">
<div id="navigation_content">
@switch (navigationActiveIndex) {
@case (0) {
<app-dm-list [token]="serviceManager.currentSession()!.token"
[userid]="serviceManager.currentSession()!.userData.userid"></app-dm-list>
}
}
</div>
<nav tuiTabBar [(activeItemIndex)]="navigationActiveIndex">
@for (item of tabBarItems; track item; let i = $index) {
<button
[disabled]="!item.implemented"
[class.disabled]="!item.implemented"
tuiTabBarItem
type="button"
[icon]="item.icon"
(click)="navigationActiveIndex = i"
>
{{ item.text | translate }}
</button>
}
</nav>
</div>
}
@defer (when serviceManager.chatsStatus() != LoadStatus.loading) {
<router-outlet (activate)="routerOutletActive.set(true)" (deactivate)="routerOutletActive.set(false)"/>
}
</main>
}
}

View File

@@ -65,3 +65,23 @@
}
}
}
#layout_mobile {
height: 93svh;
#navigation {
height: 100%;
grid-template-rows: 1fr 50px;
button {
&.disabled {
opacity: 0.5;
}
}
#navigation_content {
height: 100%;
padding: 20px;
}
}
}

View File

@@ -1,15 +1,16 @@
import {Component, inject, OnInit, signal} from '@angular/core';
import {RouterOutlet} from '@angular/router';
import {Component, computed, inject, OnInit, signal} from '@angular/core';
import {isActive, IsActiveMatchOptions, Router, RouterOutlet} from '@angular/router';
import {TuiSegmented} from '@taiga-ui/kit';
import {TuiAppearance, TuiButton, TuiDialog, TuiGroup, TuiIcon, TuiLoader} from '@taiga-ui/core';
import {TUI_BREAKPOINT, TuiAppearance, TuiButton, TuiDialog, TuiGroup, TuiIcon, TuiLoader} from '@taiga-ui/core';
import {SessionManager} from '@chatenium/chatenium-sdk/services/sessionManager';
import {LoadStatus, ServiceManager} from '../service-manager';
import {IndexedDB} from '../storage/indexed-db';
import {DmList} from './dm-list/dm-list';
import {JsonPipe} from '@angular/common';
import {WebSocketHandler} from '@chatenium/chatenium-sdk/core/webSocketHandler';
import {TranslatePipe} from '@ngx-translate/core';
import {TranslatePipe, TranslateService} from '@ngx-translate/core';
import {environment} from '../../environments/environment';
import {TuiTabBarComponent, TuiTabBarItem} from '@taiga-ui/addon-mobile';
@Component({
selector: 'app-chat',
@@ -24,7 +25,9 @@ import {environment} from '../../environments/environment';
TuiAppearance,
TuiGroup,
TuiDialog,
TranslatePipe
TranslatePipe,
TuiTabBarComponent,
TuiTabBarItem
],
templateUrl: './chat.html',
styleUrl: './chat.scss',
@@ -32,6 +35,35 @@ import {environment} from '../../environments/environment';
export class Chat implements OnInit {
serviceManager = inject(ServiceManager)
indexedDb = inject(IndexedDB)
breakpoint = inject(TUI_BREAKPOINT)
router = inject(Router)
routerOutletActive = signal(false)
navigationActiveIndex = 0
// Mobile navigation //
protected readonly tabBarItems = [
{
text: "chat.tabBar.tab1",
icon: '@tui.message-circle',
implemented: true,
},
{
text: "chat.tabBar.tab2",
icon: '@tui.network',
implemented: false,
},
{
text: "chat.tabBar.tab3",
icon: '@tui.image',
implemented: false,
},
{
text: "chat.tabBar.tab4",
icon: '@tui.cog',
implemented: false,
}
];
changeLogOpen = signal(false)

View File

@@ -1,9 +1,9 @@
<button tuiButton appearance="secondary" iconStart="@tui.mail-plus">
<button disabled tuiButton appearance="secondary" iconStart="@tui.mail-plus">
{{"chat.chatnav.dmList.newChat"|translate}}
</button>
@for (chat of serviceManager.chats(); track chat.chatid) {
<button tuiButton [appearance]="router.url == '/chat/dm/' + chat.chatid ? 'primary' : 'flat'" [routerLink]="'/chat/dm/' + chat.chatid">
<button [class.enlarge]="breakpoint() == 'mobile'" tuiButton [appearance]="router.url == '/chat/dm/' + chat.chatid ? 'primary' : 'flat'" [routerLink]="'/chat/dm/' + chat.chatid">
<oimg [src]="chat.pfp" height="35px" width="35px" [radius]="10"></oimg>
<div class="info">
@if (chat.displayName == "") {

View File

@@ -9,6 +9,10 @@
justify-content: start;
font-weight: 600;
&.enlarge {
height: 75px;
}
.info {
display: flex;
flex-direction: column;

View File

@@ -2,7 +2,7 @@ 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 {TuiButton} from '@taiga-ui/core';
import {TUI_BREAKPOINT, TuiButton} from '@taiga-ui/core';
import {Oimg} from '../elements/oimg/oimg';
import {Router, RouterLink} from '@angular/router';
import {TranslatePipe} from '@ngx-translate/core';
@@ -26,6 +26,7 @@ export class DmList implements OnInit {
indexedDb = inject(IndexedDB)
router = inject(Router)
serviceManager = inject(ServiceManager)
breakpoint = inject(TUI_BREAKPOINT)
async ngOnInit() {
this.serviceManager.chatService = new ChatService(this.userid(), this.token(), this.indexedDb.getApi(), () => {})

View File

@@ -1,25 +1,28 @@
@defer (when store) {
<navbar>
<div class="items-left">
<oimg [src]="store.chatData().pfp" height="50px" width="50px" [radius]="15"></oimg>
<div class="chat-data">
@if (store.chatData().displayName == "") {
<span class="main-name">{{'@'+store.chatData().username}}</span>
} @else {
<span class="main-name">{{store.chatData().displayName}}</span>
<span class="alt-name">{{'@'+store.chatData().username}}</span>
}
<main [class.mobile]="breakpoint() == 'mobile'">
@defer (when store) {
<navbar backButtonDest="/chat">
<div class="items-left">
<oimg [src]="store.chatData().pfp" height="50px" width="50px" [radius]="15"></oimg>
<div class="chat-data">
@if (store.chatData().displayName == "") {
<span class="main-name">{{'@'+store.chatData().username}}</span>
} @else {
<span class="main-name">{{store.chatData().displayName}}</span>
<span class="alt-name">{{'@'+store.chatData().username}}</span>
}
</div>
</div>
</div>
<div class="items-right">
<button tuiButton appearance="flat" disabled>
<tui-icon icon="@tui.phone"/>
</button>
</div>
</navbar>
<div class="items-right">
<button tuiButton appearance="flat" disabled>
<tui-icon icon="@tui.phone"/>
</button>
</div>
</navbar>
<messages [messageBoxViewModel]="store.messageBox" [messages]="store.messages()" id="scrollContainer" (onDelete)="deleteMessage($event)"/>
<messages [messageBoxViewModel]="store.messageBox" [messages]="store.messages()" id="scrollContainer" (onDelete)="deleteMessage($event)"/>
<message-box [viewModel]="store.messageBox"/>
}
<message-box [viewModel]="store.messageBox"/>
}
</main>

View File

@@ -1,8 +1,17 @@
:host {
main {
height: 95svh;
display: grid;
grid-template-rows: 70px minmax(0, 1fr) auto;
&.mobile {
height: 100svh;
padding: 15px;
}
.mobile {
height: 5px;
}
navbar {
.chat-data {
display: flex;

View File

@@ -5,7 +5,7 @@ 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 {TUI_BREAKPOINT, TuiButton, TuiIcon} from '@taiga-ui/core';
import {FileDataWithPreview, MessageBox} from '../elements/message-box/message-box';
import {Messages} from '../elements/messages/messages';
import {Chat} from '@chatenium/chatenium-sdk/domain/chatService.schema';
@@ -32,6 +32,7 @@ export class Dm implements OnInit {
serviceManager = inject(ServiceManager)
route = inject(ActivatedRoute)
indexedDb = inject(IndexedDB)
breakpoint = inject(TUI_BREAKPOINT)
chatid = ""

View File

@@ -68,7 +68,7 @@
<tui-icon icon="@tui.x"/>
</button>
</div>
<div id="message-box" [style]="'border-radius:'+messageBoxRadius+'px;'">
<div id="message-box" [style]="'border-radius:'+messageBoxRadius+'px;'" [class.fullWidth]="breakpoint() != 'desktopLarge'">
<div class="items-left">
<button tuiButton appearance="flat" (click)="uplInput.click()">
<tui-icon icon="@tui.file-up"/>

View File

@@ -102,6 +102,10 @@
align-items: center;
padding: 0 10px;
&.fullWidth {
width: 100%;
}
.items-left, .items-middle, .items-right {
display: flex;
align-items: center;

View File

@@ -1,5 +1,6 @@
import {ChangeDetectorRef, Component, HostListener, inject, input} from '@angular/core';
import {
TUI_BREAKPOINT,
TuiAppearance,
TuiButton,
TuiDialog,
@@ -40,6 +41,7 @@ import {TuiTextarea, TuiTextareaComponent} from '@taiga-ui/kit';
export class MessageBox {
viewModel = input.required<MessageBoxViewModel>()
breakpoint = inject(TUI_BREAKPOINT)
cdr = inject(ChangeDetectorRef)
textareaHeight = 25

View File

@@ -4,6 +4,7 @@
flex-direction: column;
gap: 2px;
overflow-y: scroll;
overflow-x: hidden;
.message {
display: flex;

View File

@@ -1,3 +1,10 @@
<nav>
<nav [class.mobile]="breakpoint() == 'mobile'">
@if (breakpoint() == "mobile") {
<div>
<button (click)="router.navigate([backButtonDest()])" tuiButton appearance="flat" iconStart="@tui.chevron-left">
{{"back"|translate}}
</button>
</div>
}
<ng-content></ng-content>
</nav>

View File

@@ -2,6 +2,17 @@ nav {
display: grid;
grid-template-columns: 1fr 1fr;
&.mobile {
zoom: 0.85;
grid-template-columns: 1fr 1fr 1fr;
::ng-deep .items-left {
display: flex;
justify-content: center;
align-items: center;
}
}
::ng-deep .items-right, ::ng-deep .items-left {
display: flex;
gap: 10px;

View File

@@ -1,9 +1,25 @@
import { Component } from '@angular/core';
import {Component, inject, input} from '@angular/core';
import {TUI_BREAKPOINT, TuiButton} from '@taiga-ui/core';
import {TuiAppBarComponent} from '@taiga-ui/layout';
import {TuiPlatform} from '@taiga-ui/cdk';
import {NgTemplateOutlet} from '@angular/common';
import {TranslatePipe} from '@ngx-translate/core';
import {Router} from '@angular/router';
@Component({
selector: 'navbar',
imports: [],
imports: [
TuiAppBarComponent,
TuiPlatform,
NgTemplateOutlet,
TuiButton,
TranslatePipe
],
templateUrl: './navbar.html',
styleUrl: './navbar.scss',
})
export class Navbar {}
export class Navbar {
breakpoint = inject(TUI_BREAKPOINT)
router = inject(Router)
backButtonDest = input.required<string>()
}

View File

@@ -1,5 +1,5 @@
export const environment = {
version: "3.0-beta2",
version: "3.0-beta3",
api_url: "http://localhost:3000",
cdn_url: "http://localhost:4000",
ws_url: "ws://localhost:3000",

View File

@@ -1,6 +1,6 @@
export const environment = {
version: "3.0-beta2",
version: "3.0-beta3",
api_url: "https://api.chatenium.hu",
cdn_url: "https://cdn.chatenium.hu",
ws_url: "wss://cdn.chatenium.hu",
ws_url: "wss://api.chatenium.hu",
};

View File

@@ -7,8 +7,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="manifest" href="manifest.webmanifest">
</head>
<body>
<app-root></app-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body>
</html>