This commit is contained in:
병준 박 2019-11-09 17:36:03 +09:00
commit 3fc5fa254a
28 changed files with 479 additions and 37 deletions

View File

@ -19,6 +19,7 @@
<app-layout-chat-left-sidenav-group <app-layout-chat-left-sidenav-group
class="left-group-side" class="left-group-side"
(newGroupAndMember)="onClickNewGroupAndMember($event)" (newGroupAndMember)="onClickNewGroupAndMember($event)"
(openProfile)="onClickOpenProfile($event)"
></app-layout-chat-left-sidenav-group> ></app-layout-chat-left-sidenav-group>
</mat-tab> </mat-tab>
<mat-tab [aria-label]="MainMenu.Chat"> <mat-tab [aria-label]="MainMenu.Chat">

View File

@ -1,5 +1,5 @@
import { UserSelectDialogType } from './../../../types/userselect.dialog.type'; import { UserSelectDialogType } from './../../../types/userselect.dialog.type';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui'; import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui';
import { import {
@ -36,6 +36,11 @@ export enum MainMenu {
animations: ucapAnimations animations: ucapAnimations
}) })
export class LeftSideComponent implements OnInit { export class LeftSideComponent implements OnInit {
@Output()
openProfile = new EventEmitter<
UserInfo | UserInfoSS | UserInfoF | UserInfoDN
>();
badgeChatUnReadCount$: Observable<number>; badgeChatUnReadCount$: Observable<number>;
/** 조직도에서 부서원 선택 */ /** 조직도에서 부서원 선택 */
@ -122,6 +127,10 @@ export class LeftSideComponent implements OnInit {
} }
} }
onClickOpenProfile(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
this.openProfile.emit(userInfo);
}
onSelectedTabChange(event: MatTabChangeEvent) { onSelectedTabChange(event: MatTabChangeEvent) {
this.setFabInitial(event.tab.ariaLabel); this.setFabInitial(event.tab.ariaLabel);
} }

View File

@ -43,7 +43,7 @@
height: 100%; height: 100%;
.mat-form-field-flex { .mat-form-field-flex {
height: 59px; height: 59px;
padding: 0 20px; padding: 0 10px 0 20px;
align-items: center; align-items: center;
.mat-form-field-infix { .mat-form-field-infix {
width: 100%; width: 100%;

View File

@ -62,6 +62,7 @@
[presence]="getStatusBulkInfo(userInfo) | async" [presence]="getStatusBulkInfo(userInfo) | async"
[sessionVerinfo]="sessionVerinfo" [sessionVerinfo]="sessionVerinfo"
(click)="onSelectBuddy(userInfo)" (click)="onSelectBuddy(userInfo)"
(openProfile)="onClickOpenProfile($event)"
(contextmenu)="onContextMenuProfile($event, userInfo)" (contextmenu)="onContextMenuProfile($event, userInfo)"
> >
</ucap-profile-user-list-item> </ucap-profile-user-list-item>
@ -82,6 +83,7 @@
[presence]="getStatusBulkInfo(userInfo) | async" [presence]="getStatusBulkInfo(userInfo) | async"
[sessionVerinfo]="sessionVerinfo" [sessionVerinfo]="sessionVerinfo"
(click)="onSelectBuddy(userInfo)" (click)="onSelectBuddy(userInfo)"
(openProfile)="onClickOpenProfile($event)"
> >
</ucap-profile-user-list-item> </ucap-profile-user-list-item>
</div> </div>

View File

@ -66,6 +66,10 @@ import {
export class GroupComponent implements OnInit, OnDestroy { export class GroupComponent implements OnInit, OnDestroy {
@Output() @Output()
newGroupAndMember = new EventEmitter(); newGroupAndMember = new EventEmitter();
@Output()
openProfile = new EventEmitter<
UserInfo | UserInfoSS | UserInfoF | UserInfoDN
>();
@ViewChild('groupExpansionPanel', { static: true }) @ViewChild('groupExpansionPanel', { static: true })
groupExpansionPanel: GroupExpansionPanelComponent; groupExpansionPanel: GroupExpansionPanelComponent;
@ -304,6 +308,10 @@ export class GroupComponent implements OnInit, OnDestroy {
} }
} }
onClickOpenProfile(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
this.openProfile.emit(userInfo);
}
onContextMenuProfile( onContextMenuProfile(
event: MouseEvent, event: MouseEvent,
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN

View File

@ -128,6 +128,7 @@
(save)="onSave($event)" (save)="onSave($event)"
(fileViewer)="onFileViewer($event)" (fileViewer)="onFileViewer($event)"
(contextMenu)="onContextMenuMessage($event)" (contextMenu)="onContextMenuMessage($event)"
(openProfile)="onClickOpenProfile($event)"
> >
</ucap-chat-messages> </ucap-chat-messages>
</perfect-scrollbar> </perfect-scrollbar>

View File

@ -4,7 +4,9 @@ import {
OnDestroy, OnDestroy,
ViewChild, ViewChild,
ElementRef, ElementRef,
AfterViewInit AfterViewInit,
Output,
EventEmitter
} from '@angular/core'; } from '@angular/core';
import { import {
ucapAnimations, ucapAnimations,
@ -90,6 +92,9 @@ import {
animations: ucapAnimations animations: ucapAnimations
}) })
export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit { export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
@Output()
openProfile = new EventEmitter<UserInfo>();
@ViewChild('messageBoxContainer', { static: true }) @ViewChild('messageBoxContainer', { static: true })
private messageBoxContainer: ElementRef; private messageBoxContainer: ElementRef;
@ -890,4 +895,13 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
break; break;
} }
} }
onClickOpenProfile(userInfo: UserInfo) {
if (
this.roomInfo.roomType !== RoomType.Allim &&
this.roomInfo.roomType !== RoomType.Bot
) {
this.openProfile.emit(userInfo);
}
}
} }

View File

@ -1,4 +1,5 @@
import { DIALOGS as CHAT_DIALOGS } from './chat'; import { DIALOGS as CHAT_DIALOGS } from './chat';
import { DIALOGS as GROUP_DIALOGS } from './group'; import { DIALOGS as GROUP_DIALOGS } from './group';
import { DIALOGS as PROFILE_DIALOGS } from './profile';
export const DIALOGS = [...CHAT_DIALOGS, ...GROUP_DIALOGS]; export const DIALOGS = [...CHAT_DIALOGS, ...GROUP_DIALOGS, ...PROFILE_DIALOGS];

View File

@ -0,0 +1,3 @@
import { ProfileDialogComponent } from './profile.dialog.component';
export const DIALOGS = [ProfileDialogComponent];

View File

@ -0,0 +1,9 @@
<ucap-profile-profile
[userInfo]="data.userInfo"
[profileImageRoot]="sessionVerinfo.profileRoot"
[isMe]="isMe"
[isBuddy]="isBuddy"
[isFavorit]="isFavorit"
(openChat)="onClickChat($event)"
>
</ucap-profile-profile>

View File

@ -0,0 +1,27 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ProfileDialogComponent } from './profile.dialog.component';
describe('ProfileDialogComponent', () => {
let component: ProfileDialogComponent;
let fixture: ComponentFixture<ProfileDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ProfileDialogComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProfileDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,83 @@
import { Component, OnInit, Inject, ViewChild } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
import { KEY_VER_INFO } from '@app/types/ver-info.type';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import {
UserInfoSS,
UserInfoF,
UserInfoDN
} from '@ucap-webmessenger/protocol-query';
import { DialogService } from '@ucap-webmessenger/ui';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { map } from 'rxjs/operators';
export interface ProfileDialogData {
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}
export interface ProfileDialogResult {}
@Component({
selector: 'app-profile.dialog',
templateUrl: './profile.dialog.component.html',
styleUrls: ['./profile.dialog.component.scss']
})
export class ProfileDialogComponent implements OnInit {
loginRes: LoginResponse;
sessionVerinfo: VersionInfo2Response;
isMe: boolean;
isBuddy: boolean;
isFavorit: boolean;
constructor(
public dialogRef: MatDialogRef<ProfileDialogData, ProfileDialogResult>,
@Inject(MAT_DIALOG_DATA) public data: ProfileDialogData,
private dialogService: DialogService,
private sessionStorageService: SessionStorageService,
private store: Store<any>
) {
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
KEY_VER_INFO
);
this.loginRes = this.sessionStorageService.get<LoginResponse>(
KEY_LOGIN_RES_INFO
);
}
ngOnInit() {
this.isMe = this.loginRes.userSeq === this.data.userInfo.seq;
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2),
map(buddyList => {
const users = buddyList.filter(
buddy => buddy.seq === this.data.userInfo.seq
);
this.isBuddy = users.length > 0;
if (this.isBuddy) {
this.isFavorit = users[0].isFavorit;
}
})
);
}
onClickChat(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
if (userInfo.seq === this.loginRes.userSeq) {
this.store.dispatch(
ChatStore.openRoom({ userSeqList: [this.loginRes.talkWithMeBotSeq] })
);
} else {
this.store.dispatch(ChatStore.openRoom({ userSeqList: [userInfo.seq] }));
}
this.dialogRef.close();
}
}

View File

@ -1,23 +1,29 @@
<div class="container"> <div class="container">
<div class="left-side"> <div class="left-side">
<app-layout-messenger-left-side></app-layout-messenger-left-side> <app-layout-messenger-left-side
(openProfile)="onClickOpenProfile($event)"
></app-layout-messenger-left-side>
</div> </div>
<mat-drawer-container class="contents" autosize> <mat-drawer-container class="contents" autosize>
<div class="messages"> <mat-drawer #drawer mode="over">
<!-- <app-layout-messenger-intro
(click)="drawer.toggle()"
*ngIf="!(this.selectedChat$ | async)"
></app-layout-messenger-intro> -->
<app-layout-messenger-intro
*ngIf="!(this.selectedChat$ | async)"
></app-layout-messenger-intro>
<app-layout-messenger-messages
*ngIf="!!(this.selectedChat$ | async)"
></app-layout-messenger-messages>
</div>
<mat-drawer #drawer mode="side" position="end">
<p>Auto-resizing sidenav</p> <p>Auto-resizing sidenav</p>
</mat-drawer> </mat-drawer>
<div class="messages">
<app-layout-messenger-intro
(click)="drawer.toggle()"
*ngIf="!(this.selectedChat$ | async)"
></app-layout-messenger-intro>
<!-- <app-layout-messenger-intro
*ngIf="!(this.selectedChat$ | async)"
></app-layout-messenger-intro> -->
<app-layout-messenger-messages
*ngIf="!!(this.selectedChat$ | async)"
(openProfile)="onClickOpenProfile($event)"
></app-layout-messenger-messages>
</div>
<!-- <mat-drawer #drawer mode="side" position="end">
<p>Auto-resizing sidenav</p>
</mat-drawer> -->
</mat-drawer-container> </mat-drawer-container>
<!-- <div class="right-side"> <!-- <div class="right-side">

View File

@ -10,8 +10,21 @@ import {
UCAP_NATIVE_SERVICE, UCAP_NATIVE_SERVICE,
NativeService NativeService
} from '@ucap-webmessenger/native'; } from '@ucap-webmessenger/native';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import {
UserInfoSS,
UserInfoF,
UserInfoDN
} from '@ucap-webmessenger/protocol-query';
import { StatusProtocolService } from '@ucap-webmessenger/protocol-status'; import { StatusProtocolService } from '@ucap-webmessenger/protocol-status';
import { StatusType, StatusCode } from '@ucap-webmessenger/core'; import { StatusType, StatusCode } from '@ucap-webmessenger/core';
import { DialogService } from '@ucap-webmessenger/ui';
import {
ProfileDialogComponent,
ProfileDialogData,
ProfileDialogResult
} from '@app/layouts/messenger/dialogs/profile/profile.dialog.component';
@Component({ @Component({
selector: 'app-page-messenger-main', selector: 'app-page-messenger-main',
@ -25,7 +38,8 @@ export class MainPageComponent implements OnInit {
constructor( constructor(
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private store: Store<any>, private store: Store<any>,
private statusProtocolService: StatusProtocolService private statusProtocolService: StatusProtocolService,
private dialogService: DialogService
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
@ -60,4 +74,16 @@ export class MainPageComponent implements OnInit {
this.idleStateChangedSubscription.unsubscribe(); this.idleStateChangedSubscription.unsubscribe();
} }
} }
onClickOpenProfile(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
this.dialogService.open<
ProfileDialogComponent,
ProfileDialogData,
ProfileDialogResult
>(ProfileDialogComponent, {
data: {
userInfo
}
});
}
} }

View File

@ -51,8 +51,7 @@ $lg-red: (
200: #f48fb1, 200: #f48fb1,
300: #f06292, 300: #f06292,
400: #ef4c73, 400: #ef4c73,
/* 400: #ec407a,*/ /* 400: #ec407a,*/ 500: #ed097e,
500: #ed097e,
600: #d81b60, 600: #d81b60,
700: #c2185b, 700: #c2185b,
800: #ad1457, 800: #ad1457,
@ -90,6 +89,14 @@ $lg-red: (
$background: map-get($theme, background); $background: map-get($theme, background);
$foreground: map-get($theme, foreground); $foreground: map-get($theme, foreground);
.bg-primary-dark{
background: mat-color($primary, 900);
color: mat-color($primary, default-contrast);
}
.bg-primary-light{
background: mat-color($primary, 300);
color: mat-color($primary, default-contrast);
}
.bg-primary-color { .bg-primary-color {
background: mat-color($primary); background: mat-color($primary);
color: mat-color($primary, default-contrast); color: mat-color($primary, default-contrast);
@ -128,6 +135,10 @@ $lg-red: (
.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);
}*/
.mat-form-field-appearance-legacy { .mat-form-field-appearance-legacy {
.mat-form-field-label { .mat-form-field-label {
color: mat-color($primary); color: mat-color($primary);
@ -145,8 +156,12 @@ $lg-red: (
.app-dialog-full .mat-dialog-container { .app-dialog-full .mat-dialog-container {
overflow: hidden; overflow: hidden;
padding: 0px; padding: 0px;
background-color: rgba($color: #000000, $alpha: 0.3); background-color: rgba($color: #000000, $alpha: 0.7);
box-shadow: none; box-shadow: none;
border-radius: 0px; border-radius: 0px;
} }
.btn-main-float .bg-accent-dark{
background: mat-color($accent, 600);
color: mat-color($primary, default-contrast);
}
} }

View File

@ -78,6 +78,7 @@
[base]="profileImageRoot" [base]="profileImageRoot"
[path]="getUserProfile(message.senderSeq)" [path]="getUserProfile(message.senderSeq)"
[default]="'assets/images/img_nophoto_50.png'" [default]="'assets/images/img_nophoto_50.png'"
(click)="onClickOpenProfile($event, getUerInfo(message.senderSeq))"
/> />
<!-- <ucap-ui-imaage <!-- <ucap-ui-imaage
[style]="'width: 50px; height: 50px;'" [style]="'width: 50px; height: 50px;'"

View File

@ -41,6 +41,8 @@ export class MessagesComponent implements OnInit {
@Input() @Input()
sessionVerInfo: VersionInfo2Response; sessionVerInfo: VersionInfo2Response;
@Output()
openProfile = new EventEmitter<UserInfo>();
@Output() @Output()
moreEvent = new EventEmitter<number>(); moreEvent = new EventEmitter<number>();
@Output() @Output()
@ -95,6 +97,18 @@ export class MessagesComponent implements OnInit {
} }
return ''; return '';
} }
getUerInfo(seq: number): UserInfo {
if (!this.userInfos) {
return null;
}
const userInfo: UserInfo[] = this.userInfos.filter(
user => user.seq === seq
);
if (!!userInfo && userInfo.length > 0) {
return userInfo[0];
}
}
getUnreadCount(message: Info<EventJson>): string | number { getUnreadCount(message: Info<EventJson>): string | number {
const unreadCnt = this.userInfos.filter(user => { const unreadCnt = this.userInfos.filter(user => {
@ -145,6 +159,13 @@ export class MessagesComponent implements OnInit {
return false; return false;
} }
onClickOpenProfile(event: MouseEvent, userInfo: UserInfo) {
event.preventDefault();
event.stopPropagation();
this.openProfile.emit(userInfo);
}
onClickMore(event: any) { onClickMore(event: any) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();

View File

@ -0,0 +1,76 @@
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>
<span>{{ userInfo.name }}</span>
<span>{{ userInfo.grade }}</span>
</mat-card-title>
<mat-card-subtitle>{{ userInfo.deptName }}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<ul>
<li>
<img
ucapImage
[base]="profileImageRoot"
[path]="userInfo.profileImageFile"
[default]="'assets/images/img_nophoto_50.png'"
/>
</li>
<li>
<mat-icon>chat</mat-icon>
{{ userInfo.intro }}
</li>
<li>
<mat-icon>email</mat-icon>
{{ userInfo.email }}
</li>
<li>
<mat-icon>local_phone</mat-icon>
{{ userInfo.lineNumber }}
</li>
<li>
<mat-icon>phone_android</mat-icon>
{{ userInfo.hpNumber }}
</li>
</ul>
</mat-card-content>
<mat-card-actions>
<div fxFlex fxLayout="row" fxLayoutAlign="space-around center">
<button
mat-mini-fab
[matTooltip]="isMe ? 'MyTalk' : '1:1 대화'"
matTooltipPosition="above"
(click)="onClickOpenChat()"
>
<mat-icon>chat</mat-icon>
</button>
<button
mat-mini-fab
*ngIf="!isMe"
matTooltip="전화"
matTooltipPosition="above"
(click)="onClickCall()"
>
<mat-icon>call</mat-icon>
</button>
<button
mat-mini-fab
*ngIf="!isMe"
matTooltip="화상회의"
matTooltipPosition="above"
(click)="onClickVideoConference()"
>
<mat-icon>videocam</mat-icon>
</button>
<button
mat-mini-fab
*ngIf="!isMe"
matTooltip="쪽지"
matTooltipPosition="above"
(click)="onClickMessage()"
>
<mat-icon>sms</mat-icon>
</button>
</div>
</mat-card-actions>
</mat-card>

View File

@ -0,0 +1,3 @@
.example-card {
width: 400px;
}

View File

@ -0,0 +1,28 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ProfileComponent } from './profile.component';
describe('ProfileComponent', () => {
let component: ProfileComponent;
let fixture: ComponentFixture<ProfileComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProfileComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,43 @@
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import {
UserInfoSS,
UserInfoF,
UserInfoDN
} from '@ucap-webmessenger/protocol-query';
@Component({
selector: 'ucap-profile-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss']
})
export class ProfileComponent implements OnInit {
@Input()
profileImageRoot: string;
@Input()
isMe: boolean;
@Input()
isBuddy: boolean;
@Input()
isFavorit: boolean;
@Input()
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
@Output()
openChat = new EventEmitter<UserInfo | UserInfoSS | UserInfoF | UserInfoDN>();
constructor() {}
ngOnInit() {}
onClickOpenChat() {
this.openChat.emit(this.userInfo);
}
onClickCall() {}
onClickVideoConference() {}
onClickMessage() {}
}

View File

@ -15,6 +15,7 @@
[base]="profileImageRoot" [base]="profileImageRoot"
[path]="userInfo.profileImageFile" [path]="userInfo.profileImageFile"
[default]="'assets/images/img_nophoto_50.png'" [default]="'assets/images/img_nophoto_50.png'"
(click)="onClickOpenProfile($event, userInfo)"
/> />
</dt> </dt>
<dd class="info"> <dd class="info">

View File

@ -49,6 +49,10 @@ export class UserListItemComponent implements OnInit {
isChecked: boolean; isChecked: boolean;
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN; userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}>(); }>();
@Output()
openProfile = new EventEmitter<
UserInfo | UserInfoSS | UserInfoF | UserInfoDN
>();
PresenceType = PresenceType; PresenceType = PresenceType;
@ -98,4 +102,14 @@ export class UserListItemComponent implements OnInit {
userInfo userInfo
}); });
} }
onClickOpenProfile(
event: MouseEvent,
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN
) {
event.preventDefault();
event.stopPropagation();
this.openProfile.emit(userInfo);
}
} }

View File

@ -1,3 +1,5 @@
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatCardModule } from '@angular/material/card';
import { NgModule, ModuleWithProviders } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
@ -11,8 +13,9 @@ import { UCapUiModule } from '@ucap-webmessenger/ui';
import { ListItemComponent } from './components/list-item.component'; import { ListItemComponent } from './components/list-item.component';
import { UserListItemComponent } from './components/user-list-item.component'; import { UserListItemComponent } from './components/user-list-item.component';
import { ProfileComponent } from './components/profile.component';
const COMPONENTS = [ListItemComponent, UserListItemComponent]; const COMPONENTS = [ListItemComponent, UserListItemComponent, ProfileComponent];
const SERVICES = []; const SERVICES = [];
@ -24,6 +27,8 @@ const SERVICES = [];
MatIconModule, MatIconModule,
MatRippleModule, MatRippleModule,
MatCheckboxModule, MatCheckboxModule,
MatCardModule,
MatTooltipModule,
UCapUiModule UCapUiModule
], ],

View File

@ -1,6 +1,11 @@
<div class="ucap-image-viewer-container"> <div class="ucap-image-viewer-container">
<mat-toolbar color="accent" class="ucap-image-viewer-header"> <mat-toolbar class="ucap-image-viewer-header bg-primary-dark">
<mat-icon class="ucap-image-viewer-icon">image</mat-icon> <!--<mat-icon class="ucap-image-viewer-icon">image</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" class="ucap-image-viewer-icon">
<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 class="ucap-image-viewer-title">{{ fileInfo.fileName }}</span> <span class="ucap-image-viewer-title">{{ fileInfo.fileName }}</span>
<span class="ucap-image-viewer-spacer"></span> <span class="ucap-image-viewer-spacer"></span>
@ -11,7 +16,12 @@
matTooltipPosition="below" matTooltipPosition="below"
aria-label="" aria-label=""
> >
<mat-icon>settings_overscan</mat-icon> <!--<mat-icon>settings_overscan</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.8 3.8l16.4 16.4M20.2 3.8L3.8 20.2M15 3h6v6M9 3H3v6M15 21h6v-6M9 21H3v-6" />
</svg>
</button> </button>
<button <button
mat-icon-button mat-icon-button
@ -20,7 +30,8 @@
matTooltipPosition="below" matTooltipPosition="below"
aria-label="" aria-label=""
> >
<mat-icon>zoom_out</mat-icon> <!--<mat-icon>zoom_out</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"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>
</button> </button>
<button <button
mat-icon-button mat-icon-button
@ -29,7 +40,14 @@
matTooltipPosition="below" matTooltipPosition="below"
aria-label="" aria-label=""
> >
<mat-icon>zoom_in</mat-icon> <!--<mat-icon>zoom_in</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">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
<line x1="11" y1="8" x2="11" y2="14"></line>
<line x1="8" y1="11" x2="14" y2="11"></line>
</svg>
</button> </button>
<button <button
mat-icon-button mat-icon-button
@ -39,16 +57,24 @@
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-image-viewer-action" class="ucap-image-viewer-action btn-close"
matTooltip="뷰어닫기"
(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>
<div class="ucap-image-viewer-body"> <div class="ucap-image-viewer-body">

View File

@ -4,28 +4,47 @@
.ucap-image-viewer-header { .ucap-image-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-image-viewer-icon { .ucap-image-viewer-icon {
margin-right: 10px;
} }
.ucap-image-viewer-title { .ucap-image-viewer-title {
font-size: 16px;
} }
.ucap-image-viewer-spacer { .ucap-image-viewer-spacer {
flex: 1 1 auto; flex: 1 1 auto;
} }
.stroke-bar {
width: 1px;
height: 30px;
background-color: rgba(256, 256, 256, 0.3);
margin: 0 10px;
}
.ucap-image-viewer-action { .ucap-image-viewer-action {
&:hover {
opacity: 0.7;
}
} }
} }
.ucap-image-viewer-body { .ucap-image-viewer-body {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: calc(100% - 60px);
.ucap-image-viewer-image-wrapper { .ucap-image-viewer-image-wrapper {
height: 100%;
padding: 20px;
background-color: rgba(0, 0, 0, 0.7);
img {
height: inherit;
}
} }
} }
} }

View File

@ -3,7 +3,7 @@
*ngIf="fabTogglerState === 'active'" *ngIf="fabTogglerState === 'active'"
(click)="onToggleFab()" (click)="onToggleFab()"
></div> ></div>
<div class="fab-container"> <div class="fab-container btn-main-float">
<button mat-fab class="fab-toggler bg-accent-dark" (click)="onToggleFab()"> <button mat-fab class="fab-toggler bg-accent-dark" (click)="onToggleFab()">
<mat-icon [@fabToggler]="fabTogglerState">add</mat-icon> <mat-icon [@fabToggler]="fabTogglerState">add</mat-icon>
</button> </button>