":some.where 001 factorbot :Welcome factorbot"
} make-client
{ [ connect-irc ]
- [ drop 1 seconds sleep ]
+ [ drop 0.1 seconds sleep ]
[ profile>> nickname>> ]
[ terminate-irc ]
} cleave ] unit-test
} make-client
{ [ "factorbot" set-nick ]
[ connect-irc ]
- [ drop 1 seconds sleep ]
- [ join-messages>> 1 seconds mailbox-get-timeout ]
+ [ drop 0.1 seconds sleep ]
+ [ join-messages>> 0.1 seconds mailbox-get-timeout ]
[ terminate-irc ]
} cleave
[ class ] [ trailing>> ] bi ] unit-test
} cleave
[ class ] [ name>> ] [ trailing>> ] tri
] unit-test
+
+! Participants lists tests
+{ H{ { "somedude" +normal+ } } } [
+ { ":somedude!n=user@isp.net JOIN :#factortest" } make-client
+ { [ "factorbot" set-nick ]
+ [ listeners>>
+ [ "#factortest" [ <irc-channel-listener> ] keep ] dip set-at ]
+ [ connect-irc ]
+ [ drop 0.1 seconds sleep ]
+ [ listeners>> [ "#factortest" ] dip at participants>> ]
+ [ terminate-irc ]
+ } cleave
+ ] unit-test
+
+{ H{ { "somedude2" +normal+ } } } [
+ { ":somedude!n=user@isp.net PART #factortest" } make-client
+ { [ "factorbot" set-nick ]
+ [ listeners>>
+ [ "#factortest" [ <irc-channel-listener>
+ H{ { "somedude2" +normal+ }
+ { "somedude" +normal+ } } clone >>participants ] keep
+ ] dip set-at ]
+ [ connect-irc ]
+ [ drop 0.1 seconds sleep ]
+ [ listeners>> [ "#factortest" ] dip at participants>> ]
+ [ terminate-irc ]
+ } cleave
+ ] unit-test
+
+{ H{ { "somedude2" +normal+ } } } [
+ { ":somedude!n=user@isp.net QUIT" } make-client
+ { [ "factorbot" set-nick ]
+ [ listeners>>
+ [ "#factortest" [ <irc-channel-listener>
+ H{ { "somedude2" +normal+ }
+ { "somedude" +normal+ } } clone >>participants ] keep
+ ] dip set-at ]
+ [ connect-irc ]
+ [ drop 0.1 seconds sleep ]
+ [ listeners>> [ "#factortest" ] dip at participants>> ]
+ [ terminate-irc ]
+ } cleave
+ ] unit-test
+
+{ H{ { "somedude2" +normal+ } } } [
+ { ":somedude2!n=user2@isp.net KICK #factortest somedude" } make-client
+ { [ "factorbot" set-nick ]
+ [ listeners>>
+ [ "#factortest" [ <irc-channel-listener>
+ H{ { "somedude2" +normal+ }
+ { "somedude" +normal+ } } clone >>participants ] keep
+ ] dip set-at ]
+ [ connect-irc ]
+ [ drop 0.1 seconds sleep ]
+ [ listeners>> [ "#factortest" ] dip at participants>> ]
+ [ terminate-irc ]
+ } cleave
+ ] unit-test
+
+! Namelist notification
+{ T{ participant-changed f f f } } [
+ { ":ircserver.net 353 factorbot @ #factortest :@factorbot "
+ ":ircserver.net 366 factorbot #factortest :End of /NAMES list." } make-client
+ { [ "factorbot" set-nick ]
+ [ listeners>>
+ [ "#factortest" [ <irc-channel-listener> ] keep ] dip set-at ]
+ [ connect-irc ]
+ [ drop 0.1 seconds sleep ]
+ [ listeners>> [ "#factortest" ] dip at [ read-message drop ] [ read-message ] bi ]
+ [ terminate-irc ]
+ } cleave
+ ] unit-test
\ No newline at end of file
dup irc-message-origin to-listener ;
M: join handle-incoming-irc ( join -- )
- { [ maybe-forward-join ] ! keep
+ { [ maybe-forward-join ]
[ dup trailing>> to-listener ]
- [ [ drop f ] [ prefix>> parse-name ] [ trailing>> ] tri add-participant ]
+ [ [ drop +normal+ ] [ prefix>> parse-name ] [ trailing>> ] tri add-participant ]
[ handle-participant-change ]
} cleave ;
tri ;
M: kick handle-incoming-irc ( kick -- )
- { [ dup channel>> to-listener ]
+ { [ dup channel>> to-listener ]
[ [ who>> ] [ channel>> ] bi remove-participant ]
[ handle-participant-change ]
[ dup who>> me? [ unregister-listener ] [ drop ] if ]
} cleave ;
M: quit handle-incoming-irc ( quit -- )
- { [ dup prefix>> parse-name listeners-with-participant
- [ to-listener ] with each ]
- [ handle-participant-change ]
- [ prefix>> parse-name remove-participant-from-all ]
- [ call-next-method ]
- } cleave ;
+ [ dup prefix>> parse-name listeners-with-participant
+ [ to-listener ] with each ]
+ [ prefix>> parse-name remove-participant-from-all ]
+ [ handle-participant-change ]
+ tri ;
: >nick/mode ( string -- nick mode )
dup first "+@" member? [ unclip ] [ 0 ] if participant-mode ;
[ >nick/mode 2array ] map >hashtable ;
M: names-reply handle-incoming-irc ( names-reply -- )
- [ names-reply>participants ] [ channel>> listener> ] bi
- [ (>>participants) ] [ drop ] if* ;
+ [ names-reply>participants ] [ channel>> listener> ] bi [
+ [ (>>participants) ]
+ [ [ f f <participant-changed> ] dip name>> to-listener ] bi
+ ] [ drop ] if* ;
M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- )
broadcast-message-to-listeners ;
"ircserver.net" >>prefix
"MODE" >>command
{ "#factortest" "+ns" } >>parameters
- "#factortest" >>channel
+ "#factortest" >>channel
"+ns" >>mode
1array
[ ":ircserver.net MODE #factortest +ns"
+ parse-irc-line f >>timestamp ] unit-test
+
+nick new
+ ":someuser!n=user@some.where NICK :someuser2" >>line
+ "someuser!n=user@some.where" >>prefix
+ "NICK" >>command
+ { } >>parameters
+ "someuser2" >>trailing
+1array
+[ ":someuser!n=user@some.where NICK :someuser2"
parse-irc-line f >>timestamp ] unit-test
\ No newline at end of file
TUPLE: join < irc-message ;
TUPLE: part < irc-message channel ;
TUPLE: quit < irc-message ;
+TUPLE: nick < irc-message ;
TUPLE: privmsg < irc-message name ;
TUPLE: kick < irc-message channel who ;
TUPLE: roomlist < irc-message channel names ;
M: join irc-command-string ( join -- string ) drop "JOIN" ;
M: part irc-command-string ( part -- string ) drop "PART" ;
M: quit irc-command-string ( quit -- string ) drop "QUIT" ;
+M: nick irc-command-string ( nick -- string ) drop "NICK" ;
M: privmsg irc-command-string ( privmsg -- string ) drop "PRIVMSG" ;
M: notice irc-command-string ( notice -- string ) drop "NOTICE" ;
M: mode irc-command-string ( mode -- string ) drop "MODE" ;
M: join irc-command-parameters ( join -- seq ) drop { } ;
M: part irc-command-parameters ( part -- seq ) name>> 1array ;
M: quit irc-command-parameters ( quit -- seq ) drop { } ;
+M: nick irc-command-parameters ( nick -- seq ) drop { } ;
M: privmsg irc-command-parameters ( privmsg -- seq ) name>> 1array ;
M: notice irc-command-parameters ( norice -- seq ) type>> 1array ;
M: kick irc-command-parameters ( kick -- seq )
{ "353" [ names-reply ] }
{ "JOIN" [ join ] }
{ "PART" [ part ] }
+ { "NICK" [ nick ] }
{ "PRIVMSG" [ privmsg ] }
{ "QUIT" [ quit ] }
{ "MODE" [ mode ] }
sequences strings hashtables splitting fry assocs hashtables\r
ui ui.gadgets ui.gadgets.panes ui.gadgets.editors\r
ui.gadgets.scrollers ui.commands ui.gadgets.frames ui.gestures\r
- ui.gadgets.tabs ui.gadgets.grids ui.gadgets.lists ui.gadgets.labels\r
+ ui.gadgets.tabs ui.gadgets.grids ui.gadgets.packs ui.gadgets.labels\r
io io.styles namespaces calendar calendar.format models continuations\r
irc.client irc.client.private irc.messages irc.messages.private\r
irc.ui.commandparser irc.ui.load qualified ;\r
\r
TUPLE: ui-window client tabs ;\r
\r
-TUPLE: irc-tab < frame listener client listmodel ;\r
+TUPLE: irc-tab < frame listener client userlist ;\r
\r
: write-color ( str color -- )\r
foreground associate format ;\r
\r
GENERIC: handle-inbox ( tab message -- )\r
\r
-: filter-participants ( assoc val -- alist )\r
- [ >alist ] dip\r
- '[ second , = ] filter ;\r
+: filter-participants ( pack alist val color -- )\r
+ '[ , = [ <label> , >>color add-gadget ] [ drop ] if ] assoc-each ;\r
\r
: update-participants ( tab -- )\r
- [ listmodel>> ] [ listener>> participants>> ] bi\r
- [ +operator+ filter-participants ]\r
- [ +voice+ filter-participants ]\r
- [ +normal+ filter-participants ] tri\r
- append append swap set-model ;\r
+ [ userlist>> [ clear-gadget ] keep ]\r
+ [ listener>> participants>> ] bi\r
+ [ +operator+ green filter-participants ]\r
+ [ +voice+ blue filter-participants ]\r
+ [ +normal+ black filter-participants ] 2tri ;\r
\r
M: participant-changed handle-inbox\r
drop update-participants ;\r
{ T{ key-down f f "ENTER" } editor-send }\r
} define-command-map\r
\r
-: <irc-list> ( -- gadget model )\r
- [ drop ]\r
- [ first2 [ <label> ] dip >>color ]\r
- { } <model> [ <list> ] keep ;\r
-\r
: <irc-tab> ( listener client -- irc-tab )\r
irc-tab new-frame\r
swap client>> >>client swap >>listener\r
\r
: <irc-channel-tab> ( listener client -- irc-tab )\r
<irc-tab>\r
- <irc-list> [ <scroller> @right grid-add ] dip >>listmodel\r
- [ update-participants ] keep ;\r
+ <pile> [ <scroller> @right grid-add ] keep >>userlist ;\r
\r
: <irc-server-tab> ( listener client -- irc-tab )\r
<irc-tab> ;\r
\r
M: irc-tab graft*\r
- [ listener>> ] [ client>> ] bi\r
- add-listener ;\r
+ [ listener>> ] [ client>> ] bi add-listener ;\r
\r
M: irc-tab ungraft*\r
- [ listener>> ] [ client>> ] bi\r
- remove-listener ;\r
+ [ listener>> ] [ client>> ] bi remove-listener ;\r
+\r
+M: irc-tab pref-dim*\r
+ drop { 480 480 } ;\r
\r
: join-channel ( name ui-window -- )\r
[ dup <irc-channel-listener> ] dip\r