This commit is contained in:
leejinho 2019-11-26 17:54:43 +09:00
commit 0bc6968e98
28 changed files with 598 additions and 237 deletions

View File

@ -46,9 +46,12 @@
</ucap-group-expansion-panel> </ucap-group-expansion-panel>
</div> </div>
<div [style.display]="isShowSearch ? 'block' : 'none'" class="search-result"> <div [style.display]="isShowSearch ? 'block' : 'none'" class="search-result">
<div *ngIf="searchProcessing"> <div style="position: relative;">
<mat-progress-bar mode="indeterminate"></mat-progress-bar> <div *ngIf="searchProcessing" style="position: absolute; width: 100%;">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
</div> </div>
<div class="result-num"> <div class="result-num">
검색결과<span class="text-accent-color" 검색결과<span class="text-accent-color"
>({{ searchUserInfos.length }}명)</span >({{ searchUserInfos.length }}명)</span
@ -93,16 +96,36 @@
</button> </button>
<button mat-menu-item (click)="onClickGroupMenu('GROUP_EXPAND_MORE')"> <button mat-menu-item (click)="onClickGroupMenu('GROUP_EXPAND_MORE')">
<!--<mat-icon>expand_more</mat-icon>--> <!--<mat-icon>expand_more</mat-icon>-->
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" <svg
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round"> xmlns="http://www.w3.org/2000/svg"
<path d="M6 9l6 6 6-6" /></svg> width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="butt"
stroke-linejoin="round"
>
<path d="M6 9l6 6 6-6" />
</svg>
<span>그룹 전체 열기</span> <span>그룹 전체 열기</span>
</button> </button>
<button mat-menu-item (click)="onClickGroupMenu('GROUP_EXPAND_LESS')"> <button mat-menu-item (click)="onClickGroupMenu('GROUP_EXPAND_LESS')">
<!--<mat-icon>expand_less</mat-icon>--> <!--<mat-icon>expand_less</mat-icon>-->
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" <svg
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round"> xmlns="http://www.w3.org/2000/svg"
<path d="M18 15l-6-6-6 6" /></svg> width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="butt"
stroke-linejoin="round"
>
<path d="M18 15l-6-6-6 6" />
</svg>
<span>그룹 전체 닫기</span> <span>그룹 전체 닫기</span>
</button> </button>
<!-- <button mat-menu-item (click)="onClickGroupMenu('GROUP_SAVE')"> <!-- <button mat-menu-item (click)="onClickGroupMenu('GROUP_SAVE')">

View File

@ -41,8 +41,13 @@
</mat-checkbox> </mat-checkbox>
</dd> </dd>
</dl> </dl>
<div *ngIf="selectedDepartmentProcessing"> <div style="position: relative;">
<mat-progress-bar mode="indeterminate"></mat-progress-bar> <div
*ngIf="selectedDepartmentProcessing"
style="position: absolute; width: 100%;"
>
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
</div> </div>
<div *ngIf="!isShowSearch" class="search-list"> <div *ngIf="!isShowSearch" class="search-list">
<cdk-virtual-scroll-viewport <cdk-virtual-scroll-viewport

View File

@ -142,10 +142,14 @@
</div> </div>
</mat-toolbar> </mat-toolbar>
<!-- / CHAT TOOLBAR --> <!-- / CHAT TOOLBAR -->
<mat-progress-bar <div style="position: relative;">
*ngIf="eventListProcessing$ | async" <div
mode="indeterminate" *ngIf="eventListProcessing$ | async"
></mat-progress-bar> style="position: absolute; width: 100%;"
>
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
</div>
<!-- CHAT CONTENT --> <!-- CHAT CONTENT -->
<div <div
fxFlex="1 1 auto" fxFlex="1 1 auto"

View File

@ -24,8 +24,8 @@
} }
.chat-toolbar { .chat-toolbar {
width: 100%; width: 100%;
height: 80px; height: 70px;
min-height: 80px; min-height: 70px;
align-items: center; align-items: center;
background-color: #ffffff !important; background-color: #ffffff !important;
border-bottom: 1px solid #dddddd; border-bottom: 1px solid #dddddd;

View File

@ -93,9 +93,15 @@
[style.display]="isShowSearch ? 'block' : 'none'" [style.display]="isShowSearch ? 'block' : 'none'"
class="search-result" class="search-result"
> >
<div *ngIf="searchProcessing"> <div style="position: relative;">
<mat-progress-bar mode="indeterminate"></mat-progress-bar> <div
*ngIf="searchProcessing"
style="position: absolute; width: 100%;"
>
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
</div> </div>
<div class="result-num"> <div class="result-num">
검색결과 검색결과
<span class="text-accent-color" <span class="text-accent-color"

View File

@ -4,7 +4,7 @@
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<div fxFlex class="setting-tab"> <div fxFlex class="setting-tab">
<mat-tab-group animationDuration="0ms" vertical> <mat-tab-group animationDuration="0ms">
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label>
<span class="mdi mdi-settings"></span> <span class="mdi mdi-settings"></span>

View File

@ -25,11 +25,30 @@
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
.mat-tab-body-wrapper { .mat-tab-group {
border-left: 1px solid #dddddd; flex-direction: row;
position: relative; .mat-tab-header {
height: 100%; width: 160px;
padding: 0 0 10px 10px; .mat-tab-labels {
flex-direction: column;
.mat-tab-label {
padding: 0 10px;
align-content: flex-start;
text-align: left;
align-items: self-start;
justify-content: flex-start;
}
.mat-ink-bar {
display: none;
}
}
}
.mat-tab-body-wrapper {
border-left: 1px solid #dddddd;
position: relative;
height: 100%;
padding: 0 0 10px 10px;
}
} }
} }
} }
@ -51,6 +70,8 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
.mat-tab-header { .mat-tab-header {
width: 160px;
flex-flow: column;
.mat-tab-label-container { .mat-tab-label-container {
.mat-tab-list { .mat-tab-list {
.mat-tab-labels { .mat-tab-labels {

View File

@ -320,7 +320,7 @@ $daesang-grey: (
mat-tab-group[vertical] { mat-tab-group[vertical] {
display: flex; display: flex;
flex-direction: row !important; flex-direction: row;
.mat-tab-labels { .mat-tab-labels {
display: flex; display: flex;

View File

@ -14,7 +14,12 @@
class="group-tree" class="group-tree"
> >
<!-- This is the tree node template for leaf nodes --> <!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" style="height: 80px;" matRipple> <mat-tree-node
*matTreeNodeDef="let node"
style="height: 80px;"
[attr.node-type]="node?.nodeType"
matRipple
>
<li> <li>
<div class="mat-tree-node"> <div class="mat-tree-node">
<ng-container <ng-container
@ -33,6 +38,7 @@
*matTreeNodeDef="let node; when: isHeader" *matTreeNodeDef="let node; when: isHeader"
class="tree-node-frame ucap-clickable" class="tree-node-frame ucap-clickable"
style="height: 80px;" style="height: 80px;"
[attr.node-type]="node?.nodeType"
matRipple matRipple
> >
<li class="tree-node-header" matTreeNodeToggle> <li class="tree-node-header" matTreeNodeToggle>

View File

@ -51,6 +51,21 @@
} }
} }
.mat-tree-node[aria-level='0'][node-type='Profile'] {
position: relative;
widows: 100px;
height: 100%;
li {
margin-left: 0;
width: 100%;
height: 100%;
.mat-tree-node {
width: 100%;
height: 100%;
}
}
}
.path { .path {
display: flex; display: flex;
padding: 6px 4px; padding: 6px 4px;

View File

@ -27,6 +27,7 @@ import { VirtualScrollTreeFlatDataSource } from '@ucap-webmessenger/ui';
import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar'; import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
import { Subscription } from 'rxjs';
enum NodeType { enum NodeType {
None = 'None', None = 'None',
@ -66,14 +67,10 @@ export class ExpansionPanelComponent
} }
const groupNode: GroupNode = { const groupNode: GroupNode = {
nodeType: NodeType.Profile, nodeType: NodeType.Profile,
userInfo,
children: [] children: []
}; };
groupNode.children.push({
nodeType: NodeType.Profile,
userInfo
});
this.profileNodes = [groupNode]; this.profileNodes = [groupNode];
this.refreshRootNodeList(); this.refreshRootNodeList();
@ -167,8 +164,8 @@ export class ExpansionPanelComponent
@ViewChild('cvsvGroup', { static: false }) @ViewChild('cvsvGroup', { static: false })
cvsvGroup: CdkVirtualScrollViewport; cvsvGroup: CdkVirtualScrollViewport;
@ViewChild('cvsvGroup', { read: PerfectScrollbarDirective, static: false }) @ViewChild(PerfectScrollbarDirective, { static: false })
perfectScrollbar: PerfectScrollbarDirective; psDirectiveRef?: PerfectScrollbarDirective;
NodeType = NodeType; NodeType = NodeType;
@ -183,6 +180,8 @@ export class ExpansionPanelComponent
groupList: { group: GroupDetailData; buddyList: UserInfo[] }[]; groupList: { group: GroupDetailData; buddyList: UserInfo[] }[];
treeControlExpansionChangeSubscription: Subscription;
constructor( constructor(
private changeDetectorRef: ChangeDetectorRef, private changeDetectorRef: ChangeDetectorRef,
private logger: NGXLogger private logger: NGXLogger
@ -217,23 +216,40 @@ export class ExpansionPanelComponent
); );
} }
ngOnInit() {} ngOnInit() {
this.treeControlExpansionChangeSubscription = this.treeControl.expansionModel.changed.subscribe(
() => {
this.psDirectiveRef.update();
}
);
}
ngOnDestroy(): void {} ngOnDestroy(): void {
if (!!this.treeControlExpansionChangeSubscription) {
this.treeControlExpansionChangeSubscription.unsubscribe();
}
}
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.dataSource.cdkVirtualScrollViewport = this.cvsvGroup; this.dataSource.cdkVirtualScrollViewport = this.cvsvGroup;
} }
// hasChild = (_: number, node: FlatNode) => node.expandable; // hasChild = (_: number, node: FlatNode) => node.expandable;
isHeader = (_: number, node: FlatNode) => 0 === node.level; isHeader = (_: number, node: FlatNode) =>
NodeType.Profile !== node.nodeType && 0 === node.level;
expandMore() { expandMore() {
this.groupTree.treeControl.expandAll(); this.groupTree.treeControl.expandAll();
if (!!this.psDirectiveRef) {
this.psDirectiveRef.scrollToTop();
}
} }
expandLess() { expandLess() {
this.groupTree.treeControl.collapseAll(); this.groupTree.treeControl.collapseAll();
if (!!this.psDirectiveRef) {
this.psDirectiveRef.scrollToTop();
}
} }
onClickMore(event: MouseEvent, group: GroupDetailData) { onClickMore(event: MouseEvent, group: GroupDetailData) {
@ -287,8 +303,8 @@ export class ExpansionPanelComponent
]; ];
this.dataSource.data = this.rootNodeList; this.dataSource.data = this.rootNodeList;
if (!!this.perfectScrollbar) { if (!!this.psDirectiveRef) {
this.perfectScrollbar.scrollToTop(); this.psDirectiveRef.scrollToTop();
} }
} }
} }

View File

@ -15,7 +15,7 @@
<input <input
matInput matInput
#searchWordInput #searchWordInput
placeholder="name" placeholder="검색어"
(keydown.enter)="onKeyDownEnter(searchWordInput.value)" (keydown.enter)="onKeyDownEnter(searchWordInput.value)"
/> />
<button <button

View File

@ -20,18 +20,25 @@
matTreeNodePaddingIndent="20" matTreeNodePaddingIndent="20"
class="tree-no-child" class="tree-no-child"
> >
<div class="tree-node-closer-container"> <div
<div class="tree-node-closer-top"></div> class="tree-node-closer-container"
*ngFor="let i of appendDivArray(node.level)"
>
<div
class="tree-node-closer-top"
[style.left.px]="20 - 20 * i"
[attr.last-node]="isLastNode(node, i) ? '' : null"
[attr.sub-node]="0 < i ? '' : null"
></div>
<div <div
class="tree-node-closer-bottom" class="tree-node-closer-bottom"
[attr.last-node]="isLastNode(node) ? '' : null" [style.left.px]="20 - 20 * i"
[attr.last-node]="isLastNode(node, i) ? '' : null"
[attr.sub-node]="0 < i ? '' : null"
></div> ></div>
</div> </div>
<li
(click)="onClickNode(node)" <li (click)="onClickNode(node)" matRipple>
matRipple
[attr.sub-node]="isParentLastNode(node) ? '' : null"
>
<div class="tree-node-body">{{ node.name }}</div> <div class="tree-node-body">{{ node.name }}</div>
</li> </li>
</mat-tree-node> </mat-tree-node>
@ -42,19 +49,25 @@
matTreeNodePaddingIndent="20" matTreeNodePaddingIndent="20"
class="tree-has-child" class="tree-has-child"
> >
<div *ngIf="0 !== node.level" class="tree-node-closer-container"> <div
<div class="tree-node-closer-top"></div> class="tree-node-closer-container"
*ngFor="let i of appendDivArray(node.level)"
>
<div
class="tree-node-closer-top"
[style.left.px]="20 - 20 * i"
[attr.last-node]="isLastNode(node, i) ? '' : null"
[attr.sub-node]="0 < i ? '' : null"
></div>
<div <div
class="tree-node-closer-bottom" class="tree-node-closer-bottom"
[style.left.px]="20 - 20 * i"
[attr.expanded]="treeControl.isExpanded(node) ? '' : null" [attr.expanded]="treeControl.isExpanded(node) ? '' : null"
[attr.last-node]="isLastNode(node) ? '' : null" [attr.last-node]="isLastNode(node, i) ? '' : null"
[attr.sub-node]="0 < i ? '' : null"
></div> ></div>
</div> </div>
<li <li (click)="onClickNode(node)" matRipple>
(click)="onClickNode(node)"
matRipple
[attr.sub-node]="isParentLastNode(node) ? '' : null"
>
<div class="tree-node-body"> <div class="tree-node-body">
<span class="horizontal-line"></span> <span class="horizontal-line"></span>
<button <button

View File

@ -13,7 +13,7 @@
border: 1px dotted grey; border: 1px dotted grey;
border-width: 0 0 1px 1px; border-width: 0 0 1px 1px;
top: -40px; top: -40px;
left: 20px; // left: 20px;
} }
.tree-node-closer-bottom { .tree-node-closer-bottom {
width: 15px; width: 15px;
@ -22,7 +22,14 @@
border: 1px dotted grey; border: 1px dotted grey;
border-width: 0 0 1px 1px; border-width: 0 0 1px 1px;
top: 0px; top: 0px;
left: 20px; // left: 20px;
}
.tree-node-closer-top[sub-node] {
border-width: 0 0 0 1px;
}
.tree-node-closer-top[sub-node][last-node] {
border-width: 0 0 0 0;
} }
.tree-node-closer-bottom[expanded] { .tree-node-closer-bottom[expanded] {
@ -31,6 +38,12 @@
.tree-node-closer-bottom[last-node] { .tree-node-closer-bottom[last-node] {
border-width: 0 0 1px 0px; border-width: 0 0 1px 0px;
} }
.tree-node-closer-bottom[sub-node] {
border-width: 0 0 0 1px;
}
.tree-node-closer-bottom[sub-node][last-node] {
border-width: 0 0 0 0;
}
} }
li { li {
@ -39,11 +52,6 @@
list-style-type: none; list-style-type: none;
} }
// li[sub-node] {
// border: 1px dotted grey;
// border-width: 0 0 0 1px;
// }
// li:last-child { // li:last-child {
// border-left: 1px solid white; // border-left: 1px solid white;
// margin-left: -41px; // margin-left: -41px;

View File

@ -19,6 +19,8 @@ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { VirtualScrollTreeFlatDataSource } from '@ucap-webmessenger/ui'; import { VirtualScrollTreeFlatDataSource } from '@ucap-webmessenger/ui';
import { ucapAnimations } from '@ucap-webmessenger/ui'; import { ucapAnimations } from '@ucap-webmessenger/ui';
import { trigger, transition, style, animate } from '@angular/animations'; import { trigger, transition, style, animate } from '@angular/animations';
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
import { Subscription } from 'rxjs';
interface OrganizationNode { interface OrganizationNode {
deptInfo: DeptInfo; deptInfo: DeptInfo;
@ -110,10 +112,15 @@ export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
@ViewChild('orgranizationTree', { static: false }) @ViewChild('orgranizationTree', { static: false })
orgranizationTree: MatTree<OrganizationNode>; orgranizationTree: MatTree<OrganizationNode>;
@ViewChild(PerfectScrollbarDirective, { static: false })
psDirectiveRef?: PerfectScrollbarDirective;
treeControl: FlatTreeControl<FlatNode>; treeControl: FlatTreeControl<FlatNode>;
treeFlattener: MatTreeFlattener<OrganizationNode, FlatNode>; treeFlattener: MatTreeFlattener<OrganizationNode, FlatNode>;
dataSource: VirtualScrollTreeFlatDataSource<OrganizationNode, FlatNode>; dataSource: VirtualScrollTreeFlatDataSource<OrganizationNode, FlatNode>;
treeControlExpansionChangeSubscription: Subscription;
constructor( constructor(
private changeDetectorRef: ChangeDetectorRef, private changeDetectorRef: ChangeDetectorRef,
private logger: NGXLogger private logger: NGXLogger
@ -141,10 +148,19 @@ export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
>(this.treeControl, this.treeFlattener); >(this.treeControl, this.treeFlattener);
} }
ngOnInit() {} ngOnInit() {
this.treeControlExpansionChangeSubscription = this.treeControl.expansionModel.changed.subscribe(
() => {
this.psDirectiveRef.update();
}
);
}
ngOnDestroy(): void { ngOnDestroy(): void {
this.logger.debug('-----------------------TreeComponent ngOnDestroy'); this.logger.debug('-----------------------TreeComponent ngOnDestroy');
if (!!this.treeControlExpansionChangeSubscription) {
this.treeControlExpansionChangeSubscription.unsubscribe();
}
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
@ -153,51 +169,70 @@ export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
hasChild = (_: number, node: FlatNode) => node.expandable; hasChild = (_: number, node: FlatNode) => node.expandable;
isLastNode(node: FlatNode): boolean { isLastNode(node: FlatNode, depth: number): boolean {
const i = this.findNodeIndex(node); const i = this.findNodeIndex(node, depth);
if (-1 === i) {
return false;
}
if (i === this.dataSource.expandedDataSubject.value.length - 1) { if (i === this.dataSource.expandedDataSubject.value.length - 1) {
return true; return true;
} }
if (node.level !== this.dataSource.expandedDataSubject.value[i + 1].level) { const n = this.dataSource.expandedDataSubject.value[i];
return true;
for (
let idx = i + 1;
idx < this.dataSource.expandedDataSubject.value.length;
idx++
) {
const element = this.dataSource.expandedDataSubject.value[idx];
if (n.level === element.level) {
return false;
}
if (n.level > element.level) {
return true;
}
} }
return false; return true;
} }
isParentLastNode(node: FlatNode): boolean { appendDivArray(level: number): number[] {
const pi = this.findParentNodeIndex(node); if (0 === level) {
if (-1 === pi) { return [];
return false;
} }
return this.isLastNode(this.dataSource.expandedDataSubject.value[pi]);
return Array.from({ length: level }, (_, i: number) => i);
} }
onClickNode(node: OrganizationNode) { onClickNode(node: OrganizationNode) {
this.selected.emit(node.deptInfo); this.selected.emit(node.deptInfo);
} }
private findNodeIndex(node: FlatNode): number { private findNodeIndex(node: FlatNode, depth: number): number {
return this.dataSource.expandedDataSubject.value.findIndex(n => { if (!node) {
return node.deptInfo.seq === n.deptInfo.seq;
});
}
private findParentNodeIndex(node: FlatNode): number {
const i = this.findNodeIndex(node);
if (-1 === i) {
return -1; return -1;
} }
const i = this.dataSource.expandedDataSubject.value.findIndex(n => {
return node.deptInfo.seq === n.deptInfo.seq;
});
for (let idx = i - 1; idx >= 0; idx--) { if (0 === depth) {
if ( return i;
this.dataSource.expandedDataSubject.value[idx].level === }
node.level - 1 return this.findNodeIndex(this.findParentNode(i), depth - 1);
) { }
return idx;
private findParentNode(index: number): FlatNode {
const node = this.dataSource.expandedDataSubject.value[index];
for (let idx = index - 1; idx >= 0; idx--) {
const n = this.dataSource.expandedDataSubject.value[idx];
if (n.level === node.level - 1) {
return n;
} }
} }
return -1; return undefined;
} }
} }

View File

@ -11,6 +11,15 @@
<span *ngIf="roomInfo.isTimeRoom" class="text-warn-color badge-timer"> <span *ngIf="roomInfo.isTimeRoom" class="text-warn-color badge-timer">
<mat-icon>timer</mat-icon> <mat-icon>timer</mat-icon>
</span> </span>
<!-- <div style="position: relative;">
<div
class="num text-accent-darkest thumbnail"
*ngIf="roomInfo.roomType === RoomType.Multi"
style="position: absolute; width: 40px; height: 40px; top: -40px"
>
{{ roomInfo.joinUserCount }}
</div>
</div> -->
</dt> </dt>
<dd class="info"> <dd class="info">
<div class="detail"> <div class="detail">

View File

@ -25,19 +25,19 @@ $thumbnail-msize: 40px;
} }
.badge-timer { .badge-timer {
position:absolute; position: absolute;
background-color: #ffffff; background-color: #ffffff;
width: 18px; width: 18px;
height: 18px; height: 18px;
border-radius: 50%; border-radius: 50%;
bottom: 14px; bottom: 14px;
left: 46px; left: 46px;
text-align:center; text-align: center;
.mat-icon{ .mat-icon {
font-size:14px; font-size: 14px;
width: 18px; width: 18px;
height: 18px; height: 18px;
line-height:18px; line-height: 18px;
} }
} }
@ -131,7 +131,7 @@ $thumbnail-msize: 40px;
font-size: 16px; font-size: 16px;
color: #666666; color: #666666;
margin-left: 4px; margin-left: 4px;
line-height:unset; line-height: unset;
} }
.num { .num {
font-size: 12px; font-size: 12px;
@ -158,6 +158,14 @@ $thumbnail-msize: 40px;
@include ellipsis(1); @include ellipsis(1);
} }
} }
.num {
font-size: 18px;
font: bold;
flex: none;
text-align: center;
background-color: rgba($color: #666666, $alpha: 0.5);
}
} }
.list-item { .list-item {

View File

@ -1,40 +1,37 @@
<div> <div>
<mat-list> <mat-list>
<h1 mat-subheader>테마</h1> <h1 mat-subheader>테마</h1>
<!--<ul class="theme-list">
<ul class="theme-list">
<li <li
class="theme-box default on" class="theme-box default"
(click)="onSelectedTabChange('theme-default')" (click)="onSelectedTabChange('theme-default')"
></li> ></li>
<li <li
class="theme-box lgRed" class="theme-box lgRed"
(click)="onSelectedTabChange('theme-lgRed')" (click)="onSelectedTabChange('theme-lgRed')"
></li> ></li>
</ul> </ul>-->
<mat-list-item> <mat-list-item class="theme-select">
<!-- <mat-tab-group <mat-tab-group
mat-stretch-tabs mat-stretch-tabs
animationDuration="0ms" animationDuration="0ms"
(selectedTabChange)="onSelectedTabChange($event)" (selectedTabChange)="onSelectedTabChange($event)"
fxLayout="row"
class="theme-list"
> >
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label class="theme-item">
<div class="theme-box default-theme"></div> <div class="theme-box default-theme"></div>
<div>기본값</div> <div class="theme-name">기본값</div>
</ng-template> </ng-template>
</mat-tab> </mat-tab>
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label class="theme-item">
<div class="theme-box lg-red-theme"></div> <div class="theme-box lg-red-theme"></div>
<div>LG Red</div> <div class="theme-name">LG Red</div>
</ng-template> </ng-template>
</mat-tab> </mat-tab>
</mat-tab-group> --> </mat-tab-group>
<!--
<span>기본값</span>
<span>어둡게</span>
<span>밝게</span> -->
</mat-list-item> </mat-list-item>
<mat-divider></mat-divider> <mat-divider></mat-divider>

View File

@ -1,34 +1,72 @@
.theme-list { ::ng-deep .mat-list-base {
.theme-select.mat-list-item {
position: relative;
height: 160px;
.mat-list-item-content {
flex-direction: column;
}
}
}
::ng-deep .theme-list {
position: relative; position: relative;
display: flex; display: flex;
flex-flow: row; flex-flow: row;
width: 100%;
margin: 10px; margin: 10px;
height: 120px; height: auto !important;
.mat-tab-header {
.theme-box { position: relative;
width: 140px; width: 100% !important;
height: 98px; .mat-tab-labels {
margin-right: 10px; position: relative;
border: 1px solid #dddddd; width: 100%;
background-size: 100% auto; flex-flow: row !important;
background-repeat: no-repeat; .mat-tab-label {
opacity: 0.7; width: 140px;
&.default { height: 120px;
background-image: url('../../../../ucap-webmessenger-app/src/assets/images/theme/theme-default.png'); .mat-tab-label-content {
position: relative;
flex-flow: column;
width: 100%;
}
}
} }
&.lgRed { .mat-ink-bar {
background-image: url('../../../../ucap-webmessenger-app/src/assets/images/theme/theme-lgRed.png'); display: none;
}
&.on {
border: 1px solid #333333;
opacity: 1;
} }
} }
.mat-tab-body-wrapper {
border-left: none;
}
}
.default-theme { .theme-item {
width: 140px;
height: 98px;
margin-right: 10px;
border: 1px solid #dddddd;
background-size: 100% auto;
background-repeat: no-repeat;
opacity: 0.7;
}
.theme-box {
width: 140px;
height: 98px;
border: 1px solid #dddddd;
background-size: 100% auto;
background-repeat: no-repeat;
&.default-theme {
background-image: url('../../../../ucap-webmessenger-app/src/assets/images/theme/theme-default.png'); background-image: url('../../../../ucap-webmessenger-app/src/assets/images/theme/theme-default.png');
} }
.lg-red-theme { &.lg-red-theme {
background-image: url('../../../../ucap-webmessenger-app/src/assets/images/theme/theme-lgRed.png'); background-image: url('../../../../ucap-webmessenger-app/src/assets/images/theme/theme-lgRed.png');
} }
} }
.brightness {
position: relative;
width: 100%;
display: flex;
flex-direction: row;
}

View File

@ -6,6 +6,7 @@ import {
EventEmitter EventEmitter
} from '@angular/core'; } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms'; import { FormGroup, FormBuilder } from '@angular/forms';
import { MatTabChangeEvent } from '@angular/material';
@Component({ @Component({
selector: 'ucap-settings-general', selector: 'ucap-settings-general',
@ -25,7 +26,19 @@ export class GeneralComponent implements OnInit {
ngOnInit() {} ngOnInit() {}
onSelectedTabChange(theme: string) { onSelectedTabChange(e: MatTabChangeEvent) {
let theme = 'theme-default';
switch (e.index) {
case 0:
theme = 'theme-default';
break;
case 1:
theme = 'theme-lgRed';
break;
default:
break;
}
this.selectTheme.emit(theme); this.selectTheme.emit(theme);
} }

View File

@ -1,35 +1,91 @@
<div class="ucap-binary-viewer-container"> <div class="ucap-binary-viewer-container">
<mat-toolbar class="ucap-binary-viewer-header"> <mat-toolbar class="ucap-binary-viewer-header">
<!--<mat-icon class="ucap-binary-viewer-icon">attachment</mat-icon>--> <!--<mat-icon class="ucap-binary-viewer-icon">attachment</mat-icon>-->
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" <svg
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="round" class="ucap-binary-viewer-icon"> 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="ucap-binary-viewer-icon"
>
<path <path
d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"> d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"
</path> ></path>
</svg> </svg>
<span class="ucap-binary-viewer-title">{{ fileInfo.fileName }}</span> <span class="ucap-binary-viewer-title">{{ fileInfo.fileName }}</span>
<span class="ucap-binary-viewer-spacer"></span> <span class="ucap-binary-viewer-spacer"></span>
<button mat-icon-button class="ucap-binary-viewer-action" matTooltip="다운로드" matTooltipPosition="below" aria-label="" <button
(click)="onClickDownload()"> mat-icon-button
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 24 24" fill="none" class="ucap-binary-viewer-action"
stroke="currentColor" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round"> matTooltip="다운로드"
<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" /> matTooltipPosition="below"
aria-label=""
(click)="onClickDownload()"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="21"
height="21"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
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> </svg>
</button> </button>
<span class="stroke-bar"></span> <span class="stroke-bar"></span>
<button mat-icon-button color="warn" class="ucap-binary-viewer-action" (click)="onClickClose()"> <button
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 24 24" fill="none" mat-icon-button
stroke="currentColor" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round"> color="warn"
class="ucap-binary-viewer-action"
(click)="onClickClose()"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="21"
height="21"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="butt"
stroke-linejoin="round"
>
<line x1="18" y1="6" x2="6" y2="18"></line> <line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line> <line x1="6" y1="6" x2="18" y2="18"></line>
</svg> </svg>
</button> </button>
</mat-toolbar> </mat-toolbar>
<div style="position: relative;">
<div
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
style="position: absolute; width: 100%;"
>
<mat-progress-bar
mode="determinate"
[value]="fileDownloadItem.downloadingProgress$ | async"
></mat-progress-bar>
</div>
</div>
<div class="ucap-binary-viewer-body"> <div class="ucap-binary-viewer-body">
<div class="ucap-binary-viewer-content-wrapper" fxLayout="column" fxLayout.xs="row" fxFlexFill <div
fxLayoutAlign="center center"> class="ucap-binary-viewer-content-wrapper"
fxLayout="column"
fxLayout.xs="row"
fxFlexFill
fxLayoutAlign="center center"
>
<div class="circle-box"> <div class="circle-box">
<div [ngClass]="['mime-icon', 'light', 'ico-' + fileInfo.fileExt]"> <div [ngClass]="['mime-icon', 'light', 'ico-' + fileInfo.fileExt]">
<div class="ico"></div> <div class="ico"></div>
@ -39,7 +95,12 @@
미리보기를 지원하지 않는 파일입니다. 미리보기를 지원하지 않는 파일입니다.
</div> </div>
<div> <div>
<button colori mat-raised-button aria-label="" (click)="onClickDownload()"> <button
colori
mat-raised-button
aria-label=""
(click)="onClickDownload()"
>
Download Download
</button> </button>
</div> </div>

View File

@ -53,7 +53,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
border:2px solid #ffffff; border:2px solid #ffffff;
background-color:rgba(256, 256, 256, 0.6); background-color:rgba(256, 256, 256, 0.7);
} }
.guide-msg{ .guide-msg{
font-size:16px; font-size:16px;

View File

@ -15,9 +15,15 @@
>delete</mat-icon >delete</mat-icon
> >
</mat-toolbar> </mat-toolbar>
<mat-progress-bar <div style="position: relative;">
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$" <div
mode="determinate" *ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
[value]="fileDownloadItem.downloadingProgress$ | async" style="position: absolute; width: 100%;"
></mat-progress-bar> >
<mat-progress-bar
mode="determinate"
[value]="fileDownloadItem.downloadingProgress$ | async"
></mat-progress-bar>
</div>
</div>
</div> </div>

View File

@ -143,11 +143,17 @@
</svg> </svg>
</button> </button>
</mat-toolbar> </mat-toolbar>
<mat-progress-bar <div style="position: relative;">
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$" <div
mode="determinate" *ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
[value]="fileDownloadItem.downloadingProgress$ | async" style="position: absolute; width: 100%;"
></mat-progress-bar> >
<mat-progress-bar
mode="determinate"
[value]="fileDownloadItem.downloadingProgress$ | async"
></mat-progress-bar>
</div>
</div>
<div class="ucap-image-viewer-body"> <div class="ucap-image-viewer-body">
<div <div
class="ucap-image-viewer-image-wrapper" class="ucap-image-viewer-image-wrapper"

View File

@ -5,28 +5,43 @@
<span class="ucap-sound-viewer-spacer"></span> <span class="ucap-sound-viewer-spacer"></span>
<button <button
mat-icon-button mat-icon-button
class="ucap-sound-viewer-action" class="ucap-image-viewer-action"
matTooltip="다운로드" matTooltip="다운로드"
matTooltipPosition="below" matTooltipPosition="below"
aria-label="" aria-label=""
(click)="onClickDownload()" (click)="onClickDownload()"
> >
<mat-icon>get_app</mat-icon> <!--<mat-icon>get_app</mat-icon>-->
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" 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>
</button> </button>
<span class="stroke-bar"></span>
<button <button
mat-raised-button mat-icon-button
color="primary" color="warn"
class="ucap-sound-viewer-action" class="ucap-image-viewer-action btn-close"
(click)="onClickClose()" (click)="onClickClose()"
> >
Close <svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button> </button>
</mat-toolbar> </mat-toolbar>
<mat-progress-bar <div style="position: relative;">
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$" <div
mode="determinate" *ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
[value]="fileDownloadItem.downloadingProgress$ | async" style="position: absolute; width: 100%;"
></mat-progress-bar> >
<mat-progress-bar
mode="determinate"
[value]="fileDownloadItem.downloadingProgress$ | async"
></mat-progress-bar>
</div>
</div>
<div class="ucap-sound-viewer-body"> <div class="ucap-sound-viewer-body">
<div <div
class="ucap-sound-viewer-sound-icon" class="ucap-sound-viewer-sound-icon"
@ -44,45 +59,49 @@
(loadstart)="onLoadStartAudio()" (loadstart)="onLoadStartAudio()"
(loadeddata)="onLoadedDataAudio()" (loadeddata)="onLoadedDataAudio()"
></audio> ></audio>
<mat-icon class="ucap-sound-viewer-icon">music_note</mat-icon> <div class="circle-box">
</div> <mat-icon class="ucap-sound-viewer-icon">music_note</mat-icon>
<div
class="ucap-sound-viewer-sound-time"
fxLayout="row"
fxLayout.xs="column"
fxLayoutAlign="center center"
>
<mat-slider
#timeSlider
min="0"
[max]="duration"
[value]="currentTime"
(change)="onChangeTimeSlider($event)"
>
</mat-slider>
</div>
<div
class="ucap-sound-viewer-sound-controls"
fxLayout="row"
fxLayout.xs="column"
fxLayoutAlign="center center"
>
<div class="ucap-sound-viewer-sound-time-current">
{{ currentTime | ucapSecondsToMinutes }}
</div> </div>
<span class="ucap-sound-viewer-spacer"></span> </div>
<button <div class="viewer-bottom">
mat-icon-button <div
class="ucap-sound-viewer-action" class="ucap-sound-viewer-sound-time"
[matTooltip]="playing ? '멈춤' : '재생'" fxLayout="row"
aria-label="" fxLayout.xs="column"
(click)="onClickPlayOrPause()" fxLayoutAlign="center center"
> >
<mat-icon>{{ playing ? 'pause' : 'play_arrow' }}</mat-icon> <mat-slider
</button> #timeSlider
<span class="ucap-sound-viewer-spacer"></span> min="0"
<div class="ucap-sound-viewer-sound-time-total"> [max]="duration"
{{ duration | ucapSecondsToMinutes }} [value]="currentTime"
(change)="onChangeTimeSlider($event)"
>
</mat-slider>
</div>
<div
class="ucap-sound-viewer-sound-controls"
fxLayout="row"
fxLayout.xs="column"
fxLayoutAlign="center center"
>
<div class="ucap-sound-viewer-sound-time-current">
{{ currentTime | ucapSecondsToMinutes }}
</div>
<span class="ucap-sound-viewer-spacer"></span>
<button
mat-icon-button
class="ucap-sound-viewer-action"
[matTooltip]="playing ? '멈춤' : '재생'"
aria-label=""
(click)="onClickPlayOrPause()"
>
<mat-icon>{{ playing ? 'pause' : 'play_arrow' }}</mat-icon>
</button>
<span class="ucap-sound-viewer-spacer"></span>
<div class="ucap-sound-viewer-sound-time-total">
{{ duration | ucapSecondsToMinutes }}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,40 +4,73 @@
.ucap-sound-viewer-header { .ucap-sound-viewer-header {
width: 100%; width: 100%;
height: 50px; height: 60px;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.6);
background-color: #333333;
.ucap-sound-viewer-icon { .ucap-sound-viewer-icon {
margin-right: 10px;
} }
.ucap-sound-viewer-title { .ucap-sound-viewer-title {
font-size:16px;
}
.stroke-bar {
width: 1px;
height: 30px;
background-color: rgba(256, 256, 256, 0.3);
margin: 0 10px;
}
.ucap-sound-viewer-action {
&:hover {
opacity: 0.7;
}
} }
} }
.ucap-sound-viewer-body { .ucap-sound-viewer-body {
position: relative; position: relative;
background-color: white;
width: 100%; width: 100%;
height: 100%; height: calc(100% - 60px);
padding-bottom: 70px;
.ucap-sound-viewer-sound-icon { .circle-box{
width: 100%; display:flex;
height: calc(100% - 60px); width:140px;
} height:140px;
.ucap-sound-viewer-sound-time { border-radius:50%;
width: 100%; justify-content: center;
height: 30px; align-items: center;
} border:2px solid #ffffff;
.ucap-sound-viewer-sound-controls { background-color:rgba(256, 256, 256, 0.7);
width: 100%; .mat-icon{
height: 30px; font-size: 100px;
height: 100px;
.ucap-sound-viewer-sound-time-current { width: 100px;
padding-left: 30px;
} }
}
.ucap-sound-viewer-sound-time-total { .ucap-sound-viewer-sound-icon{
padding-right: 30px; width: 100%;
height: calc(100% - 80px);
}
.viewer-bottom{
background-color: #212121;
color:#ffffff;
.ucap-sound-viewer-sound-time {
width: 100%;
height: 30px;
}
.ucap-sound-viewer-sound-controls {
width: 100%;
height: 50px;
.ucap-sound-viewer-sound-time-current {
padding-left: 30px;
}
.ucap-sound-viewer-sound-time-total {
padding-right: 30px;
}
} }
} }
} }
@ -45,9 +78,22 @@
flex: 1 1 auto; flex: 1 1 auto;
} }
.ucap-sound-viewer-action { .ucap-sound-viewer-action {
.mat-icon{
font-size: 40px;
width: 100%;
height: 100%;
line-height:40px;
}
} }
} }
mat-slider { mat-slider {
width: 95%; width: 94%;
}
::ng-deep .mat-slider-horizontal .mat-slider-track-background{
background-color: #999999 !important;
}
::ng-deep .mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{
border-color: #999999 !important;
} }

View File

@ -73,11 +73,17 @@
</svg> </svg>
</button> </button>
</mat-toolbar> </mat-toolbar>
<mat-progress-bar <div style="position: relative;">
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$" <div
mode="determinate" *ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
[value]="fileDownloadItem.downloadingProgress$ | async" style="position: absolute; width: 100%;"
></mat-progress-bar> >
<mat-progress-bar
mode="determinate"
[value]="fileDownloadItem.downloadingProgress$ | async"
></mat-progress-bar>
</div>
</div>
<div class="ucap-video-viewer-body"> <div class="ucap-video-viewer-body">
<div <div
class="ucap-video-viewer-video-icon" class="ucap-video-viewer-video-icon"

View File

@ -71,7 +71,7 @@ export class SplashScreenService {
.build([ .build([
style({ opacity: '1' }), style({ opacity: '1' }),
animate( animate(
'400ms ease', '700ms ease',
style({ style({
opacity: '0', opacity: '0',
display: 'none', display: 'none',