# 이슈처리

158 대화 상대 없음 표시 없음
159 쪽지 파일 다운로드 되지 않음
162 PC원격 로그아웃시 로그아웃되지 않음
This commit is contained in:
leejinho 2020-01-16 18:07:03 +09:00
parent 0a1523fbff
commit b9ed6bf6cf
13 changed files with 125 additions and 36 deletions

View File

@ -77,7 +77,7 @@
{{ roomInfo.roomName }} {{ roomInfo.roomName }}
</ng-template> </ng-template>
<ng-template #roomNameNotExist> <ng-template #roomNameNotExist>
{{ _roomUserInfos | ucapTranslate: 'name':',' }} {{ getRoomNameByRoomUser(_roomUserInfos) }}
</ng-template> </ng-template>
</ng-container> </ng-container>
</ng-container> </ng-container>
@ -319,9 +319,7 @@
#messageContextMenuTrigger="matMenuTrigger" #messageContextMenuTrigger="matMenuTrigger"
[matMenuTriggerFor]="messageContextMenu" [matMenuTriggerFor]="messageContextMenu"
></div> ></div>
<mat-menu <mat-menu #messageContextMenu="matMenu">
#messageContextMenu="matMenu"
>
<ng-template matMenuContent let-message="message" let-clicktype="clicktype"> <ng-template matMenuContent let-message="message" let-clicktype="clicktype">
<ng-container *ngIf="!isRecalledMessage(message.type)"> <ng-container *ngIf="!isRecalledMessage(message.type)">
<button <button

View File

@ -6,7 +6,8 @@ import {
AfterViewInit, AfterViewInit,
Output, Output,
EventEmitter, EventEmitter,
Inject Inject,
ChangeDetectorRef
} from '@angular/core'; } from '@angular/core';
import { import {
ucapAnimations, ucapAnimations,
@ -60,7 +61,12 @@ import {
RightDrawer, RightDrawer,
KEY_STICKER_HISTORY KEY_STICKER_HISTORY
} from '@app/types'; } from '@app/types';
import { RoomInfo, UserInfo, RoomType } from '@ucap-webmessenger/protocol-room'; import {
RoomInfo,
UserInfo,
RoomType,
UserInfoShort
} from '@ucap-webmessenger/protocol-room';
import { tap, take, map, catchError, finalize } from 'rxjs/operators'; import { tap, take, map, catchError, finalize } from 'rxjs/operators';
import { FormComponent as UCapUiChatFormComponent } from '@ucap-webmessenger/ui-chat'; import { FormComponent as UCapUiChatFormComponent } from '@ucap-webmessenger/ui-chat';
import { KEY_VER_INFO } from '@app/types'; import { KEY_VER_INFO } from '@app/types';
@ -109,6 +115,8 @@ import {
} from '../dialogs/chat/mass-detail.component'; } from '../dialogs/chat/mass-detail.component';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { TranslatePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/translate.pipe';
import { TranslateService as uiTranslateService } from '@ucap-webmessenger/ui';
@Component({ @Component({
selector: 'app-layout-messenger-messages', selector: 'app-layout-messenger-messages',
@ -209,7 +217,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
private localStorageService: LocalStorageService, private localStorageService: LocalStorageService,
private commonApiService: CommonApiService, private commonApiService: CommonApiService,
private clipboardService: ClipboardService, private clipboardService: ClipboardService,
private uiTranslateService: uiTranslateService,
private translateService: TranslateService, private translateService: TranslateService,
private changeDetectorRef: ChangeDetectorRef,
private dialogService: DialogService, private dialogService: DialogService,
private snackBarService: SnackBarService, private snackBarService: SnackBarService,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
@ -455,6 +465,18 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
} }
getRoomNameByRoomUser(roomUserInfos: (UserInfo | UserInfoShort)[]) {
let roomName = new TranslatePipe(
this.uiTranslateService,
this.changeDetectorRef
).transform(roomUserInfos, 'name', ',');
if (!roomName || roomName.trim().length === 0) {
roomName = this.translateService.instant('chat.noRoomUser');
}
return roomName;
}
/** 대화전송 가능한 방인지 판단 */ /** 대화전송 가능한 방인지 판단 */
getEnableSend() { getEnableSend() {
if (!this.roomInfo) { if (!this.roomInfo) {

View File

@ -65,6 +65,7 @@
/> />
<video <video
controls controls
controlsList="nodownload nofullscreen"
*ngIf="selectedFile.info.type === FileType.Video" *ngIf="selectedFile.info.type === FileType.Video"
[src]="getImageUrl(selectedFile)" [src]="getImageUrl(selectedFile)"
class="preview-video" class="preview-video"

View File

@ -14,7 +14,7 @@ import * as AppStore from '@app/store';
import * as SyncStore from '@app/store/messenger/sync'; import * as SyncStore from '@app/store/messenger/sync';
import * as RoomStore from '@app/store/messenger/room'; import * as RoomStore from '@app/store/messenger/room';
import { UserInfo, RoomInfo } from '@ucap-webmessenger/protocol-room'; import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { import {
@ -217,6 +217,9 @@ export class RoomUserListComponent implements OnInit, OnDestroy {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
if (this.roomInfo.roomType !== RoomType.Multi) {
return;
}
if (buddy.seq === this.loginRes.userSeq) { if (buddy.seq === this.loginRes.userSeq) {
return; return;
} }

View File

@ -424,7 +424,7 @@ export class MessageDetailDialogComponent implements OnInit {
// single :: success // single :: success
this.snackBarService.open( this.snackBarService.open(
this.translateService.instant( this.translateService.instant(
'common.file.errors.savedToPath', 'common.file.results.savedToPath',
{ path: attachFile.downloadType } { path: attachFile.downloadType }
), ),
'', '',
@ -437,7 +437,7 @@ export class MessageDetailDialogComponent implements OnInit {
// all // all
this.snackBarService.open( this.snackBarService.open(
this.translateService.instant( this.translateService.instant(
'common.file.errors.savedAll' 'common.file.results.savedAll'
), ),
'', '',
{ {

View File

@ -33,6 +33,7 @@ import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
import { LogoutInfo, KEY_LOGOUT_INFO } from '@app/types'; import { LogoutInfo, KEY_LOGOUT_INFO } from '@app/types';
import { AppAuthenticationService } from '@app/services/authentication.service'; import { AppAuthenticationService } from '@app/services/authentication.service';
import { logoutInitialize } from '@app/store/account/authentication'; import { logoutInitialize } from '@app/store/account/authentication';
import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
selector: 'app-page-account-login', selector: 'app-page-account-login',
@ -85,6 +86,7 @@ export class LoginPageComponent implements OnInit, OnDestroy {
constructor( constructor(
private store: Store<any>, private store: Store<any>,
private router: Router, private router: Router,
private translateService: TranslateService,
private dialogService: DialogService, private dialogService: DialogService,
private protocolService: ProtocolService, private protocolService: ProtocolService,
private localStorageService: LocalStorageService, private localStorageService: LocalStorageService,
@ -114,7 +116,7 @@ export class LoginPageComponent implements OnInit, OnDestroy {
(this.rotateInfomationIndex + 1) % this.rotateInfomation.length; (this.rotateInfomationIndex + 1) % this.rotateInfomation.length;
}, 8000); }, 8000);
this.defatulLoginBtnText = 'LOGIN'; this.defatulLoginBtnText = this.translateService.instant('accounts.login');
this.defatulWaitingTime = 5 * 60; // sec this.defatulWaitingTime = 5 * 60; // sec
this.store.dispatch( this.store.dispatch(
@ -140,8 +142,10 @@ export class LoginPageComponent implements OnInit, OnDestroy {
>(AlertDialogComponent, { >(AlertDialogComponent, {
width: '360px', width: '360px',
data: { data: {
title: '로그인', title: '',
html: `아이디 또는 패스워드가<br/>일치하지 않습니다.` html: this.translateService.instant(
'accounts.errors.loginFail'
)
} }
}); });
} }
@ -154,8 +158,10 @@ export class LoginPageComponent implements OnInit, OnDestroy {
>(AlertDialogComponent, { >(AlertDialogComponent, {
width: '360px', width: '360px',
data: { data: {
title: '로그인', title: '',
html: `비밀번호 오류 횟수 초과입니다.<br/>비밀번호를 확인하신 후<br/>잠시 후 다시 시작해 주세요.` html: this.translateService.instant(
'accounts.errors.loginFailOverTry'
)
} }
}); });
@ -182,11 +188,26 @@ export class LoginPageComponent implements OnInit, OnDestroy {
KEY_LOGOUT_INFO KEY_LOGOUT_INFO
); );
if ( if (!!personLogout && !!personLogout.reasonCode) {
!!personLogout && let msg = this.translateService.instant('accounts.results.doLogout');
!!personLogout.reasonCode && switch (personLogout.reasonCode) {
personLogout.reasonCode === ServerErrorCode.ERRCD_DUPLICATE case ServerErrorCode.ERRCD_DUPLICATE:
) { msg = this.translateService.instant(
'accounts.results.doLogoutDuplicate',
{
ip: personLogout.ip,
mac: personLogout.mac
}
);
break;
case ServerErrorCode.ERRCD_FORCE_INIT:
msg = this.translateService.instant(
'accounts.results.doLogoutByOthers'
);
break;
}
const result = this.dialogService.open< const result = this.dialogService.open<
AlertDialogComponent, AlertDialogComponent,
AlertDialogData, AlertDialogData,
@ -195,7 +216,7 @@ export class LoginPageComponent implements OnInit, OnDestroy {
width: '360px', width: '360px',
data: { data: {
title: '', title: '',
html: `다른 디바이스에서 로그인하였습니다.<br/> * Ip : ${personLogout.ip}<br/> * Mac : ${personLogout.mac}` html: msg
} }
}); });
@ -206,7 +227,9 @@ export class LoginPageComponent implements OnInit, OnDestroy {
// Daesang.. // Daesang..
this.fixedCompany = environment.companyConfig.fixedCompanyCode; this.fixedCompany = environment.companyConfig.fixedCompanyCode;
this.fixedNotiBtnText = '이용 주의사항'; this.fixedNotiBtnText = this.translateService.instant(
'accounts.usageNotes'
);
} }
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@ -113,6 +113,7 @@ import { MessageType } from '@ucap-webmessenger/api-message';
import { LogoutInfo, KEY_LOGOUT_INFO } from '@app/types'; import { LogoutInfo, KEY_LOGOUT_INFO } from '@app/types';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { deleteMessageSuccess } from '@app/store/messenger/message'; import { deleteMessageSuccess } from '@app/store/messenger/message';
import { ServerErrorCode } from '@ucap-webmessenger/protocol';
@Injectable() @Injectable()
export class AppNotificationService { export class AppNotificationService {
@ -161,6 +162,12 @@ export class AppNotificationService {
'Notification::authenticationProtocolService::LogoutRemoteNotification', 'Notification::authenticationProtocolService::LogoutRemoteNotification',
noti noti
); );
this.sessionStorageService.set<LogoutInfo>(KEY_LOGOUT_INFO, {
personLogout: true,
reasonCode: ServerErrorCode.ERRCD_FORCE_INIT,
forceType: noti.requestDeviceType
} as LogoutInfo);
} }
break; break;
default: default:

View File

@ -5,4 +5,5 @@ export interface LogoutInfo {
reasonCode?: number; reasonCode?: number;
ip?: string; ip?: string;
mac?: string; mac?: string;
forceType?: string;
} }

View File

@ -15,11 +15,15 @@
"consentOfPrivacy": "Agreement of ", "consentOfPrivacy": "Agreement of ",
"changePassword": "Change password", "changePassword": "Change password",
"resetPassword": "Reset password", "resetPassword": "Reset password",
"usageNotes": "Usage Notes",
"passwordExpired": "Password expired", "passwordExpired": "Password expired",
"descriptionOfPasswordExpired": "Password has expired.<br/>Please change your password and log in again.", "descriptionOfPasswordExpired": "Password has expired.<br/>Please change your password and log in again.",
"confirmLogout": "Do you want to log out?", "confirmLogout": "Do you want to log out?",
"results": { "results": {
"changedPassword": "Password changed. Please log in again." "changedPassword": "Password changed. Please log in again.",
"doLogout": "You have been logged out.",
"doLogoutDuplicate": "You logged in from another device.<br/> * Ip : {{ip}}<br/> * Mac : {{mac}}",
"doLogoutByOthers": "Forced logout by user."
}, },
"errors": { "errors": {
"requireLoginId": "Login ID is required.", "requireLoginId": "Login ID is required.",
@ -38,7 +42,9 @@
"notAllowedConsecutiveAlphaNumOver3TimesForPassword": "You cannot use consecutive numbers or letters more than 3 times.", "notAllowedConsecutiveAlphaNumOver3TimesForPassword": "You cannot use consecutive numbers or letters more than 3 times.",
"notSatisfiedCombineForPassword": "Combination of two or more kinds of letters, numbers and special characters.", "notSatisfiedCombineForPassword": "Combination of two or more kinds of letters, numbers and special characters.",
"minLengthCombineForPassword": "Password must be {{lengthOfPassword}} characters if {{countOfCombine}} combination.", "minLengthCombineForPassword": "Password must be {{lengthOfPassword}} characters if {{countOfCombine}} combination.",
"failToChangePassword": "Failed to change password." "failToChangePassword": "Failed to change password.",
"loginFail": "Username or password do not match.",
"loginFailOverTry": "Password error count exceeded. <br/> Check your password <br/> Please try again later."
} }
}, },
"profile": { "profile": {
@ -203,6 +209,7 @@
"btnAttachFile": "Attach files", "btnAttachFile": "Attach files",
"btnSticker": "Sticker", "btnSticker": "Sticker",
"btnTranslate": "Translate", "btnTranslate": "Translate",
"noRoomUser": "No chat users",
"event": { "event": {
"inviteToRoomWith": "{{owner}} invited {{inviter}}.", "inviteToRoomWith": "{{owner}} invited {{inviter}}.",
"exitFromRoomWith": "{{exitor}} has left.", "exitFromRoomWith": "{{exitor}} has left.",

View File

@ -15,11 +15,15 @@
"consentOfPrivacy": "개인정보 동의", "consentOfPrivacy": "개인정보 동의",
"changePassword": "비밀번호 변경", "changePassword": "비밀번호 변경",
"resetPassword": "비밀번호 초기화", "resetPassword": "비밀번호 초기화",
"usageNotes": "이용 주의사항",
"passwordExpired": "비밀번호 만기", "passwordExpired": "비밀번호 만기",
"descriptionOfPasswordExpired": "비밀번호가 만료되었습니다.<br/>비밀번호 변경 후 다시 로그인 하세요.", "descriptionOfPasswordExpired": "비밀번호가 만료되었습니다.<br/>비밀번호 변경 후 다시 로그인 하세요.",
"confirmLogout": "로그아웃 하시겠습니까?", "confirmLogout": "로그아웃 하시겠습니까?",
"results": { "results": {
"changedPassword": "비밀번호가 변경되었습니다. 다시 로그인하여 주십시오" "changedPassword": "비밀번호가 변경되었습니다. 다시 로그인하여 주십시오",
"doLogout": "로그아웃 되었습니다.",
"doLogoutDuplicate": "다른 디바이스에서 로그인하였습니다.<br/> * Ip : {{ip}}<br/> * Mac : {{mac}}",
"doLogoutByOthers": "사용자에 의해 강제로그아웃 하였습니다."
}, },
"errors": { "errors": {
"requireLoginId": "로그인 아이디를 입력해 주세요.", "requireLoginId": "로그인 아이디를 입력해 주세요.",
@ -38,7 +42,9 @@
"notAllowedConsecutiveAlphaNumOver3TimesForPassword": "연속되는 숫자나 문자를 3번이상 사용할 수 없습니다", "notAllowedConsecutiveAlphaNumOver3TimesForPassword": "연속되는 숫자나 문자를 3번이상 사용할 수 없습니다",
"notSatisfiedCombineForPassword": "문자, 숫자, 특수문자 중 2종류 이상 조합을 해야 합니다", "notSatisfiedCombineForPassword": "문자, 숫자, 특수문자 중 2종류 이상 조합을 해야 합니다",
"minLengthCombineForPassword": "비밀번호는 {{countOfCombine}}가지가 조합된 경우 {{lengthOfPassword}}자를 넘어야 합니다", "minLengthCombineForPassword": "비밀번호는 {{countOfCombine}}가지가 조합된 경우 {{lengthOfPassword}}자를 넘어야 합니다",
"failToChangePassword": "비밀번호 변경에 실패하였습니다." "failToChangePassword": "비밀번호 변경에 실패하였습니다.",
"loginFail": "아이디 또는 패스워드가<br/>일치하지 않습니다.",
"loginFailOverTry": "비밀번호 오류 횟수 초과입니다.<br/>비밀번호를 확인하신 후<br/>잠시 후 다시 시작해 주세요."
} }
}, },
"profile": { "profile": {
@ -203,6 +209,7 @@
"btnAttachFile": "첨부파일", "btnAttachFile": "첨부파일",
"btnSticker": "스티커", "btnSticker": "스티커",
"btnTranslate": "번역", "btnTranslate": "번역",
"noRoomUser": "대화상대 없음",
"event": { "event": {
"inviteToRoomWith": "{{owner}}이 {{inviter}}을 초대했습니다.", "inviteToRoomWith": "{{owner}}이 {{inviter}}을 초대했습니다.",
"exitFromRoomWith": "{{exitor}}님이 퇴장하셨습니다.", "exitFromRoomWith": "{{exitor}}님이 퇴장하셨습니다.",

View File

@ -46,8 +46,10 @@ export const decodeLogoutRemote: ProtocolDecoder<LogoutRemoteResponse> = (
} as LogoutRemoteResponse); } as LogoutRemoteResponse);
}; };
export const decodeLogoutRemoteNotification: ProtocolDecoder< export const decodeLogoutRemoteNotification: ProtocolDecoder<LogoutRemoteNotification> = (
LogoutRemoteNotification message: ProtocolMessage
> = (message: ProtocolMessage) => { ) => {
return { requestDeviceType: message.bodyList[0] } as LogoutRemoteNotification; return decodeProtocolMessage(message, {
requestDeviceType: message.bodyList[0]
} as LogoutRemoteNotification);
}; };

View File

@ -51,7 +51,7 @@
{{ roomInfo.roomName }} {{ roomInfo.roomName }}
</ng-template> </ng-template>
<ng-template #roomNameNotExist> <ng-template #roomNameNotExist>
{{ _roomUserInfos | ucapTranslate: 'name':',' }} {{ getRoomNameByRoomUser(_roomUserInfos) }}
</ng-template> </ng-template>
</ng-container> </ng-container>
</ng-container> </ng-container>
@ -94,6 +94,5 @@
matBadgeOverlap="true" matBadgeOverlap="true"
matBadgeColor="accent" matBadgeColor="accent"
matBadgePosition="below after" matBadgePosition="below after"
> ></div>
</div>
</div> </div>

View File

@ -4,7 +4,8 @@ import {
Input, Input,
Output, Output,
EventEmitter, EventEmitter,
ViewChildren ViewChildren,
ChangeDetectorRef
} from '@angular/core'; } from '@angular/core';
import { import {
RoomInfo, RoomInfo,
@ -15,8 +16,9 @@ import {
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { FormsModule } from '@angular/forms'; import { TranslatePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/translate.pipe';
import { MatCheckbox } from '@angular/material'; import { TranslateService as uiTranslateService } from '@ucap-webmessenger/ui';
import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
selector: 'ucap-room-list-item', selector: 'ucap-room-list-item',
@ -50,7 +52,12 @@ export class ListItemComponent implements OnInit {
finalEventMessage: string; finalEventMessage: string;
RoomType = RoomType; RoomType = RoomType;
constructor(private logger: NGXLogger) {} constructor(
private logger: NGXLogger,
private uiTranslateService: uiTranslateService,
private translateService: TranslateService,
private changeDetectorRef: ChangeDetectorRef
) {}
ngOnInit() { ngOnInit() {
if (this.roomInfo.isTimeRoom) { if (this.roomInfo.isTimeRoom) {
@ -96,6 +103,18 @@ export class ListItemComponent implements OnInit {
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
} }
getRoomNameByRoomUser(roomUserInfos: (RoomUserInfo | UserInfoShort)[]) {
let roomName = new TranslatePipe(
this.uiTranslateService,
this.changeDetectorRef
).transform(roomUserInfos, 'name', ',');
if (!roomName || roomName.trim().length === 0) {
roomName = this.translateService.instant('chat.noRoomUser');
}
return roomName;
}
// getChecked(value: boolean, roomInfo: RoomInfo) { // getChecked(value: boolean, roomInfo: RoomInfo) {
// if (value && !this.multiCheckable) { // if (value && !this.multiCheckable) {
// if (this.selected === roomInfo.roomSeq) { // if (this.selected === roomInfo.roomSeq) {