3.0 Beta 2

This commit is contained in:
2026-04-10 21:57:29 +02:00
parent 67918644e0
commit a01b5347d6
65 changed files with 1619 additions and 175 deletions

View File

@@ -12,4 +12,5 @@ export class MessageBoxViewModel {
message = signal<string>("")
files = signal<FileDataWithPreview[]>([])
dialogOpen = signal<boolean>(false)
editingMessage = signal<{messageId: string, message: string} | null >(null)
}

View File

@@ -5,7 +5,7 @@
</div>
<span>{{ "chat.elements.messageBox.uplDrag.upload"|translate }}</span>
</div>
<div class="method">
<div class="method" style="opacity: 0.5">
<div class="icon-holder">
<tui-icon icon="@tui.cloud-sync"/>
</div>
@@ -14,13 +14,25 @@
</div>
<ng-template [(tuiDialog)]="viewModel().dialogOpen" [tuiDialogOptions]="{label: 'chat.elements.messageBox.fileUploadDialog.label'|translate}">
<masonry [maxColSize]="2" style="overflow-y: scroll; height: 500px">
@if (filterPictureVideo(viewModel().files()).length != 0) {
<masonry [maxColSize]="2" style="overflow-y: scroll; height: 200px">
@for (file of viewModel().files(); track file) {
@if (file.type == "image") {
<img [src]="file.blob" style="width: 100%; height: 100%; object-fit: fill;"/>
}
}
</masonry>
}
<div tuiGroup orientation="vertical" style="width: 100%">
@for (file of viewModel().files(); track file) {
@if (file.type == "image") {
<img [src]="file.blob" style="width: 100%; height: 100%; object-fit: fill;"/>
@if (file.type != "image") {
<div style="background: var(--tui-background-neutral-1); height: 50px; display: flex; align-items: center; padding: 0 10px">
<span>{{ file.name }}</span>
</div>
}
}
</masonry>
</div>
<div style="margin-top: 10px; display: flex; gap: 10px; width: 100%">
<tui-textfield style="width: 100%">
@@ -37,25 +49,45 @@
</div>
</ng-template>
<div id="message-box" [style]="'border-radius:'+messageBoxRadius+'px;'">
<div class="items-left">
<button tuiButton appearance="flat" (click)="uplInput.click()">
<tui-icon icon="@tui.file-up"/>
<input #uplInput type="file" (change)="handleFileInput($event)" multiple hidden/>
</button>
<main>
<div id="message-box-extension" tuiAppearance="floating" [class.shown]="viewModel().editingMessage()">
<div id="content">
@if (viewModel().editingMessage()) {
<tui-icon icon="@tui.pencil"></tui-icon>
<span>{{"chat.elements.messageBox.editMessageLabel"|translate}}</span>
@if (viewModel().editingMessage()!.message == "") {
<tui-icon icon="@tui.paperclip"></tui-icon>
<span>{{"chat.elements.messageBox.attachments"|translate}}</span>
} @else {
{{viewModel().editingMessage()!.message}}
}
}
</div>
<button tuiButton appearance="flat">
<tui-icon icon="@tui.cloud-sync"/>
<button id="close" tuiButton appearance="flat" (click)="viewModel().editingMessage.set(null); viewModel().message.set('');">
<tui-icon icon="@tui.x"/>
</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 id="message-box" [style]="'border-radius:'+messageBoxRadius+'px;'">
<div class="items-left">
<button tuiButton appearance="flat" (click)="uplInput.click()">
<tui-icon icon="@tui.file-up"/>
<input #uplInput type="file" (change)="handleFileInput($event)" multiple hidden/>
</button>
<button tuiButton appearance="flat" disabled>
<tui-icon icon="@tui.cloud-sync"/>
</button>
</div>
<div class="items-middle">
<textarea (keydown.enter)="handleEnterKeydown($event); viewModel().onMessageSend(message.value, null)" [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 [disabled]="message.value.trim() == ''" tuiButton appearance="flat" (click)="viewModel().onMessageSend(message.value, null)">
<tui-icon icon="@tui.send"/>
</button>
</div>
</div>
<div class="items-right">
<button tuiButton appearance="flat" (click)="viewModel().onMessageSend(message.value, null)">
<tui-icon icon="@tui.send"/>
</button>
</div>
</div>
</main>

View File

@@ -48,72 +48,115 @@
}
}
#message-box {
transition: all 0.2s ease-in-out;
width: 60%;
background: var(--tui-background-base-alt);
min-height: 75px;
max-height: 200px;
border: 2px solid var(--tui-border-normal);
display: grid;
grid-template-columns: 85px 1fr 100px;
main {
width: 100%;
display: flex;
align-items: center;
padding: 0 10px;
flex-direction: column;
gap: 5px;
.items-left, .items-middle, .items-right {
display: flex;
align-items: center;
}
#message-box-extension {
transition: all 0.2s ease-in-out;
width: 50%;
border-radius: 20px;
background: var(--tui-background-base-alt);
border: 2px solid var(--tui-border-normal);
transform: translateY(50px);
display: grid;
grid-template-columns: 1fr 40px;
justify-content: center;
height: 0;
#content {
padding-left: 10px;
display: flex;
gap: 5px;
align-items: center;
}
tui-icon {
font-size: 13px;
}
.items-left, .items-right {
button {
height: 30px;
height: 26px;
width: 30px;
}
tui-icon {
font-size: 20px;
}
&.shown {
transform: translateY(0);
height: 30px;
}
}
.items-middle {
::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 10px;
#message-box {
z-index: 5;
transition: all 0.2s ease-in-out;
width: 60%;
background: var(--tui-background-base-alt);
min-height: 75px;
max-height: 200px;
border: 2px solid var(--tui-border-normal);
display: grid;
grid-template-columns: 85px 1fr 100px;
align-items: center;
padding: 0 10px;
.items-left, .items-middle, .items-right {
display: flex;
align-items: center;
}
position: relative;
.items-left, .items-right {
button {
height: 30px;
width: 30px;
textarea {
width: 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;
tui-icon {
font-size: 20px;
}
}
}
}
.items-right {
display: flex;
justify-content: end;
.items-middle {
::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 10px;
}
position: relative;
textarea {
width: 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

@@ -103,6 +103,15 @@ export class MessageBox {
this.viewModel().dialogOpen.set(false)
}
handleEnterKeydown(e: any) {
e.preventDefault()
return false
}
filterPictureVideo(files: FileDataWithPreview[]) {
return files.filter(f => f.type == "image")
}
async processFiles(fileList: FileList) {
for (let i = 0; i < fileList.length; i++) {
const file = fileList[i];