11package tui
22
33import (
4- "context"
54 "encoding/json"
65 "fmt"
7- "github.com/Adeithe/go-twitch"
86 "github.com/charmbracelet/bubbles/list"
97 tea "github.com/charmbracelet/bubbletea"
108 "log"
119 "time"
1210 "ttv-cli/internal/pkg/twitch/gql/operation/redeemcustomreward"
1311 "ttv-cli/internal/pkg/twitch/pubsub/communitypointschannel"
12+ "ttv-cli/internal/pkg/twitch/pubsub/communitypointsuser"
1413)
1514
1615type initialRewards []list.Item
1716type updatedReward communitypointschannel.UpdatedReward
1817type tick int
18+ type newBalance int
1919
2020func (m Model ) Update (msg tea.Msg ) (tea.Model , tea.Cmd ) {
2121 switch msg := msg .(type ) {
2222 case initialRewards :
2323 cmd := m .list .SetItems (msg )
24- return m , tea .Batch (cmd , m .processUpdates , m .tick ())
24+ return m , tea .Batch (cmd , m .processRewardUpdates , m .tick ())
2525
2626 case updatedReward :
2727 // Reward has been paused or disabled, remove it from the list
@@ -35,7 +35,11 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
3535 } else if item , ok := m .itemsById [msg .Id ]; ok {
3636 item .CooldownExpiresAt = msg .CooldownExpiresAt
3737 }
38- return m , m .processUpdates
38+ return m , m .processRewardUpdates
39+
40+ case newBalance :
41+ m .list .Title = fmt .Sprintf ("%s's Rewards (%d points)" , m .twitchChannel .DisplayName , msg )
42+ return m , m .processPointsUpdates
3943
4044 case tick :
4145 cmd := m .list .SetItems (m .list .Items ()) // Force re-render
@@ -72,29 +76,52 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
7276 return m , cmd
7377}
7478
75- func (m Model ) subscribeToRewards (ctx context.Context ) {
76- p := twitch .PubSub ()
77- err := p .Listen ("community-points-channel-v1" , m .twitchChannel .Id )
79+ func (m Model ) subscribeToRewards () {
80+ err := m .pubsubClient .Listen ("community-points-channel-v1" , m .twitchChannel .Id )
7881 if err != nil {
79- log .Fatalln ( err )
82+ log .Fatalf ( "Could not subscribe to community-points-channel-v1: %s \n " , err )
8083 }
8184
82- defer p .Close ()
83-
84- handleUpdate := func (_ int , _ string , data []byte ) {
85- response := communitypointschannel.Response {}
86- if err := json .Unmarshal (data , & response ); err != nil {
87- log .Fatalln (err )
85+ subscribedTopic := "community-points-channel-v1." + m .twitchChannel .Id
86+ handleUpdate := func (_ int , topic string , data []byte ) {
87+ if topic == subscribedTopic {
88+ var response communitypointschannel.Response
89+ if err := json .Unmarshal (data , & response ); err != nil {
90+ log .Fatalln (err )
91+ }
92+ m .rewardsUpdateChannel <- response
8893 }
89- m .rewardsUpdateChannel <- response
9094 }
9195
92- p .OnShardMessage (handleUpdate )
96+ m .pubsubClient .OnShardMessage (handleUpdate )
97+ }
98+
99+ func (m Model ) subscribeToPoints () {
100+ userId := m .config .TokenDetails .UserId
93101
94- <- ctx .Done ()
102+ err := m .pubsubClient .ListenWithAuth (m .config .AuthToken , "community-points-user-v1" , userId )
103+ if err != nil {
104+ log .Fatalf ("Could not subscribe to community-points-user-v1.%s: %s\n " , m .twitchChannel .Id , err )
105+ }
106+
107+ subscribedTopic := "community-points-user-v1." + userId
108+ handleUpdate := func (_ int , topic string , data []byte ) {
109+ if topic == subscribedTopic {
110+ var response communitypointsuser.Response
111+ if err := json .Unmarshal (data , & response ); err != nil {
112+ log .Fatalf ("Failed to unmarshal response: %s, error: %s\n " , data , err )
113+ }
114+
115+ if response .Type == "points-earned" || response .Type == "points-spent" {
116+ m .pointsUpdateChannel <- response
117+ }
118+ }
119+ }
120+
121+ m .pubsubClient .OnShardMessage (handleUpdate )
95122}
96123
97- func (m Model ) processUpdates () tea.Msg {
124+ func (m Model ) processRewardUpdates () tea.Msg {
98125 for update := range m .rewardsUpdateChannel {
99126 if update .Type == "custom-reward-updated" {
100127 return updatedReward (update .Data .UpdatedReward )
@@ -103,6 +130,25 @@ func (m Model) processUpdates() tea.Msg {
103130 return nil // Unreachable
104131}
105132
133+ func (m Model ) processPointsUpdates () tea.Msg {
134+ for update := range m .pointsUpdateChannel {
135+ if update .Type == "points-spent" {
136+ var data communitypointsuser.PointsSpentData
137+ if err := json .Unmarshal (update .Data , & data ); err != nil {
138+ log .Fatalf ("Could not process point update: %s, error: %s\n " , update , err )
139+ }
140+ return newBalance (data .Balance .Balance )
141+ } else if update .Type == "points-earned" {
142+ var data communitypointsuser.PointsEarnedData
143+ if err := json .Unmarshal (update .Data , & data ); err != nil {
144+ log .Fatalf ("Could not process point update: %s, error: %s\n " , update , err )
145+ }
146+ return newBalance (data .Balance .Balance )
147+ }
148+ }
149+ return nil
150+ }
151+
106152func (m Model ) tick () tea.Cmd {
107153 return tea .Tick (time .Second , func (_ time.Time ) tea.Msg {
108154 return tick (0 )
@@ -123,7 +169,7 @@ func (m Model) redeemReward(i *item) error {
123169 input .TextInput = ":)" // FIXME
124170 }
125171
126- _ , err := redeemcustomreward .Redeem (input , m .authToken )
172+ _ , err := redeemcustomreward .Redeem (input , m .config . AuthToken )
127173 if err != nil {
128174 return fmt .Errorf ("could not redeem reward: %w" , err )
129175 }
0 commit comments