Refactor search service

This commit is contained in:
Geomitron
2020-03-11 22:51:24 -04:00
parent 3a3c2b5476
commit 18afa01e5c
9 changed files with 110 additions and 44 deletions

View File

@@ -1,4 +1,4 @@
<app-search-bar (resultsUpdated)="onResultsUpdated($event)"></app-search-bar>
<app-search-bar></app-search-bar>
<div class="ui celled two column grid">
<div id="table-row" class="row">
<div id="table-column" class="column twelve wide">

View File

@@ -1,7 +1,6 @@
import { Component, ViewChild, AfterViewInit } from '@angular/core'
import { ChartSidebarComponent } from './chart-sidebar/chart-sidebar.component'
import { StatusBarComponent } from './status-bar/status-bar.component'
import { SongResult } from 'src/electron/shared/interfaces/search.interface'
import { ResultTableComponent } from './result-table/result-table.component'
@Component({
@@ -35,15 +34,6 @@ export class BrowseComponent implements AfterViewInit {
})
}
onResultsUpdated(results: SongResult[]) {
this.resultTable.results = results
this.resultTable.onNewSearch()
this.resultTable.checkAll(false)
this.chartSidebar.selectVersion(undefined)
this.statusBar.resultCount = results.length
this.statusBar.selectedResults = []
}
loadMoreResults() {
// TODO: use the same query as the current search, but append more results if there are any more to be viewed
}

View File

@@ -1,23 +1,35 @@
import { Component } from '@angular/core'
import { Component, OnInit } from '@angular/core'
import { SongResult } from '../../../../electron/shared/interfaces/search.interface'
import { ElectronService } from '../../../core/services/electron.service'
import { VersionResult } from '../../../../electron/shared/interfaces/songDetails.interface'
import { AlbumArtService } from '../../../core/services/album-art.service'
import { DownloadService } from '../../../core/services/download.service'
import { groupBy } from 'src/electron/shared/UtilFunctions'
import { SearchService } from 'src/app/core/services/search.service'
@Component({
selector: 'app-chart-sidebar',
templateUrl: './chart-sidebar.component.html',
styleUrls: ['./chart-sidebar.component.scss']
})
export class ChartSidebarComponent {
export class ChartSidebarComponent implements OnInit {
private songResult: SongResult
selectedVersion: VersionResult
charts: VersionResult[][]
constructor(private electronService: ElectronService, private albumArtService: AlbumArtService, private downloadService: DownloadService) { }
constructor(
private electronService: ElectronService,
private albumArtService: AlbumArtService,
private downloadService: DownloadService,
private searchService: SearchService
) { }
ngOnInit() {
this.searchService.onNewSearch(() => {
this.selectVersion(undefined)
})
}
/**
* Displays the information for the selected song.

View File

@@ -1,15 +1,15 @@
import { Component, Input, Output, EventEmitter, ViewChildren, QueryList, ViewChild } from '@angular/core'
import { Component, Output, EventEmitter, ViewChildren, QueryList, ViewChild, OnInit } from '@angular/core'
import { SongResult } from '../../../../electron/shared/interfaces/search.interface'
import { ResultTableRowComponent } from './result-table-row/result-table-row.component'
import { CheckboxDirective } from 'src/app/core/directives/checkbox.directive'
import { SearchService } from 'src/app/core/services/search.service'
@Component({
selector: 'app-result-table',
templateUrl: './result-table.component.html',
styleUrls: ['./result-table.component.scss']
})
export class ResultTableComponent {
@Input() results: SongResult[]
export class ResultTableComponent implements OnInit {
@Output() rowClicked = new EventEmitter<SongResult>()
@Output() songChecked = new EventEmitter<SongResult>()
@@ -18,7 +18,23 @@ export class ResultTableComponent {
@ViewChild(CheckboxDirective, { static: true }) checkboxColumn: CheckboxDirective
@ViewChildren('tableRow') tableRows: QueryList<ResultTableRowComponent>
constructor() { }
results: SongResult[]
constructor(private searchService: SearchService) { }
ngOnInit() {
this.searchService.onNewSearch(() => {
this.checkboxColumn.check(false)
this.checkAll(false)
})
this.searchService.onSearchChanged(results => {
this.results = results
if (this.checkboxColumn.isChecked) {
this.checkAll(true)
}
})
}
onRowClicked(result: SongResult) {
this.rowClicked.emit(result)
@@ -39,8 +55,4 @@ export class ResultTableComponent {
onSongsDeselected(songs: SongResult['id'][]) {
this.tableRows.forEach(row => row.check(!songs.includes(row.songID)))
}
onNewSearch() {
this.checkboxColumn.check(false)
}
}

View File

@@ -19,7 +19,7 @@
<a class="item">Charter</a>
</div>
</div>
<!-- <div class="item right">
<!-- TODO <div class="item right">
<button class="ui positive disabled button">Bulk Download</button>
</div> -->
</div>

View File

@@ -1,6 +1,5 @@
import { Component, AfterViewInit, Output, EventEmitter } from '@angular/core'
import { ElectronService } from '../../../core/services/electron.service'
import { SearchType, SongResult } from '../../../../electron/shared/interfaces/search.interface'
import { Component, AfterViewInit } from '@angular/core'
import { SearchService } from 'src/app/core/services/search.service'
@Component({
selector: 'app-search-bar',
@@ -8,17 +7,14 @@ import { SearchType, SongResult } from '../../../../electron/shared/interfaces/s
styleUrls: ['./search-bar.component.scss']
})
export class SearchBarComponent implements AfterViewInit {
@Output() resultsUpdated = new EventEmitter<SongResult[]>()
constructor(private electronService: ElectronService) { }
constructor(private searchService: SearchService) { }
ngAfterViewInit() {
$('.ui.dropdown').dropdown()
}
async onSearch(query: string) {
const results = await this.electronService.invoke('song-search', { query, type: SearchType.Any })
this.resultsUpdated.emit(results)
this.searchService.newSearch(query)
}
}

View File

@@ -4,6 +4,7 @@ import { DownloadService } from 'src/app/core/services/download.service'
import { ElectronService } from 'src/app/core/services/electron.service'
import { groupBy } from 'src/electron/shared/UtilFunctions'
import { VersionResult } from 'src/electron/shared/interfaces/songDetails.interface'
import { SearchService } from 'src/app/core/services/search.service'
@Component({
selector: 'app-status-bar',
@@ -21,12 +22,25 @@ export class StatusBarComponent {
batchResults: VersionResult[]
chartGroups: VersionResult[][]
constructor(private electronService: ElectronService, private downloadService: DownloadService, ref: ChangeDetectorRef) {
constructor(
private electronService: ElectronService,
private downloadService: DownloadService,
searchService: SearchService,
ref: ChangeDetectorRef
) {
downloadService.onDownloadUpdated(() => {
this.downloading = downloadService.downloadCount > 0
this.percent = downloadService.totalPercent
ref.detectChanges()
})
searchService.onSearchChanged(() => {
this.resultCount = searchService.resultCount
})
searchService.onNewSearch(() => {
this.selectedResults = []
})
}
showDownloads() {

View File

@@ -6,24 +6,33 @@ import { Directive, ElementRef, Output, EventEmitter, AfterViewInit } from '@ang
export class CheckboxDirective implements AfterViewInit {
@Output() checked = new EventEmitter<boolean>()
_isChecked = false
constructor(private checkbox: ElementRef) { }
ngAfterViewInit() {
$(this.checkbox.nativeElement).checkbox({
onChecked: () => {
this.checked.emit(true)
this._isChecked = true
},
onUnchecked: () => {
this.checked.emit(false)
this._isChecked = false
}
})
}
check(isChecked: boolean) {
this._isChecked = isChecked
if (isChecked) {
$(this.checkbox.nativeElement).checkbox('check')
} else {
$(this.checkbox.nativeElement).checkbox('uncheck')
}
}
get isChecked() {
return this._isChecked
}
}

View File

@@ -0,0 +1,33 @@
import { Injectable, EventEmitter } from '@angular/core'
import { ElectronService } from './electron.service'
import { SearchType, SongResult } from 'src/electron/shared/interfaces/search.interface'
@Injectable({
providedIn: 'root'
})
export class SearchService {
private resultsChangedEmitter = new EventEmitter<SongResult[]>() // For when any results change
private newResultsEmitter = new EventEmitter<SongResult[]>() // For when a new search happens
private results: SongResult[] = []
constructor(private electronService: ElectronService) { }
async newSearch(query: string) {
this.results = await this.electronService.invoke('song-search', { query, type: SearchType.Any })
this.newResultsEmitter.emit(this.results)
this.resultsChangedEmitter.emit(this.results)
}
onSearchChanged(callback: (results: SongResult[]) => void) {
this.resultsChangedEmitter.subscribe(callback)
}
onNewSearch(callback: (results: SongResult[]) => void) {
this.newResultsEmitter.subscribe(callback)
}
get resultCount() {
return this.results.length
}
}