쪽지 미리보기 중간 적용.
This commit is contained in:
parent
664a92781f
commit
e0c1e181f7
|
@ -6,7 +6,9 @@ import {
|
||||||
} from '@ucap-webmessenger/api';
|
} from '@ucap-webmessenger/api';
|
||||||
import { DeviceType } from '@ucap-webmessenger/core';
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
import { MessageType } from '../types/message.type';
|
import { MessageType } from '../types/message.type';
|
||||||
import { CategoryType } from '../types/category.type';
|
import { MessageDetailInfo } from '../models/message-list';
|
||||||
|
import { DetailContent } from '../models/detail-content';
|
||||||
|
import { DetailReceiver } from '../models/detail-receiver';
|
||||||
|
|
||||||
export interface DetailRequest extends APIRequest {
|
export interface DetailRequest extends APIRequest {
|
||||||
userSeq: number;
|
userSeq: number;
|
||||||
|
@ -18,32 +20,11 @@ export interface DetailRequest extends APIRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DetailResponse extends MessageAPIResponse {
|
export interface DetailResponse extends MessageAPIResponse {
|
||||||
msgInfo: {
|
msgInfo: MessageDetailInfo;
|
||||||
msgId: number;
|
|
||||||
category: CategoryType;
|
|
||||||
title: string;
|
|
||||||
titleYn: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
content: {
|
contents: DetailContent[];
|
||||||
type: MessageType;
|
|
||||||
sendUserSeq: number;
|
|
||||||
sendUserName: string;
|
|
||||||
reservationTime: string | null;
|
|
||||||
sendYn: boolean;
|
|
||||||
regDate: string;
|
|
||||||
attachmentYn: boolean;
|
|
||||||
smsYn: boolean;
|
|
||||||
fileAllow: string;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
recvList: {
|
recvList: DetailReceiver[];
|
||||||
userSeq: number;
|
|
||||||
userName: string;
|
|
||||||
cancelYn: boolean;
|
|
||||||
readDate: string;
|
|
||||||
readYn: boolean;
|
|
||||||
}[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const encodeDetail: APIJsonEncoder<DetailRequest> = (
|
export const encodeDetail: APIJsonEncoder<DetailRequest> = (
|
||||||
|
@ -53,15 +34,50 @@ export const encodeDetail: APIJsonEncoder<DetailRequest> = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const decodeDetail: APIDecoder<DetailResponse> = (res: any) => {
|
export const decodeDetail: APIDecoder<DetailResponse> = (res: any) => {
|
||||||
|
let msgInfo: MessageDetailInfo = null;
|
||||||
|
const contents: DetailContent[] = [];
|
||||||
|
const recvList: DetailReceiver[] = [];
|
||||||
|
if (!!res.msgInfo) {
|
||||||
|
// msgInfo
|
||||||
|
msgInfo = {
|
||||||
|
...res.msgInfo,
|
||||||
|
|
||||||
|
titleYn: res.msgInfo.titleYn === 'Y' ? true : false,
|
||||||
|
attachmentYn: res.msgInfo.attachmentYn === 'Y' ? true : false,
|
||||||
|
smsYn: res.msgInfo.smsYn === 'Y' ? true : false
|
||||||
|
};
|
||||||
|
|
||||||
|
// contents
|
||||||
|
if (!!res.msgInfo.content && res.msgInfo.content.length > 0) {
|
||||||
|
for (const content of res.msgInfo.content) {
|
||||||
|
contents.push({
|
||||||
|
...content,
|
||||||
|
|
||||||
|
activeYn: content.activeYn === 'Y' ? true : false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// receiver
|
||||||
|
if (!!res.recvList && res.recvList.length > 0) {
|
||||||
|
for (const recv of res.recvList) {
|
||||||
|
recvList.push({
|
||||||
|
...recv,
|
||||||
|
|
||||||
|
cancelYn: recv.cancelYn === 'Y' ? true : false,
|
||||||
|
readYn: recv.readYn === 'Y' ? true : false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
responseCode: res.responseCode,
|
responseCode: res.responseCode,
|
||||||
responseMsg: res.responseMsg,
|
responseMsg: res.responseMsg,
|
||||||
|
|
||||||
msgInfo: null,
|
msgInfo,
|
||||||
|
contents,
|
||||||
content: [],
|
recvList
|
||||||
|
|
||||||
recvList: []
|
|
||||||
} as DetailResponse;
|
} as DetailResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { ContentType } from '../types/content.type';
|
||||||
|
|
||||||
|
export interface DetailContent {
|
||||||
|
// text default
|
||||||
|
activeYn: boolean;
|
||||||
|
resSeq: number;
|
||||||
|
resUrl: string;
|
||||||
|
resContent: string;
|
||||||
|
resType: ContentType;
|
||||||
|
resSize: number;
|
||||||
|
|
||||||
|
// attach file default
|
||||||
|
companyCode?: string;
|
||||||
|
synapKey?: string;
|
||||||
|
|
||||||
|
// image default
|
||||||
|
resResolution?: string;
|
||||||
|
thumbnailNm?: string;
|
||||||
|
thumbnailSeq?: number;
|
||||||
|
thumbnailUrl?: string;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export interface DetailReceiver {
|
||||||
|
userSeq: number;
|
||||||
|
userName: string;
|
||||||
|
cancelYn: boolean;
|
||||||
|
readDate: string;
|
||||||
|
readYn: boolean;
|
||||||
|
}
|
|
@ -32,3 +32,10 @@ export interface MessageList {
|
||||||
/** 읽음여부 */
|
/** 읽음여부 */
|
||||||
readYn?: boolean;
|
readYn?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MessageDetailInfo extends MessageList {
|
||||||
|
sendUserSeq: number;
|
||||||
|
sendUserName: string;
|
||||||
|
smsYn?: boolean;
|
||||||
|
fileAllow?: string;
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
import { Injectable, Inject } from '@angular/core';
|
import { Injectable, Inject } from '@angular/core';
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import {
|
||||||
|
HttpClient,
|
||||||
|
HttpHeaders,
|
||||||
|
HttpRequest,
|
||||||
|
HttpResponse
|
||||||
|
} 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 '../config/token';
|
import { _MODULE_CONFIG } from '../config/token';
|
||||||
import { ModuleConfig } from '../config/module-config';
|
import { ModuleConfig } from '../config/module-config';
|
||||||
|
@ -203,16 +208,47 @@ export class MessageApiService {
|
||||||
}
|
}
|
||||||
public retrieveResourceFile(
|
public retrieveResourceFile(
|
||||||
req: RetrieveResourceFileRequest
|
req: RetrieveResourceFileRequest
|
||||||
): Observable<RetrieveResourceFileResponse> {
|
): Observable<Blob> {
|
||||||
return this.httpClient
|
const httpReq = new HttpRequest(
|
||||||
.post<any>(
|
'POST',
|
||||||
|
this.urls.retrieveResourceFile,
|
||||||
|
encodeRetrieveResourceFile(req),
|
||||||
|
{
|
||||||
|
headers: this.headers,
|
||||||
|
responseType: 'blob'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return this.httpClient.request(httpReq).pipe(
|
||||||
|
filter(event => {
|
||||||
|
if (event instanceof HttpResponse) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
map((event: HttpResponse<any>) => {
|
||||||
|
return event.body;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// return this.httpClient
|
||||||
|
// .post<any>(
|
||||||
|
// this.urls.retrieveResourceFile,
|
||||||
|
// encodeRetrieveResourceFile(req),
|
||||||
|
// {
|
||||||
|
// headers: this.headers
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// .pipe(map(res => decodeRetrieveResourceFile(res)));
|
||||||
|
}
|
||||||
|
public urlForFileMessageDownload(req: RetrieveResourceFileRequest): string {
|
||||||
|
const httpReq = new HttpRequest(
|
||||||
|
'POST',
|
||||||
this.urls.retrieveResourceFile,
|
this.urls.retrieveResourceFile,
|
||||||
encodeRetrieveResourceFile(req),
|
encodeRetrieveResourceFile(req),
|
||||||
{
|
{
|
||||||
headers: this.headers
|
headers: this.headers
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
.pipe(map(res => decodeRetrieveResourceFile(res)));
|
return httpReq.urlWithParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** del */
|
/** del */
|
||||||
|
|
|
@ -13,6 +13,8 @@ export * from './lib/services/message-api.service';
|
||||||
|
|
||||||
export * from './lib/ucap-message-api.module';
|
export * from './lib/ucap-message-api.module';
|
||||||
|
|
||||||
|
export * from './lib/models/detail-receiver';
|
||||||
|
export * from './lib/models/detail-content';
|
||||||
export * from './lib/models/message-list';
|
export * from './lib/models/message-list';
|
||||||
|
|
||||||
export * from './lib/types/category.type';
|
export * from './lib/types/category.type';
|
||||||
|
|
|
@ -89,7 +89,16 @@
|
||||||
<mat-tab [aria-label]="MainMenu.Message">
|
<mat-tab [aria-label]="MainMenu.Message">
|
||||||
<ng-template mat-tab-label>
|
<ng-template mat-tab-label>
|
||||||
<!--<mat-icon>device_hub</mat-icon>-->
|
<!--<mat-icon>device_hub</mat-icon>-->
|
||||||
<div class="icon-item" matTooltip="Message" matTooltipPosition="after">
|
<div
|
||||||
|
class="icon-item"
|
||||||
|
[matBadgeHidden]="badgeMessageUnReadCount <= 0"
|
||||||
|
[matBadge]="badgeMessageUnReadCount"
|
||||||
|
matBadgeDescription="확인하지 않은 메시지가 있습니다."
|
||||||
|
matBadgeColor="accent"
|
||||||
|
matBadgePosition="above after"
|
||||||
|
matTooltip="Message"
|
||||||
|
matTooltipPosition="after"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="24"
|
width="24"
|
||||||
|
@ -191,6 +200,7 @@
|
||||||
>
|
>
|
||||||
<app-layout-chat-left-sidenav-message
|
<app-layout-chat-left-sidenav-message
|
||||||
[isVisible]="currentTabLable === MainMenu.Message"
|
[isVisible]="currentTabLable === MainMenu.Message"
|
||||||
|
(doRefreshUnReadCount)="getMessageUnreadCount()"
|
||||||
></app-layout-chat-left-sidenav-message>
|
></app-layout-chat-left-sidenav-message>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
CreateChatDialogData,
|
CreateChatDialogData,
|
||||||
CreateChatDialogResult
|
CreateChatDialogResult
|
||||||
} from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component';
|
} from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription, of } from 'rxjs';
|
||||||
import { Store, select } from '@ngrx/store';
|
import { Store, select } from '@ngrx/store';
|
||||||
|
|
||||||
import * as AppStore from '@app/store';
|
import * as AppStore from '@app/store';
|
||||||
|
@ -35,6 +35,11 @@ import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
||||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||||
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
||||||
|
import { MessageApiService } from '@ucap-webmessenger/api-message';
|
||||||
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
|
import { UnreadCountRequest } from 'projects/ucap-webmessenger-api-message/src/lib/apis/unread-count';
|
||||||
|
import { map, catchError } from 'rxjs/operators';
|
||||||
|
import { MessageStatusCode } from '@ucap-webmessenger/api';
|
||||||
|
|
||||||
export enum MainMenu {
|
export enum MainMenu {
|
||||||
Group = 'GROUP',
|
Group = 'GROUP',
|
||||||
|
@ -62,6 +67,9 @@ export class LeftSideComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
badgeChatUnReadCount: number;
|
badgeChatUnReadCount: number;
|
||||||
badgeChatUnReadCountSubscription: Subscription;
|
badgeChatUnReadCountSubscription: Subscription;
|
||||||
|
badgeMessageUnReadCount: number;
|
||||||
|
badgeMessageUnReadCountSubscription: Subscription;
|
||||||
|
badgeMessageInterval: any;
|
||||||
|
|
||||||
/** 조직도에서 부서원 선택 */
|
/** 조직도에서 부서원 선택 */
|
||||||
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
|
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
|
||||||
|
@ -79,6 +87,7 @@ export class LeftSideComponent implements OnInit, OnDestroy {
|
||||||
private store: Store<any>,
|
private store: Store<any>,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private sessionStorageService: SessionStorageService,
|
private sessionStorageService: SessionStorageService,
|
||||||
|
private messageApiService: MessageApiService,
|
||||||
private logger: NGXLogger
|
private logger: NGXLogger
|
||||||
) {
|
) {
|
||||||
this.loginRes = this.sessionStorageService.get<LoginResponse>(
|
this.loginRes = this.sessionStorageService.get<LoginResponse>(
|
||||||
|
@ -98,6 +107,12 @@ export class LeftSideComponent implements OnInit, OnDestroy {
|
||||||
this.badgeChatUnReadCount = count;
|
this.badgeChatUnReadCount = count;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.getMessageUnreadCount();
|
||||||
|
this.badgeMessageInterval = setInterval(
|
||||||
|
() => this.getMessageUnreadCount(),
|
||||||
|
5 * 60 * 1000
|
||||||
|
);
|
||||||
|
|
||||||
this.setFabInitial(MainMenu.Group);
|
this.setFabInitial(MainMenu.Group);
|
||||||
this.currentTabLable = MainMenu.Group;
|
this.currentTabLable = MainMenu.Group;
|
||||||
}
|
}
|
||||||
|
@ -106,6 +121,13 @@ export class LeftSideComponent implements OnInit, OnDestroy {
|
||||||
if (!!this.badgeChatUnReadCountSubscription) {
|
if (!!this.badgeChatUnReadCountSubscription) {
|
||||||
this.badgeChatUnReadCountSubscription.unsubscribe();
|
this.badgeChatUnReadCountSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
if (!!this.badgeMessageUnReadCountSubscription) {
|
||||||
|
this.badgeMessageUnReadCountSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!this.badgeMessageInterval) {
|
||||||
|
clearInterval(this.badgeMessageInterval);
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.debug('-----------------------LeftSideComponent ngOnDestroy');
|
this.logger.debug('-----------------------LeftSideComponent ngOnDestroy');
|
||||||
}
|
}
|
||||||
|
@ -314,4 +336,23 @@ export class LeftSideComponent implements OnInit, OnDestroy {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMessageUnreadCount(): void {
|
||||||
|
this.badgeMessageUnReadCountSubscription = this.messageApiService
|
||||||
|
.retrieveUnreadCount({
|
||||||
|
userSeq: this.loginRes.userSeq,
|
||||||
|
deviceType: DeviceType.PC,
|
||||||
|
tokenKey: this.loginRes.tokenString
|
||||||
|
} as UnreadCountRequest)
|
||||||
|
.pipe(
|
||||||
|
map(res => {
|
||||||
|
if (res.responseCode === MessageStatusCode.Success) {
|
||||||
|
this.badgeMessageUnReadCount = res.unreadCount;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError(error => of(this.logger.error(error)))
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,11 @@
|
||||||
수신
|
수신
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<div *ngFor="let message of messageList">
|
<div
|
||||||
|
*ngFor="let message of messageList"
|
||||||
|
(click)="onClickDetail(message)"
|
||||||
|
class="message-item"
|
||||||
|
>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
|
@ -82,7 +86,11 @@
|
||||||
발신
|
발신
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<div *ngFor="let message of messageList">
|
<div
|
||||||
|
*ngFor="let message of messageList"
|
||||||
|
(click)="onClickDetail(message)"
|
||||||
|
class="message-item"
|
||||||
|
>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
|
@ -114,7 +122,11 @@
|
||||||
예약
|
예약
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<div *ngFor="let message of messageList">
|
<div
|
||||||
|
*ngFor="let message of messageList"
|
||||||
|
(click)="onClickDetail(message)"
|
||||||
|
class="message-item"
|
||||||
|
>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
|
@ -147,7 +159,10 @@
|
||||||
<div class="search-sub">
|
<div class="search-sub">
|
||||||
<form [formGroup]="fgSearchType" class="w-100-p">
|
<form [formGroup]="fgSearchType" class="w-100-p">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-select formControlName="searchMessageType" (selectionChange)="onChangeSelection($event)">
|
<mat-select
|
||||||
|
formControlName="searchMessageType"
|
||||||
|
(selectionChange)="onChangeSelection($event)"
|
||||||
|
>
|
||||||
<mat-option [value]="MessageType.All">전체</mat-option>
|
<mat-option [value]="MessageType.All">전체</mat-option>
|
||||||
<mat-option [value]="MessageType.Receive">수신</mat-option>
|
<mat-option [value]="MessageType.Receive">수신</mat-option>
|
||||||
<mat-option [value]="MessageType.Send">발신</mat-option>
|
<mat-option [value]="MessageType.Send">발신</mat-option>
|
||||||
|
@ -171,7 +186,11 @@
|
||||||
</mat-radio-group>
|
</mat-radio-group>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div *ngFor="let message of messageList">
|
<div
|
||||||
|
*ngFor="let message of messageList"
|
||||||
|
(click)="onClickDetail(message)"
|
||||||
|
class="message-item"
|
||||||
|
>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
|
|
|
@ -65,3 +65,7 @@
|
||||||
.mat-tab-label-active {
|
.mat-tab-label-active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
import { Subscription, of } from 'rxjs';
|
import { Subscription, of } from 'rxjs';
|
||||||
import { Store, select } from '@ngrx/store';
|
import { Store, select } from '@ngrx/store';
|
||||||
import { tap, map, catchError } from 'rxjs/operators';
|
import { tap, map, catchError } from 'rxjs/operators';
|
||||||
|
import { NGXLogger } from 'ngx-logger';
|
||||||
|
|
||||||
import * as AppStore from '@app/store';
|
import * as AppStore from '@app/store';
|
||||||
|
|
||||||
|
@ -27,7 +28,8 @@ import {
|
||||||
RetrieveRequest,
|
RetrieveRequest,
|
||||||
MessageList,
|
MessageList,
|
||||||
RetrieveSearchRequest,
|
RetrieveSearchRequest,
|
||||||
MessageSearchType
|
MessageSearchType,
|
||||||
|
DetailRequest
|
||||||
} from '@ucap-webmessenger/api-message';
|
} from '@ucap-webmessenger/api-message';
|
||||||
import { DeviceType } from '@ucap-webmessenger/core';
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
import { MessageStatusCode } from '@ucap-webmessenger/api';
|
import { MessageStatusCode } from '@ucap-webmessenger/api';
|
||||||
|
@ -38,6 +40,11 @@ import {
|
||||||
MatSelectChange,
|
MatSelectChange,
|
||||||
MatRadioChange
|
MatRadioChange
|
||||||
} from '@angular/material';
|
} from '@angular/material';
|
||||||
|
import {
|
||||||
|
MessageDetailDialogComponent,
|
||||||
|
MessageDetailDialogResult,
|
||||||
|
MessageDetailDialogData
|
||||||
|
} from '../../dialogs/message/message-detail.dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-layout-chat-left-sidenav-message',
|
selector: 'app-layout-chat-left-sidenav-message',
|
||||||
|
@ -49,6 +56,9 @@ export class MessageBoxComponent
|
||||||
@Input()
|
@Input()
|
||||||
isVisible = false;
|
isVisible = false;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
doRefreshUnReadCount = new EventEmitter();
|
||||||
|
|
||||||
@ViewChild('tabs', { static: false }) tabs: MatTabGroup;
|
@ViewChild('tabs', { static: false }) tabs: MatTabGroup;
|
||||||
isInitTabs = false;
|
isInitTabs = false;
|
||||||
|
|
||||||
|
@ -85,7 +95,8 @@ export class MessageBoxComponent
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private sessionStorageService: SessionStorageService,
|
private sessionStorageService: SessionStorageService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private messageApiService: MessageApiService
|
private messageApiService: MessageApiService,
|
||||||
|
private logger: NGXLogger
|
||||||
) {
|
) {
|
||||||
this.loginRes = this.sessionStorageService.get<LoginResponse>(
|
this.loginRes = this.sessionStorageService.get<LoginResponse>(
|
||||||
KEY_LOGIN_RES_INFO
|
KEY_LOGIN_RES_INFO
|
||||||
|
@ -210,7 +221,6 @@ export class MessageBoxComponent
|
||||||
} as RetrieveSearchRequest)
|
} as RetrieveSearchRequest)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => {
|
map(res => {
|
||||||
console.log(res);
|
|
||||||
if (res.responseCode === MessageStatusCode.Success) {
|
if (res.responseCode === MessageStatusCode.Success) {
|
||||||
this.currentTotalCount = res.totalCount;
|
this.currentTotalCount = res.totalCount;
|
||||||
this.currentPage = res.pageCount;
|
this.currentPage = res.pageCount;
|
||||||
|
@ -219,7 +229,7 @@ export class MessageBoxComponent
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
catchError(error => of(console.log(error)))
|
catchError(error => of(this.logger.error(error)))
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
@ -244,7 +254,6 @@ export class MessageBoxComponent
|
||||||
} as RetrieveRequest)
|
} as RetrieveRequest)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => {
|
map(res => {
|
||||||
console.log(res);
|
|
||||||
if (res.responseCode === MessageStatusCode.Success) {
|
if (res.responseCode === MessageStatusCode.Success) {
|
||||||
this.currentTotalCount = res.totalCount;
|
this.currentTotalCount = res.totalCount;
|
||||||
this.currentPage = res.pageCount;
|
this.currentPage = res.pageCount;
|
||||||
|
@ -253,7 +262,7 @@ export class MessageBoxComponent
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
catchError(error => of(console.log(error)))
|
catchError(error => of(this.logger.error(error)))
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
@ -271,7 +280,6 @@ export class MessageBoxComponent
|
||||||
} as RetrieveRequest)
|
} as RetrieveRequest)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => {
|
map(res => {
|
||||||
console.log(res);
|
|
||||||
if (res.responseCode === MessageStatusCode.Success) {
|
if (res.responseCode === MessageStatusCode.Success) {
|
||||||
this.currentTotalCount = res.totalCount;
|
this.currentTotalCount = res.totalCount;
|
||||||
this.currentPage = res.pageCount;
|
this.currentPage = res.pageCount;
|
||||||
|
@ -280,7 +288,7 @@ export class MessageBoxComponent
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
catchError(error => of(console.log(error)))
|
catchError(error => of(this.logger.error(error)))
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
@ -298,7 +306,6 @@ export class MessageBoxComponent
|
||||||
} as RetrieveRequest)
|
} as RetrieveRequest)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => {
|
map(res => {
|
||||||
console.log(res);
|
|
||||||
if (res.responseCode === MessageStatusCode.Success) {
|
if (res.responseCode === MessageStatusCode.Success) {
|
||||||
this.currentTotalCount = res.totalCount;
|
this.currentTotalCount = res.totalCount;
|
||||||
this.currentPage = res.pageCount;
|
this.currentPage = res.pageCount;
|
||||||
|
@ -307,11 +314,51 @@ export class MessageBoxComponent
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
catchError(error => of(console.log(error)))
|
catchError(error => of(this.logger.error(error)))
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClickDetail(message: MessageList) {
|
||||||
|
this.messageApiService
|
||||||
|
.detailMessage({
|
||||||
|
userSeq: this.loginRes.userSeq,
|
||||||
|
deviceType: DeviceType.PC,
|
||||||
|
tokenKey: this.loginRes.tokenString,
|
||||||
|
type: message.type,
|
||||||
|
msgId: message.msgId
|
||||||
|
} as DetailRequest)
|
||||||
|
.pipe(
|
||||||
|
map(async res => {
|
||||||
|
if (res.responseCode === MessageStatusCode.Success) {
|
||||||
|
// Badge Refresh in case Receive Message..
|
||||||
|
if (res.msgInfo.type === MessageType.Receive) {
|
||||||
|
this.doRefreshUnReadCount.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// detail view..
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
MessageDetailDialogComponent,
|
||||||
|
MessageDetailDialogData,
|
||||||
|
MessageDetailDialogResult
|
||||||
|
>(MessageDetailDialogComponent, {
|
||||||
|
width: '600px',
|
||||||
|
data: {
|
||||||
|
detail: res,
|
||||||
|
loginRes: this.loginRes
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// if (!!result && !!result.choice && result.choice) {
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError(error => of(this.logger.error(error)))
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import { DIALOGS as CHAT_DIALOGS } from './chat';
|
import { DIALOGS as CHAT_DIALOGS } from './chat';
|
||||||
import { DIALOGS as GROUP_DIALOGS } from './group';
|
import { DIALOGS as GROUP_DIALOGS } from './group';
|
||||||
|
import { DIALOGS as MESSAGE_DIALOGS } from './message';
|
||||||
import { DIALOGS as PROFILE_DIALOGS } from './profile';
|
import { DIALOGS as PROFILE_DIALOGS } from './profile';
|
||||||
import { DIALOGS as SETTINGS_DIALOGS } from './settings';
|
import { DIALOGS as SETTINGS_DIALOGS } from './settings';
|
||||||
|
|
||||||
export const DIALOGS = [
|
export const DIALOGS = [
|
||||||
...CHAT_DIALOGS,
|
...CHAT_DIALOGS,
|
||||||
...GROUP_DIALOGS,
|
...GROUP_DIALOGS,
|
||||||
|
...MESSAGE_DIALOGS,
|
||||||
...PROFILE_DIALOGS,
|
...PROFILE_DIALOGS,
|
||||||
...SETTINGS_DIALOGS
|
...SETTINGS_DIALOGS
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { MessageDetailDialogComponent } from './message-detail.dialog.component';
|
||||||
|
|
||||||
|
export const DIALOGS = [MessageDetailDialogComponent];
|
|
@ -0,0 +1,82 @@
|
||||||
|
<mat-card class="confirm-card mat-elevation-z">
|
||||||
|
<mat-card-header>
|
||||||
|
<mat-card-title>
|
||||||
|
<ng-container [ngSwitch]="messageInfo.type">
|
||||||
|
<span *ngSwitchCase="MessageType.Receive">받은 쪽지</span>
|
||||||
|
<span *ngSwitchCase="MessageType.Send">보낸 쪽지</span>
|
||||||
|
<span *ngSwitchCase="MessageType.Reservation">예약 쪽지</span>
|
||||||
|
</ng-container>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<div fxFlex fxLayout="column" fxLayoutAlign=" stretch">
|
||||||
|
<div class="title">
|
||||||
|
{{ messageInfo.title }}
|
||||||
|
<span>
|
||||||
|
<button mat-icon-button aria-label="group menu" class="message-menu">
|
||||||
|
<mat-icon>more_vert</mat-icon>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<span *ngIf="messageInfo.type === MessageType.Receive" class="label"
|
||||||
|
>보낸사람</span
|
||||||
|
>
|
||||||
|
<span *ngIf="messageInfo.type !== MessageType.Receive" class="label"
|
||||||
|
>받는사람</span
|
||||||
|
>
|
||||||
|
<span>{{ messageInfo.sendUserName }}</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span class="label">받은시간</span>
|
||||||
|
<span>{{
|
||||||
|
messageInfo.regDate
|
||||||
|
| dateToStringFormat: 'YYYY.MM.dd (KS) a/p HH:mm'
|
||||||
|
}}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="contents">
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let cont of contents">
|
||||||
|
<pre *ngIf="cont.resType === ContentType.Text">{{
|
||||||
|
cont.resContent
|
||||||
|
}}</pre>
|
||||||
|
<img
|
||||||
|
*ngIf="cont.resType === ContentType.Image"
|
||||||
|
[src]="getThumbImage(cont)"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="attachFile && attachFile.length > 0" class="attachFile">
|
||||||
|
<div>
|
||||||
|
<div class="title">
|
||||||
|
<span *ngIf="isExpiredAttachFile">기간이 만료된 파일입니다</span>
|
||||||
|
<button mat-stroked-button class="mat-primary">
|
||||||
|
모두저장
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let file of attachFile">
|
||||||
|
<div>
|
||||||
|
<span class="mdi mdi-attachment"></span>
|
||||||
|
<span>{{ file.resContent }}</span>
|
||||||
|
<span>{{ file.resSize | ucapBytes }}</span>
|
||||||
|
<span class="mdi mdi-download"></span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-card-actions class="button-farm flex-row">
|
||||||
|
<button mat-stroked-button (click)="onClickConfirm()" class="mat-primary">
|
||||||
|
Confirm
|
||||||
|
</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
|
@ -0,0 +1,18 @@
|
||||||
|
::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;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MessageDetailDialogComponent } from './message-detail.dialog.component';
|
||||||
|
|
||||||
|
describe('app::layouts::messenger::MessageDetailDialogComponent', () => {
|
||||||
|
let component: MessageDetailDialogComponent;
|
||||||
|
let fixture: ComponentFixture<MessageDetailDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [MessageDetailDialogComponent]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MessageDetailDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,142 @@
|
||||||
|
import { Component, OnInit, Inject, ViewChild } from '@angular/core';
|
||||||
|
import {
|
||||||
|
MatDialogRef,
|
||||||
|
MAT_DIALOG_DATA,
|
||||||
|
MatSelectionList,
|
||||||
|
MatSelectionListChange
|
||||||
|
} 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
|
||||||
|
} from '@ucap-webmessenger/ui';
|
||||||
|
import { GroupDetailData, UserInfo } from '@ucap-webmessenger/protocol-sync';
|
||||||
|
import {
|
||||||
|
DetailResponse,
|
||||||
|
MessageType,
|
||||||
|
MessageList,
|
||||||
|
DetailContent,
|
||||||
|
DetailReceiver,
|
||||||
|
ContentType,
|
||||||
|
MessageDetailInfo,
|
||||||
|
MessageApiService,
|
||||||
|
RetrieveResourceFileRequest
|
||||||
|
} from '@ucap-webmessenger/api-message';
|
||||||
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
|
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||||
|
import { NGXLogger } from 'ngx-logger';
|
||||||
|
|
||||||
|
export interface MessageDetailDialogData {
|
||||||
|
detail: DetailResponse;
|
||||||
|
loginRes: LoginResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line: no-empty-interface
|
||||||
|
export interface MessageDetailDialogResult {}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-layout-messenger-message-detail',
|
||||||
|
templateUrl: './message-detail.dialog.component.html',
|
||||||
|
styleUrls: ['./message-detail.dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class MessageDetailDialogComponent implements OnInit {
|
||||||
|
messageDetail: DetailResponse;
|
||||||
|
messageInfo: MessageDetailInfo;
|
||||||
|
contents: DetailContent[] = [];
|
||||||
|
attachFile: DetailContent[] = [];
|
||||||
|
receivers: DetailReceiver[] = [];
|
||||||
|
|
||||||
|
isExpiredAttachFile = true;
|
||||||
|
|
||||||
|
MessageType = MessageType;
|
||||||
|
ContentType = ContentType;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<
|
||||||
|
MessageDetailDialogData,
|
||||||
|
MessageDetailDialogResult
|
||||||
|
>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: MessageDetailDialogData,
|
||||||
|
private messageApiService: MessageApiService,
|
||||||
|
private logger: NGXLogger,
|
||||||
|
private store: Store<any>,
|
||||||
|
private dialogService: DialogService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.messageDetail = this.data.detail;
|
||||||
|
this.messageInfo = this.messageDetail.msgInfo;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!!this.messageDetail.contents &&
|
||||||
|
this.messageDetail.contents.length > 0
|
||||||
|
) {
|
||||||
|
this.messageDetail.contents.forEach(cont => {
|
||||||
|
if (cont.resType !== ContentType.AttachFile) {
|
||||||
|
this.contents.push(cont);
|
||||||
|
} else if (cont.resType === ContentType.AttachFile) {
|
||||||
|
if (cont.activeYn) {
|
||||||
|
this.isExpiredAttachFile = false;
|
||||||
|
}
|
||||||
|
this.attachFile.push(cont);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.receivers = this.messageDetail.recvList;
|
||||||
|
}
|
||||||
|
|
||||||
|
getThumbImage(content: DetailContent): string {
|
||||||
|
console.log(
|
||||||
|
JSON.stringify({
|
||||||
|
userSeq: this.data.loginRes.userSeq,
|
||||||
|
deviceType: DeviceType.PC,
|
||||||
|
tokenKey: this.data.loginRes.tokenString,
|
||||||
|
type: this.messageInfo.type,
|
||||||
|
msgId: this.messageInfo.msgId,
|
||||||
|
resUrl: content.thumbnailUrl
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (content.resType === ContentType.Image) {
|
||||||
|
// // return this.messageApiService.urlForFileMessageDownload({
|
||||||
|
// // userSeq: this.data.loginRes.userSeq,
|
||||||
|
// // deviceType: DeviceType.PC,
|
||||||
|
// // tokenKey: this.data.loginRes.tokenString,
|
||||||
|
// // type: this.messageInfo.type,
|
||||||
|
// // msgId: this.messageInfo.msgId,
|
||||||
|
// // resUrl: content.thumbnailUrl
|
||||||
|
// // } as RetrieveResourceFileRequest);
|
||||||
|
// this.messageApiService
|
||||||
|
// .retrieveResourceFile({
|
||||||
|
// userSeq: this.data.loginRes.userSeq,
|
||||||
|
// deviceType: DeviceType.PC,
|
||||||
|
// tokenKey: this.data.loginRes.tokenString,
|
||||||
|
// type: this.messageInfo.type,
|
||||||
|
// msgId: this.messageInfo.msgId,
|
||||||
|
// resUrl: content.thumbnailUrl
|
||||||
|
// } as RetrieveResourceFileRequest)
|
||||||
|
// .pipe(
|
||||||
|
// take(1),
|
||||||
|
// map(async rawBlob => {
|
||||||
|
// console.log(rawBlob);
|
||||||
|
// return URL.createObjectURL(rawBlob);
|
||||||
|
// })
|
||||||
|
// )
|
||||||
|
// .subscribe();
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickConfirm(): void {
|
||||||
|
this.dialogRef.close({});
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,7 +78,7 @@ export class MainPageComponent implements OnInit, OnDestroy {
|
||||||
this.idleStateChangedSubscription = this.nativeService
|
this.idleStateChangedSubscription = this.nativeService
|
||||||
.idleStateChanged()
|
.idleStateChanged()
|
||||||
.subscribe(action => {
|
.subscribe(action => {
|
||||||
console.log(action);
|
this.logger.debug(action);
|
||||||
let statusType: StatusCode;
|
let statusType: StatusCode;
|
||||||
|
|
||||||
if (action === 'IDLE') {
|
if (action === 'IDLE') {
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
</ul>
|
</ul>
|
||||||
<ul *ngIf="!expired && fileInfo && fileInfo.attachmentSeq">
|
<ul *ngIf="!expired && fileInfo && fileInfo.attachmentSeq">
|
||||||
<li>
|
<li>
|
||||||
<button mat-button (click)="onClickSave()">Save</button>
|
<button mat-button (click)="onClickSave()">저장</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button mat-button (click)="onClickSaveAs()">Save As</button>
|
<button mat-button (click)="onClickSaveAs()">다른이름으로 저장</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
</ul>
|
</ul>
|
||||||
<ul *ngIf="!expired && fileInfo && fileInfo.attachmentSeq">
|
<ul *ngIf="!expired && fileInfo && fileInfo.attachmentSeq">
|
||||||
<li>
|
<li>
|
||||||
<button mat-button (click)="onClickSave()">Save</button>
|
<button mat-button (click)="onClickSave()">저장</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button mat-button (click)="onClickSaveAs()">Save As</button>
|
<button mat-button (click)="onClickSaveAs()">다른이름으로 저장</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user