file upload is implemented
This commit is contained in:
parent
5b9fa9f55c
commit
086a4556f8
3
package-lock.json
generated
3
package-lock.json
generated
|
@ -14104,7 +14104,8 @@
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
||||||
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
|
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"tslint": {
|
"tslint": {
|
||||||
"version": "5.15.0",
|
"version": "5.15.0",
|
||||||
|
|
|
@ -6,25 +6,28 @@ import {
|
||||||
APIDecoder,
|
APIDecoder,
|
||||||
ParameterUtil,
|
ParameterUtil,
|
||||||
StatusCode,
|
StatusCode,
|
||||||
JsonAnalization
|
JsonAnalization,
|
||||||
|
APIFormDataEncoder
|
||||||
} from '@ucap-webmessenger/api';
|
} from '@ucap-webmessenger/api';
|
||||||
import { JsonObject } from 'type-fest';
|
import { JsonObject } from 'type-fest';
|
||||||
|
import { FileUploadItem } from '../models/file-upload-item';
|
||||||
|
|
||||||
export interface FileTalkSaveRequest extends APIRequest {
|
export interface FileTalkSaveRequest extends APIRequest {
|
||||||
userSeq: string;
|
userSeq: number;
|
||||||
deviceType: DeviceType;
|
deviceType: DeviceType;
|
||||||
token: string;
|
token: string;
|
||||||
file?: File;
|
file: File;
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
|
fileUploadItem: FileUploadItem;
|
||||||
thumb?: File;
|
thumb?: File;
|
||||||
voice?: boolean;
|
voice?: boolean;
|
||||||
voiceTime?: string;
|
voiceTime?: string;
|
||||||
roomId?: string;
|
roomSeq?: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileTalkSaveResponse extends APIResponse {
|
export interface FileTalkSaveResponse extends APIResponse {
|
||||||
roomID?: string;
|
roomSeq?: string;
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
fileExt?: string;
|
fileExt?: string;
|
||||||
fileType?: string;
|
fileType?: string;
|
||||||
|
@ -49,19 +52,21 @@ const fileTalkSaveEncodeMap = {
|
||||||
thumb: 'thumb',
|
thumb: 'thumb',
|
||||||
voice: 'p_voice',
|
voice: 'p_voice',
|
||||||
voiceTime: 'p_voice_time',
|
voiceTime: 'p_voice_time',
|
||||||
roomId: 'p_room_id',
|
roomSeq: 'p_room_id',
|
||||||
type: 'p_type'
|
type: 'p_type'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const encodeFileTalkSave: APIEncoder<FileTalkSaveRequest> = (
|
export const encodeFileTalkSave: APIFormDataEncoder<FileTalkSaveRequest> = (
|
||||||
req: FileTalkSaveRequest
|
req: FileTalkSaveRequest
|
||||||
) => {
|
) => {
|
||||||
const extraParams: any = {};
|
const extraParams: any = {};
|
||||||
|
|
||||||
|
extraParams.userSeq = String(req.userSeq);
|
||||||
if (!!req.voice) {
|
if (!!req.voice) {
|
||||||
extraParams.voice = req.voice ? 'Y' : 'N';
|
extraParams.voice = req.voice ? 'Y' : 'N';
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParameterUtil.encode(fileTalkSaveEncodeMap, req, extraParams);
|
return ParameterUtil.encodeFormData(fileTalkSaveEncodeMap, req, extraParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const decodeFileTalkSave: APIDecoder<FileTalkSaveResponse> = (
|
export const decodeFileTalkSave: APIDecoder<FileTalkSaveResponse> = (
|
||||||
|
@ -71,7 +76,7 @@ export const decodeFileTalkSave: APIDecoder<FileTalkSaveResponse> = (
|
||||||
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
|
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
|
||||||
return {
|
return {
|
||||||
statusCode: json.StatusCode,
|
statusCode: json.StatusCode,
|
||||||
roomID: json.RoomID,
|
roomSeq: json.RoomID,
|
||||||
fileName: json.FileName,
|
fileName: json.FileName,
|
||||||
fileExt: json.FileExt,
|
fileExt: json.FileExt,
|
||||||
fileType: json.FileType,
|
fileType: json.FileType,
|
||||||
|
|
|
@ -4,32 +4,43 @@ import {
|
||||||
APIResponse,
|
APIResponse,
|
||||||
APIEncoder,
|
APIEncoder,
|
||||||
APIDecoder,
|
APIDecoder,
|
||||||
ParameterUtil
|
ParameterUtil,
|
||||||
|
JsonAnalization,
|
||||||
|
StatusCode
|
||||||
} from '@ucap-webmessenger/api';
|
} from '@ucap-webmessenger/api';
|
||||||
|
import { JsonObject } from 'type-fest';
|
||||||
|
|
||||||
export interface FileTalkShareRequest extends APIRequest {
|
export interface FileTalkShareRequest extends APIRequest {
|
||||||
userSeq: string;
|
userSeq: string;
|
||||||
deviceType: DeviceType;
|
deviceType: DeviceType;
|
||||||
token: string;
|
token: string;
|
||||||
attachmentsSeq?: string;
|
attachmentsSeq?: string;
|
||||||
roomId?: string;
|
roomSeq?: string;
|
||||||
synapKey?: string;
|
synapKey?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileTalkShareResponse extends APIResponse {
|
export interface FileTalkShareResponse extends APIResponse {
|
||||||
RoomID?: string;
|
roomSeq?: string;
|
||||||
FileName?: string;
|
fileName?: string;
|
||||||
FileExt?: string;
|
fileExt?: string;
|
||||||
FileType?: string;
|
fileType?: string;
|
||||||
ThumbURL?: string;
|
thumbnailUrl?: string;
|
||||||
AttSEQ?: string;
|
attachmentSeq?: string;
|
||||||
AttSize?: string;
|
attachmentSize?: string;
|
||||||
AttRegDate?: string;
|
attachmentRegDate?: string;
|
||||||
CompanyCode?: string;
|
companyCode?: string;
|
||||||
SynapKey?: string;
|
synapKey?: string;
|
||||||
|
returnJson?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileTalkShareEncodeMap = {};
|
const fileTalkShareEncodeMap = {
|
||||||
|
userSeq: 'p_user_seq',
|
||||||
|
deviceType: 'p_device_type',
|
||||||
|
token: 'p_token',
|
||||||
|
attachmentsSeq: 'p_att_seq',
|
||||||
|
roomSeq: 'p_room_id',
|
||||||
|
synapKey: 'p_synap_key'
|
||||||
|
};
|
||||||
|
|
||||||
export const encodeFileTalkShare: APIEncoder<FileTalkShareRequest> = (
|
export const encodeFileTalkShare: APIEncoder<FileTalkShareRequest> = (
|
||||||
req: FileTalkShareRequest
|
req: FileTalkShareRequest
|
||||||
|
@ -40,5 +51,26 @@ export const encodeFileTalkShare: APIEncoder<FileTalkShareRequest> = (
|
||||||
export const decodeFileTalkShare: APIDecoder<FileTalkShareResponse> = (
|
export const decodeFileTalkShare: APIDecoder<FileTalkShareResponse> = (
|
||||||
res: any
|
res: any
|
||||||
) => {
|
) => {
|
||||||
return {} as FileTalkShareResponse;
|
try {
|
||||||
|
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
|
||||||
|
return {
|
||||||
|
statusCode: json.StatusCode,
|
||||||
|
roomSeq: json.RoomID,
|
||||||
|
fileName: json.FileName,
|
||||||
|
fileExt: json.FileExt,
|
||||||
|
fileType: json.FileType,
|
||||||
|
thumbnailUrl: json.ThumbURL,
|
||||||
|
attachmentSeq: json.AttSEQ,
|
||||||
|
attachmentSize: json.AttSize,
|
||||||
|
attachmentRegDate: json.AttRegDate,
|
||||||
|
companyCode: json.CompanyCode,
|
||||||
|
synapKey: json.SynapKey,
|
||||||
|
returnJson: res
|
||||||
|
} as FileTalkShareResponse;
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
statusCode: StatusCode.Fail,
|
||||||
|
errorMessage: e
|
||||||
|
} as FileTalkShareResponse;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ export interface MassTalkSaveRequest extends APIRequest {
|
||||||
|
|
||||||
export interface MassTalkSaveResponse extends APIResponse {
|
export interface MassTalkSaveResponse extends APIResponse {
|
||||||
eventMassSeq?: string;
|
eventMassSeq?: string;
|
||||||
roomID?: string;
|
roomSeq?: string;
|
||||||
regDate?: string;
|
regDate?: string;
|
||||||
content?: string;
|
content?: string;
|
||||||
returnJson?: any;
|
returnJson?: any;
|
||||||
|
@ -51,7 +51,7 @@ export const decodeMassTalkSave: APIDecoder<MassTalkSaveResponse> = (
|
||||||
content: json.Content,
|
content: json.Content,
|
||||||
eventMassSeq: json.EventMassSeq,
|
eventMassSeq: json.EventMassSeq,
|
||||||
regDate: json.RegDate,
|
regDate: json.RegDate,
|
||||||
roomID: json.RoomID,
|
roomSeq: json.RoomID,
|
||||||
returnJson: res
|
returnJson: res
|
||||||
} as MassTalkSaveResponse;
|
} as MassTalkSaveResponse;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -4,8 +4,11 @@ import {
|
||||||
APIResponse,
|
APIResponse,
|
||||||
APIEncoder,
|
APIEncoder,
|
||||||
APIDecoder,
|
APIDecoder,
|
||||||
ParameterUtil
|
ParameterUtil,
|
||||||
|
JsonAnalization,
|
||||||
|
StatusCode
|
||||||
} from '@ucap-webmessenger/api';
|
} from '@ucap-webmessenger/api';
|
||||||
|
import { JsonObject } from 'type-fest';
|
||||||
|
|
||||||
export interface TransMassTalkSaveRequest extends APIRequest {
|
export interface TransMassTalkSaveRequest extends APIRequest {
|
||||||
userSeq: string;
|
userSeq: string;
|
||||||
|
@ -13,20 +16,29 @@ export interface TransMassTalkSaveRequest extends APIRequest {
|
||||||
token: string;
|
token: string;
|
||||||
original?: string;
|
original?: string;
|
||||||
translation?: string;
|
translation?: string;
|
||||||
roomId?: string;
|
roomSeq?: string;
|
||||||
locale: string;
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransMassTalkSaveResponse extends APIResponse {
|
export interface TransMassTalkSaveResponse extends APIResponse {
|
||||||
EventTransSEQ?: string;
|
roomSeq?: string;
|
||||||
RoomID?: string;
|
registrationDate?: string;
|
||||||
RegDate?: string;
|
translationSeq?: string;
|
||||||
Locale?: string;
|
locale?: string;
|
||||||
Original?: string;
|
original?: string;
|
||||||
Translation?: string;
|
translation?: string;
|
||||||
|
returnJson?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transMassTalkSaveEncodeMap = {};
|
const transMassTalkSaveEncodeMap = {
|
||||||
|
userSeq: 'p_user_seq',
|
||||||
|
deviceType: 'p_device_type',
|
||||||
|
token: 'p_token',
|
||||||
|
original: 'p_original',
|
||||||
|
translation: 'p_translation',
|
||||||
|
roomSeq: 'p_room_id',
|
||||||
|
locale: 'p_locale'
|
||||||
|
};
|
||||||
|
|
||||||
export const encodeTransMassTalkSave: APIEncoder<TransMassTalkSaveRequest> = (
|
export const encodeTransMassTalkSave: APIEncoder<TransMassTalkSaveRequest> = (
|
||||||
req: TransMassTalkSaveRequest
|
req: TransMassTalkSaveRequest
|
||||||
|
@ -37,5 +49,22 @@ export const encodeTransMassTalkSave: APIEncoder<TransMassTalkSaveRequest> = (
|
||||||
export const decodeTransMassTalkSave: APIDecoder<TransMassTalkSaveResponse> = (
|
export const decodeTransMassTalkSave: APIDecoder<TransMassTalkSaveResponse> = (
|
||||||
res: any
|
res: any
|
||||||
) => {
|
) => {
|
||||||
return {} as TransMassTalkSaveResponse;
|
try {
|
||||||
|
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
|
||||||
|
return {
|
||||||
|
statusCode: json.StatusCode,
|
||||||
|
translationSeq: json.EventTransSEQ,
|
||||||
|
roomSeq: json.RoomID,
|
||||||
|
registrationDate: json.RegDate,
|
||||||
|
locale: json.Locale,
|
||||||
|
original: json.Original,
|
||||||
|
translation: json.Translation,
|
||||||
|
returnJson: res
|
||||||
|
} as TransMassTalkSaveResponse;
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
statusCode: StatusCode.Fail,
|
||||||
|
errorMessage: e
|
||||||
|
} as TransMassTalkSaveResponse;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,30 +4,42 @@ import {
|
||||||
APIResponse,
|
APIResponse,
|
||||||
APIEncoder,
|
APIEncoder,
|
||||||
APIDecoder,
|
APIDecoder,
|
||||||
ParameterUtil
|
ParameterUtil,
|
||||||
|
JsonAnalization,
|
||||||
|
StatusCode
|
||||||
} from '@ucap-webmessenger/api';
|
} from '@ucap-webmessenger/api';
|
||||||
|
import { JsonObject } from 'type-fest';
|
||||||
|
|
||||||
export interface TranslationSaveRequest extends APIRequest {
|
export interface TranslationSaveRequest extends APIRequest {
|
||||||
userSeq: string;
|
userSeq: string;
|
||||||
deviceType: DeviceType;
|
deviceType: DeviceType;
|
||||||
token: string;
|
token: string;
|
||||||
roomId?: string;
|
roomSeq?: string;
|
||||||
original?: string;
|
original?: string;
|
||||||
srcLocale: string;
|
srcLocale: string;
|
||||||
destLocale: string;
|
destLocale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TranslationSaveResponse extends APIResponse {
|
export interface TranslationSaveResponse extends APIResponse {
|
||||||
EventTransSeq?: string;
|
translationSeq?: string;
|
||||||
RoomID?: string;
|
roomSeq?: string;
|
||||||
RegDate?: string;
|
registrationDate?: string;
|
||||||
SrcLocale?: string;
|
srcLocale?: string;
|
||||||
DestLocale?: string;
|
destLocale?: string;
|
||||||
Original?: string;
|
original?: string;
|
||||||
Translation?: string;
|
translation?: string;
|
||||||
|
returnJson?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const translationSaveEncodeMap = {};
|
const translationSaveEncodeMap = {
|
||||||
|
userSeq: 'p_user_seq',
|
||||||
|
deviceType: 'p_device_type',
|
||||||
|
token: 'p_token',
|
||||||
|
roomSeq: 'p_room_id',
|
||||||
|
original: 'p_original',
|
||||||
|
srcLocale: 'p_src_locale',
|
||||||
|
destLocale: 'p_dest_locale'
|
||||||
|
};
|
||||||
|
|
||||||
export const encodeTranslationSave: APIEncoder<TranslationSaveRequest> = (
|
export const encodeTranslationSave: APIEncoder<TranslationSaveRequest> = (
|
||||||
req: TranslationSaveRequest
|
req: TranslationSaveRequest
|
||||||
|
@ -38,5 +50,23 @@ export const encodeTranslationSave: APIEncoder<TranslationSaveRequest> = (
|
||||||
export const decodeTranslationSave: APIDecoder<TranslationSaveResponse> = (
|
export const decodeTranslationSave: APIDecoder<TranslationSaveResponse> = (
|
||||||
res: any
|
res: any
|
||||||
) => {
|
) => {
|
||||||
return {} as TranslationSaveResponse;
|
try {
|
||||||
|
const json: JsonObject | Error = JsonAnalization.receiveAnalization(res);
|
||||||
|
return {
|
||||||
|
statusCode: json.StatusCode,
|
||||||
|
translationSeq: json.EventTransSEQ,
|
||||||
|
roomSeq: json.RoomID,
|
||||||
|
registrationDate: json.RegDate,
|
||||||
|
srcLocale: json.SrcLocale,
|
||||||
|
destLocale: json.DestLocale,
|
||||||
|
original: json.Original,
|
||||||
|
translation: json.Translation,
|
||||||
|
returnJson: res
|
||||||
|
} as TranslationSaveResponse;
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
statusCode: StatusCode.Fail,
|
||||||
|
errorMessage: e
|
||||||
|
} as TranslationSaveResponse;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,12 +3,11 @@ import {
|
||||||
HttpClient,
|
HttpClient,
|
||||||
HttpEventType,
|
HttpEventType,
|
||||||
HttpResponse,
|
HttpResponse,
|
||||||
HttpRequest,
|
HttpRequest
|
||||||
HttpProgressEvent
|
|
||||||
} from '@angular/common/http';
|
} from '@angular/common/http';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map, filter } from 'rxjs/operators';
|
||||||
|
|
||||||
import { _MODULE_CONFIG } from '../types/token';
|
import { _MODULE_CONFIG } from '../types/token';
|
||||||
import { ModuleConfig } from '../types/module-config';
|
import { ModuleConfig } from '../types/module-config';
|
||||||
|
@ -115,21 +114,30 @@ export class CommonApiService {
|
||||||
public fileTalkSave(
|
public fileTalkSave(
|
||||||
req: FileTalkSaveRequest,
|
req: FileTalkSaveRequest,
|
||||||
fileTalkSaveUrl?: string
|
fileTalkSaveUrl?: string
|
||||||
): Observable<FileTalkSaveResponse | HttpProgressEvent> {
|
): Observable<FileTalkSaveResponse> {
|
||||||
|
const asa = encodeFileTalkSave(req);
|
||||||
|
|
||||||
const httpReq = new HttpRequest(
|
const httpReq = new HttpRequest(
|
||||||
'POST',
|
'POST',
|
||||||
!!fileTalkSaveUrl ? fileTalkSaveUrl : this.moduleConfig.urls.fileTalkSave,
|
!!fileTalkSaveUrl ? fileTalkSaveUrl : this.moduleConfig.urls.fileTalkSave,
|
||||||
encodeFileTalkSave(req),
|
encodeFileTalkSave(req),
|
||||||
{ reportProgress: true }
|
{ reportProgress: true, responseType: 'text' as 'json' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const progress = req.fileUploadItem.uploadStart();
|
||||||
|
|
||||||
return this.httpClient.request(httpReq).pipe(
|
return this.httpClient.request(httpReq).pipe(
|
||||||
map(event => {
|
filter(event => {
|
||||||
if (event instanceof HttpResponse) {
|
if (event instanceof HttpResponse) {
|
||||||
return decodeFileTalkSave(event);
|
return true;
|
||||||
} else if (HttpEventType.UploadProgress === event.type) {
|
} else if (HttpEventType.UploadProgress === event.type) {
|
||||||
return event;
|
progress.next(Math.round((100 * event.loaded) / event.total));
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
map((event: HttpResponse<any>) => {
|
||||||
|
req.fileUploadItem.uploadComplete();
|
||||||
|
return decodeFileTalkSave(event.body);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
.current-head{
|
.current-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
h3{
|
h3 {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.btn-box{
|
.btn-box {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
@ -24,41 +24,41 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border-bottom: 1px solid #dddddd;
|
border-bottom: 1px solid #dddddd;
|
||||||
.searchbox{
|
.searchbox {
|
||||||
width:100%;
|
width: 100%;
|
||||||
height:100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::ng-deep .searchbox{
|
::ng-deep .searchbox {
|
||||||
.mat-form-field{
|
.mat-form-field {
|
||||||
display:block;
|
display: block;
|
||||||
.mat-form-field-wrapper{
|
.mat-form-field-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-bottom:0 !important;
|
padding-bottom: 0 !important;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.mat-form-field-flex{
|
.mat-form-field-flex {
|
||||||
height: 59px;
|
height: 59px;
|
||||||
padding:0 20px;
|
padding: 0 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.mat-form-field-infix{
|
.mat-form-field-infix {
|
||||||
width:100%;
|
width: 100%;
|
||||||
font-size:14px;
|
font-size: 14px;
|
||||||
border:none;
|
border: none;
|
||||||
}
|
}
|
||||||
.mat-form-field-suffix{
|
.mat-form-field-suffix {
|
||||||
.mat-icon{
|
.mat-icon {
|
||||||
line-height:24px;
|
line-height: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.mat-form-field-appearance-legacy{
|
.mat-form-field-appearance-legacy {
|
||||||
.mat-form-field-wrapper{
|
.mat-form-field-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.mat-form-field-underline{
|
.mat-form-field-underline {
|
||||||
bottom:0;
|
bottom: 0;
|
||||||
background-color: unset !important;
|
background-color: unset !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,8 @@
|
||||||
fxFlex="1 1 auto"
|
fxFlex="1 1 auto"
|
||||||
class="chat-content"
|
class="chat-content"
|
||||||
#messageBoxContainer
|
#messageBoxContainer
|
||||||
ucapUiFileUploadFor
|
ucapFileUploadFor
|
||||||
|
[fileUploadQueue]="fileUploadQueue"
|
||||||
(fileSelected)="onFileSelected($event)"
|
(fileSelected)="onFileSelected($event)"
|
||||||
(fileDragEnter)="onFileDragEnter($event)"
|
(fileDragEnter)="onFileDragEnter($event)"
|
||||||
(fileDragOver)="onFileDragOver()"
|
(fileDragOver)="onFileDragOver()"
|
||||||
|
@ -109,16 +110,11 @@
|
||||||
</ucap-chat-messages>
|
</ucap-chat-messages>
|
||||||
</perfect-scrollbar>
|
</perfect-scrollbar>
|
||||||
<!-- CHAT MESSAGES -->
|
<!-- CHAT MESSAGES -->
|
||||||
<div
|
<div class="file-drop-zone-container">
|
||||||
*ngIf="fileDragOver || (files && 0 < files.length)"
|
<ucap-file-upload-queue
|
||||||
class="file-drop-zone-container"
|
#fileUploadQueue
|
||||||
>
|
class="file-drop-zone"
|
||||||
<div class="file-drop-zone">
|
></ucap-file-upload-queue>
|
||||||
<ucap-ui-file-upload-queue
|
|
||||||
[(files)]="files"
|
|
||||||
[items]="fileItems"
|
|
||||||
></ucap-ui-file-upload-queue>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- / CHAT CONTENT -->
|
<!-- / CHAT CONTENT -->
|
||||||
|
@ -128,6 +124,7 @@
|
||||||
<!-- REPLY FORM -->
|
<!-- REPLY FORM -->
|
||||||
<ucap-chat-form
|
<ucap-chat-form
|
||||||
#chatForm
|
#chatForm
|
||||||
|
[fileUploadQueue]="fileUploadQueue"
|
||||||
(send)="onSendMessage($event)"
|
(send)="onSendMessage($event)"
|
||||||
(sendFiles)="onFileSelected($event)"
|
(sendFiles)="onFileSelected($event)"
|
||||||
></ucap-chat-form>
|
></ucap-chat-form>
|
||||||
|
@ -147,7 +144,7 @@
|
||||||
<mat-menu
|
<mat-menu
|
||||||
#messageContextMenu="matMenu"
|
#messageContextMenu="matMenu"
|
||||||
[hasBackdrop]="false"
|
[hasBackdrop]="false"
|
||||||
(ucapUiClickOutside)="messageContextMenuTrigger.closeMenu()"
|
(ucapClickOutside)="messageContextMenuTrigger.closeMenu()"
|
||||||
>
|
>
|
||||||
<ng-template matMenuContent let-message="message" let-loginRes="loginRes">
|
<ng-template matMenuContent let-message="message" let-loginRes="loginRes">
|
||||||
<ng-container *ngIf="!isRecalledMessage(message.type)">
|
<ng-container *ngIf="!isRecalledMessage(message.type)">
|
||||||
|
|
|
@ -91,15 +91,16 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: rgba(255, 255, 255, 0.95);
|
background-color: transparent;
|
||||||
|
|
||||||
.file-drop-zone {
|
.file-drop-zone {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
background-color: rgb(180, 180, 180);
|
||||||
|
|
||||||
top: 10%;
|
top: calc(100% - 200px);
|
||||||
left: 10%;
|
left: 20%;
|
||||||
width: 80%;
|
width: 60%;
|
||||||
height: 80%;
|
height: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@ import {
|
||||||
Component,
|
Component,
|
||||||
OnInit,
|
OnInit,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
AfterViewChecked,
|
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
AfterContentInit,
|
|
||||||
AfterViewInit
|
AfterViewInit
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {
|
import {
|
||||||
|
@ -18,11 +16,12 @@ import {
|
||||||
ConfirmDialogResult,
|
ConfirmDialogResult,
|
||||||
AlertDialogComponent,
|
AlertDialogComponent,
|
||||||
AlertDialogData,
|
AlertDialogData,
|
||||||
AlertDialogResult
|
AlertDialogResult,
|
||||||
|
FileUploadQueueComponent
|
||||||
} from '@ucap-webmessenger/ui';
|
} from '@ucap-webmessenger/ui';
|
||||||
import { Store, select } from '@ngrx/store';
|
import { Store, select } from '@ngrx/store';
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription, forkJoin, of } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
Info,
|
Info,
|
||||||
EventType,
|
EventType,
|
||||||
|
@ -44,7 +43,7 @@ import {
|
||||||
UserSelectDialogType
|
UserSelectDialogType
|
||||||
} from '@app/types';
|
} from '@app/types';
|
||||||
import { RoomInfo, UserInfo, RoomType } from '@ucap-webmessenger/protocol-room';
|
import { RoomInfo, UserInfo, RoomType } from '@ucap-webmessenger/protocol-room';
|
||||||
import { tap, take } from 'rxjs/operators';
|
import { tap, take, map, catchError } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
FileInfo,
|
FileInfo,
|
||||||
FormComponent as UCapUiChatFormComponent
|
FormComponent as UCapUiChatFormComponent
|
||||||
|
@ -52,7 +51,12 @@ import {
|
||||||
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
||||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||||
import { MatMenuTrigger } from '@angular/material';
|
import { MatMenuTrigger } from '@angular/material';
|
||||||
import { CommonApiService } from '@ucap-webmessenger/api-common';
|
import {
|
||||||
|
CommonApiService,
|
||||||
|
FileUploadItem,
|
||||||
|
FileTalkSaveRequest,
|
||||||
|
FileTalkSaveResponse
|
||||||
|
} from '@ucap-webmessenger/api-common';
|
||||||
import {
|
import {
|
||||||
CreateChatDialogComponent,
|
CreateChatDialogComponent,
|
||||||
CreateChatDialogData,
|
CreateChatDialogData,
|
||||||
|
@ -65,6 +69,7 @@ import {
|
||||||
} from '@app/layouts/common/dialogs/image-viewer.dialog.component';
|
} from '@app/layouts/common/dialogs/image-viewer.dialog.component';
|
||||||
import { CONST } from '@ucap-webmessenger/core';
|
import { CONST } from '@ucap-webmessenger/core';
|
||||||
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
|
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
|
||||||
|
import { StatusCode } from '@ucap-webmessenger/api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-layout-messenger-messages',
|
selector: 'app-layout-messenger-messages',
|
||||||
|
@ -86,6 +91,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
@ViewChild('psChatContent', { static: true })
|
@ViewChild('psChatContent', { static: true })
|
||||||
psChatContent: PerfectScrollbarComponent;
|
psChatContent: PerfectScrollbarComponent;
|
||||||
|
|
||||||
|
@ViewChild('fileUploadQueue', { static: true })
|
||||||
|
fileUploadQueue: FileUploadQueueComponent;
|
||||||
|
|
||||||
environmentsInfo: EnvironmentsInfo;
|
environmentsInfo: EnvironmentsInfo;
|
||||||
|
|
||||||
loginRes: LoginResponse;
|
loginRes: LoginResponse;
|
||||||
|
@ -106,10 +114,6 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
isCopyableMessage = isCopyable;
|
isCopyableMessage = isCopyable;
|
||||||
isRecallableMessage = isRecallable;
|
isRecallableMessage = isRecallable;
|
||||||
|
|
||||||
fileDragOver = false;
|
|
||||||
files: File[];
|
|
||||||
fileItems: DataTransferItemList;
|
|
||||||
|
|
||||||
/** Timer 대화방의 대화 삭제를 위한 interval */
|
/** Timer 대화방의 대화 삭제를 위한 interval */
|
||||||
interval: any;
|
interval: any;
|
||||||
|
|
||||||
|
@ -185,7 +189,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
);
|
);
|
||||||
|
|
||||||
this.interval = setInterval(() => {
|
this.interval = setInterval(() => {
|
||||||
if (!!this.roomInfo.isTimeRoom) {
|
if (!!this.roomInfo && !!this.roomInfo.isTimeRoom) {
|
||||||
this.store.dispatch(EventStore.infoIntervalClear({}));
|
this.store.dispatch(EventStore.infoIntervalClear({}));
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -369,8 +373,6 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
|
|
||||||
onFileDragEnter(items: DataTransferItemList) {
|
onFileDragEnter(items: DataTransferItemList) {
|
||||||
this.logger.debug('onFileDragEnter', items);
|
this.logger.debug('onFileDragEnter', items);
|
||||||
this.fileDragOver = true;
|
|
||||||
this.fileItems = items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFileDragOver() {
|
onFileDragOver() {
|
||||||
|
@ -379,17 +381,64 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
|
|
||||||
onFileDragLeave() {
|
onFileDragLeave() {
|
||||||
this.logger.debug('onFileDragLeave');
|
this.logger.debug('onFileDragLeave');
|
||||||
this.fileDragOver = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFileSelected(files: File[]) {
|
onFileSelected(fileUploadItems: FileUploadItem[]) {
|
||||||
this.logger.debug('onFileSelected', files);
|
this.logger.debug('onFileSelected', fileUploadItems);
|
||||||
if (!this.files) {
|
|
||||||
this.files = [];
|
|
||||||
}
|
|
||||||
this.files.push(...files);
|
|
||||||
|
|
||||||
this.fileDragOver = false;
|
const allObservables: Observable<FileTalkSaveResponse>[] = [];
|
||||||
|
|
||||||
|
for (const fileUploadItem of fileUploadItems) {
|
||||||
|
const req: FileTalkSaveRequest = {
|
||||||
|
userSeq: this.loginRes.userSeq,
|
||||||
|
deviceType: this.environmentsInfo.deviceType,
|
||||||
|
token: this.loginRes.tokenString,
|
||||||
|
roomSeq: this.roomInfo.roomSeq,
|
||||||
|
file: fileUploadItem.file,
|
||||||
|
fileName: fileUploadItem.file.name,
|
||||||
|
fileUploadItem
|
||||||
|
};
|
||||||
|
|
||||||
|
allObservables.push(
|
||||||
|
this.commonApiService
|
||||||
|
.fileTalkSave(req, this.sessionVerInfo.uploadUrl)
|
||||||
|
.pipe(
|
||||||
|
map(res => {
|
||||||
|
if (!res) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StatusCode.Success === res.statusCode) {
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
throw res;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
forkJoin(allObservables)
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe(
|
||||||
|
resList => {
|
||||||
|
for (const res of resList) {
|
||||||
|
this.store.dispatch(
|
||||||
|
EventStore.send({
|
||||||
|
senderSeq: this.loginRes.userSeq,
|
||||||
|
req: {
|
||||||
|
roomSeq: this.roomInfo.roomSeq,
|
||||||
|
eventType: EventType.File,
|
||||||
|
sentMessage: res.returnJson
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error => {},
|
||||||
|
() => {
|
||||||
|
this.fileUploadQueue.onUploadComplete();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onContextMenuMessage(params: { event: MouseEvent; message: Info }) {
|
onContextMenuMessage(params: { event: MouseEvent; message: Info }) {
|
||||||
|
|
|
@ -65,7 +65,6 @@ import {
|
||||||
cancel,
|
cancel,
|
||||||
cancelFailure,
|
cancelFailure,
|
||||||
forward,
|
forward,
|
||||||
forwardFailure,
|
|
||||||
forwardAfterRoomOpen,
|
forwardAfterRoomOpen,
|
||||||
sendMass,
|
sendMass,
|
||||||
sendMassFailure,
|
sendMassFailure,
|
||||||
|
@ -418,7 +417,7 @@ export class Effects {
|
||||||
send({
|
send({
|
||||||
senderSeq: action.senderSeq,
|
senderSeq: action.senderSeq,
|
||||||
req: {
|
req: {
|
||||||
roomSeq: res.roomID,
|
roomSeq: res.roomSeq,
|
||||||
eventType: EventType.MassText,
|
eventType: EventType.MassText,
|
||||||
sentMessage: res.returnJson
|
sentMessage: res.returnJson
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,12 @@ import {
|
||||||
Output,
|
Output,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ElementRef
|
ElementRef,
|
||||||
|
Input
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
|
import { FileUploadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
import { FileUploadQueueComponent } from '@ucap-webmessenger/ui';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-chat-form',
|
selector: 'ucap-chat-form',
|
||||||
|
@ -14,11 +17,14 @@ import { NgForm } from '@angular/forms';
|
||||||
styleUrls: ['./form.component.scss']
|
styleUrls: ['./form.component.scss']
|
||||||
})
|
})
|
||||||
export class FormComponent implements OnInit {
|
export class FormComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
fileUploadQueue: FileUploadQueueComponent;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
send = new EventEmitter<string>();
|
send = new EventEmitter<string>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
sendFiles = new EventEmitter<File[]>();
|
sendFiles = new EventEmitter<FileUploadItem[]>();
|
||||||
|
|
||||||
@ViewChild('replyForm', { static: false })
|
@ViewChild('replyForm', { static: false })
|
||||||
replyForm: NgForm;
|
replyForm: NgForm;
|
||||||
|
@ -53,6 +59,13 @@ export class FormComponent implements OnInit {
|
||||||
for (let i = 0; i < this.fileInput.nativeElement.files.length; i++) {
|
for (let i = 0; i < this.fileInput.nativeElement.files.length; i++) {
|
||||||
files.push(this.fileInput.nativeElement.files.item(i));
|
files.push(this.fileInput.nativeElement.files.item(i));
|
||||||
}
|
}
|
||||||
this.sendFiles.emit(files);
|
|
||||||
|
const fileUploadItems = FileUploadItem.fromFiles(files);
|
||||||
|
|
||||||
|
if (!!this.fileUploadQueue) {
|
||||||
|
this.fileUploadQueue.onFileSelected(fileUploadItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendFiles.emit(fileUploadItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,31 @@
|
||||||
<div
|
<div fxLayout="row wrap" fxFlex="100" class="ucap-file-upload-queue-container">
|
||||||
fxLayout="row wrap"
|
|
||||||
fxFlex="100"
|
|
||||||
class="ucap-ui-file-upload-queue-container"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
fxLayout="column"
|
fxLayout="column"
|
||||||
fxFlex="100"
|
fxFlex="100"
|
||||||
fxFlex.gt-xs="100"
|
fxFlex.gt-xs="100"
|
||||||
fxFlex.gt-md="25"
|
fxFlex.gt-md="25"
|
||||||
*ngFor="let file of uploadFiles"
|
*ngFor="let fileUploadItem of fileUploadItems"
|
||||||
>
|
>
|
||||||
<div fxLayout="row">
|
<div fxLayout="row">
|
||||||
<div>
|
<div>
|
||||||
<mat-icon>image</mat-icon>
|
<mat-icon>image</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
<div>{{ file.name }}</div>
|
<div>{{ fileUploadItem.file.name }}</div>
|
||||||
<div (click)="onClickClear(file)">
|
<!-- <div (click)="onClickClear(fileUploadItem)">
|
||||||
<mat-icon>clear</mat-icon>
|
<mat-icon>clear</mat-icon>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div fxLayout="row">
|
<div fxLayout="row">
|
||||||
<mat-progress-bar mode="determinate" value="40"> </mat-progress-bar>
|
<mat-progress-bar
|
||||||
|
mode="determinate"
|
||||||
|
[value]="fileUploadItem.uploadingProgress$ | async"
|
||||||
|
>
|
||||||
|
</mat-progress-bar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="uploadItems" fxLayout="column">
|
<div *ngIf="uploadItems" fxLayout="column">
|
||||||
<div>여기에 파일을 Drop하시면 업로드 됩니다.</div>
|
<div>여기에 파일을 Drop하시면 업로드 됩니다.</div>
|
||||||
<div>
|
<div></div>
|
||||||
<div
|
|
||||||
fxLayout="row"
|
|
||||||
fxFlex="100"
|
|
||||||
fxFlex.gt-xs="20"
|
|
||||||
fxFlex.gt-md="25"
|
|
||||||
*ngFor="let item of uploadItems"
|
|
||||||
>
|
|
||||||
<mat-icon>image</mat-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.ucap-ui-file-upload-queue-container {
|
.ucap-file-upload-queue-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,108 @@
|
||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
EventEmitter,
|
||||||
|
ElementRef,
|
||||||
|
AfterViewInit
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
|
import { FileUploadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-ui-file-upload-queue',
|
selector: 'ucap-file-upload-queue',
|
||||||
templateUrl: './file-upload-queue.component.html',
|
templateUrl: './file-upload-queue.component.html',
|
||||||
styleUrls: ['./file-upload-queue.component.scss']
|
styleUrls: ['./file-upload-queue.component.scss']
|
||||||
})
|
})
|
||||||
export class FileUploadQueueComponent implements OnInit {
|
export class FileUploadQueueComponent implements OnInit, AfterViewInit {
|
||||||
@Output()
|
fileUploadItems: FileUploadItem[];
|
||||||
filesChange = new EventEmitter<File[]>();
|
uploadItems: DataTransferItem[];
|
||||||
|
|
||||||
@Input() set files(files: File[]) {
|
constructor(
|
||||||
this.uploadFiles = files;
|
private elementRef: ElementRef<HTMLElement>,
|
||||||
this.uploadItems = undefined;
|
private logger: NGXLogger
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
this.changeStyleDisplay(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragEnter(items: DataTransferItemList): void {
|
||||||
|
if (!items || 0 === items.length) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
uploadFiles: File[];
|
|
||||||
|
|
||||||
@Input() set items(items: DataTransferItemList) {
|
|
||||||
const uploadItems: DataTransferItem[] = [];
|
const uploadItems: DataTransferItem[] = [];
|
||||||
// tslint:disable-next-line: prefer-for-of
|
// tslint:disable-next-line: prefer-for-of
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
uploadItems.push(items[i]);
|
uploadItems.push(items[i]);
|
||||||
}
|
}
|
||||||
this.uploadItems = [...uploadItems];
|
this.uploadItems = [...uploadItems];
|
||||||
|
this.changeStyleDisplay(true);
|
||||||
}
|
}
|
||||||
uploadItems: DataTransferItem[];
|
|
||||||
|
|
||||||
constructor(private logger: NGXLogger) {}
|
onDragLeave(): void {
|
||||||
|
this.changeStyleDisplay(false);
|
||||||
ngOnInit() {}
|
|
||||||
|
|
||||||
onClickClear(file: File) {
|
|
||||||
this.uploadFiles = this.uploadFiles.filter(f => {
|
|
||||||
return f.name !== file.name && f.path !== file.path;
|
|
||||||
});
|
|
||||||
this.filesChange.emit(this.uploadFiles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDrop(fileUploadItems: FileUploadItem[]) {
|
||||||
|
if (!fileUploadItems || 0 === fileUploadItems.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.fileUploadItems = fileUploadItems;
|
||||||
|
this.uploadItems = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileSelected(fileUploadItems: FileUploadItem[]): void {
|
||||||
|
if (!fileUploadItems || 0 === fileUploadItems.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.fileUploadItems = fileUploadItems;
|
||||||
|
this.uploadItems = undefined;
|
||||||
|
this.changeStyleDisplay(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
onUploadComplete(): void {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.fileUploadItems = undefined;
|
||||||
|
this.changeStyleDisplay(false);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
isEventInElement(event: DragEvent): boolean {
|
||||||
|
const rect = this.elementRef.nativeElement.getBoundingClientRect();
|
||||||
|
// const rect: DOMRect = this.elementRef.nativeElement.getBoundingClientRect();
|
||||||
|
|
||||||
|
if (
|
||||||
|
event.pageX >= rect.left &&
|
||||||
|
event.pageX <= rect.left + rect.width &&
|
||||||
|
event.pageY >= rect.top &&
|
||||||
|
event.pageY <= rect.top + rect.height
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private changeStyleDisplay(show: boolean): void {
|
||||||
|
if (show || (!!this.fileUploadItems && 0 < this.fileUploadItems.length)) {
|
||||||
|
this.elementRef.nativeElement.style.display = '';
|
||||||
|
} else {
|
||||||
|
this.elementRef.nativeElement.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// onClickClear(fileUploadItem: FileUploadItem) {
|
||||||
|
// this.fileUploadItems = this.fileUploadItems.filter(f => {
|
||||||
|
// return (
|
||||||
|
// f.file.name !== fileUploadItem.file.name &&
|
||||||
|
// f.file.path !== fileUploadItem.file.path
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// this.filesChange.emit(this.fileUploadItems);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,22 @@ import {
|
||||||
ElementRef,
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
HostListener,
|
HostListener,
|
||||||
Output
|
Output,
|
||||||
|
Input,
|
||||||
|
AfterViewInit
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
|
import { FileUploadQueueComponent } from '../components/file-upload-queue.component';
|
||||||
|
import { FileUploadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: 'input[ucapUiFileUploadFor], div[ucapUiFileUploadFor]'
|
selector: 'input[ucapFileUploadFor], div[ucapFileUploadFor]'
|
||||||
})
|
})
|
||||||
export class FileUploadForDirective {
|
export class FileUploadForDirective implements AfterViewInit {
|
||||||
|
@Input()
|
||||||
|
fileUploadQueue: FileUploadQueueComponent;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
public fileDragEnter = new EventEmitter<DataTransferItemList>();
|
public fileDragEnter = new EventEmitter<DataTransferItemList>();
|
||||||
|
|
||||||
|
@ -22,12 +29,14 @@ export class FileUploadForDirective {
|
||||||
public fileDragLeave = new EventEmitter<void>();
|
public fileDragLeave = new EventEmitter<void>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
public fileSelected = new EventEmitter<File[]>();
|
public fileSelected = new EventEmitter<FileUploadItem[]>();
|
||||||
|
|
||||||
dragOver = false;
|
dragOver = false;
|
||||||
|
|
||||||
constructor(private elementRef: ElementRef, private logger: NGXLogger) {}
|
constructor(private elementRef: ElementRef, private logger: NGXLogger) {}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {}
|
||||||
|
|
||||||
@HostListener('window:dragenter', ['$event'])
|
@HostListener('window:dragenter', ['$event'])
|
||||||
public onDragEnter(event: DragEvent): any {
|
public onDragEnter(event: DragEvent): any {
|
||||||
if (!this.isFileDrag(event.dataTransfer)) {
|
if (!this.isFileDrag(event.dataTransfer)) {
|
||||||
|
@ -37,6 +46,9 @@ export class FileUploadForDirective {
|
||||||
if (!this.dragOver) {
|
if (!this.dragOver) {
|
||||||
this.fileDragEnter.emit(event.dataTransfer.items);
|
this.fileDragEnter.emit(event.dataTransfer.items);
|
||||||
this.dragOver = true;
|
this.dragOver = true;
|
||||||
|
if (!!this.fileUploadQueue) {
|
||||||
|
this.fileUploadQueue.onDragEnter(event.dataTransfer.items);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +58,7 @@ export class FileUploadForDirective {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isEventInElement(event)) {
|
if (this.fileUploadQueue.isEventInElement(event)) {
|
||||||
event.dataTransfer.dropEffect = 'copy';
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
} else {
|
} else {
|
||||||
event.dataTransfer.dropEffect = 'none';
|
event.dataTransfer.dropEffect = 'none';
|
||||||
|
@ -63,13 +75,16 @@ export class FileUploadForDirective {
|
||||||
if (event && event.pageX === 0 && event.pageY === 0) {
|
if (event && event.pageX === 0 && event.pageY === 0) {
|
||||||
this.fileDragLeave.emit();
|
this.fileDragLeave.emit();
|
||||||
this.dragOver = false;
|
this.dragOver = false;
|
||||||
|
if (!!this.fileUploadQueue) {
|
||||||
|
this.fileUploadQueue.onDragLeave();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('change')
|
@HostListener('change')
|
||||||
public onChange(): any {
|
public onChange(): any {
|
||||||
const files = this.elementRef.nativeElement.files;
|
const files = this.elementRef.nativeElement.files;
|
||||||
this.fileSelected.emit(files);
|
this.fileSelected.emit(FileUploadItem.fromFiles(files));
|
||||||
this.elementRef.nativeElement.value = '';
|
this.elementRef.nativeElement.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,11 +94,15 @@ export class FileUploadForDirective {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const files = event.dataTransfer.files;
|
const files = event.dataTransfer.files;
|
||||||
this.fileSelected.emit(files);
|
const fileUploadItems = FileUploadItem.fromFiles(files);
|
||||||
|
this.fileSelected.emit(fileUploadItems);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.elementRef.nativeElement.value = '';
|
this.elementRef.nativeElement.value = '';
|
||||||
this.dragOver = false;
|
this.dragOver = false;
|
||||||
|
if (!!this.fileUploadQueue) {
|
||||||
|
this.fileUploadQueue.onDrop(fileUploadItems);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private isFileDrag(dataTransfer: DataTransfer): boolean {
|
private isFileDrag(dataTransfer: DataTransfer): boolean {
|
||||||
|
@ -101,18 +120,4 @@ export class FileUploadForDirective {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isEventInElement(event: DragEvent): boolean {
|
|
||||||
const rect: DOMRect = this.elementRef.nativeElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
if (
|
|
||||||
event.pageX >= rect.left &&
|
|
||||||
event.pageX <= rect.left + rect.width &&
|
|
||||||
event.pageY >= rect.top &&
|
|
||||||
event.pageY <= rect.top + rect.height
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user