This commit is contained in:
2026-04-09 11:23:26 +02:00
parent c5bc817efe
commit 9baab3d3bc
18 changed files with 489 additions and 37 deletions

View File

@@ -0,0 +1,11 @@
import {signal} from '@angular/core';
export class MessageBoxViewModel {
onMessageSend: (message: string) => void
constructor(onMessageSend: (message: string) => void) {
this.onMessageSend = onMessageSend
}
message = signal<string>("")
}

View File

@@ -1,7 +1,36 @@
<div id="message-box">
<div></div>
<div class="items-middle">
<textarea></textarea>
<div id="dragOverlay" tuiGroup orientation="vertical" [class.show]="isDraggingOverWindow">
<div class="method">
<div class="icon-holder">
<tui-icon icon="@tui.file-up"/>
</div>
<span>{{ "chat.elements.messageBox.uplDrag.upload"|translate }}</span>
</div>
<div class="method">
<div class="icon-holder">
<tui-icon icon="@tui.cloud-sync"/>
</div>
<span>{{ "chat.elements.messageBox.uplDrag.transfer"|translate }}</span>
</div>
</div>
<div id="message-box" [style]="'border-radius:'+messageBoxRadius+'px;'">
<div class="items-left">
<button tuiButton appearance="flat">
<tui-icon icon="@tui.file-up"/>
</button>
<button tuiButton appearance="flat">
<tui-icon icon="@tui.cloud-sync"/>
</button>
</div>
<div class="items-middle">
<textarea [style]="'height:'+textareaHeight+'px;'" #message (input)="onTextAreaInput(message)" [(ngModel)]="viewModel().message"></textarea>
<span class="placeholder"
[class.hidden]="message.value != ''">{{ "chat.elements.messageBox.placeholder"|translate }}</span>
</div>
<div class="items-right">
<button tuiButton appearance="flat" (click)="viewModel().onMessageSend(message.value)">
<tui-icon icon="@tui.send"/>
</button>
</div>
<div></div>
</div>

View File

@@ -3,27 +3,117 @@
display: flex;
justify-content: center;
#dragOverlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease-in-out;
&.show {
opacity: 1;
pointer-events: all;
}
.method {
width: 800px;
height: 200px;
background: var(--tui-background-accent-1-hover);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 15px;
.icon-holder {
border-radius: 50%;
background: var(--tui-background-accent-1);
padding: 20px;
tui-icon {
font-size: 50px;
}
}
span {
font-size: 20px;
font-weight: 600;
}
}
}
#message-box {
transition: all 0.2s ease-in-out;
width: 60%;
background: var(--tui-background-base-alt);
height: 75px;
border-radius: 200px;
min-height: 75px;
max-height: 200px;
border: 2px solid var(--tui-border-normal);
display: grid;
grid-template-columns: 10% 80% 10%;
grid-template-columns: 85px 1fr 100px;
align-items: center;
padding: 0 10px;
.items-left, .items-middle, .items-right {
display: flex;
align-items: center;
}
.items-left, .items-right {
button {
height: 30px;
width: 30px;
tui-icon {
font-size: 20px;
}
}
}
.items-middle {
::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 10px;
}
position: relative;
textarea {
width: 100%;
height: 100%;
background: transparent;
border: none;
outline: none;
resize: none;
color: var(--tui-text-01);
font-size: 16px;
z-index: 1;
}
.placeholder {
position: absolute;
font-size: 16px;
height: 25px;
top: 2px;
left: 2px;
color: gray;
transition: all 0.2s ease-in-out;
&.hidden {
margin-left: 10px;
opacity: 0;
}
}
}
.items-right {
display: flex;
justify-content: end;
}
}
}

View File

@@ -1,12 +1,59 @@
import { Component } from '@angular/core';
import {TuiAppearance} from '@taiga-ui/core';
import {Component, HostListener, inject, input} from '@angular/core';
import {TuiAppearance, TuiButton, TuiGroup, TuiIcon, TuiScrollbarDirective} from '@taiga-ui/core';
import {TranslatePipe} from '@ngx-translate/core';
import {ServiceManager} from '../../../service-manager';
import {MessageBoxViewModel} from './message-box-viewmodel';
import {FormsModule} from '@angular/forms';
@Component({
selector: 'message-box',
imports: [
TuiAppearance
TuiAppearance,
TranslatePipe,
TuiScrollbarDirective,
TuiGroup,
TuiIcon,
TuiButton,
FormsModule
],
templateUrl: './message-box.html',
styleUrl: './message-box.scss',
})
export class MessageBox {}
export class MessageBox {
viewModel = input.required<MessageBoxViewModel>()
textareaHeight = 25
messageBoxRadius = 200
private dragCounter = 0;
isDraggingOverWindow = false;
@HostListener('window:dragenter', ['$event'])
onDragEnter(event: DragEvent) {
event.preventDefault();
this.dragCounter++;
if (this.dragCounter === 1) {
this.isDraggingOverWindow = true;
console.log("Drag entered the window area");
}
}
@HostListener('window:dragleave', ['$event'])
onDragLeave(event: DragEvent) {
event.preventDefault();
this.dragCounter--;
if (this.dragCounter === 0) {
this.isDraggingOverWindow = false;
console.log("Drag left the window completely");
}
}
onTextAreaInput(e: HTMLTextAreaElement) {
const calculatedHeight = e.value.split(/\r?\n/).length * 25
const calculatedRadius = (200 - this.textareaHeight)
this.textareaHeight = calculatedHeight > 180 ? 180 : calculatedHeight
this.messageBoxRadius = calculatedRadius < 30 ? 30 : calculatedRadius
}
}