user profile / added prototype

This commit is contained in:
leejh 2019-11-08 13:35:39 +09:00
parent 75627e0a16
commit d71100f66f
23 changed files with 401 additions and 19 deletions

View File

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

View File

@ -1,5 +1,5 @@
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 { ucapAnimations, DialogService } from '@ucap-webmessenger/ui';
import {
@ -36,6 +36,11 @@ export enum MainMenu {
animations: ucapAnimations
})
export class LeftSideComponent implements OnInit {
@Output()
openProfile = new EventEmitter<
UserInfo | UserInfoSS | UserInfoF | UserInfoDN
>();
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) {
this.setFabInitial(event.tab.ariaLabel);
}

View File

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

View File

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

View File

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

View File

@ -4,7 +4,9 @@ import {
OnDestroy,
ViewChild,
ElementRef,
AfterViewInit
AfterViewInit,
Output,
EventEmitter
} from '@angular/core';
import {
ucapAnimations,
@ -89,6 +91,9 @@ import {
animations: ucapAnimations
})
export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
@Output()
openProfile = new EventEmitter<UserInfo>();
@ViewChild('messageBoxContainer', { static: true })
private messageBoxContainer: ElementRef;
@ -889,4 +894,13 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
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 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="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>
<mat-drawer-container class="contents" autosize>
<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)"
></app-layout-messenger-messages>
</div>
<mat-drawer #drawer mode="side" position="end">
<mat-drawer #drawer mode="over">
<p>Auto-resizing sidenav</p>
</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>
<!-- <div class="right-side">

View File

@ -10,8 +10,21 @@ import {
UCAP_NATIVE_SERVICE,
NativeService
} 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 { 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({
selector: 'app-page-messenger-main',
@ -25,7 +38,8 @@ export class MainPageComponent implements OnInit {
constructor(
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private store: Store<any>,
private statusProtocolService: StatusProtocolService
private statusProtocolService: StatusProtocolService,
private dialogService: DialogService
) {}
ngOnInit(): void {
@ -60,4 +74,16 @@ export class MainPageComponent implements OnInit {
this.idleStateChangedSubscription.unsubscribe();
}
}
onClickOpenProfile(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
this.dialogService.open<
ProfileDialogComponent,
ProfileDialogData,
ProfileDialogResult
>(ProfileDialogComponent, {
data: {
userInfo
}
});
}
}

View File

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

View File

@ -41,6 +41,8 @@ export class MessagesComponent implements OnInit {
@Input()
sessionVerInfo: VersionInfo2Response;
@Output()
openProfile = new EventEmitter<UserInfo>();
@Output()
moreEvent = new EventEmitter<number>();
@Output()
@ -95,6 +97,18 @@ export class MessagesComponent implements OnInit {
}
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 {
const unreadCnt = this.userInfos.filter(user => {
@ -145,6 +159,13 @@ export class MessagesComponent implements OnInit {
return false;
}
onClickOpenProfile(event: MouseEvent, userInfo: UserInfo) {
event.preventDefault();
event.stopPropagation();
this.openProfile.emit(userInfo);
}
onClickMore(event: any) {
event.preventDefault();
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"
[path]="userInfo.profileImageFile"
[default]="'assets/images/img_nophoto_50.png'"
(click)="onClickOpenProfile($event, userInfo)"
/>
</dt>
<dd class="info">

View File

@ -49,6 +49,10 @@ export class UserListItemComponent implements OnInit {
isChecked: boolean;
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}>();
@Output()
openProfile = new EventEmitter<
UserInfo | UserInfoSS | UserInfoF | UserInfoDN
>();
PresenceType = PresenceType;
@ -98,4 +102,14 @@ export class UserListItemComponent implements OnInit {
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 { CommonModule } from '@angular/common';
@ -11,8 +13,9 @@ import { UCapUiModule } from '@ucap-webmessenger/ui';
import { ListItemComponent } from './components/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 = [];
@ -24,6 +27,8 @@ const SERVICES = [];
MatIconModule,
MatRippleModule,
MatCheckboxModule,
MatCardModule,
MatTooltipModule,
UCapUiModule
],