스티커 기능 구현..
## issue : 스티커 해제를 위한 로직 추가 필요.
This commit is contained in:
parent
92e2ec75e4
commit
d7cec3f93f
|
@ -79,8 +79,10 @@
|
|||
|
||||
<button
|
||||
mat-icon-button
|
||||
#chatMenuTrigger="matMenuTrigger"
|
||||
[matMenuTriggerFor]="contactMenu"
|
||||
aria-label="more"
|
||||
(ucapClickOutside)="chatMenuTrigger.closeMenu()"
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
|
@ -190,13 +192,15 @@
|
|||
></ucap-file-upload-queue>
|
||||
</div>
|
||||
|
||||
<!-- <div class="sticker-selector-container">
|
||||
<div class="sticker-selector-container">
|
||||
<ucap-sticker-selector
|
||||
*ngIf="isShowStickerSelector"
|
||||
#stickerSelector
|
||||
(selectedSticker)="onSelectedSticker($event)"
|
||||
class="sticker-selector-zone"
|
||||
></ucap-sticker-selector>
|
||||
<div></div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / CHAT CONTENT -->
|
||||
|
||||
|
@ -208,6 +212,7 @@
|
|||
[fileUploadQueue]="fileUploadQueue"
|
||||
(send)="onSendMessage($event)"
|
||||
(sendFiles)="onFileSelected($event)"
|
||||
(clearView)="clearView()"
|
||||
(toggleStickerSelector)="onShowToggleStickerSelector($event)"
|
||||
></ucap-chat-form>
|
||||
<!-- / REPLY FORM -->
|
||||
|
|
|
@ -103,16 +103,15 @@
|
|||
|
||||
.sticker-selector-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
|
||||
.sticker-selector-zone {
|
||||
position: absolute;
|
||||
padding: 10px 10px 0 10px;
|
||||
background-color: rgb(54, 54, 54, 0.8);
|
||||
background-color: rgba(250, 255, 255, 0.8);
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ import {
|
|||
isRecallable,
|
||||
InfoResponse,
|
||||
EventJson,
|
||||
FileEventJson
|
||||
FileEventJson,
|
||||
StickerEventJson
|
||||
} from '@ucap-webmessenger/protocol-event';
|
||||
|
||||
import * as AppStore from '@app/store';
|
||||
|
@ -78,7 +79,12 @@ import {
|
|||
FileViewerDialogData,
|
||||
FileViewerDialogResult
|
||||
} 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 { StatusCode } from '@ucap-webmessenger/api';
|
||||
import {
|
||||
|
@ -147,7 +153,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
/** Timer 대화방의 대화 삭제를 위한 interval */
|
||||
interval: any;
|
||||
|
||||
/** About Sticker */
|
||||
isShowStickerSelector = false;
|
||||
selectedSticker: StickerFilesInfo;
|
||||
|
||||
snackBarPreviewEvent: MatSnackBarRef<SimpleSnackBar>;
|
||||
|
||||
|
@ -270,6 +278,15 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
// this.readyToReply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 채팅방의 여러 팝업들을 닫아준다.
|
||||
*/
|
||||
clearView() {
|
||||
// Sticker Selector Clear..
|
||||
this.isShowStickerSelector = false;
|
||||
this.selectedSticker = undefined;
|
||||
}
|
||||
|
||||
getRoomName() {
|
||||
if (!this.roomInfo || !this.userInfoList) {
|
||||
return '대화방명을 가져오고 있습니다..';
|
||||
|
@ -468,22 +485,58 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
async onSendMessage(message: string) {
|
||||
this.setEventMoreInit();
|
||||
|
||||
if (!message || message.trim().length === 0) {
|
||||
const result = await this.dialogService.open<
|
||||
AlertDialogComponent,
|
||||
AlertDialogData,
|
||||
AlertDialogResult
|
||||
>(AlertDialogComponent, {
|
||||
width: '360px',
|
||||
data: {
|
||||
title: 'Alert',
|
||||
message: `대화내용을 입력해주세요.`
|
||||
}
|
||||
});
|
||||
return;
|
||||
if (!this.selectedSticker) {
|
||||
if (!message || message.trim().length === 0) {
|
||||
const result = await this.dialogService.open<
|
||||
AlertDialogComponent,
|
||||
AlertDialogData,
|
||||
AlertDialogResult
|
||||
>(AlertDialogComponent, {
|
||||
width: '360px',
|
||||
data: {
|
||||
title: 'Alert',
|
||||
message: `대화내용을 입력해주세요.`
|
||||
}
|
||||
});
|
||||
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
|
||||
this.store.dispatch(
|
||||
EventStore.sendMass({
|
||||
|
@ -523,10 +576,6 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
);
|
||||
}
|
||||
|
||||
onShowToggleStickerSelector() {
|
||||
this.isShowStickerSelector = !this.isShowStickerSelector;
|
||||
}
|
||||
|
||||
async onFileViewer(fileInfo: FileEventJson) {
|
||||
const result = await this.dialogService.open<
|
||||
FileViewerDialogComponent,
|
||||
|
@ -558,6 +607,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
}
|
||||
|
||||
onFileDragEnter(items: DataTransferItemList) {
|
||||
this.clearView();
|
||||
this.logger.debug('onFileDragEnter', items);
|
||||
}
|
||||
|
||||
|
@ -571,6 +621,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
|
||||
async onFileSelected(fileUploadItems: FileUploadItem[]) {
|
||||
this.logger.debug('onFileSelected', fileUploadItems);
|
||||
this.clearView();
|
||||
|
||||
const info = {
|
||||
senderSeq: this.loginRes.userSeq,
|
||||
|
@ -1031,4 +1082,13 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
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 {
|
||||
index: string;
|
||||
title: string;
|
||||
|
@ -148,7 +150,13 @@ export class StickerUtil {
|
|||
const stickerInfos: StickerInfo[] = StickerMap.filter(
|
||||
sticker => sticker.index === idx && sticker.useYn
|
||||
);
|
||||
|
||||
if (!!stickerInfos && stickerInfos.length > 0) {
|
||||
if (idx === '00') {
|
||||
// history.
|
||||
stickerInfos[0].fileInfos = this.getStickerHistory();
|
||||
}
|
||||
|
||||
rtnStickerList.push(stickerInfos[0]);
|
||||
}
|
||||
});
|
||||
|
@ -168,4 +176,50 @@ export class StickerUtil {
|
|||
|
||||
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()
|
||||
toggleStickerSelector = new EventEmitter<void>();
|
||||
|
||||
@Output()
|
||||
clearView = new EventEmitter();
|
||||
|
||||
@ViewChild('replyForm', { static: false })
|
||||
replyForm: NgForm;
|
||||
|
||||
|
@ -54,6 +57,7 @@ export class FormComponent implements OnInit {
|
|||
}
|
||||
|
||||
onClickFileInput() {
|
||||
this.clearView.emit();
|
||||
this.fileInput.nativeElement.click();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,39 @@
|
|||
<p>sticker-selector works!</p>
|
||||
<p *ngFor="let stickerInfo of stickerInfoList">
|
||||
{{ stickerInfo.title }}
|
||||
</p>
|
||||
<div *ngIf="currentSticker" class="selected-sticker">
|
||||
<img [src]="getStickerContentsImage(currentSticker)" />
|
||||
</div>
|
||||
<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 {
|
||||
StickerInfo,
|
||||
StickerFilesInfo,
|
||||
|
@ -11,12 +11,49 @@ import {
|
|||
styleUrls: ['./sticker-selector.component.scss']
|
||||
})
|
||||
export class StickerSelectorComponent implements OnInit {
|
||||
@Output()
|
||||
selectedSticker = new EventEmitter<StickerFilesInfo>();
|
||||
|
||||
stickerBasePath = 'assets/sticker/';
|
||||
stickerInfoList: StickerInfo[] = [];
|
||||
stickerFileInfoList: StickerFilesInfo[] = [];
|
||||
currentSticker: StickerFilesInfo;
|
||||
|
||||
currentTabIndex: number;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
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 { LinkyPipe } from './pipes/linky.pipe';
|
||||
import { StickerSelectorComponent } from './components/sticker-selector.component';
|
||||
import { MatTabsModule } from '@angular/material';
|
||||
|
||||
const COMPONENTS = [
|
||||
FileUploadQueueComponent,
|
||||
|
@ -98,6 +99,7 @@ const SERVICES = [
|
|||
MatSnackBarModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
MatTabsModule,
|
||||
DragDropModule
|
||||
],
|
||||
exports: [...COMPONENTS, ...DIRECTIVES, ...PIPES],
|
||||
|
|
Loading…
Reference in New Issue
Block a user