Class ::xo::ChatClass

::xo::ChatClass[i] create ...

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xotcl::Class[i]
::xotcl::Class create ::xo::ChatClass \
     -superclass ::xotcl::Class

Methods (to be applied on the object)

  • is_chat_p (scripted)

    return [expr {[nsf::is object $class] && [$class class] eq [self]}]

Methods (to be applied on instances)

  • flush_messages (scripted)

    set array "[self]-$chat_id"
    ::acs::clusterwide nsv_unset -nocomplain $array
    ::acs::clusterwide nsv_unset -nocomplain $array-seen
    ::acs::clusterwide nsv_unset -nocomplain $array-last-activity
  • init (scripted)

    # default setting is set19 from http://www.graphviz.org/doc/info/colors.html
    # per parameter settings in the chat package are available (param UserColors)
    set :colors [list #1b9e77 #d95f02 #7570b3 #e7298a #66a61e #e6ab02 #a6761d #666666]
  • initialize_nsvs (scripted)

    # empty stub for subclasses to extend
  • login (scripted, public)

     <instance of xo::ChatClass[i]> login -chat_id chat_id  \
        [ -skin skin ] [ -package_id package_id ] [ -mode mode ] \
        [ -path path ] [ -avatar_p on|off ] [ -force_login_p on|off ] \
        [ -login_messages_p on|off ] [ -logout_messages_p on|off ] \
        [ -timewindow timewindow ]

    Logs into a chat

    Switches:
    -chat_id
    (required)
    -skin
    (defaults to "classic") (optional)
    -package_id
    (optional)
    -mode
    (optional)
    -path
    (optional)
    -avatar_p
    (boolean) (defaults to "true") (optional)
    -force_login_p
    (boolean) (defaults to "false") (optional)
    -login_messages_p
    (boolean) (optional)
    -logout_messages_p
    (boolean) (optional)
    -timewindow
    (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3 _ _ (public) ad_conn ad_conn (public) apm_package_installed_p apm_package_installed_p (public) auth::require_login auth::require_login (public) export_vars export_vars (public) xo::ChatClass instproc login xo::ChatClass instproc login xo::ChatClass instproc login->_ xo::ChatClass instproc login->ad_conn xo::ChatClass instproc login->apm_package_installed_p xo::ChatClass instproc login->auth::require_login xo::ChatClass instproc login->export_vars

    Testcases:
    No testcase defined.
    #:log "--chat"
    if {![ns_conn isconnected]} {
      return
    }
    if {$force_login_p} {
      auth::require_login
    }
    
    # This might come in handy to get resources from the chat package
    # if we want to have e.g. a separate css.
    # set package_key [apm_package_key_from_id $package_id]
    # set resources_path /resources/${package_key}
    template::head::add_css -href /resources/xowiki/chat-skins/chat-$skin.css
    
    #
    # Check, whether we have the tcllibthread and a sufficiently new
    # AOLserver/NaviServer supporting bgdelivery transfers. When this
    # is missing, we must force the mode to polling.
    #
    if {[info commands ::thread::mutex] eq "" ||
        [catch {ns_conn contentsentlength}]} {
      set mode polling
    }
    
    set session_id [ad_conn session_id].[clock seconds]
    set base_url [export_vars -base /shared/ajax/chat -no_empty {
      {id $chat_id} {s $session_id} {class "[self]"} mode
    }]
    
    # get LinkRegex parameter from the chat package
    set link_regex [::parameter::get_global_value  -package_key "chat"  -parameter "LinkRegex"]
    
    # Should we add a full screen link to the chat?
    set fs_link_p true
    
    # Should we display avatars? (JavaScript can only take 'true' or 'false' as boolean values)
    if {$avatar_p} {
        set show_avatar true
    } else {
        set show_avatar false
    }
    
    template::head::add_javascript -script "const linkRegex = \"${link_regex}\";" -order 19
    template::head::add_javascript -script "const show_avatar = $show_avatar;" -order 20
    template::head::add_javascript -src /resources/xowiki/chat-skins/chat-$skin.js -order 22
    template::head::add_javascript -src /resources/xowiki/chat.js -order 30
    
    #:log "--CHAT mode=$mode"
    
    set html ""
    
    if {[apm_package_installed_p chat]} {
      set message_label [_ xowiki.chat_message]
      set send_label [_ xowiki.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 {
      <div id='xowiki-chat'>
         <div id='xowiki-chat-messages-and-form'>
           <div id='xowiki-chat-messages'></div>
           <div id='xowiki-chat-messages-form-block'>
             <form id='xowiki-chat-messages-form' action='#'>
               <input type='text' placeholder="$message_label" name='msg' id='xowiki-chat-send' autocomplete="off" />
               <button id='xowiki-chat-send-button' type='submit'>$send_label</button>
             </form>
           </div>
         </div>
         <div id='xowiki-chat-users'></div>
      </div>
    }]
    
    set conf [dict create]
    foreach var {force_login_p login_messages_p logout_messages_p timewindow} {
      if {[info exists $var]} {
        dict set conf $var [set $var]
      }
    }
    
    :create c1  -chat_id    $chat_id  -session_id $session_id  -mode       $mode  -conf       $conf  -destroy_on_cleanup
    #:log "--CHAT created c1 with mode=$mode"
    
    append html [subst {
      <span id="xowiki-my-user-id" style="display:none;">[c1 set user_id]</span>
    }]
    
    set js ""
    set data [c1 login]
    if {$data ne ""} {
      append js [subst -nocommands {
        let data = $data;
        for (var i = 0; i < data.length; i++) {
          renderData(data[i]);
        }
      }]
    }
    
    if {$fs_link_p} {
      append js {addFullScreenLink();}
    }
    
    append js {addSendPic();}
    
    #:log "--CHAT create HTML for mode=$mode"
    
    append js [subst {
      chatSubscribe('$base_url');
    }]
    
    #
    # A chat may be embedded later in the page's lifecycle, e.g. when
    # it is extracted from a template. The javascript to subscribe
    # should trigger when the markup becomes part of the DOM.
    #
    append html [subst {
      <script nonce="[security::csp::nonce]">
        $js
      </script>
    }]
    
    template::add_refresh_on_history_handler
    
    return $html
  • sweep_all_chats (scripted)

    #:log "-- starting"
    foreach nsv [nsv_names "[self]-*-seen"] {
      if { [regexp "[self]-(\[0-9\]+)-seen" $nsv _ chat_id] } {
        #:log "--Chat_id $chat_id"
        :new -volatile -chat_id $chat_id -user_id 0 -session_id 0 -init -sweeper
      }
    }
    #:log "-- ending"

Variables

::xo::ChatClass set __default_metaclass ::xotcl::Class
::xo::ChatClass set __default_superclass ::xotcl::Object