Restructure; use DaisyUI

This commit is contained in:
Geomitron
2023-11-28 19:50:45 -06:00
parent 49c3f38f99
commit 2eef4d0bee
727 changed files with 1283 additions and 298840 deletions

View File

@@ -1,26 +0,0 @@
import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service'
@Injectable({
providedIn: 'root',
})
export class AlbumArtService {
private imageCache: { [songID: number]: string } = {}
constructor(private electronService: ElectronService) { }
async getImage(songID: number): Promise<string | null> {
if (this.imageCache[songID] == undefined) {
const albumArtResult = await this.electronService.invoke('album-art', songID)
if (albumArtResult) {
this.imageCache[songID] = albumArtResult.base64Art
} else {
this.imageCache[songID] = null
}
}
return this.imageCache[songID]
}
}

View File

@@ -1,7 +1,6 @@
import { EventEmitter, Injectable } from '@angular/core'
import { DownloadProgress, NewDownload } from '../../../electron/shared/interfaces/download.interface'
import { ElectronService } from './electron.service'
import { DownloadProgress, NewDownload } from '../../../../src-shared/interfaces/download.interface'
@Injectable({
providedIn: 'root',
@@ -11,13 +10,13 @@ export class DownloadService {
private downloadUpdatedEmitter = new EventEmitter<DownloadProgress>()
private downloads: DownloadProgress[] = []
constructor(private electronService: ElectronService) {
this.electronService.receiveIPC('download-updated', result => {
constructor() {
window.electron.on.downloadUpdated(result => {
// Update <this.downloads> with result
const thisDownloadIndex = this.downloads.findIndex(download => download.versionID == result.versionID)
if (result.type == 'cancel') {
this.downloads = this.downloads.filter(download => download.versionID != result.versionID)
} else if (thisDownloadIndex == -1) {
const thisDownloadIndex = this.downloads.findIndex(download => download.versionID === result.versionID)
if (result.type === 'cancel') {
this.downloads = this.downloads.filter(download => download.versionID !== result.versionID)
} else if (thisDownloadIndex === -1) {
this.downloads.push(result)
} else {
this.downloads[thisDownloadIndex] = result
@@ -32,7 +31,7 @@ export class DownloadService {
}
get completedCount() {
return this.downloads.filter(download => download.type == 'done').length
return this.downloads.filter(download => download.type === 'done').length
}
get totalDownloadingPercent() {
@@ -48,15 +47,15 @@ export class DownloadService {
}
get anyErrorsExist() {
return this.downloads.find(download => download.type == 'error') ? true : false
return this.downloads.find(download => download.type === 'error') ? true : false
}
addDownload(versionID: number, newDownload: NewDownload) {
if (!this.downloads.find(download => download.versionID == versionID)) { // Don't download something twice
if (this.downloads.every(download => download.type == 'done')) { // Reset overall progress bar if it finished
if (!this.downloads.find(download => download.versionID === versionID)) { // Don't download something twice
if (this.downloads.every(download => download.type === 'done')) { // Reset overall progress bar if it finished
this.downloads.forEach(download => download.stale = true)
}
this.electronService.sendIPC('download', { action: 'add', versionID, data: newDownload })
window.electron.emit.download({ action: 'add', versionID, data: newDownload })
}
}
@@ -65,25 +64,25 @@ export class DownloadService {
}
cancelDownload(versionID: number) {
const removedDownload = this.downloads.find(download => download.versionID == versionID)
const removedDownload = this.downloads.find(download => download.versionID === versionID)!
if (['error', 'done'].includes(removedDownload.type)) {
this.downloads = this.downloads.filter(download => download.versionID != versionID)
this.downloads = this.downloads.filter(download => download.versionID !== versionID)
removedDownload.type = 'cancel'
this.downloadUpdatedEmitter.emit(removedDownload)
} else {
this.electronService.sendIPC('download', { action: 'cancel', versionID })
window.electron.emit.download({ action: 'cancel', versionID })
}
}
cancelCompleted() {
for (const download of this.downloads) {
if (download.type == 'done') {
if (download.type === 'done') {
this.cancelDownload(download.versionID)
}
}
}
retryDownload(versionID: number) {
this.electronService.sendIPC('download', { action: 'retry', versionID })
window.electron.emit.download({ action: 'retry', versionID })
}
}

View File

@@ -1,81 +0,0 @@
import { Injectable } from '@angular/core'
// If you import a module but never use any of the imported values other than as TypeScript types,
// the resulting javascript file will look as if you never imported the module at all.
import * as electron from 'electron'
import { IPCEmitEvents, IPCInvokeEvents } from '../../../electron/shared/IPCHandler'
const { app, getCurrentWindow, dialog, session } = window.require('@electron/remote')
@Injectable({
providedIn: 'root',
})
export class ElectronService {
electron: typeof electron
get isElectron() {
return !!(window && window.process && window.process.type)
}
constructor() {
if (this.isElectron) {
this.electron = window.require('electron')
this.receiveIPC('log', results => results.forEach(result => console.log(result)))
}
}
get currentWindow() {
return getCurrentWindow()
}
/**
* Calls an async function in the main process.
* @param event The name of the IPC event to invoke.
* @param data The data object to send across IPC.
* @returns A promise that resolves to the output data.
*/
async invoke<E extends keyof IPCInvokeEvents>(event: E, data: IPCInvokeEvents[E]['input']) {
return this.electron.ipcRenderer.invoke(event, data) as Promise<IPCInvokeEvents[E]['output']>
}
/**
* Sends an IPC message to the main process.
* @param event The name of the IPC event to send.
* @param data The data object to send across IPC.
*/
sendIPC<E extends keyof IPCEmitEvents>(event: E, data: IPCEmitEvents[E]) {
this.electron.ipcRenderer.send(event, data)
}
/**
* Receives an IPC message from the main process.
* @param event The name of the IPC event to receive.
* @param callback The data object to receive across IPC.
*/
receiveIPC<E extends keyof IPCEmitEvents>(event: E, callback: (result: IPCEmitEvents[E]) => void) {
this.electron.ipcRenderer.on(event, (_event, ...results) => {
callback(results[0])
})
}
quit() {
app.exit()
}
openFolder(filepath: string) {
this.electron.shell.openPath(filepath)
}
showFolder(filepath: string) {
this.electron.shell.showItemInFolder(filepath)
}
showOpenDialog(options: Electron.OpenDialogOptions) {
return dialog.showOpenDialog(this.currentWindow, options)
}
get defaultSession() {
return session.defaultSession
}
}

View File

@@ -1,8 +1,7 @@
import { EventEmitter, Injectable } from '@angular/core'
import { SongResult, SongSearch } from 'src/electron/shared/interfaces/search.interface'
import { VersionResult } from 'src/electron/shared/interfaces/songDetails.interface'
import { ElectronService } from './electron.service'
import { SongResult, SongSearch } from '../../../../src-shared/interfaces/search.interface'
import { VersionResult } from '../../../../src-shared/interfaces/songDetails.interface'
@Injectable({
providedIn: 'root',
@@ -17,14 +16,12 @@ export class SearchService {
private currentQuery: SongSearch
private _allResultsVisible = true
constructor(private electronService: ElectronService) { }
async newSearch(query: SongSearch) {
if (this.awaitingResults) { return }
this.awaitingResults = true
this.currentQuery = query
try {
this.results = this.trimLastChart(await this.electronService.invoke('song-search', this.currentQuery))
this.results = this.trimLastChart(await window.electron.invoke.songSearch(this.currentQuery))
this.errorStateEmitter.emit(false)
} catch (err) {
this.results = []
@@ -74,7 +71,7 @@ export class SearchService {
if (!this.awaitingResults && !this._allResultsVisible) {
this.awaitingResults = true
this.currentQuery.offset += 50
this.results.push(...this.trimLastChart(await this.electronService.invoke('song-search', this.currentQuery)))
this.results.push(...this.trimLastChart(await window.electron.invoke.songSearch(this.currentQuery)))
this.awaitingResults = false
this.resultsChangedEmitter.emit(this.results)
@@ -105,7 +102,7 @@ export class SearchService {
versionResults.forEach(version => dates[version.versionID] = new Date(version.lastModified).getTime())
versionResults.sort((v1, v2) => {
const diff = dates[v2.versionID] - dates[v1.versionID]
if (Math.abs(diff) < 6.048e+8 && v1.driveData.inChartPack != v2.driveData.inChartPack) {
if (Math.abs(diff) < 6.048e+8 && v1.driveData.inChartPack !== v2.driveData.inChartPack) {
if (v1.driveData.inChartPack) {
return 1 // prioritize v2
} else {

View File

@@ -1,6 +1,6 @@
import { EventEmitter, Injectable } from '@angular/core'
import { SongResult } from '../../../electron/shared/interfaces/search.interface'
import { SongResult } from '../../../../src-shared/interfaces/search.interface'
import { SearchService } from './search.service'
// Note: this class prevents event cycles by only emitting events if the checkbox changes
@@ -35,7 +35,7 @@ export class SelectionService {
}
getSelectedResults() {
return this.searchResults.filter(result => this.selections[result.id] == true)
return this.searchResults.filter(result => this.selections[result.id] === true)
}
onSelectAllChanged(callback: (selected: boolean) => void) {

View File

@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core'
import { Settings } from 'src/electron/shared/Settings'
import { ElectronService } from './electron.service'
import { Settings } from '../../../../src-shared/Settings'
@Injectable({
providedIn: 'root',
@@ -12,22 +11,20 @@ export class SettingsService {
private settings: Settings
private currentThemeLink: HTMLLinkElement
constructor(private electronService: ElectronService) { }
async loadSettings() {
this.settings = await this.electronService.invoke('get-settings', undefined)
if (this.settings.theme != this.builtinThemes[0]) {
this.settings = await window.electron.invoke.getSettings()
if (this.settings.theme !== this.builtinThemes[0]) {
this.changeTheme(this.settings.theme)
}
}
saveSettings() {
this.electronService.sendIPC('set-settings', this.settings)
window.electron.emit.setSettings(this.settings)
}
changeTheme(theme: string) {
if (this.currentThemeLink != undefined) this.currentThemeLink.remove()
if (theme == 'Default') { return }
if (this.currentThemeLink !== undefined) this.currentThemeLink.remove()
if (theme === 'Default') { return }
const link = document.createElement('link')
link.type = 'text/css'
@@ -36,21 +33,11 @@ export class SettingsService {
this.currentThemeLink = document.head.appendChild(link)
}
async getCacheSize() {
return this.electronService.defaultSession.getCacheSize()
}
async clearCache() {
this.saveSettings()
await this.electronService.defaultSession.clearCache()
await this.electronService.invoke('clear-cache', undefined)
}
// Individual getters/setters
get libraryDirectory() {
return this.settings.libraryPath
}
set libraryDirectory(newValue: string) {
set libraryDirectory(newValue: string | undefined) {
this.settings.libraryPath = newValue
this.saveSettings()
}