@@ -13,46 +13,48 @@ import (
1313 "unicode"
1414)
1515
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-
2616var CurrentSession * jike.Session
2717var fm = newFm ()
2818
2919type Music struct {
30- url string
31- index int
20+ url string
21+ topicId string
22+ current int
23+ next int
3224}
3325
3426type JikeFm struct {
35- playlist []jike.Message
3627 player * Player
37- currentMusic Music
38- currentTopicIndex int
39- nextMusicIndex int
40- skip string
41- more chan bool
28+ music * Music
29+ viewingTopicIndex int
4230 timer * time.Timer
4331}
4432
4533func newFm () * JikeFm {
4634 p := & JikeFm {
47- currentTopicIndex : 0 ,
48- more : make (chan bool , 1 ),
35+ viewingTopicIndex : 0 ,
4936 }
5037 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+ }
5343 return p
5444}
5545
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+
5658func (p * JikeFm ) setTimer (d time.Duration ) {
5759 if p .timer != nil {
5860 p .stopTimer ()
@@ -69,145 +71,85 @@ func (p *JikeFm) stopTimer() {
6971 }
7072}
7173
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-
10174func (p * JikeFm ) play () {
10275 p .player .open ()
10376}
10477
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 ,
11685 }
11786 UI .app .QueueUpdateDraw (func () {
118- p .drawHeader ()
119- p .changeSong (current , next )
87+ prevTopic .ChangeSong (prevIndex , - 1 )
12088 })
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
14289 p .player .reset ().open ()
14390}
14491
14592func (p * JikeFm ) drawHeader () {
14693 text := fmt .Sprintf (headerTpl ,
147- p .playlist [p .currentMusic . index ].GetTitle (),
94+ p .playingList () [p .music . current ].GetTitle (),
14895 p .player .currentPosition (),
14996 "" ,
15097 )
15198 UI .header .SetText (text )
15299}
153100
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-
176101func (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 ()
180105 }
181- if next >= len (p .playlist ) {
106+ if next >= len (p .playingList () ) {
182107 next = 0
183108 }
184109 return next
185110}
186111
187112func (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 {
189119 return nil
190120 }
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 )
194131}
195132
196133func (p * JikeFm ) handle (event * tcell.EventKey ) * tcell.EventKey {
197134 switch event .Key () {
198135 case tcell .KeyCtrlN :
199- p .nextMusicIndex = p .calcNextIndex ()
136+ p .music . next = p .calcNextIndex ()
200137 p .player .reset ().open ()
201138 return nil
202139 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 {
205142 n = 0
206143 }
207- p .nextMusicIndex = n
144+ p .music . next = n
208145 p .player .reset ().open ()
209146 return nil
210147 case tcell .KeyTab :
148+ p .viewingTopicIndex += 1
149+ if p .viewingTopicIndex == len (topicOrder ) {
150+ p .viewingTopicIndex = 0
151+ }
152+ p .switchTopic ()
211153 return nil
212154 case tcell .KeyRune :
213155 switch unicode .ToLower (event .Rune ()) {
@@ -221,30 +163,34 @@ func (p *JikeFm) handle(event *tcell.EventKey) *tcell.EventKey {
221163 return event
222164}
223165
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+
224175func main () {
225176 CurrentSession = jike .NewSession ()
226177 _ = speaker .Init (targetFormat .SampleRate , targetFormat .SampleRate .N (time .Second / 30 ))
227178
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+ }
232187
233- fm .onSelectChange ( 0 , "" , "" , 0 )
188+ defer fm .player . close ( )
234189
235- UI .side .
236- SetChangedFunc (fm .onSelectChange ).
237- SetSelectedFunc (fm .onEnterPlay ).
238- ShowSecondaryText (false )
239190 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- }
245191 UI .footerTopic .SetText ("| " + strings .Join (s , " | " ) + " |" )
246- UI .footerTopic .Highlight (strconv .Itoa (fm .currentTopicIndex ))
247192
193+ fm .switchTopic ()
248194 fm .play ()
249195
250196 go func () {
0 commit comments