fix: load FA locally instead of CDN; Alpine color input error via x-init+

This commit is contained in:
Maksim Totmin
2026-06-17 13:53:48 +07:00
parent a093719bd1
commit 84038b5be2
15 changed files with 71 additions and 16 deletions
+3 -1
View File
@@ -101,7 +101,7 @@ func Run(ctx context.Context, cfg *config.Config, opts RunOptions) error {
ssCtrl := NewScreensaver(&cfg.Screensaver)
ge := NewGestureEngine(cfg.Timing.LongPressMs, cfg.Timing.DoubleTapMs, func(a *config.Action) {
ge := NewGestureEngine(cfg.Timing.LongPressMs, cfg.Timing.DoubleTapMs, func(idx int, a *config.Action) {
if a == nil {
return
}
@@ -119,6 +119,8 @@ func Run(ctx context.Context, cfg *config.Config, opts RunOptions) error {
pm.startPeriodicKeys()
}
web.BroadcastPageChange(newPage)
} else {
primaryPM.RefreshDisplayKey(idx)
}
})
+6 -6
View File
@@ -7,7 +7,7 @@ import (
"streamdeck-lets-go/internal/config"
)
type ActionCallback func(a *config.Action)
type ActionCallback func(idx int, a *config.Action)
type gestureKeyState struct {
mu sync.Mutex
@@ -122,9 +122,9 @@ func (ge *GestureEngine) handleKeyPress(state *gestureKeyState, evt Event, actio
state.mu.Unlock()
if a := findAction(actions, "hold_start"); a != nil {
ge.onAction(a)
ge.onAction(evt.Index, a)
} else if a := findAction(actions, "long_press"); a != nil {
ge.onAction(a)
ge.onAction(evt.Index, a)
}
})
state.mu.Unlock()
@@ -138,7 +138,7 @@ func (ge *GestureEngine) handleKeyRelease(state *gestureKeyState, evt Event, act
state.holdActive = false
state.mu.Unlock()
if a := findAction(actions, "hold_end"); a != nil {
ge.onAction(a)
ge.onAction(evt.Index, a)
}
return
}
@@ -147,7 +147,7 @@ func (ge *GestureEngine) handleKeyRelease(state *gestureKeyState, evt Event, act
state.lastTapAt = time.Time{}
state.mu.Unlock()
if a := findAction(actions, "double_tap"); a != nil {
ge.onAction(a)
ge.onAction(evt.Index, a)
}
return
}
@@ -162,7 +162,7 @@ func (ge *GestureEngine) handleKeyRelease(state *gestureKeyState, evt Event, act
state.pendingTap = nil
state.mu.Unlock()
if a := findAction(actions, "tap"); a != nil {
ge.onAction(a)
ge.onAction(evt.Index, a)
}
return
}
+22
View File
@@ -490,6 +490,28 @@ func (pm *PageManager) renderKeyOutput(idx int, d *config.DisplayCfg, output str
}
}
func (pm *PageManager) RefreshDisplayKey(idx int) {
pm.mu.RLock()
page := pm.pages[pm.active]
pm.mu.RUnlock()
if page == nil {
return
}
for _, k := range page.Keys {
if k.Index == idx && k.Display != nil {
timeout := 30 * time.Second
if k.Display.Timeout != "" {
if t, err := time.ParseDuration(k.Display.Timeout); err == nil && t > 0 {
timeout = t
}
}
output, err := execDisplayCapture(k.Display, timeout)
pm.renderKeyOutput(idx, k.Display, output, err)
return
}
}
}
var (
unicodeFontOnce sync.Once
unicodeFontData []byte
+1
View File
@@ -15,6 +15,7 @@ document.addEventListener('alpine:init', () => {
// ── Edit state ──
editing: null,
editForm: {
bg_color: '',
actions: {
tap: {},
long_press: {},
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -3
View File
@@ -6,7 +6,7 @@
<title>StreamDeck</title>
<script src="/static/app.js"></script>
<script defer src="/static/alpine.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/static/styles.css">
</head>
<body>
@@ -505,8 +505,8 @@
<div class="form-group">
<label>Background</label>
<div style="display:flex;gap:8px;align-items:center;">
<input type="color" :value="editForm.bg_color || '#000000'"
@input="editForm.bg_color = $event.target.value"
<input type="color"
x-init="$el.value = editForm.bg_color || '#000000'; $el.addEventListener('input', () => editForm.bg_color = $el.value); $watch('editForm.bg_color', v => $el.value = v || '#000000')"
style="width:40px;height:40px;padding:2px;border-radius:var(--radius-xs);cursor:pointer;">
<input type="text" x-model="editForm.bg_color"
placeholder="#rrggbb or #rrggbbaa" maxlength="9"
+27 -6
View File
@@ -459,6 +459,16 @@ func backupOldConfig(path string) {
}
}
func collectIcons(cfg *config.Config, used map[string]bool) {
for _, p := range cfg.Pages {
for _, k := range p.Keys {
if k.Icon != "" {
used[k.Icon] = true
}
}
}
}
func gcImages(cfg *config.Config) {
imgDir := filepath.Join(configDir(), "images")
entries, err := os.ReadDir(imgDir)
@@ -466,13 +476,24 @@ func gcImages(cfg *config.Config) {
return
}
used := make(map[string]bool, len(entries))
for _, p := range cfg.Pages {
for _, k := range p.Keys {
if k.Icon != "" {
used[k.Icon] = true
}
used := make(map[string]bool)
collectIcons(cfg, used)
backupDir := filepath.Join(configDir(), "backups")
backupEntries, _ := os.ReadDir(backupDir)
for _, be := range backupEntries {
if be.IsDir() {
continue
}
data, err := os.ReadFile(filepath.Join(backupDir, be.Name()))
if err != nil {
continue
}
var backupCfg config.Config
if err := json.Unmarshal(data, &backupCfg); err != nil {
continue
}
collectIcons(&backupCfg, used)
}
for _, e := range entries {