@@ -13,46 +13,48 @@ import (
13
13
"unicode"
14
14
)
15
15
16
- type Topic struct {
17
- id string
18
- name string
19
- }
20
-
21
- var topics = []Topic {
22
- {id : "55483ddee4b03ccbae843925" , name : "晚安电台" },
23
- {id : "5a1ccf936e6e7c0011037480" , name : "即友在听什么歌" },
24
- }
25
-
26
16
var CurrentSession * jike.Session
27
17
var fm = newFm ()
28
18
29
19
type Music struct {
30
- url string
31
- index int
20
+ url string
21
+ topicId string
22
+ current int
23
+ next int
32
24
}
33
25
34
26
type JikeFm struct {
35
- playlist []jike.Message
36
27
player * Player
37
- currentMusic Music
38
- currentTopicIndex int
39
- nextMusicIndex int
40
- skip string
41
- more chan bool
28
+ music * Music
29
+ viewingTopicIndex int
42
30
timer * time.Timer
43
31
}
44
32
45
33
func newFm () * JikeFm {
46
34
p := & JikeFm {
47
- currentTopicIndex : 0 ,
48
- more : make (chan bool , 1 ),
35
+ viewingTopicIndex : 0 ,
49
36
}
50
37
p .player = newPlayer (p .iter )
51
- p .nextMusicIndex = 0
52
- go p .fetchMore ()
38
+ p .music = & Music {
39
+ topicId : topicOrder [0 ],
40
+ current : 0 ,
41
+ next : 0 ,
42
+ }
53
43
return p
54
44
}
55
45
46
+ func (p * JikeFm ) playingTopic () * Topic {
47
+ return topics [p .music .topicId ]
48
+ }
49
+
50
+ func (p * JikeFm ) viewingTopic () * Topic {
51
+ return topics [topicOrder [p.viewingTopicIndex ]]
52
+ }
53
+
54
+ func (p * JikeFm ) playingList () []jike.Message {
55
+ return p .playingTopic ().playlist
56
+ }
57
+
56
58
func (p * JikeFm ) setTimer (d time.Duration ) {
57
59
if p .timer != nil {
58
60
p .stopTimer ()
@@ -69,145 +71,85 @@ func (p *JikeFm) stopTimer() {
69
71
}
70
72
}
71
73
72
- func (p * JikeFm ) fetchMore () {
73
- for {
74
- <- p .more
75
- msgs := p .feed ()
76
-
77
- UI .app .QueueUpdateDraw (func () {
78
- currentLen := len (p .playlist )
79
- p .addToPlaylist (msgs )
80
- updateTotalSong (len (p .playlist ))
81
- if p .nextMusicIndex == 0 {
82
- p .nextMusicIndex = currentLen
83
- }
84
- })
85
- }
86
- }
87
-
88
- func (p * JikeFm ) feed () []jike.Message {
89
- res , next , _ := jike .FetchMoreSelectedFM (CurrentSession , topics [p .currentTopicIndex ].id , p .skip )
90
- p .skip = next
91
- return res
92
- }
93
-
94
- func (p * JikeFm ) addToPlaylist (messages []jike.Message ) {
95
- for _ , msg := range messages {
96
- p .playlist = append (p .playlist , msg )
97
- UI .side .AddItem (normalText (len (p .playlist ), msg .GetTitle ()), "" , 0 , nil )
98
- }
99
- }
100
-
101
74
func (p * JikeFm ) play () {
102
75
p .player .open ()
103
76
}
104
77
105
- func (p * JikeFm ) playIndex (next int ) beep.Streamer {
106
- mp3Url := musicapi .NeteaseUrlToMp3 (p .playlist [next ].LinkInfo .LinkUrl )
107
- f , err := musicapi .NeteaseDownload (mp3Url )
108
- if err != nil {
109
- fmt .Println (err )
110
- return nil
111
- }
112
- current := p .currentMusic .index
113
- p .currentMusic = Music {
114
- url : mp3Url ,
115
- index : next ,
78
+ func (p * JikeFm ) onEnterPlay (topicId string , index int ) {
79
+ prevTopic := topics [p .music .topicId ]
80
+ prevIndex := p .music .current
81
+ p .music = & Music {
82
+ topicId : topicId ,
83
+ next : index ,
84
+ current : 0 ,
116
85
}
117
86
UI .app .QueueUpdateDraw (func () {
118
- p .drawHeader ()
119
- p .changeSong (current , next )
87
+ prevTopic .ChangeSong (prevIndex , - 1 )
120
88
})
121
- return p .player .playMp3 (f )
122
- }
123
-
124
- func (p * JikeFm ) onSelectChange (index int , _ string , _ string , _ rune ) {
125
- i := index
126
- if index < 0 {
127
- i = len (p .playlist ) + index
128
- }
129
- if index >= len (p .playlist ) {
130
- i = index - len (p .playlist )
131
- }
132
- if index == len (p .playlist )- 1 {
133
- p .queueMore ()
134
- }
135
- msg := p .playlist [i ]
136
- UI .main .SetText (msg .Content )
137
- UI .mainAuthor .SetText ("[green]@" + msg .User .ScreenName )
138
- }
139
-
140
- func (p * JikeFm ) onEnterPlay (index int , mainText string , secondaryText string , shortcut rune ) {
141
- p .nextMusicIndex = index
142
89
p .player .reset ().open ()
143
90
}
144
91
145
92
func (p * JikeFm ) drawHeader () {
146
93
text := fmt .Sprintf (headerTpl ,
147
- p .playlist [p .currentMusic . index ].GetTitle (),
94
+ p .playingList () [p .music . current ].GetTitle (),
148
95
p .player .currentPosition (),
149
96
"" ,
150
97
)
151
98
UI .header .SetText (text )
152
99
}
153
100
154
- func (p * JikeFm ) changeSong (from int , target int ) {
155
- if from >= 0 {
156
- UI .side .SetItemText (
157
- from ,
158
- normalText (from + 1 , p .playlist [from ].GetTitle ()),
159
- "" ,
160
- )
161
- }
162
- UI .side .SetItemText (
163
- target ,
164
- playingText (target + 1 , p .playlist [target ].GetTitle ()),
165
- "" ,
166
- )
167
- }
168
-
169
- func (p * JikeFm ) queueMore () {
170
- select {
171
- case p .more <- true :
172
- default :
173
- }
174
- }
175
-
176
101
func (p * JikeFm ) calcNextIndex () int {
177
- next := p .currentMusic . index + 1
178
- if next > len (p .playlist )- 1 {
179
- p .queueMore ()
102
+ next := p .music . current + 1
103
+ if next > len (p .playingList () )- 1 {
104
+ p .playingTopic (). queueMore ()
180
105
}
181
- if next >= len (p .playlist ) {
106
+ if next >= len (p .playingList () ) {
182
107
next = 0
183
108
}
184
109
return next
185
110
}
186
111
187
112
func (p * JikeFm ) iter () beep.Streamer {
188
- if len (p .playlist ) == 0 {
113
+ if len (p .playingList ()) == 0 {
114
+ return nil
115
+ }
116
+ mp3Url := p .playingList ()[p .music .next ].Mp3Url
117
+ f , err := musicapi .NeteaseDownload (mp3Url )
118
+ if err != nil {
189
119
return nil
190
120
}
191
- stream := p .playIndex (p .nextMusicIndex )
192
- p .nextMusicIndex = p .calcNextIndex ()
193
- return stream
121
+ c := p .music .current
122
+ p .music .url = mp3Url
123
+ p .music .current = p .music .next
124
+ p .music .next = p .calcNextIndex ()
125
+
126
+ UI .app .QueueUpdateDraw (func () {
127
+ p .drawHeader ()
128
+ topics [p .music .topicId ].ChangeSong (c , p .music .current )
129
+ })
130
+ return p .player .playMp3 (f )
194
131
}
195
132
196
133
func (p * JikeFm ) handle (event * tcell.EventKey ) * tcell.EventKey {
197
134
switch event .Key () {
198
135
case tcell .KeyCtrlN :
199
- p .nextMusicIndex = p .calcNextIndex ()
136
+ p .music . next = p .calcNextIndex ()
200
137
p .player .reset ().open ()
201
138
return nil
202
139
case tcell .KeyCtrlP :
203
- var n int
204
- if n := p . currentMusic . index - 1 ; n < 0 {
140
+ n := p . music . current - 1
141
+ if n < 0 {
205
142
n = 0
206
143
}
207
- p .nextMusicIndex = n
144
+ p .music . next = n
208
145
p .player .reset ().open ()
209
146
return nil
210
147
case tcell .KeyTab :
148
+ p .viewingTopicIndex += 1
149
+ if p .viewingTopicIndex == len (topicOrder ) {
150
+ p .viewingTopicIndex = 0
151
+ }
152
+ p .switchTopic ()
211
153
return nil
212
154
case tcell .KeyRune :
213
155
switch unicode .ToLower (event .Rune ()) {
@@ -221,30 +163,34 @@ func (p *JikeFm) handle(event *tcell.EventKey) *tcell.EventKey {
221
163
return event
222
164
}
223
165
166
+ func (p * JikeFm ) switchTopic () {
167
+ UI .footerTopic .Highlight (strconv .Itoa (fm .viewingTopicIndex ))
168
+ UI .topicPages .SwitchToPage (topicOrder [fm .viewingTopicIndex ])
169
+ UI .app .SetFocus (UI .topics [fm .viewingTopicIndex ].side )
170
+ }
171
+
172
+ func (p * JikeFm ) highlight () {
173
+ }
174
+
224
175
func main () {
225
176
CurrentSession = jike .NewSession ()
226
177
_ = speaker .Init (targetFormat .SampleRate , targetFormat .SampleRate .N (time .Second / 30 ))
227
178
228
- defer fm .player .close ()
229
-
230
- fm .addToPlaylist (fm .feed ())
231
- updateTotalSong (len (fm .playlist ))
179
+ var s []string
180
+ for index , topicId := range topicOrder {
181
+ t := topics [topicId ]
182
+ t .BindUI (addTopic (topicId )).SetSelectedFunc (fm .onEnterPlay )
183
+ s = append (s , fmt .Sprintf (`["%d"]%s[""]` , index , t .name ))
184
+ t .AddToPlaylist (t .Feed ())
185
+ t .onSelect (0 , "" , "" , 0 )
186
+ }
232
187
233
- fm .onSelectChange ( 0 , "" , "" , 0 )
188
+ defer fm .player . close ( )
234
189
235
- UI .side .
236
- SetChangedFunc (fm .onSelectChange ).
237
- SetSelectedFunc (fm .onEnterPlay ).
238
- ShowSecondaryText (false )
239
190
UI .app .SetInputCapture (fm .handle )
240
-
241
- var s []string
242
- for index , topic := range topics {
243
- s = append (s , fmt .Sprintf (`["%d"]%s[""]` , index , topic .name ))
244
- }
245
191
UI .footerTopic .SetText ("| " + strings .Join (s , " | " ) + " |" )
246
- UI .footerTopic .Highlight (strconv .Itoa (fm .currentTopicIndex ))
247
192
193
+ fm .switchTopic ()
248
194
fm .play ()
249
195
250
196
go func () {
0 commit comments