Skip to content
This repository has been archived by the owner on Oct 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #194 from app-outlet/feature/180
Browse files Browse the repository at this point in the history
Feature/180
  • Loading branch information
MessiasLima committed May 18, 2021
2 parents bdbe1ae + 5ea74c2 commit 4e4694a
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 34 deletions.
4 changes: 4 additions & 0 deletions core/interface/InterfaceChannel.js
Expand Up @@ -14,4 +14,8 @@ module.exports = {
setTheme: 'settings.setTheme',
getLastSynchronizationDate: 'settings.getLastSynchronizationDate',
},
synchronization: {
isRunning: 'synchronization.isRunning',
isRunningSync: 'synchronization.isRunning.sync',
},
};
1 change: 1 addition & 0 deletions core/interface/index.js
@@ -1,2 +1,3 @@
require('./application/ApplicationInterface');
require('./settings/SettingsInterface');
require('./synchronization/SynchronizationInterface');
21 changes: 21 additions & 0 deletions core/interface/synchronization/SynchronizationInterface.js
@@ -0,0 +1,21 @@
const synchronizationService = require('../../service/synchronization/SynchornizationService');
const { ipcMain } = require('electron');
const InterfaceChannel = require('../InterfaceChannel');

let isSynchronizingCache = false;

synchronizationService
.getSynchronizationStatus()
.subscribe((isSynchronizing) => {
if (isSynchronizing) {
isSynchronizingCache = isSynchronizing;
}
ipcMain.emit(
InterfaceChannel.synchronization.isRunning,
isSynchronizing,
);
});

ipcMain?.handle(InterfaceChannel.synchronization.isRunningSync, () => {
return isSynchronizingCache;
});
9 changes: 8 additions & 1 deletion core/service/synchronization/SynchornizationService.js
@@ -1,4 +1,4 @@
const { forkJoin } = require('rxjs');
const { forkJoin, Subject } = require('rxjs');

const flathubSynchronizer = require('./synchronizer/FlathubSynchronizer');
const appImageHubSynchronizer = require('./synchronizer/AppImageHubSynchronizer');
Expand All @@ -7,6 +7,9 @@ const settingsService = require('../settings/SettingsService');

const DAY_IN_MILLIS = 1000 * 60 * 60 * 24 * 7;

const isSynchronizationRunning = new Subject();
isSynchronizationRunning.next(false);

async function shouldSynchronize() {
const now = new Date();
const lastSync = await settingsService.getLastSynchronizationDate();
Expand All @@ -28,6 +31,7 @@ async function startSynchronization() {
}

function synchronize() {
isSynchronizationRunning.next(true);
forkJoin([
flathubSynchronizer.startSynchronization(),
appImageHubSynchronizer.startSynchronization(),
Expand All @@ -36,13 +40,16 @@ function synchronize() {
() => {
console.log('Synchronization succeeded');
settingsService.setLastSynchronizationDate(new Date());
isSynchronizationRunning.next(false);
},
(error) => {
console.error(error);
isSynchronizationRunning.next(false);
},
);
}

module.exports = {
startSynchronization,
getSynchronizationStatus: () => isSynchronizationRunning,
};
24 changes: 24 additions & 0 deletions src/app/service/synchronization/synchronization.service.spec.ts
@@ -0,0 +1,24 @@
import { SynchronizationService } from './synchronization.service';

describe('SynchronizationService', () => {
let service: SynchronizationService;

const mockCoreService = {
invoke: jest.fn(),
};

beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
service = new SynchronizationService(mockCoreService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});

it('should get current synchronization status', async () => {
mockCoreService.invoke.mockReturnValue(Promise.resolve(true));
expect(await service.getCurrentSynchronizationStatus()).toBeTruthy();
});
});
14 changes: 14 additions & 0 deletions src/app/service/synchronization/synchronization.service.ts
@@ -0,0 +1,14 @@
import { Injectable } from '@angular/core';
import { CoreService } from '../core/core.service';
import * as InterfaceChannel from '../../../../core/interface/InterfaceChannel';

@Injectable()
export class SynchronizationService {
constructor(private coreService: CoreService) {}

getCurrentSynchronizationStatus(): Promise<boolean> {
return this.coreService.invoke<boolean>(
InterfaceChannel.synchronization.isRunningSync,
);
}
}
9 changes: 9 additions & 0 deletions src/app/ui/pages/main/main.component.html
Expand Up @@ -11,5 +11,14 @@
<nb-layout-column>
<app-toolbar></app-toolbar>
<router-outlet></router-outlet>
<nb-alert
*ngIf="shouldShowSynchronizationMessage && isSynchronizationRunning"
status="warning"
closable="true"
class="synchronization-message"
(close)="closeSynchronizationMessage()"
>
{{ 'PAGES.MAIN.SYNCHRONIZATION_MESSAGE' | translate }}
</nb-alert>
</nb-layout-column>
</nb-layout>
8 changes: 8 additions & 0 deletions src/app/ui/pages/main/main.component.scss
Expand Up @@ -16,3 +16,11 @@ nb-layout-column {
app-main-menu {
padding-bottom: 15rem;
}

.synchronization-message {
position: sticky;
bottom: 0.5rem;
margin-left: 10rem;
margin-right: 10rem;
z-index: 1;
}
51 changes: 22 additions & 29 deletions src/app/ui/pages/main/main.component.spec.ts
@@ -1,42 +1,35 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { MainComponent } from './main.component';
import { MainMenuModule } from '../../components/main-menu/main-menu.module';
import { NbLayoutModule, NbSidebarModule, NbThemeModule } from '@nebular/theme';
import { NbEvaIconsModule } from '@nebular/eva-icons';
import { RouterModule } from '@angular/router';
import { APP_BASE_HREF } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { ToolbarModule } from '../../components/toolbar/toolbar.module';

describe('MainComponent', () => {
let component: MainComponent;
let fixture: ComponentFixture<MainComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
MainMenuModule,
NbLayoutModule,
NbEvaIconsModule,
NbSidebarModule.forRoot(),
RouterModule.forRoot([]),
NbThemeModule.forRoot(),
TranslateModule.forRoot(),
ToolbarModule,
],
declarations: [MainComponent],
providers: [{ provide: APP_BASE_HREF, useValue: './' }],
}).compileComponents();
});
const mockSynchronizationService = {
getCurrentSynchronizationStatus: jest.fn(),
};

beforeEach(() => {
fixture = TestBed.createComponent(MainComponent);
component = fixture.componentInstance;
fixture.detectChanges();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
component = new MainComponent(mockSynchronizationService);
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should get current synchronization status', (done) => {
mockSynchronizationService.getCurrentSynchronizationStatus.mockReturnValue(
Promise.resolve(true),
);
component.ngOnInit();
setTimeout(() => {
expect(component.isSynchronizationRunning).toBeTruthy();
done();
}, 0);
});

it('should hide synchronization message', () => {
component.closeSynchronizationMessage();
expect(component.shouldShowSynchronizationMessage).toBeFalsy();
});
});
26 changes: 24 additions & 2 deletions src/app/ui/pages/main/main.component.ts
@@ -1,8 +1,30 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { SynchronizationService } from '../../../service/synchronization/synchronization.service';

@Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.scss'],
})
export class MainComponent {}
export class MainComponent implements OnInit {
shouldShowSynchronizationMessage = true;
isSynchronizationRunning = false;

constructor(private synchronizationService: SynchronizationService) {}

ngOnInit(): void {
this.getCurrentSynchronizationStatus();
}

private getCurrentSynchronizationStatus(): void {
this.synchronizationService
.getCurrentSynchronizationStatus()
.then((status) => {
this.isSynchronizationRunning = status;
});
}

closeSynchronizationMessage(): void {
this.shouldShowSynchronizationMessage = false;
}
}
15 changes: 14 additions & 1 deletion src/app/ui/pages/main/main.module.ts
Expand Up @@ -3,10 +3,17 @@ import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';

import { MainComponent } from './main.component';
import { NbLayoutModule, NbSidebarModule } from '@nebular/theme';
import {
NbAlertModule,
NbCardModule,
NbLayoutModule,
NbSidebarModule,
} from '@nebular/theme';
import { NbEvaIconsModule } from '@nebular/eva-icons';
import { MainMenuModule } from '../../components/main-menu/main-menu.module';
import { ToolbarModule } from '../../components/toolbar/toolbar.module';
import { TranslateModule } from '@ngx-translate/core';
import { SynchronizationService } from '../../../service/synchronization/synchronization.service';

/* eslint-disable @typescript-eslint/explicit-function-return-type */
const routes: Routes = [
Expand Down Expand Up @@ -81,6 +88,12 @@ const routes: Routes = [
NbLayoutModule,
NbEvaIconsModule,
NbSidebarModule.forRoot(),
NbCardModule,
NbAlertModule,

// Other
TranslateModule.forChild(),
],
providers: [SynchronizationService],
})
export class MainModule {}
3 changes: 2 additions & 1 deletion src/assets/i18n/en.json
Expand Up @@ -66,7 +66,8 @@
"INTERNET": "Internet and Communication",
"UTILITY": "Utility and Productivity",
"MISC": "Miscellaneous"
}
},
"SYNCHRONIZATION_MESSAGE": "App Outlet is synchronizing its database. It can affect the search performance. When synchronization ends, it will back to normal"
},
"SEARCH": {
"NO_RESULTS_FOUND": "No results found",
Expand Down

0 comments on commit 4e4694a

Please sign in to comment.