fix: load FA locally instead of CDN; Alpine color input error via x-init+
This commit is contained in:
parent
44ad064488
commit
fe8ca312c4
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
12
gesture.go
12
gesture.go
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
22
page.go
22
page.go
@ -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: {},
|
||||||
|
|||||||
9
static/fontawesome/css/all.min.css
vendored
Normal file
9
static/fontawesome/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
static/fontawesome/webfonts/fa-brands-400.ttf
Normal file
BIN
static/fontawesome/webfonts/fa-brands-400.ttf
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-brands-400.woff2
Normal file
BIN
static/fontawesome/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-regular-400.ttf
Normal file
BIN
static/fontawesome/webfonts/fa-regular-400.ttf
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-regular-400.woff2
Normal file
BIN
static/fontawesome/webfonts/fa-regular-400.woff2
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-solid-900.ttf
Normal file
BIN
static/fontawesome/webfonts/fa-solid-900.ttf
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-solid-900.woff2
Normal file
BIN
static/fontawesome/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-v4compatibility.ttf
Normal file
BIN
static/fontawesome/webfonts/fa-v4compatibility.ttf
Normal file
Binary file not shown.
BIN
static/fontawesome/webfonts/fa-v4compatibility.woff2
Normal file
BIN
static/fontawesome/webfonts/fa-v4compatibility.woff2
Normal file
Binary file not shown.
@ -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"
|
||||||
|
|||||||
31
web.go
31
web.go
@ -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 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user