presence is modified

This commit is contained in:
Richard Park 2020-01-10 16:49:53 +09:00
parent ed00ae2a80
commit b7f1a16f28
21 changed files with 405 additions and 41 deletions

View File

@ -645,6 +645,16 @@ ipcMain.on(
} }
); );
ipcMain.on(
IdleStateChannel.ChangeLimitTime,
(event: IpcMainEvent, ...args: any[]) => {
const limitTime: number = args[0];
if (!!idle) {
idle.resetIdleTime(limitTime);
}
}
);
ipcMain.on( ipcMain.on(
NotificationChannel.Notify, NotificationChannel.Notify,
(event: IpcMainEvent, ...args: any[]) => { (event: IpcMainEvent, ...args: any[]) => {

View File

@ -150,6 +150,7 @@
<ucap-profile-my-profile-widget <ucap-profile-my-profile-widget
[profileImageRoot]="sessionVerinfo.profileRoot" [profileImageRoot]="sessionVerinfo.profileRoot"
[profileImageFile]="getMyProfileImageWidget()" [profileImageFile]="getMyProfileImageWidget()"
[presence]="myStatus"
*ngIf="!!loginRes" *ngIf="!!loginRes"
class="myprofile-item" class="myprofile-item"
[matMenuTriggerFor]="profileMenu" [matMenuTriggerFor]="profileMenu"
@ -254,7 +255,19 @@
yPosition="below" yPosition="below"
> >
<div class="setting"> <div class="setting">
<button mat-menu-item [matMenuTriggerFor]="presenseMenu">대화 가능</button> <button mat-menu-item [matMenuTriggerFor]="presenseMenu">
<ng-container [ngSwitch]="myStatus.pcStatus">
<ng-container *ngSwitchCase="StatusCode.OnLine">
{{ 'presence.online' | translate }}
</ng-container>
<ng-container *ngSwitchCase="StatusCode.Away">
{{ 'presence.away' | translate }}
</ng-container>
<ng-container *ngSwitchCase="StatusCode.Busy">
{{ myStatus.statusMessage }}
</ng-container>
</ng-container>
</button>
</div> </div>
<div class="setting"> <div class="setting">
<button mat-menu-item (click)="onClickOpenProfile($event)"> <button mat-menu-item (click)="onClickOpenProfile($event)">
@ -302,28 +315,83 @@
<mat-menu #presenseMenu="matMenu" class="status-pc-set"> <mat-menu #presenseMenu="matMenu" class="status-pc-set">
<div class="setting"> <div class="setting">
<button mat-menu-item> <button mat-menu-item (click)="onClickStatusOnline($event)">
<span class="presence pcOn"> </span>{{ 'presence.online' | translate }} <span class="presence pcOn"> </span>
{{ 'presence.online' | translate }}
</button> </button>
</div> </div>
<div class="setting"> <div class="setting">
<button mat-menu-item> <button mat-menu-item (click)="onClickStatusAway($event)">
<span class="presence pcOut"> </span <span class="presence pcOut"> </span>
>{{ 'presence.offline' | translate }}</button {{ 'presence.away' | translate }}
><button mat-menu-item class="clock"></button> </button>
<button
mat-menu-item
class="clock"
[matMenuTriggerFor]="awayTimeMenu"
></button>
</div> </div>
<div class="setting"> <div class="setting">
<button mat-menu-item> <button mat-menu-item (click)="onClickStatusBusy($event, 1)">
<span class="presence pcOther"> </span>다른용무중</button <span class="presence pcOther"> </span>
><button mat-menu-item class="edit"></button> {{ loginRes?.statusMessage1 }}
</button>
<button
mat-menu-item
class="edit"
(click)="onClickChangeStatusBusy($event, 1)"
></button>
</div> </div>
<div class="setting"> <div class="setting">
<button mat-menu-item><span class="presence pcOther"> </span>회의중</button <button mat-menu-item (click)="onClickStatusBusy($event, 2)">
><button mat-menu-item class="edit"></button> <span class="presence pcOther"> </span>
{{ loginRes?.statusMessage2 }}
</button>
<button
mat-menu-item
class="edit"
(click)="onClickChangeStatusBusy($event, 2)"
></button>
</div> </div>
<div class="setting"> <div class="setting">
<button mat-menu-item> <button mat-menu-item (click)="onClickStatusBusy($event, 3)">
<span class="presence pcOther"> </span>집중근무중</button <span class="presence pcOther"> </span>
><button mat-menu-item class="edit"></button> {{ loginRes?.statusMessage3 }}
</button>
<button
mat-menu-item
class="edit"
(click)="onClickChangeStatusBusy($event, 3)"
></button>
</div>
</mat-menu>
<mat-menu #awayTimeMenu="matMenu">
<div mat-menu-item (click)="$event.stopPropagation()">
{{ 'presence.settingOfAwayTime' | translate }}
</div>
<div mat-menu-item>
<mat-radio-button
value="10"
[checked]="myIdleCheckTime === 10"
(change)="onChangeAwayTime($event)"
>10{{ 'common.units.minute' | translate }}</mat-radio-button
>
</div>
<div mat-menu-item>
<mat-radio-button
value="20"
[checked]="myIdleCheckTime === 20"
(change)="onChangeAwayTime($event)"
>20{{ 'common.units.minute' | translate }}</mat-radio-button
>
</div>
<div mat-menu-item>
<mat-radio-button
value="30"
[checked]="myIdleCheckTime === 30"
(change)="onChangeAwayTime($event)"
>30{{ 'common.units.minute' | translate }}</mat-radio-button
>
</div> </div>
</mat-menu> </mat-menu>

View File

@ -20,6 +20,7 @@ import * as ChatStore from '@app/store/messenger/chat';
import * as AuthenticationStore from '@app/store/account/authentication'; import * as AuthenticationStore from '@app/store/account/authentication';
import * as SettingsStore from '@app/store/messenger/settings'; import * as SettingsStore from '@app/store/messenger/settings';
import * as UpdateStore from '@app/store/setting/update'; import * as UpdateStore from '@app/store/setting/update';
import * as StatusStore from '@app/store/messenger/status';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { tap, take, map, catchError } from 'rxjs/operators'; import { tap, take, map, catchError } from 'rxjs/operators';
@ -55,7 +56,9 @@ import {
} from '@app/layouts/messenger/dialogs/profile/profile.dialog.component'; } from '@app/layouts/messenger/dialogs/profile/profile.dialog.component';
import { DialogService } from '@ucap-webmessenger/ui'; import { DialogService } from '@ucap-webmessenger/ui';
import { DOCUMENT } from '@angular/common'; import { DOCUMENT } from '@angular/common';
import { MatMenu } from '@angular/material'; import { MatMenu, MatRadioChange } from '@angular/material';
import { StatusCode, StatusType } from '@ucap-webmessenger/core';
import { StatusInfo } from '@ucap-webmessenger/protocol-status';
@Component({ @Component({
selector: 'app-layout-native-top-bar', selector: 'app-layout-native-top-bar',
@ -72,12 +75,19 @@ export class TopBarComponent implements OnInit, OnDestroy {
updateInfo$: Observable<UpdateInfo>; updateInfo$: Observable<UpdateInfo>;
myStatus: StatusInfo;
myStatusSubscription: Subscription;
myIdleCheckTime: number;
myIdleCheckTimeSubscription: Subscription;
loginInfo: LoginInfo; loginInfo: LoginInfo;
weblink: WebLink[] = []; weblink: WebLink[] = [];
webLinkBadgeMail = 0; webLinkBadgeMail = 0;
webLinkBadgePayment = 0; webLinkBadgePayment = 0;
WebLinkType = WebLinkType; WebLinkType = WebLinkType;
StatusCode = StatusCode;
@ViewChild('profileMenu', { static: true }) @ViewChild('profileMenu', { static: true })
profileMenu: MatMenu; profileMenu: MatMenu;
@ -118,11 +128,39 @@ export class TopBarComponent implements OnInit, OnDestroy {
) )
.subscribe(); .subscribe();
this.myStatusSubscription = this.store
.pipe(select(AppStore.MessengerSelector.StatusSelector.selectedMyStatus))
.subscribe(myStatus => {
this.myStatus = myStatus;
});
this.myIdleCheckTimeSubscription = this.store
.pipe(
select(
AppStore.MessengerSelector.StatusSelector.selectedMyIdleCheckTime
)
)
.subscribe(myIdleCheckTime => {
this.myIdleCheckTime = myIdleCheckTime;
});
this.updateInfo$ = this.store.pipe( this.updateInfo$ = this.store.pipe(
select(AppStore.SettingSelector.UpdateSelector.updateInfo) select(AppStore.SettingSelector.UpdateSelector.updateInfo)
); );
} }
ngOnDestroy(): void {
if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe();
}
if (!!this.myStatusSubscription) {
this.myStatusSubscription.unsubscribe();
}
if (!!this.myIdleCheckTimeSubscription) {
this.myIdleCheckTimeSubscription.unsubscribe();
}
}
initWebLink(): void { initWebLink(): void {
const loginRes = this.sessionStorageService.get<LoginResponse>( const loginRes = this.sessionStorageService.get<LoginResponse>(
KEY_LOGIN_RES_INFO KEY_LOGIN_RES_INFO
@ -207,12 +245,6 @@ export class TopBarComponent implements OnInit, OnDestroy {
} }
} }
ngOnDestroy(): void {
if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe();
}
}
onClickClose() { onClickClose() {
this.nativeService.windowClose(); this.nativeService.windowClose();
} }
@ -343,4 +375,61 @@ export class TopBarComponent implements OnInit, OnDestroy {
onClickRemoteSupport(event: Event) { onClickRemoteSupport(event: Event) {
this.nativeService.executeProcess('AeroAdmin'); this.nativeService.executeProcess('AeroAdmin');
} }
onClickStatusOnline(event: Event) {
this.store.dispatch(
StatusStore.status({
req: {
statusDivisionType: StatusType.Messenger,
statusType: StatusCode.OnLine
}
})
);
}
onClickStatusAway(event: Event) {
this.store.dispatch(
StatusStore.status({
req: {
statusDivisionType: StatusType.Messenger,
statusType: StatusCode.Away
}
})
);
}
onClickStatusBusy(event: Event, index: number) {
let statusMessage = '';
switch (index) {
case 1:
statusMessage = this.loginRes.statusMessage1;
break;
case 2:
statusMessage = this.loginRes.statusMessage2;
break;
case 3:
statusMessage = this.loginRes.statusMessage3;
break;
}
this.store.dispatch(
StatusStore.status({
req: {
statusDivisionType: StatusType.Messenger,
statusType: StatusCode.Busy,
statusMessage
}
})
);
}
onClickChangeStatusBusy(event: Event, index: number) {
event.stopPropagation();
}
onChangeAwayTime(event: MatRadioChange) {
this.store.dispatch(
StatusStore.changeMyIdleCheckTime({ checkTime: Number(event.value) })
);
}
} }

View File

@ -6,6 +6,7 @@ import { FlexLayoutModule } from '@angular/flex-layout';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { MatRadioModule } from '@angular/material/radio';
import { MatToolbarModule } from '@angular/material/toolbar'; import { MatToolbarModule } from '@angular/material/toolbar';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
@ -25,6 +26,7 @@ import { MatTooltipModule, MatBadgeModule } from '@angular/material';
MatToolbarModule, MatToolbarModule,
MatTooltipModule, MatTooltipModule,
MatMenuModule, MatMenuModule,
MatRadioModule,
MatBadgeModule, MatBadgeModule,
TranslateModule, TranslateModule,

View File

@ -13,6 +13,7 @@ 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 MessageStore from '@app/store/messenger/message'; import * as MessageStore from '@app/store/messenger/message';
import * as StatusStore from '@app/store/messenger/status';
import { Observable, Subscription, of } from 'rxjs'; import { Observable, Subscription, of } from 'rxjs';
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native'; import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
@ -59,6 +60,7 @@ export class MainPageComponent implements OnInit, OnDestroy {
idleStateChangedSubscription: Subscription; idleStateChangedSubscription: Subscription;
chatOpenRoomSubscription: Subscription; chatOpenRoomSubscription: Subscription;
msgOpenMessageSubscription: Subscription; msgOpenMessageSubscription: Subscription;
myIdleCheckTimeSubscription: Subscription;
defaultLeftSideComponentWidth = 380; defaultLeftSideComponentWidth = 380;
leftSideComponentWidth = this.defaultLeftSideComponentWidth; leftSideComponentWidth = this.defaultLeftSideComponentWidth;
@ -122,11 +124,39 @@ export class MainPageComponent implements OnInit, OnDestroy {
statusType = StatusCode.OnLine; statusType = StatusCode.OnLine;
} }
this.statusProtocolService.status({ this.store.dispatch(
statusDivisionType: StatusType.Messenger, StatusStore.status({
statusType, req: {
statusMessage: '' statusDivisionType: StatusType.Messenger,
}); statusType,
statusMessage: ''
}
})
);
});
this.myIdleCheckTimeSubscription = this.store
.pipe(
select(
AppStore.MessengerSelector.StatusSelector.selectedMyIdleCheckTime
)
)
.subscribe(checkTime => {
this.nativeService.changeLimitOfIdleState(checkTime);
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
KEY_APP_USER_INFO,
environment.customConfig.appKey
);
this.localStorageService.encSet<AppUserInfo>(
KEY_APP_USER_INFO,
{
...appUserInfo,
idleCheckTime: checkTime
},
environment.customConfig.appKey
);
}); });
this.chatOpenRoomSubscription = this.nativeService this.chatOpenRoomSubscription = this.nativeService
@ -186,6 +216,10 @@ export class MainPageComponent implements OnInit, OnDestroy {
this.loginResSubscription.unsubscribe(); this.loginResSubscription.unsubscribe();
} }
if (!!this.myIdleCheckTimeSubscription) {
this.myIdleCheckTimeSubscription.unsubscribe();
}
this.logger.debug('-----------------------MainPageComponent ngOnDestroy'); this.logger.debug('-----------------------MainPageComponent ngOnDestroy');
} }

View File

@ -17,7 +17,10 @@ import {
import { Store, select } from '@ngrx/store'; import { Store, select } from '@ngrx/store';
import { ProtocolService, ServerErrorCode } from '@ucap-webmessenger/protocol'; import { ProtocolService, ServerErrorCode } from '@ucap-webmessenger/protocol';
import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import {
SessionStorageService,
LocalStorageService
} from '@ucap-webmessenger/web-storage';
import { import {
PublicApiService, PublicApiService,
VersionInfo2Response VersionInfo2Response
@ -54,6 +57,7 @@ import * as VersionInfoStore from '@app/store/setting/version-info';
import * as OptionStore from '@app/store/messenger/option'; import * as OptionStore from '@app/store/messenger/option';
import * as QueryStore from '@app/store/messenger/query'; import * as QueryStore from '@app/store/messenger/query';
import * as SyncStore from '@app/store/messenger/sync'; import * as SyncStore from '@app/store/messenger/sync';
import * as StatusStore from '@app/store/messenger/status';
import { KEY_LOGIN_RES_INFO, KEY_VER_INFO } from '@app/types'; import { KEY_LOGIN_RES_INFO, KEY_VER_INFO } from '@app/types';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
@ -66,6 +70,7 @@ import {
} from '@ucap-webmessenger/api-external'; } from '@ucap-webmessenger/api-external';
import { StatusCode } from '@ucap-webmessenger/api'; import { StatusCode } from '@ucap-webmessenger/api';
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native'; import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
@Injectable() @Injectable()
export class AppMessengerResolver implements Resolve<void> { export class AppMessengerResolver implements Resolve<void> {
@ -73,6 +78,7 @@ export class AppMessengerResolver implements Resolve<void> {
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private store: Store<any>, private store: Store<any>,
private sessionStorageService: SessionStorageService, private sessionStorageService: SessionStorageService,
private localStorageService: LocalStorageService,
private publicApiService: PublicApiService, private publicApiService: PublicApiService,
private externalApiService: ExternalApiService, private externalApiService: ExternalApiService,
private protocolService: ProtocolService, private protocolService: ProtocolService,
@ -264,6 +270,17 @@ export class AppMessengerResolver implements Resolve<void> {
); );
this.store.dispatch(AuthenticationStore.postLogin({ loginRes })); this.store.dispatch(AuthenticationStore.postLogin({ loginRes }));
this.appNativeService.subscribeAfterLogin(); this.appNativeService.subscribeAfterLogin();
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
KEY_APP_USER_INFO,
environment.customConfig.appKey
);
this.store.dispatch(
StatusStore.changeMyIdleCheckTime({
checkTime: appUserInfo.idleCheckTime
})
);
resolve(); resolve();
}, },
err => { err => {

View File

@ -64,6 +64,7 @@ export class AppAuthenticationService {
if (!appUserInfo) { if (!appUserInfo) {
appUserInfo = { appUserInfo = {
idleCheckTime: 10,
settings: { settings: {
...environment.productConfig.defaultSettings, ...environment.productConfig.defaultSettings,
chat: { chat: {

View File

@ -2,7 +2,9 @@ import { createAction, props } from '@ngrx/store';
import { import {
BulkInfoRequest, BulkInfoRequest,
StatusBulkInfo, StatusBulkInfo,
StatusNotification StatusNotification,
StatusRequest,
StatusResponse
} from '@ucap-webmessenger/protocol-status'; } from '@ucap-webmessenger/protocol-status';
export const bulkInfo = createAction( export const bulkInfo = createAction(
@ -24,3 +26,23 @@ export const statusNotification = createAction(
'[Messenger::Status] Status Notification', '[Messenger::Status] Status Notification',
props<{ noti: StatusNotification }>() props<{ noti: StatusNotification }>()
); );
export const status = createAction(
'[Messenger::Status] Status',
props<{ req: StatusRequest }>()
);
export const statusSuccess = createAction(
'[Messenger::Status] Status Success',
props<{
res: StatusResponse;
}>()
);
export const statusFailure = createAction(
'[Messenger::Status] Status Failure',
props<{ error: any }>()
);
export const changeMyIdleCheckTime = createAction(
'[Messenger::Status] Change MyIdleCheckTime',
props<{ checkTime: number }>()
);

View File

@ -10,15 +10,18 @@ import {
bulkInfo, bulkInfo,
bulkInfoSuccess, bulkInfoSuccess,
bulkInfoFailure, bulkInfoFailure,
statusNotification status,
statusFailure,
statusSuccess
} from './actions'; } from './actions';
import { tap, switchMap, map, catchError } from 'rxjs/operators'; import { tap, switchMap, map, catchError, exhaustMap } from 'rxjs/operators';
import { import {
StatusProtocolService, StatusProtocolService,
SSVC_TYPE_STATUS_BULK_INFO_DATA, SSVC_TYPE_STATUS_BULK_INFO_DATA,
SSVC_TYPE_STATUS_BULK_INFO_RES, SSVC_TYPE_STATUS_BULK_INFO_RES,
BulkInfoData, BulkInfoData,
StatusBulkInfo StatusBulkInfo,
StatusResponse
} from '@ucap-webmessenger/protocol-status'; } from '@ucap-webmessenger/protocol-status';
import { of } from 'rxjs'; import { of } from 'rxjs';
@ -84,6 +87,21 @@ export class Effects {
// { dispatch: false } // { dispatch: false }
// ); // );
status$ = createEffect(() =>
this.actions$.pipe(
ofType(status),
map(action => action.req),
exhaustMap(req => {
return this.statusProtocolService.status(req).pipe(
map((res: StatusResponse) => {
return statusSuccess({ res });
}),
catchError(error => of(statusFailure({ error })))
);
})
)
);
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private store: Store<any>, private store: Store<any>,

View File

@ -1,6 +1,11 @@
import { createReducer, on } from '@ngrx/store'; import { createReducer, on } from '@ngrx/store';
import { initialState, State, adapterStatusBulkInfo } from './state'; import { initialState, State, adapterStatusBulkInfo } from './state';
import { bulkInfoSuccess, statusNotification } from './actions'; import {
bulkInfoSuccess,
statusNotification,
statusSuccess,
changeMyIdleCheckTime
} from './actions';
import * as AuthenticationStore from '@app/store/account/authentication'; import * as AuthenticationStore from '@app/store/account/authentication';
import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status'; import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status';
@ -42,6 +47,24 @@ export const reducer = createReducer(
}; };
}), }),
on(statusSuccess, (state, action) => {
return {
...state,
myStatus: {
...state.myStatus,
pcStatus: action.res.statusType,
statusMessage: action.res.statusMessage
}
} as State;
}),
on(changeMyIdleCheckTime, (state, action) => {
return {
...state,
myIdleCheckTime: action.checkTime
} as State;
}),
on(AuthenticationStore.logoutInitialize, (state, action) => { on(AuthenticationStore.logoutInitialize, (state, action) => {
return { return {
...initialState ...initialState

View File

@ -1,11 +1,14 @@
import { Selector, createSelector } from '@ngrx/store'; import { Selector, createSelector } from '@ngrx/store';
import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status'; import { StatusBulkInfo, StatusInfo } from '@ucap-webmessenger/protocol-status';
import { EntityState, createEntityAdapter } from '@ngrx/entity'; import { EntityState, createEntityAdapter } from '@ngrx/entity';
import { StatusCode } from '@ucap-webmessenger/core';
export interface StatusBulkInfoState extends EntityState<StatusBulkInfo> {} export interface StatusBulkInfoState extends EntityState<StatusBulkInfo> {}
export interface State { export interface State {
statusBulkInfo: StatusBulkInfoState; statusBulkInfo: StatusBulkInfoState;
myStatus: StatusInfo;
myIdleCheckTime: number;
} }
export const adapterStatusBulkInfo = createEntityAdapter<StatusBulkInfo>({ export const adapterStatusBulkInfo = createEntityAdapter<StatusBulkInfo>({
@ -17,7 +20,18 @@ const statusBulkInfoInitialState: StatusBulkInfoState = adapterStatusBulkInfo.ge
); );
export const initialState: State = { export const initialState: State = {
statusBulkInfo: statusBulkInfoInitialState statusBulkInfo: statusBulkInfoInitialState,
myStatus: {
userSeq: -1,
pcStatus: StatusCode.OnLine,
phoneStatus: StatusCode.Offline,
mobileStatus: StatusCode.Offline,
conferenceStatus: StatusCode.Offline,
statusMessage: '',
mobileConferenceStatus: StatusCode.Offline,
imessengerStatus: StatusCode.Offline
},
myIdleCheckTime: 10
}; };
const { const {
@ -47,6 +61,14 @@ export function selectors<S>(selector: Selector<any, State>) {
selectStatusBulkInfo, selectStatusBulkInfo,
ngeSelectEntitiesStatusBulkInfo, ngeSelectEntitiesStatusBulkInfo,
(_, entities) => (!!entities ? entities[userSeq] : undefined) (_, entities) => (!!entities ? entities[userSeq] : undefined)
) ),
selectedMyStatus: createSelector(
selector,
(state: State) => state.myStatus
),
selectedMyIdleCheckTime: createSelector(
selector,
(state: State) => state.myIdleCheckTime
)
}; };
} }

View File

@ -10,6 +10,7 @@ export interface AppUserInfo {
companyCode?: string; companyCode?: string;
companyGroupType?: string; companyGroupType?: string;
localeCode?: LocaleCode; localeCode?: LocaleCode;
idleCheckTime?: number;
settings?: Settings; settings?: Settings;
} }

View File

@ -111,8 +111,12 @@
} }
}, },
"presence": { "presence": {
"settingOfAwayTime": "Setting of away time",
"online": "Online", "online": "Online",
"offline": "Offline" "away": "Away",
"statusMessage1": "Busy",
"statusMessage2": "In conference",
"statusMessage3": "In intensive work"
}, },
"group": { "group": {
"label": "Group", "label": "Group",

View File

@ -111,8 +111,12 @@
} }
}, },
"presence": { "presence": {
"settingOfAwayTime": "부재 중 시간 설정",
"online": "온라인", "online": "온라인",
"offline": "부재중" "away": "부재중",
"statusMessage1": "다른용무중",
"statusMessage2": "회의중",
"statusMessage3": "집중근무중"
}, },
"group": { "group": {
"label": "그룹", "label": "그룹",

View File

@ -226,6 +226,8 @@ export class BrowserNativeService extends NativeService {
}); });
} }
changeLimitOfIdleState(limitTime: number): void {}
chatOpenRoom(): Observable<string> { chatOpenRoom(): Observable<string> {
if (!this.chatOpenRoomSubject) { if (!this.chatOpenRoomSubject) {
this.chatOpenRoomSubject = new Subject<WindowIdle>(); this.chatOpenRoomSubject = new Subject<WindowIdle>();

View File

@ -396,6 +396,10 @@ export class ElectronNativeService implements NativeService {
return this.idleStateChanged$; return this.idleStateChanged$;
} }
changeLimitOfIdleState(limitTime: number): void {
this.ipcRenderer.send(IdleStateChannel.ChangeLimitTime, limitTime);
}
chatOpenRoom(): Observable<string> { chatOpenRoom(): Observable<string> {
if (!this.chatOpenRoomSubject) { if (!this.chatOpenRoomSubject) {
this.chatOpenRoomSubject = new Subject<WindowIdle>(); this.chatOpenRoomSubject = new Subject<WindowIdle>();

View File

@ -49,5 +49,6 @@ export enum WindowStateChannel {
export enum IdleStateChannel { export enum IdleStateChannel {
Changed = 'UCAP::idleState::changed', Changed = 'UCAP::idleState::changed',
StartCheck = 'UCAP::idleState::startCheck' StartCheck = 'UCAP::idleState::startCheck',
ChangeLimitTime = 'UCAP::idleState::changeLimitTime'
} }

View File

@ -68,6 +68,7 @@ export abstract class NativeService {
abstract windowMaximize(): void; abstract windowMaximize(): void;
abstract idleStateChanged(): Observable<WindowIdle>; abstract idleStateChanged(): Observable<WindowIdle>;
abstract changeLimitOfIdleState(limitTime: number): void;
abstract chatOpenRoom(): Observable<string>; abstract chatOpenRoom(): Observable<string>;
abstract msgOpenMessage(): Observable<string>; abstract msgOpenMessage(): Observable<string>;

View File

@ -9,7 +9,7 @@
/> />
</span> </span>
<div class="btn-setting"> <div class="btn-setting">
<span class="presence pcOff"></span> <span class="presence" [ngClass]="getPresence(PresenceType.PC)"></span>
<button> <button>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View File

@ -1,5 +1,8 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { PresenceType } from '../types/presence-type.type';
import { StatusBulkInfo, StatusInfo } from '@ucap-webmessenger/protocol-status';
import { StatusCode } from '@ucap-webmessenger/core';
@Component({ @Component({
selector: 'ucap-profile-my-profile-widget', selector: 'ucap-profile-my-profile-widget',
@ -11,8 +14,44 @@ export class MyProfileWidgetComponent implements OnInit {
profileImageRoot: string; profileImageRoot: string;
@Input() @Input()
profileImageFile: string; profileImageFile: string;
@Input()
presence: StatusBulkInfo | StatusInfo;
PresenceType = PresenceType;
constructor(private logger: NGXLogger) {} constructor(private logger: NGXLogger) {}
ngOnInit() {} ngOnInit() {}
getPresence(type: PresenceType): string {
let status: string;
let rtnClass = '';
switch (type) {
case PresenceType.PC:
status = !!this.presence ? this.presence.pcStatus : undefined;
break;
case PresenceType.MOBILE:
status = !!this.presence ? this.presence.mobileStatus : undefined;
break;
}
if (!!status) {
switch (status) {
case StatusCode.OnLine:
rtnClass = type + 'On';
break;
case StatusCode.Away:
rtnClass = type + 'Out';
break;
case StatusCode.Busy:
rtnClass = type + 'Other';
break;
default:
rtnClass = type + 'Off';
break;
}
}
return rtnClass;
}
} }

View File

@ -44,6 +44,8 @@ export class NotificationComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.logger.debug('setting', this.setting); this.logger.debug('setting', this.setting);
this.setNotificationMethodList();
this.langChangeSubscription = merge( this.langChangeSubscription = merge(
this.translateService.onLangChange, this.translateService.onLangChange,
this.translateService.onDefaultLangChange, this.translateService.onDefaultLangChange,