forked from taylorskalyo/goreader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.go
130 lines (117 loc) · 2.6 KB
/
app.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
termbox "github.com/nsf/termbox-go"
"github.com/nico385412/goreader/epub"
)
// app is used to store the current state of the application.
type app struct {
pager pager
book *epub.Rootfile
chapter int
}
// run opens a book, renders its contents within the pager, and polls for
// terminal events until an error occurs or an exit event is detected.
func (a *app) run() error {
if err := termbox.Init(); err != nil {
return err
}
defer termbox.Flush()
defer termbox.Close()
if err := a.openChapter(); err != nil {
return err
}
for {
if err := a.pager.draw(); err != nil {
return err
}
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
switch ev.Key {
case termbox.KeyEsc:
return nil
case termbox.KeyArrowDown:
a.pager.scrollDown()
case termbox.KeyArrowUp:
a.pager.scrollUp()
case termbox.KeyArrowRight:
a.pager.scrollRight()
case termbox.KeyArrowLeft:
a.pager.scrollLeft()
default:
switch ev.Ch {
case 'q':
return nil
case 'j':
a.pager.scrollDown()
case 'k':
a.pager.scrollUp()
case 'h':
a.pager.scrollLeft()
case 'l':
a.pager.scrollRight()
case 'f':
if a.pager.pageDown() || a.chapter >= len(a.book.Spine.Itemrefs)-1 {
continue
}
// Go to the next chapter if we reached the end.
if err := a.nextChapter(); err != nil {
return err
}
a.pager.toTop()
case 'b':
if a.pager.pageUp() || a.chapter <= 0 {
continue
}
// Go to the previous chapter if we reached the beginning.
if err := a.prevChapter(); err != nil {
return err
}
a.pager.toBottom()
case 'g':
a.pager.toTop()
case 'G':
a.pager.toBottom()
case 'L':
if a.chapter >= len(a.book.Spine.Itemrefs)-1 {
continue
}
if err := a.nextChapter(); err != nil {
return err
}
a.pager.toTop()
case 'H':
if a.chapter <= 0 {
continue
}
if err := a.prevChapter(); err != nil {
return err
}
a.pager.toTop()
}
}
}
}
}
// openChapter opens the current chapter and renders it within the pager.
func (a *app) openChapter() error {
f, err := a.book.Spine.Itemrefs[a.chapter].Open()
if err != nil {
return err
}
doc, err := parseText(f, a.book.Manifest.Items)
if err != nil {
return err
}
a.pager.doc = doc
return nil
}
// nextChapter opens the next chapter.
func (a *app) nextChapter() error {
a.chapter++
return a.openChapter()
}
// prevChapter opens the previous chapter.
func (a *app) prevChapter() error {
a.chapter--
return a.openChapter()
}