Merge branch 'master' of http://10.81.13.221:6990/Web/next-ucap-messenger
This commit is contained in:
commit
bd7d82aba5
Binary file not shown.
Before Width: | Height: | Size: 105 KiB |
|
@ -103,10 +103,13 @@ body.theme-pink-dark {
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Define the primary, accent and warn palettes
|
// Define the primary, accent and warn palettes
|
||||||
$pink-light-theme-primary-palette: mat-palette($mat-grey,800);
|
/*$pink-light-theme-primary-palette: mat-palette($mat-grey,800);
|
||||||
//$pink-light-theme-accent-palette: mat-palette($lg-red, 400);
|
$pink-light-theme-accent-palette: mat-palette($lg-red, 400);
|
||||||
|
$pink-light-theme-warn-palette: mat-palette($mat-red);*/
|
||||||
|
|
||||||
|
$pink-light-theme-primary-palette: mat-palette($daesang-grey, 900);
|
||||||
$pink-light-theme-accent-palette: mat-palette($daesang);
|
$pink-light-theme-accent-palette: mat-palette($daesang);
|
||||||
$pink-light-theme-warn-palette: mat-palette($mat-red);
|
$pink-light-theme-warn-palette: mat-palette($mat-deep-orange);
|
||||||
|
|
||||||
|
|
||||||
// Create the Material theme object
|
// Create the Material theme object
|
||||||
|
|
|
@ -38,9 +38,7 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
::ng-deep .global-menu {
|
::ng-deep .global-menu {
|
||||||
border-right: 2px solid #4f4f4f;
|
|
||||||
.mat-tab-label-container {
|
.mat-tab-label-container {
|
||||||
background-color: #4f4f4f;
|
|
||||||
.mat-tab-list {
|
.mat-tab-list {
|
||||||
.mat-tab-labels {
|
.mat-tab-labels {
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
.current-head {
|
.current-head {
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
height: 70px;
|
|
||||||
background: #352a37;
|
|
||||||
background: -webkit-linear-gradient(to right, #352a37, #f15f79);
|
|
||||||
background: linear-gradient(to right, #352a37, #ef4c73);
|
|
||||||
h3 {
|
h3 {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
|
@ -76,9 +69,17 @@
|
||||||
|
|
||||||
.app-layout-chat-left-sidenav-chat-list {
|
.app-layout-chat-left-sidenav-chat-list {
|
||||||
height: calc(100% - 130px);
|
height: calc(100% - 130px);
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-layout-chat-left-sidenav-chat-list-viewport {
|
.app-layout-chat-left-sidenav-chat-list-viewport {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
::ng-deep .cdk-virtual-scroll-orientation-vertical {
|
||||||
|
.cdk-virtual-scroll-content-wrapper{
|
||||||
|
width: 100%;
|
||||||
|
height:100%;
|
||||||
|
contain: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
@charset 'utf-8';
|
@charset 'utf-8';
|
||||||
.current-head {
|
.current-head {
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
height: 70px;
|
|
||||||
background-color: #eeeeee;
|
|
||||||
background: #f15f79;
|
|
||||||
background: -webkit-linear-gradient(to right, #352a37, #f15f79);
|
|
||||||
background: linear-gradient(to right, #352a37, #ef4c73);
|
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
h3 {
|
h3 {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
|
@ -298,6 +298,12 @@ export class GroupComponent implements OnInit, OnDestroy {
|
||||||
userInfo
|
userInfo
|
||||||
);
|
);
|
||||||
switch (menuType) {
|
switch (menuType) {
|
||||||
|
case 'VIEW_PROFILE':
|
||||||
|
this.openProfile.emit(userInfo);
|
||||||
|
break;
|
||||||
|
case 'CHAT':
|
||||||
|
this.onSelectBuddy(userInfo);
|
||||||
|
break;
|
||||||
case 'REGISTER_FAVORITE':
|
case 'REGISTER_FAVORITE':
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
SyncStore.updateBuddy({
|
SyncStore.updateBuddy({
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-head {
|
.current-head {
|
||||||
display: flex;
|
/*display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
background: #f15f79;
|
background: #f15f79;
|
||||||
background: -webkit-linear-gradient(to right, #352a37, #f15f79);
|
background: -webkit-linear-gradient(to right, #352a37, #f15f79);
|
||||||
background: linear-gradient(to right, #352a37, #ef4c73);
|
background: linear-gradient(to right, #352a37, #ef4c73);
|
||||||
color: #ffffff;
|
color: #ffffff;*/
|
||||||
h3 {
|
h3 {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
|
@ -83,6 +83,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
dt {
|
dt {
|
||||||
|
font-weight:600;
|
||||||
}
|
}
|
||||||
dd {
|
dd {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
|
@ -160,6 +160,14 @@
|
||||||
class="file-drop-zone"
|
class="file-drop-zone"
|
||||||
></ucap-file-upload-queue>
|
></ucap-file-upload-queue>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="sticker-selector-container">
|
||||||
|
<ucap-sticker-selector
|
||||||
|
*ngIf="isShowStickerSelector"
|
||||||
|
class="sticker-selector-zone"
|
||||||
|
></ucap-sticker-selector>
|
||||||
|
<div></div>
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<!-- / CHAT CONTENT -->
|
<!-- / CHAT CONTENT -->
|
||||||
|
|
||||||
|
@ -171,6 +179,7 @@
|
||||||
[fileUploadQueue]="fileUploadQueue"
|
[fileUploadQueue]="fileUploadQueue"
|
||||||
(send)="onSendMessage($event)"
|
(send)="onSendMessage($event)"
|
||||||
(sendFiles)="onFileSelected($event)"
|
(sendFiles)="onFileSelected($event)"
|
||||||
|
(toggleStickerSelector)="onShowToggleStickerSelector($event)"
|
||||||
></ucap-chat-form>
|
></ucap-chat-form>
|
||||||
<!-- / REPLY FORM -->
|
<!-- / REPLY FORM -->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #ffffff !important;
|
background-color: #ffffff !important;
|
||||||
border-bottom: 1px solid #dddddd;
|
border-bottom: 1px solid #dddddd;
|
||||||
box-shadow: 0 3px 6px rgba(0,0,0,.16);
|
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
|
||||||
.chat-header {
|
.chat-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -45,7 +45,6 @@
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #604850;
|
|
||||||
color: #efefef;
|
color: #efefef;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
|
@ -95,9 +94,27 @@
|
||||||
|
|
||||||
.file-drop-zone {
|
.file-drop-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: rgb(54, 54, 54, 0.8);
|
||||||
bottom:0
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticker-selector-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 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);
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,8 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
/** Timer 대화방의 대화 삭제를 위한 interval */
|
/** Timer 대화방의 대화 삭제를 위한 interval */
|
||||||
interval: any;
|
interval: any;
|
||||||
|
|
||||||
|
isShowStickerSelector = false;
|
||||||
|
|
||||||
snackBarPreviewEvent: MatSnackBarRef<SimpleSnackBar>;
|
snackBarPreviewEvent: MatSnackBarRef<SimpleSnackBar>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -484,6 +486,10 @@ 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,
|
||||||
|
|
|
@ -6,8 +6,33 @@
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
</div>
|
</div>
|
||||||
<div fxFlex="1 1 240px" class="select-filebox bg-accent-brightest">
|
<div fxFlex="1 1 240px" class="select-filebox bg-accent-brightest">
|
||||||
|
<!--<ng-container *ngIf="!selectedFile">-->
|
||||||
<ng-container *ngIf="!selectedFile">
|
<ng-container *ngIf="!selectedFile">
|
||||||
Select File.
|
<!--이미지 빈화면-->
|
||||||
|
<div class="empty-msg">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
||||||
|
<circle cx="8.5" cy="8.5" r="1.5" />
|
||||||
|
<path d="M20.4 14.5L16 10 4 20" />
|
||||||
|
</svg>
|
||||||
|
<span>Select File.</span>
|
||||||
|
</div>
|
||||||
|
<!--비디오 빈화면-->
|
||||||
|
<div class="empty-msg">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<rect x="2" y="2" width="20" height="20" rx="2.18" ry="2.18"></rect>
|
||||||
|
<line x1="7" y1="2" x2="7" y2="22"></line>
|
||||||
|
<line x1="17" y1="2" x2="17" y2="22"></line>
|
||||||
|
<line x1="2" y1="12" x2="22" y2="12"></line>
|
||||||
|
<line x1="2" y1="7" x2="7" y2="7"></line>
|
||||||
|
<line x1="2" y1="17" x2="7" y2="17"></line>
|
||||||
|
<line x1="17" y1="17" x2="22" y2="17"></line>
|
||||||
|
<line x1="17" y1="7" x2="22" y2="7"></line>
|
||||||
|
</svg>
|
||||||
|
<span>Select File.</span>
|
||||||
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="selectedFile">
|
<ng-container *ngIf="selectedFile">
|
||||||
<div class="select-file">
|
<div class="select-file">
|
||||||
|
@ -25,10 +50,10 @@
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li>name : {{ selectedFile.info.name }}</li>
|
<li class="name"> {{ selectedFile.info.name }}</li>
|
||||||
<li>size : {{ selectedFile.info.size | ucapBytes }}</li>
|
<li><span class="text-accent-color">size :</span> {{ selectedFile.info.size | ucapBytes }}</li>
|
||||||
<li>
|
<li>
|
||||||
date :
|
<span class="text-accent-color">date :</span>
|
||||||
{{ selectedFile.info.sendDate | dateToStringFormat: 'YYYY.MM.DD' }}
|
{{ selectedFile.info.sendDate | dateToStringFormat: 'YYYY.MM.DD' }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
@mixin ellipsis($row) {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
@if $row == 1 {
|
||||||
|
display: block;
|
||||||
|
white-space: nowrap;
|
||||||
|
word-wrap: normal;
|
||||||
|
} @else if $row >= 2 {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: $row;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.album-box {
|
.album-box {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -17,22 +32,32 @@
|
||||||
margin:10px;
|
margin:10px;
|
||||||
padding:10px;
|
padding:10px;
|
||||||
border:1px solid #cccccc;
|
border:1px solid #cccccc;
|
||||||
.select-flie{
|
.select-file{
|
||||||
display: flex;
|
|
||||||
flex-flow: row;
|
|
||||||
align-items: center;
|
|
||||||
color: #212121;
|
color: #212121;
|
||||||
align-items: center;
|
|
||||||
border-bottom: 1px dotted #dddddd;
|
border-bottom: 1px dotted #dddddd;
|
||||||
text-align:center;
|
text-align:center;
|
||||||
|
padding-bottom:10px;
|
||||||
|
}
|
||||||
ul{
|
ul{
|
||||||
padding:0;
|
padding-top:10px;
|
||||||
margin-top:10px;
|
li{
|
||||||
.name{
|
@include ellipsis(1);
|
||||||
|
&.name{
|
||||||
font-weight:600;
|
font-weight:600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.empty-msg{
|
||||||
|
display:inline-flex;
|
||||||
|
flex-flow: column;
|
||||||
|
margin:auto 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color:#999999;
|
||||||
|
span{
|
||||||
|
padding:6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-list{
|
.search-list{
|
||||||
|
@ -41,11 +66,12 @@
|
||||||
height: calc(100% - 450px);
|
height: calc(100% - 450px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
|
||||||
.img-item {
|
.img-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-bottom:10px;
|
margin-bottom:10px;
|
||||||
|
margin-right:9px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
height: 150px;
|
||||||
dl{
|
dl{
|
||||||
dt{
|
dt{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -55,6 +81,7 @@
|
||||||
height: 120px;
|
height: 120px;
|
||||||
background-color: #efefef;
|
background-color: #efefef;
|
||||||
border: 1px dotted #cccccc;
|
border: 1px dotted #cccccc;
|
||||||
|
box-sizing: border-box;
|
||||||
img{
|
img{
|
||||||
width:100%;
|
width:100%;
|
||||||
height:100%;
|
height:100%;
|
||||||
|
@ -66,14 +93,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
& :nth-child(3n+0){
|
&:nth-child(3n+0){
|
||||||
margin-right:0;
|
margin-right:0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-image {
|
.preview-image,
|
||||||
max-height: 300px;
|
.preview-video{
|
||||||
|
max-height: 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-box {
|
.btn-box {
|
||||||
|
|
|
@ -7,7 +7,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div fxFlex="1 1 200px" class="select-filebox bg-accent-brightest">
|
<div fxFlex="1 1 200px" class="select-filebox bg-accent-brightest">
|
||||||
<ng-container *ngIf="!selectedFile" >
|
<ng-container *ngIf="!selectedFile" >
|
||||||
Select File.
|
<div class="empty-msg">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<path d="M13 2H6a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V9l-7-7z" />
|
||||||
|
<path d="M13 3v6h6" /></svg>
|
||||||
|
<span>Select File.</span>
|
||||||
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="selectedFile">
|
<ng-container *ngIf="selectedFile">
|
||||||
<div class="select-flie">
|
<div class="select-flie">
|
||||||
|
@ -21,7 +27,7 @@
|
||||||
<div class="ico"></div>
|
<div class="ico"></div>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="name">name : {{ selectedFile.info.name }}</li>
|
<li class="name"> {{ selectedFile.info.name }}</li>
|
||||||
<li>size : {{ selectedFile.info.size | ucapBytes }}</li>
|
<li>size : {{ selectedFile.info.size | ucapBytes }}</li>
|
||||||
<li>
|
<li>
|
||||||
date :
|
date :
|
||||||
|
@ -29,8 +35,35 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="select-file-option">
|
||||||
아이콘
|
<!--툴팁 부탁해요 -->
|
||||||
|
<span matTooltip="다운로드" class="text-accent-darkest">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5" /></svg>
|
||||||
|
</span>
|
||||||
|
<span matTooltip="나에게전달" class="text-accent-darkest">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<path d="M5.52 19c.64-2.2 1.84-3 3.22-3h6.52c1.38 0 2.58.8 3.22 3" />
|
||||||
|
<circle cx="12" cy="10" r="3" />
|
||||||
|
<circle cx="12" cy="12" r="10" /></svg>
|
||||||
|
</span>
|
||||||
|
<span matTooltip="파일전달" class="text-accent-darkest">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M18 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h5M15 3h6v6M10 14L20.2 3.8" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span matTooltip="파일삭제" class="text-accent-darkest">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
||||||
|
<path d="M20 11.08V8l-6-6H6a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h6" />
|
||||||
|
<path d="M14 3v5h5M15.88 20.12l4.24-4.24M15.88 15.88l4.24 4.24" /></svg>
|
||||||
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-filebox {
|
.select-filebox {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #cccccc;
|
border: 1px solid #cccccc;
|
||||||
.select-flie {
|
.select-flie {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #212121;
|
color: #212121;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: 10px;
|
||||||
border-bottom: 1px dotted #dddddd;
|
border-bottom: 1px dotted #dddddd;
|
||||||
ul {
|
ul {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -47,6 +48,43 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.empty-msg {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-flow: column;
|
||||||
|
margin: auto 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #999999;
|
||||||
|
span {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.select-file-option {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
bottom: 4px;
|
||||||
|
span {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: inline-flex;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
svg {
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #999999;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-table {
|
.mat-table {
|
||||||
|
@ -75,7 +113,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.table-box{
|
.table-box {
|
||||||
height: calc(100% - 450px);
|
height: calc(100% - 450px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
@ -89,13 +127,14 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-fix{
|
.footer-fix {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height:160px;
|
height: 160px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
border-top: 1px solid #dddddd;
|
||||||
.btn-box {
|
.btn-box {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
@ -128,3 +167,8 @@
|
||||||
order: 5;
|
order: 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
::ng-deep .mat-form-field-appearance-legacy {
|
||||||
|
.mat-form-field-infix {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@import "../../../../../../../ucap-webmessenger-ui/src/assets/scss/partials/presence";
|
||||||
.list {
|
.list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.mat-tab-group > .mat-tab-header .mat-tab-label {
|
::ng-deep .mat-card > .mat-tab-labels {
|
||||||
border-bottom: 2px solid #dddddd;
|
border-bottom: 2px solid #dddddd;
|
||||||
}
|
}
|
||||||
::ng-deep .ps-content {
|
::ng-deep .ps-content {
|
||||||
|
|
|
@ -5,5 +5,7 @@
|
||||||
[isBuddy]="isBuddy"
|
[isBuddy]="isBuddy"
|
||||||
[isFavorit]="isFavorit"
|
[isFavorit]="isFavorit"
|
||||||
(openChat)="onClickChat($event)"
|
(openChat)="onClickChat($event)"
|
||||||
|
(toggleFavorit)="onClickToggleFavorit($event)"
|
||||||
|
(toggleBuddy)="onClickToggleBuddy($event)"
|
||||||
>
|
>
|
||||||
</ucap-profile-profile>
|
</ucap-profile-profile>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, OnInit, Inject, ViewChild } from '@angular/core';
|
import { Component, OnInit, Inject, ViewChild, OnDestroy } from '@angular/core';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
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 { KEY_VER_INFO } from '@app/types/ver-info.type';
|
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
||||||
|
@ -7,17 +7,20 @@ import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
import { Store, select } from '@ngrx/store';
|
import { Store, select } from '@ngrx/store';
|
||||||
import * as AppStore from '@app/store';
|
import * as AppStore from '@app/store';
|
||||||
import * as ChatStore from '@app/store/messenger/chat';
|
import * as ChatStore from '@app/store/messenger/chat';
|
||||||
|
import * as SyncStore from '@app/store/messenger/sync';
|
||||||
|
|
||||||
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
|
import { UserInfo, GroupDetailData } from '@ucap-webmessenger/protocol-sync';
|
||||||
import {
|
import {
|
||||||
UserInfoSS,
|
UserInfoSS,
|
||||||
UserInfoF,
|
UserInfoF,
|
||||||
UserInfoDN
|
UserInfoDN
|
||||||
} from '@ucap-webmessenger/protocol-query';
|
} from '@ucap-webmessenger/protocol-query';
|
||||||
import { DialogService } from '@ucap-webmessenger/ui';
|
import { DialogService, ConfirmDialogComponent, ConfirmDialogData, ConfirmDialogResult } from '@ucap-webmessenger/ui';
|
||||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { SelectGroupDialogComponent, SelectGroupDialogData, SelectGroupDialogResult } from '../group/select-group.dialog.component';
|
||||||
|
|
||||||
export interface ProfileDialogData {
|
export interface ProfileDialogData {
|
||||||
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
|
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
|
||||||
|
@ -30,13 +33,15 @@ export interface ProfileDialogResult {}
|
||||||
templateUrl: './profile.dialog.component.html',
|
templateUrl: './profile.dialog.component.html',
|
||||||
styleUrls: ['./profile.dialog.component.scss']
|
styleUrls: ['./profile.dialog.component.scss']
|
||||||
})
|
})
|
||||||
export class ProfileDialogComponent implements OnInit {
|
export class ProfileDialogComponent implements OnInit, OnDestroy {
|
||||||
loginRes: LoginResponse;
|
loginRes: LoginResponse;
|
||||||
sessionVerinfo: VersionInfo2Response;
|
sessionVerinfo: VersionInfo2Response;
|
||||||
isMe: boolean;
|
isMe: boolean;
|
||||||
isBuddy: boolean;
|
isBuddy: boolean;
|
||||||
isFavorit: boolean;
|
isFavorit: boolean;
|
||||||
|
|
||||||
|
selectAllBuddy2Subscription: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<ProfileDialogData, ProfileDialogResult>,
|
public dialogRef: MatDialogRef<ProfileDialogData, ProfileDialogResult>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: ProfileDialogData,
|
@Inject(MAT_DIALOG_DATA) public data: ProfileDialogData,
|
||||||
|
@ -55,7 +60,8 @@ export class ProfileDialogComponent implements OnInit {
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.isMe = this.loginRes.userSeq === this.data.userInfo.seq;
|
this.isMe = this.loginRes.userSeq === this.data.userInfo.seq;
|
||||||
|
|
||||||
this.store.pipe(
|
this.selectAllBuddy2Subscription = this.store
|
||||||
|
.pipe(
|
||||||
select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2),
|
select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2),
|
||||||
map(buddyList => {
|
map(buddyList => {
|
||||||
const users = buddyList.filter(
|
const users = buddyList.filter(
|
||||||
|
@ -66,7 +72,14 @@ export class ProfileDialogComponent implements OnInit {
|
||||||
this.isFavorit = users[0].isFavorit;
|
this.isFavorit = users[0].isFavorit;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (!!this.selectAllBuddy2Subscription) {
|
||||||
|
this.selectAllBuddy2Subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickChat(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
|
onClickChat(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
|
||||||
|
@ -80,4 +93,71 @@ export class ProfileDialogComponent implements OnInit {
|
||||||
|
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClickToggleFavorit(param: {
|
||||||
|
userInfo: UserInfo | UserInfoF;
|
||||||
|
isFavorit: boolean;
|
||||||
|
}) {
|
||||||
|
this.store.dispatch(
|
||||||
|
SyncStore.updateBuddy({
|
||||||
|
seq: param.userInfo.seq,
|
||||||
|
isFavorit: param.isFavorit
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onClickToggleBuddy(param: {
|
||||||
|
userInfo: UserInfo | UserInfoF;
|
||||||
|
isBuddy: boolean;
|
||||||
|
}) {
|
||||||
|
if (param.isBuddy) {
|
||||||
|
// 동료추가.
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
SelectGroupDialogComponent,
|
||||||
|
SelectGroupDialogData,
|
||||||
|
SelectGroupDialogResult
|
||||||
|
>(SelectGroupDialogComponent, {
|
||||||
|
width: '600px',
|
||||||
|
data: {
|
||||||
|
title: 'Group Select'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!result && !!result.choice && result.choice) {
|
||||||
|
if (!!result.group) {
|
||||||
|
const oldGroup: GroupDetailData = result.group;
|
||||||
|
const trgtUserSeq: number[] = [];
|
||||||
|
result.group.userSeqs.map(seq => trgtUserSeq.push(seq));
|
||||||
|
trgtUserSeq.push(param.userInfo.seq);
|
||||||
|
|
||||||
|
this.store.dispatch(
|
||||||
|
SyncStore.updateGroupMember({
|
||||||
|
oldGroup,
|
||||||
|
trgtUserSeq
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 동료삭제.
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
ConfirmDialogComponent,
|
||||||
|
ConfirmDialogData,
|
||||||
|
ConfirmDialogResult
|
||||||
|
>(ConfirmDialogComponent, {
|
||||||
|
width: '360px',
|
||||||
|
data: {
|
||||||
|
title: 'Delete Buddy',
|
||||||
|
html: `[${param.userInfo.name} ${param.userInfo.grade}]를 그룹에서 삭제하시겠습니까?<br/>프로필에서 삭제하면 모든 그룹에서 삭제됩니다.`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!result && !!result.choice && result.choice) {
|
||||||
|
this.store.dispatch(
|
||||||
|
SyncStore.delBuddyAndClear({ seq: param.userInfo.seq })
|
||||||
|
);
|
||||||
|
this.isBuddy = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: #4f4f4f;
|
|
||||||
height: 30px;
|
height: 30px;
|
||||||
color:#ffffff;
|
color:#ffffff;
|
||||||
//background: rgba(37, 27, 30, 0.9);
|
//background: rgba(37, 27, 30, 0.9);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="container">
|
<div class="main-container">
|
||||||
<as-split
|
<as-split
|
||||||
unit="pixel"
|
unit="pixel"
|
||||||
gutterSize="5"
|
gutterSize="5"
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
.container {
|
.main-container {
|
||||||
height:100%;
|
height:100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row;
|
flex-flow: row;
|
||||||
padding-top: 30px;
|
padding-top: 27px;
|
||||||
border: 3px solid #4f4f4f;
|
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
||||||
.split-area{
|
.split-area{
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
.left-side {
|
.left-side {
|
||||||
|
@ -25,10 +23,13 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.rightDrawer{
|
.rightDrawer{
|
||||||
width:420px;
|
width:400px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
-webkit-box-shadow: -1px 0px 3px 0px rgba(0,0,0,0.3);
|
||||||
|
-moz-box-shadow: -1px 0px 3px 0px rgba(0,0,0,0.3);
|
||||||
|
box-shadow: -1px 0px 3px 0px rgba(0,0,0,0.3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.right-side {
|
.right-side {
|
||||||
|
|
|
@ -176,6 +176,19 @@ export const delBuddyFailure = createAction(
|
||||||
'[Messenger::Sync] Buddy Del Failure',
|
'[Messenger::Sync] Buddy Del Failure',
|
||||||
props<{ error: any }>()
|
props<{ error: any }>()
|
||||||
);
|
);
|
||||||
|
/** 동료 삭제 및 그룹 클리어.(in profile) */
|
||||||
|
export const delBuddyAndClear = createAction(
|
||||||
|
'[Messenger::Sync] Buddy Del and Group Clear',
|
||||||
|
props<{ seq: number }>()
|
||||||
|
);
|
||||||
|
export const delBuddyAndClearSuccess = createAction(
|
||||||
|
'[Messenger::Sync] Buddy Del and Group Clear Success',
|
||||||
|
props<BuddyDelResponse>()
|
||||||
|
);
|
||||||
|
export const delBuddyAndClearFailure = createAction(
|
||||||
|
'[Messenger::Sync] Buddy Del and Group Clear Failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
/** 동료 변경(즐겨찾기) */
|
/** 동료 변경(즐겨찾기) */
|
||||||
export const updateBuddy = createAction(
|
export const updateBuddy = createAction(
|
||||||
'[Messenger::Sync] Buddy Update',
|
'[Messenger::Sync] Buddy Update',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { openTimer } from './../room/actions';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Actions, ofType, createEffect } from '@ngrx/effects';
|
import { Actions, ofType, createEffect } from '@ngrx/effects';
|
||||||
|
@ -48,7 +47,8 @@ import {
|
||||||
updateGroupMember,
|
updateGroupMember,
|
||||||
delGroup,
|
delGroup,
|
||||||
delGroupFailure,
|
delGroupFailure,
|
||||||
delGroupSuccess
|
delGroupSuccess,
|
||||||
|
delBuddyAndClear
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
||||||
|
@ -727,6 +727,54 @@ export class Effects {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
delBuddyAndClear$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(delBuddyAndClear),
|
||||||
|
withLatestFrom(
|
||||||
|
this.store.pipe(
|
||||||
|
select(
|
||||||
|
(state: any) =>
|
||||||
|
state.messenger.sync.group2.entities as Dictionary<
|
||||||
|
GroupDetailData
|
||||||
|
>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
tap(([req, groupList]) => {
|
||||||
|
// tslint:disable-next-line: forin
|
||||||
|
for (const key in groupList) {
|
||||||
|
const group: GroupDetailData = groupList[key];
|
||||||
|
if (group.userSeqs.indexOf(req.seq) > -1) {
|
||||||
|
// Group Clear..
|
||||||
|
this.store.dispatch(
|
||||||
|
updateGroup({
|
||||||
|
groupSeq: group.seq,
|
||||||
|
groupName: group.name,
|
||||||
|
userSeqs: group.userSeqs.filter(
|
||||||
|
userSeq => userSeq !== req.seq
|
||||||
|
)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Favorit Clear..
|
||||||
|
this.store.dispatch(
|
||||||
|
updateBuddy({
|
||||||
|
seq: req.seq,
|
||||||
|
isFavorit: false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Buddy Clear..
|
||||||
|
this.store.dispatch(delBuddy({ userSeqs: [req.seq] }));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
updateBuddy$ = createEffect(() =>
|
updateBuddy$ = createEffect(() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
ofType(updateBuddy),
|
ofType(updateBuddy),
|
||||||
|
|
|
@ -60,6 +60,7 @@ $lg-red: (
|
||||||
A200: #ff4081,
|
A200: #ff4081,
|
||||||
A400: #ff3399,
|
A400: #ff3399,
|
||||||
A700: #c51162,
|
A700: #c51162,
|
||||||
|
B100: #4f4f4f,
|
||||||
G100: #ef4c73,
|
G100: #ef4c73,
|
||||||
G900: #352a37,
|
G900: #352a37,
|
||||||
contrast: (
|
contrast: (
|
||||||
|
@ -77,28 +78,33 @@ $lg-red: (
|
||||||
A200: $light-primary-text,
|
A200: $light-primary-text,
|
||||||
A400: $light-primary-text,
|
A400: $light-primary-text,
|
||||||
A700: $light-primary-text,
|
A700: $light-primary-text,
|
||||||
|
B100: $light-primary-text,
|
||||||
G100: $dark-primary-text,
|
G100: $dark-primary-text,
|
||||||
G900: $light-primary-text
|
G900: $light-primary-text
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$daesang: (
|
$daesang: (
|
||||||
50: #e0f7fa,
|
50: #f9feff,
|
||||||
|
//#e0f7fa,
|
||||||
100: #b2ebf2,
|
100: #b2ebf2,
|
||||||
200: #80deea,
|
200: #4dd0e1,
|
||||||
|
//#80deea,
|
||||||
300: #4dd0e1,
|
300: #4dd0e1,
|
||||||
400: #26c6da,
|
400: #26c6da,
|
||||||
500: #00bcd4,
|
500: #00bcd4,
|
||||||
/*600: #00acc1,*/ 600: #00b6d5,
|
/*600: #00acc1,*/ 600: #00b6d5,
|
||||||
700: #0097a7,
|
700: #0097a7,
|
||||||
800: #2c8493,
|
800: #0367a6,
|
||||||
900: #126a79,
|
900: #024873,
|
||||||
A100: #84ffff,
|
A100: #84ffff,
|
||||||
A200: #18ffff,
|
A200: #18ffff,
|
||||||
A400: #00e5ff,
|
A400: #00e5ff,
|
||||||
A700: #00b8d4,
|
A700: #00b8d4,
|
||||||
G100: #6dd5ed,
|
B100: #2d3a4a,
|
||||||
/*G900: #192a2c,*/ G900: #2193b0,
|
//,#47667fbackgroundcolor
|
||||||
|
G100: #0367a6,
|
||||||
|
/*G900: #192a2c,*/ G900: #6dd5ed,
|
||||||
contrast: (
|
contrast: (
|
||||||
50: $dark-primary-text,
|
50: $dark-primary-text,
|
||||||
100: $dark-primary-text,
|
100: $dark-primary-text,
|
||||||
|
@ -114,10 +120,43 @@ $daesang: (
|
||||||
A200: $dark-primary-text,
|
A200: $dark-primary-text,
|
||||||
A400: $dark-primary-text,
|
A400: $dark-primary-text,
|
||||||
A700: $dark-primary-text,
|
A700: $dark-primary-text,
|
||||||
|
B100: $light-primary-text,
|
||||||
G100: $dark-primary-text,
|
G100: $dark-primary-text,
|
||||||
G900: $light-primary-text
|
G900: $light-primary-text
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
$daesang-grey: (
|
||||||
|
50: #fafafa,
|
||||||
|
100: #f5f5f5,
|
||||||
|
200: #eeeeee,
|
||||||
|
300: #e0e0e0,
|
||||||
|
400: #bdbdbd,
|
||||||
|
500: #9e9e9e,
|
||||||
|
600: #757575,
|
||||||
|
700: #616161,
|
||||||
|
800: #424242,
|
||||||
|
900: #2d3a4a,
|
||||||
|
A100: #ffffff,
|
||||||
|
A200: #eeeeee,
|
||||||
|
A400: #bdbdbd,
|
||||||
|
A700: #616161,
|
||||||
|
contrast: (
|
||||||
|
50: $dark-primary-text,
|
||||||
|
100: $dark-primary-text,
|
||||||
|
200: $dark-primary-text,
|
||||||
|
300: $dark-primary-text,
|
||||||
|
400: $dark-primary-text,
|
||||||
|
500: $dark-primary-text,
|
||||||
|
600: $light-primary-text,
|
||||||
|
700: $light-primary-text,
|
||||||
|
800: $light-primary-text,
|
||||||
|
900: $light-primary-text,
|
||||||
|
A100: $dark-primary-text,
|
||||||
|
A200: $dark-primary-text,
|
||||||
|
A400: $dark-primary-text,
|
||||||
|
A700: $light-primary-text
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
@mixin ucap-material-theme($theme) {
|
@mixin ucap-material-theme($theme) {
|
||||||
@include ucap-core-theme($theme);
|
@include ucap-core-theme($theme);
|
||||||
|
@ -133,6 +172,7 @@ $daesang: (
|
||||||
$gradient-darkest: mat-color($accent, G900);
|
$gradient-darkest: mat-color($accent, G900);
|
||||||
$gradient-light: mat-color($accent, G100);
|
$gradient-light: mat-color($accent, G100);
|
||||||
|
|
||||||
|
//basic
|
||||||
.bg-primary-dark {
|
.bg-primary-dark {
|
||||||
background: mat-color($primary, 900);
|
background: mat-color($primary, 900);
|
||||||
color: mat-color($primary, default-contrast);
|
color: mat-color($primary, default-contrast);
|
||||||
|
@ -168,6 +208,9 @@ $daesang: (
|
||||||
.text-primary-color {
|
.text-primary-color {
|
||||||
color: mat-color($primary);
|
color: mat-color($primary);
|
||||||
}
|
}
|
||||||
|
.text-accent-darkest {
|
||||||
|
color: mat-color($accent, 900);
|
||||||
|
}
|
||||||
.text-accent-color {
|
.text-accent-color {
|
||||||
color: mat-color($accent);
|
color: mat-color($accent);
|
||||||
}
|
}
|
||||||
|
@ -180,6 +223,18 @@ $daesang: (
|
||||||
.border-accent-color {
|
.border-accent-color {
|
||||||
border: 1px solid mat-color($accent);
|
border: 1px solid mat-color($accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sass 정의
|
||||||
|
.mat-toolbar {
|
||||||
|
background-color: mat-color($accent, B100);
|
||||||
|
}
|
||||||
|
.main-container {
|
||||||
|
border: 3px solid mat-color($accent, B100);
|
||||||
|
}
|
||||||
|
.global-menu {
|
||||||
|
background-color: mat-color($accent, B100);
|
||||||
|
}
|
||||||
|
|
||||||
.mat-tab-group.mat-primary .mat-ink-bar,
|
.mat-tab-group.mat-primary .mat-ink-bar,
|
||||||
body.theme-default .mat-tab-nav-bar.mat-primary .mat-ink-bar {
|
body.theme-default .mat-tab-nav-bar.mat-primary .mat-ink-bar {
|
||||||
background-color: mat-color($accent, 400);
|
background-color: mat-color($accent, 400);
|
||||||
|
@ -187,9 +242,7 @@ $daesang: (
|
||||||
.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
|
.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
|
||||||
background-color: mat-color($accent, 200);
|
background-color: mat-color($accent, 200);
|
||||||
}
|
}
|
||||||
/*.mat-form-field-appearance-legacy .mat-hint{
|
|
||||||
color: mat-color($accent, 800);
|
|
||||||
}*/
|
|
||||||
.global-menu {
|
.global-menu {
|
||||||
.mat-tab-label[aria-selected='true'] {
|
.mat-tab-label[aria-selected='true'] {
|
||||||
.mat-tab-label-content {
|
.mat-tab-label-content {
|
||||||
|
@ -266,4 +319,12 @@ $daesang: (
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column !important;
|
flex-direction: column !important;
|
||||||
}
|
}
|
||||||
|
.messages .container {
|
||||||
|
background: mat-color($accent, 50);
|
||||||
|
}
|
||||||
|
.profile-img {
|
||||||
|
.responsive-chats-button:last-child {
|
||||||
|
background-color: $gradient-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
171
projects/ucap-webmessenger-core/src/lib/utils/sticker.util.ts
Normal file
171
projects/ucap-webmessenger-core/src/lib/utils/sticker.util.ts
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
export interface StickerInfo {
|
||||||
|
index: string;
|
||||||
|
title: string;
|
||||||
|
iconPath: string;
|
||||||
|
iconPathOn: string;
|
||||||
|
useYn: boolean;
|
||||||
|
fileInfos: StickerFilesInfo[];
|
||||||
|
}
|
||||||
|
export interface StickerFilesInfo {
|
||||||
|
index: string;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
const StickerMap: StickerInfo[] = [
|
||||||
|
{
|
||||||
|
index: '00',
|
||||||
|
title: 'History',
|
||||||
|
iconPath: 'sticker_cate00.png',
|
||||||
|
iconPathOn: 'sticker_cate00_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: '01',
|
||||||
|
title: '꼼므',
|
||||||
|
iconPath: 'sticker_cate01.png',
|
||||||
|
iconPathOn: 'sticker_cate01_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: [
|
||||||
|
{ index: '01_01', path: 'sticker_s_01_01.png' },
|
||||||
|
{ index: '01_02', path: 'sticker_s_01_02.png' },
|
||||||
|
{ index: '01_03', path: 'sticker_s_01_03.png' },
|
||||||
|
{ index: '01_04', path: 'sticker_s_01_04.png' },
|
||||||
|
{ index: '01_05', path: 'sticker_s_01_05.png' },
|
||||||
|
{ index: '01_06', path: 'sticker_s_01_06.png' },
|
||||||
|
{ index: '01_07', path: 'sticker_s_01_07.png' },
|
||||||
|
{ index: '01_08', path: 'sticker_s_01_08.png' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: '02',
|
||||||
|
title: '까미',
|
||||||
|
iconPath: 'sticker_cate02.png',
|
||||||
|
iconPathOn: 'sticker_cate02_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: [
|
||||||
|
{ index: '02_02', path: 'sticker_s_02_02.png' },
|
||||||
|
{ index: '02_03', path: 'sticker_s_02_03.png' },
|
||||||
|
{ index: '02_04', path: 'sticker_s_02_04.png' },
|
||||||
|
{ index: '02_05', path: 'sticker_s_02_05.png' },
|
||||||
|
{ index: '02_06', path: 'sticker_s_02_06.png' },
|
||||||
|
{ index: '02_07', path: 'sticker_s_02_07.png' },
|
||||||
|
{ index: '02_08', path: 'sticker_s_02_08.png' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: '03',
|
||||||
|
title: '왈도',
|
||||||
|
iconPath: 'sticker_cate03.png',
|
||||||
|
iconPathOn: 'sticker_cate03_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: [
|
||||||
|
{ index: '03_01', path: 'sticker_s_03_01.png' },
|
||||||
|
{ index: '03_02', path: 'sticker_s_03_02.png' },
|
||||||
|
{ index: '03_03', path: 'sticker_s_03_03.png' },
|
||||||
|
{ index: '03_04', path: 'sticker_s_03_04.png' },
|
||||||
|
{ index: '03_05', path: 'sticker_s_03_05.png' },
|
||||||
|
{ index: '03_06', path: 'sticker_s_03_06.png' },
|
||||||
|
{ index: '03_07', path: 'sticker_s_03_07.png' },
|
||||||
|
{ index: '03_08', path: 'sticker_s_03_08.png' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: '04',
|
||||||
|
title: '웅쓰',
|
||||||
|
iconPath: 'sticker_cate04.png',
|
||||||
|
iconPathOn: 'sticker_cate04_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: [
|
||||||
|
{ index: '04_01', path: 'sticker_s_04_01.png' },
|
||||||
|
{ index: '04_02', path: 'sticker_s_04_02.png' },
|
||||||
|
{ index: '04_03', path: 'sticker_s_04_03.png' },
|
||||||
|
{ index: '04_04', path: 'sticker_s_04_04.png' },
|
||||||
|
{ index: '04_05', path: 'sticker_s_04_05.png' },
|
||||||
|
{ index: '04_06', path: 'sticker_s_04_06.png' },
|
||||||
|
{ index: '04_07', path: 'sticker_s_04_07.png' },
|
||||||
|
{ index: '04_08', path: 'sticker_s_04_08.png' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: '05',
|
||||||
|
title: '말풍선',
|
||||||
|
iconPath: 'sticker_cate05.png',
|
||||||
|
iconPathOn: 'sticker_cate05_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: [
|
||||||
|
{ index: '05_01', path: 'sticker_s_05_01.png' },
|
||||||
|
{ index: '05_02', path: 'sticker_s_05_02.png' },
|
||||||
|
{ index: '05_03', path: 'sticker_s_05_03.png' },
|
||||||
|
{ index: '05_04', path: 'sticker_s_05_04.png' },
|
||||||
|
{ index: '05_05', path: 'sticker_s_05_05.png' },
|
||||||
|
{ index: '05_06', path: 'sticker_s_05_06.png' },
|
||||||
|
{ index: '05_07', path: 'sticker_s_05_07.png' },
|
||||||
|
{ index: '05_08', path: 'sticker_s_05_08.png' },
|
||||||
|
{ index: '05_09', path: 'sticker_s_05_09.png' },
|
||||||
|
{ index: '05_10', path: 'sticker_s_05_10.png' },
|
||||||
|
{ index: '05_11', path: 'sticker_s_05_11.png' },
|
||||||
|
{ index: '05_12', path: 'sticker_s_05_12.png' },
|
||||||
|
{ index: '05_13', path: 'sticker_s_05_13.png' },
|
||||||
|
{ index: '05_14', path: 'sticker_s_05_14.png' },
|
||||||
|
{ index: '05_15', path: 'sticker_s_05_15.png' },
|
||||||
|
{ index: '05_16', path: 'sticker_s_05_16.png' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: '12',
|
||||||
|
title: '황소',
|
||||||
|
iconPath: 'sticker_cate12.png',
|
||||||
|
iconPathOn: 'sticker_cate12_f.png',
|
||||||
|
useYn: true,
|
||||||
|
fileInfos: [
|
||||||
|
{ index: '12_01', path: 'sticker_s_12_01.gif' },
|
||||||
|
{ index: '12_02', path: 'sticker_s_12_02.gif' },
|
||||||
|
{ index: '12_03', path: 'sticker_s_12_03.gif' },
|
||||||
|
{ index: '12_04', path: 'sticker_s_12_04.gif' },
|
||||||
|
{ index: '12_05', path: 'sticker_s_12_05.gif' },
|
||||||
|
{ index: '12_06', path: 'sticker_s_12_06.gif' },
|
||||||
|
{ index: '12_07', path: 'sticker_s_12_07.gif' },
|
||||||
|
{ index: '12_08', path: 'sticker_s_12_08.gif' },
|
||||||
|
{ index: '12_09', path: 'sticker_s_12_09.gif' },
|
||||||
|
{ index: '12_10', path: 'sticker_s_12_10.gif' },
|
||||||
|
{ index: '12_11', path: 'sticker_s_12_11.gif' },
|
||||||
|
{ index: '12_12', path: 'sticker_s_12_12.gif' },
|
||||||
|
{ index: '12_13', path: 'sticker_s_12_13.gif' },
|
||||||
|
{ index: '12_14', path: 'sticker_s_12_14.gif' },
|
||||||
|
{ index: '12_15', path: 'sticker_s_12_15.gif' },
|
||||||
|
{ index: '12_16', path: 'sticker_s_12_16.gif' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const ActiveAndOrdering: string[] = ['00', '01', '02', '03', '04', '05'];
|
||||||
|
|
||||||
|
export class StickerUtil {
|
||||||
|
static getStickerInfoList(): StickerInfo[] {
|
||||||
|
const rtnStickerList: StickerInfo[] = [];
|
||||||
|
|
||||||
|
ActiveAndOrdering.forEach(idx => {
|
||||||
|
const stickerInfos: StickerInfo[] = StickerMap.filter(
|
||||||
|
sticker => sticker.index === idx && sticker.useYn
|
||||||
|
);
|
||||||
|
if (!!stickerInfos && stickerInfos.length > 0) {
|
||||||
|
rtnStickerList.push(stickerInfos[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return rtnStickerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getStickerInfoSub(index: string): StickerFilesInfo[] {
|
||||||
|
const stickerFilesList: StickerFilesInfo[] = [];
|
||||||
|
const stickerInfos: StickerInfo[] = StickerMap.filter(
|
||||||
|
sticker => sticker.index === index && sticker.useYn
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!!stickerInfos && stickerInfos.length > 0) {
|
||||||
|
stickerFilesList.concat(stickerInfos[0].fileInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stickerFilesList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ export * from './lib/types/video-conference-type.type';
|
||||||
|
|
||||||
export * from './lib/utils/file.util';
|
export * from './lib/utils/file.util';
|
||||||
export * from './lib/utils/mime.util';
|
export * from './lib/utils/mime.util';
|
||||||
|
export * from './lib/utils/sticker.util';
|
||||||
export * from './lib/utils/string.util';
|
export * from './lib/utils/string.util';
|
||||||
|
|
||||||
export * from './lib/config/host.config';
|
export * from './lib/config/host.config';
|
||||||
|
|
|
@ -16,13 +16,17 @@
|
||||||
(change)="onChangeFileInput()"
|
(change)="onChangeFileInput()"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button mat-icon-button class="material-icons">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
class="material-icons"
|
||||||
|
(click)="onClickStickerSelector()"
|
||||||
|
>
|
||||||
<mat-icon>sentiment_satisfied_alt</mat-icon>
|
<mat-icon>sentiment_satisfied_alt</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-icon-button class="material-icons">
|
<!-- <button mat-icon-button class="material-icons">
|
||||||
<mat-icon>g_translate</mat-icon>
|
<mat-icon>g_translate</mat-icon>
|
||||||
</button>
|
</button> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
|
|
|
@ -26,6 +26,9 @@ export class FormComponent implements OnInit {
|
||||||
@Output()
|
@Output()
|
||||||
sendFiles = new EventEmitter<FileUploadItem[]>();
|
sendFiles = new EventEmitter<FileUploadItem[]>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
toggleStickerSelector = new EventEmitter<void>();
|
||||||
|
|
||||||
@ViewChild('replyForm', { static: false })
|
@ViewChild('replyForm', { static: false })
|
||||||
replyForm: NgForm;
|
replyForm: NgForm;
|
||||||
|
|
||||||
|
@ -67,4 +70,8 @@ export class FormComponent implements OnInit {
|
||||||
|
|
||||||
this.fileInput.nativeElement.value = '';
|
this.fileInput.nativeElement.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClickStickerSelector() {
|
||||||
|
this.toggleStickerSelector.emit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
.file-thumbimg{
|
.file-thumbimg{
|
||||||
display:inline-flex;
|
display:inline-flex;
|
||||||
img {
|
img {
|
||||||
width:200px;
|
height:140px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ $meBox-bg: #ffffff;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #dddddd;
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,6 @@ $meBox-bg: #ffffff;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin-right: 40px;
|
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
.profile-img {
|
.profile-img {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
@ -172,7 +171,7 @@ $meBox-bg: #ffffff;
|
||||||
&.me {
|
&.me {
|
||||||
.chat-row {
|
.chat-row {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
margin-left: 40px;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
.profile-info {
|
.profile-info {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
|
|
@ -9,71 +9,147 @@
|
||||||
|
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<div class="profile-img">
|
<div class="profile-img">
|
||||||
<img ucapImage [base]="profileImageRoot" [path]="userInfo.profileImageFile"
|
<img
|
||||||
[default]="'assets/images/img_nophoto_50.png'" />
|
ucapImage
|
||||||
|
[base]="profileImageRoot"
|
||||||
|
[path]="userInfo.profileImageFile"
|
||||||
|
[default]="'assets/images/img_nophoto_50.png'"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 내프로필의 경우<div class="profile-option">이 없음 -->
|
|
||||||
<div class="profile-option">
|
<div *ngIf="!isMe" class="profile-option">
|
||||||
<span class="btn-favorite">
|
<span *ngIf="isBuddy" class="btn-favorite" (click)="onToggleFavorit()">
|
||||||
<!--즐겨찾기 추가버튼 추가된 상태: svg에 class="on"-->
|
<svg
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
[ngClass]="[isFavorit ? 'on' : '']"
|
||||||
|
>
|
||||||
<polygon
|
<polygon
|
||||||
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2">
|
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
|
||||||
</polygon>
|
></polygon>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-groupadd">
|
<span class="btn-groupadd">
|
||||||
<!--친구 추가 버튼-->
|
<ng-container [ngSwitch]="isBuddy">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
<svg
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round" class="on">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="on"
|
||||||
|
*ngSwitchCase="false"
|
||||||
|
(click)="onClickAddBuddy()"
|
||||||
|
>
|
||||||
|
<!-- not buddy -->
|
||||||
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||||
<circle cx="8.5" cy="7" r="4"></circle>
|
<circle cx="8.5" cy="7" r="4"></circle>
|
||||||
<line x1="20" y1="8" x2="20" y2="14"></line>
|
<line x1="20" y1="8" x2="20" y2="14"></line>
|
||||||
<line x1="23" y1="11" x2="17" y2="11"></line>
|
<line x1="23" y1="11" x2="17" y2="11"></line>
|
||||||
</svg>
|
</svg>
|
||||||
<!--친구 삭제 버튼-->
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
<svg
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="on"
|
||||||
|
*ngSwitchCase="true"
|
||||||
|
(click)="onClickDelBuddy()"
|
||||||
|
>
|
||||||
|
<!-- is buddy -->
|
||||||
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||||
<circle cx="8.5" cy="7" r="4"></circle>
|
<circle cx="8.5" cy="7" r="4"></circle>
|
||||||
<line x1="23" y1="11" x2="17" y2="11"></line>
|
<line x1="23" y1="11" x2="17" y2="11"></line>
|
||||||
</svg>
|
</svg>
|
||||||
|
</ng-container>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<!--<mat-icon>chat</mat-icon>-->
|
<svg
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
width="20"
|
||||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
{{ userInfo.intro }}
|
{{ userInfo.intro }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<!--<mat-icon>email</mat-icon>-->
|
<svg
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
width="20"
|
||||||
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"
|
||||||
|
></path>
|
||||||
<polyline points="22,6 12,13 2,6"></polyline>
|
<polyline points="22,6 12,13 2,6"></polyline>
|
||||||
</svg>
|
</svg>
|
||||||
{{ userInfo.email }}
|
{{ userInfo.email }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<!--<mat-icon>local_phone</mat-icon>-->
|
<svg
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z">
|
d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"
|
||||||
</path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
{{ userInfo.lineNumber }}
|
{{ userInfo.lineNumber }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<!--<mat-icon>phone_android</mat-icon>-->
|
<svg
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor" stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round">
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect>
|
<rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect>
|
||||||
<line x1="12" y1="18" x2="12" y2="18"></line>
|
<line x1="12" y1="18" x2="12" y2="18"></line>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -84,43 +160,99 @@
|
||||||
|
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-around center">
|
<div fxFlex fxLayout="row" fxLayoutAlign="space-around center">
|
||||||
<button mat-mini-fab class="mat-elevation-z" [matTooltip]="isMe ? 'MyTalk' : '1:1 대화'" matTooltipPosition="above"
|
<button
|
||||||
(click)="onClickOpenChat()">
|
mat-mini-fab
|
||||||
<!--<mat-icon>chat</mat-icon>-->
|
class="mat-elevation-z"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
[matTooltip]="isMe ? 'MyTalk' : '1:1 대화'"
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
matTooltipPosition="above"
|
||||||
|
(click)="onClickOpenChat()"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z">
|
d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"
|
||||||
</path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-mini-fab class="mat-elevation-z" *ngIf="!isMe" matTooltip="전화" matTooltipPosition="above"
|
<button
|
||||||
(click)="onClickCall()">
|
mat-mini-fab
|
||||||
<!--<mat-icon>call</mat-icon>-->
|
class="mat-elevation-z"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
*ngIf="!isMe"
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
matTooltip="전화"
|
||||||
|
matTooltipPosition="above"
|
||||||
|
(click)="onClickCall()"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z">
|
d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"
|
||||||
</path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-mini-fab class="mat-elevation-z" *ngIf="!isMe" matTooltip="화상회의" matTooltipPosition="above"
|
<button
|
||||||
(click)="onClickVideoConference()">
|
mat-mini-fab
|
||||||
<!--<mat-icon>videocam</mat-icon>-->
|
class="mat-elevation-z"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
*ngIf="!isMe"
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
matTooltip="화상회의"
|
||||||
|
matTooltipPosition="above"
|
||||||
|
(click)="onClickVideoConference()"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d="M15.6 11.6L22 7v10l-6.4-4.5v-1zM4 5h9a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7c0-1.1.9-2 2-2z" />
|
d="M15.6 11.6L22 7v10l-6.4-4.5v-1zM4 5h9a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7c0-1.1.9-2 2-2z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-mini-fab class="mat-elevation-z" *ngIf="!isMe" matTooltip="쪽지" matTooltipPosition="above"
|
<button
|
||||||
(click)="onClickMessage()">
|
mat-mini-fab
|
||||||
<!--<mat-icon>sms</mat-icon>-->
|
class="mat-elevation-z"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
*ngIf="!isMe"
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
matTooltip="쪽지"
|
||||||
|
matTooltipPosition="above"
|
||||||
|
(click)="onClickMessage()"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="butt"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<line class="st0" x1="18" y1="2" x2="9.2" y2="10.8" />
|
<line class="st0" x1="18" y1="2" x2="9.2" y2="10.8" />
|
||||||
<polygon class="st0" points="18,2 12.4,18 9.2,10.8 2,7.6 " />
|
<polygon class="st0" points="18,2 12.4,18 9.2,10.8 2,7.6 " />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -22,10 +22,20 @@ export class ProfileComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
isFavorit: boolean;
|
isFavorit: boolean;
|
||||||
@Input()
|
@Input()
|
||||||
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
|
userInfo: UserInfo | UserInfoF;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
openChat = new EventEmitter<UserInfo | UserInfoSS | UserInfoF | UserInfoDN>();
|
openChat = new EventEmitter<UserInfo | UserInfoF>();
|
||||||
|
@Output()
|
||||||
|
toggleFavorit = new EventEmitter<{
|
||||||
|
userInfo: UserInfo | UserInfoF;
|
||||||
|
isFavorit: boolean;
|
||||||
|
}>();
|
||||||
|
@Output()
|
||||||
|
toggleBuddy = new EventEmitter<{
|
||||||
|
userInfo: UserInfo | UserInfoF;
|
||||||
|
isBuddy: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -40,4 +50,27 @@ export class ProfileComponent implements OnInit {
|
||||||
onClickVideoConference() {}
|
onClickVideoConference() {}
|
||||||
|
|
||||||
onClickMessage() {}
|
onClickMessage() {}
|
||||||
|
|
||||||
|
onToggleFavorit() {
|
||||||
|
this.isFavorit = !this.isFavorit;
|
||||||
|
|
||||||
|
this.toggleFavorit.emit({
|
||||||
|
userInfo: this.userInfo,
|
||||||
|
isFavorit: this.isFavorit
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickAddBuddy() {
|
||||||
|
this.toggleBuddy.emit({
|
||||||
|
userInfo: this.userInfo,
|
||||||
|
isBuddy: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickDelBuddy() {
|
||||||
|
this.toggleBuddy.emit({
|
||||||
|
userInfo: this.userInfo,
|
||||||
|
isBuddy: false
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,6 @@ $thumbnail-msize: 40px;
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
background-color: #ef4c73;
|
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,32 +17,25 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.file-upload-item {
|
.file-upload-item {
|
||||||
background-color: #eeeeee;
|
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
margin: 0 0.5%;
|
margin: 0 1%;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
width: 32%;
|
width: 48%;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
border:1px solid #dddddd;
|
||||||
.file-upload-info {
|
.file-upload-info {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color:#ffffff;
|
|
||||||
border-bottom: 1px solid #dddddd;
|
|
||||||
svg {
|
svg {
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
.file-upload-name {
|
.file-upload-name {
|
||||||
height: 40px;
|
height: 20px;
|
||||||
@include ellipsis(2);
|
@include ellipsis(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.file-upload-progress {
|
.file-upload-progress {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
}
|
}
|
||||||
&:nth-child(3n + 1) {
|
|
||||||
margin-left: 1%;
|
|
||||||
}
|
|
||||||
&:nth-child(3n + 0) {
|
|
||||||
margin-right: 1%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<p>sticker-selector works!</p>
|
||||||
|
<p *ngFor="let stickerInfo of stickerInfoList">
|
||||||
|
{{ stickerInfo.title }}
|
||||||
|
</p>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { StickerSelectorComponent } from './sticker-selector.component';
|
||||||
|
|
||||||
|
describe('StickerSelectorComponent', () => {
|
||||||
|
let component: StickerSelectorComponent;
|
||||||
|
let fixture: ComponentFixture<StickerSelectorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ StickerSelectorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(StickerSelectorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {
|
||||||
|
StickerInfo,
|
||||||
|
StickerFilesInfo,
|
||||||
|
StickerUtil
|
||||||
|
} from '@ucap-webmessenger/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ucap-sticker-selector',
|
||||||
|
templateUrl: './sticker-selector.component.html',
|
||||||
|
styleUrls: ['./sticker-selector.component.scss']
|
||||||
|
})
|
||||||
|
export class StickerSelectorComponent implements OnInit {
|
||||||
|
stickerInfoList: StickerInfo[] = [];
|
||||||
|
stickerFileInfoList: StickerFilesInfo[] = [];
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.stickerInfoList = StickerUtil.getStickerInfoList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,12 +47,14 @@ import {
|
||||||
} from './pipes/dates.pipe';
|
} from './pipes/dates.pipe';
|
||||||
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';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
FileUploadQueueComponent,
|
FileUploadQueueComponent,
|
||||||
FloatActionButtonComponent,
|
FloatActionButtonComponent,
|
||||||
FileViewerComponent,
|
FileViewerComponent,
|
||||||
ExpansionPanelComponent,
|
ExpansionPanelComponent,
|
||||||
|
StickerSelectorComponent,
|
||||||
|
|
||||||
BinaryViewerComponent,
|
BinaryViewerComponent,
|
||||||
DocumentViewerComponent,
|
DocumentViewerComponent,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user