diff --git a/changelog.md b/changelog.md deleted file mode 100644 index 8124dd0..0000000 --- a/changelog.md +++ /dev/null @@ -1,28 +0,0 @@ -# Changelog - -## [Unreleased] - -### Added - -- Added proclamation sync when entering "proclamations" settings page - -### Changed - -- Changed audio devices page to be strictly an audio on/off toggle -- Changed settings menu items to be left-aligned with eachother -- Changed settings entry organization - -### Deprecated - -### Removed - -- Removed list of audio devices from audio device page - -### Fixed - -- Fixed audio device not being initialized on first entry to F2 screen - -### Security - ---- - diff --git a/internal/application/application.go b/internal/application/application.go index 2c10d62..697b43d 100644 --- a/internal/application/application.go +++ b/internal/application/application.go @@ -4,7 +4,6 @@ import ( "errors" "os" "path/filepath" - "sync/atomic" "time" "github.com/go-gl/gl/v3.3-core/gl" @@ -51,7 +50,6 @@ type Application struct { pendingAction func() running bool DB *gorm.DB - Config atomic.Pointer[db.AppConfig] PageRouter *page.Router state State } @@ -112,7 +110,7 @@ func Run() { // Populate the initial Config cache OR create defaults firstRun := false - result = DB.First(&initialConfig) + result = DB.Unscoped().First(&initialConfig) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { logger.Info("First run detected: Creating default configuration...") @@ -148,8 +146,6 @@ func Run() { app.state = FIRST_RUN } - app.refreshCache() - w, h := app.initializeSDLAndOpenGL() defer app.cleanup() @@ -159,12 +155,10 @@ func Run() { downloadProgressChan := make(chan download.DownloadStatus, 1000) app.PageRouter = page.NewRouter(page.PageCtx{ - CfgPtr: app.Config.Load(), DbPtr: app.DB, W: w, H: h, MessageChannel: downloadProgressChan, - RefreshConfig: app.refreshCache, }) // Sync the proclamations from the API to the Database @@ -188,7 +182,12 @@ func Run() { "PinealGland.wav", } - go download.DownloadAudioFiles(app.PageRouter.Context.MessageChannel, audioFileNames, filepath.Join(app.PageRouter.Context.CfgPtr.AssetsDir, "audio")) + config, err := db.GetConfig(app.DB) + if err != nil { + panic(err) + } + + go download.DownloadAudioFiles(app.PageRouter.Context.MessageChannel, audioFileNames, filepath.Join(config.AssetsDir, "audio")) app.runEventLoop() } @@ -221,7 +220,12 @@ func (app *Application) checkState() { } // Then check for an email address - if app.Config.Load().EmailAddress == "" { + config, err := db.GetConfig(app.DB) + if err != nil { + panic(err) + } + + if config.EmailAddress == "" { if app.state != NEEDS_EMAIL_ADDRESS { app.PageRouter.NavigateTo(page.EMAIL_ADDRESS) app.state = NEEDS_EMAIL_ADDRESS @@ -230,7 +234,11 @@ func (app *Application) checkState() { } // Then check for a license key - if app.Config.Load().LicenseKey == "" { + config, err = db.GetConfig(app.DB) + if err != nil { + panic(err) + } + if config.LicenseKey == "" { if app.state != NEEDS_LICENSE_KEY { app.PageRouter.NavigateTo(page.LICENSE_KEY) app.state = NEEDS_LICENSE_KEY @@ -242,14 +250,6 @@ func (app *Application) checkState() { app.PageRouter.NavigateTo(page.HOME) } -func (app *Application) refreshCache() { - var freshConfig db.AppConfig - if result := app.DB.First(&freshConfig); result.Error != nil { - logger.Error("failed to fetch configuration from the database: %v", result.Error) - } - app.Config.Store(&freshConfig) -} - func (app *Application) initializeSDLAndOpenGL() (W, H int32) { logger.Info("Initializing SDL") if err := sdl.Init(sdl.INIT_VIDEO | sdl.INIT_AUDIO); err != nil { @@ -324,29 +324,38 @@ func (app *Application) initializeSDLAndOpenGL() (W, H int32) { func (app *Application) initializeManagers() { logger.Info("Initializing ShaderManager") - shaderDir := filepath.Join(app.Config.Load().AssetsDir, "shaders") + config, err := db.GetConfig(app.DB) + if err != nil { + panic(err) + } + shaderDir := filepath.Join(config.AssetsDir, "shaders") logger.Info("Loading shaders from %s", shaderDir) if err := shaderManager.InitShaderManager(shaderDir); err != nil { logger.Fatal("ShaderManager initialization failed: %v", err) } logger.Info("Initializing FontManager") - if err := fontManager.InitFontManager(app.Config.Load()); err != nil { + if err := fontManager.InitFontManager(config); err != nil { logger.Fatal("FontManager initialization failed: %v", err) } } func (app *Application) initializeAudio() { logger.Info("Initializing audio") - - if err := mixer.Init(app.Config.Load(), app.refreshCache); err != nil { - logger.Error("Unable to initialize audio device '%s': %v", app.Config.Load().SelectedAudioDevice, err) + config, err := db.GetConfig(app.DB) + if err != nil { + panic(err) + } + if err := mixer.Init(config, app.refreshCache); err != nil { + logger.Error("Unable to initialize audio device '%s': %v", config.SelectedAudioDevice, err) logger.Error("Audio will be unavailable until a device is configured") } else { - logger.Info("Audio initialized with device: '%s'", app.Config.Load().SelectedAudioDevice) + logger.Info("Audio initialized with device: '%s'", config.SelectedAudioDevice) } } +func (app *Application) refreshCache() {} + func (app *Application) cleanup() { logger.Info("Cleaning up") diff --git a/internal/fontManager/fontManager.go b/internal/fontManager/fontManager.go index 99358a5..20e0096 100644 --- a/internal/fontManager/fontManager.go +++ b/internal/fontManager/fontManager.go @@ -57,7 +57,7 @@ func InitFontManager(cfg *db.AppConfig) error { // --- NEW: Create the scrambled font after loading normal fonts --- // We will use "DejaVuSans" as the base. If you use a different default font, // change this string. - baseFontForScramble := "Roboto-Regular" + baseFontForScramble := "SpaceMonoNerdFont-Regular" if _, ok := fm.Fonts[baseFontForScramble]; ok { if err := fm.CreateScrambledFont(baseFontForScramble, "Scrambled"); err != nil { // This is not a fatal error for the whole application, so we just log it. @@ -506,26 +506,27 @@ func (fm *FontManager) createFontMap(font *FontEntry, scramble bool, baseFont *F 126, // ~ // Common Unicode punctuation - 161, // ¡ - 191, // ¿ - 8211, // – - 8212, // — - 8216, // ‘ - 8217, // ’ - 8220, // “ - 8221, // ” - 8226, // • - 8230, // … - 8240, // ‰ - 8364, // € - 162, // ¢ - 163, // £ - 165, // ¥ - 169, // © - 174, // ® - 8482, // ™ - 232, // è - 233, // é + 161, // ¡ + 191, // ¿ + 8211, // – + 8212, // — + 8216, // ‘ + 8217, // ’ + 8220, // “ + 8221, // ” + 8226, // • + 8230, // … + 8240, // ‰ + 8364, // € + 162, // ¢ + 163, // £ + 165, // ¥ + 169, // © + 174, // ® + 8482, // ™ + 232, // è + 233, // é + 10003, // checkmark } tempGlyphs := make([]TempGlyph, 0, len(chars)) var totalWidth, maxHeight int32 diff --git a/internal/mixer/mixer.go b/internal/mixer/mixer.go index 8977c00..e3a0cb9 100644 --- a/internal/mixer/mixer.go +++ b/internal/mixer/mixer.go @@ -70,7 +70,7 @@ func Init(cfg *db.AppConfig, onUpdate func()) error { return err } - SetAllSinkVolumes(1.0) + SetAllSinkVolumes(0.20) inited = true return nil diff --git a/internal/page/AudioOptions.go b/internal/page/AudioOptions.go index a59e7a2..acb6a4d 100644 --- a/internal/page/AudioOptions.go +++ b/internal/page/AudioOptions.go @@ -100,7 +100,7 @@ func (p *AudioOptions) Init(ctx *PageCtx) error { // Font fm := fontManager.Get() - font, ok := fm.GetFont("Roboto-Regular") + font, ok := fm.GetFont("SpaceMonoNerdFont-Regular") if !ok { return fmt.Errorf("failed to get font: %w", sdl.GetError()) } @@ -121,7 +121,12 @@ func (p *AudioOptions) Init(ctx *PageCtx) error { return fmt.Errorf("base init failed: %w", err) } - baseFontSize := p.Context.CfgPtr.StandardFontSize + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + + baseFontSize := config.StandardFontSize titleScale := float32(64) / float32(baseFontSize) p.ItemScale = float32(32) / float32(baseFontSize) @@ -211,7 +216,11 @@ func (p *AudioOptions) seedAudioFiles() error { // ── Audio status toggle ─────────────────────────────────────────────────────── func (p *AudioOptions) CreateAudioStatusItem() error { - on := p.Context.CfgPtr.AudioEnabled + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + on := config.AudioEnabled statusString := "Turn Audio On" color := colors.Green if on { @@ -277,7 +286,11 @@ func (p *AudioOptions) CreateVolumePercentItem() error { if p.volumePercent.ID != 0 { gl.DeleteTextures(1, &p.volumePercent.ID) } - pct := int(p.Context.CfgPtr.SavedVolume * 100) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + pct := int(config.SavedVolume * 100) item, err := NewStringItem(fmt.Sprintf("%d%%", pct), p.font, colors.White) if err != nil { return fmt.Errorf("failed to create volume percent item: %v", err) @@ -288,15 +301,19 @@ func (p *AudioOptions) CreateVolumePercentItem() error { } func (p *AudioOptions) UpdateVolume(level int) { - newVol := mixer.ConvertVolume(level) + p.Context.CfgPtr.SavedVolume + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + newVol := mixer.ConvertVolume(level) + config.SavedVolume if newVol < 0.0 || newVol > 1.0 { return } if newVol > .99 { newVol = 1.0 } - p.Context.CfgPtr.SavedVolume = newVol - p.Context.DbPtr.Save(&p.Context.CfgPtr) + config.SavedVolume = newVol + p.Context.DbPtr.Save(&config) if err := mixer.SetAllSinkVolumes(newVol); err != nil { logger.Error("Error setting allSinkVolumes: %v", err) } @@ -311,6 +328,11 @@ func (p *AudioOptions) UpdateVolume(level int) { // ── Layout ──────────────────────────────────────────────────────────────────── func (p *AudioOptions) layout() { + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + // Title p.title.X = p.ScreenCenterX - p.title.W/2 p.title.Y = p.ScreenHeight - p.title.H - p.verticalMargin*2 @@ -320,7 +342,7 @@ func (p *AudioOptions) layout() { p.prompt.Y = p.title.Y - p.verticalMargin - p.prompt.H // Volume row - barH := int32(float32(p.Context.CfgPtr.StandardFontSize) * p.ItemScale) + barH := int32(float32(config.StandardFontSize) * p.ItemScale) barW := int32(float32(p.ScreenWidth) * 0.30) barX := p.ScreenCenterX - barW/2 barY := p.prompt.Y - p.verticalMargin*2 - barH @@ -376,8 +398,12 @@ func (p *AudioOptions) updateCursorPosition() { // ── Toggle ──────────────────────────────────────────────────────────────────── func (p *AudioOptions) ToggleAudio() { - p.Context.CfgPtr.AudioEnabled = !p.Context.CfgPtr.AudioEnabled - p.Context.DbPtr.Save(p.Context.CfgPtr) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + config.AudioEnabled = !config.AudioEnabled + p.Context.DbPtr.Save(config) p.Context.RefreshConfig() p.CreateAudioStatusItem() p.layout() @@ -447,7 +473,11 @@ func (p *AudioOptions) Update(dt float32) error { // ── Render helpers ──────────────────────────────────────────────────────────── func (p *AudioOptions) renderVolumeBar() error { - vol := p.Context.CfgPtr.SavedVolume + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + vol := config.SavedVolume fillW := float32(p.volumeBarW) * float32(vol) if fillW > 0 { diff --git a/internal/page/emailAddressPage.go b/internal/page/emailAddressPage.go index 3465c09..14b274c 100644 --- a/internal/page/emailAddressPage.go +++ b/internal/page/emailAddressPage.go @@ -8,6 +8,7 @@ import ( "github.com/go-gl/mathgl/mgl32" "github.com/veandco/go-sdl2/sdl" "rhemawavetech.com/rhemawave/internal/colors" + "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/shaderManager" ) @@ -59,7 +60,7 @@ func (p *EmailAddressPage) Init(ctx *PageCtx) error { p.title = "Your Email Address" - applicationFont := "Roboto-Regular" + applicationFont := "SpaceMonoNerdFont-Regular" fm := fontManager.Get() textShader, ok := shaderManager.Get().Get("text") @@ -81,7 +82,11 @@ func (p *EmailAddressPage) Init(ctx *PageCtx) error { p.titleTextureHeight = titleHeight // Load existing email address from database - emailAddress := ctx.CfgPtr.EmailAddress + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + emailAddress := config.EmailAddress if emailAddress != "" { p.inputText = emailAddress @@ -154,9 +159,12 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error { sdl.StopTextInput() // Save email address to database - p.Context.CfgPtr.EmailAddress = p.inputText - p.Context.DbPtr.Save(p.Context.CfgPtr) - p.Context.RefreshConfig() + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + config.EmailAddress = p.inputText + p.Context.DbPtr.Save(config) if p.isFirstTimeSetup { // First-time setup: navigate to License Key page @@ -189,7 +197,7 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error { // Update updates animations and changing textures and other changes using `dt` which represents a time delta in float32. func (p *EmailAddressPage) Update(dt float32) error { // Get application font from database - applicationFont := "Roboto-Regular" + applicationFont := "SpaceMonoNerdFont-Regular" fm := fontManager.Get() sm := shaderManager.Get() @@ -252,8 +260,12 @@ func (p *EmailAddressPage) Update(dt float32) error { // Render performs page drawing logic. func (p *EmailAddressPage) Render() error { + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } // Get base font size from database - baseFontSize := p.Context.CfgPtr.StandardFontSize + baseFontSize := config.StandardFontSize sm := shaderManager.Get() diff --git a/internal/page/home.go b/internal/page/home.go index cf0c891..699a9f2 100644 --- a/internal/page/home.go +++ b/internal/page/home.go @@ -7,6 +7,7 @@ import ( "github.com/go-gl/mathgl/mgl32" "github.com/veandco/go-sdl2/sdl" "rhemawavetech.com/rhemawave/internal/colors" + "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/download" "rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/shaderManager" @@ -45,7 +46,7 @@ func (p *Home) Init(ctx *PageCtx) error { // Get font p.fm = fontManager.Get() - font, ok := p.fm.GetFont("Roboto-Regular") + font, ok := p.fm.GetFont("SpaceMonoNerdFont-Regular") if !ok { return fmt.Errorf("unable to fetch font") } @@ -86,8 +87,13 @@ func (p *Home) Init(ctx *PageCtx) error { return fmt.Errorf("unable to create initial message texture: %w", err) } + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + // Create license info textures if data exists - if p.Context.CfgPtr.EmailAddress != "" || p.Context.CfgPtr.LicenseKey != "" { + if config.EmailAddress != "" || config.LicenseKey != "" { p.hasLicenseInfo = true // Create heading @@ -97,8 +103,8 @@ func (p *Home) Init(ctx *PageCtx) error { } // Create email display if exists - if p.Context.CfgPtr.EmailAddress != "" { - emailText := fmt.Sprintf("Email: %s", p.Context.CfgPtr.EmailAddress) + if config.EmailAddress != "" { + emailText := fmt.Sprintf("Email: %s", config.EmailAddress) p.emailDisplay, err = NewStringItem(emailText, font, colors.White) if err != nil { return fmt.Errorf("unable to create email display texture: %w", err) @@ -106,8 +112,8 @@ func (p *Home) Init(ctx *PageCtx) error { } // Create license key display if exists - if p.Context.CfgPtr.LicenseKey != "" { - licenseKeyText := fmt.Sprintf("License Key: %s", p.Context.CfgPtr.LicenseKey) + if config.LicenseKey != "" { + licenseKeyText := fmt.Sprintf("License Key: %s", config.LicenseKey) p.licenseKeyDisplay, err = NewStringItem(licenseKeyText, font, colors.White) if err != nil { return fmt.Errorf("unable to create license key display texture: %w", err) @@ -116,7 +122,7 @@ func (p *Home) Init(ctx *PageCtx) error { } // Get base font size from database - baseFontSize := p.Context.CfgPtr.StandardFontSize + baseFontSize := config.StandardFontSize p.baseFontSize = baseFontSize // Scale the note text diff --git a/internal/page/licenseKeyPage.go b/internal/page/licenseKeyPage.go index d971d47..675354e 100644 --- a/internal/page/licenseKeyPage.go +++ b/internal/page/licenseKeyPage.go @@ -10,6 +10,7 @@ import ( "github.com/go-gl/mathgl/mgl32" "github.com/veandco/go-sdl2/sdl" "rhemawavetech.com/rhemawave/internal/colors" + "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/logger" "rhemawavetech.com/rhemawave/internal/shaderManager" @@ -55,7 +56,7 @@ func (p *LicenseKeyPage) Init(ctx *PageCtx) error { p.title = "License Key" // Get application font from database - applicationFont := "Roboto-Regular" + applicationFont := "SpaceMonoNerdFont-Regular" fm := fontManager.Get() textShader, ok := shaderManager.Get().Get("text") @@ -77,7 +78,11 @@ func (p *LicenseKeyPage) Init(ctx *PageCtx) error { p.titleTextureHeight = titleHeight // Load existing license key from database - licenseKey := p.Context.CfgPtr.LicenseKey + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + licenseKey := config.LicenseKey if licenseKey != "" { p.inputText = licenseKey @@ -188,9 +193,12 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error { sdl.StopTextInput() // Save license key to database - p.Context.CfgPtr.LicenseKey = p.inputText - p.Context.DbPtr.Save(p.Context.CfgPtr) - p.Context.RefreshConfig() + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + config.LicenseKey = p.inputText + p.Context.DbPtr.Save(config) // Write license key to plain text file for the updater if homeDir, err := os.UserHomeDir(); err == nil { @@ -239,7 +247,7 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error { // Update updates animations and changing textures and other changes using `dt` which represents a time delta in float32. func (p *LicenseKeyPage) Update(dt float32) error { // Get application font from database - applicationFont := "Roboto-Regular" + applicationFont := "SpaceMonoNerdFont-Regular" fm := fontManager.Get() sm := shaderManager.Get() @@ -302,8 +310,12 @@ func (p *LicenseKeyPage) Update(dt float32) error { // Render performs page drawing logic. func (p *LicenseKeyPage) Render() error { + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } // Get base font size from database - baseFontSize := p.Context.CfgPtr.StandardFontSize + baseFontSize := config.StandardFontSize sm := shaderManager.Get() diff --git a/internal/page/logViewerPage.go b/internal/page/logViewerPage.go index b59963f..4f367ac 100644 --- a/internal/page/logViewerPage.go +++ b/internal/page/logViewerPage.go @@ -79,7 +79,7 @@ func (p *LogViewerPage) Init(ctx *PageCtx) error { p.lineColors = append(p.lineColors, color) } - applicationFont := "Roboto-Regular" + applicationFont := "SpaceMonoNerdFont-Regular" fm := fontManager.Get() textShader, ok := shaderManager.Get().Get("text") @@ -177,7 +177,11 @@ func (p *LogViewerPage) Update(dt float32) error { } func (p *LogViewerPage) Render() error { - baseFontSize := p.Context.CfgPtr.StandardFontSize + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + baseFontSize := config.StandardFontSize sm := shaderManager.Get() textShader, _ := sm.Get("text") diff --git a/internal/page/proclamationOptions.go b/internal/page/proclamationOptions.go index 941a6a8..c0ac305 100644 --- a/internal/page/proclamationOptions.go +++ b/internal/page/proclamationOptions.go @@ -105,7 +105,7 @@ func (p *ProclamationOptions) Init(ctx *PageCtx) error { sync.SyncFrequencies(ctx.DbPtr) fm := fontManager.Get() - font, _ := fm.GetFont("Roboto-Regular") + font, _ := fm.GetFont("SpaceMonoNerdFont-Regular") p.font = font sm := shaderManager.Get() @@ -114,9 +114,14 @@ func (p *ProclamationOptions) Init(ctx *PageCtx) error { p.Base.Init(ctx) - itemScale := float32(32) / float32(ctx.CfgPtr.StandardFontSize) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + + itemScale := float32(32) / float32(config.StandardFontSize) p.title, _ = NewStringItem("Proclamation Browser", p.font, colors.White) - p.title.Scale(float32(64) / float32(ctx.CfgPtr.StandardFontSize)) + p.title.Scale(float32(64) / float32(config.StandardFontSize)) p.prompt, _ = NewStringItem("Type to Search Space to Select Enter to Save Escape to Exit", p.font, colors.White) p.prompt.Scale(itemScale * 0.8) @@ -183,7 +188,11 @@ func (p *ProclamationOptions) createFlatItem(name, id string, isCat bool, depth if isCat && depth == 0 { text = "[+] " + name } - itemScale := float32(32) / float32(p.Context.CfgPtr.StandardFontSize) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + itemScale := float32(32) / float32(config.StandardFontSize) lbl, _ := NewStringItem(text, p.font, colors.White) lbl.Scale(itemScale) return &FlatItem{ @@ -277,7 +286,12 @@ func (p *ProclamationOptions) toggleExpansion(index int) { pureName := item.Label.content[4:] gl.DeleteTextures(1, &item.Label.ID) - itemScale := float32(32) / float32(p.Context.CfgPtr.StandardFontSize) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + + itemScale := float32(32) / float32(config.StandardFontSize) if item.Expanded { p.collapse(index) item.Label, _ = NewStringItem("[+] "+pureName, p.font, colors.White) @@ -401,7 +415,11 @@ func (p *ProclamationOptions) rebuildSearchLabel() { if p.searchQuery == "" { return } - itemScale := float32(32) / float32(p.Context.CfgPtr.StandardFontSize) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + itemScale := float32(32) / float32(config.StandardFontSize) p.searchInput, _ = NewStringItem("Search: "+p.searchQuery, p.font, colors.Yellow) p.searchInput.Scale(itemScale * 1.1) } diff --git a/internal/page/router.go b/internal/page/router.go index eb8dda8..75dd312 100644 --- a/internal/page/router.go +++ b/internal/page/router.go @@ -2,7 +2,6 @@ package page import ( "gorm.io/gorm" - "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/download" ) @@ -23,7 +22,6 @@ const ( ) type PageCtx struct { - CfgPtr *db.AppConfig DbPtr *gorm.DB W, H int32 MessageChannel chan download.DownloadStatus diff --git a/internal/page/scrollerPage.go b/internal/page/scrollerPage.go index 35a79ef..157ce5b 100644 --- a/internal/page/scrollerPage.go +++ b/internal/page/scrollerPage.go @@ -220,8 +220,11 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error { } // Get line pattern from database - var err error - linePatternName := p.Context.CfgPtr.LinePattern + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + linePatternName := config.LinePattern p.activePattern, err = linePattern.Get(linePatternName) if err != nil { @@ -241,7 +244,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error { p.colorPattern = colorPattern.NewColorPattern(baseColors) // Font setup - p.fontScale = float32(32) / float32(p.Context.CfgPtr.StandardFontSize) + p.fontScale = float32(32) / float32(config.StandardFontSize) nLines := int(float32(p.ScreenHeight) / 32.0) p.lines = NewLineDeque(nLines * 2) @@ -288,14 +291,14 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error { if err := p.Context.DbPtr.Where("Selected = ?", true).First(&selectedAudio).Error; err != nil { selectedAudio = db.AudioFile{ Name: "OriginalAudio", - Path: filepath.Join(p.Context.CfgPtr.AssetsDir, "audio", "OriginalAudio.wav"), + Path: filepath.Join(config.AssetsDir, "audio", "OriginalAudio.wav"), Selected: true, Order: 0, } } logger.Info("Playing %s", selectedAudio.Path) - if err := mixer.Play(selectedAudio.Path, true, p.Context.CfgPtr); err != nil { + if err := mixer.Play(selectedAudio.Path, true, config); err != nil { logger.Error("Mixer returned an error: %v", err) } } @@ -420,7 +423,11 @@ func (p *ScrollerPage) loadProclamations() error { // audioPathForFrequency builds the on-disk path for a solfeggio frequency's // audio file, e.g. 396 -> "/audio/396Hz.wav". func (p *ScrollerPage) audioPathForFrequency(freq int) string { - return filepath.Join(p.Context.CfgPtr.AssetsDir, "audio", fmt.Sprintf("%dHz.wav", freq)) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + return filepath.Join(config.AssetsDir, "audio", fmt.Sprintf("%dHz.wav", freq)) } // switchAudioForFrequency swaps the currently playing track to match freq. @@ -449,9 +456,12 @@ func (p *ScrollerPage) switchAudioForFrequency(freq int) bool { logger.Warning("No audio file for %dHz (%s), keeping current track", freq, path) return false } - - mixer.Stop(3000, p.Context.CfgPtr) - if err := mixer.Play(path, true, p.Context.CfgPtr); err != nil { + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + mixer.Stop(3000, config) + if err := mixer.Play(path, true, config); err != nil { logger.Error("Mixer returned an error: %v", err) return false } @@ -722,7 +732,12 @@ func (p *ScrollerPage) Destroy() error { return nil } - mixer.Stop(3000, p.Context.CfgPtr) + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + + mixer.Stop(3000, config) // Delete each cached word texture exactly once. for k, item := range p.wordTextureCache { diff --git a/internal/page/settingsPage.go b/internal/page/settingsPage.go index 23cee0a..93eb689 100644 --- a/internal/page/settingsPage.go +++ b/internal/page/settingsPage.go @@ -6,6 +6,7 @@ import ( "github.com/go-gl/gl/v3.3-core/gl" "github.com/veandco/go-sdl2/sdl" "rhemawavetech.com/rhemawave/internal/colors" + "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/shaderManager" ) @@ -34,7 +35,7 @@ func (p *Settings) Init(ctx *PageCtx) error { // Get font fm := fontManager.Get() - font, ok := fm.GetFont("Roboto-Regular") + font, ok := fm.GetFont("SpaceMonoNerdFont-Regular") if !ok { return fmt.Errorf("failed to get font: %w", sdl.GetError()) } @@ -127,7 +128,11 @@ func (p *Settings) Init(ctx *PageCtx) error { // TODO: Add entry for "About" // Get base font size from database - baseFontSize := p.Context.CfgPtr.StandardFontSize + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + baseFontSize := config.StandardFontSize // Calculate scales titleScale := float32(64) / float32(baseFontSize) diff --git a/internal/page/wifiSetupPage.go b/internal/page/wifiSetupPage.go index a74118f..35f18cb 100644 --- a/internal/page/wifiSetupPage.go +++ b/internal/page/wifiSetupPage.go @@ -8,6 +8,7 @@ import ( "github.com/go-gl/mathgl/mgl32" "github.com/veandco/go-sdl2/sdl" "rhemawavetech.com/rhemawave/internal/colors" + "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/keybinds" "rhemawavetech.com/rhemawave/internal/logger" @@ -39,6 +40,7 @@ type WiFiSetupPage struct { applicationFont *fontManager.FontEntry // UI elements + BaseFontSize int titleItem StringItem scanningStatusItem StringItem connectionStatusItem StringItem @@ -75,9 +77,9 @@ func (p *WiFiSetupPage) Init(ctx *PageCtx) error { } fm := fontManager.Get() - font, ok := fm.GetFont("Roboto-Regular") + font, ok := fm.GetFont("SpaceMonoNerdFont-Regular") if !ok { - return fmt.Errorf("could not find application font: Roboto-Regular") + return fmt.Errorf("could not find application font: SpaceMonoNerdFont-Regular") } p.applicationFont = font @@ -92,6 +94,12 @@ func (p *WiFiSetupPage) Init(ctx *PageCtx) error { return fmt.Errorf("failed to create scanning status item: %w", err) } + config, err := db.GetConfig(p.Context.DbPtr) + if err != nil { + panic(err) + } + p.BaseFontSize = config.StandardFontSize + p.connectResultCh = make(chan error, 1) p.ctx, p.cancel = context.WithCancel(context.Background()) @@ -310,7 +318,20 @@ func (p *WiFiSetupPage) rebuildNetworkList(nets []network.Network) { label += " ★" } if n.Security != network.SecurityOpen { - label += " [" + string(n.Security) + "]" + var secStr string + switch n.Security { + case network.SecurityWEP: + secStr = "WEP" + case network.SecurityWPA: + secStr = "WPA" + case network.SecurityWPA2: + secStr = "WPA2" + case network.SecurityWPA3: + secStr = "WPA3" + default: + secStr = "Secured" + } + label += " [" + secStr + "]" } c := colors.White @@ -417,8 +438,6 @@ func (p *WiFiSetupPage) rebuildPasswordErrorTexture() { // ─── Render ─────────────────────────────────────────────────────────────────── func (p *WiFiSetupPage) Render() error { - baseFontSize := p.Context.CfgPtr.StandardFontSize - solidShader, _ := shaderManager.Get().Get("solid_color") textShader, _ := shaderManager.Get().Get("text") @@ -435,7 +454,7 @@ func (p *WiFiSetupPage) Render() error { ) // Title — 48pt - titleScale := float32(48) / float32(baseFontSize) + titleScale := float32(48) / float32(p.BaseFontSize) titleW := float32(p.titleItem.W) * titleScale titleH := float32(p.titleItem.H) * titleScale titleX := float32(p.ScreenCenterX) - titleW/2 @@ -449,7 +468,7 @@ func (p *WiFiSetupPage) Render() error { // Status message — 30pt (was 24pt, now 1.25x) statusY := titleY - titleH - vertMargin if p.status == wifiStatusScanning { - scale := float32(30) / float32(baseFontSize) + scale := float32(30) / float32(p.BaseFontSize) w := float32(p.scanningStatusItem.W) * scale h := float32(p.scanningStatusItem.H) * scale x := float32(p.ScreenCenterX) - w/2 @@ -459,7 +478,7 @@ func (p *WiFiSetupPage) Render() error { white, ) } else if p.connectionStatusItem.ID != 0 { - scale := float32(30) / float32(baseFontSize) + scale := float32(30) / float32(p.BaseFontSize) w := float32(p.connectionStatusItem.W) * scale h := float32(p.connectionStatusItem.H) * scale x := float32(p.ScreenCenterX) - w/2 @@ -488,7 +507,7 @@ func (p *WiFiSetupPage) Render() error { ) } - scale := float32(24) / float32(baseFontSize) + scale := float32(24) / float32(p.BaseFontSize) tw := float32(item.Item.W) * scale th := float32(item.Item.H) * scale tx := listX + float32(listPad) @@ -502,7 +521,7 @@ func (p *WiFiSetupPage) Render() error { // Password dialog if p.isEnteringPassword { - if err := p.renderPasswordDialog(solidShader, textShader, float32(baseFontSize)); err != nil { + if err := p.renderPasswordDialog(solidShader, textShader, float32(p.BaseFontSize)); err != nil { return err } } diff --git a/share/rhemawave/fonts/SpaceMonoNerdFont-Regular.ttf b/share/rhemawave/fonts/SpaceMonoNerdFont-Regular.ttf new file mode 100644 index 0000000..de3d014 Binary files /dev/null and b/share/rhemawave/fonts/SpaceMonoNerdFont-Regular.ttf differ