Fix settings page

This commit is contained in:
Geomitron
2023-11-29 20:06:11 -06:00
parent 6fae59f762
commit d689843f27
10 changed files with 109 additions and 123 deletions

View File

@@ -1,4 +1,4 @@
<div *ngIf="settingsLoaded" style="display: flex; flex-direction: column; height: 100%">
<div *ngIf="settingsLoaded" class="flex flex-col h-screen">
<app-toolbar></app-toolbar>
<router-outlet></router-outlet>
</div>

View File

@@ -1,5 +1,5 @@
<div id="sidebarCard" *ngIf="selectedVersion" class="ui fluid card">
<div class="ui placeholder" [ngClass]="{ placeholder: albumArtSrc === '', inverted: settingsService.theme === 'Dark' }">
<div class="ui placeholder" [ngClass]="{ placeholder: albumArtSrc === '', inverted: settingsService.theme === 'dark' }">
<img *ngIf="albumArtSrc !== null" class="ui square image" [src]="albumArtSrc" />
</div>
<div *ngIf="charts.length > 1" id="chartDropdown" class="ui fluid right labeled scrolling icon dropdown button">

View File

@@ -1,7 +1,7 @@
<table
id="resultTable"
class="ui stackable selectable single sortable fixed line striped compact small table"
[class.inverted]="settingsService.theme === 'Dark'">
[class.inverted]="settingsService.theme === 'dark'">
<!-- TODO: maybe have some of these tags customizable? E.g. small/large/compact/padded -->
<!-- TODO: learn semantic themes in order to change the $mobileBreakpoint global variable (better search table adjustment) -->
<thead>

View File

@@ -1,64 +1,68 @@
<h3 class="ui header">Paths</h3>
<div class="ui form">
<div class="field">
<label>Chart library directory</label>
<div class="ui action input">
<div class="p-8 flex flex-col gap-3">
<label class="form-control w-full">
<div class="label">
<span class="label-text">Chart library directory</span>
</div>
<div class="join w-full">
<input
[value]="settingsService.libraryDirectory || 'No folder selected'"
class="default-cursor"
class="join-item input input-bordered cursor-default pointer-events-none flex-1"
readonly
type="text"
placeholder="No directory selected!" />
<button *ngIf="settingsService.libraryDirectory !== undefined" (click)="openLibraryDirectory()" class="ui button">Open Folder</button>
<button (click)="getLibraryDirectory()" class="ui button positive">Choose</button>
<button *ngIf="settingsService.libraryDirectory !== undefined" (click)="openLibraryDirectory()" class="join-item btn btn-neutral">
Open Folder
</button>
<button (click)="getLibraryDirectory()" class="join-item btn btn-primary">Choose</button>
</div>
</label>
<label class="form-control w-full max-w-xs">
<div class="label">
<span class="label-text">Theme</span>
</div>
<div class="dropdown dropdown-hover">
<label tabindex="0" class="btn btn-neutral">{{ capitalize(settingsService.theme) }}</label>
<ul tabindex="0" class="dropdown-content z-[2] menu p-2 shadow bg-neutral text-neutral-content rounded-box w-36">
<li>
<h2 class="menu-title text-neutral-content text-opacity-50">Dark</h2>
<ul>
<li><a (click)="setTheme('business')">Business</a></li>
<li><a (click)="setTheme('dark')">Dark</a></li>
<li><a (click)="setTheme('halloween')">Halloween</a></li>
<li><a (click)="setTheme('night')">Night</a></li>
<li><a (click)="setTheme('synthwave')">Synthwave</a></li>
</ul>
</li>
<li>
<h2 class="menu-title text-neutral-content text-opacity-50">Light</h2>
<ul>
<li><a (click)="setTheme('aqua')">Aqua</a></li>
<li><a (click)="setTheme('emerald')">Emerald</a></li>
<li><a (click)="setTheme('lemonade')">Lemonade</a></li>
<li><a (click)="setTheme('valentine')">Valentine</a></li>
<li><a (click)="setTheme('winter')">Winter</a></li>
</ul>
</li>
</ul>
</div>
</label>
<div class="absolute bottom-8 right-8 flex gap-6">
<div class="join">
<button *ngIf="updateAvailable" class="join-item btn btn-primary" (click)="downloadUpdate()">
<i class="bi text-xl" [ngClass]="updateDownloaded ? 'bi-arrow-repeat' : 'bi-cloud-arrow-down'"></i>{{ downloadUpdateText }}
</button>
<button *ngIf="updateAvailable === null" class="join-item btn btn-warning" [class.disabled]="updateRetrying" (click)="retryUpdate()">
<i class="bi bi-arrow-repeat text-xl" [class.loading]="updateRetrying"></i>{{ retryUpdateText }}
</button>
<button class="join-item btn btn-outline btn-disabled">{{ currentVersion }}</button>
</div>
<div class="tooltip tooltip-left" data-tip="Toggle developer tools">
<button class="btn btn-primary btn-square btn-neutral" (click)="toggleDevTools()">
<i class="bi bi-gear text-lg"></i>
</button>
</div>
</div>
</div>
<h3 class="ui header">Downloads</h3>
<div class="ui form">
<div class="field">
<div appCheckbox #videoCheckbox class="ui checkbox" (checked)="downloadVideos($event)">
<input type="checkbox" />
<label>Download video backgrounds</label>
</div>
</div>
</div>
<div class="field">
<label>Google rate limit delay</label>
<div id="rateLimitInput" class="ui right labeled input">
<input type="number" [value]="settingsService.rateLimitDelay" (input)="changeRateLimit($event)" />
<div class="ui basic label">sec</div>
</div>
</div>
<div *ngIf="settingsService.rateLimitDelay < 30" class="ui warning message">
<i class="exclamation circle icon"></i>
<b>Warning:</b> downloading files from Google with a delay less than about 30 seconds will eventually cause Google to refuse download requests from
this program for a few hours. This limitation will be removed in a future update.
</div>
<h3 class="ui header">Theme</h3>
<div #themeDropdown class="ui selection dropdown mr">
<input type="hidden" name="sort" [value]="settingsService.theme" />
<i class="dropdown icon"></i>
<div class="default text">{{ settingsService.theme }}</div>
<div class="menu">
<div class="item" [attr.data-value]="i" *ngFor="let theme of settingsService.builtinThemes; let i = index">{{ theme }}</div>
</div>
</div>
<div class="bottom">
<div class="ui buttons">
<button *ngIf="updateAvailable" class="ui labeled icon positive button" (click)="downloadUpdate()">
<i class="left alternate icon" [ngClass]="updateDownloaded ? 'sync' : 'cloud download'"></i>{{ downloadUpdateText }}
</button>
<button *ngIf="updateAvailable === null" class="ui labeled yellow icon button" [class.disabled]="updateRetrying" (click)="retryUpdate()">
<i class="left alternate sync alternate icon" [class.loading]="updateRetrying"></i>{{ retryUpdateText }}
</button>
<button id="versionNumberButton" class="ui basic disabled button">{{ currentVersion }}</button>
</div>
<button class="ui basic icon button" data-tooltip="Toggle developer tools" data-position="top right" (click)="toggleDevTools()">
<i class="cog icon"></i>
</button>
</div>

View File

@@ -1,24 +0,0 @@
:host {
flex: 1;
padding: 2em;
overflow-y: auto;
}
.default-cursor {
cursor: default;
pointer-events: none;
}
#rateLimitInput {
width: unset !important;
}
.bottom {
position: absolute;
bottom: 2em;
right: 2em;
}
#versionNumberButton {
margin-right: 1em;
}

View File

@@ -1,16 +1,15 @@
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'
import { CheckboxDirective } from 'src-angular/app/core/directives/checkbox.directive'
import { capitalize } from 'lodash'
import { SettingsService } from 'src-angular/app/core/services/settings.service'
import { themes } from 'src-shared/Settings'
@Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.scss'],
})
export class SettingsComponent implements OnInit, AfterViewInit {
export class SettingsComponent implements OnInit {
@ViewChild('themeDropdown', { static: true }) themeDropdown: ElementRef
@ViewChild(CheckboxDirective, { static: true }) videoCheckbox: CheckboxDirective
updateAvailable: boolean | null = false
loginClicked = false
@@ -52,17 +51,6 @@ export class SettingsComponent implements OnInit, AfterViewInit {
})
}
ngAfterViewInit() {
// TODO
// $(this.themeDropdown.nativeElement).dropdown({
// onChange: (_value: string, text: string) => {
// this.settingsService.theme = text
// },
// })
this.videoCheckbox.check(this.settingsService.downloadVideos)
}
async downloadVideos(isChecked: boolean) {
this.settingsService.downloadVideos = isChecked
}
@@ -85,9 +73,12 @@ export class SettingsComponent implements OnInit, AfterViewInit {
}
}
changeRateLimit(event: Event) {
const inputElement = event.srcElement as HTMLInputElement
this.settingsService.rateLimitDelay = Number(inputElement.value)
setTheme(theme: typeof themes[number]) {
this.settingsService.theme = theme
}
capitalize(text: string) {
return capitalize(text)
}
downloadUpdate() {

View File

@@ -1,8 +1,8 @@
<div class="navbar p-0 min-h-0 bg-base-100" style="-webkit-app-region: drag">
<div style="-webkit-app-region: no-drag">
<button class="btn btn-square btn-ghost rounded-none px-14 cursor-default" routerLinkActive="btn-active" routerLink="/browse">Browse</button>
<button class="btn btn-square btn-ghost rounded-none px-10 cursor-default" routerLinkActive="btn-active" routerLink="/browse">Browse</button>
<!-- TODO <a class="btn btn-square btn-ghost rounded-none cursor-default" routerLinkActive="btn-active" routerLink="/library">Library</a> -->
<button class="btn btn-square btn-ghost rounded-none px-12 cursor-default" routerLinkActive="btn-active" routerLink="/settings">
<button class="btn btn-square btn-ghost rounded-none px-10 cursor-default" routerLinkActive="btn-active" routerLink="/settings">
<i *ngIf="updateAvailable" class="teal small circle icon"></i>
<i *ngIf="updateAvailable === null" class="small yellow exclamation triangle icon"></i>
Settings
@@ -14,6 +14,8 @@
<button class="btn btn-square btn-ghost rounded-none cursor-default" (click)="toggleMaximized()">
<i class="bi" [ngClass]="isMaximized ? 'bi-window-stack' : 'bi-window'"></i>
</button>
<button class="btn btn-square btn-ghost rounded-none hover:bg-red-600/20 cursor-default" (click)="close()"><i class="bi bi-x-lg"></i></button>
<button class="btn btn-square btn-ghost rounded-none hover:bg-red-600/20 cursor-default" (click)="close()">
<i class="bi bi-x-lg"></i>
</button>
</div>
</div>

View File

@@ -1,19 +1,24 @@
import { Injectable } from '@angular/core'
import { DOCUMENT } from '@angular/common'
import { Inject, Injectable } from '@angular/core'
import { Settings } from '../../../../src-shared/Settings'
import { Settings, themes } from '../../../../src-shared/Settings'
@Injectable({
providedIn: 'root',
})
export class SettingsService {
readonly builtinThemes = ['Default', 'Dark']
private settings: Settings
private currentThemeLink: HTMLLinkElement
constructor(
@Inject(DOCUMENT) private document: Document,
) { }
async loadSettings() {
this.settings = await window.electron.invoke.getSettings()
if (this.settings.theme !== this.builtinThemes[0]) {
if (!themes.includes(this.settings.theme)) {
this.changeTheme('dark')
} else {
this.changeTheme(this.settings.theme)
}
}
@@ -22,15 +27,8 @@ export class SettingsService {
window.electron.emit.setSettings(this.settings)
}
changeTheme(theme: string) {
if (this.currentThemeLink !== undefined) this.currentThemeLink.remove()
if (theme === 'Default') { return }
const link = document.createElement('link')
link.type = 'text/css'
link.rel = 'stylesheet'
link.href = `./assets/themes/${theme.toLowerCase()}.css`
this.currentThemeLink = document.head.appendChild(link)
changeTheme(theme: typeof themes[number]) {
this.document.documentElement.setAttribute('data-theme', theme)
}
// Individual getters/setters
@@ -53,7 +51,7 @@ export class SettingsService {
get theme() {
return this.settings.theme
}
set theme(newValue: string) {
set theme(newValue: typeof themes[number]) {
this.settings.theme = newValue
this.changeTheme(newValue)
this.saveSettings()

View File

@@ -131,7 +131,7 @@ async function loadWindow(retries = 0) {
try {
await mainWindow.loadURL(getLoadUrl())
} catch (err) {
console.log('FAILED TO LOAD WINDOW #', retries)
await new Promise<void>(resolve => setTimeout(resolve, 1000))
await loadWindow(retries + 1)
}
}

View File

@@ -1,10 +1,25 @@
export const themes = [
'business',
'dark',
'halloween',
'night',
'synthwave',
'aqua',
'emerald',
'lemonade',
'valentine',
'winter',
'aren',
'froogs',
] as const
/**
* 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
theme: typeof themes[number] // The name of the currently enabled UI theme
libraryPath: string | undefined // The path to the user's library
}
@@ -14,6 +29,6 @@ export interface Settings {
export const defaultSettings: Settings = {
rateLimitDelay: 31,
downloadVideos: true,
theme: 'Default',
theme: 'dark',
libraryPath: undefined,
}