message is added
This commit is contained in:
parent
05a52dd1d5
commit
ccf7ea0092
34
angular.json
34
angular.json
|
@ -729,6 +729,40 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ucap-webmessenger-ui-message": {
|
||||
"projectType": "library",
|
||||
"root": "projects/ucap-webmessenger-ui-message",
|
||||
"sourceRoot": "projects/ucap-webmessenger-ui-message/src",
|
||||
"prefix": "ucap-message",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/ucap-webmessenger-ui-message/tsconfig.lib.json",
|
||||
"project": "projects/ucap-webmessenger-ui-message/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/ucap-webmessenger-ui-message/src/test.ts",
|
||||
"tsConfig": "projects/ucap-webmessenger-ui-message/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/ucap-webmessenger-ui-message/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/ucap-webmessenger-ui-message/tsconfig.lib.json",
|
||||
"projects/ucap-webmessenger-ui-message/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"ucap-webmessenger-ui-settings": {
|
||||
"projectType": "library",
|
||||
"root": "projects/ucap-webmessenger-ui-settings",
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
JsonAnalization,
|
||||
StatusCode
|
||||
} from '@ucap-webmessenger/api';
|
||||
import { FileUploadItem } from '../models/file-upload-item';
|
||||
import { FileUploadItem } from '../../../../ucap-webmessenger-api/src/lib/models/file-upload-item';
|
||||
|
||||
export interface FileProfileSaveRequest extends APIRequest {
|
||||
userSeq: number;
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
ParameterUtil,
|
||||
APIFormDataEncoder
|
||||
} from '@ucap-webmessenger/api';
|
||||
import { FileDownloadItem } from '../models/file-download-item';
|
||||
import { FileDownloadItem } from '../../../../ucap-webmessenger-api/src/lib/models/file-download-item';
|
||||
|
||||
export interface FileTalkDownloadRequest extends APIRequest {
|
||||
userSeq: number;
|
||||
|
@ -33,9 +33,9 @@ export const encodeFileTalkDownload: APIEncoder<FileTalkDownloadRequest> = (
|
|||
return ParameterUtil.encode(fileTalkDownloadEncodeMap, req, extraParams);
|
||||
};
|
||||
|
||||
export const encodeFormDataFileTalkDownload: APIFormDataEncoder<
|
||||
FileTalkDownloadRequest
|
||||
> = (req: FileTalkDownloadRequest) => {
|
||||
export const encodeFormDataFileTalkDownload: APIFormDataEncoder<FileTalkDownloadRequest> = (
|
||||
req: FileTalkDownloadRequest
|
||||
) => {
|
||||
const extraParams: any = {};
|
||||
|
||||
extraParams.userSeq = String(req.userSeq);
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
JsonAnalization,
|
||||
APIFormDataEncoder
|
||||
} from '@ucap-webmessenger/api';
|
||||
import { FileUploadItem } from '../models/file-upload-item';
|
||||
import { FileUploadItem } from '../../../../ucap-webmessenger-api/src/lib/models/file-upload-item';
|
||||
|
||||
export interface FileTalkSaveRequest extends APIRequest {
|
||||
userSeq: number;
|
||||
|
|
|
@ -13,9 +13,6 @@ export * from './lib/apis/trans-mass-talk-save';
|
|||
export * from './lib/apis/translation-req';
|
||||
export * from './lib/apis/translation-save';
|
||||
|
||||
export * from './lib/models/file-download-item';
|
||||
export * from './lib/models/file-upload-item';
|
||||
|
||||
export * from './lib/services/common-api.service';
|
||||
|
||||
export * from './lib/ucap-common-api.module';
|
||||
|
|
|
@ -2,12 +2,15 @@ import {
|
|||
APIRequest,
|
||||
MessageAPIResponse,
|
||||
APIJsonEncoder,
|
||||
APIDecoder
|
||||
APIDecoder,
|
||||
APIFormDataEncoder,
|
||||
ParameterUtil
|
||||
} from '@ucap-webmessenger/api';
|
||||
import { DeviceType } from '@ucap-webmessenger/core';
|
||||
import { MessageType } from '../types/message.type';
|
||||
import { CategoryType } from '../types/category.type';
|
||||
import { ContentType } from '../types/content.type';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
export interface SendRequest extends APIRequest {
|
||||
userSeq: number;
|
||||
|
@ -25,12 +28,72 @@ export interface SendRequest extends APIRequest {
|
|||
|
||||
textContent: { text: string }[];
|
||||
recvUserList: { userSeq: number; userName: string }[];
|
||||
|
||||
files: File[];
|
||||
fileUploadItem: FileUploadItem;
|
||||
}
|
||||
|
||||
export interface SendResponse extends MessageAPIResponse {}
|
||||
|
||||
export const encodeSend: APIJsonEncoder<SendRequest> = (req: SendRequest) => {
|
||||
return JSON.stringify(req);
|
||||
const sendEncodeMap = {
|
||||
userSeq: 'userSeq',
|
||||
deviceType: 'deviceType',
|
||||
tokenKey: 'tokenKey',
|
||||
type: 'type',
|
||||
userName: 'userName',
|
||||
category: 'category',
|
||||
title: 'title',
|
||||
titleYn: 'titleYn',
|
||||
listOrder: 'listOrder',
|
||||
reservationTime: 'reservationTime',
|
||||
smsYn: 'smsYn',
|
||||
textContent: 'textContent',
|
||||
recvUserList: 'recvUserList',
|
||||
files: 'files'
|
||||
};
|
||||
|
||||
export const encodeSend: APIFormDataEncoder<SendRequest> = (
|
||||
req: SendRequest
|
||||
) => {
|
||||
const extraParams: any = {};
|
||||
|
||||
extraParams.userSeq = String(req.userSeq);
|
||||
if (!!req.titleYn) {
|
||||
extraParams.titleYn = req.titleYn ? 'Y' : 'N';
|
||||
}
|
||||
if (!!req.smsYn) {
|
||||
extraParams.smsYn = req.smsYn ? 'Y' : 'N';
|
||||
}
|
||||
if (!!req.listOrder) {
|
||||
let s = '';
|
||||
req.listOrder.forEach(v => {
|
||||
s = s + String(v);
|
||||
});
|
||||
extraParams.listOrder = s;
|
||||
}
|
||||
if (!!req.textContent) {
|
||||
let s = '';
|
||||
req.textContent.forEach(v => {
|
||||
if ('' !== s) {
|
||||
s = s + `,${JSON.stringify(v)}`;
|
||||
} else {
|
||||
s = s + `${JSON.stringify(v)}`;
|
||||
}
|
||||
});
|
||||
extraParams.textContent = `[${s}]`;
|
||||
}
|
||||
if (!!req.recvUserList) {
|
||||
let s = '';
|
||||
req.recvUserList.forEach(v => {
|
||||
if ('' !== s) {
|
||||
s = s + `,${JSON.stringify(v)}`;
|
||||
} else {
|
||||
s = s + `${JSON.stringify(v)}`;
|
||||
}
|
||||
});
|
||||
extraParams.recvUserList = `[${s}]`;
|
||||
}
|
||||
return ParameterUtil.encodeFormData(sendEncodeMap, req, extraParams);
|
||||
};
|
||||
|
||||
export const decodeSend: APIDecoder<SendResponse> = (res: any) => {
|
||||
|
|
|
@ -158,11 +158,29 @@ export class MessageApiService {
|
|||
|
||||
/** send */
|
||||
public sendMessage(req: SendRequest): Observable<SendResponse> {
|
||||
return this.httpClient
|
||||
.post<any>(this.urls.sendNewMessage, encodeSend(req), {
|
||||
headers: this.headers
|
||||
const httpReq = new HttpRequest(
|
||||
'POST',
|
||||
this.urls.sendNewMessage,
|
||||
encodeSend(req),
|
||||
{ reportProgress: true, responseType: 'text' as 'json' }
|
||||
);
|
||||
|
||||
const progress = req.fileUploadItem.uploadStart();
|
||||
|
||||
return this.httpClient.request(httpReq).pipe(
|
||||
filter(event => {
|
||||
if (event instanceof HttpResponse) {
|
||||
return true;
|
||||
} else if (HttpEventType.UploadProgress === event.type) {
|
||||
progress.next(Math.round((100 * event.loaded) / event.total));
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
map((event: HttpResponse<any>) => {
|
||||
req.fileUploadItem.uploadComplete();
|
||||
return decodeSend(event.body);
|
||||
})
|
||||
.pipe(map(res => decodeSend(res)));
|
||||
);
|
||||
}
|
||||
|
||||
/** detail */
|
||||
|
|
|
@ -7,6 +7,9 @@ export * from './lib/apis/api';
|
|||
export * from './lib/types/message-status-code.type';
|
||||
export * from './lib/types/status-code.type';
|
||||
|
||||
export * from './lib/models/file-download-item';
|
||||
export * from './lib/models/file-upload-item';
|
||||
|
||||
export * from './lib/utils/json.util';
|
||||
export * from './lib/utils/parameter.util';
|
||||
export * from './lib/utils/url.util';
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
OnInit,
|
||||
OnDestroy,
|
||||
Inject,
|
||||
EventEmitter,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
@ -13,10 +13,8 @@ import { DeviceType, FileUtil, MimeUtil } from '@ucap-webmessenger/core';
|
|||
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
|
||||
import { take, map, finalize, tap } from 'rxjs/operators';
|
||||
import { SnackBarService } from '@ucap-webmessenger/ui';
|
||||
import {
|
||||
FileDownloadItem,
|
||||
CommonApiService,
|
||||
} from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
import { CommonApiService } from '@ucap-webmessenger/api-common';
|
||||
|
||||
export interface FileViewerDialogData {
|
||||
fileInfo: FileEventJson;
|
||||
|
@ -31,7 +29,7 @@ export interface FileViewerDialogResult {}
|
|||
@Component({
|
||||
selector: 'app-layout-common-file-viewer',
|
||||
templateUrl: './file-viewer.dialog.component.html',
|
||||
styleUrls: ['./file-viewer.dialog.component.scss'],
|
||||
styleUrls: ['./file-viewer.dialog.component.scss']
|
||||
})
|
||||
export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||
fileInfo: FileEventJson;
|
||||
|
@ -64,7 +62,7 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
|||
userSeq: this.userSeq,
|
||||
deviceType: this.deviceType,
|
||||
token: this.token,
|
||||
attachmentsSeq: this.fileInfo.attachmentSeq,
|
||||
attachmentsSeq: this.fileInfo.attachmentSeq
|
||||
},
|
||||
this.downloadUrl
|
||||
);
|
||||
|
@ -82,7 +80,7 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
|||
deviceType: this.deviceType,
|
||||
token: this.token,
|
||||
attachmentsSeq: this.fileInfo.attachmentSeq,
|
||||
fileDownloadItem,
|
||||
fileDownloadItem
|
||||
},
|
||||
this.downloadUrl
|
||||
)
|
||||
|
@ -103,7 +101,7 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
|||
'',
|
||||
{
|
||||
duration: 3000,
|
||||
verticalPosition: 'bottom',
|
||||
verticalPosition: 'bottom'
|
||||
}
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -40,10 +40,10 @@ import { UnreadCountRequest } from 'projects/ucap-webmessenger-api-message/src/l
|
|||
import { map, catchError, tap } from 'rxjs/operators';
|
||||
import { MessageStatusCode } from '@ucap-webmessenger/api';
|
||||
import {
|
||||
EditMessageDialogComponent,
|
||||
EditMessageDialogResult,
|
||||
EditMessageDialogData
|
||||
} from '../dialogs/message/edit-message.dialog.component';
|
||||
MessageWriteDialogComponent,
|
||||
MessageWriteDialogResult,
|
||||
MessageWriteDialogData
|
||||
} from '../dialogs/message/message-write.dialog.component';
|
||||
|
||||
export enum MainMenu {
|
||||
Group = 'GROUP',
|
||||
|
@ -209,11 +209,12 @@ export class LeftSideComponent implements OnInit, OnDestroy {
|
|||
|
||||
async onClickNewMessage() {
|
||||
const result = await this.dialogService.open<
|
||||
EditMessageDialogComponent,
|
||||
EditMessageDialogData,
|
||||
EditMessageDialogResult
|
||||
>(EditMessageDialogComponent, {
|
||||
MessageWriteDialogComponent,
|
||||
MessageWriteDialogData,
|
||||
MessageWriteDialogResult
|
||||
>(MessageWriteDialogComponent, {
|
||||
width: '600px',
|
||||
height: '600px',
|
||||
data: {
|
||||
loginRes: this.loginRes
|
||||
}
|
||||
|
|
|
@ -67,9 +67,9 @@ import {
|
|||
MatSnackBarRef,
|
||||
SimpleSnackBar
|
||||
} from '@angular/material';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
import {
|
||||
CommonApiService,
|
||||
FileUploadItem,
|
||||
FileTalkSaveRequest,
|
||||
FileTalkSaveResponse
|
||||
} from '@ucap-webmessenger/api-common';
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
<mat-card class="confirm-card mat-elevation-z">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
쪽지 보내기
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
새쪽지를 보내요.
|
||||
|
||||
<ucap-message-editor></ucap-message-editor>
|
||||
</mat-card-content>
|
||||
<mat-card-actions class="button-farm flex-row">
|
||||
<button mat-stroked-button (click)="onClickTest()" class="mat-primary">
|
||||
테스트
|
||||
</button>
|
||||
<button
|
||||
mat-stroked-button
|
||||
(click)="onClickChoice(false)"
|
||||
class="mat-primary"
|
||||
>
|
||||
취소
|
||||
</button>
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="getBtnValid()"
|
||||
(click)="onClickChoice(true)"
|
||||
class="mat-primary"
|
||||
>
|
||||
보내기
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
|
@ -1,27 +0,0 @@
|
|||
::ng-deep .mat-card-header-tex {
|
||||
margin: 0;
|
||||
}
|
||||
.confirm-card {
|
||||
min-width: 500px;
|
||||
.mat-card-content {
|
||||
}
|
||||
.button-farm {
|
||||
text-align: right;
|
||||
.mat-primary {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .mat-mini-fab .mat-button-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.contents {
|
||||
height: 380px;
|
||||
|
||||
.thumbnail {
|
||||
max-width: 250px;
|
||||
max-height: 250px;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EditMessageDialogComponent } from './edit-message.dialog.component';
|
||||
|
||||
describe('app::layouts::messenger::EditMessageDialogComponent', () => {
|
||||
let component: EditMessageDialogComponent;
|
||||
let fixture: ComponentFixture<EditMessageDialogComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EditMessageDialogComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditMessageDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,99 +0,0 @@
|
|||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Inject,
|
||||
ViewChild,
|
||||
ElementRef
|
||||
} from '@angular/core';
|
||||
import {
|
||||
MatDialogRef,
|
||||
MAT_DIALOG_DATA,
|
||||
MatSelectionList,
|
||||
MatSelectionListChange,
|
||||
MatDrawer
|
||||
} from '@angular/material';
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import { map, catchError, take } from 'rxjs/operators';
|
||||
|
||||
import * as AppStore from '@app/store';
|
||||
import * as SyncStore from '@app/store/messenger/sync';
|
||||
|
||||
import {
|
||||
DialogService,
|
||||
ConfirmDialogComponent,
|
||||
ConfirmDialogData,
|
||||
ConfirmDialogResult,
|
||||
SnackBarService,
|
||||
AlertDialogComponent,
|
||||
AlertDialogResult,
|
||||
AlertDialogData
|
||||
} from '@ucap-webmessenger/ui';
|
||||
import { GroupDetailData, UserInfo } from '@ucap-webmessenger/protocol-sync';
|
||||
import {
|
||||
DetailResponse,
|
||||
MessageType,
|
||||
DetailContent,
|
||||
DetailReceiver,
|
||||
ContentType,
|
||||
MessageDetailInfo,
|
||||
MessageApiService,
|
||||
RetrieveResourceFileRequest,
|
||||
CancelRequest
|
||||
} from '@ucap-webmessenger/api-message';
|
||||
import { DeviceType, MimeUtil, FileUtil } from '@ucap-webmessenger/core';
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
|
||||
import { MessageStatusCode } from '@ucap-webmessenger/api';
|
||||
import { MessageEditorComponent } from 'projects/ucap-webmessenger-ui/src/lib/components/message-editor.component';
|
||||
|
||||
export interface EditMessageDialogData {
|
||||
loginRes: LoginResponse;
|
||||
detail?: DetailResponse;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-empty-interface
|
||||
export interface EditMessageDialogResult {}
|
||||
|
||||
export interface DownloadQueueForMessage extends DetailContent {
|
||||
downloadType: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-messenger-edit-message',
|
||||
templateUrl: './edit-message.dialog.component.html',
|
||||
styleUrls: ['./edit-message.dialog.component.scss']
|
||||
})
|
||||
export class EditMessageDialogComponent implements OnInit {
|
||||
@ViewChild(MessageEditorComponent, { static: false })
|
||||
editor?: MessageEditorComponent;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<
|
||||
EditMessageDialogData,
|
||||
EditMessageDialogResult
|
||||
>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: EditMessageDialogData,
|
||||
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
||||
private messageApiService: MessageApiService,
|
||||
private snackBarService: SnackBarService,
|
||||
private logger: NGXLogger,
|
||||
private store: Store<any>,
|
||||
private dialogService: DialogService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
getBtnValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
onClickChoice(choice: boolean): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onClickTest() {
|
||||
console.log(this.editor.getContents());
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { MessageDetailDialogComponent } from './message-detail.dialog.component';
|
||||
import { EditMessageDialogComponent } from './edit-message.dialog.component';
|
||||
import { MessageWriteDialogComponent } from './message-write.dialog.component';
|
||||
|
||||
export const DIALOGS = [
|
||||
MessageDetailDialogComponent,
|
||||
EditMessageDialogComponent
|
||||
MessageWriteDialogComponent
|
||||
];
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<mat-card class="confirm-card mat-elevation-z">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
쪽지 보내기
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<ucap-message-write #messageWrite></ucap-message-write>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
|
@ -0,0 +1,8 @@
|
|||
.confirm-card {
|
||||
min-width: 500px;
|
||||
height: 100%;
|
||||
|
||||
mat-card-content {
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MessageWriteDialogComponent } from './message-write.dialog.component';
|
||||
|
||||
describe('app::layouts::messenger::MessageWriteDialogComponent', () => {
|
||||
let component: MessageWriteDialogComponent;
|
||||
let fixture: ComponentFixture<MessageWriteDialogComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MessageWriteDialogComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MessageWriteDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
import { Component, OnInit, Inject, ViewChild } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
||||
import { DialogService, SnackBarService } from '@ucap-webmessenger/ui';
|
||||
|
||||
import {
|
||||
DetailResponse,
|
||||
DetailContent,
|
||||
MessageApiService
|
||||
} from '@ucap-webmessenger/api-message';
|
||||
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { MessageStatusCode } from '@ucap-webmessenger/api';
|
||||
import { WriteComponent as UCapMessageWriteComponent } from '@ucap-webmessenger/ui-message';
|
||||
|
||||
export interface MessageWriteDialogData {
|
||||
loginRes: LoginResponse;
|
||||
detail?: DetailResponse;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-empty-interface
|
||||
export interface MessageWriteDialogResult {}
|
||||
|
||||
export interface DownloadQueueForMessage extends DetailContent {
|
||||
downloadType: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-messenger-message-write',
|
||||
templateUrl: './message-write.dialog.component.html',
|
||||
styleUrls: ['./message-write.dialog.component.scss']
|
||||
})
|
||||
export class MessageWriteDialogComponent implements OnInit {
|
||||
@ViewChild('messageWrite', { static: true })
|
||||
messageWrite: UCapMessageWriteComponent;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<
|
||||
MessageWriteDialogData,
|
||||
MessageWriteDialogResult
|
||||
>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: MessageWriteDialogData,
|
||||
private messageApiService: MessageApiService,
|
||||
private snackBarService: SnackBarService,
|
||||
private logger: NGXLogger,
|
||||
private dialogService: DialogService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
getBtnValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
onClickChoice(choice: boolean): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onClickTest() {
|
||||
this.messageWrite.printEditor();
|
||||
}
|
||||
}
|
|
@ -32,10 +32,8 @@ import {
|
|||
SelectGroupDialogData,
|
||||
SelectGroupDialogResult
|
||||
} from '../group/select-group.dialog.component';
|
||||
import {
|
||||
FileUploadItem,
|
||||
CommonApiService
|
||||
} from '@ucap-webmessenger/api-common';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
import { CommonApiService } from '@ucap-webmessenger/api-common';
|
||||
import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types';
|
||||
import { StatusCode } from '@ucap-webmessenger/api';
|
||||
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
|
||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
|
||||
import {
|
||||
MatCheckboxModule,
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
MatRippleModule,
|
||||
MatSortModule,
|
||||
MatTooltipModule,
|
||||
MatSidenavModule
|
||||
} from '@angular/material';
|
||||
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
|
@ -22,21 +34,9 @@ import { MatTabsModule } from '@angular/material/tabs';
|
|||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import {
|
||||
MatCheckboxModule,
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
MatRippleModule,
|
||||
MatSortModule,
|
||||
MatTooltipModule,
|
||||
MatSidenavModule
|
||||
} from '@angular/material';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
|
||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
||||
|
||||
import { UCapUiModule } from '@ucap-webmessenger/ui';
|
||||
|
@ -45,6 +45,7 @@ import { UCapUiChatModule } from '@ucap-webmessenger/ui-chat';
|
|||
import { UCapUiRoomModule } from '@ucap-webmessenger/ui-room';
|
||||
import { UCapUiProfileModule } from '@ucap-webmessenger/ui-profile';
|
||||
import { UCapUiGroupModule } from '@ucap-webmessenger/ui-group';
|
||||
import { UCapUiMessageModule } from '@ucap-webmessenger/ui-message';
|
||||
import { UCapUiOrganizationModule } from '@ucap-webmessenger/ui-organization';
|
||||
import { UCapUiSettingsModule } from '@ucap-webmessenger/ui-settings';
|
||||
|
||||
|
@ -92,6 +93,7 @@ import { DIALOGS } from './dialogs';
|
|||
UCapUiModule,
|
||||
UCapUiAccountModule,
|
||||
UCapUiChatModule,
|
||||
UCapUiMessageModule,
|
||||
UCapUiRoomModule,
|
||||
UCapUiProfileModule,
|
||||
UCapUiGroupModule,
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
Input
|
||||
} from '@angular/core';
|
||||
import { NgForm } from '@angular/forms';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
import { FileUploadQueueComponent } from '@ucap-webmessenger/ui';
|
||||
|
||||
@Component({
|
||||
|
|
24
projects/ucap-webmessenger-ui-message/README.md
Normal file
24
projects/ucap-webmessenger-ui-message/README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# UcapWebmessengerUiMessage
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.11.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project ucap-webmessenger-ui-message` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ucap-webmessenger-ui-message`.
|
||||
> Note: Don't forget to add `--project ucap-webmessenger-ui-message` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build ucap-webmessenger-ui-message` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build ucap-webmessenger-ui-message`, go to the dist folder `cd dist/ucap-webmessenger-ui-message` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test ucap-webmessenger-ui-message` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
32
projects/ucap-webmessenger-ui-message/karma.conf.js
Normal file
32
projects/ucap-webmessenger-ui-message/karma.conf.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../coverage/ucap-webmessenger-ui-message'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
7
projects/ucap-webmessenger-ui-message/ng-package.json
Normal file
7
projects/ucap-webmessenger-ui-message/ng-package.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/ucap-webmessenger-ui-message",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
8
projects/ucap-webmessenger-ui-message/package.json
Normal file
8
projects/ucap-webmessenger-ui-message/package.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@ucap-webmessenger/ui-message",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^8.2.11",
|
||||
"@angular/core": "^8.2.11"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<mat-card class="mat-elevation-z0 ucap-message-write">
|
||||
<form name="messageWriteForm" [formGroup]="messageWriteForm" novalidate>
|
||||
<mat-form-field class="message-receiver-list">
|
||||
<mat-chip-list #chipList aria-label="Fruit selection">
|
||||
<mat-chip *ngFor="let receiver of receiverList">
|
||||
{{ receiver }}
|
||||
<span matChipRemove class="mdi mdi-close"></span>
|
||||
</mat-chip>
|
||||
<input
|
||||
matInput
|
||||
placeholder="수신자"
|
||||
formControlName="receiverList"
|
||||
[matChipInputFor]="chipList"
|
||||
/>
|
||||
</mat-chip-list>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="message-title">
|
||||
<input matInput formControlName="title" placeholder="제목" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-card-content class="message-write-body">
|
||||
<div
|
||||
#editor
|
||||
class="ucap-message-write-editor"
|
||||
contenteditable="true"
|
||||
(paste)="onPasteEditor($event)"
|
||||
></div>
|
||||
<input type="file" #fileInput style="display: none" multiple />
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let attachment of attachmentList">
|
||||
{{ attachment.name }}
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-icon-button aria-label="이미지" (click)="onClickImage()">
|
||||
<span class="mdi mdi-camera mdi-24px"></span>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
aria-label="첨부파일"
|
||||
(click)="onClickAttachment()"
|
||||
>
|
||||
<span class="mdi mdi-attachment mdi-rotate-90 mdi-24px"></span>
|
||||
</button>
|
||||
<button mat-stroked-button (click)="onClickCancel()" class="mat-primary">
|
||||
취소
|
||||
</button>
|
||||
<button mat-flat-button (click)="onClickSend()" class="mat-primary">
|
||||
보내기
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</form>
|
||||
</mat-card>
|
|
@ -0,0 +1,24 @@
|
|||
.ucap-message-write {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.message-receiver-list {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.message-title {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.message-write-body {
|
||||
overflow: auto;
|
||||
height: 270px;
|
||||
|
||||
.ucap-message-write-editor {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 270px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { WriteComponent } from './write.component';
|
||||
|
||||
describe('Message::WriteComponent', () => {
|
||||
let component: WriteComponent;
|
||||
let fixture: ComponentFixture<WriteComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [WriteComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(WriteComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,190 @@
|
|||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
ViewChild,
|
||||
ContentChild,
|
||||
TemplateRef,
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
OnDestroy,
|
||||
ElementRef
|
||||
} from '@angular/core';
|
||||
|
||||
import { ucapAnimations } from '@ucap-webmessenger/ui';
|
||||
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { FileUtil } from '@ucap-webmessenger/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
|
||||
interface Content {
|
||||
contentType: 'text' | 'image' | 'attachment';
|
||||
content: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-message-write',
|
||||
templateUrl: './write.component.html',
|
||||
styleUrls: ['./write.component.scss'],
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class WriteComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
@ViewChild('editor', { static: true })
|
||||
editor: ElementRef<HTMLDivElement>;
|
||||
|
||||
@ViewChild('fileInput', { static: true })
|
||||
fileInput: ElementRef<HTMLInputElement>;
|
||||
|
||||
messageWriteForm: FormGroup;
|
||||
receiverList: string[] = ['이진호', '강희경', '이유진'];
|
||||
attachmentList: File[];
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logger: NGXLogger
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.messageWriteForm = this.formBuilder.group({
|
||||
receiverList: ['', [Validators.required]],
|
||||
title: ['', [Validators.required]]
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {}
|
||||
|
||||
ngAfterViewInit(): void {}
|
||||
|
||||
onClickImage() {
|
||||
this.fileInput.nativeElement.click();
|
||||
const self = this;
|
||||
this.fileInput.nativeElement.onchange = () => {
|
||||
const fileList: FileList = self.fileInput.nativeElement.files;
|
||||
|
||||
FileUtil.fromBlobToDataUrl(fileList.item(0)).then(dataUrl => {
|
||||
const img = document.createElement('img');
|
||||
img.src = dataUrl as string;
|
||||
self.insertNode(img);
|
||||
});
|
||||
|
||||
self.fileInput.nativeElement.value = '';
|
||||
};
|
||||
}
|
||||
|
||||
onClickAttachment() {
|
||||
this.fileInput.nativeElement.click();
|
||||
const self = this;
|
||||
this.fileInput.nativeElement.onchange = () => {
|
||||
const fileList: FileList = this.fileInput.nativeElement.files;
|
||||
|
||||
if (!self.attachmentList) {
|
||||
self.attachmentList = [];
|
||||
}
|
||||
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
const file = fileList.item(i);
|
||||
self.attachmentList.push(file);
|
||||
}
|
||||
|
||||
self.changeDetectorRef.detectChanges();
|
||||
|
||||
self.fileInput.nativeElement.value = '';
|
||||
};
|
||||
}
|
||||
|
||||
onPasteEditor(event: ClipboardEvent) {
|
||||
const text = document.createTextNode(
|
||||
event.clipboardData.getData('text/plain')
|
||||
);
|
||||
this.insertNode(text, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onClickSend() {}
|
||||
onClickCancel() {}
|
||||
|
||||
printEditor(): void {
|
||||
const contentList: Content[] = [];
|
||||
|
||||
this.editor.nativeElement.childNodes.forEach((v, k) => {
|
||||
this.parseNode(contentList, v);
|
||||
});
|
||||
|
||||
this.logger.debug('printEditor', contentList);
|
||||
}
|
||||
|
||||
private parseNode(contentList: Content[], node: ChildNode) {
|
||||
switch (node.nodeType) {
|
||||
case Node.ELEMENT_NODE:
|
||||
{
|
||||
if (0 < node.childNodes.length) {
|
||||
let prevNode: ChildNode;
|
||||
node.childNodes.forEach(v => {
|
||||
if (
|
||||
!!prevNode &&
|
||||
'IMG' === prevNode.nodeName &&
|
||||
'BR' === v.nodeName
|
||||
) {
|
||||
prevNode = v;
|
||||
return;
|
||||
}
|
||||
prevNode = v;
|
||||
this.parseNode(contentList, v);
|
||||
});
|
||||
} else {
|
||||
if ('IMG' === node.nodeName) {
|
||||
this.appendNode(contentList, 'image', node.textContent);
|
||||
} else if ('BR' === node.nodeName) {
|
||||
this.appendNode(contentList, 'text', `\n`);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Node.TEXT_NODE:
|
||||
this.appendNode(contentList, 'text', node.textContent);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private appendNode(
|
||||
contentList: Content[],
|
||||
contentType: 'text' | 'image' | 'attachment',
|
||||
content: string
|
||||
) {
|
||||
const prevContent = contentList[contentList.length - 1];
|
||||
switch (contentType) {
|
||||
case 'text':
|
||||
if (!!prevContent && 'text' === prevContent.contentType) {
|
||||
prevContent.content = `${prevContent.content}${content}`;
|
||||
} else {
|
||||
contentList.push({
|
||||
contentType: 'text',
|
||||
content
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
contentList.push({ contentType, content });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private insertNode(node: Node, removeSelected: boolean = false) {
|
||||
const selection: Selection = document.getSelection();
|
||||
const range: Range = selection.getRangeAt(0);
|
||||
|
||||
if (removeSelected) {
|
||||
selection.empty();
|
||||
}
|
||||
|
||||
range.insertNode(node);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
|
||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatGridListModule } from '@angular/material/grid-list';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
|
||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
||||
|
||||
import { WriteComponent } from './components/write.component';
|
||||
|
||||
const COMPONENTS = [WriteComponent];
|
||||
const DIALOGS = [];
|
||||
const DIRECTIVES = [];
|
||||
const SERVICES = [];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
FlexLayoutModule,
|
||||
|
||||
ScrollingModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatChipsModule,
|
||||
MatDividerModule,
|
||||
MatFormFieldModule,
|
||||
MatGridListModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
|
||||
PerfectScrollbarModule
|
||||
],
|
||||
exports: [...COMPONENTS, ...DIRECTIVES],
|
||||
declarations: [...COMPONENTS, ...DIRECTIVES, ...DIALOGS],
|
||||
entryComponents: [...DIALOGS]
|
||||
})
|
||||
export class UCapUiMessageModule {
|
||||
public static forRoot(): ModuleWithProviders<UCapUiMessageModule> {
|
||||
return {
|
||||
ngModule: UCapUiMessageModule,
|
||||
providers: [...SERVICES]
|
||||
};
|
||||
}
|
||||
}
|
7
projects/ucap-webmessenger-ui-message/src/public-api.ts
Normal file
7
projects/ucap-webmessenger-ui-message/src/public-api.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Public API Surface of ucap-webmessenger-ui-message
|
||||
*/
|
||||
|
||||
export * from './lib/components/write.component';
|
||||
|
||||
export * from './lib/ucap-ui-message.module';
|
21
projects/ucap-webmessenger-ui-message/src/test.ts
Normal file
21
projects/ucap-webmessenger-ui-message/src/test.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
26
projects/ucap-webmessenger-ui-message/tsconfig.lib.json
Normal file
26
projects/ucap-webmessenger-ui-message/tsconfig.lib.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
17
projects/ucap-webmessenger-ui-message/tsconfig.spec.json
Normal file
17
projects/ucap-webmessenger-ui-message/tsconfig.spec.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
17
projects/ucap-webmessenger-ui-message/tslint.json
Normal file
17
projects/ucap-webmessenger-ui-message/tslint.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"ucapMessage",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"ucap-message",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import {
|
|||
|
||||
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
|
||||
import { UserInfoF } from '@ucap-webmessenger/protocol-query';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from '@angular/core';
|
||||
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-file-upload-queue',
|
||||
|
|
|
@ -3,13 +3,13 @@ import { ucapAnimations } from '../animations';
|
|||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { FileViewerType } from '../types/file-viewer.type';
|
||||
import { FileType } from '@ucap-webmessenger/protocol-file';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-file-viewer',
|
||||
templateUrl: './file-viewer.component.html',
|
||||
styleUrls: ['./file-viewer.component.scss'],
|
||||
animations: ucapAnimations,
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class FileViewerComponent implements OnInit {
|
||||
@Input()
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { ucapAnimations } from '../../animations';
|
||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { DeviceType } from '@ucap-webmessenger/core';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-binary-viewer',
|
||||
templateUrl: './binary-viewer.component.html',
|
||||
styleUrls: ['./binary-viewer.component.scss'],
|
||||
animations: ucapAnimations,
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class BinaryViewerComponent implements OnInit {
|
||||
@Input()
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { ucapAnimations } from '../../animations';
|
||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { DeviceType } from '@ucap-webmessenger/core';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-document-viewer',
|
||||
templateUrl: './document-viewer.component.html',
|
||||
styleUrls: ['./document-viewer.component.scss'],
|
||||
animations: ucapAnimations,
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class DocumentViewerComponent implements OnInit {
|
||||
@Input()
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { ucapAnimations } from '../../animations';
|
||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { DeviceType } from '@ucap-webmessenger/core';
|
||||
import {
|
||||
CommonApiService,
|
||||
FileDownloadItem,
|
||||
} from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-image-viewer',
|
||||
templateUrl: './image-viewer.component.html',
|
||||
styleUrls: ['./image-viewer.component.scss'],
|
||||
animations: ucapAnimations,
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class ImageViewerComponent implements OnInit {
|
||||
@Input()
|
||||
|
|
|
@ -5,18 +5,18 @@ import {
|
|||
Output,
|
||||
EventEmitter,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
ElementRef
|
||||
} from '@angular/core';
|
||||
import { ucapAnimations } from '../../animations';
|
||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { MatSlider, MatSliderChange } from '@angular/material';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-sound-viewer',
|
||||
templateUrl: './sound-viewer.component.html',
|
||||
styleUrls: ['./sound-viewer.component.scss'],
|
||||
animations: ucapAnimations,
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class SoundViewerComponent implements OnInit {
|
||||
@Input()
|
||||
|
|
|
@ -5,18 +5,18 @@ import {
|
|||
Output,
|
||||
EventEmitter,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
ElementRef
|
||||
} from '@angular/core';
|
||||
import { ucapAnimations } from '../../animations';
|
||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { MatSlider, MatSliderChange } from '@angular/material';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-video-viewer',
|
||||
templateUrl: './video-viewer.component.html',
|
||||
styleUrls: ['./video-viewer.component.scss'],
|
||||
animations: ucapAnimations,
|
||||
animations: ucapAnimations
|
||||
})
|
||||
export class VideoViewerComponent implements OnInit {
|
||||
@Input()
|
||||
|
|
|
@ -29,46 +29,41 @@ export class MessageEditorComponent implements OnInit, AfterViewInit {
|
|||
ngOnInit() {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
setTimeout(() => {
|
||||
this.contentArea.nativeElement.focus();
|
||||
|
||||
document
|
||||
.querySelector('#contentArea')
|
||||
.addEventListener('paste', (event: ClipboardEvent) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
const clipboardData = event.clipboardData;
|
||||
let pastedData = clipboardData.getData('Text');
|
||||
pastedData = this.convertHtmltoEntity(pastedData);
|
||||
clipboardData.setData('Text', pastedData);
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = pastedData;
|
||||
|
||||
this.attachElementNextFocused(div);
|
||||
});
|
||||
|
||||
document
|
||||
.querySelector('#contentArea')
|
||||
.addEventListener('keyup', event => {
|
||||
if (
|
||||
document.querySelector('#contentArea').innerHTML === '' ||
|
||||
document.querySelector('#contentArea').innerHTML === '<br>'
|
||||
) {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = ' <br>';
|
||||
document.querySelector('#contentArea').innerHTML = '';
|
||||
this.attachElementNextFocused(div);
|
||||
}
|
||||
});
|
||||
|
||||
// init..
|
||||
if (document.querySelector('#contentArea').innerHTML === '') {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = ' <br>';
|
||||
this.attachElementNextFocused(div);
|
||||
}
|
||||
}, 700);
|
||||
// setTimeout(() => {
|
||||
// this.contentArea.nativeElement.focus();
|
||||
// document
|
||||
// .querySelector('#contentArea')
|
||||
// .addEventListener('paste', (event: ClipboardEvent) => {
|
||||
// event.stopPropagation();
|
||||
// event.preventDefault();
|
||||
// const clipboardData = event.clipboardData;
|
||||
// let pastedData = clipboardData.getData('Text');
|
||||
// pastedData = this.convertHtmltoEntity(pastedData);
|
||||
// clipboardData.setData('Text', pastedData);
|
||||
// const div = document.createElement('div');
|
||||
// div.innerHTML = pastedData;
|
||||
// this.attachElementNextFocused(div);
|
||||
// });
|
||||
// document
|
||||
// .querySelector('#contentArea')
|
||||
// .addEventListener('keyup', event => {
|
||||
// if (
|
||||
// document.querySelector('#contentArea').innerHTML === '' ||
|
||||
// document.querySelector('#contentArea').innerHTML === '<br>'
|
||||
// ) {
|
||||
// const div = document.createElement('div');
|
||||
// div.innerHTML = ' <br>';
|
||||
// document.querySelector('#contentArea').innerHTML = '';
|
||||
// this.attachElementNextFocused(div);
|
||||
// }
|
||||
// });
|
||||
// // init..
|
||||
// if (document.querySelector('#contentArea').innerHTML === '') {
|
||||
// const div = document.createElement('div');
|
||||
// div.innerHTML = ' <br>';
|
||||
// this.attachElementNextFocused(div);
|
||||
// }
|
||||
// }, 700);
|
||||
}
|
||||
|
||||
onClickFileInput(type: string) {
|
||||
|
@ -92,7 +87,7 @@ export class MessageEditorComponent implements OnInit, AfterViewInit {
|
|||
this.attachFiles.push({ file: files[i], idx: this.fileIndex });
|
||||
} else {
|
||||
this.imageFiles.push({ file: files[i], idx: this.fileIndex });
|
||||
this.addImageInInputField(files[i], this.fileIndex);
|
||||
// this.addImageInInputField(files[i], this.fileIndex);
|
||||
}
|
||||
this.fileIndex++;
|
||||
}
|
||||
|
@ -103,71 +98,71 @@ export class MessageEditorComponent implements OnInit, AfterViewInit {
|
|||
return 'this is contents';
|
||||
}
|
||||
|
||||
addImageInInputField(image: File, index: number) {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(image);
|
||||
reader.onloadend = () => {
|
||||
const img = document.createElement('img');
|
||||
img.setAttribute('src', reader.result.toString());
|
||||
img.setAttribute('data-seq', index.toString());
|
||||
// addImageInInputField(image: File, index: number) {
|
||||
// const reader = new FileReader();
|
||||
// reader.readAsDataURL(image);
|
||||
// reader.onloadend = () => {
|
||||
// const img = document.createElement('img');
|
||||
// img.setAttribute('src', reader.result.toString());
|
||||
// img.setAttribute('data-seq', index.toString());
|
||||
|
||||
this.attachElementNextFocused(img);
|
||||
};
|
||||
}
|
||||
// this.attachElementNextFocused(img);
|
||||
// };
|
||||
// }
|
||||
|
||||
attachElementNextFocused(el: HTMLElement) {
|
||||
if (window.getSelection) {
|
||||
const sel = window.getSelection();
|
||||
const selAnchorNode: Node = sel.anchorNode;
|
||||
const focusedEl = selAnchorNode.parentElement;
|
||||
// attachElementNextFocused(el: HTMLElement) {
|
||||
// if (window.getSelection) {
|
||||
// const sel = window.getSelection();
|
||||
// const selAnchorNode: Node = sel.anchorNode;
|
||||
// const focusedEl = selAnchorNode.parentElement;
|
||||
|
||||
if (this.isParentIdCheck(focusedEl, 'contentArea')) {
|
||||
if (sel.rangeCount) {
|
||||
const range = sel.getRangeAt(0);
|
||||
// if (this.isParentIdCheck(focusedEl, 'contentArea')) {
|
||||
// if (sel.rangeCount) {
|
||||
// const range = sel.getRangeAt(0);
|
||||
|
||||
if (selAnchorNode.nodeType === Node.TEXT_NODE) {
|
||||
const content: string = focusedEl.textContent;
|
||||
// if (selAnchorNode.nodeType === Node.TEXT_NODE) {
|
||||
// const content: string = focusedEl.textContent;
|
||||
|
||||
focusedEl.innerText =
|
||||
content.substr(0, range.startOffset) +
|
||||
el.textContent +
|
||||
content.substr(range.endOffset);
|
||||
} else if (
|
||||
selAnchorNode.nodeType === Node.ELEMENT_NODE &&
|
||||
focusedEl.id === 'contentArea'
|
||||
) {
|
||||
const selEl = selAnchorNode as HTMLElement;
|
||||
const content: string = selEl.textContent;
|
||||
// focusedEl.innerText =
|
||||
// content.substr(0, range.startOffset) +
|
||||
// el.textContent +
|
||||
// content.substr(range.endOffset);
|
||||
// } else if (
|
||||
// selAnchorNode.nodeType === Node.ELEMENT_NODE &&
|
||||
// focusedEl.id === 'contentArea'
|
||||
// ) {
|
||||
// const selEl = selAnchorNode as HTMLElement;
|
||||
// const content: string = selEl.textContent;
|
||||
|
||||
selEl.innerText =
|
||||
content.substr(0, range.startOffset) +
|
||||
el.textContent +
|
||||
content.substr(range.endOffset);
|
||||
} else {
|
||||
focusedEl.append(el);
|
||||
}
|
||||
} else {
|
||||
focusedEl.append(el);
|
||||
}
|
||||
} else {
|
||||
this.contentArea.nativeElement.appendChild(el);
|
||||
}
|
||||
} else {
|
||||
this.contentArea.nativeElement.appendChild(el);
|
||||
}
|
||||
}
|
||||
// selEl.innerText =
|
||||
// content.substr(0, range.startOffset) +
|
||||
// el.textContent +
|
||||
// content.substr(range.endOffset);
|
||||
// } else {
|
||||
// focusedEl.append(el);
|
||||
// }
|
||||
// } else {
|
||||
// focusedEl.append(el);
|
||||
// }
|
||||
// } else {
|
||||
// this.contentArea.nativeElement.appendChild(el);
|
||||
// }
|
||||
// } else {
|
||||
// this.contentArea.nativeElement.appendChild(el);
|
||||
// }
|
||||
// }
|
||||
|
||||
isParentIdCheck(el: HTMLElement, id: string): boolean {
|
||||
if (el.id === id) {
|
||||
return true;
|
||||
} else {
|
||||
if (el.tagName === 'BODY' || el.tagName === 'body') {
|
||||
return false;
|
||||
} else {
|
||||
return this.isParentIdCheck(el.parentElement, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// isParentIdCheck(el: HTMLElement, id: string): boolean {
|
||||
// if (el.id === id) {
|
||||
// return true;
|
||||
// } else {
|
||||
// if (el.tagName === 'BODY' || el.tagName === 'body') {
|
||||
// return false;
|
||||
// } else {
|
||||
// return this.isParentIdCheck(el.parentElement, id);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
test(): void {
|
||||
if (!!this.contentArea) {
|
||||
|
|
|
@ -10,10 +10,8 @@ import {
|
|||
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { FileUploadQueueComponent } from '../components/file-upload-queue.component';
|
||||
import {
|
||||
FileUploadItem,
|
||||
CommonApiService
|
||||
} from '@ucap-webmessenger/api-common';
|
||||
import { FileUploadItem } from '@ucap-webmessenger/api';
|
||||
import { CommonApiService } from '@ucap-webmessenger/api-common';
|
||||
import { FileUtil } from '@ucap-webmessenger/core';
|
||||
import { DialogService } from '../services/dialog.service';
|
||||
import {
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
"@ucap-webmessenger/ui-messenger": [
|
||||
"projects/ucap-webmessenger-ui-messenger/src/public-api"
|
||||
],
|
||||
"@ucap-webmessenger/ui-message": [
|
||||
"projects/ucap-webmessenger-ui-message/src/public-api"
|
||||
],
|
||||
"@ucap-webmessenger/ui-organization": [
|
||||
"projects/ucap-webmessenger-ui-organization/src/public-api"
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue
Block a user