Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions frontend/src/SettingsWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function SettingsWindow() {
const [watchFolder, setWatchFolder] = useState("");
const [exportFolder, setExportFolder] = useState("");
const [jpegQuality, setJpegQuality] = useState("auto");
const [enableBetaUpdates, setEnableBetaUpdates] = useState<boolean>(false);

// Frame Settings
const [aspectRatioPreset, setAspectRatioPreset] = useState<string>("4300:3618");
Expand Down Expand Up @@ -46,6 +47,7 @@ function SettingsWindow() {
setWatchFolder(s.watchFolder || "");
setExportFolder(s.exportFolder || "");
setJpegQuality(s.jpegQuality || "auto");
setEnableBetaUpdates(s.enableBetaUpdates ?? false);

setAspectRatioPreset(s.aspectRatioPreset || "4300:3618");
setCustomRatioW(s.customRatioW || 4300);
Expand Down Expand Up @@ -102,6 +104,7 @@ function SettingsWindow() {
s.watchFolder = watchFolder;
s.exportFolder = exportFolder;
s.jpegQuality = jpegQuality;
s.enableBetaUpdates = enableBetaUpdates;
s.aspectRatioPreset = aspectRatioPreset;
s.customRatioW = customRatioW;
s.customRatioH = customRatioH;
Expand Down Expand Up @@ -222,6 +225,18 @@ function SettingsWindow() {
</select>
<small style={{ display: 'block', marginTop: '0.5rem', color: 'var(--text-secondary)', textAlign: 'left' }}>Auto calculates the optimal quality based on the original image compression to prevent file size bloat.</small>
</div>
<div className="input-group">
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', cursor: 'pointer', fontWeight: 'normal', margin: 0, color: 'var(--text-primary)', fontSize: '0.85rem' }}>
<input
type="checkbox"
checked={enableBetaUpdates}
onChange={(e) => setEnableBetaUpdates(e.target.checked)}
style={{ margin: 0, width: 'auto', height: 'auto', cursor: 'pointer' }}
/>
Receive Beta Updates
</label>
<small style={{ display: 'block', marginTop: '0.5rem', marginLeft: '1.5rem', color: 'var(--text-secondary)', textAlign: 'left' }}>Receive pre-release (beta) versions of ExifFrame automatically.</small>
</div>
</div>
)}
{activeTab === 'frame' && (
Expand Down
4 changes: 4 additions & 0 deletions settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ type Settings struct {
VisibilityDilution bool `json:"visibilityDilution"`
VisibilityTemperature bool `json:"visibilityTemperature"`
VisibilityTime bool `json:"visibilityTime"`

// Updater settings
EnableBetaUpdates bool `json:"enableBetaUpdates"`
}

var (
Expand Down Expand Up @@ -97,6 +100,7 @@ func init() {
VisibilityDilution: true,
VisibilityTemperature: true,
VisibilityTime: true,
EnableBetaUpdates: false,
}
loadSettings()
}
Expand Down
57 changes: 52 additions & 5 deletions updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"io"
"log"
"strings"
"time"
Expand All @@ -17,27 +18,73 @@ const (
updateCheckInterval = 4 * time.Hour
)

// dynamicGithubProvider routes updater requests to either a stable or beta
// GitHub provider depending on the user's settings.
type dynamicGithubProvider struct {
updater.Provider // Embedded default provider for future-proofing interface additions
betaProvider updater.Provider
}

// We let the embedded Provider handle Name(), which will correctly return "github"
// or whatever the underlying github provider returns.

func (p *dynamicGithubProvider) Check(ctx context.Context, req updater.CheckRequest) (*updater.Release, error) {
settingsMu.RLock()
betaEnabled := currentSettings.EnableBetaUpdates
settingsMu.RUnlock()

if betaEnabled {
return p.betaProvider.Check(ctx, req)
}
return p.Provider.Check(ctx, req)
}

func (p *dynamicGithubProvider) Download(ctx context.Context, r *updater.Release, dst io.Writer, onProgress func(written, total int64)) error {
settingsMu.RLock()
betaEnabled := currentSettings.EnableBetaUpdates
settingsMu.RUnlock()

if betaEnabled {
return p.betaProvider.Download(ctx, r, dst, onProgress)
}
return p.Provider.Download(ctx, r, dst, onProgress)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

// InitUpdater initialises the Wails v3 built-in updater on the given app
// instance. It configures a GitHub provider pointed at the ExifFrame
// repository and enables periodic background checks.
func InitUpdater(app *application.App) {
ghProvider, err := github.New(github.Config{
stableProvider, err := github.New(github.Config{
Repository: updateOwner + "/" + updateRepo,
ChecksumAsset: "SHA256SUMS",
Prerelease: false,
})
if err != nil {
log.Printf("GitHub stable provider creation failed: %v", err)
return
}

betaProvider, err := github.New(github.Config{
Repository: updateOwner + "/" + updateRepo,
ChecksumAsset: "SHA256SUMS",
Prerelease: true,
})
if err != nil {
// Non-fatal: if the provider can't be constructed the app still works,
// just without auto-update.
log.Printf("GitHub provider creation failed: %v", err)
log.Printf("GitHub beta provider creation failed: %v", err)
return
}

dynProvider := &dynamicGithubProvider{
Provider: stableProvider,
betaProvider: betaProvider,
}

// The Wails updater expects versions without the "v" prefix.
ver := strings.TrimPrefix(Version, "v")

err = app.Updater.Init(updater.Config{
CurrentVersion: ver,
Providers: []updater.Provider{ghProvider},
Providers: []updater.Provider{dynProvider},
CheckInterval: updateCheckInterval,
})
if err != nil {
Expand Down
Loading