156 lines
4.0 KiB
TypeScript
156 lines
4.0 KiB
TypeScript
import {Component, HostListener, inject, input} from '@angular/core';
|
|
import {
|
|
TuiAppearance,
|
|
TuiButton,
|
|
TuiDialog,
|
|
TuiGroup,
|
|
TuiIcon,
|
|
TuiScrollbarDirective,
|
|
TuiTextfield
|
|
} 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';
|
|
import {v4 as uuidv4} from 'uuid';
|
|
import {Masonry} from '../masonry/masonry';
|
|
import {Oimg} from '../oimg/oimg';
|
|
import {FileData} from '@chatenium/chatenium-sdk/domain/fileUploadService.schema';
|
|
import {TuiTextarea, TuiTextareaComponent} from '@taiga-ui/kit';
|
|
|
|
@Component({
|
|
selector: 'message-box',
|
|
imports: [
|
|
TuiAppearance,
|
|
TranslatePipe,
|
|
TuiScrollbarDirective,
|
|
TuiGroup,
|
|
TuiIcon,
|
|
TuiButton,
|
|
FormsModule,
|
|
TuiDialog,
|
|
Oimg,
|
|
Masonry,
|
|
TuiTextfield,
|
|
TuiTextarea
|
|
],
|
|
templateUrl: './message-box.html',
|
|
styleUrl: './message-box.scss',
|
|
})
|
|
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
|
|
}
|
|
|
|
handleFileInput(event: any) {
|
|
this.processFiles(event.target.files)
|
|
}
|
|
|
|
sendMessageWithCaption(e: TuiTextareaComponent) {
|
|
this.viewModel().onMessageSend((e.content() as string), this.viewModel().files())
|
|
}
|
|
|
|
async processFiles(fileList: FileList) {
|
|
for (let i = 0; i < fileList.length; i++) {
|
|
const file = fileList[i];
|
|
const type = file.type.split("/").shift() ?? ""
|
|
let preview = ""
|
|
let height = 0
|
|
let width = 0
|
|
|
|
console.log(type)
|
|
|
|
if (type == "image") {
|
|
try {
|
|
const imgData = await makePicturePreview(file)
|
|
console.log(imgData)
|
|
preview = imgData.preview
|
|
height = imgData.height
|
|
width = imgData.width
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
}
|
|
|
|
console.log("push")
|
|
this.viewModel().files().push({
|
|
fileId: uuidv4(),
|
|
data: file,
|
|
name: file.name,
|
|
type: type,
|
|
extension: file.name.split(".").pop() ?? "",
|
|
preview: preview,
|
|
height: height,
|
|
width: width,
|
|
})
|
|
console.log(this.viewModel().files())
|
|
}
|
|
|
|
function makePicturePreview(file: File): Promise<{ preview: string, height: number, width: number }> {
|
|
return new Promise((resolve, reject) => {
|
|
const img = new Image();
|
|
const objectUrl = URL.createObjectURL(file);
|
|
|
|
img.onload = () => {
|
|
console.log("Loaded image")
|
|
resolve({
|
|
preview: objectUrl,
|
|
width: img.naturalWidth,
|
|
height: img.naturalHeight,
|
|
});
|
|
};
|
|
|
|
img.onerror = (err) => {
|
|
URL.revokeObjectURL(objectUrl);
|
|
console.error("Error loading image:", err);
|
|
reject(err);
|
|
};
|
|
|
|
img.src = objectUrl;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* All the extra data for client-side rendering. (With finished messages these are generated on the server)
|
|
*/
|
|
export interface FileDataWithPreview extends FileData {
|
|
preview: string;
|
|
height: number;
|
|
width: number;
|
|
}
|