event json is refactored

This commit is contained in:
병준 박 2019-11-06 13:48:06 +09:00
parent dda8d41325
commit 820e4b8675
84 changed files with 1132 additions and 247 deletions

View File

@ -9,7 +9,6 @@ import {
JsonAnalization,
APIFormDataEncoder
} from '@ucap-webmessenger/api';
import { JsonObject } from 'type-fest';
import { FileUploadItem } from '../models/file-upload-item';
export interface FileTalkSaveRequest extends APIRequest {
@ -73,7 +72,7 @@ export const decodeFileTalkSave: APIDecoder<FileTalkSaveResponse> = (
res: any
) => {
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
const json = JsonAnalization.receiveAnalization(res);
return {
statusCode: json.StatusCode,
roomSeq: json.RoomID,

View File

@ -8,7 +8,6 @@ import {
JsonAnalization,
StatusCode
} from '@ucap-webmessenger/api';
import { JsonObject } from 'type-fest';
export interface FileTalkShareRequest extends APIRequest {
userSeq: string;
@ -52,7 +51,7 @@ export const decodeFileTalkShare: APIDecoder<FileTalkShareResponse> = (
res: any
) => {
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
const json = JsonAnalization.receiveAnalization(res);
return {
statusCode: json.StatusCode,
roomSeq: json.RoomID,

View File

@ -8,7 +8,6 @@ import {
JsonAnalization,
StatusCode
} from '@ucap-webmessenger/api';
import { JsonObject } from 'type-fest';
export interface MassTalkDownloadRequest extends APIRequest {
userSeq: number;
@ -40,7 +39,7 @@ export const decodeMassTalkDownload: APIDecoder<MassTalkDownloadResponse> = (
res: any
) => {
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
const json = JsonAnalization.receiveAnalization(res);
return {
statusCode: json.StatusCode,
errorMessage: json.ErrorMessage,

View File

@ -8,7 +8,6 @@ import {
StatusCode,
JsonAnalization
} from '@ucap-webmessenger/api';
import { JsonObject } from 'type-fest';
export interface MassTalkSaveRequest extends APIRequest {
userSeq: number;
@ -44,7 +43,7 @@ export const decodeMassTalkSave: APIDecoder<MassTalkSaveResponse> = (
res: any
) => {
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
const json = JsonAnalization.receiveAnalization(res);
return {
statusCode: json.StatusCode,
errorMessage: json.ErrorMessage,

View File

@ -8,7 +8,6 @@ import {
JsonAnalization,
StatusCode
} from '@ucap-webmessenger/api';
import { JsonObject } from 'type-fest';
export interface TransMassTalkSaveRequest extends APIRequest {
userSeq: string;
@ -50,7 +49,7 @@ export const decodeTransMassTalkSave: APIDecoder<TransMassTalkSaveResponse> = (
res: any
) => {
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
const json = JsonAnalization.receiveAnalization(res);
return {
statusCode: json.StatusCode,
translationSeq: json.EventTransSEQ,

View File

@ -8,7 +8,6 @@ import {
JsonAnalization,
StatusCode
} from '@ucap-webmessenger/api';
import { JsonObject } from 'type-fest';
export interface TranslationSaveRequest extends APIRequest {
userSeq: string;
@ -51,7 +50,7 @@ export const decodeTranslationSave: APIDecoder<TranslationSaveResponse> = (
res: any
) => {
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
const json = JsonAnalization.receiveAnalization(res);
return {
statusCode: json.StatusCode,
translationSeq: json.EventTransSEQ,

View File

@ -1,11 +1,9 @@
import { JsonObject } from 'type-fest';
export class JsonAnalization {
/**
* Raw string Analization for JSON string.
* @description Editing with string.util.ts
*/
public static receiveAnalization(jsonStr: string): JsonObject {
public static receiveAnalization(jsonStr: string): any {
const startJson = jsonStr.indexOf('{');
const endJson = jsonStr.lastIndexOf('}');

View File

@ -0,0 +1 @@
<ucap-file-viewer></ucap-file-viewer>

View File

@ -3,20 +3,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ImageViewerDialogComponent } from './image-viewer.dialog.component';
import { FileViewerDialogComponent } from './file-viewer.dialog.component';
describe('ImageViewerDialogComponent', () => {
let component: ImageViewerDialogComponent;
let fixture: ComponentFixture<ImageViewerDialogComponent>;
describe('FileViewerDialogComponent', () => {
let component: FileViewerDialogComponent;
let fixture: ComponentFixture<FileViewerDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ImageViewerDialogComponent]
declarations: [FileViewerDialogComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ImageViewerDialogComponent);
fixture = TestBed.createComponent(FileViewerDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@ -0,0 +1,34 @@
import {
Component,
OnInit,
OnDestroy,
Inject,
EventEmitter
} from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { NGXLogger } from 'ngx-logger';
export interface FileViewerDialogData {}
export interface FileViewerDialogResult {}
@Component({
selector: 'app-layout-common-file-viewer',
templateUrl: './file-viewer.dialog.component.html',
styleUrls: ['./file-viewer.dialog.component.scss']
})
export class FileViewerDialogComponent implements OnInit, OnDestroy {
constructor(
public dialogRef: MatDialogRef<
FileViewerDialogData,
FileViewerDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: FileViewerDialogData,
private logger: NGXLogger
) {}
ngOnInit() {}
ngOnDestroy(): void {}
}

View File

@ -1,34 +0,0 @@
import {
Component,
OnInit,
OnDestroy,
Inject,
EventEmitter
} from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { NGXLogger } from 'ngx-logger';
export interface ImageViewerDialogData {}
export interface ImageViewerDialogResult {}
@Component({
selector: 'app-layout-common-image-viewer',
templateUrl: './image-viewer.dialog.component.html',
styleUrls: ['./image-viewer.dialog.component.scss']
})
export class ImageViewerDialogComponent implements OnInit, OnDestroy {
constructor(
public dialogRef: MatDialogRef<
ImageViewerDialogData,
ImageViewerDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: ImageViewerDialogData,
private logger: NGXLogger
) {}
ngOnInit() {}
ngOnDestroy(): void {}
}

View File

@ -1,3 +1,3 @@
import { ImageViewerDialogComponent } from './image-viewer.dialog.component';
import { FileViewerDialogComponent } from './file-viewer.dialog.component';
export const DIALOGS = [ImageViewerDialogComponent];
export const DIALOGS = [FileViewerDialogComponent];

View File

@ -28,7 +28,8 @@ import {
isRecalled,
isCopyable,
isRecallable,
InfoResponse
InfoResponse,
EventJson
} from '@ucap-webmessenger/protocol-event';
import * as AppStore from '@app/store';
@ -63,10 +64,10 @@ import {
CreateChatDialogResult
} from '../dialogs/chat/create-chat.dialog.component';
import {
ImageViewerDialogComponent,
ImageViewerDialogData,
ImageViewerDialogResult
} from '@app/layouts/common/dialogs/image-viewer.dialog.component';
FileViewerDialogComponent,
FileViewerDialogData,
FileViewerDialogResult
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
import { CONST } from '@ucap-webmessenger/core';
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
import { StatusCode } from '@ucap-webmessenger/api';
@ -98,7 +99,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
loginRes: LoginResponse;
loginResSubscription: Subscription;
eventList$: Observable<Info[]>;
eventList$: Observable<Info<EventJson>[]>;
baseEventSeq = 0;
roomInfo: RoomInfo;
roomInfoSubscription: Subscription;
@ -350,10 +351,10 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
async onImageViewer(value: FileInfo) {
this.logger.debug('imageViewer', value);
const result = await this.dialogService.open<
ImageViewerDialogComponent,
ImageViewerDialogData,
ImageViewerDialogResult
>(ImageViewerDialogComponent, {
FileViewerDialogComponent,
FileViewerDialogData,
FileViewerDialogResult
>(FileViewerDialogComponent, {
position: {
top: '30px'
},
@ -362,6 +363,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
height: 'calc(100% - 30px)',
width: '100%',
hasBackdrop: false,
panelClass: 'app-dialog-full',
data: {}
});
}
@ -448,7 +450,10 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
);
}
onContextMenuMessage(params: { event: MouseEvent; message: Info }) {
onContextMenuMessage(params: {
event: MouseEvent;
message: Info<EventJson>;
}) {
params.event.preventDefault();
params.event.stopPropagation();
@ -462,7 +467,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
this.messageContextMenuTrigger.openMenu();
}
async onClickMessageContextMenu(menuType: string, message: Info) {
async onClickMessageContextMenu(menuType: string, message: Info<EventJson>) {
switch (menuType) {
case 'COPY':
{
@ -470,7 +475,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
case EventType.Character:
{
if (
this.clipboardService.copyFromContent(message.sentMessage)
this.clipboardService.copyFromContent(
(message as Info<string>).sentMessage
)
) {
this.snackBarService.open('클립보드에 복사되었습니다.', '', {
duration: 3000,

View File

@ -13,7 +13,7 @@ import {
} from '@ucap-webmessenger/protocol-status';
import { Router } from '@angular/router';
import { Company } from '@ucap-webmessenger/api-external';
import { EventType, Info } from '@ucap-webmessenger/protocol-event';
import { EventType, Info, EventJson } from '@ucap-webmessenger/protocol-event';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { StatusCode as ApiStatusCode } from '@ucap-webmessenger/api';
import { StatusCode } from '@ucap-webmessenger/core';
@ -302,7 +302,7 @@ const companyList: Company[] = [
}
];
const eventInfo: Info[] = [
const eventInfo: Info<EventJson>[] = [
{
seq: 6,
type: EventType.Character,

View File

@ -1,5 +1,5 @@
import { createAction, props } from '@ngrx/store';
import { Info } from '@ucap-webmessenger/protocol-event';
import { Info, EventJson } from '@ucap-webmessenger/protocol-event';
import {
MassTalkDownloadRequest,
MassTalkDownloadResponse
@ -18,7 +18,7 @@ export const newEventMessage = createAction(
'[Messenger::Chat] newEventMessage',
props<{
roomSeq: string;
info: Info;
info: Info<EventJson>;
}>()
);

View File

@ -13,7 +13,8 @@ import {
DelRequest,
DelResponse,
CancelRequest,
CancelResponse
CancelResponse,
EventJson
} from '@ucap-webmessenger/protocol-event';
export const info = createAction(
@ -24,7 +25,7 @@ export const info = createAction(
export const infoSuccess = createAction(
'[Messenger::Event] Info Success',
props<{
infoList: Info[];
infoList: Info<EventJson>[];
res: InfoResponse;
}>()
);
@ -32,7 +33,7 @@ export const infoSuccess = createAction(
export const infoMoreSuccess = createAction(
'[Messenger::Event] Info More Success',
props<{
infoList: Info[];
infoList: Info<EventJson>[];
res: InfoResponse;
}>()
);
@ -51,7 +52,7 @@ export const newInfo = createAction(
'[Messenger::Event] New Info',
props<{
roomSeq: string;
info: Info;
info: Info<EventJson>;
SVC_TYPE?: number;
SSVC_TYPE?: number;
}>()
@ -60,7 +61,7 @@ export const newInfo = createAction(
export const appendInfoList = createAction(
'[Messenger::Event] Append InfoList',
props<{
info: Info;
info: Info<EventJson>;
}>()
);
@ -134,7 +135,7 @@ export const read = createAction(
export const readSuccess = createAction(
'[Messenger::Event] read Success',
props<{
infoList: Info[];
infoList: Info<EventJson>[];
res: InfoResponse;
}>()
);

View File

@ -36,7 +36,8 @@ import {
EventType,
ReadNotification,
SSVC_TYPE_EVENT_SEND_RES,
SSVC_TYPE_EVENT_SEND_NOTI
SSVC_TYPE_EVENT_SEND_NOTI,
EventJson
} from '@ucap-webmessenger/protocol-event';
import * as ChatStore from '@app/store/messenger/chat';
@ -102,7 +103,7 @@ export class Effects {
info$ = createEffect(
() => {
let infoList: Info[];
let infoList: Info<EventJson>[];
return this.actions$.pipe(
ofType(info),
@ -170,7 +171,9 @@ export class Effects {
this.store.pipe(
select(
(state: any) =>
state.messenger.event.infoList.entities as Dictionary<Info>
state.messenger.event.infoList.entities as Dictionary<
Info<EventJson>
>
)
)
),
@ -179,7 +182,7 @@ export class Effects {
const delEventSeq: number[] = [];
// tslint:disable-next-line: forin
for (const key in eventList) {
const event: Info = eventList[key];
const event: Info<EventJson> = eventList[key];
if (
new Date().getTime() - new Date(event.sendDate).getTime() >=
roomInfo.timeRoomInterval * 1000
@ -276,19 +279,11 @@ export class Effects {
ofType(sendSuccess),
tap(action => {
const res = action.res;
const appendInfo: Info = {
seq: res.seq,
type: res.eventType,
senderSeq: action.senderSeq,
sendDate: res.sendDate,
sentMessage: res.message,
receiverCount: res.receiverCount
};
this.store.dispatch(
newInfo({
roomSeq: res.roomSeq,
info: appendInfo,
info: res.info,
SVC_TYPE: res.SVC_TYPE,
SSVC_TYPE: res.SSVC_TYPE
})
@ -305,19 +300,10 @@ export class Effects {
ofType(sendNotification),
map(action => action.noti),
tap(noti => {
const appendInfo: Info = {
seq: noti.seq,
type: noti.eventType,
senderSeq: noti.SENDER_SEQ,
sendDate: noti.sendDate,
sentMessage: noti.message,
receiverCount: noti.receiverCount
};
this.store.dispatch(
newInfo({
roomSeq: noti.roomSeq,
info: appendInfo,
info: noti.info,
SVC_TYPE: noti.SVC_TYPE,
SSVC_TYPE: noti.SSVC_TYPE
})

View File

@ -10,7 +10,7 @@ import {
infoMoreSuccess
} from './actions';
import * as AuthenticationStore from '@app/store/account/authentication';
import { Info, EventType } from '@ucap-webmessenger/protocol-event';
import { Info, EventType, EventJson } from '@ucap-webmessenger/protocol-event';
import { CONST } from '@ucap-webmessenger/core';
export const reducer = createReducer(
@ -63,7 +63,7 @@ export const reducer = createReducer(
on(appendInfoList, (state, action) => {
const eventinfo = action.info;
const statusEventInfo: Info = {
const statusEventInfo: Info<EventJson> = {
...state.infoList.entities[eventinfo.seq],
type: eventinfo.type,
senderSeq: eventinfo.senderSeq,
@ -81,7 +81,7 @@ export const reducer = createReducer(
on(recallInfoList, (state, action) => {
const eventSeq = action.eventSeq;
const statusEventInfo: Info = {
const statusEventInfo: Info<EventJson> = {
...state.infoList.entities[eventSeq],
type: EventType.RecalledMessage,
sentMessage: '회수된 메시지'

View File

@ -1,8 +1,12 @@
import { Selector, createSelector } from '@ngrx/store';
import { InfoResponse, Info } from '@ucap-webmessenger/protocol-event';
import {
InfoResponse,
Info,
EventJson
} from '@ucap-webmessenger/protocol-event';
import { EntityState, createEntityAdapter } from '@ngrx/entity';
export interface InfoListState extends EntityState<Info> {}
export interface InfoListState extends EntityState<Info<EventJson>> {}
export interface State {
infoListProcessing: boolean;
@ -11,7 +15,7 @@ export interface State {
remainInfo: boolean;
}
export const adapterInfoList = createEntityAdapter<Info>({
export const adapterInfoList = createEntityAdapter<Info<EventJson>>({
selectId: info => info.seq,
sortComparer: (a, b) => {
return a.seq - b.seq;

View File

@ -13,7 +13,7 @@ import {
UserInfo as RoomUserInfo,
InfoRequest
} from '@ucap-webmessenger/protocol-room';
import { Info } from '@ucap-webmessenger/protocol-event';
import { Info, EventJson } from '@ucap-webmessenger/protocol-event';
import {
AddResponse as GroupAddResponse,
UpdateRequest as GroupUpdateRequest,
@ -88,7 +88,7 @@ export const updateRoomForNewEventMessage = createAction(
'[Messenger::Sync] updateRoomForNewEventMessage',
props<{
roomSeq: string;
info: Info;
info: Info<EventJson>;
}>()
);

View File

@ -1,56 +1,63 @@
import { EventType } from '@ucap-webmessenger/protocol-event';
import {
EventType,
EventJson,
FileEventJson,
MassTextEventJson
} from '@ucap-webmessenger/protocol-event';
import { FileType } from '@ucap-webmessenger/protocol-file';
import { JsonObject } from 'type-fest';
import { JsonAnalization } from '@ucap-webmessenger/api';
export class StringUtil {
public static convertFinalEventMessage(
eventType: EventType,
finalEventMessage: string
finalEventMessage: EventJson
): string | null {
let eventMessage: string = null;
switch (eventType) {
case EventType.Join:
case EventType.Exit:
case EventType.RenameRoom:
case EventType.NotificationForTimerRoom:
case EventType.GuideForRoomTimerChanged: {
/**
* .
* @description Edit with ui-chat > messages.component.ts
*/
return null;
}
case EventType.GuideForRoomTimerChanged:
{
/**
* .
* @description Edit with ui-chat > messages.component.ts
*/
}
break;
case EventType.Sticker:
finalEventMessage = '스티커';
eventMessage = '스티커';
break;
case EventType.File:
{
const contentJson = JSON.parse(finalEventMessage);
if (contentJson.FileType === FileType.Image) {
finalEventMessage = '이미지';
const m = finalEventMessage as FileEventJson;
if (FileType.Image === m.fileType) {
eventMessage = '이미지';
} else {
finalEventMessage = '첨부파일';
eventMessage = '첨부파일';
}
}
break;
case EventType.VideoConference:
finalEventMessage = '화상회의';
eventMessage = '화상회의';
break;
case EventType.MassText:
{
try {
const json: JsonObject | Error = JsonAnalization.receiveAnalization(
finalEventMessage
);
finalEventMessage = json.Content.toString();
} catch (e) {
finalEventMessage = '대용량 텍스트';
}
const m = finalEventMessage as MassTextEventJson;
eventMessage = m.content;
}
break;
default:
return finalEventMessage;
{
const m = finalEventMessage as string;
eventMessage = m;
}
break;
}
return eventMessage;
}
}

View File

@ -1,6 +1,6 @@
import { EventType } from '../types/event.type';
export interface Info {
export interface Info<T = {}> {
// 이벤트SEQ
seq: number;
// 이벤트타입
@ -11,6 +11,8 @@ export interface Info {
sendDate: string;
// 발신내용
sentMessage: string;
// // 발신내용
sentMessageJson?: T;
// 수신자수
receiverCount: number;
}
@ -25,7 +27,7 @@ export function isRecalled(eventType: EventType): boolean {
return EventType.RecalledMessage === eventType;
}
export function isRecallable(event: Info, userSeq: number): boolean {
export function isRecallable(event: Info<any>, userSeq: number): boolean {
return (
event.senderSeq === userSeq && event.type !== EventType.RecalledMessage
);

View File

@ -0,0 +1,9 @@
import { EventJsonDecoder } from './event-json';
export type CharacterEventJson = string;
export const decodeCharacterEventJson: EventJsonDecoder<CharacterEventJson> = (
message: string
) => {
return message as CharacterEventJson;
};

View File

@ -0,0 +1,124 @@
import { EventType } from '../../types/event.type';
import { FileEventJson, decodeFileEventJson } from './file.event-json';
import {
MassTextEventJson,
decodeMassTextEventJson
} from './mass-text.event-json';
import { StickerEventJson, decodeStickerEventJson } from './sticker.event-json';
import { PlanEventJson, decodePlanEventJson } from './plan.event-json';
import {
VideoConferenceEventJson,
decodeVideoConferenceEventJson
} from './video-conference.event-json';
import {
RenameRoomEventJson,
decodeRenameRoomEventJson
} from './rename-room.event-json';
import {
TranslationEventJson,
decodeTranslationEventJson
} from './translation.event-json';
import {
MassTranslationEventJson,
decodeMassTranslationEventJson
} from './mass-translation.event-json';
import {
GuideForRoomTimerChangedEventJson,
decodeGuideForRoomTimerChangedEventJson
} from './guide-for-room-timer-changed.event-json';
import { JoinEventJson, decodeJoinEventJson } from './join.event-json';
import {
CharacterEventJson,
decodeCharacterEventJson
} from './character.event-json';
import { ExitEventJson, decodeExitEventJson } from './exit.event-json';
import { LinkEventJson, decodeLinkEventJson } from './link.event-json';
import {
RecalledMessageEventJson,
decodeRecalledMessageEventJson
} from './recalled-message.event-json';
import {
VideoStreammingEventJson,
decodeVideoStreammingEventJson
} from './video-streamming.event-json';
import {
NotificationForTimerRoomEventJson,
decodeNotificationForTimerRoomEventJson
} from './notification-for-timer-room.event-json';
export type EventJson =
| string
| string[]
| JoinEventJson
| CharacterEventJson
| ExitEventJson
| FileEventJson
| LinkEventJson
| MassTextEventJson
| RecalledMessageEventJson
| StickerEventJson
| PlanEventJson
| VideoConferenceEventJson
| RenameRoomEventJson
| NotificationForTimerRoomEventJson
| TranslationEventJson
| MassTranslationEventJson
| VideoStreammingEventJson
| GuideForRoomTimerChangedEventJson;
export const decodeEventJson = (
eventType: EventType,
message: string
): EventJson => {
switch (eventType) {
case EventType.Join:
return decodeJoinEventJson(message);
case EventType.Character:
return decodeCharacterEventJson(message);
case EventType.File:
return decodeFileEventJson(message);
case EventType.Sticker:
return decodeStickerEventJson(message);
case EventType.MassText:
return decodeMassTextEventJson(message);
case EventType.Exit:
return decodeExitEventJson(message);
case EventType.Plan:
return decodePlanEventJson(message);
case EventType.VideoConference:
return decodeVideoConferenceEventJson(message);
case EventType.Link:
return decodeLinkEventJson(message);
case EventType.RenameRoom:
return decodeRenameRoomEventJson(message);
case EventType.Translation:
return decodeTranslationEventJson(message);
case EventType.MassTranslation:
return decodeMassTranslationEventJson(message);
case EventType.RecalledMessage:
return decodeRecalledMessageEventJson(message);
case EventType.GuideForRoomTimerChanged:
return decodeGuideForRoomTimerChangedEventJson(message);
case EventType.NotificationForiOSCapture:
return message;
case EventType.NotificationForTimerRoom:
return decodeNotificationForTimerRoomEventJson(message);
case EventType.Before2MonthsAgo:
return message;
case EventType.ForcedExit:
return message;
case EventType.ChatbotStart:
return message;
case EventType.ChatbotEnd:
return message;
case EventType.ChatbotSend:
return message;
case EventType.ChatbotSendMass:
return message;
case EventType.VideoStreamming:
return decodeVideoStreammingEventJson(message);
default:
return message;
}
};

View File

@ -0,0 +1 @@
export type EventJsonDecoder<T> = (message: string) => T;

View File

@ -0,0 +1,9 @@
import { EventJsonDecoder } from './event-json';
export type ExitEventJson = string;
export const decodeExitEventJson: EventJsonDecoder<ExitEventJson> = (
message: string
) => {
return message;
};

View File

@ -0,0 +1,52 @@
import { StatusCode, JsonAnalization } from '@ucap-webmessenger/api';
import { FileType } from '@ucap-webmessenger/protocol-file';
import { EventJsonDecoder } from './event-json';
export interface FileEventJson {
statusCode?: StatusCode;
errorMessage?: string;
roomSeq?: number;
fileName?: string;
fileExt?: string;
fileType?: FileType;
thumbUrl?: string;
attachmentSeq?: number;
attachmentSize?: number;
attachmentRegDate?: string;
imageWidth?: number;
imageHeight?: number;
companyCode?: string;
voiceTime?: string;
synappKey?: string;
}
export const decodeFileEventJson: EventJsonDecoder<FileEventJson> = (
message: string
) => {
try {
const json = JsonAnalization.receiveAnalization(message);
return {
statusCode: json.StatusCode,
errorMessage: json.ErrorMessage,
roomSeq: json.RoomID,
fileName: json.FileName,
fileExt: json.FileExt,
fileType: json.FileType,
thumbUrl: json.ThumbURL,
attachmentSeq: json.AttSEQ,
attachmentSize: json.AttSize,
attachmentRegDate: json.AttRegDate,
imageWidth: json.ImageWidth,
imageHeight: json.ImageHeight,
companyCode: json.CompanyCode,
voiceTime: json.VoiceTime,
synappKey: json.SynappKey
} as FileEventJson;
} catch (e) {
return {
statusCode: StatusCode.Fail,
errorMessage: e.toString()
} as FileEventJson;
}
};

View File

@ -0,0 +1,17 @@
import { EventJsonDecoder } from './event-json';
export interface GuideForRoomTimerChangedEventJson {
senderSeq?: number;
time?: number;
}
export const decodeGuideForRoomTimerChangedEventJson: EventJsonDecoder<
GuideForRoomTimerChangedEventJson
> = (message: string) => {
const v = message.split(',');
return {
senderSeq: Number(v[0]),
time: Number(v[1])
} as GuideForRoomTimerChangedEventJson;
};

View File

@ -0,0 +1,17 @@
import { EventJsonDecoder } from './event-json';
export interface JoinEventJson {
owner?: string;
inviter?: string[];
}
export const decodeJoinEventJson: EventJsonDecoder<JoinEventJson> = (
message: string
) => {
const v = message.split(',');
return {
owner: v[0],
inviter: v.slice(1)
} as JoinEventJson;
};

View File

@ -0,0 +1,9 @@
import { EventJsonDecoder } from './event-json';
export type LinkEventJson = string;
export const decodeLinkEventJson: EventJsonDecoder<LinkEventJson> = (
message: string
) => {
return message as LinkEventJson;
};

View File

@ -0,0 +1,33 @@
import { StatusCode, JsonAnalization } from '@ucap-webmessenger/api';
import { EventJsonDecoder } from './event-json';
export interface MassTextEventJson {
statusCode?: StatusCode;
errorMessage?: string;
roomSeq?: number;
massSeq?: number;
regDate?: string;
content?: string;
}
export const decodeMassTextEventJson: EventJsonDecoder<MassTextEventJson> = (
message: string
) => {
try {
const json = JsonAnalization.receiveAnalization(message);
return {
statusCode: json.StatusCode,
errorMessage: json.ErrorMessage,
roomSeq: json.RoomID,
massSeq: json.EventMassSeq,
regDate: json.RegDate,
content: json.Content
} as MassTextEventJson;
} catch (e) {
return {
statusCode: StatusCode.Fail,
errorMessage: e.toString()
} as MassTextEventJson;
}
};

View File

@ -0,0 +1,37 @@
import { StatusCode, JsonAnalization } from '@ucap-webmessenger/api';
import { EventJsonDecoder } from './event-json';
export interface MassTranslationEventJson {
statusCode?: StatusCode;
errorMessage?: string;
translationSeq?: number;
destLocale?: string;
roomSeq?: number;
regDate?: string;
original?: string;
translation?: string;
}
export const decodeMassTranslationEventJson: EventJsonDecoder<
MassTranslationEventJson
> = (message: string) => {
try {
const json = JsonAnalization.receiveAnalization(message);
return {
statusCode: json.StatusCode,
errorMessage: json.ErrorMessage,
translationSeq: json.EventTransSeq,
destLocale: json.DestLocale,
roomSeq: json.RoomID,
regDate: json.RegDate,
original: json.Original,
translation: json.Translation
} as MassTranslationEventJson;
} catch (e) {
return {
statusCode: StatusCode.Fail,
errorMessage: e.toString()
} as MassTranslationEventJson;
}
};

View File

@ -0,0 +1,9 @@
import { EventJsonDecoder } from './event-json';
export type NotificationForTimerRoomEventJson = string;
export const decodeNotificationForTimerRoomEventJson: EventJsonDecoder<
NotificationForTimerRoomEventJson
> = (message: string) => {
return message as NotificationForTimerRoomEventJson;
};

View File

@ -0,0 +1,30 @@
import { EventJsonDecoder } from './event-json';
import { JsonAnalization } from '@ucap-webmessenger/api';
export interface PlanEventJson {
planSeq?: number;
title?: string;
contents?: string;
date?: string;
endDate?: string;
active?: boolean;
}
export const decodePlanEventJson: EventJsonDecoder<PlanEventJson> = (
message: string
) => {
try {
const json = JsonAnalization.receiveAnalization(message);
return {
planSeq: json.planSeq,
title: json.title,
contents: json.contents,
date: json.date,
endDate: json.endDate,
chat: json.chat,
active: !!json.activeYn && 'Y' === json.activeYn ? true : false
} as PlanEventJson;
} catch (e) {
return {} as PlanEventJson;
}
};

View File

@ -0,0 +1,9 @@
import { EventJsonDecoder } from './event-json';
export type RecalledMessageEventJson = string;
export const decodeRecalledMessageEventJson: EventJsonDecoder<
RecalledMessageEventJson
> = (message: string) => {
return message as RecalledMessageEventJson;
};

View File

@ -0,0 +1,15 @@
import { EventJsonDecoder } from './event-json';
export interface RenameRoomEventJson {
requester?: string;
roomName?: string;
}
export const decodeRenameRoomEventJson: EventJsonDecoder<
RenameRoomEventJson
> = (message: string) => {
return {
requester: message.substring(0, message.indexOf(',')),
roomName: message.substring(message.indexOf(',') + 1)
} as RenameRoomEventJson;
};

View File

@ -0,0 +1,19 @@
import { EventJsonDecoder } from './event-json';
export interface StickerEventJson {
name?: string;
file?: string;
chat?: string;
}
export const decodeStickerEventJson: EventJsonDecoder<StickerEventJson> = (
message: string
) => {
const json = JSON.parse(message);
return {
name: json.name,
file: json.file,
chat: json.chat
} as StickerEventJson;
};

View File

@ -0,0 +1,27 @@
import { EventJsonDecoder } from './event-json';
import { JsonAnalization } from '@ucap-webmessenger/api';
export interface TranslationEventJson {
locale?: string;
original?: string;
translation?: string;
stickerName?: string;
stickerFile?: string;
}
export const decodeTranslationEventJson: EventJsonDecoder<
TranslationEventJson
> = (message: string) => {
try {
const json = JsonAnalization.receiveAnalization(message);
return {
locale: json.locale,
original: json.original,
translation: json.translation,
stickerName: json.stickername,
stickerFile: json.stickerfile
} as TranslationEventJson;
} catch (e) {
return {} as TranslationEventJson;
}
};

View File

@ -0,0 +1,32 @@
import { EventJsonDecoder } from './event-json';
import { JsonAnalization } from '@ucap-webmessenger/api';
export interface VideoConferenceEventJson {
conferenceSeq?: number;
title?: string;
contents?: string;
startDate?: string;
endDate?: string;
register?: string;
attendee?: string;
}
export const decodeVideoConferenceEventJson: EventJsonDecoder<
VideoConferenceEventJson
> = (message: string) => {
try {
const json = JsonAnalization.receiveAnalization(message);
return {
conferenceSeq: json.confSeq,
title: json.title,
contents: json.contents,
startDate: json.startDate,
endDate: json.endDate,
register: json.register,
attendee: json.attendee
} as VideoConferenceEventJson;
} catch (e) {
return {} as VideoConferenceEventJson;
}
};

View File

@ -0,0 +1,9 @@
import { EventJsonDecoder } from './event-json';
export type VideoStreammingEventJson = string;
export const decodeVideoStreammingEventJson: EventJsonDecoder<
VideoStreammingEventJson
> = (message: string) => {
return message as VideoStreammingEventJson;
};

View File

@ -12,6 +12,7 @@ import {
} from '@ucap-webmessenger/protocol';
import { EventType } from '../types/event.type';
import { Info } from '../models/info';
import { decodeEventJson, EventJson } from './event-json/codec';
export interface InfoRequest extends ProtocolRequest {
// 대화방SEQ(s)
@ -25,7 +26,7 @@ export interface InfoRequest extends ProtocolRequest {
export interface InfoData extends ProtocolStream {
// 대화방SEQ(s)
roomSeq: string;
infoList: Info[];
infoList: Info<EventJson>[];
}
export interface InfoResponse extends ProtocolResponse {
@ -52,17 +53,20 @@ export const encodeInfo: ProtocolEncoder<InfoRequest> = (req: InfoRequest) => {
export const decodeInfoData: ProtocolDecoder<InfoData> = (
message: ProtocolMessage
) => {
const infoList: Info[] = [];
const infoList: Info<EventJson>[] = [];
for (const body of message.bodyList) {
const info = body.split(BodyStringDivider);
if (info.length > 5) {
const eventType = info[1] as EventType;
infoList.push({
seq: Number(info[0]),
type: info[1] as EventType,
type: eventType,
senderSeq: Number(info[2]),
sendDate: info[3],
sentMessage: info[4],
sentMessageJson: decodeEventJson(eventType, info[4]),
receiverCount: Number(info[5])
});
}

View File

@ -12,6 +12,8 @@ import {
} from '@ucap-webmessenger/protocol';
import { EventType } from '../types/event.type';
import { PushStatus } from '../types/push-status.type';
import { EventJson, decodeEventJson } from './event-json/codec';
import { Info } from '../models/info';
export interface SendRequest extends ProtocolRequest {
// 0. 대화방SEQ(s)
@ -41,6 +43,8 @@ export interface SendResponse extends ProtocolResponse {
ForcedExitType: string;
// 요청자 이름(s)
senderName: string;
/** Decoded Info */
info?: Info<EventJson>;
}
export interface SendNotification extends ProtocolNotification {
@ -66,6 +70,8 @@ export interface SendNotification extends ProtocolNotification {
id?: string;
/** 회사코드(s) */
companyCode?: string;
/** Decoded Info */
info?: Info<EventJson>;
}
export const encodeSend: ProtocolEncoder<SendRequest> = (req: SendRequest) => {
@ -83,33 +89,63 @@ export const encodeSend: ProtocolEncoder<SendRequest> = (req: SendRequest) => {
export const decodeSend: ProtocolDecoder<SendResponse> = (
message: ProtocolMessage
) => {
const seq = message.bodyList[1];
const eventType = message.bodyList[2] as EventType;
const sendDate = message.bodyList[3];
const sentMessage = message.bodyList[4];
const receiverCount = message.bodyList[5] || 0;
return decodeProtocolMessage(message, {
roomSeq: message.bodyList[0],
seq: message.bodyList[1],
eventType: message.bodyList[2] as EventType,
sendDate: message.bodyList[3],
message: message.bodyList[4],
receiverCount: message.bodyList[5] || 0,
eventType,
sendDate,
message: sentMessage,
receiverCount,
pushStatus: message.bodyList[6] as PushStatus,
ForcedExitType: message.bodyList[7],
senderName: message.bodyList[8]
senderName: message.bodyList[8],
info: {
seq,
type: eventType,
senderSeq: message.senderSeq,
sendDate,
sentMessage,
sentMessageJson: decodeEventJson(eventType, sentMessage),
receiverCount
}
} as SendResponse);
};
export const decodeSendNotification: ProtocolDecoder<SendNotification> = (
message: ProtocolMessage
) => {
const seq = message.bodyList[1];
const eventType = message.bodyList[2] as EventType;
const sendDate = message.bodyList[3];
const sentMessage = message.bodyList[4];
const receiverCount = message.bodyList[5] || 0;
return decodeProtocolMessage(message, {
roomSeq: message.bodyList[0],
seq: message.bodyList[1],
eventType: message.bodyList[2] as EventType,
sendDate: message.bodyList[3],
message: message.bodyList[4],
receiverCount: message.bodyList[5] || 0,
seq,
eventType,
sendDate,
message: sentMessage,
receiverCount,
pushStatus: message.bodyList[6] as PushStatus,
ForcedExitType: message.bodyList[7],
senderName: message.bodyList[8],
id: message.bodyList[9],
companyCode: message.bodyList[10]
companyCode: message.bodyList[10],
info: {
seq,
type: eventType,
senderSeq: message.senderSeq,
sendDate,
sentMessage,
sentMessageJson: decodeEventJson(eventType, sentMessage),
receiverCount
}
} as SendNotification);
};

View File

@ -11,6 +11,27 @@ export * from './lib/protocols/push';
export * from './lib/protocols/read';
export * from './lib/protocols/send';
export * from './lib/protocols/event-json/event-json';
export * from './lib/protocols/event-json/character.event-json';
export * from './lib/protocols/event-json/exit.event-json';
export * from './lib/protocols/event-json/file.event-json';
export * from './lib/protocols/event-json/guide-for-room-timer-changed.event-json';
export * from './lib/protocols/event-json/join.event-json';
export * from './lib/protocols/event-json/link.event-json';
export * from './lib/protocols/event-json/mass-text.event-json';
export * from './lib/protocols/event-json/mass-translation.event-json';
export * from './lib/protocols/event-json/notification-for-timer-room.event-json';
export * from './lib/protocols/event-json/plan.event-json';
export * from './lib/protocols/event-json/recalled-message.event-json';
export * from './lib/protocols/event-json/rename-room.event-json';
export * from './lib/protocols/event-json/sticker.event-json';
export * from './lib/protocols/event-json/translation.event-json';
export * from './lib/protocols/event-json/video-conference.event-json';
export * from './lib/protocols/event-json/video-streamming.event-json';
export * from './lib/protocols/event-json/codec';
export * from './lib/services/event-protocol.service';
export * from './lib/types/event.type';

View File

@ -1,18 +1,18 @@
<div class="bubble-main">
<!--파일명에 따라 doc exe hwp ppt xls zip 으로 추가되고 나머지 파일 명은 file로 기간이 만료된 파일은 그뒤에 disable도 추가-->
<!-- <div class="file-img" [ngClass]="fileInfo.FileExt"></div> -->
<div [ngClass]="['mime-icon', 'light', 'ico-' + fileInfo.FileExt]">
<div [ngClass]="['mime-icon', 'light', 'ico-' + fileInfo.fileExt]">
<div class="ico"></div>
</div>
<ul class="file-info">
<li class="file-name">
{{ fileInfo.FileName }}
{{ fileInfo.fileName }}
</li>
<li class="file-size">
{{ fileInfo.AttSize | ucapBytes }}
{{ fileInfo.attachmentSize | ucapBytes }}
</li>
<li class="file-ext">
{{ fileInfo.FileExt }}
{{ fileInfo.fileExt }}
</li>
</ul>
</div>
@ -20,7 +20,7 @@
<ul *ngIf="expired" class="expired">
<li>기간이 만료된 파일입니다.</li>
</ul>
<ul *ngIf="!expired && fileInfo && fileInfo.AttSEQ">
<ul *ngIf="!expired && fileInfo && fileInfo.attachmentSeq">
<li>
<button mat-button (click)="onClickSave()">Save</button>
</li>

View File

@ -1,6 +1,6 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FileInfo } from '../../models/file-info.json';
import { NGXLogger } from 'ngx-logger';
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
@Component({
selector: 'ucap-chat-message-box-attach-file',
@ -9,7 +9,7 @@ import { NGXLogger } from 'ngx-logger';
})
export class AttachFileComponent implements OnInit {
@Input()
fileInfo: FileInfo;
fileInfo: FileEventJson;
@Input()
expired = false;

View File

@ -1,5 +1,5 @@
import { Component, OnInit, Input } from '@angular/core';
import { Info } from '@ucap-webmessenger/protocol-event';
import { Info, EventJson } from '@ucap-webmessenger/protocol-event';
import { DatePipe } from '@angular/common';
@Component({
@ -9,7 +9,7 @@ import { DatePipe } from '@angular/common';
})
export class DateSplitterComponent implements OnInit {
@Input()
message: Info;
message: Info<EventJson>;
dateInfo: string;

View File

@ -1,6 +1,6 @@
<ng-container
*ngIf="fileInfo && fileInfo.FileType"
[ngSwitch]="fileInfo.FileType"
*ngIf="fileInfo && fileInfo.fileType"
[ngSwitch]="fileInfo.fileType"
>
<ucap-chat-message-box-attach-file
*ngSwitchCase="FileType.File"

View File

@ -1,9 +1,12 @@
import { Component, OnInit, Output, Input, EventEmitter } from '@angular/core';
import { Info, InfoResponse } from '@ucap-webmessenger/protocol-event';
import {
Info,
InfoResponse,
FileEventJson
} from '@ucap-webmessenger/protocol-event';
import { StatusCode } from '@ucap-webmessenger/api';
import { FileType } from '@ucap-webmessenger/protocol-file';
import { NGXLogger } from 'ngx-logger';
import { FileInfo } from '../../models/file-info.json';
@Component({
selector: 'ucap-chat-message-box-file',
@ -12,27 +15,27 @@ import { FileInfo } from '../../models/file-info.json';
})
export class FileComponent implements OnInit {
@Input()
message: Info;
message: Info<FileEventJson>;
@Input()
eventInfoStatus: InfoResponse;
@Output()
save = new EventEmitter<{ fileInfo: FileInfo; type: string }>();
save = new EventEmitter<{ fileInfo: FileEventJson; type: string }>();
@Output()
imageViewer = new EventEmitter<FileInfo>();
imageViewer = new EventEmitter<FileEventJson>();
fileInfo?: FileInfo;
fileInfo?: FileEventJson;
errorMessage?: string;
FileType = FileType;
constructor(private logger: NGXLogger) {}
ngOnInit() {
const contentJson: FileInfo = JSON.parse(this.message.sentMessage);
if (contentJson.StatusCode === StatusCode.Success) {
this.fileInfo = contentJson;
if (StatusCode.Success === this.message.sentMessageJson.statusCode) {
this.fileInfo = this.message.sentMessageJson;
} else {
this.errorMessage = contentJson.ErrorMessage || '[Error] System Error!!';
this.errorMessage =
this.message.sentMessageJson.errorMessage || '[Error] System Error!!';
}
}
@ -47,7 +50,7 @@ export class FileComponent implements OnInit {
}
}
onClickImageViewer(fileInfo: FileInfo) {
onClickImageViewer(fileInfo: FileEventJson) {
this.imageViewer.emit(this.fileInfo);
}

View File

@ -1,3 +1,3 @@
<div class="bubble-main">
<img [src]="fileInfo.ThumbURL">
<div class="bubble-main">
<img [src]="fileInfo.thumbUrl" />
</div>

View File

@ -1,6 +1,6 @@
import { Component, OnInit, Input } from '@angular/core';
import { NGXLogger } from 'ngx-logger';
import { FileInfo } from '../../models/file-info.json';
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
@Component({
selector: 'ucap-chat-message-box-image',
@ -9,7 +9,7 @@ import { FileInfo } from '../../models/file-info.json';
})
export class ImageComponent implements OnInit {
@Input()
fileInfo: FileInfo;
fileInfo: FileEventJson;
@Input()
expired = false;

View File

@ -1,6 +1,14 @@
import { Component, OnInit, Input } from '@angular/core';
import { NGXLogger } from 'ngx-logger';
import { Info, EventType } from '@ucap-webmessenger/protocol-event';
import {
Info,
EventType,
EventJson,
JoinEventJson,
RenameRoomEventJson,
NotificationForTimerRoomEventJson,
GuideForRoomTimerChangedEventJson
} from '@ucap-webmessenger/protocol-event';
@Component({
selector: 'ucap-chat-message-box-information',
@ -9,7 +17,7 @@ import { Info, EventType } from '@ucap-webmessenger/protocol-event';
})
export class InformationComponent implements OnInit {
@Input()
message: Info;
message: Info<EventJson>;
@Input()
senderName?: string;
@ -20,41 +28,47 @@ export class InformationComponent implements OnInit {
ngOnInit() {
switch (this.message.type) {
case EventType.Join:
let owner: string;
const inviter: string[] = [];
this.message.sentMessage.split(',').forEach((userName, idx) => {
if (idx === 0) {
owner = userName + '님';
} else {
{
const m = this.message as Info<JoinEventJson>;
const owner = m.sentMessageJson.owner + '님';
const inviter: string[] = [];
m.sentMessageJson.inviter.forEach((userName, idx) => {
inviter.push(userName + '님');
}
});
this.contents = `${owner}${inviter.join(',')}을 초대했습니다.`;
});
this.contents = `${owner}${inviter.join(',')}을 초대했습니다.`;
}
break;
case EventType.Exit:
this.contents = `${this.message.sentMessage}님이 퇴장하셨습니다.`;
{
const m = this.message as Info<JoinEventJson>;
this.contents = `${m.sentMessage}님이 퇴장하셨습니다.`;
}
break;
case EventType.RenameRoom:
this.contents = `${this.message.sentMessage.substring(
0,
this.message.sentMessage.indexOf(',')
)} '${this.message.sentMessage.substring(
this.message.sentMessage.indexOf(',') + 1
)}' .`;
{
const m = this.message as Info<RenameRoomEventJson>;
this.contents = `${m.sentMessageJson.requester}님이 대화방명을 '${m.sentMessageJson.roomName}'으로 변경하셨습니다.`;
}
break;
case EventType.NotificationForTimerRoom:
/**
* , .
*/
this.contents = this.message.sentMessage;
{
const m = this.message as Info<NotificationForTimerRoomEventJson>;
/**
* , .
*/
this.contents = m.sentMessage;
}
break;
case EventType.GuideForRoomTimerChanged:
const values = this.message.sentMessage.split(',');
if (values && values.length === 2) {
{
const m = this.message as Info<GuideForRoomTimerChangedEventJson>;
this.contents = `${
this.senderName
} .(${this.getCalcTimer(
Number(values[1]) * 1000
m.sentMessageJson.time * 1000
)})`;
}
break;

View File

@ -1,9 +1,7 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Info } from '@ucap-webmessenger/protocol-event';
import { Info, MassTextEventJson } from '@ucap-webmessenger/protocol-event';
import { NGXLogger } from 'ngx-logger';
import { StatusCode } from '@ucap-webmessenger/api';
import { MassTextInfo } from '../../models/mass-talk-info.json';
import { StringUtil } from '@ucap-webmessenger/ui';
@Component({
selector: 'ucap-chat-message-box-mass',
@ -12,7 +10,7 @@ import { StringUtil } from '@ucap-webmessenger/ui';
})
export class MassComponent implements OnInit {
@Input()
message: Info;
message: Info<MassTextEventJson>;
@Output()
massDetail = new EventEmitter<number>();
@ -25,18 +23,16 @@ export class MassComponent implements OnInit {
ngOnInit() {
try {
const contentJson: MassTextInfo = StringUtil.receiveAnalization(
this.message.sentMessage
);
if (contentJson.StatusCode === StatusCode.Success) {
this.content = contentJson.Content;
if (StatusCode.Success === this.message.sentMessageJson.statusCode) {
this.content = this.message.sentMessageJson.content;
} else {
this.content = contentJson.ErrorMessage || '[Error] System Error!!';
this.content =
this.message.sentMessageJson.errorMessage || '[Error] System Error!!';
this.detailButteonShow = false;
}
if (!!contentJson.EventMassSeq) {
this.eventMassSeq = contentJson.EventMassSeq;
if (!!this.message.sentMessageJson.massSeq) {
this.eventMassSeq = this.message.sentMessageJson.massSeq;
} else {
this.detailButteonShow = false;
}

View File

@ -2,14 +2,12 @@
<div class="event-header">이벤트제목</div>
<ul class="event-info">
<li class="event-title">
이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀
</li>
<li class="event-date">
<span>날짜</span> 2019.09.30
</li>
<li class="event-time">
<span>시간</span>오후 10시
이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트
타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트 타일틀이벤트
타일틀이벤트 타일틀
</li>
<li class="event-date"><span>날짜</span> 2019.09.30</li>
<li class="event-time"><span>시간</span>오후 10시</li>
</ul>
<div class="btn-box">

View File

@ -9,4 +9,6 @@ export class ScheduleComponent implements OnInit {
constructor() {}
ngOnInit() {}
onClickSave(): void {}
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit, Input } from '@angular/core';
import { Info } from '@ucap-webmessenger/protocol-event';
import { Info, StickerEventJson } from '@ucap-webmessenger/protocol-event';
import { NGXLogger } from 'ngx-logger';
import { StickerInfo } from '../../models/sticker-info.json';
@ -10,7 +10,7 @@ import { StickerInfo } from '../../models/sticker-info.json';
})
export class StickerComponent implements OnInit {
@Input()
message: Info;
message: Info<StickerEventJson>;
contentJson?: StickerInfo;
stickerUrl?: string;
@ -18,9 +18,8 @@ export class StickerComponent implements OnInit {
ngOnInit() {
try {
this.contentJson = JSON.parse(this.message.sentMessage);
if (!!this.contentJson.file) {
this.stickerUrl = `assets/sticker/sticker_s_${this.contentJson.file}.png`;
if (!!this.message.sentMessageJson.file) {
this.stickerUrl = `assets/sticker/sticker_s_${this.message.sentMessageJson.file}.png`;
}
} catch (e) {
this.logger.error(e);

View File

@ -1,6 +1,5 @@
import { Component, OnInit, Input } from '@angular/core';
import { Info } from '@ucap-webmessenger/protocol-event';
import { StringUtil } from '@ucap-webmessenger/ui';
import { Info, EventJson } from '@ucap-webmessenger/protocol-event';
@Component({
selector: 'ucap-chat-message-box-text',
@ -9,7 +8,7 @@ import { StringUtil } from '@ucap-webmessenger/ui';
})
export class TextComponent implements OnInit {
@Input()
message: Info;
message: Info<EventJson>;
test = `가<br>나<br >다<br/>라<br />마<br class=""/>바사`;
constructor() {}

View File

@ -1,11 +1,15 @@
<div class="translation-main">
<div class="original">
{{ message.sentMessage }}
{{ message.sentMessageJson.translation }}
</div>
<div class="translation">
<span class="language">Kor</span>
녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문
롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트
녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문
롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요
장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문
롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요
장문장문 롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문
롱텍스트안녕하세요 장문장문 롱텍스트안녕하세요 장문장문 롱텍스트
</div>
<div class="btn-box">
<ul>

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
import { Info, TranslationEventJson } from '@ucap-webmessenger/protocol-event';
@Component({
selector: 'ucap-chat-message-box-translation',
@ -6,6 +7,9 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./translation.component.scss']
})
export class TranslationComponent implements OnInit {
@Input()
message: Info<TranslationEventJson>;
constructor() {}
ngOnInit() {}

View File

@ -11,7 +11,8 @@ import {
import {
Info,
EventType,
InfoResponse
InfoResponse,
EventJson
} from '@ucap-webmessenger/protocol-event';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { UserInfo } from '@ucap-webmessenger/protocol-room';
@ -29,7 +30,7 @@ export class MessagesComponent implements OnInit {
@Input()
loginRes: LoginResponse;
@Input()
messages: Info[];
messages: Info<EventJson>[];
@Input()
eventInfoStatus?: InfoResponse;
@Input()
@ -50,7 +51,7 @@ export class MessagesComponent implements OnInit {
@Output()
contextMenu = new EventEmitter<{
event: MouseEvent;
message: Info;
message: Info<EventJson>;
}>();
EventType = EventType;
@ -94,7 +95,7 @@ export class MessagesComponent implements OnInit {
return '';
}
getUnreadCount(message: Info): string | number {
getUnreadCount(message: Info<EventJson>): string | number {
const unreadCnt = this.userInfos.filter(user => {
if (message.senderSeq === user.seq) {
// 본인 글은 unreadCount 에 포함하지 않는다.
@ -110,7 +111,7 @@ export class MessagesComponent implements OnInit {
* @description event , .
* Edit with reducers.ts / sync / updateRoomForNewEventMessage
*/
getIsInformation(info: Info) {
getIsInformation(info: Info<EventJson>) {
if (
info.type === EventType.Join ||
info.type === EventType.Exit ||
@ -166,7 +167,7 @@ export class MessagesComponent implements OnInit {
}
/** [Event] Context Menu */
onContextMenuMessage(event: MouseEvent, message: Info) {
onContextMenuMessage(event: MouseEvent, message: Info<EventJson>) {
this.contextMenu.emit({ event, message });
}
}

View File

@ -0,0 +1,18 @@
<div class="ucap-image-viewer-container">
<div class="ucap-image-viewer-header">
<span>Third Line</span>
<span class="ucap-image-viewer-spacer"></span>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example heart icon"
>favorite</mat-icon
>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example delete icon"
>delete</mat-icon
>
</div>
</div>

View File

@ -0,0 +1,13 @@
.ucap-image-viewer-container {
width: 100%;
height: 100%;
.ucap-image-viewer-header {
width: 100%;
height: 50px;
.ucap-image-viewer-spacer {
flex: 1 1 auto;
}
}
}

View File

@ -0,0 +1,27 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { FileViewerComponent } from './file-viewer.component';
describe('FileViewerComponent', () => {
let component: FileViewerComponent;
let fixture: ComponentFixture<FileViewerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FileViewerComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FileViewerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,16 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ucapAnimations } from '../animations';
@Component({
selector: 'ucap-file-viewer',
templateUrl: './file-viewer.component.html',
styleUrls: ['./file-viewer.component.scss'],
animations: ucapAnimations
})
export class FileViewerComponent implements OnInit {
@Output()
closed = new EventEmitter<void>();
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,18 @@
<div class="ucap-image-viewer-container">
<mat-toolbar color="primary">
<span>Third Line</span>
<span class="ucap-image-viewer-spacer"></span>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example heart icon"
>favorite</mat-icon
>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example delete icon"
>delete</mat-icon
>
</mat-toolbar>
</div>

View File

@ -0,0 +1,4 @@
.ucap-image-viewer-container {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,27 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { DocumentViewerComponent } from './document-viewer.component';
describe('DocumentViewerComponent', () => {
let component: DocumentViewerComponent;
let fixture: ComponentFixture<DocumentViewerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DocumentViewerComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DocumentViewerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,16 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ucapAnimations } from '../../animations';
@Component({
selector: 'ucap-document-viewer',
templateUrl: './document-viewer.component.html',
styleUrls: ['./document-viewer.component.scss'],
animations: ucapAnimations
})
export class DocumentViewerComponent implements OnInit {
@Output()
closed = new EventEmitter<void>();
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,18 @@
<div class="ucap-image-viewer-container">
<mat-toolbar color="primary">
<span>Third Line</span>
<span class="ucap-image-viewer-spacer"></span>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example heart icon"
>favorite</mat-icon
>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example delete icon"
>delete</mat-icon
>
</mat-toolbar>
</div>

View File

@ -0,0 +1,4 @@
.ucap-image-viewer-container {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,27 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ImageViewerComponent } from './image-viewer.component';
describe('ImageViewerComponent', () => {
let component: ImageViewerComponent;
let fixture: ComponentFixture<ImageViewerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ImageViewerComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ImageViewerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,16 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ucapAnimations } from '../../animations';
@Component({
selector: 'ucap-image-viewer',
templateUrl: './image-viewer.component.html',
styleUrls: ['./image-viewer.component.scss'],
animations: ucapAnimations
})
export class ImageViewerComponent implements OnInit {
@Output()
closed = new EventEmitter<void>();
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,18 @@
<div class="ucap-image-viewer-container">
<mat-toolbar color="primary">
<span>Third Line</span>
<span class="ucap-image-viewer-spacer"></span>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example heart icon"
>favorite</mat-icon
>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example delete icon"
>delete</mat-icon
>
</mat-toolbar>
</div>

View File

@ -0,0 +1,4 @@
.ucap-image-viewer-container {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,27 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { SoundViewerComponent } from './sound-viewer.component';
describe('SoundViewerComponent', () => {
let component: SoundViewerComponent;
let fixture: ComponentFixture<SoundViewerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SoundViewerComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SoundViewerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,16 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ucapAnimations } from '../../animations';
@Component({
selector: 'ucap-sound-viewer',
templateUrl: './sound-viewer.component.html',
styleUrls: ['./sound-viewer.component.scss'],
animations: ucapAnimations
})
export class SoundViewerComponent implements OnInit {
@Output()
closed = new EventEmitter<void>();
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,18 @@
<div class="ucap-image-viewer-container">
<mat-toolbar color="primary">
<span>Third Line</span>
<span class="ucap-image-viewer-spacer"></span>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example heart icon"
>favorite</mat-icon
>
<mat-icon
class="example-icon"
aria-hidden="false"
aria-label="Example delete icon"
>delete</mat-icon
>
</mat-toolbar>
</div>

View File

@ -0,0 +1,4 @@
.ucap-image-viewer-container {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,27 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ImageViewerComponent } from './image-viewer.component';
describe('ImageViewerComponent', () => {
let component: ImageViewerComponent;
let fixture: ComponentFixture<ImageViewerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ImageViewerComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ImageViewerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,16 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ucapAnimations } from '../../animations';
@Component({
selector: 'ucap-video-viewer',
templateUrl: './video-viewer.component.html',
styleUrls: ['./video-viewer.component.scss'],
animations: ucapAnimations
})
export class VideoViewerComponent implements OnInit {
@Output()
closed = new EventEmitter<void>();
constructor() {}
ngOnInit() {}
}

View File

@ -1,7 +1,19 @@
import { FileUploadQueueComponent } from './file-upload-queue.component';
import { FloatActionButtonComponent } from './float-action-button.component';
import { FileViewerComponent } from './file-viewer.component';
import { DocumentViewerComponent } from './file-viewer/document-viewer.component';
import { ImageViewerComponent } from './file-viewer/image-viewer.component';
import { SoundViewerComponent } from './file-viewer/sound-viewer.component';
import { VideoViewerComponent } from './file-viewer/video-viewer.component';
export const UI_COMMON_COMPONENTS = [
FileUploadQueueComponent,
FloatActionButtonComponent
FloatActionButtonComponent,
FileViewerComponent,
DocumentViewerComponent,
ImageViewerComponent,
SoundViewerComponent,
VideoViewerComponent
];

View File

@ -10,6 +10,7 @@ import { MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatToolbarModule } from '@angular/material/toolbar';
import { DragDropModule } from '@angular/cdk/drag-drop';
@ -61,6 +62,7 @@ const SERVICES = [
MatIconModule,
MatProgressBarModule,
MatSnackBarModule,
MatToolbarModule,
MatTooltipModule,
DragDropModule
],

View File

@ -1,5 +1,3 @@
import { JsonObject } from 'type-fest';
export class StringUtil {
/**
* linefeed > <br>
@ -39,7 +37,7 @@ export class StringUtil {
* Json String Analization.
* @description Editing with json.util.ts
*/
public static receiveAnalization(jsonStr: string): JsonObject {
public static receiveAnalization(jsonStr: string): any {
const startJson = jsonStr.indexOf('{');
const endJson = jsonStr.lastIndexOf('}');