zooming is implemented
This commit is contained in:
parent
ff87a0540e
commit
d47dd78e4b
|
@ -5,7 +5,8 @@ import {
|
|||
Tray,
|
||||
Menu,
|
||||
shell,
|
||||
dialog
|
||||
dialog,
|
||||
webFrame
|
||||
} from 'electron';
|
||||
import path from 'path';
|
||||
import fse from 'fs-extra';
|
||||
|
|
|
@ -274,14 +274,14 @@
|
|||
{{ 'profile.open' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<!-- <div class="setting">
|
||||
<div class="setting">
|
||||
<button
|
||||
mat-menu-item
|
||||
class="zoom minus-square"
|
||||
(click)="onClickZoomOut($event)"
|
||||
>
|
||||
축소</button
|
||||
><span class="set-size">100%</span
|
||||
><span class="set-size" (click)="onClickZoomLabel($event)">{{ zoom }}%</span
|
||||
><button
|
||||
mat-menu-item
|
||||
class="zoom plus-square"
|
||||
|
@ -289,7 +289,7 @@
|
|||
>
|
||||
확대
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="setting">
|
||||
<button mat-menu-item (click)="onClickNotice()">
|
||||
{{ 'notice.label' | translate }}
|
||||
|
@ -334,13 +334,20 @@
|
|||
<div class="setting">
|
||||
<button mat-menu-item (click)="onClickStatusBusy($event, 1)">
|
||||
<span class="presence pcOther"> </span>
|
||||
{{ loginRes?.statusMessage1 }}
|
||||
<ucap-inline-edit-input
|
||||
#statusMessage1
|
||||
(click)="$event.stopPropagation()"
|
||||
>
|
||||
<span ucapInlineEditInput="view">{{ loginRes?.statusMessage1 }}</span>
|
||||
<span ucapInlineEditInput="edit"><input matInput type="text"/></span>
|
||||
</ucap-inline-edit-input>
|
||||
<!-- {{ loginRes?.statusMessage1 }} -->
|
||||
</button>
|
||||
<button
|
||||
<!-- <button
|
||||
mat-menu-item
|
||||
class="edit"
|
||||
(click)="onClickChangeStatusBusy($event, 1)"
|
||||
></button>
|
||||
(click)="$event.stopPropagation(); statusMessage1.editMode = true"
|
||||
></button> -->
|
||||
</div>
|
||||
<div class="setting">
|
||||
<button mat-menu-item (click)="onClickStatusBusy($event, 2)">
|
||||
|
|
|
@ -20,6 +20,7 @@ import * as ChatStore from '@app/store/messenger/chat';
|
|||
import * as AuthenticationStore from '@app/store/account/authentication';
|
||||
import * as SettingsStore from '@app/store/messenger/settings';
|
||||
import * as UpdateStore from '@app/store/setting/update';
|
||||
import * as SettingNativeStore from '@app/store/setting/native';
|
||||
import * as StatusStore from '@app/store/messenger/status';
|
||||
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
|
@ -60,6 +61,8 @@ import { MatMenu, MatRadioChange } from '@angular/material';
|
|||
import { StatusCode, StatusType } from '@ucap-webmessenger/core';
|
||||
import { StatusInfo } from '@ucap-webmessenger/protocol-status';
|
||||
|
||||
const zoomFactors = [60, 70, 85, 100, 120, 145, 170, 200];
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-native-top-bar',
|
||||
templateUrl: './top-bar.component.html',
|
||||
|
@ -81,6 +84,9 @@ export class TopBarComponent implements OnInit, OnDestroy {
|
|||
myIdleCheckTime: number;
|
||||
myIdleCheckTimeSubscription: Subscription;
|
||||
|
||||
zoom: number;
|
||||
zoomSubscription: Subscription;
|
||||
|
||||
loginInfo: LoginInfo;
|
||||
weblink: WebLink[] = [];
|
||||
webLinkBadgeMail = 0;
|
||||
|
@ -129,24 +135,35 @@ export class TopBarComponent implements OnInit, OnDestroy {
|
|||
.subscribe();
|
||||
|
||||
this.myStatusSubscription = this.store
|
||||
.pipe(select(AppStore.MessengerSelector.StatusSelector.selectedMyStatus))
|
||||
.pipe(select(AppStore.MessengerSelector.StatusSelector.selectMyStatus))
|
||||
.subscribe(myStatus => {
|
||||
this.myStatus = myStatus;
|
||||
});
|
||||
|
||||
this.myIdleCheckTimeSubscription = this.store
|
||||
.pipe(
|
||||
select(
|
||||
AppStore.MessengerSelector.StatusSelector.selectedMyIdleCheckTime
|
||||
)
|
||||
select(AppStore.MessengerSelector.StatusSelector.selectMyIdleCheckTime)
|
||||
)
|
||||
.subscribe(myIdleCheckTime => {
|
||||
this.myIdleCheckTime = myIdleCheckTime;
|
||||
});
|
||||
|
||||
this.zoomSubscription = this.store
|
||||
.pipe(select(AppStore.SettingSelector.NativeSelector.selectZoom))
|
||||
.subscribe(zoom => {
|
||||
this.zoom = zoom;
|
||||
});
|
||||
|
||||
this.updateInfo$ = this.store.pipe(
|
||||
select(AppStore.SettingSelector.UpdateSelector.updateInfo)
|
||||
);
|
||||
|
||||
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
|
||||
KEY_APP_USER_INFO,
|
||||
environment.customConfig.appKey
|
||||
);
|
||||
|
||||
this.zoom = appUserInfo.zoom;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
@ -361,15 +378,27 @@ export class TopBarComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
onClickZoomOut(event: Event) {
|
||||
event.stopPropagation();
|
||||
const i = zoomFactors.indexOf(this.zoom);
|
||||
if (-1 === i || 0 === i) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.document.body.style.zoom = '80%';
|
||||
const zoom = zoomFactors[i - 1];
|
||||
this.store.dispatch(SettingNativeStore.changeZoom({ zoom }));
|
||||
}
|
||||
|
||||
onClickZoomLabel(event: Event) {
|
||||
this.store.dispatch(SettingNativeStore.changeZoom({ zoom: 100 }));
|
||||
}
|
||||
|
||||
onClickZoomIn(event: Event) {
|
||||
event.stopPropagation();
|
||||
const i = zoomFactors.indexOf(this.zoom);
|
||||
if (-1 === i || zoomFactors.length - 1 === i) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.document.body.style.zoom = '120%';
|
||||
const zoom = zoomFactors[i + 1];
|
||||
this.store.dispatch(SettingNativeStore.changeZoom({ zoom }));
|
||||
}
|
||||
|
||||
onClickRemoteSupport(event: Event) {
|
||||
|
|
|
@ -137,9 +137,7 @@ export class MainPageComponent implements OnInit, OnDestroy {
|
|||
|
||||
this.myIdleCheckTimeSubscription = this.store
|
||||
.pipe(
|
||||
select(
|
||||
AppStore.MessengerSelector.StatusSelector.selectedMyIdleCheckTime
|
||||
)
|
||||
select(AppStore.MessengerSelector.StatusSelector.selectMyIdleCheckTime)
|
||||
)
|
||||
.subscribe(checkTime => {
|
||||
this.nativeService.changeLimitOfIdleState(checkTime);
|
||||
|
|
|
@ -58,6 +58,7 @@ import * as OptionStore from '@app/store/messenger/option';
|
|||
import * as QueryStore from '@app/store/messenger/query';
|
||||
import * as SyncStore from '@app/store/messenger/sync';
|
||||
import * as StatusStore from '@app/store/messenger/status';
|
||||
import * as SettingInitStore from '@app/store/setting/init';
|
||||
import { KEY_LOGIN_RES_INFO, KEY_VER_INFO } from '@app/types';
|
||||
|
||||
import { environment } from '../../environments/environment';
|
||||
|
|
|
@ -66,6 +66,7 @@ export class AppAuthenticationService {
|
|||
if (!appUserInfo) {
|
||||
appUserInfo = {
|
||||
idleCheckTime: 10,
|
||||
zoom: 100,
|
||||
settings: {
|
||||
...environment.productConfig.defaultSettings,
|
||||
chat: {
|
||||
|
|
|
@ -62,11 +62,8 @@ export function selectors<S>(selector: Selector<any, State>) {
|
|||
ngeSelectEntitiesStatusBulkInfo,
|
||||
(_, entities) => (!!entities ? entities[userSeq] : undefined)
|
||||
),
|
||||
selectedMyStatus: createSelector(
|
||||
selector,
|
||||
(state: State) => state.myStatus
|
||||
),
|
||||
selectedMyIdleCheckTime: createSelector(
|
||||
selectMyStatus: createSelector(selector, (state: State) => state.myStatus),
|
||||
selectMyIdleCheckTime: createSelector(
|
||||
selector,
|
||||
(state: State) => state.myIdleCheckTime
|
||||
)
|
||||
|
|
|
@ -5,19 +5,22 @@ import * as CompanyStore from './company';
|
|||
import * as InitStore from './init';
|
||||
import * as VersionInfoStore from './version-info';
|
||||
import * as UpdateStore from './update';
|
||||
import * as NativeStore from './native';
|
||||
|
||||
export interface State {
|
||||
company: CompanyStore.State;
|
||||
init: InitStore.State;
|
||||
versionInfo: VersionInfoStore.State;
|
||||
update: UpdateStore.State;
|
||||
native: NativeStore.State;
|
||||
}
|
||||
|
||||
export const effects: Type<any>[] = [
|
||||
CompanyStore.Effects,
|
||||
InitStore.Effects,
|
||||
VersionInfoStore.Effects,
|
||||
UpdateStore.Effects
|
||||
UpdateStore.Effects,
|
||||
NativeStore.Effects
|
||||
];
|
||||
|
||||
export function reducers(state: State | undefined, action: Action) {
|
||||
|
@ -25,7 +28,8 @@ export function reducers(state: State | undefined, action: Action) {
|
|||
company: CompanyStore.reducer,
|
||||
init: InitStore.reducer,
|
||||
versionInfo: VersionInfoStore.reducer,
|
||||
update: UpdateStore.reducer
|
||||
update: UpdateStore.reducer,
|
||||
native: NativeStore.reducer
|
||||
})(state, action);
|
||||
}
|
||||
|
||||
|
@ -42,6 +46,9 @@ export function selectors<S>(selector: Selector<any, State>) {
|
|||
),
|
||||
UpdateSelector: UpdateStore.selectors(
|
||||
createSelector(selector, (state: State) => state.update)
|
||||
),
|
||||
NativeSelector: NativeStore.selectors(
|
||||
createSelector(selector, (state: State) => state.native)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ export class Effects {
|
|||
),
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private translateService: TranslateService,
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import { createAction, props } from '@ngrx/store';
|
||||
|
||||
export const changeZoom = createAction(
|
||||
'[Setting::Native] Change Zoom',
|
||||
props<{ zoom: number }>()
|
||||
);
|
||||
|
||||
export const changeZoomSuccess = createAction(
|
||||
'[Setting::Native] changeZoom Success',
|
||||
props<{
|
||||
zoom: number;
|
||||
}>()
|
||||
);
|
||||
export const changeZoomFailure = createAction(
|
||||
'[Setting::Native] changeZoom Failure',
|
||||
props<{ error: any }>()
|
||||
);
|
|
@ -0,0 +1,77 @@
|
|||
import { Injectable, Inject } from '@angular/core';
|
||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { TranslateService as UCapTranslateService } from '@ucap-webmessenger/ui';
|
||||
import { DateService as UCapDateService } from '@ucap-webmessenger/ui';
|
||||
|
||||
import * as AuthenticationStore from '@app/store/account/authentication';
|
||||
import { LocalStorageService } from '@ucap-webmessenger/web-storage';
|
||||
import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
|
||||
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { changeZoom, changeZoomSuccess, changeZoomFailure } from './actions';
|
||||
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
@Injectable()
|
||||
export class Effects {
|
||||
postLogin$ = createEffect(
|
||||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType(AuthenticationStore.postLogin),
|
||||
map(action => action.loginRes),
|
||||
tap(async loginRes => {
|
||||
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
|
||||
KEY_APP_USER_INFO,
|
||||
environment.customConfig.appKey
|
||||
);
|
||||
|
||||
this.store.dispatch(changeZoom({ zoom: appUserInfo.zoom }));
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
changeZoom$ = createEffect(
|
||||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType(changeZoom),
|
||||
map(action => action.zoom),
|
||||
tap(zoom => {
|
||||
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
|
||||
KEY_APP_USER_INFO,
|
||||
environment.customConfig.appKey
|
||||
);
|
||||
|
||||
this.nativeService
|
||||
.zoomTo(zoom)
|
||||
.then(f => {
|
||||
this.localStorageService.encSet<AppUserInfo>(
|
||||
KEY_APP_USER_INFO,
|
||||
{
|
||||
...appUserInfo,
|
||||
zoom
|
||||
},
|
||||
environment.customConfig.appKey
|
||||
);
|
||||
|
||||
this.store.dispatch(changeZoomSuccess({ zoom }));
|
||||
})
|
||||
.catch(reason => {
|
||||
this.store.dispatch(changeZoomFailure({ error: reason }));
|
||||
});
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private store: Store<any>,
|
||||
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
||||
private localStorageService: LocalStorageService
|
||||
) {}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export * from './actions';
|
||||
export * from './effects';
|
||||
export * from './reducers';
|
||||
export * from './state';
|
|
@ -0,0 +1,13 @@
|
|||
import { createReducer, on } from '@ngrx/store';
|
||||
import { State, initialState } from './state';
|
||||
import { changeZoomSuccess } from './actions';
|
||||
|
||||
export const reducer = createReducer(
|
||||
initialState,
|
||||
on(changeZoomSuccess, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
zoom: action.zoom
|
||||
} as State;
|
||||
})
|
||||
);
|
|
@ -0,0 +1,16 @@
|
|||
import { Selector, createSelector } from '@ngrx/store';
|
||||
|
||||
// tslint:disable-next-line: no-empty-interface
|
||||
export interface State {
|
||||
zoom: number;
|
||||
}
|
||||
|
||||
export const initialState: State = {
|
||||
zoom: 100
|
||||
};
|
||||
|
||||
export function selectors<S>(selector: Selector<any, State>) {
|
||||
return {
|
||||
selectZoom: createSelector(selector, (state: State) => state.zoom)
|
||||
};
|
||||
}
|
|
@ -11,6 +11,7 @@ export interface AppUserInfo {
|
|||
companyGroupType?: string;
|
||||
localeCode?: LocaleCode;
|
||||
idleCheckTime?: number;
|
||||
zoom?: number;
|
||||
|
||||
settings?: Settings;
|
||||
}
|
||||
|
|
|
@ -215,6 +215,12 @@ export class BrowserNativeService extends NativeService {
|
|||
|
||||
windowMaximize(): void {}
|
||||
|
||||
zoomTo(factor: number): Promise<number> {
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
resolve(-1);
|
||||
});
|
||||
}
|
||||
|
||||
idleStateChanged(): Observable<WindowIdle> {
|
||||
return new Observable<WindowIdle>(subscriber => {
|
||||
try {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ipcRenderer, remote, shell } from 'electron';
|
||||
import { ipcRenderer, remote, shell, webFrame } from 'electron';
|
||||
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
|
||||
|
@ -34,6 +34,7 @@ import { StatusCode } from '@ucap-webmessenger/core';
|
|||
})
|
||||
export class ElectronNativeService implements NativeService {
|
||||
private ipcRenderer: typeof ipcRenderer;
|
||||
private webFrame: typeof webFrame;
|
||||
private remote: typeof remote;
|
||||
private shell: typeof shell;
|
||||
|
||||
|
@ -377,6 +378,17 @@ export class ElectronNativeService implements NativeService {
|
|||
}
|
||||
}
|
||||
|
||||
zoomTo(factor: number): Promise<number> {
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
try {
|
||||
this.webFrame.setZoomFactor(factor / 100);
|
||||
resolve(this.webFrame.getZoomFactor());
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
idleStateChanged(): Observable<WindowIdle> {
|
||||
if (!this.idleStateChangedSubject) {
|
||||
this.idleStateChangedSubject = new Subject<WindowIdle>();
|
||||
|
@ -448,6 +460,7 @@ export class ElectronNativeService implements NativeService {
|
|||
this.ipcRenderer = (window as any).require('electron').ipcRenderer;
|
||||
this.remote = (window as any).require('electron').remote;
|
||||
this.shell = (window as any).require('electron').shell;
|
||||
this.webFrame = (window as any).require('electron').webFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ export abstract class NativeService {
|
|||
abstract windowClose(): void;
|
||||
abstract windowMinimize(): void;
|
||||
abstract windowMaximize(): void;
|
||||
abstract zoomTo(factor: number): Promise<number>;
|
||||
|
||||
abstract idleStateChanged(): Observable<WindowIdle>;
|
||||
abstract changeLimitOfIdleState(limitTime: number): void;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div>
|
||||
<mat-list>
|
||||
<h1 mat-subheader>{{ 'settings.chat.label' | translate }}</h1>
|
||||
<!-- <h1 mat-subheader>{{ 'settings.chat.label' | translate }}</h1>
|
||||
<mat-list-item>
|
||||
<span class="item-title">{{
|
||||
'settings.chat.fontFamily' | translate
|
||||
|
@ -37,7 +37,7 @@
|
|||
</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
<mat-divider></mat-divider> -->
|
||||
|
||||
<h1 mat-subheader *ngIf="_isNodeWebkit">
|
||||
{{ 'settings.chat.file' | translate }}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<ng-container>
|
||||
<ng-container #view *ngIf="!editMode">
|
||||
<ng-content select="[ucapInlineEditInput='view']"></ng-content>
|
||||
<span class="view-actions">
|
||||
<button mat-icon-button aria-label="Edit" (click)="onClickEdit($event)">
|
||||
<span class="mdi mdi-square-edit-outline mdi-20px"></span>
|
||||
</button>
|
||||
</span>
|
||||
</ng-container>
|
||||
<ng-container #edit *ngIf="editMode">
|
||||
<ng-content select="[ucapInlineEditInput='edit']"></ng-content>
|
||||
<span class="edit-actions">
|
||||
<button mat-icon-button aria-label="Apply" (click)="onClickApply($event)">
|
||||
<span class="mdi mdi-check mdi-20px"></span>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
aria-label="Cacel"
|
||||
(click)="onClickCancel($event)"
|
||||
>
|
||||
<span class="mdi mdi-close mdi-20px"></span>
|
||||
</button>
|
||||
</span>
|
||||
</ng-container>
|
||||
</ng-container>
|
|
@ -0,0 +1,7 @@
|
|||
.view-actions {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.edit-actions {
|
||||
margin-right: 0px;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InlineEditInputComponent } from './inline-edit-input.component';
|
||||
|
||||
describe('InlineEditInputComponent', () => {
|
||||
let component: InlineEditInputComponent;
|
||||
let fixture: ComponentFixture<InlineEditInputComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [InlineEditInputComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(InlineEditInputComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-inline-edit-input',
|
||||
templateUrl: './inline-edit-input.component.html',
|
||||
styleUrls: ['./inline-edit-input.component.scss']
|
||||
})
|
||||
export class InlineEditInputComponent implements OnInit {
|
||||
get editMode() {
|
||||
return this._editMode;
|
||||
}
|
||||
set editMode(editMode: boolean) {
|
||||
this._editMode = editMode;
|
||||
}
|
||||
// tslint:disable-next-line: variable-name
|
||||
_editMode = false;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onClickEdit(event: Event) {
|
||||
this.editMode = true;
|
||||
}
|
||||
|
||||
onClickCancel(event: Event) {
|
||||
this.editMode = false;
|
||||
}
|
||||
|
||||
onClickApply(event: Event) {
|
||||
this.editMode = false;
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@ import { PickDateComponent } from './components/pick-date.component';
|
|||
import { PickTimeComponent } from './components/pick-time.component';
|
||||
import { StepInputComponent } from './components/step-input.component';
|
||||
import { StickerSelectorComponent } from './components/sticker-selector.component';
|
||||
import { InlineEditInputComponent } from './components/inline-edit-input.component';
|
||||
|
||||
import { BinaryViewerComponent } from './components/file-viewer/binary-viewer.component';
|
||||
import { DocumentViewerComponent } from './components/file-viewer/document-viewer.component';
|
||||
|
@ -88,6 +89,7 @@ const COMPONENTS = [
|
|||
PickTimeComponent,
|
||||
StepInputComponent,
|
||||
TranslationSectionComponent,
|
||||
InlineEditInputComponent,
|
||||
|
||||
BinaryViewerComponent,
|
||||
DocumentViewerComponent,
|
||||
|
|
|
@ -18,6 +18,7 @@ export * from './lib/components/pick-time.component';
|
|||
export * from './lib/components/step-input.component';
|
||||
export * from './lib/components/split-button.component';
|
||||
export * from './lib/components/sticker-selector.component';
|
||||
export * from './lib/components/inline-edit-input.component';
|
||||
|
||||
export * from './lib/data-source/virtual-scroll-tree-flat.data-source';
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user