206 lines
4.5 KiB
TypeScript
206 lines
4.5 KiB
TypeScript
|
import {
|
||
|
Component,
|
||
|
OnInit,
|
||
|
Input,
|
||
|
EventEmitter,
|
||
|
Output,
|
||
|
AfterViewInit,
|
||
|
ElementRef,
|
||
|
ViewChild,
|
||
|
ChangeDetectorRef
|
||
|
} from '@angular/core';
|
||
|
|
||
|
import { shakeAnimation } from 'angular-animations';
|
||
|
|
||
|
import {
|
||
|
Info,
|
||
|
EventType,
|
||
|
InfoResponse,
|
||
|
EventJson,
|
||
|
FileEventJson,
|
||
|
MassTranslationEventJson
|
||
|
} from '@ucap-webmessenger/protocol-event';
|
||
|
import { NGXLogger } from 'ngx-logger';
|
||
|
import moment from 'moment';
|
||
|
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||
|
import { RoomInfo } from '@ucap-webmessenger/protocol-room';
|
||
|
import { SelectFileInfo } from '@ucap-webmessenger/ui';
|
||
|
|
||
|
@Component({
|
||
|
selector: 'ucap-chat-message-box',
|
||
|
templateUrl: './message-box.component.html',
|
||
|
styleUrls: ['./message-box.component.scss'],
|
||
|
animations: [shakeAnimation()]
|
||
|
})
|
||
|
export class MessageBoxComponent implements OnInit, AfterViewInit {
|
||
|
@Input()
|
||
|
message: Info<EventJson>;
|
||
|
|
||
|
@Input()
|
||
|
mine = false;
|
||
|
|
||
|
@Input()
|
||
|
highlight = false;
|
||
|
|
||
|
@Input()
|
||
|
existReadToHere = false;
|
||
|
|
||
|
@Input()
|
||
|
dateChanged = false;
|
||
|
|
||
|
@Input()
|
||
|
senderName: string;
|
||
|
|
||
|
@Input()
|
||
|
profileImageRoot: string;
|
||
|
|
||
|
@Input()
|
||
|
profileImage: string;
|
||
|
|
||
|
@Input()
|
||
|
roomInfo: RoomInfo;
|
||
|
|
||
|
@Input()
|
||
|
translationSimpleview = false;
|
||
|
|
||
|
@Input()
|
||
|
unreadCount: number;
|
||
|
|
||
|
@Output()
|
||
|
openProfile = new EventEmitter<number>();
|
||
|
|
||
|
@Output()
|
||
|
massDetail = new EventEmitter<number>();
|
||
|
|
||
|
@Output()
|
||
|
massTranslationDetail = new EventEmitter<{
|
||
|
message: Info<MassTranslationEventJson>;
|
||
|
contentsType: string;
|
||
|
}>();
|
||
|
|
||
|
@Output()
|
||
|
fileViewer = new EventEmitter<SelectFileInfo>();
|
||
|
|
||
|
@Output()
|
||
|
save = new EventEmitter<{
|
||
|
fileInfo: FileEventJson;
|
||
|
fileDownloadItem: FileDownloadItem;
|
||
|
type: string;
|
||
|
}>();
|
||
|
|
||
|
@Output()
|
||
|
contextMenu = new EventEmitter<{
|
||
|
event: MouseEvent;
|
||
|
message: Info<EventJson>;
|
||
|
type?: string;
|
||
|
}>();
|
||
|
|
||
|
@ViewChild('mbContainer', { static: true })
|
||
|
mbContainer: ElementRef<HTMLElement>;
|
||
|
|
||
|
@ViewChild('mbChatRow', { static: true })
|
||
|
mbChatRow: ElementRef<HTMLElement>;
|
||
|
|
||
|
EventType = EventType;
|
||
|
|
||
|
moment = moment;
|
||
|
|
||
|
firstEventSeq = 0;
|
||
|
existReadHere = false;
|
||
|
shakeIt = false;
|
||
|
|
||
|
get offsetTop() {
|
||
|
return this.mbChatRow.nativeElement.offsetTop;
|
||
|
}
|
||
|
|
||
|
constructor(
|
||
|
private elementRef: ElementRef<HTMLElement>,
|
||
|
private changeDetectorRef: ChangeDetectorRef,
|
||
|
private logger: NGXLogger
|
||
|
) {}
|
||
|
|
||
|
ngOnInit() {
|
||
|
this.mbContainer.nativeElement.classList.add('hide');
|
||
|
}
|
||
|
|
||
|
ngAfterViewInit(): void {
|
||
|
this.elementRef.nativeElement.style.height = `${this.mbContainer.nativeElement.offsetHeight}px`;
|
||
|
this.elementRef.nativeElement.style.maxHeight = `${this.mbContainer.nativeElement.offsetHeight}px`;
|
||
|
this.mbContainer.nativeElement.classList.remove('hide');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 정보성 Event 인지 판단.
|
||
|
* @description 정보성 event 일 경우 프로필, 일시 를 표현하지 않는다.
|
||
|
* Edit with reducers.ts / sync / updateRoomForNewEventMessage
|
||
|
*/
|
||
|
isInformation(info: Info<EventJson>) {
|
||
|
if (
|
||
|
info.type === EventType.Join ||
|
||
|
info.type === EventType.Exit ||
|
||
|
info.type === EventType.ForcedExit ||
|
||
|
info.type === EventType.RenameRoom ||
|
||
|
info.type === EventType.NotificationForiOSCapture ||
|
||
|
info.type === EventType.NotificationForTimerRoom ||
|
||
|
info.type === EventType.GuideForRoomTimerChanged
|
||
|
) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
onClickOpenProfile(event: MouseEvent, userSeq: number) {
|
||
|
event.preventDefault();
|
||
|
event.stopPropagation();
|
||
|
|
||
|
this.openProfile.emit(userSeq);
|
||
|
}
|
||
|
|
||
|
/** [Event] MassTalk Detail View */
|
||
|
onMassDetail(value: number) {
|
||
|
this.massDetail.emit(value);
|
||
|
}
|
||
|
|
||
|
// onMassTranslationDetail(params: {
|
||
|
// message: Info<MassTranslationEventJson>;
|
||
|
// contentsType: string;
|
||
|
// }) {
|
||
|
// this.massTranslationDetail.emit(params);
|
||
|
// }
|
||
|
|
||
|
/** [Event] Image Viewer */
|
||
|
onFileViewer(fileInfo: SelectFileInfo) {
|
||
|
this.fileViewer.emit(fileInfo);
|
||
|
}
|
||
|
|
||
|
/** [Event] Attach File Save & Save As */
|
||
|
onSave(value: {
|
||
|
fileInfo: FileEventJson;
|
||
|
fileDownloadItem: FileDownloadItem;
|
||
|
type: string;
|
||
|
}) {
|
||
|
this.save.emit(value);
|
||
|
}
|
||
|
|
||
|
/** [Event] Context Menu */
|
||
|
onContextMenu(event: any, message: Info<EventJson>) {
|
||
|
if (
|
||
|
message.type === EventType.Translation ||
|
||
|
message.type === EventType.MassTranslation
|
||
|
) {
|
||
|
this.contextMenu.emit({ event: event.event, message, type: event.type });
|
||
|
} else {
|
||
|
this.contextMenu.emit({ event, message });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
shake() {
|
||
|
this.shakeIt = false;
|
||
|
this.changeDetectorRef.detectChanges();
|
||
|
setTimeout(() => {
|
||
|
this.shakeIt = true;
|
||
|
this.changeDetectorRef.detectChanges();
|
||
|
}, 1);
|
||
|
}
|
||
|
}
|