fix: load FA locally instead of CDN; Alpine color input error via x-init+
This commit is contained in:
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,6 +15,7 @@ document.addEventListener('alpine:init', () => {
|
||||
// ── Edit state ──
|
||||
editing: null,
|
||||
editForm: {
|
||||
bg_color: '',
|
||||
actions: {
|
||||
tap: {},
|
||||
long_press: {},
|
||||
|
||||
Vendored
+9
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
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user