mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-30 10:27:03 +08:00
Tiny UX improvements
This commit is contained in:
4
go.mod
4
go.mod
@@ -178,7 +178,7 @@ require (
|
|||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
lukechampine.com/blake3 v1.2.1 // indirect
|
lukechampine.com/blake3 v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -231,7 +231,7 @@ require (
|
|||||||
github.com/xaionaro-go/kickcom v0.0.0-20241022142825-25a234cc8628
|
github.com/xaionaro-go/kickcom v0.0.0-20241022142825-25a234cc8628
|
||||||
github.com/xaionaro-go/lockmap v0.0.0-20240901172806-e17aea364748
|
github.com/xaionaro-go/lockmap v0.0.0-20240901172806-e17aea364748
|
||||||
github.com/xaionaro-go/mediamtx v0.0.0-20241009124606-94c22c603970
|
github.com/xaionaro-go/mediamtx v0.0.0-20241009124606-94c22c603970
|
||||||
github.com/xaionaro-go/object v0.0.0-20241024025057-382352276e7b
|
github.com/xaionaro-go/object v0.0.0-20241026212449-753ce10ec94c
|
||||||
github.com/xaionaro-go/obs-grpc-proxy v0.0.0-20241018162120-5faf4e7a684a
|
github.com/xaionaro-go/obs-grpc-proxy v0.0.0-20241018162120-5faf4e7a684a
|
||||||
github.com/xaionaro-go/timeapiio v0.0.0-20240915203246-b907cf699af3
|
github.com/xaionaro-go/timeapiio v0.0.0-20240915203246-b907cf699af3
|
||||||
github.com/xaionaro-go/typing v0.0.0-20221123235249-2229101d38ba
|
github.com/xaionaro-go/typing v0.0.0-20221123235249-2229101d38ba
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -697,6 +697,8 @@ github.com/xaionaro-go/mediamtx v0.0.0-20241009124606-94c22c603970 h1:QmbvVR2Jt+
|
|||||||
github.com/xaionaro-go/mediamtx v0.0.0-20241009124606-94c22c603970/go.mod h1:3J9s+wGt6CV4MDnoXApKEdY3kdc5sd6AYEndLJSAIYI=
|
github.com/xaionaro-go/mediamtx v0.0.0-20241009124606-94c22c603970/go.mod h1:3J9s+wGt6CV4MDnoXApKEdY3kdc5sd6AYEndLJSAIYI=
|
||||||
github.com/xaionaro-go/object v0.0.0-20241024025057-382352276e7b h1:tAZ8x7bEoxhv2/o73ykCvuI/cR7ifcuH6dUxiEZLTqw=
|
github.com/xaionaro-go/object v0.0.0-20241024025057-382352276e7b h1:tAZ8x7bEoxhv2/o73ykCvuI/cR7ifcuH6dUxiEZLTqw=
|
||||||
github.com/xaionaro-go/object v0.0.0-20241024025057-382352276e7b/go.mod h1:kiXodA4gThh6NpkPWRlgdqbtel8/F7zj4xIBAhDPygM=
|
github.com/xaionaro-go/object v0.0.0-20241024025057-382352276e7b/go.mod h1:kiXodA4gThh6NpkPWRlgdqbtel8/F7zj4xIBAhDPygM=
|
||||||
|
github.com/xaionaro-go/object v0.0.0-20241026212449-753ce10ec94c h1:2CIIxTRox9auImHyfbfrqSyrvPaWrw5w2Yw5TkOioZw=
|
||||||
|
github.com/xaionaro-go/object v0.0.0-20241026212449-753ce10ec94c/go.mod h1:vRcA12NWsR0IrS75eqnPBs5aVfCYmJy4bR+6DbJpBCg=
|
||||||
github.com/xaionaro-go/obs-grpc-proxy v0.0.0-20241018162120-5faf4e7a684a h1:PyX7XpLkj+eAwrPMFMGpvZIG4zBfzAfwNhwTtbORqN0=
|
github.com/xaionaro-go/obs-grpc-proxy v0.0.0-20241018162120-5faf4e7a684a h1:PyX7XpLkj+eAwrPMFMGpvZIG4zBfzAfwNhwTtbORqN0=
|
||||||
github.com/xaionaro-go/obs-grpc-proxy v0.0.0-20241018162120-5faf4e7a684a/go.mod h1:exSKIlCibB0ww+ABDwH+YG/iNdqVfdzXBBg5LYxkxGw=
|
github.com/xaionaro-go/obs-grpc-proxy v0.0.0-20241018162120-5faf4e7a684a/go.mod h1:exSKIlCibB0ww+ABDwH+YG/iNdqVfdzXBBg5LYxkxGw=
|
||||||
github.com/xaionaro-go/pulse v0.0.0-20241023202712-7151fa00d4bb h1:9iHPI27CYbmJDhzEuCABQthE/DGVNvT60ybWvv3BV8w=
|
github.com/xaionaro-go/pulse v0.0.0-20241023202712-7151fa00d4bb h1:9iHPI27CYbmJDhzEuCABQthE/DGVNvT60ybWvv3BV8w=
|
||||||
@@ -1256,6 +1258,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
|||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
||||||
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||||
|
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
|
||||||
|
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|||||||
39
pkg/streamcontrol/kick/cache.go
Normal file
39
pkg/streamcontrol/kick/cache.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package kick
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/xaionaro-go/kickcom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache struct {
|
||||||
|
ChanInfo *kickcom.ChannelV1
|
||||||
|
}
|
||||||
|
|
||||||
|
type ctxKeyCacheT struct{}
|
||||||
|
|
||||||
|
var ctxKeyCache ctxKeyCacheT
|
||||||
|
|
||||||
|
func CtxWithCache(ctx context.Context, cache *Cache) context.Context {
|
||||||
|
return context.WithValue(ctx, ctxKeyCache, cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CacheFromCtx(ctx context.Context) *Cache {
|
||||||
|
cacheIface := ctx.Value(ctxKeyCache)
|
||||||
|
cache, _ := cacheIface.(*Cache)
|
||||||
|
return cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cache *Cache) GetChanInfo() *kickcom.ChannelV1 {
|
||||||
|
if cache == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*kickcom.ChannelV1)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&cache.ChanInfo))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cache *Cache) SetChanInfo(chanInfo *kickcom.ChannelV1) {
|
||||||
|
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&cache.ChanInfo)), unsafe.Pointer(chanInfo))
|
||||||
|
}
|
||||||
@@ -45,27 +45,31 @@ func New(
|
|||||||
return nil, fmt.Errorf("channel is not set")
|
return nil, fmt.Errorf("channel is not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
client, err := kickcom.New()
|
||||||
var client *kickcom.Kick
|
|
||||||
var channel *kickcom.ChannelV1
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
|
|
||||||
client, err = kickcom.New()
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("unable to initialize a client to Kick: %w", err)
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
channel, err = client.GetChannelV1(ctx, cfg.Config.Channel)
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("unable to obtain channel info: %w", err)
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unable to initialize a client to Kick: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel *kickcom.ChannelV1
|
||||||
|
cache := CacheFromCtx(ctx)
|
||||||
|
if chanInfo := cache.GetChanInfo(); chanInfo != nil && chanInfo.Slug == cfg.Config.Channel {
|
||||||
|
channel = cache.ChanInfo
|
||||||
|
logger.Debugf(ctx, "reuse the cache, instead of querying channel info")
|
||||||
|
} else {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
channel, err = client.GetChannelV1(ctx, cfg.Config.Channel)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("unable to obtain channel info: %w", err)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cache != nil {
|
||||||
|
cache.SetChanInfo(channel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, closeFn := context.WithCancel(ctx)
|
ctx, closeFn := context.WithCancel(ctx)
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ type BackendDataTwitch struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BackendDataKick struct {
|
type BackendDataKick struct {
|
||||||
|
Cache cache.Kick
|
||||||
}
|
}
|
||||||
|
|
||||||
type BackendDataYouTube struct {
|
type BackendDataYouTube struct {
|
||||||
|
|||||||
4
pkg/streamd/cache/cache.go
vendored
4
pkg/streamd/cache/cache.go
vendored
@@ -10,9 +10,12 @@ import (
|
|||||||
"github.com/facebookincubator/go-belt/tool/logger"
|
"github.com/facebookincubator/go-belt/tool/logger"
|
||||||
"github.com/goccy/go-yaml"
|
"github.com/goccy/go-yaml"
|
||||||
"github.com/nicklaw5/helix/v2"
|
"github.com/nicklaw5/helix/v2"
|
||||||
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/kick"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/youtube"
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/youtube"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Kick = kick.Cache
|
||||||
|
|
||||||
type Twitch struct {
|
type Twitch struct {
|
||||||
Categories []helix.Game
|
Categories []helix.Game
|
||||||
}
|
}
|
||||||
@@ -22,6 +25,7 @@ type YouTube struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
|
Kick Kick
|
||||||
Twitch Twitch
|
Twitch Twitch
|
||||||
Youtube YouTube
|
Youtube YouTube
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/andreykaipov/goobs/api/events/subscriptions"
|
"github.com/andreykaipov/goobs/api/events/subscriptions"
|
||||||
"github.com/facebookincubator/go-belt/tool/logger"
|
"github.com/facebookincubator/go-belt/tool/logger"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/xaionaro-go/object"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/streamcontrol"
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/kick"
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/kick"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs"
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs"
|
||||||
@@ -345,8 +346,9 @@ func (d *StreamD) initTwitchBackend(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *StreamD) initKickBackend(ctx context.Context) error {
|
func (d *StreamD) initKickBackend(ctx context.Context) error {
|
||||||
|
cacheHashBeforeInit, _ := object.CalcCryptoHash(d.Cache.Kick)
|
||||||
kick, err := newKick(
|
kick, err := newKick(
|
||||||
ctx,
|
kick.CtxWithCache(ctx, &d.Cache.Kick),
|
||||||
d.Config.Backends[kick.ID],
|
d.Config.Backends[kick.ID],
|
||||||
func(cfg *streamcontrol.AbstractPlatformConfig) error {
|
func(cfg *streamcontrol.AbstractPlatformConfig) error {
|
||||||
return d.setPlatformConfig(ctx, kick.ID, cfg)
|
return d.setPlatformConfig(ctx, kick.ID, cfg)
|
||||||
@@ -357,6 +359,13 @@ func (d *StreamD) initKickBackend(ctx context.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
cacheHashAfterInit, _ := object.CalcCryptoHash(d.Cache.Kick)
|
||||||
|
if len(cacheHashAfterInit) == 0 || !cacheHashAfterInit.Equals(cacheHashBeforeInit) {
|
||||||
|
err := d.writeCache(ctx)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf(ctx, "unable to write cache: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
d.StreamControllers.Kick = kick
|
d.StreamControllers.Kick = kick
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -455,8 +455,7 @@ func (d *StreamD) saveConfig(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *StreamD) ResetCache(ctx context.Context) error {
|
func (d *StreamD) ResetCache(ctx context.Context) error {
|
||||||
d.Cache.Twitch = cache.Twitch{}
|
d.Cache = &cache.Cache{}
|
||||||
d.Cache.Youtube = cache.YouTube{}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,7 +717,7 @@ func (d *StreamD) getBackendData(
|
|||||||
case twitch.ID:
|
case twitch.ID:
|
||||||
return api.BackendDataTwitch{Cache: d.Cache.Twitch}, nil
|
return api.BackendDataTwitch{Cache: d.Cache.Twitch}, nil
|
||||||
case kick.ID:
|
case kick.ID:
|
||||||
return api.BackendDataKick{}, nil
|
return api.BackendDataKick{Cache: d.Cache.Kick}, nil
|
||||||
case youtube.ID:
|
case youtube.ID:
|
||||||
return api.BackendDataYouTube{Cache: d.Cache.Youtube}, nil
|
return api.BackendDataYouTube{Cache: d.Cache.Youtube}, nil
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -2418,6 +2418,7 @@ func (p *Panel) initMainWindow(
|
|||||||
|
|
||||||
p.statusPanel = widget.NewLabel("")
|
p.statusPanel = widget.NewLabel("")
|
||||||
p.statusPanel.Wrapping = fyne.TextWrapWord
|
p.statusPanel.Wrapping = fyne.TextWrapWord
|
||||||
|
p.statusPanel.Truncation = fyne.TextTruncateEllipsis
|
||||||
|
|
||||||
w.SetContent(container.NewBorder(
|
w.SetContent(container.NewBorder(
|
||||||
container.NewVBox(
|
container.NewVBox(
|
||||||
|
|||||||
Reference in New Issue
Block a user