refactor: auto-update mechanism

This commit is contained in:
4gray committed 2023-02-23 13:35:45 +01:00
1 parent 02192a73be
commit e0c6eb6790
9 files changed
+207 -89

No files matched your search

+12 -7
View File
@@ -11,11 +11,13 @@ import { RouterTestingModule } from '@angular/router/testing';
import { provideMockStore } from '@ngrx/store/testing';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { MockModule, MockPipe, MockProviders } from 'ng-mocks';
import { NgxIndexedDBService } from 'ngx-indexed-db';
import { NgxWhatsNewModule } from 'ngx-whats-new';
import { of } from 'rxjs';
import { AppComponent } from './app.component';
import { DataService } from './services/data.service';
import { ElectronServiceStub } from './services/electron.service.stub';
import { PlaylistsService } from './services/playlists.service';
import { SettingsService } from './services/settings.service';
import { WhatsNewService } from './services/whats-new.service';
import { WhatsNewServiceStub } from './services/whats-new.service.stub';
@@ -23,10 +25,6 @@ import { Language } from './settings/language.enum';
import { Theme } from './settings/theme.enum';
import { STORE_KEY } from './shared/enums/store-keys.enum';
class MatSnackBarStub {
open(): void {}
}
jest.spyOn(global.console, 'error').mockImplementation(() => {});
describe('AppComponent', () => {
@@ -43,10 +41,14 @@ describe('AppComponent', () => {
TestBed.configureTestingModule({
declarations: [AppComponent, MockPipe(TranslatePipe)],
providers: [
{ provide: MatSnackBar, useClass: MatSnackBarStub },
{ provide: WhatsNewService, useClass: WhatsNewServiceStub },
MockProviders(TranslateService),
SettingsService, // TODO: stub
MockProviders(
TranslateService,
PlaylistsService,
NgxIndexedDBService,
MatSnackBar
),
SettingsService,
{
provide: DataService,
useClass: ElectronServiceStub,
@@ -70,6 +72,9 @@ describe('AppComponent', () => {
translateService = TestBed.inject(TranslateService);
whatsNewService = TestBed.inject(WhatsNewService);
component = fixture.componentInstance;
// TODO: investigate in detail
component.triggerAutoUpdateMechanism = jest.fn();
component.modals = [];
fixture.detectChanges();
});
+20 -7
View File
@@ -4,9 +4,11 @@ import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core';
import { ModalWindow } from 'ngx-whats-new/lib/modal-window.interface';
import { firstValueFrom } from 'rxjs';
import * as semver from 'semver';
import { IpcCommand } from '../../shared/ipc-command.class';
import {
AUTO_UPDATE_PLAYLISTS,
EPG_ERROR,
EPG_FETCH_DONE,
ERROR,
@@ -17,6 +19,7 @@ import {
} from '../../shared/ipc-commands';
import { DataService } from './services/data.service';
import { EpgService } from './services/epg.service';
import { PlaylistsService } from './services/playlists.service';
import { SettingsService } from './services/settings.service';
import { WhatsNewService } from './services/whats-new.service';
import { Language } from './settings/language.enum';
@@ -58,13 +61,11 @@ export class AppComponent {
listeners = [];
/**
* Creates an instance of AppComponent
*/
constructor(
private electronService: DataService,
private epgService: EpgService,
private ngZone: NgZone,
private playlistService: PlaylistsService,
private router: Router,
private store: Store,
private snackBar: MatSnackBar,
@@ -93,16 +94,28 @@ export class AppComponent {
}
}
/**
* Starts all the functions to initialize the component
*/
ngOnInit(): void {
ngOnInit() {
this.store.dispatch(PlaylistActions.loadPlaylists());
this.translate.setDefaultLang(this.DEFAULT_LANG);
this.setRendererListeners();
this.initSettings();
this.handleWhatsNewDialog();
this.triggerAutoUpdateMechanism();
}
async triggerAutoUpdateMechanism() {
if (this.electronService.isElectron) {
const playlistForAutoUpdate = await firstValueFrom(
this.playlistService.getPlaylistsForAutoUpdate()
);
if (playlistForAutoUpdate && playlistForAutoUpdate.length > 0)
this.electronService.sendIpcEvent(
AUTO_UPDATE_PLAYLISTS,
playlistForAutoUpdate
);
}
}
/**
@@ -18,6 +18,7 @@ import { DataService } from '../../services/data.service';
import * as PlaylistActions from '../../state/actions';
import { selectAllPlaylistsMeta } from '../../state/selectors';
import {
AUTO_UPDATE_PLAYLISTS_RESPONSE,
DELETE_ALL_PLAYLISTS,
IS_PLAYLISTS_MIGRATION_POSSIBLE,
IS_PLAYLISTS_MIGRATION_POSSIBLE_RESPONSE,
@@ -49,7 +50,6 @@ export class RecentPlaylistsComponent implements OnDestroy {
this.snackBar.open(response.message, null, { duration: 2000 });
this.store.dispatch(
PlaylistActions.updatePlaylist({
// TODO: check if this is correct
playlistId: response.playlist._id,
playlist: response.playlist,
})
@@ -78,6 +78,16 @@ export class RecentPlaylistsComponent implements OnDestroy {
);
}
),
new IpcCommand(
AUTO_UPDATE_PLAYLISTS_RESPONSE,
(playlists: Playlist[]) => {
this.store.dispatch(
PlaylistActions.updateManyPlaylists({
playlists,
})
);
}
),
];
isMigrationPossible = false;
+21 -8
View File
@@ -100,15 +100,15 @@ export class PlaylistsService {
);
}
// TODO: for-loop
updatePlaylistPosition(id: string, position: number) {
return this.getPlaylistById(id).pipe(
switchMap((playlist) =>
this.dbService.update(DbStores.Playlists, {
updateManyPlaylists(playlists: Playlist[]) {
return combineLatest(
playlists.map((playlist) => {
return this.dbService.update(DbStores.Playlists, {
...playlist,
position,
})
)
updateDate: Date.now(),
autoRefresh: true,
});
})
);
}
@@ -167,4 +167,17 @@ export class PlaylistsService {
addManyPlaylists(playlists: Playlist[]) {
return this.dbService.bulkAdd(DbStores.Playlists, playlists as any); // TODO: update ngx-indexed-db
}
getPlaylistsForAutoUpdate() {
return this.dbService.getAll(DbStores.Playlists).pipe(
map((playlists: Playlist[]) => {
return playlists
.filter((item) => item.autoRefresh)
.map(
({ playlist, header, items, favorites, ...rest }) =>
rest
);
})
);
}
}
+5
View File
@@ -41,6 +41,11 @@ export const updatePlaylist = createAction(
props<{ playlist: Playlist; playlistId: string }>()
);
export const updateManyPlaylists = createAction(
`${PLAYLISTS_STORE_KEY} Update many playlists (auto-update mechanism)`,
props<{ playlists: Playlist[] }>()
);
export const parsePlaylist = createAction(
`${PLAYLISTS_STORE_KEY} parse playlist`,
props<{
+12
View File
@@ -173,6 +173,18 @@ export class PlaylistEffects {
{ dispatch: false }
);
updateManyPlaylists$ = createEffect(
() => {
return this.actions$.pipe(
ofType(PlaylistActions.updateManyPlaylists),
switchMap((action) =>
this.playlistsService.updateManyPlaylists(action.playlists)
)
);
},
{ dispatch: false }
);
constructor(
private actions$: Actions,
private playlistsService: PlaylistsService,
+22 -1
View File
@@ -97,7 +97,13 @@ export const playlistReducer = createReducer(
playlists: playlistsAdapter.updateOne(
{
id: action.playlistId,
changes: { ...action.playlist, _id: action.playlistId },
changes: {
...action.playlist,
_id: action.playlistId,
updateDate: Date.now(),
favorites: [],
count: action.playlist.playlist.items.length,
},
},
state.playlists
),
@@ -162,6 +168,21 @@ export const playlistReducer = createReducer(
...state,
channels: action.channels,
};
}),
on(PlaylistActions.updateManyPlaylists, (state, action): PlaylistState => {
return {
...state,
playlists: playlistsAdapter.updateMany(
action.playlists.map((updatedPlaylist) => ({
id: updatedPlaylist._id,
changes: {
...updatedPlaylist,
updateDate: Date.now(),
},
})),
state.playlists
),
};
})
);