This commit is contained in:
leejh 2019-09-24 09:30:20 +09:00
commit b9e4b34e5b
60 changed files with 3942 additions and 55 deletions

View File

@ -1308,6 +1308,111 @@
}
}
}
},
"ucap-webmessenger-ui-group": {
"projectType": "library",
"root": "projects/ucap-webmessenger-ui-group",
"sourceRoot": "projects/ucap-webmessenger-ui-group/src",
"prefix": "ucap-group",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "projects/ucap-webmessenger-ui-group/tsconfig.lib.json",
"project": "projects/ucap-webmessenger-ui-group/ng-package.json"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/ucap-webmessenger-ui-group/src/test.ts",
"tsConfig": "projects/ucap-webmessenger-ui-group/tsconfig.spec.json",
"karmaConfig": "projects/ucap-webmessenger-ui-group/karma.conf.js"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"projects/ucap-webmessenger-ui-group/tsconfig.lib.json",
"projects/ucap-webmessenger-ui-group/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"ucap-webmessenger-util-translate": {
"projectType": "library",
"root": "projects/ucap-webmessenger-util-translate",
"sourceRoot": "projects/ucap-webmessenger-util-translate/src",
"prefix": "ucap-util-translate",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "projects/ucap-webmessenger-util-translate/tsconfig.lib.json",
"project": "projects/ucap-webmessenger-util-translate/ng-package.json"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/ucap-webmessenger-util-translate/src/test.ts",
"tsConfig": "projects/ucap-webmessenger-util-translate/tsconfig.spec.json",
"karmaConfig": "projects/ucap-webmessenger-util-translate/karma.conf.js"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"projects/ucap-webmessenger-util-translate/tsconfig.lib.json",
"projects/ucap-webmessenger-util-translate/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"ucap-webmessenger-native-browser": {
"projectType": "library",
"root": "projects/ucap-webmessenger-native-browser",
"sourceRoot": "projects/ucap-webmessenger-native-browser/src",
"prefix": "ucap-native-browser",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "projects/ucap-webmessenger-native-browser/tsconfig.lib.json",
"project": "projects/ucap-webmessenger-native-browser/ng-package.json"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/ucap-webmessenger-native-browser/src/test.ts",
"tsConfig": "projects/ucap-webmessenger-native-browser/tsconfig.spec.json",
"karmaConfig": "projects/ucap-webmessenger-native-browser/karma.conf.js"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"projects/ucap-webmessenger-native-browser/tsconfig.lib.json",
"projects/ucap-webmessenger-native-browser/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "ucap-webmessenger-app"

View File

@ -1,11 +1,13 @@
import { app, ipcMain, IpcMainEvent } from 'electron';
import * as path from 'path';
import * as url from 'url';
import * as fse from 'fs-extra';
import { AppWindow } from './app/AppWindow';
import { now } from './util/now';
import { showUncaughtException } from './crash/show-uncaught-exception';
import { Channel } from '@ucap-webmessenger/native-electron';
import { root } from './util/root';
let appWindow: AppWindow | null = null;
@ -168,3 +170,21 @@ function onDidLoad(fn: OnDidLoadFn) {
ipcMain.on(Channel.checkForUpdates, (event: IpcMainEvent, ...args: any[]) => {
event.returnValue = false;
});
ipcMain.on(Channel.readFile, (event: IpcMainEvent, ...args: any[]) => {
try {
const rBuf = fse.readFileSync(root(args[0]));
event.returnValue = rBuf.buffer;
} catch (error) {
event.returnValue = null;
}
});
ipcMain.on(Channel.saveFile, (event: IpcMainEvent, ...args: any[]) => {
try {
fse.writeFileSync(root(args[0]), args[1]);
event.returnValue = true;
} catch (error) {
event.returnValue = false;
}
});

11
main/src/util/root.ts Normal file
View File

@ -0,0 +1,11 @@
import * as path from 'path';
// tslint:disable-next-line: variable-name
const _root = __DEV__
? path.resolve(__dirname, '..', '..')
: path.resolve(__dirname);
export function root(...paths: string[]) {
const args = Array.prototype.slice.call(paths, 0);
return path.join.apply(path, [_root].concat(args));
}

28
package-lock.json generated
View File

@ -2208,6 +2208,15 @@
"integrity": "sha512-cGnXW1YH24LI6iCWFjaJ9nVX/WX3d1XzIjJuniZWMD+hpGBWDECCeh8H4MwTg17IMKRU1pfjwfI8crok7b2fEA==",
"dev": true
},
"@types/fs-extra": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.0.0.tgz",
"integrity": "sha512-bCtL5v9zdbQW86yexOlXWTEGvLNqWxMFyi7gQA7Gcthbezr2cPSOb8SkESVKA937QD5cIwOFLDFt0MQoXOEr9Q==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
@ -5543,6 +5552,17 @@
"ms": "^2.1.1"
}
},
"fs-extra": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@ -6660,12 +6680,12 @@
}
},
"fs-extra": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}

View File

@ -45,6 +45,7 @@
"@types/crypto-js": "^3.1.43",
"@types/detect-browser": "^4.0.0",
"@types/extract-text-webpack-plugin": "^3.0.4",
"@types/fs-extra": "^8.0.0",
"@types/filesize": "^4.1.0",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
@ -70,6 +71,7 @@
"electron-reload": "^1.5.0",
"electron-store": "^4.0.0",
"electron-window-state": "^5.0.3",
"fs-extra": "^8.1.0",
"filesize": "^4.1.2",
"hammerjs": "^2.0.8",
"jasmine-core": "~3.4.0",

View File

@ -2,8 +2,32 @@ import { NgModule } from '@angular/core';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
export async function createTranslateLoader(nativeService: NativeService) {
// tslint:disable-next-line: variable-name
let _TranslateLoader;
_TranslateLoader = await import('@ucap-webmessenger/native-browser').then(
m => m.TranslateBrowserLoader
);
_TranslateLoader = await import('@ucap-webmessenger/native-electron').then(
m => m.TranslateElectronLoader
);
// return new TranslateBrowserLoader(nativeService, './assets/i18n/', '.json');
return new _TranslateLoader(nativeService, './assets/i18n/', '.json');
}
@NgModule({
imports: [TranslateModule.forRoot({})],
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [UCAP_NATIVE_SERVICE]
}
})
],
exports: []
})
export class AppTranslateModule {}

View File

@ -7,6 +7,8 @@ import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { UCapUiChatModule } from '@ucap-webmessenger/ui-chat';
import { UCapUiGroupModule } from '@ucap-webmessenger/ui-group';
import { UCapUiOrganizationModule } from '@ucap-webmessenger/ui-organization';
import { COMPONENTS } from './components';
@ -17,7 +19,9 @@ import { COMPONENTS } from './components';
MatMenuModule,
MatTabsModule,
MatToolbarModule,
UCapUiChatModule
UCapUiChatModule,
UCapUiGroupModule,
UCapUiOrganizationModule
],
exports: [...COMPONENTS],
declarations: [...COMPONENTS],

View File

@ -1,7 +1,7 @@
<mat-tab-group>
<mat-tab-group md-stretch-tabs>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon></mat-icon>
<mat-icon>group</mat-icon>
</ng-template>
<ng-template matTabContent>
<app-layout-chat-left-sidenav-group></app-layout-chat-left-sidenav-group>
@ -9,7 +9,7 @@
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon></mat-icon>
<mat-icon>chat</mat-icon>
</ng-template>
<ng-template matTabContent>
<app-layout-chat-left-sidenav-chat></app-layout-chat-left-sidenav-chat>
@ -17,7 +17,7 @@
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>thumb_up</mat-icon>
<mat-icon>device_hub</mat-icon>
</ng-template>
<ng-template matTabContent>
<app-layout-chat-left-sidenav-organization></app-layout-chat-left-sidenav-organization>
@ -25,7 +25,7 @@
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>thumb_up</mat-icon>
<mat-icon>phone</mat-icon>
</ng-template>
<ng-template matTabContent>
<app-layout-chat-left-sidenav-call></app-layout-chat-left-sidenav-call>

View File

@ -1 +1 @@
Group
<ucap-group-expansion-panel></ucap-group-expansion-panel>

View File

@ -1 +1 @@
Organization
<ucap-organization-expansion-panel></ucap-organization-expansion-panel>

View File

@ -45,7 +45,7 @@ export class LoginPageComponent implements OnInit {
notValid: () => void;
}) {
this.store.dispatch(
AuthenticationStore.login({
AuthenticationStore.webLogin({
loginInfo: {
companyCode: value.companyCode,
loginId: value.loginId,

View File

@ -1,4 +1,4 @@
<div id="chat" class="page-layout carded fullwidth inner-scroll">
<div id="messenger" class="page-layout carded fullwidth inner-scroll">
<!-- TOP BACKGROUND -->
<div class="top-bg accent"></div>
<!-- / TOP BACKGROUND -->
@ -10,7 +10,7 @@
<mat-sidenav-container>
<!-- LEFT SIDENAV -->
<mat-sidenav
class="sidenav"
class="sidenav left-sidenav"
position="start"
opened="true"
mode="side"
@ -28,7 +28,12 @@
></app-layout-chat-messages>
<!-- / CONTENT -->
<!-- RIGHT SIDENAV -->
<mat-sidenav class="sidenav" position="end" opened="true" mode="side">
<mat-sidenav
class="sidenav right-sidenav"
position="end"
opened="true"
mode="side"
>
<app-layout-chat-right-sidenav></app-layout-chat-right-sidenav>
</mat-sidenav>
<!-- / RIGHT SIDENAV -->

View File

@ -1,6 +1,12 @@
#chat {
#messenger {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
height: auto !important;
.center {
padding: 32px !important;
max-width: 1400px;
margin: 0 auto;
@ -15,11 +21,20 @@
flex: 1;
width: 100%;
.left-sidenav {
width: 300px;
}
.right-sidenav {
width: 70px;
}
> .mat-sidenav-content,
> .mat-drawer-content {
display: flex;
flex: 1 1 auto;
min-height: 100%;
width: auto;
height: auto;
}

View File

@ -4,8 +4,8 @@ import {
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { Observable } from 'rxjs';
import { take, map } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { take, map, catchError } from 'rxjs/operators';
import { Store, select } from '@ngrx/store';
@ -22,6 +22,7 @@ import {
SSOMode
} from '@ucap-webmessenger/protocol-authentication';
import { LocaleCode } from '@ucap-webmessenger/core';
import * as AuthenticationStore from '@app/store/account/authentication';
@Injectable()
export class AppMessengerResolver implements Resolve<void> {
@ -59,6 +60,7 @@ export class AppMessengerResolver implements Resolve<void> {
.pipe(
take(1),
map(connRes => {
console.log('connRes', connRes);
this.authenticationProtocolService
.login({
loginId: loginInfo.loginId,
@ -82,7 +84,16 @@ export class AppMessengerResolver implements Resolve<void> {
.pipe(
take(1),
map(loginRes => {
console.log('loginRes', loginRes);
this.store.dispatch(
AuthenticationStore.loginSuccess({
loginInfo: loginRes
})
);
}),
catchError(err => {
return of(
AuthenticationStore.loginFailure({ error: err })
);
})
)
.subscribe();

View File

@ -1,19 +1,20 @@
import { createAction, props } from '@ngrx/store';
import { Login2Response } from '@ucap-webmessenger/pi';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { LoginInfo } from '../../../types';
export const login = createAction(
'[Account::Authentication] Login',
export const webLogin = createAction(
'[Account::Authentication] Web Login',
props<{
loginInfo: LoginInfo;
rememberMe: boolean;
}>()
);
export const loginSuccess = createAction(
'[Account::Authentication] Login Success',
export const webLoginSuccess = createAction(
'[Account::Authentication] Web Login Success',
props<{
loginInfo: LoginInfo;
rememberMe: boolean;
@ -21,6 +22,18 @@ export const loginSuccess = createAction(
}>()
);
export const webLoginFailure = createAction(
'[Account::Authentication] Web Login Failure',
props<{ error: any }>()
);
export const loginSuccess = createAction(
'[Account::Authentication] Login Success',
props<{
loginInfo: LoginResponse;
}>()
);
export const loginFailure = createAction(
'[Account::Authentication] Login Failure',
props<{ error: any }>()

View File

@ -20,22 +20,24 @@ import {
} from '@ucap-webmessenger/ui';
import {
login,
loginSuccess,
loginFailure,
loginRedirect,
logout,
logoutConfirmation,
logoutConfirmationDismiss
logoutConfirmationDismiss,
webLogin,
webLoginSuccess,
webLoginFailure
} from './actions';
import { LoginInfo } from '../../../types';
import { AppAuthenticationService } from '../../../services/authentication.service';
@Injectable()
export class Effects {
login$ = createEffect(() =>
webLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(login),
ofType(webLogin),
map(action => action),
exhaustMap((params: { loginInfo: LoginInfo; rememberMe: boolean }) =>
this.piService
@ -47,25 +49,25 @@ export class Effects {
.pipe(
map((res: Login2Response) => {
if (res.status === ResponseStatus.Fail) {
return loginFailure({ error: 'Failed' });
return webLoginFailure({ error: 'Failed' });
} else {
return loginSuccess({
return webLoginSuccess({
loginInfo: params.loginInfo,
rememberMe: params.rememberMe,
login2Response: res
});
}
}),
catchError(error => of(loginFailure({ error })))
catchError(error => of(webLoginFailure({ error })))
)
)
)
);
loginSuccess$ = createEffect(
webLoginSuccess$ = createEffect(
() =>
this.actions$.pipe(
ofType(loginSuccess),
ofType(webLoginSuccess),
tap(params => {
this.nativeService
.checkForUpdates()

View File

@ -1,6 +1,13 @@
import { Action, combineReducers } from '@ngrx/store';
import { State } from './state';
import { Action, combineReducers, createReducer, on } from '@ngrx/store';
import { State, initialState } from './state';
import { loginSuccess } from './actions';
export function reducers(state: State | undefined, action: Action) {
return combineReducers({})(state, action);
}
export const reducer = createReducer(
initialState,
on(loginSuccess, (state, action) => {
return {
...state,
loginInfo: action.loginInfo
};
})
);

View File

@ -1,10 +1,20 @@
import { Selector } from '@ngrx/store';
import { Selector, createSelector } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
// tslint:disable-next-line: no-empty-interface
export interface State {}
export interface State {
loginInfo: LoginResponse | null;
}
export const initialState: State = {};
export const initialState: State = {
loginInfo: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {};
return {
loginInfo: createSelector(
selector,
(state: State) => state.loginInfo
)
};
}

View File

@ -11,7 +11,7 @@ export const effects: Type<any>[] = [AuthenticationStore.Effects];
export function reducers(state: State | undefined, action: Action) {
return combineReducers({
authentication: AuthenticationStore.reducers
authentication: AuthenticationStore.reducer
})(state, action);
}

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link href="assets/images/icons/material/style.css" rel="stylesheet" />
</head>
<body class="theme-default">
<app-root></app-root>

View File

@ -0,0 +1,24 @@
# UcapWebmessengerNativeBrowser
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.5.
## Code scaffolding
Run `ng generate component component-name --project ucap-webmessenger-native-browser` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ucap-webmessenger-native-browser`.
> Note: Don't forget to add `--project ucap-webmessenger-native-browser` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build ucap-webmessenger-native-browser` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build ucap-webmessenger-native-browser`, go to the dist folder `cd dist/ucap-webmessenger-native-browser` and run `npm publish`.
## Running unit tests
Run `ng test ucap-webmessenger-native-browser` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@ -0,0 +1,32 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../../coverage/ucap-webmessenger-native-browser'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

View File

@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/ucap-webmessenger-native-browser",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@ -0,0 +1,8 @@
{
"name": "@ucap-webmessenger/native-browser",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^8.2.5",
"@angular/core": "^8.2.5"
}
}

View File

@ -0,0 +1,3 @@
import { BrowserNativeService } from './browser-native.service';
describe('BrowserNativeService', () => {});

View File

@ -0,0 +1,39 @@
import { Observable } from 'rxjs';
import { NativeService } from '@ucap-webmessenger/native';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
export class BrowserNativeService implements NativeService {
showNotify(
roomSeq: number,
title: string,
contents: string,
image: string,
useSound: boolean
): void {}
checkForUpdates(): Observable<boolean> {
return new Observable<boolean>(subscriber => {
try {
subscriber.next(false);
} catch (error) {
subscriber.error(error);
} finally {
subscriber.complete();
}
});
}
showImageViewer(): void {}
readFile(path: string): Observable<ArrayBuffer> {
return this.httpClient.get(path, { responseType: 'arraybuffer' });
}
saveFile(path: string, buf: ArrayBuffer): Observable<boolean> {
return this.httpClient.post<boolean>(path, buf, {});
}
constructor(private httpClient: HttpClient) {}
}

View File

@ -0,0 +1,26 @@
import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { NativeService } from '@ucap-webmessenger/native';
import { take, map } from 'rxjs/operators';
export class TranslateBrowserLoader implements TranslateLoader {
constructor(
private nativeService: NativeService,
private prefix: string = '/assets/i18n/',
private suffix: string = '.json'
) {}
/**
* Gets the translations from the server
*/
public getTranslation(lang: string): Observable<any> {
return this.nativeService
.readFile(`${this.prefix}${lang}.${this.suffix}`)
.pipe(
take(1),
map(buf => {
return JSON.parse(Buffer.from(buf).toString('utf8'));
})
);
}
}

View File

@ -0,0 +1,7 @@
/*
* Public API Surface of ucap-webmessenger-native-browser
*/
export * from './lib/services/browser-native.service';
export * from './lib/translate/browser-loader';

View File

@ -0,0 +1,21 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

View File

@ -0,0 +1,26 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"target": "es2015",
"declaration": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"enableResourceInlining": true
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}

View File

@ -0,0 +1,17 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"src/test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

View File

@ -0,0 +1,17 @@
{
"extends": "../../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"ucapNativeBrowser",
"camelCase"
],
"component-selector": [
true,
"element",
"ucap-native-browser",
"kebab-case"
]
}
}

View File

@ -1,5 +1,3 @@
import { Injectable } from '@angular/core';
import { ipcRenderer } from 'electron';
import { Observable } from 'rxjs';
@ -41,8 +39,29 @@ export class ElectronNativeService implements NativeService {
ipcRenderer.send(Channel.showImageViewer);
}
saveFile(blob: Blob): void {
ipcRenderer.send(Channel.saveFile, blob);
readFile(path: string): Observable<ArrayBuffer> {
return new Observable<ArrayBuffer>(subscriber => {
try {
subscriber.next(ipcRenderer.sendSync(Channel.readFile, path));
} catch (error) {
subscriber.error(error);
} finally {
subscriber.complete();
}
});
}
saveFile(path: string, buf: ArrayBuffer): Observable<boolean> {
return new Observable<boolean>(subscriber => {
try {
subscriber.next(ipcRenderer.sendSync(Channel.saveFile, path, buf));
} catch (error) {
subscriber.error(error);
} finally {
subscriber.complete();
}
});
}
constructor() {}
}

View File

@ -0,0 +1,26 @@
import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { NativeService } from '@ucap-webmessenger/native';
import { take, map } from 'rxjs/operators';
export class TranslateElectronLoader implements TranslateLoader {
constructor(
private nativeService: NativeService,
private prefix: string = '/assets/i18n/',
private suffix: string = '.json'
) {}
/**
* Gets the translations from the server
*/
public getTranslation(lang: string): Observable<any> {
return this.nativeService
.readFile(`${this.prefix}${lang}.${this.suffix}`)
.pipe(
take(1),
map(buf => {
return JSON.parse(buf.toString());
})
);
}
}

View File

@ -2,5 +2,6 @@ export enum Channel {
showNotify = 'UCAP::showNotify',
checkForUpdates = 'UCAP::checkForUpdates',
showImageViewer = 'UCAP::showImageViewer',
saveFile = 'UCAP::saveFile'
saveFile = 'UCAP::saveFile',
readFile = 'UCAP::readFile'
}

View File

@ -4,4 +4,6 @@
export * from './lib/services/electron-native.service';
export * from './lib/translate/electron-loader';
export * from './lib/types/channel.type';

View File

@ -13,5 +13,6 @@ export interface NativeService {
showImageViewer(): void;
saveFile(blob: Blob): void;
saveFile(path: string, buf: ArrayBuffer): Observable<boolean>;
readFile(path: string): Observable<ArrayBuffer>;
}

View File

@ -194,7 +194,7 @@ export class ProtocolService {
this._requestId = this.moduleConfig.requestId.min;
}
return this._requestId;
return this._requestId++;
}
private decodePacket(

View File

@ -0,0 +1,24 @@
# UcapWebmessengerUiGroup
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.5.
## Code scaffolding
Run `ng generate component component-name --project ucap-webmessenger-ui-group` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ucap-webmessenger-ui-group`.
> Note: Don't forget to add `--project ucap-webmessenger-ui-group` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build ucap-webmessenger-ui-group` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build ucap-webmessenger-ui-group`, go to the dist folder `cd dist/ucap-webmessenger-ui-group` and run `npm publish`.
## Running unit tests
Run `ng test ucap-webmessenger-ui-group` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@ -0,0 +1,32 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../../coverage/ucap-webmessenger-ui-group'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

View File

@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/ucap-webmessenger-ui-group",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@ -0,0 +1,8 @@
{
"name": "@ucap-webmessenger/ui-group",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^8.2.5",
"@angular/core": "^8.2.5"
}
}

View File

@ -0,0 +1,8 @@
<mat-accordion>
<mat-expansion-panel *ngFor="let group of groupList">
<mat-expansion-panel-header>
<mat-panel-title> </mat-panel-title>
<mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
</mat-accordion>

View File

@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ExpansionPanelComponent } from './expansion-panel.component';
describe('Organization::ExpansionPanelComponent', () => {
let component: ExpansionPanelComponent;
let fixture: ComponentFixture<ExpansionPanelComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ExpansionPanelComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExpansionPanelComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'ucap-group-expansion-panel',
templateUrl: './expansion-panel.component.html',
styleUrls: ['./expansion-panel.component.scss']
})
export class ExpansionPanelComponent implements OnInit {
@Input()
groupList: any[];
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,24 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { MatExpansionModule } from '@angular/material/expansion';
import { ExpansionPanelComponent } from './components/expansion-panel.component';
const COMPONENTS = [ExpansionPanelComponent];
const SERVICES = [];
@NgModule({
imports: [CommonModule, ReactiveFormsModule, MatExpansionModule],
exports: [...COMPONENTS],
declarations: [...COMPONENTS]
})
export class UCapUiGroupModule {
public static forRoot(): ModuleWithProviders<UCapUiGroupModule> {
return {
ngModule: UCapUiGroupModule,
providers: [...SERVICES]
};
}
}

View File

@ -0,0 +1,7 @@
/*
* Public API Surface of ucap-webmessenger-ui-group
*/
export * from './lib/components/expansion-panel.component';
export * from './lib/ucap-ui-group.module';

View File

@ -0,0 +1,21 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

View File

@ -0,0 +1,26 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"target": "es2015",
"declaration": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"enableResourceInlining": true
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}

View File

@ -0,0 +1,17 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"src/test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

View File

@ -0,0 +1,17 @@
{
"extends": "../../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"ucapGroup",
"camelCase"
],
"component-selector": [
true,
"element",
"ucap-group",
"kebab-case"
]
}
}

View File

@ -0,0 +1,8 @@
<mat-accordion>
<mat-expansion-panel *ngFor="let organization of organizationList">
<mat-expansion-panel-header>
<mat-panel-title> </mat-panel-title>
<mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
</mat-accordion>

View File

@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ExpansionPanelComponent } from './expansion-panel.component';
describe('Organization::ExpansionPanelComponent', () => {
let component: ExpansionPanelComponent;
let fixture: ComponentFixture<ExpansionPanelComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ExpansionPanelComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExpansionPanelComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'ucap-organization-expansion-panel',
templateUrl: './expansion-panel.component.html',
styleUrls: ['./expansion-panel.component.scss']
})
export class ExpansionPanelComponent implements OnInit {
@Input()
organizationList: any[];
constructor() {}
ngOnInit() {}
}

View File

@ -2,11 +2,15 @@ import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
const COMPONENTS = [];
import { MatExpansionModule } from '@angular/material/expansion';
import { ExpansionPanelComponent } from './components/expansion-panel.component';
const COMPONENTS = [ExpansionPanelComponent];
const SERVICES = [];
@NgModule({
imports: [CommonModule, ReactiveFormsModule],
imports: [CommonModule, ReactiveFormsModule, MatExpansionModule],
exports: [...COMPONENTS],
declarations: [...COMPONENTS]
})

View File

@ -1,5 +1,6 @@
/*
* Public API Surface of ucap-webmessenger-ui-organization
*/
export * from './lib/components/expansion-panel.component';
export * from './lib/ucap-ui-organization.module';

View File

@ -16,7 +16,6 @@
"lib": ["es2018", "dom"],
"paths": {
"@app/*": ["projects/ucap-webmessenger-app/src/app/*"],
"@ucap-webmessenger/core": [
"projects/ucap-webmessenger-core/src/public-api"
],
@ -40,6 +39,9 @@
"@ucap-webmessenger/ui-chat": [
"projects/ucap-webmessenger-ui-chat/src/public-api"
],
"@ucap-webmessenger/ui-group": [
"projects/ucap-webmessenger-ui-group/src/public-api"
],
"@ucap-webmessenger/ui-messenger": [
"projects/ucap-webmessenger-ui-messenger/src/public-api"
],
@ -106,6 +108,9 @@
"@ucap-webmessenger/native": [
"projects/ucap-webmessenger-native/src/public-api"
],
"@ucap-webmessenger/native-browser": [
"projects/ucap-webmessenger-native-browser/src/public-api"
],
"@ucap-webmessenger/native-electron": [
"projects/ucap-webmessenger-native-electron/src/public-api"
],