Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

139 lines
4.0KB

  1. import {Component, Output, EventEmitter, Input, ViewChild, ElementRef, OnDestroy} from '@angular/core';
  2. import {CommonModule} from '@angular/common';
  3. import {FormsModule} from '@angular/forms';
  4. import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
  5. import {faPaperclip, faTimes} from '@fortawesome/free-solid-svg-icons';
  6. import {SafeHtml} from '@angular/platform-browser';
  7. import {AttachedFile} from '../../models/data.model';
  8. import {FileHandlerService} from '../../services/file-handler.service';
  9. @Component({
  10. selector: 'app-chat-input',
  11. standalone: true,
  12. imports: [CommonModule, FormsModule, FontAwesomeModule],
  13. templateUrl: './chat-input.html',
  14. styleUrls: ['./chat-input.scss']
  15. })
  16. export class ChatInput implements OnDestroy {
  17. @Input() disabled = false;
  18. @Output() messageSent = new EventEmitter<{ message: string; files: AttachedFile[] }>();
  19. @Output() fileAttached = new EventEmitter<File[]>();
  20. @Output() voiceActivated = new EventEmitter<void>();
  21. @ViewChild('messageInput') messageInput!: ElementRef<HTMLTextAreaElement>;
  22. @ViewChild('fileInput') fileInput!: ElementRef<HTMLInputElement>;
  23. message = '';
  24. attachedFiles: AttachedFile[] = [];
  25. faPaperclip = faPaperclip;
  26. faTimes = faTimes;
  27. constructor(
  28. private fileHandlerService: FileHandlerService
  29. ) {
  30. }
  31. ngOnDestroy(): void {
  32. this.fileHandlerService.cleanupFiles(this.attachedFiles);
  33. }
  34. onSend(): void {
  35. if ((this.message.trim() || this.attachedFiles.length > 0) && !this.disabled) {
  36. const filesClone = this.fileHandlerService.cloneAttachedFiles(this.attachedFiles);
  37. this.messageSent.emit({
  38. message: this.message.trim(),
  39. files: filesClone
  40. });
  41. this.message = '';
  42. this.attachedFiles = [];
  43. this.adjustTextareaHeight();
  44. }
  45. }
  46. onInputChange(): void {
  47. const textarea = this.messageInput.nativeElement;
  48. textarea.style.height = 'auto';
  49. textarea.style.height = textarea.scrollHeight + 'px';
  50. }
  51. onAttach(): void {
  52. this.fileInput.nativeElement.click();
  53. }
  54. onFileSelected(event: Event): void {
  55. const input = event.target as HTMLInputElement;
  56. if (input.files && input.files.length > 0) {
  57. this.handleFiles(Array.from(input.files));
  58. input.value = '';
  59. }
  60. }
  61. onFileDrop(event: DragEvent): void {
  62. event.preventDefault();
  63. event.stopPropagation();
  64. if (event.dataTransfer?.files && event.dataTransfer.files.length > 0) {
  65. this.handleFiles(Array.from(event.dataTransfer.files));
  66. }
  67. }
  68. onDragOver(event: DragEvent): void {
  69. event.preventDefault();
  70. event.stopPropagation();
  71. }
  72. private async handleFiles(files: File[]): Promise<void> {
  73. const validationResult = this.fileHandlerService.validateFiles(
  74. files,
  75. this.attachedFiles.length
  76. );
  77. if (!validationResult.isValid) {
  78. alert(validationResult.error);
  79. return;
  80. }
  81. try {
  82. const processedFiles = await this.fileHandlerService.processFiles(files);
  83. this.attachedFiles.push(...processedFiles);
  84. this.fileAttached.emit(files);
  85. } catch (error) {
  86. console.error('Erreur lors du traitement des fichiers:', error);
  87. alert('Erreur lors du traitement des fichiers');
  88. }
  89. }
  90. removeFile(id: string): void {
  91. const file = this.attachedFiles.find(f => f.id === id);
  92. if (file) {
  93. this.fileHandlerService.cleanupFile(file);
  94. }
  95. this.attachedFiles = this.attachedFiles.filter(f => f.id !== id);
  96. }
  97. getFileIcon(file: File): SafeHtml {
  98. return this.fileHandlerService.getFileIcon(file);
  99. }
  100. formatFileSize(bytes: number): string {
  101. return this.fileHandlerService.formatFileSize(bytes);
  102. }
  103. onVoice(): void {
  104. this.voiceActivated.emit();
  105. }
  106. private adjustTextareaHeight(): void {
  107. if (this.messageInput) {
  108. const textarea = this.messageInput.nativeElement;
  109. textarea.style.height = 'auto';
  110. textarea.style.height = Math.min(textarea.scrollHeight, 200) + 'px';
  111. }
  112. }
  113. protected getAcceptedTypes() {
  114. return this.fileHandlerService.getAcceptedTypes;
  115. }
  116. }