mirror of
https://github.com/Myxelium/Bridge-Multi.git
synced 2026-04-11 14:19:38 +00:00
Refactor song selection to a service
This commit is contained in:
96
src/app/core/services/selection.service.ts
Normal file
96
src/app/core/services/selection.service.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { Injectable, EventEmitter } from '@angular/core'
|
||||
import { SongResult } from 'src/electron/shared/interfaces/search.interface'
|
||||
import { SearchService } from './search.service'
|
||||
|
||||
// Note: this class prevents event cycles by only emitting events if the checkbox changes
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SelectionService {
|
||||
|
||||
private searchResults: SongResult[] = []
|
||||
|
||||
private selectAllChangedEmitter = new EventEmitter<boolean>()
|
||||
private selectionChangedEmitters: { [songID: number]: EventEmitter<boolean> } = {}
|
||||
|
||||
private allSelected = false
|
||||
private selections: { [songID: number]: boolean | undefined } = {}
|
||||
|
||||
constructor(searchService: SearchService) {
|
||||
searchService.onSearchChanged((results) => {
|
||||
this.searchResults = results
|
||||
this.removeOldListeners(results.map(result => result.id))
|
||||
|
||||
if (this.allSelected) {
|
||||
this.selectAll() // Select newly added rows if allSelected
|
||||
}
|
||||
})
|
||||
|
||||
searchService.onNewSearch((results) => {
|
||||
this.searchResults = results
|
||||
this.removeOldListeners(results.map(result => result.id))
|
||||
|
||||
this.deselectAll()
|
||||
})
|
||||
}
|
||||
|
||||
private removeOldListeners(songIDs: number[]) {
|
||||
for (const oldSongID in this.selectionChangedEmitters) {
|
||||
if (!songIDs.find(newSongID => newSongID == Number(oldSongID))) {
|
||||
delete this.selectionChangedEmitters[oldSongID]
|
||||
delete this.selections[oldSongID]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedResults() {
|
||||
return this.searchResults.filter(result => this.selections[result.id] == true)
|
||||
}
|
||||
|
||||
onSelectAllChanged(callback: (selected: boolean) => void) {
|
||||
this.selectAllChangedEmitter.subscribe(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event when the selection for `songID` needs to change.
|
||||
* (note: only one emitter can be registered per `songID`)
|
||||
*/
|
||||
onSelectionChanged(songID: number, callback: (selection: boolean) => void) {
|
||||
this.selectionChangedEmitters[songID] = new EventEmitter()
|
||||
this.selectionChangedEmitters[songID].subscribe(callback)
|
||||
}
|
||||
|
||||
|
||||
deselectAll() {
|
||||
if (this.allSelected) {
|
||||
this.allSelected = false
|
||||
this.selectAllChangedEmitter.emit(false)
|
||||
}
|
||||
|
||||
setTimeout(() => this.searchResults.forEach(result => this.deselectSong(result.id)), 0)
|
||||
}
|
||||
|
||||
selectAll() {
|
||||
if (!this.allSelected) {
|
||||
this.allSelected = true
|
||||
this.selectAllChangedEmitter.emit(true)
|
||||
}
|
||||
|
||||
setTimeout(() => this.searchResults.forEach(result => this.selectSong(result.id)), 0)
|
||||
}
|
||||
|
||||
deselectSong(songID: number) {
|
||||
if (this.selections[songID]) {
|
||||
this.selections[songID] = false
|
||||
this.selectionChangedEmitters[songID].emit(false)
|
||||
}
|
||||
}
|
||||
|
||||
selectSong(songID: number) {
|
||||
if (!this.selections[songID] && this.selectionChangedEmitters[songID] != undefined) {
|
||||
this.selections[songID] = true
|
||||
this.selectionChangedEmitters[songID].emit(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user