preparement of deploy

This commit is contained in:
병준 박 2019-11-12 18:54:21 +09:00
parent 1d282b59cb
commit e9b444e64b
80 changed files with 1384 additions and 923 deletions

View File

@ -82,7 +82,7 @@
"budgets": [ "budgets": [
{ {
"type": "initial", "type": "initial",
"maximumWarning": "2mb", "maximumWarning": "4mb",
"maximumError": "5mb" "maximumError": "5mb"
}, },
{ {
@ -140,7 +140,7 @@
"budgets": [ "budgets": [
{ {
"type": "initial", "type": "initial",
"maximumWarning": "2mb", "maximumWarning": "4mb",
"maximumError": "5mb" "maximumError": "5mb"
}, },
{ {

View File

@ -4,14 +4,12 @@ module.exports = (config, options) => {
const PRODUCTION = process.env.NODE_ENV === 'production'; const PRODUCTION = process.env.NODE_ENV === 'production';
const BROWSER = process.env.UCAP_ENV_RUNTIME === 'BROWSER'; const BROWSER = process.env.UCAP_ENV_RUNTIME === 'BROWSER';
console.log('BROWSER', BROWSER, config.target);
if (!BROWSER) { if (!BROWSER) {
config.target = 'electron-renderer'; config.target = 'electron-renderer';
} else { } else {
config.target = 'web'; config.target = 'web';
config.node = { config.node = {
fs: 'empty' fs: 'empty',
}; };
} }
@ -21,7 +19,7 @@ module.exports = (config, options) => {
__dirname, __dirname,
'..', '..',
'projects/ucap-webmessenger-ui/src/assets/scss' 'projects/ucap-webmessenger-ui/src/assets/scss'
) ),
}; };
return config; return config;

View File

@ -20,18 +20,18 @@ const mainConfig: webpack.Configuration = {
__dirname, __dirname,
'..', '..',
'electron-projects/ucap-webmessenger-electron/src/index' 'electron-projects/ucap-webmessenger-electron/src/index'
) ),
}, },
target: 'electron-main', target: 'electron-main',
mode: enviroments.__DEV__ ? 'development' : 'production', mode: enviroments.__DEV__ ? 'development' : 'production',
devtool: 'source-map', devtool: 'source-map',
optimization: { optimization: {
noEmitOnErrors: true noEmitOnErrors: true,
}, },
externals, externals,
output: { output: {
filename: '[name].js', filename: '[name].js',
path: path.resolve(__dirname, '..', outputDir) path: path.resolve(__dirname, '..', outputDir),
}, },
module: { module: {
rules: [ rules: [
@ -44,7 +44,7 @@ const mainConfig: webpack.Configuration = {
'electron-projects/ucap-webmessenger-electron/src' 'electron-projects/ucap-webmessenger-electron/src'
), ),
path.resolve(__dirname, '..', 'electron-projects'), path.resolve(__dirname, '..', 'electron-projects'),
path.resolve(__dirname, '..', 'projects') path.resolve(__dirname, '..', 'projects'),
], ],
use: [ use: [
{ {
@ -55,20 +55,20 @@ const mainConfig: webpack.Configuration = {
__dirname, __dirname,
'..', '..',
'electron-projects/ucap-webmessenger-electron/tsconfig.electron.json' 'electron-projects/ucap-webmessenger-electron/tsconfig.electron.json'
) ),
} },
} },
], ],
exclude: /node_modules/ exclude: /node_modules/,
}, },
{ {
test: /\.node$/, test: /\.node$/,
loader: 'awesome-node-loader', loader: 'awesome-node-loader',
options: { options: {
name: '[name].[ext]' name: '[name].[ext]',
} },
} },
] ],
}, },
plugins: [ plugins: [
new CleanWebpackPlugin({ verbose: false }), new CleanWebpackPlugin({ verbose: false }),
@ -77,16 +77,16 @@ const mainConfig: webpack.Configuration = {
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new webpack.DefinePlugin( new webpack.DefinePlugin(
Object.assign({}, enviroments, { Object.assign({}, enviroments, {
__PROCESS_KIND__: JSON.stringify('main') __PROCESS_KIND__: JSON.stringify('main'),
}) })
), ),
new CopyWebpackPlugin([ new CopyWebpackPlugin([
{ {
from: 'ucap-webmessenger-electron/resources/**/*', from: 'ucap-webmessenger-electron/resources/**/*',
to: path.resolve(__dirname, '..', 'dist'), to: path.resolve(__dirname, '..', 'dist'),
context: 'electron-projects' context: 'electron-projects',
} },
]) ]),
], ],
resolve: { resolve: {
extensions: ['.js', '.ts'], extensions: ['.js', '.ts'],
@ -101,6 +101,11 @@ const mainConfig: webpack.Configuration = {
'..', '..',
'electron-projects/ucap-webmessenger-electron-notification/src/public-api' 'electron-projects/ucap-webmessenger-electron-notification/src/public-api'
), ),
'@ucap-webmessenger/core': path.resolve(
__dirname,
'..',
'projects/ucap-webmessenger-core/src/public-api'
),
'@ucap-webmessenger/native': path.resolve( '@ucap-webmessenger/native': path.resolve(
__dirname, __dirname,
'..', '..',
@ -115,14 +120,14 @@ const mainConfig: webpack.Configuration = {
__dirname, __dirname,
'..', '..',
'electron-projects/ucap-webmessenger-electron/src/public-api' 'electron-projects/ucap-webmessenger-electron/src/public-api'
) ),
}, },
modules: [path.resolve(__dirname, '..', 'node_modules/')] modules: [path.resolve(__dirname, '..', 'node_modules/')],
}, },
node: { node: {
__dirname: false, __dirname: false,
__filename: false __filename: false,
} },
}; };
export default [mainConfig]; export default [mainConfig];

View File

@ -0,0 +1,9 @@
version: '3.1'
services:
nginx:
image: nginx:1.17.5-alpine
volumes:
- ../dist/ucap-webmessenger-app:/usr/share/nginx/html:ro
ports:
- 8099:80

View File

@ -19,6 +19,9 @@
"@ucap-webmessenger/electron-notification": [ "@ucap-webmessenger/electron-notification": [
"../ucap-webmessenger-electron-notification/src/public-api" "../ucap-webmessenger-electron-notification/src/public-api"
], ],
"@ucap-webmessenger/core": [
"../../projects/ucap-webmessenger-core/src/public-api"
],
"@ucap-webmessenger/native": [ "@ucap-webmessenger/native": [
"../../projects/ucap-webmessenger-native/src/public-api" "../../projects/ucap-webmessenger-native/src/public-api"
], ],

View File

@ -8,6 +8,7 @@
"start:renderer": "cross-env UCAP_ENV_RUNTIME=ELECTRON ng serve -c renderer-development", "start:renderer": "cross-env UCAP_ENV_RUNTIME=ELECTRON ng serve -c renderer-development",
"start:browser": "cross-env UCAP_ENV_RUNTIME=BROWSER ng serve -c browser-development -o", "start:browser": "cross-env UCAP_ENV_RUNTIME=BROWSER ng serve -c browser-development -o",
"build:renderer": "cross-env NODE_ENV=production ng build --base-href ./", "build:renderer": "cross-env NODE_ENV=production ng build --base-href ./",
"build:browser": "cross-env UCAP_ENV_RUNTIME=BROWSER ng build -c browser-development",
"build:main:development": "cross-env NODE_ENV=development TS_NODE_PROJECT='./config/tsconfig.webpack.json' parallel-webpack --config=config/main.webpack.config.ts", "build:main:development": "cross-env NODE_ENV=development TS_NODE_PROJECT='./config/tsconfig.webpack.json' parallel-webpack --config=config/main.webpack.config.ts",
"build:main:production": "cross-env NODE_ENV=production TS_NODE_PROJECT='./config/tsconfig.webpack.json' NODE_OPTIONS='--max_old_space_size=4096' parallel-webpack --config=config/main.webpack.config.ts", "build:main:production": "cross-env NODE_ENV=production TS_NODE_PROJECT='./config/tsconfig.webpack.json' NODE_OPTIONS='--max_old_space_size=4096' parallel-webpack --config=config/main.webpack.config.ts",
"test": "ng test", "test": "ng test",

View File

@ -0,0 +1,7 @@
import { ModuleConfig as CoreModuleConfig } from '@ucap-webmessenger/core';
import { Urls } from './urls';
export interface ModuleConfig extends CoreModuleConfig<Urls> {
acceptableFileExtensions: string[];
}

View File

@ -0,0 +1,12 @@
export interface Urls {
fileProfileSave: string;
fileTalkDownload: string;
fileTalkSave: string;
fileTalkShare: string;
massTalkDownload: string;
massTalkSave: string;
transMassTalkDownload: string;
transMassTalkSave: string;
translationReq: string;
translationSave: string;
}

View File

@ -3,82 +3,92 @@ import {
HttpClient, HttpClient,
HttpEventType, HttpEventType,
HttpResponse, HttpResponse,
HttpRequest HttpRequest,
} from '@angular/common/http'; } from '@angular/common/http';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { map, filter } from 'rxjs/operators'; import { map, filter } from 'rxjs/operators';
import { _MODULE_CONFIG } from '../types/token';
import { ModuleConfig } from '../types/module-config';
import { import {
FileProfileSaveRequest, FileProfileSaveRequest,
FileProfileSaveResponse, FileProfileSaveResponse,
encodeFileProfileSave, encodeFileProfileSave,
decodeFileProfileSave decodeFileProfileSave,
} from '../apis/file-profile-save'; } from '../apis/file-profile-save';
import { import {
FileTalkDownloadRequest, FileTalkDownloadRequest,
encodeFileTalkDownload, encodeFileTalkDownload,
encodeFormDataFileTalkDownload encodeFormDataFileTalkDownload,
} from '../apis/file-talk-download'; } from '../apis/file-talk-download';
import { import {
FileTalkSaveRequest, FileTalkSaveRequest,
FileTalkSaveResponse, FileTalkSaveResponse,
encodeFileTalkSave, encodeFileTalkSave,
decodeFileTalkSave decodeFileTalkSave,
} from '../apis/file-talk-save'; } from '../apis/file-talk-save';
import { import {
FileTalkShareRequest, FileTalkShareRequest,
FileTalkShareResponse, FileTalkShareResponse,
encodeFileTalkShare, encodeFileTalkShare,
decodeFileTalkShare decodeFileTalkShare,
} from '../apis/file-talk-share'; } from '../apis/file-talk-share';
import { import {
MassTalkDownloadRequest, MassTalkDownloadRequest,
MassTalkDownloadResponse, MassTalkDownloadResponse,
encodeMassTalkDownload, encodeMassTalkDownload,
decodeMassTalkDownload decodeMassTalkDownload,
} from '../apis/mass-talk-download'; } from '../apis/mass-talk-download';
import { import {
MassTalkSaveRequest, MassTalkSaveRequest,
MassTalkSaveResponse, MassTalkSaveResponse,
encodeMassTalkSave, encodeMassTalkSave,
decodeMassTalkSave decodeMassTalkSave,
} from '../apis/mass-talk-save'; } from '../apis/mass-talk-save';
import { import {
TransMassTalkDownloadRequest, TransMassTalkDownloadRequest,
TransMassTalkDownloadResponse, TransMassTalkDownloadResponse,
encodeTransMassTalkDownload, encodeTransMassTalkDownload,
decodeTransMassTalkDownload decodeTransMassTalkDownload,
} from '../apis/trans-mass-talk-download'; } from '../apis/trans-mass-talk-download';
import { import {
TransMassTalkSaveRequest, TransMassTalkSaveRequest,
TransMassTalkSaveResponse, TransMassTalkSaveResponse,
encodeTransMassTalkSave, encodeTransMassTalkSave,
decodeTransMassTalkSave decodeTransMassTalkSave,
} from '../apis/trans-mass-talk-save'; } from '../apis/trans-mass-talk-save';
import { import {
TranslationReqRequest, TranslationReqRequest,
TranslationReqResponse, TranslationReqResponse,
encodeTranslationReq, encodeTranslationReq,
decodeTranslationReq decodeTranslationReq,
} from '../apis/translation-req'; } from '../apis/translation-req';
import { import {
TranslationSaveRequest, TranslationSaveRequest,
TranslationSaveResponse, TranslationSaveResponse,
encodeTranslationSave, encodeTranslationSave,
decodeTranslationSave decodeTranslationSave,
} from '../apis/translation-save'; } from '../apis/translation-save';
import { _MODULE_CONFIG } from '../config/token';
import { ModuleConfig } from '../config/module-config';
import { Urls } from '../config/urls';
import { UrlConfig } from '@ucap-webmessenger/core';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class CommonApiService { export class CommonApiService {
readonly urls: Urls;
constructor( constructor(
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig, @Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
private httpClient: HttpClient private httpClient: HttpClient
) {} ) {
this.urls = UrlConfig.getUrls(
this.moduleConfig.hostConfig,
this.moduleConfig.urls
);
}
public fileProfileSave( public fileProfileSave(
req: FileProfileSaveRequest, req: FileProfileSaveRequest,
@ -86,12 +96,10 @@ export class CommonApiService {
): Observable<FileProfileSaveResponse> { ): Observable<FileProfileSaveResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
!!fileProfileSaveUrl !!fileProfileSaveUrl ? fileProfileSaveUrl : this.urls.fileProfileSave,
? fileProfileSaveUrl
: this.moduleConfig.urls.fileProfileSave,
{}, {},
{ {
params: encodeFileProfileSave(req) params: encodeFileProfileSave(req),
} }
) )
.pipe(map(res => decodeFileProfileSave(res))); .pipe(map(res => decodeFileProfileSave(res)));
@ -103,12 +111,10 @@ export class CommonApiService {
): string { ): string {
const httpReq = new HttpRequest( const httpReq = new HttpRequest(
'GET', 'GET',
!!fileTalkDownloadUrl !!fileTalkDownloadUrl ? fileTalkDownloadUrl : this.urls.fileTalkDownload,
? fileTalkDownloadUrl
: this.moduleConfig.urls.fileTalkDownload,
{}, {},
{ {
params: encodeFileTalkDownload(req) params: encodeFileTalkDownload(req),
} }
); );
@ -121,9 +127,7 @@ export class CommonApiService {
): Observable<Blob> { ): Observable<Blob> {
const httpReq = new HttpRequest( const httpReq = new HttpRequest(
'POST', 'POST',
!!fileTalkDownloadUrl !!fileTalkDownloadUrl ? fileTalkDownloadUrl : this.urls.fileTalkDownload,
? fileTalkDownloadUrl
: this.moduleConfig.urls.fileTalkDownload,
encodeFormDataFileTalkDownload(req), encodeFormDataFileTalkDownload(req),
{ reportProgress: true, responseType: 'blob' } { reportProgress: true, responseType: 'blob' }
); );
@ -159,7 +163,7 @@ export class CommonApiService {
): Observable<FileTalkSaveResponse> { ): Observable<FileTalkSaveResponse> {
const httpReq = new HttpRequest( const httpReq = new HttpRequest(
'POST', 'POST',
!!fileTalkSaveUrl ? fileTalkSaveUrl : this.moduleConfig.urls.fileTalkSave, !!fileTalkSaveUrl ? fileTalkSaveUrl : this.urls.fileTalkSave,
encodeFileTalkSave(req), encodeFileTalkSave(req),
{ reportProgress: true, responseType: 'text' as 'json' } { reportProgress: true, responseType: 'text' as 'json' }
); );
@ -185,7 +189,10 @@ export class CommonApiService {
public acceptableExtensionForFileTalk(extensions: string[]): boolean { public acceptableExtensionForFileTalk(extensions: string[]): boolean {
for (const extension of extensions) { for (const extension of extensions) {
if ( if (
-1 === this.moduleConfig.acceptableFileExtensions.indexOf(extension.toLowerCase()) -1 ===
this.moduleConfig.acceptableFileExtensions.indexOf(
extension.toLowerCase()
)
) { ) {
return false; return false;
} }
@ -198,10 +205,10 @@ export class CommonApiService {
): Observable<FileTalkShareResponse> { ): Observable<FileTalkShareResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.fileTalkShare, this.urls.fileTalkShare,
{}, {},
{ {
params: encodeFileTalkShare(req) params: encodeFileTalkShare(req),
} }
) )
.pipe(map(res => decodeFileTalkShare(res))); .pipe(map(res => decodeFileTalkShare(res)));
@ -212,11 +219,11 @@ export class CommonApiService {
): Observable<MassTalkDownloadResponse> { ): Observable<MassTalkDownloadResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.massTalkDownload, this.urls.massTalkDownload,
{}, {},
{ {
params: encodeMassTalkDownload(req), params: encodeMassTalkDownload(req),
responseType: 'text' as 'json' responseType: 'text' as 'json',
} }
) )
.pipe(map(res => decodeMassTalkDownload(res))); .pipe(map(res => decodeMassTalkDownload(res)));
@ -227,11 +234,11 @@ export class CommonApiService {
): Observable<MassTalkSaveResponse> { ): Observable<MassTalkSaveResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.massTalkSave, this.urls.massTalkSave,
{}, {},
{ {
params: encodeMassTalkSave(req), params: encodeMassTalkSave(req),
responseType: 'text' as 'json' responseType: 'text' as 'json',
} }
) )
.pipe(map(res => decodeMassTalkSave(res))); .pipe(map(res => decodeMassTalkSave(res)));
@ -242,10 +249,10 @@ export class CommonApiService {
): Observable<TransMassTalkDownloadResponse> { ): Observable<TransMassTalkDownloadResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.transMassTalkDownload, this.urls.transMassTalkDownload,
{}, {},
{ {
params: encodeTransMassTalkDownload(req) params: encodeTransMassTalkDownload(req),
} }
) )
.pipe(map(res => decodeTransMassTalkDownload(res))); .pipe(map(res => decodeTransMassTalkDownload(res)));
@ -256,10 +263,10 @@ export class CommonApiService {
): Observable<TransMassTalkSaveResponse> { ): Observable<TransMassTalkSaveResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.transMassTalkSave, this.urls.transMassTalkSave,
{}, {},
{ {
params: encodeTransMassTalkSave(req) params: encodeTransMassTalkSave(req),
} }
) )
.pipe(map(res => decodeTransMassTalkSave(res))); .pipe(map(res => decodeTransMassTalkSave(res)));
@ -270,10 +277,10 @@ export class CommonApiService {
): Observable<TranslationReqResponse> { ): Observable<TranslationReqResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.translationReq, this.urls.translationReq,
{}, {},
{ {
params: encodeTranslationReq(req) params: encodeTranslationReq(req),
} }
) )
.pipe(map(res => decodeTranslationReq(res))); .pipe(map(res => decodeTranslationReq(res)));
@ -284,10 +291,10 @@ export class CommonApiService {
): Observable<TranslationSaveResponse> { ): Observable<TranslationSaveResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.translationSave, this.urls.translationSave,
{}, {},
{ {
params: encodeTranslationSave(req) params: encodeTranslationSave(req),
} }
) )
.pipe(map(res => decodeTranslationSave(res))); .pipe(map(res => decodeTranslationSave(res)));

View File

@ -1,15 +0,0 @@
export interface ModuleConfig {
urls: {
fileProfileSave: string;
fileTalkDownload: string;
fileTalkSave: string;
fileTalkShare: string;
massTalkDownload: string;
massTalkSave: string;
transMassTalkDownload: string;
transMassTalkSave: string;
translationReq: string;
translationSave: string;
};
acceptableFileExtensions: string[];
}

View File

@ -1,15 +1,16 @@
import { NgModule, ModuleWithProviders } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { _MODULE_CONFIG } from './types/token';
import { CommonApiService } from './services/common-api.service'; import { CommonApiService } from './services/common-api.service';
import { ModuleConfig } from './types/module-config';
import { _MODULE_CONFIG } from './config/token';
import { ModuleConfig } from './config/module-config';
const SERVICES = [CommonApiService]; const SERVICES = [CommonApiService];
@NgModule({ @NgModule({
declarations: [], declarations: [],
imports: [], imports: [],
exports: [] exports: [],
}) })
export class UCapCommonApiModule { export class UCapCommonApiModule {
public static forRoot( public static forRoot(
@ -17,7 +18,7 @@ export class UCapCommonApiModule {
): ModuleWithProviders<UCapCommonApiModule> { ): ModuleWithProviders<UCapCommonApiModule> {
return { return {
ngModule: UCapCommonApiModule, ngModule: UCapCommonApiModule,
providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES] providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES],
}; };
} }
} }

View File

@ -2,8 +2,6 @@
* Public API Surface of ucap-webmessenger-api-common * Public API Surface of ucap-webmessenger-api-common
*/ */
export * from './lib/types/module-config';
export * from './lib/apis/file-profile-save'; export * from './lib/apis/file-profile-save';
export * from './lib/apis/file-talk-download'; export * from './lib/apis/file-talk-download';
export * from './lib/apis/file-talk-save'; export * from './lib/apis/file-talk-save';
@ -21,3 +19,6 @@ export * from './lib/models/file-upload-item';
export * from './lib/services/common-api.service'; export * from './lib/services/common-api.service';
export * from './lib/ucap-common-api.module'; export * from './lib/ucap-common-api.module';
export * from './lib/config/urls';
export * from './lib/config/module-config';

View File

@ -0,0 +1,5 @@
import { ModuleConfig as CoreModuleConfig } from '@ucap-webmessenger/core';
import { Urls } from './urls';
export interface ModuleConfig extends CoreModuleConfig<Urls> {}

View File

@ -0,0 +1,6 @@
export interface Urls {
checkUserInfoEx: string;
companyList: string;
tokenUpdate: string;
urlInfo: string;
}

View File

@ -4,51 +4,61 @@ import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { _MODULE_CONFIG } from '../types/token';
import { ModuleConfig } from '../types/module-config';
import { import {
CheckUserInfoExRequest, CheckUserInfoExRequest,
CheckUserInfoExResponse, CheckUserInfoExResponse,
encodeCheckUserInfoEx, encodeCheckUserInfoEx,
decodeCheckUserInfoEx decodeCheckUserInfoEx,
} from '../apis/check-user-info-ex'; } from '../apis/check-user-info-ex';
import { import {
CompanyListRequest, CompanyListRequest,
CompanyListResponse, CompanyListResponse,
encodeCompanyList, encodeCompanyList,
decodeCompanyList decodeCompanyList,
} from '../apis/company-list'; } from '../apis/company-list';
import { import {
TokenUpdateRequest, TokenUpdateRequest,
TokenUpdateResponse, TokenUpdateResponse,
encodeTokenUpdate, encodeTokenUpdate,
decodeTokenUpdate decodeTokenUpdate,
} from '../apis/token-update'; } from '../apis/token-update';
import { import {
UrlInfoResponse, UrlInfoResponse,
UrlInfoRequest, UrlInfoRequest,
encodeUrlInfo, encodeUrlInfo,
decodeUrlInfo decodeUrlInfo,
} from '../apis/url-info'; } from '../apis/url-info';
import { _MODULE_CONFIG } from '../config/token';
import { ModuleConfig } from '../config/module-config';
import { Urls } from '../config/urls';
import { UrlConfig } from '@ucap-webmessenger/core';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class ExternalApiService { export class ExternalApiService {
readonly urls: Urls;
constructor( constructor(
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig, @Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
private httpClient: HttpClient private httpClient: HttpClient
) {} ) {
this.urls = UrlConfig.getUrls(
this.moduleConfig.hostConfig,
this.moduleConfig.urls
);
}
public checkUserInfoEx( public checkUserInfoEx(
req: CheckUserInfoExRequest req: CheckUserInfoExRequest
): Observable<CheckUserInfoExResponse> { ): Observable<CheckUserInfoExResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.checkUserInfoEx, this.urls.checkUserInfoEx,
{}, {},
{ {
params: encodeCheckUserInfoEx(req) params: encodeCheckUserInfoEx(req),
} }
) )
.pipe(map(res => decodeCheckUserInfoEx(res))); .pipe(map(res => decodeCheckUserInfoEx(res)));
@ -57,10 +67,10 @@ export class ExternalApiService {
public companyList(req: CompanyListRequest): Observable<CompanyListResponse> { public companyList(req: CompanyListRequest): Observable<CompanyListResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.companyList, this.urls.companyList,
{}, {},
{ {
params: encodeCompanyList(req) params: encodeCompanyList(req),
} }
) )
.pipe(map(res => decodeCompanyList(res))); .pipe(map(res => decodeCompanyList(res)));
@ -69,10 +79,10 @@ export class ExternalApiService {
public tokenUpdate(req: TokenUpdateRequest): Observable<TokenUpdateResponse> { public tokenUpdate(req: TokenUpdateRequest): Observable<TokenUpdateResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.tokenUpdate, this.urls.tokenUpdate,
{}, {},
{ {
params: encodeTokenUpdate(req) params: encodeTokenUpdate(req),
} }
) )
.pipe(map(res => decodeTokenUpdate(res))); .pipe(map(res => decodeTokenUpdate(res)));
@ -81,10 +91,10 @@ export class ExternalApiService {
public urlInfo(req: UrlInfoRequest): Observable<UrlInfoResponse> { public urlInfo(req: UrlInfoRequest): Observable<UrlInfoResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.urlInfo, this.urls.urlInfo,
{}, {},
{ {
params: encodeUrlInfo(req) params: encodeUrlInfo(req),
} }
) )
.pipe(map(res => decodeUrlInfo(res))); .pipe(map(res => decodeUrlInfo(res)));

View File

@ -1,8 +0,0 @@
export interface ModuleConfig {
urls: {
checkUserInfoEx: string;
companyList: string;
tokenUpdate: string;
urlInfo: string;
};
}

View File

@ -1,15 +1,16 @@
import { NgModule, ModuleWithProviders } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { _MODULE_CONFIG } from './types/token';
import { ExternalApiService } from './services/external-api.service'; import { ExternalApiService } from './services/external-api.service';
import { ModuleConfig } from './types/module-config';
import { _MODULE_CONFIG } from './config/token';
import { ModuleConfig } from './config/module-config';
const SERVICES = [ExternalApiService]; const SERVICES = [ExternalApiService];
@NgModule({ @NgModule({
declarations: [], declarations: [],
imports: [], imports: [],
exports: [] exports: [],
}) })
export class UCapExternalApiModule { export class UCapExternalApiModule {
public static forRoot( public static forRoot(
@ -17,7 +18,7 @@ export class UCapExternalApiModule {
): ModuleWithProviders<UCapExternalApiModule> { ): ModuleWithProviders<UCapExternalApiModule> {
return { return {
ngModule: UCapExternalApiModule, ngModule: UCapExternalApiModule,
providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES] providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES],
}; };
} }
} }

View File

@ -2,8 +2,6 @@
* Public API Surface of ucap-webmessenger-api-public * Public API Surface of ucap-webmessenger-api-public
*/ */
export * from './lib/types/module-config';
export * from './lib/models/company'; export * from './lib/models/company';
export * from './lib/apis/check-user-info-ex'; export * from './lib/apis/check-user-info-ex';
@ -14,3 +12,6 @@ export * from './lib/apis/url-info';
export * from './lib/services/external-api.service'; export * from './lib/services/external-api.service';
export * from './lib/ucap-external-api.module'; export * from './lib/ucap-external-api.module';
export * from './lib/config/urls';
export * from './lib/config/module-config';

View File

@ -4,7 +4,7 @@ import {
APIResponse, APIResponse,
APIEncoder, APIEncoder,
APIDecoder, APIDecoder,
ParameterUtil ParameterUtil,
} from '@ucap-webmessenger/api'; } from '@ucap-webmessenger/api';
export interface UpdateInfoRequest extends APIRequest { export interface UpdateInfoRequest extends APIRequest {
@ -19,7 +19,7 @@ export interface UpdateInfoResponse extends APIResponse {
} }
const updateInfoEncodeMap = { const updateInfoEncodeMap = {
deviceType: 'p_device_type' deviceType: 'p_device_type',
}; };
export const encodeUpdateInfo: APIEncoder<UpdateInfoRequest> = ( export const encodeUpdateInfo: APIEncoder<UpdateInfoRequest> = (
@ -35,6 +35,6 @@ export const decodeUpdateInfo: APIDecoder<UpdateInfoResponse> = (res: any) => {
appVersion: res.AppVer, appVersion: res.AppVer,
installUrl: res.InstallURL, installUrl: res.InstallURL,
launcherAppVersion: res.LauncherAppVer, launcherAppVersion: res.LauncherAppVer,
launcherInstallUrl: res.LauncherInstallURL launcherInstallUrl: res.LauncherInstallURL,
} as UpdateInfoResponse; } as UpdateInfoResponse;
}; };

View File

@ -0,0 +1,5 @@
import { ModuleConfig as CoreModuleConfig } from '@ucap-webmessenger/core';
import { Urls } from './urls';
export interface ModuleConfig extends CoreModuleConfig<Urls> {}

View File

@ -0,0 +1,4 @@
export interface Urls {
versionInfo2: string;
updateInfo: string;
}

View File

@ -4,39 +4,49 @@ import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { _MODULE_CONFIG } from '../types/token';
import { import {
VersionInfo2Request, VersionInfo2Request,
VersionInfo2Response, VersionInfo2Response,
encodeVersionInfo2, encodeVersionInfo2,
decodeVersionInfo2 decodeVersionInfo2,
} from '../apis/version-info2'; } from '../apis/version-info2';
import { import {
UpdateInfoRequest, UpdateInfoRequest,
UpdateInfoResponse, UpdateInfoResponse,
encodeUpdateInfo, encodeUpdateInfo,
decodeUpdateInfo decodeUpdateInfo,
} from '../apis/update-info'; } from '../apis/update-info';
import { ModuleConfig } from '../types/module-config';
import { _MODULE_CONFIG } from '../config/token';
import { ModuleConfig } from '../config/module-config';
import { UrlConfig } from '@ucap-webmessenger/core';
import { Urls } from '../config/urls';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class PublicApiService { export class PublicApiService {
readonly urls: Urls;
constructor( constructor(
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig, @Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
private httpClient: HttpClient private httpClient: HttpClient
) {} ) {
this.urls = UrlConfig.getUrls(
this.moduleConfig.hostConfig,
this.moduleConfig.urls
);
}
public versionInfo2( public versionInfo2(
req: VersionInfo2Request req: VersionInfo2Request
): Observable<VersionInfo2Response> { ): Observable<VersionInfo2Response> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.versionInfo2, this.urls.versionInfo2,
{}, {},
{ {
params: encodeVersionInfo2(req) params: encodeVersionInfo2(req),
} }
) )
.pipe(map((res: any) => decodeVersionInfo2(res))); .pipe(map((res: any) => decodeVersionInfo2(res)));
@ -45,10 +55,10 @@ export class PublicApiService {
public updateInfo(req: UpdateInfoRequest): Observable<UpdateInfoResponse> { public updateInfo(req: UpdateInfoRequest): Observable<UpdateInfoResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.updateInfo, this.urls.updateInfo,
{}, {},
{ {
params: encodeUpdateInfo(req) params: encodeUpdateInfo(req),
} }
) )
.pipe(map(res => decodeUpdateInfo(res))); .pipe(map(res => decodeUpdateInfo(res)));

View File

@ -1,6 +0,0 @@
export interface ModuleConfig {
urls: {
versionInfo2: string;
updateInfo: string;
};
}

View File

@ -1,15 +1,16 @@
import { NgModule, ModuleWithProviders } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { _MODULE_CONFIG } from './types/token';
import { PublicApiService } from './services/public-api.service'; import { PublicApiService } from './services/public-api.service';
import { ModuleConfig } from './types/module-config';
import { _MODULE_CONFIG } from './config/token';
import { ModuleConfig } from './config/module-config';
const SERVICES = [PublicApiService]; const SERVICES = [PublicApiService];
@NgModule({ @NgModule({
declarations: [], declarations: [],
imports: [], imports: [],
exports: [] exports: [],
}) })
export class UCapPublicApiModule { export class UCapPublicApiModule {
public static forRoot( public static forRoot(
@ -17,7 +18,7 @@ export class UCapPublicApiModule {
): ModuleWithProviders<UCapPublicApiModule> { ): ModuleWithProviders<UCapPublicApiModule> {
return { return {
ngModule: UCapPublicApiModule, ngModule: UCapPublicApiModule,
providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES] providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES],
}; };
} }
} }

View File

@ -7,7 +7,9 @@ export * from './lib/apis/version-info2';
export * from './lib/services/public-api.service'; export * from './lib/services/public-api.service';
export * from './lib/types/module-config';
export * from './lib/types/sync-mode.type'; export * from './lib/types/sync-mode.type';
export * from './lib/ucap-public-api.module'; export * from './lib/ucap-public-api.module';
export * from './lib/config/urls';
export * from './lib/config/module-config';

View File

@ -1,4 +1,4 @@
export enum StatusCode { export enum StatusCode {
Success = '200', Success = '200',
Fail = '500' Fail = '500',
} }

View File

@ -1,35 +1,59 @@
import { NgModule, APP_INITIALIZER } from '@angular/core'; import { NgModule, APP_INITIALIZER, Type } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
import { RESOLVERS } from './resolvers'; import { RESOLVERS } from './resolvers';
import { SERVICES } from './services'; import { SERVICES } from './services';
import { AppService } from './services/app.service'; import { AppService } from './services/app.service';
import { HttpClient } from '@angular/common/http';
import { UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { environment } from '../environments/environment';
export function initializeApp(appService: AppService) { import { environment } from '../environments/environment';
import { BrowserNativeService } from '@ucap-webmessenger/native-browser';
import { ElectronNativeService } from '@ucap-webmessenger/native-electron';
export function initializeApp(
appService: AppService,
nativeService: NativeService
) {
return (): Promise<any> => { return (): Promise<any> => {
return appService.postInit(); return appService.postInit();
}; };
} }
// export function nativeServiceFactory(httpClient: HttpClient) {
// if ('browser' === environment.runtime) {
// return import('@ucap-webmessenger/native-browser').then(
// m => new m.BrowserNativeService(httpClient)
// );
// } else {
// return import('@ucap-webmessenger/native-electron').then(
// m => new m.ElectronNativeService()
// );
// }
// }
@NgModule({ @NgModule({
imports: [], imports: [],
exports: [], exports: [],
providers: [ providers: [
...SERVICES,
...RESOLVERS,
{ {
provide: UCAP_NATIVE_SERVICE, provide: UCAP_NATIVE_SERVICE,
useClass: environment.modules.native.serviceClass, // useFactory: nativeServiceFactory,
deps: [HttpClient] useClass:
'browser' === environment.runtime
? BrowserNativeService
: ElectronNativeService,
deps: [HttpClient],
}, },
...SERVICES,
...RESOLVERS,
{ {
provide: APP_INITIALIZER, provide: APP_INITIALIZER,
useFactory: initializeApp, useFactory: initializeApp,
deps: [AppService, UCAP_NATIVE_SERVICE], deps: [AppService, UCAP_NATIVE_SERVICE],
multi: true multi: true,
} },
] ],
}) })
export class AppProviderModule {} export class AppProviderModule {}

View File

@ -10,26 +10,26 @@ const routes: Routes = [
import('./pages/messenger/messenger.page.module').then( import('./pages/messenger/messenger.page.module').then(
m => m.AppMessengerPageModule m => m.AppMessengerPageModule
), ),
canActivate: [AppAuthGuard] canActivate: [AppAuthGuard],
}, },
{ {
path: 'account', path: 'account',
loadChildren: () => loadChildren: () =>
import('./pages/account/account.page.module').then( import('./pages/account/account.page.module').then(
m => m.AppAccountPageModule m => m.AppAccountPageModule
) ),
}, },
{ {
path: 'template', path: 'template',
loadChildren: () => loadChildren: () =>
import('./pages/template/template.page.module').then( import('./pages/template/template.page.module').then(
m => m.AppTemplatePageModule m => m.AppTemplatePageModule
) ),
} },
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: false })], imports: [RouterModule.forRoot(routes, { enableTracing: false })],
exports: [RouterModule] exports: [RouterModule],
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

View File

@ -7,6 +7,13 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { UCapUiModule } from '@ucap-webmessenger/ui';
import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account';
import { UCapWebStorageModule } from '@ucap-webmessenger/web-storage';
import { UCapUtilModule } from '@ucap-webmessenger/util';
import { UCapCommonApiModule } from '@ucap-webmessenger/api-common'; import { UCapCommonApiModule } from '@ucap-webmessenger/api-common';
import { UCapExternalApiModule } from '@ucap-webmessenger/api-external'; import { UCapExternalApiModule } from '@ucap-webmessenger/api-external';
import { UCapPublicApiModule } from '@ucap-webmessenger/api-public'; import { UCapPublicApiModule } from '@ucap-webmessenger/api-public';
@ -25,17 +32,8 @@ import { UCapServiceProtocolModule } from '@ucap-webmessenger/protocol-service';
import { UCapStatusProtocolModule } from '@ucap-webmessenger/protocol-status'; import { UCapStatusProtocolModule } from '@ucap-webmessenger/protocol-status';
import { UCapSyncProtocolModule } from '@ucap-webmessenger/protocol-sync'; import { UCapSyncProtocolModule } from '@ucap-webmessenger/protocol-sync';
import { UCapUiModule } from '@ucap-webmessenger/ui';
import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account';
import { UCapWebStorageModule } from '@ucap-webmessenger/web-storage';
import { UCapUtilModule } from '@ucap-webmessenger/util';
import { LoggerModule, NgxLoggerLevel } from 'ngx-logger'; import { LoggerModule, NgxLoggerLevel } from 'ngx-logger';
import { environment } from '../environments/environment';
import { AppProviderModule } from './app-provider.module'; import { AppProviderModule } from './app-provider.module';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppStoreModule } from './app-store.module'; import { AppStoreModule } from './app-store.module';
@ -47,6 +45,8 @@ import { GUARDS } from './guards';
import { AppMessengerLayoutModule } from './layouts/messenger/messenger.layout.module'; import { AppMessengerLayoutModule } from './layouts/messenger/messenger.layout.module';
import { AppNativeLayoutModule } from './layouts/native/native.layout.module'; import { AppNativeLayoutModule } from './layouts/native/native.layout.module';
import { environment } from '../environments/environment';
@NgModule({ @NgModule({
imports: [ imports: [
BrowserModule, BrowserModule,
@ -58,28 +58,14 @@ import { AppNativeLayoutModule } from './layouts/native/native.layout.module';
PerfectScrollbarModule, PerfectScrollbarModule,
UCapCommonApiModule.forRoot({ UCapCommonApiModule.forRoot(environment.commonApiModuleConfig),
urls: environment.urls.apiCommon,
acceptableFileExtensions:
environment.modules.event.acceptableFileExtensions
}),
UCapPublicApiModule.forRoot({ UCapPublicApiModule.forRoot(environment.publicApiModuleConfig),
urls: environment.urls.apiPublic UCapExternalApiModule.forRoot(environment.externalApiModuleConfig),
}),
UCapExternalApiModule.forRoot({
urls: environment.urls.apiExternal
}),
UCapPiModule.forRoot({ UCapPiModule.forRoot(environment.piModuleConfig),
urls: environment.urls.pi
}),
UCapProtocolModule.forRoot({ UCapProtocolModule.forRoot(environment.protocolModuleConfig),
urls: environment.urls.protocol,
reconnect: environment.protocol.reconnect,
requestId: environment.protocol.requestId
}),
UCapAuthenticationProtocolModule.forRoot(), UCapAuthenticationProtocolModule.forRoot(),
UCapEventProtocolModule.forRoot(), UCapEventProtocolModule.forRoot(),
UCapGroupProtocolModule.forRoot(), UCapGroupProtocolModule.forRoot(),
@ -107,12 +93,12 @@ import { AppNativeLayoutModule } from './layouts/native/native.layout.module';
AppNativeLayoutModule, AppNativeLayoutModule,
LoggerModule.forRoot({ LoggerModule.forRoot({
level: NgxLoggerLevel.DEBUG level: NgxLoggerLevel.DEBUG,
}) }),
], ],
providers: [...GUARDS], providers: [...GUARDS],
declarations: [AppComponent], declarations: [AppComponent],
bootstrap: [AppComponent], bootstrap: [AppComponent],
entryComponents: [] entryComponents: [],
}) })
export class AppModule {} export class AppModule {}

View File

@ -9,8 +9,17 @@
<ng-template mat-tab-label> <ng-template mat-tab-label>
<!--<mat-icon>group</mat-icon>--> <!--<mat-icon>group</mat-icon>-->
<div class="icon-item"> <div class="icon-item">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" 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"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="butt"
stroke-linejoin="round"
>
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
<circle cx="12" cy="7" r="4"></circle> <circle cx="12" cy="7" r="4"></circle>
</svg> </svg>
@ -18,7 +27,7 @@
</ng-template> </ng-template>
<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()"
(openProfile)="onClickOpenProfile($event)" (openProfile)="onClickOpenProfile($event)"
></app-layout-chat-left-sidenav-group> ></app-layout-chat-left-sidenav-group>
</mat-tab> </mat-tab>
@ -32,16 +41,28 @@
matBadgePosition="above after" matBadgePosition="above after"
>chat</mat-icon >chat</mat-icon
>--> >-->
<div class="icon-item" [matBadgeHidden]="(badgeChatUnReadCount$ | async) <= 0" <div
class="icon-item"
[matBadgeHidden]="(badgeChatUnReadCount$ | async) <= 0"
[matBadge]="badgeChatUnReadCount$ | async" [matBadge]="badgeChatUnReadCount$ | async"
matBadgeDescription="확인하지 않은 메시지가 있습니다." matBadgeDescription="확인하지 않은 메시지가 있습니다."
matBadgeColor="accent" matBadgeColor="accent"
matBadgePosition="above after"> matBadgePosition="above after"
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" >
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="bevel"> <svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#000000"
stroke-width="1.5"
stroke-linecap="butt"
stroke-linejoin="bevel"
>
<path <path
d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"> d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"
</path> ></path>
</svg> </svg>
</div> </div>
</ng-template> </ng-template>
@ -51,8 +72,17 @@
<ng-template mat-tab-label> <ng-template mat-tab-label>
<!--<mat-icon>device_hub</mat-icon>--> <!--<mat-icon>device_hub</mat-icon>-->
<div class="icon-item"> <div class="icon-item">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" <svg
stroke-width="1.5" stroke-linecap="butt" stroke-linejoin="bevel"> xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#000000"
stroke-width="1.5"
stroke-linecap="butt"
stroke-linejoin="bevel"
>
<circle class="st0" cx="18.4" cy="18.5" r="3" /> <circle class="st0" cx="18.4" cy="18.5" r="3" />
<circle class="st0" cx="12" cy="5" r="3" /> <circle class="st0" cx="12" cy="5" r="3" />
<path class="st0" d="M12.4,10.5h4c1.1,0,2,0.9,2,2v3" /> <path class="st0" d="M12.4,10.5h4c1.1,0,2,0.9,2,2v3" />
@ -73,16 +103,27 @@
<ng-template mat-tab-label> <ng-template mat-tab-label>
<!--<mat-icon>phone</mat-icon>--> <!--<mat-icon>phone</mat-icon>-->
<div class="icon-item"> <div class="icon-item">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" <svg
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-phone"> xmlns="http://www.w3.org/2000/svg"
<path class="st0" width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-phone"
>
<path
class="st0"
d="M2,5.8c0.1-0.6,0.3-1.1,0.7-1.6l1.7-1.7C4.7,2.2,5,2.1,5.3,2.1c0.3,0,0.6,0.1,0.8,0.4c0.3,0.3,0.6,0.6,0.9,0.9 d="M2,5.8c0.1-0.6,0.3-1.1,0.7-1.6l1.7-1.7C4.7,2.2,5,2.1,5.3,2.1c0.3,0,0.6,0.1,0.8,0.4c0.3,0.3,0.6,0.6,0.9,0.9
c0.2,0.2,0.3,0.3,0.5,0.5l1.4,1.4c0.3,0.3,0.4,0.6,0.4,0.9S9.2,6.7,8.9,7C8.8,7.2,8.6,7.3,8.5,7.5C8.1,7.9,7.7,8.3,7.2,8.7 c0.2,0.2,0.3,0.3,0.5,0.5l1.4,1.4c0.3,0.3,0.4,0.6,0.4,0.9S9.2,6.7,8.9,7C8.8,7.2,8.6,7.3,8.5,7.5C8.1,7.9,7.7,8.3,7.2,8.7
c0,0,0,0,0,0C6.8,9.1,6.9,9.5,7,9.7c0,0,0,0,0,0c0.4,0.9,0.9,1.7,1.6,2.6c1.4,1.7,2.9,3,4.5,4.1c0.2,0.1,0.4,0.2,0.6,0.3 c0,0,0,0,0,0C6.8,9.1,6.9,9.5,7,9.7c0,0,0,0,0,0c0.4,0.9,0.9,1.7,1.6,2.6c1.4,1.7,2.9,3,4.5,4.1c0.2,0.1,0.4,0.2,0.6,0.3
c0.2,0.1,0.4,0.2,0.5,0.3c0,0,0,0,0.1,0c0.2,0.1,0.3,0.1,0.4,0.1c0.4,0,0.6-0.2,0.7-0.3l1.7-1.7c0.3-0.3,0.6-0.4,0.8-0.4 c0.2,0.1,0.4,0.2,0.5,0.3c0,0,0,0,0.1,0c0.2,0.1,0.3,0.1,0.4,0.1c0.4,0,0.6-0.2,0.7-0.3l1.7-1.7c0.3-0.3,0.6-0.4,0.8-0.4
c0.4,0,0.6,0.2,0.8,0.4l2.8,2.8c0.6,0.6,0.6,1.2,0,1.7c-0.2,0.2-0.4,0.4-0.6,0.6c-0.3,0.3-0.7,0.6-1,1c-0.5,0.6-1.2,0.8-2,0.8 c0.4,0,0.6,0.2,0.8,0.4l2.8,2.8c0.6,0.6,0.6,1.2,0,1.7c-0.2,0.2-0.4,0.4-0.6,0.6c-0.3,0.3-0.7,0.6-1,1c-0.5,0.6-1.2,0.8-2,0.8
c-0.1,0-0.2,0-0.2,0c-1.5-0.1-2.9-0.7-4-1.2c-2.9-1.4-5.4-3.4-7.5-5.9C4.5,13,3.3,11.1,2.6,9C2.1,7.7,1.9,6.7,2,5.8z"> c-0.1,0-0.2,0-0.2,0c-1.5-0.1-2.9-0.7-4-1.2c-2.9-1.4-5.4-3.4-7.5-5.9C4.5,13,3.3,11.1,2.6,9C2.1,7.7,1.9,6.7,2,5.8z"
</path> ></path>
</svg> </svg>
</div> </div>
</ng-template> </ng-template>

View File

@ -17,7 +17,7 @@
[companyList]="companyList$ | async" [companyList]="companyList$ | async"
[companyCode]="companyCode" [companyCode]="companyCode"
(keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)" (keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)"
(cancel)="onClickCancel($event)" (cancel)="onClickCancel()"
></ucap-organization-tenant-search> ></ucap-organization-tenant-search>
<mat-menu <mat-menu
@ -28,8 +28,17 @@
> >
<button mat-menu-item (click)="onClickGroupMenu('GROUP_NEW')"> <button mat-menu-item (click)="onClickGroupMenu('GROUP_NEW')">
<!--<mat-icon>group_add</mat-icon>--> <!--<mat-icon>group_add</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"
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="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
<circle cx="8.5" cy="7" r="4"></circle> <circle cx="8.5" cy="7" r="4"></circle>
<line x1="20" y1="8" x2="20" y2="14"></line> <line x1="20" y1="8" x2="20" y2="14"></line>

View File

@ -6,7 +6,7 @@
[companyList]="companyList$ | async" [companyList]="companyList$ | async"
[companyCode]="companyCode" [companyCode]="companyCode"
(keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)" (keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)"
(cancel)="onClickCancel($event)" (cancel)="onClickCancel()"
> >
</ucap-organization-tenant-search> </ucap-organization-tenant-search>
</div> </div>

View File

@ -66,7 +66,7 @@
<button <button
*ngIf="!!roomInfo" *ngIf="!!roomInfo"
mat-icon-button mat-icon-button
(click)="onClickReceiveAlarm($event)" (click)="onClickReceiveAlarm()"
aria-label="Toggle Receive Alarm" aria-label="Toggle Receive Alarm"
> >
<mat-icon class="amber-fg" *ngIf="roomInfo.receiveAlarm" <mat-icon class="amber-fg" *ngIf="roomInfo.receiveAlarm"

View File

@ -44,7 +44,7 @@
(keyDownEnter)=" (keyDownEnter)="
onKeyDownEnterOrganizationTenantSearch($event) onKeyDownEnterOrganizationTenantSearch($event)
" "
(cancel)="onClickCancel($event)" (cancel)="onClickCancel()"
></ucap-organization-tenant-search> ></ucap-organization-tenant-search>
</div> </div>
<div *ngIf="!isShowSearch" class="list-panel"> <div *ngIf="!isShowSearch" class="list-panel">

View File

@ -32,7 +32,7 @@ export class AppService {
this.sessionStorageService.set<EnvironmentsInfo>( this.sessionStorageService.set<EnvironmentsInfo>(
KEY_ENVIRONMENTS_INFO, KEY_ENVIRONMENTS_INFO,
{ {
deviceType deviceType,
} }
); );

View File

@ -6,7 +6,7 @@ import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { LoginInfo } from '@app/types'; import { LoginInfo } from '@app/types';
import { import {
UserPasswordSetRequest, UserPasswordSetRequest,
UserPasswordSetResponse UserPasswordSetResponse,
} from '@ucap-webmessenger/protocol-service'; } from '@ucap-webmessenger/protocol-service';
export const webLogin = createAction( export const webLogin = createAction(

View File

@ -9,14 +9,14 @@ import { Actions, ofType, createEffect } from '@ngrx/effects';
import { import {
PiService, PiService,
Login2Response, Login2Response,
UserTermsActionResponse UserTermsActionResponse,
} from '@ucap-webmessenger/pi'; } from '@ucap-webmessenger/pi';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { import {
DialogService, DialogService,
ConfirmDialogComponent, ConfirmDialogComponent,
ConfirmDialogData, ConfirmDialogData,
ConfirmDialogResult ConfirmDialogResult,
} from '@ucap-webmessenger/ui'; } from '@ucap-webmessenger/ui';
import { import {
@ -34,13 +34,13 @@ import {
privacyAgreeSuccess, privacyAgreeSuccess,
changePassword, changePassword,
changePasswordFailure, changePasswordFailure,
changePasswordSuccess changePasswordSuccess,
} from './actions'; } from './actions';
import { import {
LoginInfo, LoginInfo,
KEY_LOGIN_INFO, KEY_LOGIN_INFO,
EnvironmentsInfo, EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO KEY_ENVIRONMENTS_INFO,
} from '@app/types'; } from '@app/types';
import { AppAuthenticationService } from '@app/services/authentication.service'; import { AppAuthenticationService } from '@app/services/authentication.service';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
@ -48,7 +48,7 @@ import { Store } from '@ngrx/store';
import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { import {
ServiceProtocolService, ServiceProtocolService,
UserPasswordSetResponse UserPasswordSetResponse,
} from '@ucap-webmessenger/protocol-service'; } from '@ucap-webmessenger/protocol-service';
@Injectable() @Injectable()
@ -62,7 +62,7 @@ export class Effects {
.login2({ .login2({
loginId: params.loginInfo.loginId, loginId: params.loginInfo.loginId,
loginPw: params.loginInfo.loginPw, loginPw: params.loginInfo.loginPw,
companyCode: params.loginInfo.companyCode companyCode: params.loginInfo.companyCode,
}) })
.pipe( .pipe(
map((res: Login2Response) => { map((res: Login2Response) => {
@ -72,7 +72,7 @@ export class Effects {
return webLoginSuccess({ return webLoginSuccess({
loginInfo: params.loginInfo, loginInfo: params.loginInfo,
rememberMe: params.rememberMe, rememberMe: params.rememberMe,
login2Response: res login2Response: res,
}); });
} }
}), }),
@ -138,8 +138,8 @@ export class Effects {
width: '220px', width: '220px',
data: { data: {
title: 'Logout', title: 'Logout',
message: 'Logout ?' message: 'Logout ?',
} },
}); });
return result.choice; return result.choice;
@ -168,7 +168,7 @@ export class Effects {
token: loginRes.tokenString, token: loginRes.tokenString,
deviceType: environmentsInfo.deviceType, deviceType: environmentsInfo.deviceType,
localeCode: loginInfo.localeCode, localeCode: loginInfo.localeCode,
textOnly: 'true' textOnly: 'true',
}); });
const result = await this.dialogService.open< const result = await this.dialogService.open<
@ -180,9 +180,9 @@ export class Effects {
height: '500px', height: '500px',
disableClose: true, disableClose: true,
data: { data: {
title: '개인정보 동의' title: '개인정보 동의',
// html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />` // html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
} },
}); });
if (result.choice) { if (result.choice) {
@ -204,8 +204,8 @@ export class Effects {
disableClose: true, disableClose: true,
data: { data: {
title: '패스워드 만료', title: '패스워드 만료',
message: '' message: '',
} },
}); });
if (result.choice) { if (result.choice) {
@ -232,7 +232,7 @@ export class Effects {
return { return {
loginInfo, loginInfo,
environmentsInfo, environmentsInfo,
loginResponse: action.loginRes loginResponse: action.loginRes,
}; };
}), }),
exhaustMap(params => exhaustMap(params =>
@ -240,7 +240,7 @@ export class Effects {
.userTermsAction({ .userTermsAction({
userSeq: params.loginResponse.userSeq, userSeq: params.loginResponse.userSeq,
token: params.loginResponse.tokenString, token: params.loginResponse.tokenString,
deviceType: params.environmentsInfo.deviceType deviceType: params.environmentsInfo.deviceType,
}) })
.pipe( .pipe(
map((res: UserTermsActionResponse) => { map((res: UserTermsActionResponse) => {
@ -264,7 +264,7 @@ export class Effects {
this.serviceProtocolService.userPasswordSet(req).pipe( this.serviceProtocolService.userPasswordSet(req).pipe(
map((res: UserPasswordSetResponse) => { map((res: UserPasswordSetResponse) => {
return changePasswordSuccess({ return changePasswordSuccess({
res res,
}); });
}), }),
catchError(error => of(changePasswordFailure({ error }))) catchError(error => of(changePasswordFailure({ error })))

View File

@ -7,7 +7,7 @@ export const reducer = createReducer(
on(loginSuccess, (state, action) => { on(loginSuccess, (state, action) => {
return { return {
...state, ...state,
loginRes: action.loginRes loginRes: action.loginRes,
}; };
}) })
); );

View File

@ -7,14 +7,11 @@ export interface State {
} }
export const initialState: State = { export const initialState: State = {
loginRes: null loginRes: null,
}; };
export function selectors<S>(selector: Selector<any, State>) { export function selectors<S>(selector: Selector<any, State>) {
return { return {
loginRes: createSelector( loginRes: createSelector(selector, (state: State) => state.loginRes),
selector,
(state: State) => state.loginRes
)
}; };
} }

View File

@ -1,18 +1,7 @@
import { Environment, build } from './environment.type'; import { Environment } from './environment.type';
import { BrowserNativeService } from '@ucap-webmessenger/native-browser'; import { environment as devEnvironment } from './environment.dev';
// This file can be replaced during build by using the `fileReplacements` array. export const environment: Environment = {
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. ...devEnvironment,
// The list of file replacements can be found in `angular.json`. runtime: 'browser',
};
export const environment: Environment = build(false);
environment.modules.native.serviceClass = BrowserNativeService;
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.

View File

@ -1,5 +1,7 @@
import { Environment, build } from './environment.type'; import { Environment } from './environment.type';
import { BrowserNativeService } from '@ucap-webmessenger/native-browser'; import { environment as prodEnvironment } from './environment.prod';
export const environment: Environment = build(true); export const environment: Environment = {
environment.modules.native.serviceClass = BrowserNativeService; ...prodEnvironment,
runtime: 'browser',
};

View File

@ -1,18 +1,7 @@
import { Environment, build } from './environment.type'; import { Environment } from './environment.type';
import { ElectronNativeService } from '@ucap-webmessenger/native-electron'; import { environment as devEnvironment } from './environment.dev';
// This file can be replaced during build by using the `fileReplacements` array. export const environment: Environment = {
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. ...devEnvironment,
// The list of file replacements can be found in `angular.json`. runtime: 'electron',
};
export const environment: Environment = build(false);
environment.modules.native.serviceClass = ElectronNativeService;
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.

View File

@ -1,5 +1,7 @@
import { Environment, build } from './environment.type'; import { Environment } from './environment.type';
import { ElectronNativeService } from '@ucap-webmessenger/native-electron'; import { environment as prodEnvironment } from './environment.prod';
export const environment: Environment = build(true); export const environment: Environment = {
environment.modules.native.serviceClass = ElectronNativeService; ...prodEnvironment,
runtime: 'electron',
};

View File

@ -0,0 +1,69 @@
import {
Environment,
commonApiUrls,
commonApiacceptableFileExtensions,
publicApiUrls,
externalApiUrls,
piUrls,
protocolUrls,
} from './environment.type';
export const environment: Environment = {
production: false,
title: `[개발] Woori TALK`,
commonApiModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 8011,
},
urls: commonApiUrls,
acceptableFileExtensions: commonApiacceptableFileExtensions,
},
publicApiModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 8011,
},
urls: publicApiUrls,
},
externalApiModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 8011,
},
urls: externalApiUrls,
},
piModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 9097,
},
urls: piUrls,
},
protocolModuleConfig: {
hostConfig: {
protocol: 'ws',
domain: '27.122.224.170',
port: 8080,
},
urls: protocolUrls,
reconnect: {
delay: 1000,
},
requestId: {
min: 1,
max: 59999,
},
},
nativeModuleConfig: {},
};

View File

@ -0,0 +1,69 @@
import {
Environment,
commonApiUrls,
commonApiacceptableFileExtensions,
publicApiUrls,
externalApiUrls,
piUrls,
protocolUrls,
} from './environment.type';
export const environment: Environment = {
production: true,
title: `[개발] Woori TALK`,
commonApiModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 8011,
},
urls: commonApiUrls,
acceptableFileExtensions: commonApiacceptableFileExtensions,
},
publicApiModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 8011,
},
urls: publicApiUrls,
},
externalApiModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 8011,
},
urls: externalApiUrls,
},
piModuleConfig: {
hostConfig: {
protocol: 'http',
domain: '27.122.224.170',
port: 9097,
},
urls: piUrls,
},
protocolModuleConfig: {
hostConfig: {
protocol: 'ws',
domain: '27.122.224.170',
port: 8080,
},
urls: protocolUrls,
reconnect: {
delay: 1000,
},
requestId: {
min: 1,
max: 59999,
},
},
nativeModuleConfig: {},
};

View File

@ -1,10 +1,13 @@
import { Environment, build } from './environment.type'; import { Environment } from './environment.type';
import { environment as devEnvironment } from './environment.dev';
// This file can be replaced during build by using the `fileReplacements` array. // This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`. // The list of file replacements can be found in `angular.json`.
export const environment: Environment = build(false); export const environment: Environment = {
...devEnvironment,
};
/* /*
* For easier debugging in development mode, you can import the following file * For easier debugging in development mode, you can import the following file

View File

@ -0,0 +1,7 @@
export type HostProtocol = 'http' | 'https' | 'ws' | 'wss';
export interface HostConfig {
protocol: HostProtocol;
domain: string;
port: number;
}

View File

@ -0,0 +1,6 @@
import { HostConfig } from './host.config';
export interface ModuleConfig<UrlsType = {}> {
hostConfig?: HostConfig;
urls?: UrlsType;
}

View File

@ -0,0 +1,24 @@
import { HostConfig } from './host.config';
export abstract class UrlConfig {
static getUrls<T extends any>(hotConfig: HostConfig, urls: T): T {
const nUrls: any = {};
for (const key in urls) {
if (urls.hasOwnProperty(key)) {
const pathname = urls[key];
nUrls[key] = UrlConfig.getUrl(hotConfig, pathname);
}
}
return nUrls;
}
private static getUrl(hotConfig: HostConfig, pathname: string): string {
const url = new URL(
`${hotConfig.protocol}://${hotConfig.domain}:${String(hotConfig.port)}`
);
url.pathname = pathname;
return url.href;
}
}

View File

@ -23,3 +23,7 @@ export * from './lib/types/video-conference-type.type';
export * from './lib/utils/file.util'; export * from './lib/utils/file.util';
export * from './lib/utils/mime.util'; export * from './lib/utils/mime.util';
export * from './lib/utils/string.util'; export * from './lib/utils/string.util';
export * from './lib/config/host.config';
export * from './lib/config/url.config';
export * from './lib/config/module.config';

View File

@ -8,15 +8,15 @@ import {
} from '@ucap-webmessenger/native'; } from '@ucap-webmessenger/native';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { map, share } from 'rxjs/operators'; import { map, share } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { TranslateLoader } from '@ngx-translate/core'; import { TranslateLoader } from '@ngx-translate/core';
import { TranslateLoaderService } from '../translate/browser-loader'; import { TranslateLoaderService } from '../translate/browser-loader';
import { NotificationService } from '../notification/notification.service'; import { NotificationService } from '../notification/notification.service';
import { Injectable } from '@angular/core';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class BrowserNativeService implements NativeService { export class BrowserNativeService extends NativeService {
private notificationService: NotificationService; private notificationService: NotificationService;
private chatOpenRoomSubject: Subject<string> | null = null; private chatOpenRoomSubject: Subject<string> | null = null;
@ -110,6 +110,7 @@ export class BrowserNativeService implements NativeService {
} }
constructor(private httpClient: HttpClient) { constructor(private httpClient: HttpClient) {
super();
this.notificationService = new NotificationService(); this.notificationService = new NotificationService();
} }
} }

View File

@ -1,19 +0,0 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { BrowserNativeService } from './services/browser-native.service';
const SERVICES = [BrowserNativeService];
@NgModule({
declarations: [],
imports: [],
exports: []
})
export class UCapBrowserNativeModule {
public static forRoot(): ModuleWithProviders<UCapBrowserNativeModule> {
return {
ngModule: UCapBrowserNativeModule,
providers: [...SERVICES]
};
}
}

View File

@ -2,8 +2,8 @@
* Public API Surface of ucap-webmessenger-native-browser * Public API Surface of ucap-webmessenger-native-browser
*/ */
export * from './lib/notification/notification.service';
export * from './lib/services/browser-native.service'; export * from './lib/services/browser-native.service';
export * from './lib/translate/browser-loader'; export * from './lib/translate/browser-loader';
export * from './lib/ucap-browser-native.module';

View File

@ -1,4 +1,4 @@
import { ipcRenderer, remote, IpcRendererEvent } from 'electron'; import { ipcRenderer, remote } from 'electron';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
@ -6,7 +6,7 @@ import {
NativeService, NativeService,
WindowState, WindowState,
NotificationRequest, NotificationRequest,
WindowIdle WindowIdle,
} from '@ucap-webmessenger/native'; } from '@ucap-webmessenger/native';
import { share } from 'rxjs/operators'; import { share } from 'rxjs/operators';
import { import {
@ -15,16 +15,19 @@ import {
FileChannel, FileChannel,
WindowStateChannel, WindowStateChannel,
IdleStateChannel, IdleStateChannel,
ChatChannel ChatChannel,
} from '../types/channel.type'; } from '../types/channel.type';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { TranslateLoaderService } from '../translate/electron-loader'; import { TranslateLoaderService } from '../translate/electron-loader';
import { TranslateLoader } from '@ngx-translate/core'; import { TranslateLoader } from '@ngx-translate/core';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class ElectronNativeService implements NativeService { export class ElectronNativeService implements NativeService {
private ipcRenderer: typeof ipcRenderer;
private remote: typeof remote;
private windowStateChangedSubject: Subject<WindowState> | null = null; private windowStateChangedSubject: Subject<WindowState> | null = null;
private windowStateChanged$: Observable<WindowState> | null = null; private windowStateChanged$: Observable<WindowState> | null = null;
@ -37,17 +40,17 @@ export class ElectronNativeService implements NativeService {
postAppInit(): void {} postAppInit(): void {}
notify(noti: NotificationRequest): void { notify(noti: NotificationRequest): void {
ipcRenderer.send(NotificationChannel.Notify, noti); this.ipcRenderer.send(NotificationChannel.Notify, noti);
} }
closeAllNotify(): void { closeAllNotify(): void {
ipcRenderer.send(NotificationChannel.CloseAllNotify); this.ipcRenderer.send(NotificationChannel.CloseAllNotify);
} }
checkForUpdates(): Observable<boolean> { checkForUpdates(): Observable<boolean> {
return new Observable<boolean>(subscriber => { return new Observable<boolean>(subscriber => {
try { try {
subscriber.next(ipcRenderer.sendSync(UpdaterChannel.Check)); subscriber.next(this.ipcRenderer.sendSync(UpdaterChannel.Check));
} catch (error) { } catch (error) {
subscriber.error(error); subscriber.error(error);
} finally { } finally {
@ -57,13 +60,13 @@ export class ElectronNativeService implements NativeService {
} }
showImageViewer(): void { showImageViewer(): void {
ipcRenderer.send(FileChannel.ShowImageViewer); this.ipcRenderer.send(FileChannel.ShowImageViewer);
} }
readFile(path: string): Observable<Buffer> { readFile(path: string): Observable<Buffer> {
return new Observable<Buffer>(subscriber => { return new Observable<Buffer>(subscriber => {
try { try {
subscriber.next(ipcRenderer.sendSync(FileChannel.ReadFile, path)); subscriber.next(this.ipcRenderer.sendSync(FileChannel.ReadFile, path));
} catch (error) { } catch (error) {
subscriber.error(error); subscriber.error(error);
} finally { } finally {
@ -80,7 +83,12 @@ export class ElectronNativeService implements NativeService {
return new Observable<string>(subscriber => { return new Observable<string>(subscriber => {
try { try {
subscriber.next( subscriber.next(
ipcRenderer.sendSync(FileChannel.SaveFile, buffer, fileName, path) this.ipcRenderer.sendSync(
FileChannel.SaveFile,
buffer,
fileName,
path
)
); );
} catch (error) { } catch (error) {
subscriber.error(error); subscriber.error(error);
@ -98,9 +106,9 @@ export class ElectronNativeService implements NativeService {
.pipe(share()); .pipe(share());
} }
ipcRenderer.on( this.ipcRenderer.on(
WindowStateChannel.Changed, WindowStateChannel.Changed,
(event: IpcRendererEvent, windowState: WindowState) => { (event: any, windowState: WindowState) => {
this.windowStateChangedSubject.next(windowState); this.windowStateChangedSubject.next(windowState);
} }
); );
@ -108,7 +116,7 @@ export class ElectronNativeService implements NativeService {
} }
windowClose(): void { windowClose(): void {
const currentWindow = remote.getCurrentWindow(); const currentWindow = this.remote.getCurrentWindow();
if (!currentWindow) { if (!currentWindow) {
return; return;
} }
@ -117,7 +125,7 @@ export class ElectronNativeService implements NativeService {
} }
windowMinimize(): void { windowMinimize(): void {
const currentWindow = remote.getCurrentWindow(); const currentWindow = this.remote.getCurrentWindow();
if (!currentWindow) { if (!currentWindow) {
return; return;
} }
@ -126,7 +134,7 @@ export class ElectronNativeService implements NativeService {
} }
windowMaximize(): void { windowMaximize(): void {
const currentWindow = remote.getCurrentWindow(); const currentWindow = this.remote.getCurrentWindow();
if (!currentWindow) { if (!currentWindow) {
return; return;
} }
@ -146,11 +154,11 @@ export class ElectronNativeService implements NativeService {
.pipe(share()); .pipe(share());
} }
ipcRenderer.send(IdleStateChannel.StartCheck); this.ipcRenderer.send(IdleStateChannel.StartCheck);
ipcRenderer.on( this.ipcRenderer.on(
IdleStateChannel.Changed, IdleStateChannel.Changed,
(event: IpcRendererEvent, idleState: WindowIdle) => { (event: any, idleState: WindowIdle) => {
this.idleStateChangedSubject.next(idleState); this.idleStateChangedSubject.next(idleState);
} }
); );
@ -165,12 +173,9 @@ export class ElectronNativeService implements NativeService {
.pipe(share()); .pipe(share());
} }
ipcRenderer.on( this.ipcRenderer.on(ChatChannel.OpenRoom, (event: any, roomSeq: string) => {
ChatChannel.OpenRoom, this.chatOpenRoomSubject.next(roomSeq);
(event: IpcRendererEvent, roomSeq: string) => { });
this.chatOpenRoomSubject.next(roomSeq);
}
);
return this.chatOpenRoom$; return this.chatOpenRoom$;
} }
@ -178,5 +183,14 @@ export class ElectronNativeService implements NativeService {
return new TranslateLoaderService(this, prefix, suffix); return new TranslateLoaderService(this, prefix, suffix);
} }
constructor() {} get isElectron() {
return window && (window as any).process && (window as any).process.type;
}
constructor() {
if (this.isElectron) {
this.ipcRenderer = (window as any).require('electron').ipcRenderer;
this.remote = (window as any).require('electron').remote;
}
}
} }

View File

@ -1,27 +1,27 @@
export enum ChatChannel { export enum ChatChannel {
OpenRoom = 'UCAP::chat::openRoom' OpenRoom = 'UCAP::chat::openRoom',
} }
export enum NotificationChannel { export enum NotificationChannel {
Notify = 'UCAP::notification::notify', Notify = 'UCAP::notification::notify',
CloseAllNotify = 'UCAP::notification::closeAllNotify' CloseAllNotify = 'UCAP::notification::closeAllNotify',
} }
export enum UpdaterChannel { export enum UpdaterChannel {
Check = 'UCAP::updater::check' Check = 'UCAP::updater::check',
} }
export enum FileChannel { export enum FileChannel {
ShowImageViewer = 'UCAP::file::showImageViewer', ShowImageViewer = 'UCAP::file::showImageViewer',
SaveFile = 'UCAP::file::saveFile', SaveFile = 'UCAP::file::saveFile',
ReadFile = 'UCAP::file::readFile' ReadFile = 'UCAP::file::readFile',
} }
export enum WindowStateChannel { export enum WindowStateChannel {
Changed = 'UCAP::windowState::windowStateChanged' Changed = 'UCAP::windowState::windowStateChanged',
} }
export enum IdleStateChannel { export enum IdleStateChannel {
Changed = 'UCAP::idleState::changed', Changed = 'UCAP::idleState::changed',
StartCheck = 'UCAP::idleState::startCheck' StartCheck = 'UCAP::idleState::startCheck',
} }

View File

@ -1,19 +0,0 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { ElectronNativeService } from './services/electron-native.service';
const SERVICES = [ElectronNativeService];
@NgModule({
declarations: [],
imports: [],
exports: []
})
export class UCapElectronNativeModule {
public static forRoot(): ModuleWithProviders<UCapElectronNativeModule> {
return {
ngModule: UCapElectronNativeModule,
providers: [...SERVICES]
};
}
}

View File

@ -7,5 +7,3 @@ export * from './lib/services/electron-native.service';
export * from './lib/translate/electron-loader'; export * from './lib/translate/electron-loader';
export * from './lib/types/channel.type'; export * from './lib/types/channel.type';
export * from './lib/ucap-electron-native.module';

View File

@ -0,0 +1,4 @@
import { ModuleConfig as CoreModuleConfig } from '@ucap-webmessenger/core';
// tslint:disable-next-line: no-empty-interface
export interface ModuleConfig extends CoreModuleConfig {}

View File

@ -5,27 +5,34 @@ import { WindowIdle } from '../types/window-idle.type';
import { NotificationRequest } from '../models/notification'; import { NotificationRequest } from '../models/notification';
import { TranslateLoader } from '@ngx-translate/core'; import { TranslateLoader } from '@ngx-translate/core';
export interface NativeService { export abstract class NativeService {
postAppInit(): void; abstract postAppInit(): void;
notify(noti: NotificationRequest): void; abstract notify(noti: NotificationRequest): void;
closeAllNotify(): void; abstract closeAllNotify(): void;
checkForUpdates(): Observable<boolean>; abstract checkForUpdates(): Observable<boolean>;
showImageViewer(): void; abstract showImageViewer(): void;
saveFile(buffer: Buffer, fileName: string, path?: string): Observable<string>; abstract saveFile(
readFile(path: string): Observable<Buffer>; buffer: Buffer,
fileName: string,
path?: string
): Observable<string>;
abstract readFile(path: string): Observable<Buffer>;
windowStateChanged(): Observable<WindowState>; abstract windowStateChanged(): Observable<WindowState>;
windowClose(): void; abstract windowClose(): void;
windowMinimize(): void; abstract windowMinimize(): void;
windowMaximize(): void; abstract windowMaximize(): void;
idleStateChanged(): Observable<WindowIdle>; abstract idleStateChanged(): Observable<WindowIdle>;
chatOpenRoom(): Observable<string>; abstract chatOpenRoom(): Observable<string>;
getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader; abstract getTranslateLoader(
prefix?: string,
suffix?: string
): TranslateLoader;
} }

View File

@ -1,8 +0,0 @@
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
exports: [],
declarations: []
})
export class UCapNativeModule {}

View File

@ -2,12 +2,13 @@
* Public API Surface of ucap-webmessenger-native * Public API Surface of ucap-webmessenger-native
*/ */
export * from './lib/types/token';
export * from './lib/models/notification'; export * from './lib/models/notification';
export * from './lib/services/native.service'; export * from './lib/services/native.service';
export * from './lib/types/token';
export * from './lib/types/window-state.type'; export * from './lib/types/window-state.type';
export * from './lib/types/window-idle.type'; export * from './lib/types/window-idle.type';
export * from './lib/ucap-native.module'; export * from './lib/config/module-config';

View File

@ -0,0 +1,5 @@
import { ModuleConfig as CoreModuleConfig } from '@ucap-webmessenger/core';
import { Urls } from './urls';
export interface ModuleConfig extends CoreModuleConfig<Urls> {}

View File

@ -1,5 +1,5 @@
import { InjectionToken } from '@angular/core'; import { InjectionToken } from '@angular/core';
export const _MODULE_CONFIG = new InjectionToken( export const _MODULE_CONFIG = new InjectionToken(
'@ucap-webmessenger/api-public config of module' '@ucap-webmessenger/pi config of module'
); );

View File

@ -1,4 +1,4 @@
export interface PiUrls { export interface Urls {
login2: string; login2: string;
userTermsAction: string; userTermsAction: string;
passwordInitStep1: string; passwordInitStep1: string;
@ -18,7 +18,3 @@ export interface PiUrls {
scheduleRetrieveScheduleList: string; scheduleRetrieveScheduleList: string;
userScreenCapture: string; userScreenCapture: string;
} }
export interface ModuleConfig {
urls: PiUrls;
}

View File

@ -4,13 +4,11 @@ import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { _MODULE_CONFIG } from '../types/token';
import { ModuleConfig, PiUrls } from '../types/module-config';
import { import {
Login2Request, Login2Request,
Login2Response, Login2Response,
encodeLogin2, encodeLogin2,
decodeLogin2 decodeLogin2,
} from '../apis/login2'; } from '../apis/login2';
import { PrivacyTotalRequest, encodePrivacyTotal } from '../apis/privacy-total'; import { PrivacyTotalRequest, encodePrivacyTotal } from '../apis/privacy-total';
import { UrlUtil, Parameter } from '@ucap-webmessenger/api'; import { UrlUtil, Parameter } from '@ucap-webmessenger/api';
@ -18,25 +16,37 @@ import {
UserTermsActionRequest, UserTermsActionRequest,
UserTermsActionResponse, UserTermsActionResponse,
encodeUserTermsAction, encodeUserTermsAction,
decodeUserTermsAction decodeUserTermsAction,
} from '../apis/user-terms-action'; } from '../apis/user-terms-action';
import { _MODULE_CONFIG } from '../config/token';
import { ModuleConfig } from '../config/module-config';
import { Urls } from '../config/urls';
import { UrlConfig } from '@ucap-webmessenger/core';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class PiService { export class PiService {
readonly urls: Urls;
constructor( constructor(
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig, @Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
private httpClient: HttpClient private httpClient: HttpClient
) {} ) {
this.urls = UrlConfig.getUrls(
this.moduleConfig.hostConfig,
this.moduleConfig.urls
);
}
public login2(req: Login2Request): Observable<Login2Response> { public login2(req: Login2Request): Observable<Login2Response> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.login2, this.urls.login2,
{}, {},
{ {
params: encodeLogin2(req) params: encodeLogin2(req),
} }
) )
.pipe(map(res => decodeLogin2(res))); .pipe(map(res => decodeLogin2(res)));
@ -47,10 +57,10 @@ export class PiService {
): Observable<UserTermsActionResponse> { ): Observable<UserTermsActionResponse> {
return this.httpClient return this.httpClient
.post<any>( .post<any>(
this.moduleConfig.urls.userTermsAction, this.urls.userTermsAction,
{}, {},
{ {
params: encodeUserTermsAction(req) params: encodeUserTermsAction(req),
} }
) )
.pipe(map(res => decodeUserTermsAction(res))); .pipe(map(res => decodeUserTermsAction(res)));
@ -61,12 +71,8 @@ export class PiService {
*/ */
public privacyTotalUrl(req: PrivacyTotalRequest): string { public privacyTotalUrl(req: PrivacyTotalRequest): string {
return UrlUtil.format( return UrlUtil.format(
this.moduleConfig.urls.policyTotal, this.urls.policyTotal,
encodePrivacyTotal(req) as Parameter encodePrivacyTotal(req) as Parameter
); );
} }
public get urls(): PiUrls {
return this.moduleConfig.urls;
}
} }

View File

@ -1,15 +1,16 @@
import { NgModule, ModuleWithProviders } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { _MODULE_CONFIG } from './types/token';
import { PiService } from './services/pi.service'; import { PiService } from './services/pi.service';
import { ModuleConfig } from './types/module-config';
import { _MODULE_CONFIG } from './config/token';
import { ModuleConfig } from './config/module-config';
const SERVICES = [PiService]; const SERVICES = [PiService];
@NgModule({ @NgModule({
declarations: [], declarations: [],
imports: [], imports: [],
exports: [] exports: [],
}) })
export class UCapPiModule { export class UCapPiModule {
public static forRoot( public static forRoot(
@ -17,7 +18,7 @@ export class UCapPiModule {
): ModuleWithProviders<UCapPiModule> { ): ModuleWithProviders<UCapPiModule> {
return { return {
ngModule: UCapPiModule, ngModule: UCapPiModule,
providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES] providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES],
}; };
} }
} }

View File

@ -2,8 +2,6 @@
* Public API Surface of ucap-webmessenger-pi * Public API Surface of ucap-webmessenger-pi
*/ */
export * from './lib/types/module-config';
export * from './lib/apis/pi'; export * from './lib/apis/pi';
export * from './lib/apis/login2'; export * from './lib/apis/login2';
export * from './lib/apis/privacy-total'; export * from './lib/apis/privacy-total';
@ -14,3 +12,6 @@ export * from './lib/types/response-status.type';
export * from './lib/services/pi.service'; export * from './lib/services/pi.service';
export * from './lib/ucap-pi.module'; export * from './lib/ucap-pi.module';
export * from './lib/config/urls';
export * from './lib/config/module-config';

View File

@ -0,0 +1,13 @@
import { ModuleConfig as CoreModuleConfig } from '@ucap-webmessenger/core';
import { Urls } from './urls';
export interface ModuleConfig extends CoreModuleConfig<Urls> {
reconnect: {
delay: number;
};
requestId: {
min: number;
max: number;
};
}

View File

@ -0,0 +1,3 @@
export interface Urls {
base: string;
}

View File

@ -5,24 +5,27 @@ import { share, switchMap, retryWhen, delay, finalize } from 'rxjs/operators';
import { QueueingSubject } from 'queueing-subject'; import { QueueingSubject } from 'queueing-subject';
import { NGXLogger } from 'ngx-logger';
import { import {
makeWebSocketObservable, makeWebSocketObservable,
GetWebSocketResponses, GetWebSocketResponses,
NormalClosureMessage NormalClosureMessage,
} from '@ucap-webmessenger/web-socket'; } from '@ucap-webmessenger/web-socket';
import { _MODULE_CONFIG } from '../types/token';
import { ModuleConfig } from '../types/module-config';
import { PacketBody } from '../protocols/packet'; import { PacketBody } from '../protocols/packet';
import { import {
PacketBodyValueDivider, PacketBodyValueDivider,
PacketBodyDivider PacketBodyDivider,
} from '../types/packet-body-divider'; } from '../types/packet-body-divider';
import { PacketBodyValue } from '../types/packet-body-value.type'; import { PacketBodyValue } from '../types/packet-body-value.type';
import { SSVC_TYPE_ERROR_RES, ServerErrorCode } from '../types/service'; import { SSVC_TYPE_ERROR_RES, ServerErrorCode } from '../types/service';
import { ProtocolMessage } from '../protocols/protocol'; import { ProtocolMessage } from '../protocols/protocol';
import { NGXLogger } from 'ngx-logger'; import { _MODULE_CONFIG } from '../config/token';
import { ModuleConfig } from '../config/module-config';
import { Urls } from '../config/urls';
import { UrlConfig } from '@ucap-webmessenger/core';
interface RequestState { interface RequestState {
subject: Subject<ProtocolMessage>; subject: Subject<ProtocolMessage>;
@ -34,9 +37,11 @@ interface RequestState {
} }
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class ProtocolService { export class ProtocolService {
readonly urls: Urls;
// tslint:disable-next-line: variable-name // tslint:disable-next-line: variable-name
private _requestId: number | null = null; private _requestId: number | null = null;
private readonly pendingRequests: Map<number, RequestState>; private readonly pendingRequests: Map<number, RequestState>;
@ -51,6 +56,10 @@ export class ProtocolService {
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig, @Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
private logger: NGXLogger private logger: NGXLogger
) { ) {
this.urls = UrlConfig.getUrls(
this.moduleConfig.hostConfig,
this.moduleConfig.urls
);
this.pendingRequests = new Map(); this.pendingRequests = new Map();
this.input$ = new QueueingSubject<string>(); this.input$ = new QueueingSubject<string>();
this.serverMessageSubject = new Subject(); this.serverMessageSubject = new Subject();
@ -63,7 +72,7 @@ export class ProtocolService {
return new Observable<void>(subscriber => { return new Observable<void>(subscriber => {
try { try {
this.socket$ = makeWebSocketObservable( this.socket$ = makeWebSocketObservable(
`${this.moduleConfig.urls.base}${serverIp ? serverIp : ''}` `${this.urls.base}${serverIp ? serverIp : ''}`
); );
this.messages$ = this.socket$.pipe( this.messages$ = this.socket$.pipe(
switchMap(getResponses => { switchMap(getResponses => {
@ -177,7 +186,7 @@ export class ProtocolService {
packet = this.encodePacket(serviceType, subServiceType, [ packet = this.encodePacket(serviceType, subServiceType, [
...bodyList, ...bodyList,
{ type: PacketBodyValue.RequestId, value: requestId } { type: PacketBodyValue.RequestId, value: requestId },
]); ]);
responseSubject = new Subject<ProtocolMessage>().pipe( responseSubject = new Subject<ProtocolMessage>().pipe(
@ -194,7 +203,7 @@ export class ProtocolService {
this.pendingRequests.set(requestId, { this.pendingRequests.set(requestId, {
subject: responseSubject, subject: responseSubject,
request: { serviceType, subServiceType, bodyList } request: { serviceType, subServiceType, bodyList },
}); });
} else { } else {
packet = this.encodePacket(serviceType, subServiceType, bodyList); packet = this.encodePacket(serviceType, subServiceType, bodyList);
@ -287,8 +296,8 @@ export class ProtocolService {
serviceType, serviceType,
subServiceType, subServiceType,
senderSeq, senderSeq,
bodyList bodyList,
} },
}; };
} }

View File

@ -1,12 +0,0 @@
export interface ModuleConfig {
urls: {
base: string;
};
reconnect: {
delay: number;
};
requestId: {
min: number;
max: number;
};
}

View File

@ -1,15 +1,15 @@
import { NgModule, ModuleWithProviders } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { ProtocolService } from './services/protocol.service'; import { ProtocolService } from './services/protocol.service';
import { ModuleConfig } from './types/module-config'; import { ModuleConfig } from './config/module-config';
import { _MODULE_CONFIG } from './types/token'; import { _MODULE_CONFIG } from './config/token';
const SERVICES = [ProtocolService]; const SERVICES = [ProtocolService];
@NgModule({ @NgModule({
declarations: [], declarations: [],
imports: [], imports: [],
exports: [] exports: [],
}) })
export class UCapProtocolModule { export class UCapProtocolModule {
public static forRoot( public static forRoot(
@ -17,7 +17,7 @@ export class UCapProtocolModule {
): ModuleWithProviders<UCapProtocolModule> { ): ModuleWithProviders<UCapProtocolModule> {
return { return {
ngModule: UCapProtocolModule, ngModule: UCapProtocolModule,
providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES] providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES],
}; };
} }
} }

View File

@ -7,9 +7,11 @@ export * from './lib/protocols/protocol';
export * from './lib/services/protocol.service'; export * from './lib/services/protocol.service';
export * from './lib/types/module-config';
export * from './lib/types/packet-body-divider'; export * from './lib/types/packet-body-divider';
export * from './lib/types/packet-body-value.type'; export * from './lib/types/packet-body-value.type';
export * from './lib/types/service'; export * from './lib/types/service';
export * from './lib/ucap-protocol.module'; export * from './lib/ucap-protocol.module';
export * from './lib/config/urls';
export * from './lib/config/module-config';

View File

@ -9,7 +9,7 @@
</div> </div>
</mat-card-content> </mat-card-content>
<mat-card-actions class="button-farm flex-row"> <mat-card-actions class="button-farm flex-row">
<button mat-stroked-button (click)="onClickConfirm(false)" class="mat-primary"> <button mat-stroked-button (click)="onClickConfirm()" class="mat-primary">
Confirm Confirm
</button> </button>
</mat-card-actions> </mat-card-actions>

View File

@ -15,7 +15,6 @@
"typeRoots": ["node_modules/@types"], "typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"], "lib": ["es2018", "dom"],
"paths": { "paths": {
"@app/*": ["projects/ucap-webmessenger-app/src/app/*"],
"@ucap-webmessenger/core": [ "@ucap-webmessenger/core": [
"projects/ucap-webmessenger-core/src/public-api" "projects/ucap-webmessenger-core/src/public-api"
], ],
@ -126,6 +125,8 @@
"@ucap-webmessenger/util": [ "@ucap-webmessenger/util": [
"projects/ucap-webmessenger-util/src/public-api" "projects/ucap-webmessenger-util/src/public-api"
], ],
"@app/*": ["projects/ucap-webmessenger-app/src/app/*"],
"@ucap-webmessenger/electron-core": [ "@ucap-webmessenger/electron-core": [
"electron-projects/ucap-webmessenger-electron-core/src/public-api" "electron-projects/ucap-webmessenger-electron-core/src/public-api"
], ],