Index: openacs-4/packages/chat/chat.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/chat.info,v diff -u -r1.20 -r1.21 --- openacs-4/packages/chat/chat.info 12 Jul 2018 12:43:09 -0000 1.20 +++ openacs-4/packages/chat/chat.info 28 Sep 2018 11:44:23 -0000 1.21 @@ -9,7 +9,7 @@ f t - + Peter Alberer Server based chat with an html and ajax client. 2017-08-06 @@ -18,9 +18,9 @@ Adapted by Tekne 2006/03/01 to replace JAVA server with AJAX; make use of generalized chat class from xotcl-core. 0 - + - + Index: openacs-4/packages/chat/tcl/chat-ajax-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/tcl/chat-ajax-procs.tcl,v diff -u -r1.19 -r1.20 --- openacs-4/packages/chat/tcl/chat-ajax-procs.tcl 20 Sep 2018 13:28:30 -0000 1.19 +++ openacs-4/packages/chat/tcl/chat-ajax-procs.tcl 28 Sep 2018 11:44:23 -0000 1.20 @@ -8,78 +8,30 @@ } namespace eval ::chat { - ::xo::ChatClass Chat -superclass ::xo::Chat + ::xo::ChatClass Chat -superclass ::xowiki::Chat + Chat instproc initialize_nsvs {} { + next + + # read the last_activity information at server start into a nsv array + ::xo::dc foreach get_rooms { + select room_id, to_char(max(creation_date),'HH24:MI:SS YYYY-MM-DD') as last_activity + from chat_msgs group by room_id + } { + ::xo::clusterwide nsv_set [self]-$room_id-seen last [clock scan $last_activity] + } + } + Chat instproc init {} { - :instvar chat_id - if {[chat_room_exists_p $chat_id]} { - chat_room_get -room_id $chat_id -array c + if {[chat_room_exists_p ${:chat_id}]} { + chat_room_get -room_id ${:chat_id} -array c set :login_messages_p $c(login_messages_p) set :logout_messages_p $c(logout_messages_p) set :timewindow $c(messages_time_window) } next } - Chat proc login {-chat_id -package_id} { - auth::require_login - if {![info exists package_id]} { - set package_id [ad_conn package_id] - } - if {![info exists chat_id]} { - set chat_id $package_id - } - - set path [lindex [site_node::get_url_from_object_id -object_id $package_id] 0] - set base_url ${path}ajax/chat - template::head::add_javascript -src ${base_url}.js - set base_url [export_vars -base ${base_url} {{id $chat_id} {s "[ad_conn session_id].[clock seconds]"}}] - - set login_url [ns_quotehtml "${base_url}&m=login"] - set send_url "${base_url}&m=add_msg&msg=" - set users_url [ns_quotehtml "${base_url}&m=get_users"] - set html_url [ns_quotehtml [ad_conn url]?[ad_conn query]] - regsub {client=ajax} $html_url {client=html} html_url - - return [subst { - -
- - - - <p>#chat.Your_browser_doesnt_support_#</p> - <p><a href='$html_url'>#chat.Go_to_html_version#</a></p> - -
- #chat.message# - -
-
- - - }] - } - # if chat doesn't exist anymore, send a message that will inform # the user of being looking at an invalid chat Chat instproc check_valid_room {} { Fisheye: Tag 1.9 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/ajax-chat-script.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.8 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/ajax-chat-script.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/chat/www/chat.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/chat.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/chat/www/chat.adp 28 Sep 2018 11:44:23 -0000 1.1 @@ -0,0 +1,12 @@ + +@context;literal@ +doc +ichat_form.msg + +

@doc.title@

+

+#chat.Log_off# +#chat.Transcript# +

+ +@chat_frame;noquote@ Index: openacs-4/packages/chat/www/chat.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/chat.tcl,v diff -u -r1.17 -r1.18 --- openacs-4/packages/chat/www/chat.tcl 7 Aug 2017 23:48:07 -0000 1.17 +++ openacs-4/packages/chat/www/chat.tcl 28 Sep 2018 11:44:23 -0000 1.18 @@ -8,8 +8,6 @@ @cvs-id $Id$ } { room_id:naturalnum,notnull - {client "ajax"} - {message:html ""} } -properties { context:onevalue user_id:onevalue @@ -55,24 +53,8 @@ ad_script_abort } -# Get chat screen name. -set user_name [chat_user_name $user_id] +template::head::add_css -href resources/chat.css -# Determine which template to use for html or ajax client -switch $client { - "html" { - set template_use "html-chat" - # forward to ajax if necessary - if { $message ne "" } { - set session_id [ad_conn session_id] - ::chat::Chat c1 -volatile -chat_id $room_id -session_id $session_id - c1 add_msg $message - } - } - "ajax" { - set template_use "ajax-chat-script" - } -} - -ad_return_template $template_use - +set chat_frame [::chat::Chat login \ + -package_id [ad_conn package_id] \ + -chat_id $room_id] Fisheye: Tag 1.13 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/html-chat.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.8 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/html-chat.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/chat/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/index.tcl,v diff -u -r1.16 -r1.17 --- openacs-4/packages/chat/www/index.tcl 9 May 2018 15:33:30 -0000 1.16 +++ openacs-4/packages/chat/www/index.tcl 28 Sep 2018 11:44:23 -0000 1.17 @@ -18,27 +18,20 @@ set user_id [ad_conn user_id] set actions [list] set room_create_p [permission::permission_p -object_id $package_id -privilege chat_room_create] -set default_client [parameter::get -parameter "DefaultClient" -default "ajax"] set warning "" -if { $default_client eq "ajax" && ![apm_package_installed_p xotcl-core] } { - set warning "[_ chat.xotcl_missing]" -} - if { $room_create_p } { lappend actions "#chat.Create_a_new_room#" room-edit "#chat.Create_a_new_room#" } -db_multirow -extend { active_users last_activity room_url room_html_url} rooms rooms_list {} { +db_multirow -extend { active_users last_activity room_url} rooms rooms_list {} { set room [::chat::Chat create new -volatile -chat_id $room_id] set active_users [$room nr_active_users] set last_activity [$room last_activity] if { $active_p } { - set room_url [export_vars -base "room-enter" {room_id {client $default_client}}] + set room_url [export_vars -base "room-enter" {room_id}] set room_url [ns_quotehtml $room_url] - set room_html_url [export_vars -base "room-enter" {room_id {client html}}] - set room_html_url [ns_quotehtml $room_html_url] } } @@ -67,7 +60,7 @@ label "#chat.Room_name#" display_template { - @rooms.pretty_name@ \[#chat.HTML_chat#\] + @rooms.pretty_name@ @rooms.pretty_name@ Index: openacs-4/packages/chat/www/room-enter.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/Attic/room-enter.tcl,v diff -u -r1.10 -r1.11 --- openacs-4/packages/chat/www/room-enter.tcl 7 Aug 2017 23:48:07 -0000 1.10 +++ openacs-4/packages/chat/www/room-enter.tcl 28 Sep 2018 11:44:23 -0000 1.11 @@ -8,8 +8,7 @@ @cvs-id $Id$ } { room_id:naturalnum,notnull - client:trim -} +} set user_id [ad_conn user_id] @@ -25,21 +24,4 @@ ad_script_abort } -set default_client [parameter::get -parameter "DefaultClient" -default "ajax"] - -if {$default_client eq "java"} { - chat_start_server -} - -switch $client { - "html" - "ajax" - "html-chat-script" { - ns_log Notice "YY room-enter: has_entered_the room" - # apisano: I don't think this code should be here anymore, as - # message about user entering the room is already issued by - # the parent chat class in xotcl-core when we issue the login - # method - # chat_message_post $room_id $user_id "[_ chat.has_entered_the_room]." "1" - } -} - -ad_returnredirect "chat?room_id=$room_id&client=$client" +ad_returnredirect "chat?room_id=$room_id" Index: openacs-4/packages/chat/www/room-exit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/room-exit.tcl,v diff -u -r1.8 -r1.9 --- openacs-4/packages/chat/www/room-exit.tcl 7 Aug 2017 23:48:07 -0000 1.8 +++ openacs-4/packages/chat/www/room-exit.tcl 28 Sep 2018 11:44:23 -0000 1.9 @@ -20,16 +20,9 @@ ad_script_abort } -# apisano: I don't think this code should be here anymore, as -# message about user leaving the room is already issued by -# the parent chat class in xotcl-core when we issue the logout -# method -# chat_message_post $room_id $user_id "[_ chat.has_left_the_room]." "1" - # send to AJAX set session_id [ad_conn session_id] ::chat::Chat c1 -volatile -chat_id $room_id -session_id $session_id c1 logout ad_returnredirect index -#ad_returnredirect [dotlrn::get_url] Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/ajax/chat.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.6 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/ajax/chat.js'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/chat/www/ajax/chat.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/ajax/Attic/chat.tcl,v diff -u -r1.8 -r1.9 --- openacs-4/packages/chat/www/ajax/chat.tcl 18 Sep 2018 15:08:16 -0000 1.8 +++ openacs-4/packages/chat/www/ajax/chat.tcl 28 Sep 2018 11:44:23 -0000 1.9 @@ -5,10 +5,11 @@ @creation-date Jan 31, 2006 @cvs-id $Id$ } -query { - m - id + m:word + id:integer s - {msg:optional,allhtml ""} + msg:optional,allhtml + {mode ""} } set ban_p [permission::permission_p -object_id $id -privilege "chat_ban"] @@ -17,27 +18,25 @@ ad_script_abort } -set message_output "" -set user_output "" - -::chat::Chat c1 -volatile -chat_id $id -session_id $s - +#ns_log notice "--chat m=$m session_id=$s [clock format [lindex [split $s .] 1] -format %H:%M:%S] mode=$mode" +::chat::Chat create c1 -destroy_on_cleanup -chat_id $id -session_id $s -mode $mode switch -- $m { add_msg { - set message_output [c1 add_msg $msg] + #ns_log notice "--c call c1 $m '$msg'" + ns_return 200 application/json [c1 $m $msg] + ad_script_abort + #ns_log notice "--c add_msg returns '$_'" } - login - get_new - get_all { - set message_output [c1 $m] + get_new { + ns_return 200 application/json [c1 $m] + ad_script_abort } - get_updates { - set message_output [c1 get_new] - set user_output [c1 get_users] - } - get_users { - c1 encoder noencode - set user_output [c1 get_users] - } - default { - ns_log error "--c unknown method $m called." - } + login - + subscribe - + get_all {set _ [c1 $m]} + default {ns_log error "--c unknown method $m called."} } + +#ns_log notice "--chat.tcl $m: returns '$_'" + +ns_return 200 text/html [subst {$_}] Fisheye: Tag 1.2 refers to a dead (removed) revision in file `openacs-4/packages/chat/www/ajax/scripted-streaming-chat.js'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/chat/www/resources/chat.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/chat/www/resources/Attic/chat.css,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/chat/www/resources/chat.css 28 Sep 2018 11:44:23 -0000 1.1 @@ -0,0 +1,35 @@ +* { + box-sizing: border-box; +} + +#xowiki-chat-messages { + width: 74%; + height:100%; + overflow: auto; + float: left; + padding: 10px; + border: 1px black solid; + margin-right:1%; +} + +#xowiki-chat-users { + width: 25%; + height:100%; + overflow: auto; + float: left; + padding: 10px; + border: 1px black solid; +} + +/* Clear floats after the columns */ +#xowiki-chat { + height:257px; + margin-bottom: 1%; +} + +/* Clear floats after the columns */ +#xowiki-chat:after { + content: ""; + display: table; + clear: both; +} \ No newline at end of file Index: openacs-4/packages/xotcl-core/tcl/chat-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/Attic/chat-procs.tcl,v diff -u -r1.35 -r1.36 --- openacs-4/packages/xotcl-core/tcl/chat-procs.tcl 20 Sep 2018 13:28:30 -0000 1.35 +++ openacs-4/packages/xotcl-core/tcl/chat-procs.tcl 28 Sep 2018 11:44:23 -0000 1.36 @@ -7,7 +7,7 @@ } namespace eval ::xo { - Class create Message -parameter {time user_id msg color} + Class create Message -parameter {time user_id msg color {type "message"}} Class create Chat -superclass ::xo::OrderedComposite \ -parameter { chat_id @@ -16,7 +16,7 @@ {mode default} {encoder noencode} {timewindow 600} - {sweepinterval 599} + {sweepinterval 5} {login_messages_p t} {logout_messages_p t} } @@ -70,9 +70,8 @@ set msg [ns_quotehtml $msg] # :log "-- msg=$msg" - if {$get_new - && [info commands ::thread::mutex] ne "" - && [info commands ::bgdelivery] ne ""} { + if {[info commands ::thread::mutex] ne "" && + [info commands ::bgdelivery] ne ""} { # we could use the streaming interface :broadcast_msg [Message new -volatile -time [clock seconds] \ -user_id $user_id -color $color [list -msg $msg]] @@ -124,9 +123,9 @@ } } ::xo::clusterwide nsv_set ${:array}-seen ${:session_id} ${:now} - #my log "--c setting session_id ${:session_id}: ${:now}" + # my log "--c setting session_id ${:session_id}: ${:now}" } else { - #my log "--c nothing new for ${:session_id}" + # my log "--c nothing new for ${:session_id}" } :render } @@ -152,9 +151,11 @@ # was 1200 if {$ago > 300} { :logout -user_id $user -msg "auto logout" + # ns_log warning "-user_id $user auto logout" try {::bgdelivery do ::Subscriber sweep chat-[:chat_id]} } } + :broadcast_msg [Message new -volatile -type "users" -time [clock seconds]] :log "-- ending" } @@ -163,9 +164,9 @@ ns_log Notice "--core-chat User $user_id logging out of chat" if {${:logout_messages_p}} { if {$msg eq ""} {set msg [_ chat.has_left_the_room].} - :add_msg -get_new false $msg + :add_msg -uid $user_id -get_new false $msg } - + # These values could already not be here. Just ignore when we don't # find them try { @@ -192,15 +193,7 @@ } Chat instproc get_users {} { - set output "" - foreach {user_id timestamp} [:active_user_list] { - if {$user_id > 0} { - set diff [clock format [expr {[clock seconds] - $timestamp}] -format "%H:%M:%S" -gmt 1] - set userlink [:user_link -user_id $user_id] - append output "$userlink$diff\n" - } - } - return $output + return [:json_encode_msg [Message new -volatile -type "users" -time [clock seconds]]] } Chat instproc user_active {user_id} { @@ -212,8 +205,8 @@ Chat instproc login {} { :log "--chat login" if {${:login_messages_p} && ![:user_active ${:user_id}]} { - :add_msg -get_new false [_ xotcl-core.has_entered_the_room] - } elseif {![nsv_exists ${:array}-login ${:user_id}]} { + :add_msg -uid ${:user_id} -get_new false [_ xotcl-core.has_entered_the_room] + } elseif {${:user_id} > 0 && ![nsv_exists ${:array}-login ${:user_id}]} { # give some proof of our presence to the chat system when we # don't issue the login message ::xo::clusterwide nsv_set ${:array}-login ${:user_id} [clock seconds] @@ -253,7 +246,7 @@ } else { set creator "System" } - return [:encode $creator] + return $creator } Chat instproc urlencode {string} {ns_urlencode $string} @@ -264,25 +257,48 @@ } Chat instproc json_encode_msg {msg} { - set old [:encoder] - :encoder noencode ;# just for user_link - set userlink [:user_link -user_id [$msg user_id] -color [$msg color]] - :encoder $old - set timeshort [clock format [$msg time] -format {[%H:%M:%S]}] - set text [:json_encode [$msg msg]] - foreach var {userlink timeshort} {set $var [:json_encode [set $var]]} - return [subst -nocommands {{"messages": [ - {"user": "$userlink", "time": "$timeshort", "msg": "$text"} - ]\n} - }] + set type [$msg type] + switch $type { + "message" { + set message [$msg msg] + set user_id [$msg user_id] + set color [$msg color] + set user [:user_link -user_id $user_id -color $color] + set timestamp [clock format [$msg time] -format {[%H:%M:%S]}] + foreach var {message user timestamp} { + set $var [:json_encode [set $var]] + } + return [subst {{"type": "$type", "message": "$message", "timestamp": "$timestamp", "user": "$user"}\n}] + } + "users" { + set message [list] + foreach {user_id timestamp} [:active_user_list] { + if {$user_id < 0} continue + set timestamp [clock format [expr {[clock seconds] - $timestamp}] -format "%H:%M:%S" -gmt 1] + set user [:user_link -user_id $user_id] + foreach var {user timestamp} { + set $var [:json_encode [set $var]] + } + lappend message [subst {{"timestamp": "$timestamp", "user": "$user"}}] + } + set message "\[[join $message ,]\]" + return [subst {{"type": "$type", "chat_id": "[:chat_id]", "message": $message}\n}] + } + } } Chat instproc js_encode_msg {msg} { - set json [:json_encode_msg $msg] - return "\n" + set json [string trim [:json_encode_msg $msg]] + if {$json ne ""} { + return [subst { + \n + }] + } else { + return + } } Chat instproc broadcast_msg {msg} { @@ -295,34 +311,18 @@ set user_id [expr {[info exists uid] ? $uid : ${:user_id}}] set color [:user_color $user_id] bgdelivery subscribe chat-[:chat_id] "" [:mode] - if {${:login_messages_p} && ![:user_active $user_id]} { - :broadcast_msg [Message new -volatile -time [clock seconds] \ - -user_id $user_id -color $color \ - -msg [_ xotcl-core.has_entered_the_room] ] - } - #my get_all } Chat instproc render {} { :orderby time - set result "" + set result [list] + # Piggyback the users list in every rendering, this way we don't + # need a separate ajax request for the polling interface. + :add [Message new -type "users" -time [clock seconds]] foreach child [:children] { - set msg [$child msg] - set user_id [$child user_id] - set color [$child color] - set timelong [clock format [$child time]] - set timeshort [clock format [$child time] -format {[%H:%M:%S]}] - set userlink [:user_link -user_id $user_id -color $color] - ns_log notice "encode <$msg> using encoder [:encoder] gives <[:encode $msg]>" - append result [subst { -

- $timeshort - $userlink: - [:encode $msg] -

- }] + lappend result [:json_encode_msg $child] } - return $result + return "\[[join $result ,]\]" } ############################################################################ @@ -341,13 +341,7 @@ } ChatClass method initialize_nsvs {} { - # read the last_activity information at server start into a nsv array - ::xo::dc foreach get_rooms { - select room_id, to_char(max(creation_date),'HH24:MI:SS YYYY-MM-DD') as last_activity - from chat_msgs group by room_id - } { - ::xo::clusterwide nsv_set [self]-$room_id-seen last [clock scan $last_activity] - } + # empty stub for subclasses to extend } ChatClass method flush_messages {-chat_id:required} { Index: openacs-4/packages/xowiki/xowiki.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/xowiki.info,v diff -u -r1.173 -r1.174 --- openacs-4/packages/xowiki/xowiki.info 5 Aug 2018 22:08:18 -0000 1.173 +++ openacs-4/packages/xowiki/xowiki.info 28 Sep 2018 11:44:23 -0000 1.174 @@ -10,7 +10,7 @@ t xowiki - + Gustaf Neumann A xotcl-based enterprise wiki system with multiple object types 2017-08-06 @@ -55,7 +55,7 @@ BSD-Style 2 - + Index: openacs-4/packages/xowiki/tcl/chat-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/chat-procs.tcl,v diff -u -r1.29 -r1.30 --- openacs-4/packages/xowiki/tcl/chat-procs.tcl 20 Sep 2018 13:12:27 -0000 1.29 +++ openacs-4/packages/xowiki/tcl/chat-procs.tcl 28 Sep 2018 11:44:23 -0000 1.30 @@ -5,27 +5,46 @@ @author Gustaf Neumann @cvs-id $Id$ } + namespace eval ::xowiki { ::xo::ChatClass create Chat -superclass ::xo::Chat - Chat proc login {-chat_id -package_id {-mode ""} {-path ""}} { + ::xo::ChatClass instproc login {-chat_id -package_id {-mode ""} {-path ""}} { #:log "--chat" if {![ns_conn isconnected]} return auth::require_login - if {![info exists package_id]} {set package_id [ad_conn package_id] } - if {![info exists chat_id]} {set chat_id $package_id } - set session_id [ad_conn session_id].[clock seconds] - set context id=$chat_id&s=$session_id - set base_url ${path}ajax/chat?${context} + if {[ad_conn package_key] eq "xowiki"} { + set xowiki_package_id [ad_conn package_id] + } else { + set main_node_id [site_node::get_node_id -url "/"] + set xowiki_package_id [lindex [site_node::get_children -all \ + -package_key xowiki \ + -element object_id \ + -node_id $main_node_id] 0] + } + if {![info exists package_id]} { + set package_id $xowiki_package_id + } + #:log "chat_id=$chat_id, path=$path" if {$path eq ""} { - set path [lindex [site_node::get_url_from_object_id -object_id $package_id] 0] + set path [lindex [site_node::get_url_from_object_id \ + -object_id $package_id] 0] } elseif {[string index $path end] ne "/"} { append path / } + set xowiki_path [lindex [site_node::get_url_from_object_id \ + -object_id $xowiki_package_id] 0] + + if {![info exists chat_id]} {set chat_id $package_id} + + set session_id [ad_conn session_id].[clock seconds] + set context id=$chat_id&s=$session_id + set base_url ${path}ajax/chat?${context} + if {$mode eq ""} { # # The parameter "mode" was not specified, we try to guess the @@ -74,118 +93,110 @@ :log "--chat mode $mode" } - # small JavaScript library to obtain a portable ajax request object - ::xo::Page requireJS urn:ad:js:get-http-object - switch -- $mode { polling { - set jspath ${path}ajax/chat.js - set login_url ${base_url}&m=login - set get_update "chatSendCmd(\"${base_url}&m=get_new\",chatReceiver)" - set get_all "chatSendCmd(\"${base_url}&m=get_all\",chatReceiver)" + set jspath ${xowiki_path}ajax/chat.js + set subscribe_url ${base_url}&m=get_new } streaming { - set jspath ${path}ajax/streaming-chat.js + set jspath ${xowiki_path}ajax/streaming-chat.js set subscribe_url ${base_url}&m=subscribe } scripted-streaming { - set jspath ${path}ajax/scripted-streaming-chat.js + set jspath ${xowiki_path}ajax/scripted-streaming-chat.js set subscribe_url ${base_url}&m=subscribe&mode=scripted } default { error "mode $mode unknown, valid are: polling, streaming and scripted-streaming" } } - ::xo::Page requireJS $jspath - set users_url [ns_quotehtml ${base_url}&m=get_users] + # small JavaScript library to obtain a portable ajax request object + template::head::add_javascript -src urn:ad:js:get-http-object -order 10 + template::head::add_javascript -src ${xowiki_path}ajax/chat-common.js -order 20 + template::head::add_javascript -src $jspath -order 30 + set send_url ${base_url}&m=add_msg&msg= :log "--CHAT mode=$mode" - # TODO: styling should happen in some template - # set style { - # margin:1.5em 0 1.5em 0; - # padding:1em 0 1em 1em; - # background-color: #f9f9f9; - # border:1px solid #dedede; - # height:150px; - # font-size:.95em; - # line-height:.7em; - # color:#333; - # overflow:auto; - # } - template::add_body_script -script { - document.getElementById('chatMsg').focus(); + document.getElementById('xowiki-chat-send').focus(); } - if {$mode ne "polling"} { - ::xowiki::Chat create c1 \ + set html "" + + if {[apm_package_installed_p chat]} { + set message_label [_ chat.message] + set send_label [_ chat.Send_Refresh] + } else { + set message_label "Message" + set send_label "Send" + } + + # TODO: it is currently not possible to embed multiple chats in + # the same page. + append html [subst { +
+
+
+
+
+ $message_label + +
+ }] + + [self] create c1 \ -destroy_on_cleanup \ -chat_id $chat_id \ -session_id $session_id \ -mode $mode + + set data [c1 login] + if {$data ne ""} { + append html [subst { + + }] } - set html "" switch -- $mode { "polling" { - set r [subst { - - }] - template::add_event_listener \ - -id "messages-form" \ - -event "submit" \ - -script [subst { - chatSendMsg('$send_url',chatReceiver); - }] append html [subst -nocommands { }] + set send_msg_handler pollingSendMsgHandler } "streaming" { - set r [ns_urldecode [c1 get_all]] - template::add_event_listener \ - -id "messages-form" -event "submit" \ - -script {chatSendMsg();} append html [subst { }] + set send_msg_handler streamingSendMsgHandler } "scripted-streaming" { - set r [ns_urldecode [c1 get_all]] - template::add_event_listener \ - -id "messages-form" -event "submit" \ - -script {chatSendMsg();} append html [subst { - }] + set send_msg_handler scriptedStreamingSendMsgHandler } } - append html [subst { -
$r
-
- -
- }] + template::add_event_listener \ + -id "xowiki-chat-messages-form" -event "submit" \ + -script [subst {chatSendMsg('${send_url}', ${send_msg_handler});}] return $html } Index: openacs-4/packages/xowiki/www/ajax/chat-common.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/chat-common.js,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/xowiki/www/ajax/chat-common.js 28 Sep 2018 11:44:23 -0000 1.1 @@ -0,0 +1,63 @@ +// Common xowiki chat functions, mainly for data rendering. + +function renderData(json) { + if (json.type == "message") { + renderMessage(json); + } else if (json.type == "users") { + renderUsers(json); + } +} + +function renderMessage(msg) { + var messages = document.getElementById('xowiki-chat-messages'); + p = document.createElement('p'); + span = document.createElement('span'); + span.innerHTML = msg.timestamp; + span.className = 'xowiki-chat-timestamp'; + p.appendChild(span); + + span = document.createElement('span'); + var user = msg.user.replace("\\'", "'"); + span.innerHTML = ' ' + user + ': '; + span.className = 'xowiki-chat-user'; + p.appendChild(span); + + span = document.createElement('span'); + span.innerHTML = msg.message; + span.className = 'xowiki-chat-message'; + p.appendChild(span); + + messages.appendChild(p); + messages.scrollTop = messages.scrollHeight; +} + +function renderUsers(msg) { + var users = document.getElementById('xowiki-chat-users'); + while (users.hasChildNodes()) { + users.removeChild(users.firstChild); + } + for (var i = 0; i < msg.message.length; i++) { + p = document.createElement('p'); + span = document.createElement('span'); + span.innerHTML = msg.message[i].timestamp; + span.className = 'xowiki-chat-timestamp'; + p.appendChild(span); + + span = document.createElement('span'); + var user = msg.message[i].user.replace("\\'", "'"); + span.innerHTML = ' ' + user + ' '; + span.className = 'xowiki-chat-user'; + p.appendChild(span); + users.appendChild(p); + } +} + +function chatSendMsg(send_url, handler) { + var msgField = document.getElementById('xowiki-chat-send'); + var msg = msgField.value; + if (msg == '') {return;} + http_send.open('GET', send_url + encodeURIComponent(msg), true); + http_send.onreadystatechange = handler; + http_send.send(null); + msgField.value = ''; +} Index: openacs-4/packages/xowiki/www/ajax/chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/chat.js,v diff -u -r1.8 -r1.9 --- openacs-4/packages/xowiki/www/ajax/chat.js 29 Jul 2013 08:56:44 -0000 1.8 +++ openacs-4/packages/xowiki/www/ajax/chat.js 28 Sep 2018 11:44:23 -0000 1.9 @@ -3,50 +3,38 @@ // -gustaf neumann April 2006 var http = getHttpObject(); +var http_send = getHttpObject(); -function chatReceiver() { - if (http.readyState == 4) { - // alert('status code =' + http.status); - if (http.status == 200) { - appendToMessages(http.responseText); - } else { - clearInterval(); - alert('Something wrong in HTTP request, status code = ' + http.status); - } - } +function chatSubscribe(subscribe_url) { + setInterval(function () { + http.open('GET', subscribe_url); + http.onreadystatechange = function () { + if (http.readyState == 4) { + // alert('status code =' + http.status); + if (http.status == 200) { + var json = JSON.parse(http.responseText); + for (var i = 0; i < json.length; i++) { + renderData(json[i]); + } + } else { + clearInterval(); + alert('Something wrong in HTTP request, status code = ' + http.status); + } + } + }; + http.send(null); + }, 5000); } -function appendToMessages(content) { - var xmlobject = (new DOMParser()).parseFromString(content, 'application/xhtml+xml'); - var items = xmlobject.getElementsByTagName('div')[0].children; - - //console.debug("items: " + items.length); - //if (items.length > 0) {console.log(content);} - //if (items.length > 0) {console.log(items[0].innerHTML);} - - var doc = frames['ichat'].document; - var messages = frames['ichat'].document.getElementsByTagName('div')[0]; - for (var i = 0 ; i < items.length ; i++) { - var p = doc.createElement('p'); // add class 'line' - var att = doc.createAttribute("class"); - att.value = 'line'; - p.setAttributeNode(att); - p.innerHTML = decodeURIComponent(items[i].innerHTML).replace(/\+/g,' '); - messages.appendChild(p); +function pollingSendMsgHandler() { + if (http_send.readyState == 4) { + if (http_send.status != 200) { + alert('Something wrong in HTTP request, status code = ' + http_send.status); + } else { + var json = JSON.parse(http_send.responseText); + for (var i = 0; i < json.length; i++) { + renderData(json[i]); + } + } } - frames['ichat'].window.scrollTo(0,messages.offsetHeight); -} - - -function chatSendMsg(send_url,handler) { - var msgField = document.getElementById('chatMsg'); - chatSendCmd(send_url + encodeURIComponent(msgField.value),handler); - msgField.value = ''; -} - -var msgcount = 0; // hack to overcome IE -function chatSendCmd(url,handler) { - http.open('GET', url + '&mc=' + msgcount++, true); - http.onreadystatechange = handler; - http.send(null); -} +}; Index: openacs-4/packages/xowiki/www/ajax/chat.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/chat.tcl,v diff -u -r1.9 -r1.10 --- openacs-4/packages/xowiki/www/ajax/chat.tcl 7 Aug 2017 23:48:31 -0000 1.9 +++ openacs-4/packages/xowiki/www/ajax/chat.tcl 28 Sep 2018 11:44:23 -0000 1.10 @@ -17,39 +17,24 @@ switch -- $m { add_msg { #ns_log notice "--c call c1 $m '$msg'" - set _ [c1 $m $msg] + ns_return 200 application/json [c1 $m $msg] + ad_script_abort #ns_log notice "--c add_msg returns '$_'" } + get_new { + ns_return 200 application/json [c1 $m] + ad_script_abort + } login - subscribe - - get_new - get_all {set _ [c1 $m]} - default {ns_log error "--c unknown method $m called."} + default {ns_log error "--c unknown method $m called."} } #ns_log notice "--chat.tcl $m: returns '$_'" -set style { - padding:1em 0 1em 1em; - background-color: #f9f9f9; - font-size:.95em; - color:#333; - overflow:auto; -} +ns_return 200 text/html [subst {$_}] -ns_return 200 text/html " - - - -$_ - -" - # Local variables: # mode: tcl # tcl-indent-level: 2 Index: openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/scripted-streaming-chat.js,v diff -u -r1.7 -r1.8 --- openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js 20 Sep 2018 13:25:24 -0000 1.7 +++ openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js 28 Sep 2018 11:44:23 -0000 1.8 @@ -4,43 +4,17 @@ var http_send = getHttpObject(); +// This function MUST be there as in +// xotcl-core/tcl/bgdelivery-procs.tcl we expect getData to elaborate +// data coming from the continuos javascript iframe. function getData(data) { - var messages = document.getElementById('messages'); - for (var i=0;i