1 ! Copyright (C) 2008 William Schlieper
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
4 USING: accessors kernel threads combinators concurrency.mailboxes
\r
5 sequences strings hashtables splitting fry assocs hashtables
\r
6 ui ui.gadgets ui.gadgets.panes ui.gadgets.editors
\r
7 ui.gadgets.scrollers ui.commands ui.gadgets.frames ui.gestures
\r
8 ui.gadgets.tabs ui.gadgets.grids ui.gadgets.packs ui.gadgets.labels
\r
9 io io.styles namespaces calendar calendar.format models continuations
\r
10 irc.client irc.client.private irc.messages irc.messages.private
\r
11 irc.ui.commandparser irc.ui.load qualified ;
\r
13 RENAME: join sequences => sjoin
\r
21 TUPLE: ui-window client tabs ;
\r
23 TUPLE: irc-tab < frame listener client userlist ;
\r
25 : write-color ( str color -- )
\r
26 foreground associate format ;
\r
27 : red { 0.5 0 0 1 } ;
\r
28 : green { 0 0.5 0 1 } ;
\r
29 : blue { 0 0 1 1 } ;
\r
30 : black { 0 0 0 1 } ;
\r
32 : colors H{ { +operator+ { 0 0.5 0 1 } }
\r
33 { +voice+ { 0 0 1 1 } }
\r
34 { +normal+ { 0 0 0 1 } } } ;
\r
36 : dot-or-parens ( string -- string )
\r
37 dup empty? [ drop "." ]
\r
38 [ "(" prepend ")" append ] if ;
\r
40 GENERIC: write-irc ( irc-message -- )
\r
42 M: privmsg write-irc
\r
43 "<" blue write-color
\r
44 [ prefix>> parse-name write ] keep
\r
45 "> " blue write-color
\r
48 TUPLE: own-message message nick timestamp ;
\r
50 : <own-message> ( message nick -- own-message )
\r
51 now own-message boa ;
\r
53 M: own-message write-irc
\r
54 "<" blue write-color
\r
55 [ nick>> bold font-style associate format ] keep
\r
56 "> " blue write-color
\r
60 "* " green write-color
\r
61 prefix>> parse-name write
\r
62 " has entered the channel." green write-color ;
\r
65 "* " red write-color
\r
66 [ prefix>> parse-name write ] keep
\r
67 " has left the channel" red write-color
\r
68 trailing>> dot-or-parens red write-color ;
\r
71 "* " red write-color
\r
72 [ prefix>> parse-name write ] keep
\r
73 " has left IRC" red write-color
\r
74 trailing>> dot-or-parens red write-color ;
\r
76 : full-mode ( message -- mode )
\r
77 parameters>> rest " " sjoin ;
\r
80 "* " blue write-color
\r
81 [ prefix>> parse-name write ] keep
\r
82 " has applied mode " blue write-color
\r
83 [ full-mode write ] keep
\r
84 " to " blue write-color
\r
87 M: unhandled write-irc
\r
89 line>> blue write-color ;
\r
91 M: irc-end write-irc
\r
92 drop "* You have left IRC" red write-color ;
\r
94 M: irc-disconnected write-irc
\r
95 drop "* Disconnected" red write-color ;
\r
97 M: irc-connected write-irc
\r
98 drop "* Connected" green write-color ;
\r
100 M: irc-listener-end write-irc
\r
103 M: irc-message write-irc
\r
104 drop ; ! catch all unimplemented writes, THIS WILL CHANGE
\r
106 : time-happened ( irc-message -- timestamp )
\r
107 [ timestamp>> ] [ 2drop now ] recover ;
\r
109 : print-irc ( irc-message -- )
\r
110 [ time-happened timestamp>hms write " " write ]
\r
111 [ write-irc nl ] bi ;
\r
113 : send-message ( message -- )
\r
115 [ listener get write-message ] bi ;
\r
117 GENERIC: handle-inbox ( tab message -- )
\r
119 : filter-participants ( pack alist val color -- )
\r
120 '[ , = [ <label> , >>color add-gadget ] [ drop ] if ] assoc-each ;
\r
122 : update-participants ( tab -- )
\r
123 [ userlist>> [ clear-gadget ] keep ]
\r
124 [ listener>> participants>> ] bi
\r
125 [ +operator+ green filter-participants ]
\r
126 [ +voice+ blue filter-participants ]
\r
127 [ +normal+ black filter-participants ] 2tri ;
\r
129 M: participant-changed handle-inbox
\r
130 drop update-participants ;
\r
132 M: object handle-inbox
\r
135 : display ( stream tab -- )
\r
137 [ , dup listener>> read-message handle-inbox ]
\r
138 [ ] while ] with-output-stream ] "ircv" spawn drop ;
\r
140 : <irc-pane> ( tab -- tab pane )
\r
142 [ <pane-stream> swap display ] 2keep ;
\r
144 TUPLE: irc-editor < editor outstream listener client ;
\r
146 : <irc-editor> ( tab pane -- tab editor )
\r
147 over irc-editor new-editor
\r
148 swap listener>> >>listener swap <pane-stream> >>outstream
\r
149 over client>> >>client ;
\r
151 : editor-send ( irc-editor -- )
\r
156 [ "" swap set-editor-string ] } cleave
\r
157 '[ , listener set , client set , parse-message ] with-output-stream ;
\r
159 irc-editor "general" f {
\r
160 { T{ key-down f f "RET" } editor-send }
\r
161 { T{ key-down f f "ENTER" } editor-send }
\r
162 } define-command-map
\r
164 : <irc-tab> ( listener client -- irc-tab )
\r
166 swap client>> >>client swap >>listener
\r
167 <irc-pane> [ <scroller> @center grid-add ] keep
\r
168 <irc-editor> <scroller> @bottom grid-add ;
\r
170 : <irc-channel-tab> ( listener client -- irc-tab )
\r
172 <pile> [ <scroller> @right grid-add ] keep >>userlist ;
\r
174 : <irc-server-tab> ( listener client -- irc-tab )
\r
178 [ listener>> ] [ client>> ] bi add-listener ;
\r
180 M: irc-tab ungraft*
\r
181 [ listener>> ] [ client>> ] bi remove-listener ;
\r
183 M: irc-tab pref-dim*
\r
186 : join-channel ( name ui-window -- )
\r
187 [ dup <irc-channel-listener> ] dip
\r
188 [ <irc-channel-tab> swap ] keep
\r
191 : irc-window ( ui-window -- )
\r
193 [ client>> profile>> server>> ] bi
\r
196 : ui-connect ( profile -- ui-window )
\r
197 <irc-client> ui-window new over >>client swap
\r
199 [ [ <irc-server-listener> ] dip add-listener ]
\r
200 [ listeners>> +server-listener+ swap at over <irc-tab>
\r
201 "Server" associate <tabbed> >>tabs ] tri ;
\r
203 : server-open ( server port nick password channels -- )
\r
204 [ <irc-profile> ui-connect [ irc-window ] keep ] dip
\r
205 [ over join-channel ] each drop ;
\r
207 : main-run ( -- ) run-ircui ;
\r