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)
|
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 {
|
if a == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -119,6 +119,8 @@ func Run(ctx context.Context, cfg *config.Config, opts RunOptions) error {
|
|||||||
pm.startPeriodicKeys()
|
pm.startPeriodicKeys()
|
||||||
}
|
}
|
||||||
web.BroadcastPageChange(newPage)
|
web.BroadcastPageChange(newPage)
|
||||||
|
} else {
|
||||||
|
primaryPM.RefreshDisplayKey(idx)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -7,7 +7,7 @@ import (
|
|||||||
"streamdeck-lets-go/internal/config"
|
"streamdeck-lets-go/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ActionCallback func(a *config.Action)
|
type ActionCallback func(idx int, a *config.Action)
|
||||||
|
|
||||||
type gestureKeyState struct {
|
type gestureKeyState struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -122,9 +122,9 @@ func (ge *GestureEngine) handleKeyPress(state *gestureKeyState, evt Event, actio
|
|||||||
state.mu.Unlock()
|
state.mu.Unlock()
|
||||||
|
|
||||||
if a := findAction(actions, "hold_start"); a != nil {
|
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 {
|
} else if a := findAction(actions, "long_press"); a != nil {
|
||||||
ge.onAction(a)
|
ge.onAction(evt.Index, a)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
state.mu.Unlock()
|
state.mu.Unlock()
|
||||||
@@ -138,7 +138,7 @@ func (ge *GestureEngine) handleKeyRelease(state *gestureKeyState, evt Event, act
|
|||||||
state.holdActive = false
|
state.holdActive = false
|
||||||
state.mu.Unlock()
|
state.mu.Unlock()
|
||||||
if a := findAction(actions, "hold_end"); a != nil {
|
if a := findAction(actions, "hold_end"); a != nil {
|
||||||
ge.onAction(a)
|
ge.onAction(evt.Index, a)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ func (ge *GestureEngine) handleKeyRelease(state *gestureKeyState, evt Event, act
|
|||||||
state.lastTapAt = time.Time{}
|
state.lastTapAt = time.Time{}
|
||||||
state.mu.Unlock()
|
state.mu.Unlock()
|
||||||
if a := findAction(actions, "double_tap"); a != nil {
|
if a := findAction(actions, "double_tap"); a != nil {
|
||||||
ge.onAction(a)
|
ge.onAction(evt.Index, a)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ func (ge *GestureEngine) handleKeyRelease(state *gestureKeyState, evt Event, act
|
|||||||
state.pendingTap = nil
|
state.pendingTap = nil
|
||||||
state.mu.Unlock()
|
state.mu.Unlock()
|
||||||
if a := findAction(actions, "tap"); a != nil {
|
if a := findAction(actions, "tap"); a != nil {
|
||||||
ge.onAction(a)
|
ge.onAction(evt.Index, a)
|
||||||
}
|
}
|
||||||
return
|
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 (
|
var (
|
||||||
unicodeFontOnce sync.Once
|
unicodeFontOnce sync.Once
|
||||||
unicodeFontData []byte
|
unicodeFontData []byte
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
// ── Edit state ──
|
// ── Edit state ──
|
||||||
editing: null,
|
editing: null,
|
||||||
editForm: {
|
editForm: {
|
||||||
|
bg_color: '',
|
||||||
actions: {
|
actions: {
|
||||||
tap: {},
|
tap: {},
|
||||||
long_press: {},
|
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>
|
<title>StreamDeck</title>
|
||||||
<script src="/static/app.js"></script>
|
<script src="/static/app.js"></script>
|
||||||
<script defer src="/static/alpine.min.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">
|
<link rel="stylesheet" href="/static/styles.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -505,8 +505,8 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Background</label>
|
<label>Background</label>
|
||||||
<div style="display:flex;gap:8px;align-items:center;">
|
<div style="display:flex;gap:8px;align-items:center;">
|
||||||
<input type="color" :value="editForm.bg_color || '#000000'"
|
<input type="color"
|
||||||
@input="editForm.bg_color = $event.target.value"
|
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;">
|
style="width:40px;height:40px;padding:2px;border-radius:var(--radius-xs);cursor:pointer;">
|
||||||
<input type="text" x-model="editForm.bg_color"
|
<input type="text" x-model="editForm.bg_color"
|
||||||
placeholder="#rrggbb or #rrggbbaa" maxlength="9"
|
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) {
|
func gcImages(cfg *config.Config) {
|
||||||
imgDir := filepath.Join(configDir(), "images")
|
imgDir := filepath.Join(configDir(), "images")
|
||||||
entries, err := os.ReadDir(imgDir)
|
entries, err := os.ReadDir(imgDir)
|
||||||
@@ -466,13 +476,24 @@ func gcImages(cfg *config.Config) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
used := make(map[string]bool, len(entries))
|
used := make(map[string]bool)
|
||||||
for _, p := range cfg.Pages {
|
collectIcons(cfg, used)
|
||||||
for _, k := range p.Keys {
|
|
||||||
if k.Icon != "" {
|
backupDir := filepath.Join(configDir(), "backups")
|
||||||
used[k.Icon] = true
|
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 {
|
for _, e := range entries {
|
||||||
|
|||||||
Reference in New Issue
Block a user