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,28 +0,0 @@
import { basename, parse } from 'path'
import { getSettingsHandler } from '../ipc/SettingsHandler.ipc'
import { emitIPCEvent } from '../main'
import { lower } from './UtilFunctions'
/**
* @returns The relative filepath from the library folder to `absoluteFilepath`.
*/
export function getRelativeFilepath(absoluteFilepath: string) {
const settings = getSettingsHandler.getSettings()
return basename(settings.libraryPath) + absoluteFilepath.substring(settings.libraryPath.length)
}
/**
* @returns `true` if `name` has a valid video file extension.
*/
export function hasVideoExtension(name: string) {
return (['.mp4', '.avi', '.webm', '.ogv', '.mpeg'].includes(parse(lower(name)).ext))
}
/**
* Log a message in the main BrowserWindow's console.
* Note: Error objects can't be serialized by this; use inspect(err) before passing it here.
*/
export function devLog(...messages: unknown[]) {
emitIPCEvent('log', messages)
}

View File

@@ -1,123 +0,0 @@
import { UpdateInfo } from 'electron-updater'
import { albumArtHandler } from '../ipc/browse/AlbumArtHandler.ipc'
import { batchSongDetailsHandler } from '../ipc/browse/BatchSongDetailsHandler.ipc'
import { searchHandler } from '../ipc/browse/SearchHandler.ipc'
import { songDetailsHandler } from '../ipc/browse/SongDetailsHandler.ipc'
import { clearCacheHandler } from '../ipc/CacheHandler.ipc'
import { downloadHandler } from '../ipc/download/DownloadHandler'
import { openURLHandler } from '../ipc/OpenURLHandler.ipc'
import { getSettingsHandler, setSettingsHandler } from '../ipc/SettingsHandler.ipc'
import { downloadUpdateHandler, getCurrentVersionHandler, getUpdateAvailableHandler, quitAndInstallHandler, updateChecker, UpdateProgress } from '../ipc/UpdateHandler.ipc'
import { Download, DownloadProgress } from './interfaces/download.interface'
import { SongResult, SongSearch } from './interfaces/search.interface'
import { AlbumArtResult, VersionResult } from './interfaces/songDetails.interface'
import { Settings } from './Settings'
/**
* To add a new IPC listener:
* 1.) Write input/output interfaces
* 2.) Add the event to IPCEvents
* 3.) Write a class that implements IPCHandler
* 4.) Add the class to getIPCHandlers
*/
export function getIPCInvokeHandlers(): IPCInvokeHandler<keyof IPCInvokeEvents>[] {
return [
getSettingsHandler,
clearCacheHandler,
searchHandler,
songDetailsHandler,
batchSongDetailsHandler,
albumArtHandler,
getCurrentVersionHandler,
getUpdateAvailableHandler,
]
}
/**
* The list of possible async IPC events that return values, mapped to their input and output types.
*/
export interface IPCInvokeEvents {
'get-settings': {
input: undefined
output: Settings
}
'clear-cache': {
input: undefined
output: void
}
'song-search': {
input: SongSearch
output: SongResult[]
}
'album-art': {
input: SongResult['id']
output: AlbumArtResult
}
'song-details': {
input: SongResult['id']
output: VersionResult[]
}
'batch-song-details': {
input: number[]
output: VersionResult[]
}
'get-current-version': {
input: undefined
output: string
}
'get-update-available': {
input: undefined
output: boolean
}
}
/**
* Describes an object that handles the `E` async IPC event that will return a value.
*/
export interface IPCInvokeHandler<E extends keyof IPCInvokeEvents> {
event: E
handler(data: IPCInvokeEvents[E]['input']): Promise<IPCInvokeEvents[E]['output']> | IPCInvokeEvents[E]['output']
}
export function getIPCEmitHandlers(): IPCEmitHandler<keyof IPCEmitEvents>[] {
return [
downloadHandler,
setSettingsHandler,
downloadUpdateHandler,
updateChecker,
quitAndInstallHandler,
openURLHandler,
]
}
/**
* The list of possible async IPC events that don't return values, mapped to their input types.
*/
export interface IPCEmitEvents {
'log': any[]
'download': Download
'download-updated': DownloadProgress
'set-settings': Settings
'queue-updated': number[]
'update-error': Error
'update-available': UpdateInfo
'update-progress': UpdateProgress
'update-downloaded': undefined
'download-update': undefined
'retry-update': undefined
'quit-and-install': undefined
'open-url': string
}
/**
* Describes an object that handles the `E` async IPC event that will not return a value.
*/
export interface IPCEmitHandler<E extends keyof IPCEmitEvents> {
event: E
handler(data: IPCEmitEvents[E]): void
}

View File

@@ -2,10 +2,10 @@
* Represents Bridge's user settings.
*/
export interface Settings {
rateLimitDelay: number // Number of seconds to wait between each file download from Google servers
downloadVideos: boolean // If background videos should be downloaded
theme: string // The name of the currently enabled UI theme
libraryPath: string // The path to the user's library
rateLimitDelay: number // Number of seconds to wait between each file download from Google servers
downloadVideos: boolean // If background videos should be downloaded
theme: string // The name of the currently enabled UI theme
libraryPath: string | undefined // The path to the user's library
}
/**

View File

@@ -1,4 +1,3 @@
import randomBytes from 'randombytes'
import sanitize from 'sanitize-filename'
// WARNING: do not import anything related to Electron; the code will not compile correctly.
@@ -26,7 +25,7 @@ export function sanitizeFilename(filename: string): string {
}
}),
})
return (newFilename == '' ? randomBytes(5).toString('hex') : newFilename)
return (newFilename === '' ? 'TODO_MAKE_UNIQUE' : newFilename)
}
/**
@@ -49,8 +48,8 @@ export function interpolate(val: number, fromStart: number, fromEnd: number, toS
export function groupBy<T>(objectList: T[], ...keys: (keyof T)[]) {
const results: T[][] = []
for (const object of objectList) {
const matchingGroup = results.find(result => keys.every(key => result[0][key] == object[key]))
if (matchingGroup != undefined) {
const matchingGroup = results.find(result => keys.every(key => result[0][key] === object[key]))
if (matchingGroup !== undefined) {
matchingGroup.push(object)
} else {
results.push([object])

View File

@@ -6,7 +6,7 @@ import { DriveChart } from './songDetails.interface'
export interface Download {
action: 'add' | 'retry' | 'cancel'
versionID: number
data?: NewDownload // Should be defined if action == 'add'
data?: NewDownload // Should be defined if action === 'add'
}
/**

View File

@@ -0,0 +1,105 @@
import { OpenDialogOptions, OpenDialogReturnValue } from 'electron'
import { UpdateInfo } from 'electron-updater'
import { Settings } from '../Settings'
import { Download, DownloadProgress } from './download.interface'
import { SongResult, SongSearch } from './search.interface'
import { VersionResult } from './songDetails.interface'
import { UpdateProgress } from './update.interface'
export interface ContextBridgeApi {
invoke: IpcInvokeHandlers
emit: IpcToMainEmitHandlers
on: IpcFromMainEmitHandlers
}
/**
* To add a new IPC listener:
* 1.) Add listener to this interface.
* 2.) Fix compile errors in `ipcHandler.ts` and `preload.ts`.
*/
/**
* The list of possible async IPC events that return values.
*/
export interface IpcInvokeEvents {
getSettings: {
input: void
output: Settings
}
songSearch: {
input: SongSearch
output: SongResult[]
}
getSongDetails: {
input: SongResult['id']
output: VersionResult[]
}
getBatchSongDetails: {
input: number[]
output: VersionResult[]
}
getCurrentVersion: {
input: void
output: string
}
getUpdateAvailable: {
input: void
output: boolean | null
}
isMaximized: {
input: void
output: boolean
}
showOpenDialog: {
input: OpenDialogOptions
output: OpenDialogReturnValue
}
}
export type IpcInvokeHandlers = {
[K in keyof IpcInvokeEvents]:
(input: IpcInvokeEvents[K]['input']) => Promise<IpcInvokeEvents[K]['output']>
}
/**
* The list of possible async IPC events sent to the main process that don't return values.
*/
export interface IpcToMainEmitEvents {
download: Download
setSettings: Settings
downloadUpdate: void
retryUpdate: void
quitAndInstall: void
openUrl: string
toggleDevTools: void
maximize: void
minimize: void
restore: void
quit: void
showFolder: string
showFile: string
}
export type IpcToMainEmitHandlers = {
[K in keyof IpcToMainEmitEvents]: (input: IpcToMainEmitEvents[K]) => void
}
/**
* The list of possible async IPC events sent from the main process that don't return values.
*/
export interface IpcFromMainEmitEvents {
errorLog: string
updateError: string
updateAvailable: UpdateInfo | null
updateProgress: UpdateProgress
updateDownloaded: void
downloadUpdated: DownloadProgress
queueUpdated: number[]
maximized: void
minimized: void
}
export type IpcFromMainEmitHandlers = {
[K in keyof IpcFromMainEmitEvents]: (listener: (data: IpcFromMainEmitEvents[K]) => void) => void
}

View File

@@ -22,12 +22,14 @@ export function getDefaultSearch(): SongSearch {
similarity: 'similar',
fields: { name: true, artist: true, album: true, genre: true, year: true, charter: true, tag: true },
tags: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'sections': false, 'star power': false, 'forcing': false, 'taps': false, 'lyrics': false,
'video': false, 'stems': false, 'solo sections': false, 'open notes': false
// eslint-disable-next-line @typescript-eslint/naming-convention
'video': false, 'stems': false, 'solo sections': false, 'open notes': false,
},
instruments: {
guitar: false, bass: false, rhythm: false, keys: false,
drums: false, guitarghl: false, bassghl: false, vocals: false
drums: false, guitarghl: false, bassghl: false, vocals: false,
},
difficulties: { expert: false, hard: false, medium: false, easy: false },
minDiff: 0,
@@ -49,13 +51,16 @@ export interface SearchFields {
export interface SearchTags {
'sections': boolean // Tag inverted
// eslint-disable-next-line @typescript-eslint/naming-convention
'star power': boolean // Tag inverted
'forcing': boolean // Tag inverted
'taps': boolean
'lyrics': boolean
'video': boolean
'stems': boolean
// eslint-disable-next-line @typescript-eslint/naming-convention
'solo sections': boolean
// eslint-disable-next-line @typescript-eslint/naming-convention
'open notes': boolean
}

View File

@@ -1,10 +1,3 @@
/**
* The image data for a song's album art.
*/
export interface AlbumArtResult {
base64Art: string
}
/**
* Represents a single chart version.
*/

View File

@@ -0,0 +1,7 @@
export interface UpdateProgress {
bytesPerSecond: number
percent: number
transferred: number
total: number
}