스티커 기능 구현..
## issue : 스티커 해제를 위한 로직 추가 필요.
This commit is contained in:
parent
92e2ec75e4
commit
d7cec3f93f
|
@ -79,8 +79,10 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
|
#chatMenuTrigger="matMenuTrigger"
|
||||||
[matMenuTriggerFor]="contactMenu"
|
[matMenuTriggerFor]="contactMenu"
|
||||||
aria-label="more"
|
aria-label="more"
|
||||||
|
(ucapClickOutside)="chatMenuTrigger.closeMenu()"
|
||||||
>
|
>
|
||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -190,13 +192,15 @@
|
||||||
></ucap-file-upload-queue>
|
></ucap-file-upload-queue>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class="sticker-selector-container">
|
<div class="sticker-selector-container">
|
||||||
<ucap-sticker-selector
|
<ucap-sticker-selector
|
||||||
*ngIf="isShowStickerSelector"
|
*ngIf="isShowStickerSelector"
|
||||||
|
#stickerSelector
|
||||||
|
(selectedSticker)="onSelectedSticker($event)"
|
||||||
class="sticker-selector-zone"
|
class="sticker-selector-zone"
|
||||||
></ucap-sticker-selector>
|
></ucap-sticker-selector>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- / CHAT CONTENT -->
|
<!-- / CHAT CONTENT -->
|
||||||
|
|
||||||
|
@ -208,6 +212,7 @@
|
||||||
[fileUploadQueue]="fileUploadQueue"
|
[fileUploadQueue]="fileUploadQueue"
|
||||||
(send)="onSendMessage($event)"
|
(send)="onSendMessage($event)"
|
||||||
(sendFiles)="onFileSelected($event)"
|
(sendFiles)="onFileSelected($event)"
|
||||||
|
(clearView)="clearView()"
|
||||||
(toggleStickerSelector)="onShowToggleStickerSelector($event)"
|
(toggleStickerSelector)="onShowToggleStickerSelector($event)"
|
||||||
></ucap-chat-form>
|
></ucap-chat-form>
|
||||||
<!-- / REPLY FORM -->
|
<!-- / REPLY FORM -->
|
||||||
|
|
|
@ -103,16 +103,15 @@
|
||||||
|
|
||||||
.sticker-selector-container {
|
.sticker-selector-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
.sticker-selector-zone {
|
.sticker-selector-zone {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 10px 10px 0 10px;
|
padding: 10px 10px 0 10px;
|
||||||
background-color: rgb(54, 54, 54, 0.8);
|
background-color: rgba(250, 255, 255, 0.8);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ import {
|
||||||
isRecallable,
|
isRecallable,
|
||||||
InfoResponse,
|
InfoResponse,
|
||||||
EventJson,
|
EventJson,
|
||||||
FileEventJson
|
FileEventJson,
|
||||||
|
StickerEventJson
|
||||||
} from '@ucap-webmessenger/protocol-event';
|
} from '@ucap-webmessenger/protocol-event';
|
||||||
|
|
||||||
import * as AppStore from '@app/store';
|
import * as AppStore from '@app/store';
|
||||||
|
@ -78,7 +79,12 @@ import {
|
||||||
FileViewerDialogData,
|
FileViewerDialogData,
|
||||||
FileViewerDialogResult
|
FileViewerDialogResult
|
||||||
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
|
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
|
||||||
import { CONST, FileUtil } from '@ucap-webmessenger/core';
|
import {
|
||||||
|
CONST,
|
||||||
|
FileUtil,
|
||||||
|
StickerFilesInfo,
|
||||||
|
StickerUtil
|
||||||
|
} from '@ucap-webmessenger/core';
|
||||||
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
|
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
|
||||||
import { StatusCode } from '@ucap-webmessenger/api';
|
import { StatusCode } from '@ucap-webmessenger/api';
|
||||||
import {
|
import {
|
||||||
|
@ -147,7 +153,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
/** Timer 대화방의 대화 삭제를 위한 interval */
|
/** Timer 대화방의 대화 삭제를 위한 interval */
|
||||||
interval: any;
|
interval: any;
|
||||||
|
|
||||||
|
/** About Sticker */
|
||||||
isShowStickerSelector = false;
|
isShowStickerSelector = false;
|
||||||
|
selectedSticker: StickerFilesInfo;
|
||||||
|
|
||||||
snackBarPreviewEvent: MatSnackBarRef<SimpleSnackBar>;
|
snackBarPreviewEvent: MatSnackBarRef<SimpleSnackBar>;
|
||||||
|
|
||||||
|
@ -270,6 +278,15 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
// this.readyToReply();
|
// this.readyToReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 채팅방의 여러 팝업들을 닫아준다.
|
||||||
|
*/
|
||||||
|
clearView() {
|
||||||
|
// Sticker Selector Clear..
|
||||||
|
this.isShowStickerSelector = false;
|
||||||
|
this.selectedSticker = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
getRoomName() {
|
getRoomName() {
|
||||||
if (!this.roomInfo || !this.userInfoList) {
|
if (!this.roomInfo || !this.userInfoList) {
|
||||||
return '대화방명을 가져오고 있습니다..';
|
return '대화방명을 가져오고 있습니다..';
|
||||||
|
@ -468,22 +485,58 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
async onSendMessage(message: string) {
|
async onSendMessage(message: string) {
|
||||||
this.setEventMoreInit();
|
this.setEventMoreInit();
|
||||||
|
|
||||||
if (!message || message.trim().length === 0) {
|
if (!this.selectedSticker) {
|
||||||
const result = await this.dialogService.open<
|
if (!message || message.trim().length === 0) {
|
||||||
AlertDialogComponent,
|
const result = await this.dialogService.open<
|
||||||
AlertDialogData,
|
AlertDialogComponent,
|
||||||
AlertDialogResult
|
AlertDialogData,
|
||||||
>(AlertDialogComponent, {
|
AlertDialogResult
|
||||||
width: '360px',
|
>(AlertDialogComponent, {
|
||||||
data: {
|
width: '360px',
|
||||||
title: 'Alert',
|
data: {
|
||||||
message: `대화내용을 입력해주세요.`
|
title: 'Alert',
|
||||||
}
|
message: `대화내용을 입력해주세요.`
|
||||||
});
|
}
|
||||||
return;
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.trim().length > CONST.MASSTEXT_LEN) {
|
if (!!this.selectedSticker) {
|
||||||
|
// Send Sticker
|
||||||
|
if (message.trim().length > CONST.MASSTEXT_LEN) {
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
AlertDialogComponent,
|
||||||
|
AlertDialogData,
|
||||||
|
AlertDialogResult
|
||||||
|
>(AlertDialogComponent, {
|
||||||
|
width: '360px',
|
||||||
|
data: {
|
||||||
|
title: 'Alert',
|
||||||
|
message: `스티커를 포함할 경우 ${CONST.MASSTEXT_LEN}자 이상 보낼 수 없습니다.`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stickerJson: StickerEventJson = {
|
||||||
|
name: '스티커',
|
||||||
|
file: this.selectedSticker.index,
|
||||||
|
chat: message.trim()
|
||||||
|
};
|
||||||
|
this.store.dispatch(
|
||||||
|
EventStore.send({
|
||||||
|
senderSeq: this.loginRes.userSeq,
|
||||||
|
req: {
|
||||||
|
roomSeq: this.roomInfo.roomSeq,
|
||||||
|
eventType: EventType.Sticker,
|
||||||
|
sentMessage: JSON.stringify(stickerJson)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.isShowStickerSelector = false;
|
||||||
|
StickerUtil.setStickerHistory(this.selectedSticker);
|
||||||
|
} else if (message.trim().length > CONST.MASSTEXT_LEN) {
|
||||||
// MASS TEXT
|
// MASS TEXT
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
EventStore.sendMass({
|
EventStore.sendMass({
|
||||||
|
@ -523,10 +576,6 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowToggleStickerSelector() {
|
|
||||||
this.isShowStickerSelector = !this.isShowStickerSelector;
|
|
||||||
}
|
|
||||||
|
|
||||||
async onFileViewer(fileInfo: FileEventJson) {
|
async onFileViewer(fileInfo: FileEventJson) {
|
||||||
const result = await this.dialogService.open<
|
const result = await this.dialogService.open<
|
||||||
FileViewerDialogComponent,
|
FileViewerDialogComponent,
|
||||||
|
@ -558,6 +607,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
onFileDragEnter(items: DataTransferItemList) {
|
onFileDragEnter(items: DataTransferItemList) {
|
||||||
|
this.clearView();
|
||||||
this.logger.debug('onFileDragEnter', items);
|
this.logger.debug('onFileDragEnter', items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,6 +621,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
|
|
||||||
async onFileSelected(fileUploadItems: FileUploadItem[]) {
|
async onFileSelected(fileUploadItems: FileUploadItem[]) {
|
||||||
this.logger.debug('onFileSelected', fileUploadItems);
|
this.logger.debug('onFileSelected', fileUploadItems);
|
||||||
|
this.clearView();
|
||||||
|
|
||||||
const info = {
|
const info = {
|
||||||
senderSeq: this.loginRes.userSeq,
|
senderSeq: this.loginRes.userSeq,
|
||||||
|
@ -1031,4 +1082,13 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
this.openProfile.emit(userInfo);
|
this.openProfile.emit(userInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** About Sticker */
|
||||||
|
onShowToggleStickerSelector() {
|
||||||
|
this.isShowStickerSelector = !this.isShowStickerSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectedSticker(stickerInfo: StickerFilesInfo) {
|
||||||
|
this.selectedSticker = stickerInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { LocalStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
|
|
||||||
export interface StickerInfo {
|
export interface StickerInfo {
|
||||||
index: string;
|
index: string;
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -148,7 +150,13 @@ export class StickerUtil {
|
||||||
const stickerInfos: StickerInfo[] = StickerMap.filter(
|
const stickerInfos: StickerInfo[] = StickerMap.filter(
|
||||||
sticker => sticker.index === idx && sticker.useYn
|
sticker => sticker.index === idx && sticker.useYn
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!!stickerInfos && stickerInfos.length > 0) {
|
if (!!stickerInfos && stickerInfos.length > 0) {
|
||||||
|
if (idx === '00') {
|
||||||
|
// history.
|
||||||
|
stickerInfos[0].fileInfos = this.getStickerHistory();
|
||||||
|
}
|
||||||
|
|
||||||
rtnStickerList.push(stickerInfos[0]);
|
rtnStickerList.push(stickerInfos[0]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -168,4 +176,50 @@ export class StickerUtil {
|
||||||
|
|
||||||
return stickerFilesList;
|
return stickerFilesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static setStickerHistory(sticker: StickerFilesInfo) {
|
||||||
|
const localStorageService = new LocalStorageService();
|
||||||
|
const history = localStorageService.get<string[]>('ucap::Sticker_History');
|
||||||
|
|
||||||
|
if (!!history && history.length > 0) {
|
||||||
|
const stickers: string[] = [];
|
||||||
|
[sticker.index, ...history.filter(hist => hist !== sticker.index)].map(
|
||||||
|
(s, i) => {
|
||||||
|
if (i < 10) {
|
||||||
|
stickers.push(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
localStorageService.set<string[]>('ucap::Sticker_History', stickers);
|
||||||
|
} else {
|
||||||
|
localStorageService.set<string[]>('ucap::Sticker_History', [
|
||||||
|
sticker.index
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getStickerHistory(): StickerFilesInfo[] {
|
||||||
|
const rtnArray: StickerFilesInfo[] = [];
|
||||||
|
const localStorageService = new LocalStorageService();
|
||||||
|
const history = localStorageService.get<string[]>('ucap::Sticker_History');
|
||||||
|
if (!!history && history.length > 0) {
|
||||||
|
history.forEach(sticker => {
|
||||||
|
const arr: string[] = sticker.split('_');
|
||||||
|
if (arr.length === 2) {
|
||||||
|
const sInfo: StickerInfo[] = StickerMap.filter(
|
||||||
|
stickerInfo => stickerInfo.index === arr[0]
|
||||||
|
);
|
||||||
|
if (!!sInfo && sInfo.length > 0) {
|
||||||
|
rtnArray.push(
|
||||||
|
...sInfo[0].fileInfos.filter(
|
||||||
|
fileInfo => fileInfo.index === sticker
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return rtnArray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ export class FormComponent implements OnInit {
|
||||||
@Output()
|
@Output()
|
||||||
toggleStickerSelector = new EventEmitter<void>();
|
toggleStickerSelector = new EventEmitter<void>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
clearView = new EventEmitter();
|
||||||
|
|
||||||
@ViewChild('replyForm', { static: false })
|
@ViewChild('replyForm', { static: false })
|
||||||
replyForm: NgForm;
|
replyForm: NgForm;
|
||||||
|
|
||||||
|
@ -54,6 +57,7 @@ export class FormComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickFileInput() {
|
onClickFileInput() {
|
||||||
|
this.clearView.emit();
|
||||||
this.fileInput.nativeElement.click();
|
this.fileInput.nativeElement.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,39 @@
|
||||||
<p>sticker-selector works!</p>
|
<div *ngIf="currentSticker" class="selected-sticker">
|
||||||
<p *ngFor="let stickerInfo of stickerInfoList">
|
<img [src]="getStickerContentsImage(currentSticker)" />
|
||||||
{{ stickerInfo.title }}
|
</div>
|
||||||
</p>
|
<div class="sticker-selector">
|
||||||
|
<mat-tab-group
|
||||||
|
mat-stretch-tabs
|
||||||
|
animationDuration="0ms"
|
||||||
|
(selectedIndexChange)="onSelectedIndexChange($event)"
|
||||||
|
>
|
||||||
|
<mat-tab
|
||||||
|
*ngFor="let stickerInfo of stickerInfoList; let idx = index"
|
||||||
|
[aria-label]="stickerInfo.title"
|
||||||
|
>
|
||||||
|
<ng-template mat-tab-label>
|
||||||
|
<img
|
||||||
|
#stickerTitle
|
||||||
|
[matTooltip]="stickerInfo.title"
|
||||||
|
matTooltipPosition="after"
|
||||||
|
[src]="getStickerTitleImage(stickerInfo, false, idx)"
|
||||||
|
(mouseover)="
|
||||||
|
stickerTitle.src = getStickerTitleImage(stickerInfo, true, idx)
|
||||||
|
"
|
||||||
|
(mouseout)="
|
||||||
|
stickerTitle.src = getStickerTitleImage(stickerInfo, false, idx)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</ng-template>
|
||||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
|
<div
|
||||||
|
*ngFor="let sticker of stickerInfo.fileInfos"
|
||||||
|
(click)="onClickSelectSticker(sticker)"
|
||||||
|
class="sticker-item"
|
||||||
|
>
|
||||||
|
<img [src]="getStickerContentsImage(sticker)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
.sticker-selector {
|
||||||
|
height: 200px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticker-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
StickerInfo,
|
StickerInfo,
|
||||||
StickerFilesInfo,
|
StickerFilesInfo,
|
||||||
|
@ -11,12 +11,49 @@ import {
|
||||||
styleUrls: ['./sticker-selector.component.scss']
|
styleUrls: ['./sticker-selector.component.scss']
|
||||||
})
|
})
|
||||||
export class StickerSelectorComponent implements OnInit {
|
export class StickerSelectorComponent implements OnInit {
|
||||||
|
@Output()
|
||||||
|
selectedSticker = new EventEmitter<StickerFilesInfo>();
|
||||||
|
|
||||||
|
stickerBasePath = 'assets/sticker/';
|
||||||
stickerInfoList: StickerInfo[] = [];
|
stickerInfoList: StickerInfo[] = [];
|
||||||
stickerFileInfoList: StickerFilesInfo[] = [];
|
stickerFileInfoList: StickerFilesInfo[] = [];
|
||||||
|
currentSticker: StickerFilesInfo;
|
||||||
|
|
||||||
|
currentTabIndex: number;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.stickerInfoList = StickerUtil.getStickerInfoList();
|
this.stickerInfoList = StickerUtil.getStickerInfoList();
|
||||||
|
this.currentTabIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectedIndexChange(value: number) {
|
||||||
|
this.currentTabIndex = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStickerTitleImage(
|
||||||
|
stickerInfo: StickerInfo,
|
||||||
|
hover: boolean,
|
||||||
|
tabIndex: number
|
||||||
|
) {
|
||||||
|
if (this.currentTabIndex === tabIndex) {
|
||||||
|
return this.stickerBasePath + stickerInfo.iconPathOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hover) {
|
||||||
|
return this.stickerBasePath + stickerInfo.iconPath;
|
||||||
|
} else {
|
||||||
|
return this.stickerBasePath + stickerInfo.iconPathOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getStickerContentsImage(sticker: StickerFilesInfo) {
|
||||||
|
return this.stickerBasePath + sticker.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickSelectSticker(sticker: StickerFilesInfo) {
|
||||||
|
this.currentSticker = sticker;
|
||||||
|
this.selectedSticker.emit(sticker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ import {
|
||||||
import { SecondsToMinutesPipe } from './pipes/seconds-to-minutes.pipe';
|
import { SecondsToMinutesPipe } from './pipes/seconds-to-minutes.pipe';
|
||||||
import { LinkyPipe } from './pipes/linky.pipe';
|
import { LinkyPipe } from './pipes/linky.pipe';
|
||||||
import { StickerSelectorComponent } from './components/sticker-selector.component';
|
import { StickerSelectorComponent } from './components/sticker-selector.component';
|
||||||
|
import { MatTabsModule } from '@angular/material';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
FileUploadQueueComponent,
|
FileUploadQueueComponent,
|
||||||
|
@ -98,6 +99,7 @@ const SERVICES = [
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
|
MatTabsModule,
|
||||||
DragDropModule
|
DragDropModule
|
||||||
],
|
],
|
||||||
exports: [...COMPONENTS, ...DIRECTIVES, ...PIPES],
|
exports: [...COMPONENTS, ...DIRECTIVES, ...PIPES],
|
||||||
|
|
Loading…
Reference in New Issue
Block a user