Download video backgrounds setting; improved settings loading

This commit is contained in:
Geomitron
2021-04-10 15:52:39 -05:00
parent 0ddbd00f07
commit 0a1ba51f73
10 changed files with 75 additions and 28 deletions

View File

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

View File

@@ -8,5 +8,10 @@ import { SettingsService } from './core/services/settings.service'
})
export class AppComponent {
constructor(private settingsService: SettingsService) { }
settingsLoaded = false
constructor(private settingsService: SettingsService) {
// Ensure settings are loaded before rendering the application
settingsService.loadSettings().then(() => this.settingsLoaded = true)
}
}

View File

@@ -19,6 +19,12 @@
<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 *ngIf="loginAvailable" class="field">
<label>Google rate limit delay</label>
<div id="rateLimitInput" class="ui right labeled input">
@@ -28,7 +34,6 @@
</div>
</div>
</div>
<!-- TODO: Uncomment this when switching to the OAuth2 Login system -->
<div *ngIf="loginAvailable" class="field">
<div class="ui button" data-tooltip="Removes rate limit delay" data-position="right center" (click)="googleLogin()">
<i class="google icon"></i>Sign in with Google

View File

@@ -1,4 +1,5 @@
import { Component, OnInit, AfterViewInit, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core'
import { CheckboxDirective } from 'src/app/core/directives/checkbox.directive'
import { ElectronService } from 'src/app/core/services/electron.service'
import { SettingsService } from 'src/app/core/services/settings.service'
@@ -9,6 +10,7 @@ import { SettingsService } from 'src/app/core/services/settings.service'
})
export class SettingsComponent implements OnInit, AfterViewInit {
@ViewChild('themeDropdown', { static: true }) themeDropdown: ElementRef
@ViewChild(CheckboxDirective, { static: true }) videoCheckbox: CheckboxDirective
cacheSize = 'Calculating...'
updateAvailable = false
@@ -21,7 +23,11 @@ export class SettingsComponent implements OnInit, AfterViewInit {
updateRetrying = false
currentVersion = ''
constructor(public settingsService: SettingsService, private electronService: ElectronService, private ref: ChangeDetectorRef) { }
constructor(
public settingsService: SettingsService,
private electronService: ElectronService,
private ref: ChangeDetectorRef
) { }
async ngOnInit() {
this.electronService.receiveIPC('update-available', (result) => {
@@ -61,6 +67,8 @@ export class SettingsComponent implements OnInit, AfterViewInit {
this.settingsService.theme = text
}
})
this.videoCheckbox.check(this.settingsService.downloadVideos)
}
async clearCache() {
@@ -69,6 +77,10 @@ export class SettingsComponent implements OnInit, AfterViewInit {
this.cacheSize = 'Cleared!'
}
async downloadVideos(isChecked: boolean) {
this.settingsService.downloadVideos = isChecked
}
async getLibraryDirectory() {
const result = await this.electronService.showOpenDialog({
title: 'Choose library folder',

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service'
import { Settings, defaultSettings } from 'src/electron/shared/Settings'
import { Settings } from 'src/electron/shared/Settings'
@Injectable({
providedIn: 'root'
@@ -11,25 +11,17 @@ export class SettingsService {
private settings: Settings
private currentThemeLink: HTMLLinkElement
constructor(private electronService: ElectronService) {
this.getSettings().then(() => {
if (this.settings.theme != this.builtinThemes[0]) {
this.changeTheme(this.settings.theme)
}
})
}
constructor(private electronService: ElectronService) { }
async getSettings() {
if (this.settings == undefined) {
this.settings = await this.electronService.invoke('get-settings', undefined)
async loadSettings() {
this.settings = await this.electronService.invoke('get-settings', undefined)
if (this.settings.theme != this.builtinThemes[0]) {
this.changeTheme(this.settings.theme)
}
return this.settings
}
saveSettings() {
if (this.settings != undefined) {
this.electronService.sendIPC('set-settings', this.settings)
}
this.electronService.sendIPC('set-settings', this.settings)
}
changeTheme(theme: string) {
@@ -55,15 +47,23 @@ export class SettingsService {
// Individual getters/setters
get libraryDirectory() {
return this.settings == undefined ? defaultSettings.libraryPath : this.settings.libraryPath
return this.settings.libraryPath
}
set libraryDirectory(newValue: string) {
this.settings.libraryPath = newValue
this.saveSettings()
}
get downloadVideos() {
return this.settings.downloadVideos
}
set downloadVideos(isChecked) {
this.settings.downloadVideos = isChecked
this.saveSettings()
}
get theme() {
return this.settings == undefined ? defaultSettings.theme : this.settings.theme
return this.settings.theme
}
set theme(newValue: string) {
this.settings.theme = newValue
@@ -72,7 +72,7 @@ export class SettingsService {
}
get rateLimitDelay() {
return this.settings == undefined ? defaultSettings.rateLimitDelay : this.settings.rateLimitDelay
return this.settings.rateLimitDelay
}
set rateLimitDelay(delay: number) {
this.settings.rateLimitDelay = delay

View File

@@ -52,6 +52,7 @@ class GetSettingsHandler implements IPCInvokeHandler<'get-settings'> {
// Read/create settings
if (await exists(settingsPath)) {
settings = JSON.parse(await readFile(settingsPath, 'utf8'))
settings = Object.assign(JSON.parse(JSON.stringify(defaultSettings)), settings)
} else {
await SetSettingsHandler.saveSettings(defaultSettings)
settings = defaultSettings

View File

@@ -9,6 +9,8 @@ import { DriveFile } from 'src/electron/shared/interfaces/songDetails.interface'
import { FileTransfer } from './FileTransfer'
import * as _rimraf from 'rimraf'
import { FilesystemChecker } from './FilesystemChecker'
import { getSettings } from '../SettingsHandler.ipc'
import { hasVideoExtension } from '../../shared/ElectronUtilFunctions'
const rimraf = promisify(_rimraf)
@@ -45,7 +47,7 @@ export class ChartDownload {
constructor(public versionID: number, private data: NewDownload) {
this.updateGUI('', 'Waiting for other downloads to finish...', 'good')
this.files = data.driveData.files
this.files = this.filterDownloadFiles(data.driveData.files)
this.individualFileProgressPortion = 80 / this.files.length
if (data.driveData.inChartPack) {
this.destinationFolderName = sanitizeFilename(parse(data.driveData.files[0].name).name)
@@ -61,6 +63,12 @@ export class ChartDownload {
this.callbacks[event] = callback
}
filterDownloadFiles(files: DriveFile[]) {
return files.filter(file => {
return (file.name != 'ch.dat') && (getSettings().downloadVideos || !hasVideoExtension(file.name))
})
}
/**
* Retries the last failed step if it is running.
*/
@@ -135,7 +143,6 @@ export class ChartDownload {
// DOWNLOAD FILES
for (let i = 0; i < this.files.length; i++) {
if (this.files[i].name == 'ch.dat') { continue }
let wasCanceled = false
this.cancelFn = () => { wasCanceled = true }
const downloader = await getDownloader(this.files[i].webContentLink, join(this.tempPath, this.files[i].name))

View File

@@ -1,6 +1,7 @@
import { basename } from 'path'
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`.
@@ -10,6 +11,13 @@ export function getRelativeFilepath(absoluteFilepath: string) {
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.
*/

View File

@@ -2,9 +2,10 @@
* Represents Bridge's user settings.
*/
export interface Settings {
rateLimitDelay: number // Number of seconds to wait between each file download from Google servers
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 // The path to the user's library
}
/**
@@ -12,6 +13,7 @@ export interface Settings {
*/
export const defaultSettings: Settings = {
rateLimitDelay: 31,
downloadVideos: true,
theme: 'Default',
libraryPath: undefined
}

View File

@@ -29,6 +29,13 @@ export function sanitizeFilename(filename: string): string {
return (newFilename == '' ? randomBytes(5).toString('hex') : newFilename)
}
/**
* @returns `text` converted to lower case.
*/
export function lower(text: string) {
return text.toLowerCase()
}
/**
* Converts `val` from the range (`fromStart`, `fromEnd`) to the range (`toStart`, `toEnd`).
*/