commit a7a47a113fdfb6a44ff86e2ef897dcca4d91a576
parent ebbcb27e89a2a4eb2373000d0b60a411e0e4a170
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Thu, 28 Dec 2023 21:42:26 -0500
fix "stop tab loading icon" for new stream menu
Diffstat:
2 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/pkg/pubsub/pubsub.go b/pkg/pubsub/pubsub.go
@@ -50,7 +50,7 @@ func (p *PubSub[T]) removeSubscriber(s *Sub[T]) {
// Subscribe is an alias for NewSub
func (p *PubSub[T]) Subscribe(topics []string) *Sub[T] {
ctx, cancel := context.WithCancel(context.Background())
- s := &Sub[T]{topics: topics, ch: make(chan payload[T], 10), ctx: ctx, cancel: cancel, p: p}
+ s := &Sub[T]{topics: topics, ch: make(chan Payload[T], 10), ctx: ctx, cancel: cancel, p: p}
p.addSubscriber(s)
return s
}
@@ -58,14 +58,13 @@ func (p *PubSub[T]) Subscribe(topics []string) *Sub[T] {
// Pub shortcut for publish which ignore the error
func (p *PubSub[T]) Pub(topic string, msg T) {
for _, s := range p.getSubscribers(topic) {
- s.publish(payload[T]{topic, msg})
+ s.publish(Payload[T]{topic, msg})
}
}
-//
-type payload[T any] struct {
- topic string
- msg T
+type Payload[T any] struct {
+ Topic string
+ Msg T
}
// ErrTimeout error returned when timeout occurs
@@ -74,10 +73,10 @@ var ErrTimeout = errors.New("timeout")
// ErrCancelled error returned when context is cancelled
var ErrCancelled = errors.New("cancelled")
-// Sub subscriber will receive messages published on a topic in his ch
+// Sub subscriber will receive messages published on a Topic in his ch
type Sub[T any] struct {
topics []string // Topics subscribed to
- ch chan payload[T] // Receives messages in this channel
+ ch chan Payload[T] // Receives messages in this channel
ctx context.Context
cancel context.CancelFunc
p *PubSub[T]
@@ -87,7 +86,7 @@ type Sub[T any] struct {
func (s *Sub[T]) ReceiveTimeout2(timeout time.Duration, c1 <-chan struct{}) (topic string, msg T, err error) {
select {
case p := <-s.ch:
- return p.topic, p.msg, nil
+ return p.Topic, p.Msg, nil
case <-time.After(timeout):
return topic, msg, ErrTimeout
case <-c1:
@@ -108,20 +107,25 @@ func (s *Sub[T]) Receive() (topic string, msg T, err error) {
var res T
select {
case p := <-s.ch:
- return p.topic, p.msg, nil
+ return p.Topic, p.Msg, nil
case <-s.ctx.Done():
return topic, res, ErrCancelled
}
}
-// Close will remove the subscriber from the topic subscribers
+// ReceiveCh returns a message
+func (s *Sub[T]) ReceiveCh() <-chan Payload[T] {
+ return s.ch
+}
+
+// Close will remove the subscriber from the Topic subscribers
func (s *Sub[T]) Close() {
s.cancel()
s.p.removeSubscriber(s)
}
// publish a message to the subscriber channel
-func (s *Sub[T]) publish(p payload[T]) {
+func (s *Sub[T]) publish(p Payload[T]) {
select {
case s.ch <- p:
default:
diff --git a/pkg/web/handlers/api/v1/chat.go b/pkg/web/handlers/api/v1/chat.go
@@ -178,12 +178,14 @@ func ChatStreamMessagesHandler(c echo.Context) error {
c.Response().Flush()
// Create a subscriber and topics to listen to
+ selfRefreshLoadingIconTopic := "refresh_loading_icon_" + string(authUser.Username)
selfRefreshTopic := "refresh_" + string(authUser.Username)
selfWizzTopic := "wizz_" + string(authUser.Username)
readMarkerTopic := "readmarker_" + authUser.ID.String()
authorizedTopics := []string{
database.RefreshTopic,
selfRefreshTopic,
+ selfRefreshLoadingIconTopic,
selfWizzTopic,
readMarkerTopic,
"room_" + room.ID.String()}
@@ -283,6 +285,11 @@ Loop:
continue
}
+ if topic == selfRefreshLoadingIconTopic {
+ send(`<meta http-equiv="refresh" content="1" />`)
+ return nil
+ }
+
if topic == selfRefreshTopic || msgTyp.Typ == database.ForceRefresh {
send(metaRefresh)
return nil
@@ -430,10 +437,14 @@ func ChatStreamMenuHandler(c echo.Context) error {
hutils.SetStreamingHeaders(c)
quit := hutils.CloseSignalChan(c)
send := func(s string) { _, _ = c.Response().Write([]byte(s)) }
+ selfRefreshTopic := "refresh_loading_icon_" + string(authUser.Username)
var prevHash string
var menuID int
var once utils.Once
+ sub := database.MsgPubSub.Subscribe([]string{selfRefreshTopic})
+ defer sub.Close()
+
send(GenerateStyle(authUser, ChatMessagesData{}))
Loop:
@@ -441,9 +452,13 @@ Loop:
select {
case <-once.After(0 * time.Millisecond):
case <-time.After(5 * time.Second):
+ case <-sub.ReceiveCh():
+ send(`<meta http-equiv="refresh" content="1" />`)
+ return nil
case <-quit:
break Loop
}
+
data := GetChatMenuData(c, room)
rightColumn := RenderRightColumn(authUser, data)
newHash := utils.MD5([]byte(rightColumn))
@@ -461,6 +476,6 @@ Loop:
func ChatStreamMessagesRefreshHandler(c echo.Context) error {
authUser := c.Get("authUser").(*database.User)
- database.MsgPubSub.Pub("refresh_"+string(authUser.Username), database.ChatMessageType{Typ: database.ForceRefresh})
+ database.MsgPubSub.Pub("refresh_loading_icon_"+string(authUser.Username), database.ChatMessageType{Typ: database.ForceRefresh})
return c.NoContent(http.StatusOK)
}