commit 9a732d4
Hubert Hirtz
·
2020-06-03 17:03:58 +0000 UTC
parent 881d634
Part Join Typing
5 files changed,
+114,
-29
+27,
-13
1@@ -59,6 +59,8 @@ func main() {
2 app.AddLine("home", "Connected to the server", time.Now())
3 case irc.SelfJoinEvent:
4 app.AddBuffer(ev.Channel)
5+ case irc.SelfPartEvent:
6+ app.RemoveBuffer(ev.Channel)
7 case irc.ChannelMessageEvent:
8 line := formatIRCMessage(ev.Nick, ev.Content)
9 app.AddLine(ev.Channel, line, ev.Time)
10@@ -94,11 +96,14 @@ func main() {
11 case tcell.KeyBackspace2:
12 app.InputBackspace()
13 case tcell.KeyEnter:
14- content := app.InputEnter()
15- handleInput(app, &s, content)
16+ buffer := app.CurrentBuffer()
17+ input := app.InputEnter()
18+ handleInput(&s, buffer, input)
19 case tcell.KeyRune:
20 app.InputRune(ev.Rune())
21- s.Typing(app.CurrentBuffer())
22+ if app.CurrentBuffer() != "home" && !strings.HasPrefix(app.Input(), "/") {
23+ s.Typing(app.CurrentBuffer())
24+ }
25 }
26 }
27 }
28@@ -117,35 +122,44 @@ func parseCommand(s string) (command, args string) {
29
30 i := strings.IndexByte(s, ' ')
31 if i < 0 {
32- i = len(s) - 1
33+ i = len(s)
34 }
35
36 command = strings.ToUpper(s[1:i])
37- args = s[i+1:]
38+ args = strings.TrimLeft(s[i:], " ")
39
40 return
41 }
42
43-func handleInput(app *ui.UI, s *irc.Session, content string) {
44+func handleInput(s *irc.Session, buffer, content string) {
45 cmd, args := parseCommand(content)
46
47 switch cmd {
48 case "":
49- ch := app.CurrentBuffer()
50- if ch == "home" {
51+ if buffer == "home" {
52+ return
53+ }
54+
55+ s.PrivMsg(buffer, args)
56+ case "J", "JOIN":
57+ s.Join(args)
58+ case "PART":
59+ if buffer == "home" {
60 return
61 }
62
63- s.PrivMsg(ch, args)
64+ if args == "" {
65+ args = buffer
66+ }
67+
68+ s.Part(args)
69 case "ME":
70- ch := app.CurrentBuffer()
71- if ch == "home" {
72+ if buffer == "home" {
73 return
74 }
75
76 line := fmt.Sprintf("\x01ACTION %s\x01", args)
77- s.PrivMsg(ch, line)
78- default:
79+ s.PrivMsg(buffer, line)
80 }
81 }
82
+9,
-0
1@@ -34,6 +34,15 @@ type UserJoinEvent struct {
2 ChannelEvent
3 }
4
5+type SelfPartEvent struct {
6+ ChannelEvent
7+}
8+
9+type UserPartEvent struct {
10+ UserEvent
11+ ChannelEvent
12+}
13+
14 type SelfJoinEvent struct {
15 ChannelEvent
16 }
+67,
-15
1@@ -84,16 +84,23 @@ type Channel struct {
2 type action interface{}
3
4 type (
5+ actionJoin struct {
6+ Channel string
7+ }
8+ actionPart struct {
9+ Channel string
10+ }
11+
12 actionPrivMsg struct {
13- To string
14+ Channel string
15 Content string
16 }
17
18 actionTyping struct {
19- To string
20+ Channel string
21 }
22 actionTypingStop struct {
23- To string
24+ Channel string
25 }
26 )
27
28@@ -137,9 +144,9 @@ type Session struct {
29 func NewSession(conn io.ReadWriteCloser, params SessionParams) (s Session, err error) {
30 s = Session{
31 conn: conn,
32- msgs: make(chan Message, 10),
33- acts: make(chan action, 10),
34- evts: make(chan Event, 10),
35+ msgs: make(chan Message, 128),
36+ acts: make(chan action, 128),
37+ evts: make(chan Event, 128),
38 typingStamps: map[string]time.Time{},
39 nick: params.Nickname,
40 lNick: strings.ToLower(params.Nickname),
41@@ -205,17 +212,35 @@ func (s *Session) IsChannel(name string) bool {
42 return strings.IndexAny(name, "#&") == 0 // TODO compute CHANTYPES
43 }
44
45-func (s *Session) PrivMsg(to, content string) {
46- s.acts <- actionPrivMsg{to, content}
47+func (s *Session) Join(channel string) {
48+ s.acts <- actionJoin{channel}
49+}
50+
51+func (s *Session) join(act actionJoin) (err error) {
52+ err = s.send("JOIN %s\r\n", act.Channel)
53+ return
54+}
55+
56+func (s *Session) Part(channel string) {
57+ s.acts <- actionPart{channel}
58+}
59+
60+func (s *Session) part(act actionPart) (err error) {
61+ err = s.send("PART %s\r\n", act.Channel)
62+ return
63+}
64+
65+func (s *Session) PrivMsg(channel, content string) {
66+ s.acts <- actionPrivMsg{channel, content}
67 }
68
69 func (s *Session) privMsg(act actionPrivMsg) (err error) {
70- err = s.send("PRIVMSG %s :%s\r\n", act.To, act.Content)
71+ err = s.send("PRIVMSG %s :%s\r\n", act.Channel, act.Content)
72 return
73 }
74
75-func (s *Session) Typing(to string) {
76- s.acts <- actionTyping{to}
77+func (s *Session) Typing(channel string) {
78+ s.acts <- actionTyping{channel}
79 }
80
81 func (s *Session) typing(act actionTyping) (err error) {
82@@ -223,13 +248,16 @@ func (s *Session) typing(act actionTyping) (err error) {
83 return
84 }
85
86- to := strings.ToLower(act.To)
87+ to := strings.ToLower(act.Channel)
88+ now := time.Now()
89
90- if t, ok := s.typingStamps[to]; ok && time.Now().Sub(t) < 3 {
91+ if t, ok := s.typingStamps[to]; ok && now.Sub(t).Seconds() < 3.0 {
92 return
93 }
94
95- err = s.send("@+typing=active TAGMSG %s\r\n", act.To)
96+ s.typingStamps[to] = now
97+
98+ err = s.send("@+typing=active TAGMSG %s\r\n", act.Channel)
99 return
100 }
101
102@@ -242,7 +270,7 @@ func (s *Session) typingStop(act actionTypingStop) (err error) {
103 return
104 }
105
106- err = s.send("@+typing=done TAGMSG %s\r\n", act.To)
107+ err = s.send("@+typing=done TAGMSG %s\r\n", act.Channel)
108 return
109 }
110
111@@ -256,6 +284,10 @@ func (s *Session) run() {
112 select {
113 case act := <-s.acts:
114 switch act := act.(type) {
115+ case actionJoin:
116+ err = s.join(act)
117+ case actionPart:
118+ err = s.part(act)
119 case actionPrivMsg:
120 err = s.privMsg(act)
121 case actionTyping:
122@@ -497,6 +529,19 @@ func (s *Session) handle(msg Message) (ev Event, err error) {
123 c.Members[lNick] = ""
124 ev = UserJoinEvent{ChannelEvent: channelEv, UserEvent: UserEvent{Nick: nick}}
125 }
126+ case "PART":
127+ nick, _, _ := FullMask(msg.Prefix)
128+ lNick := strings.ToLower(nick)
129+ channel := strings.ToLower(msg.Params[0])
130+ channelEv := ChannelEvent{Channel: msg.Params[0]}
131+
132+ if lNick == s.lNick {
133+ delete(s.channels, channel)
134+ ev = SelfPartEvent{ChannelEvent: channelEv}
135+ } else if c, ok := s.channels[channel]; ok {
136+ delete(c.Members, lNick)
137+ ev = UserPartEvent{ChannelEvent: channelEv, UserEvent: UserEvent{Nick: nick}}
138+ }
139 case "353": // RPL_NAMREPLY
140 channel := strings.ToLower(msg.Params[2])
141
142@@ -623,3 +668,10 @@ func (s *Session) send(format string, args ...interface{}) (err error) {
143 }
144
145 // */
146+
147+/*
148+func (s *Session) send(format string, args ...interface{}) (err error) {
149+ go fmt.Fprintf(s.conn, format, args...)
150+ return
151+}
152+// */
+6,
-0
1@@ -201,6 +201,12 @@ func (msg *Message) Validate() (err error) {
2 } else if msg.Prefix == "" {
3 err = errNoPrefix
4 }
5+ case "PART":
6+ if len(msg.Params) < 1 {
7+ err = errNotEnoughParams
8+ } else if msg.Prefix == "" {
9+ err = errNoPrefix
10+ }
11 case "353":
12 if len(msg.Params) < 4 {
13 err = errNotEnoughParams
M
ui/ui.go
+5,
-1
1@@ -34,7 +34,7 @@ func New() (ui *UI, err error) {
2 ui.screen.Clear()
3 ui.screen.ShowCursor(0, h-2)
4
5- ui.Events = make(chan tcell.Event)
6+ ui.Events = make(chan tcell.Event, 128)
7 go func() {
8 for !ui.ShouldExit() {
9 ui.Events <- ui.screen.PollEvent()
10@@ -125,6 +125,10 @@ func (ui *UI) AddLine(buffer string, line string, t time.Time) {
11 }
12 }
13
14+func (ui *UI) Input() string {
15+ return string(ui.textInput)
16+}
17+
18 func (ui *UI) InputRune(r rune) {
19 ui.textInput = append(ui.textInput, r)
20 ui.textCursor++