3.0 Beta 2
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user