phpBB Part: Forum
MOD Name: AJAX Chat
MOD Version: 2.0.0 Beta 8
Author: Handyman
MOD Description: This Mod Adds AJAX Chat to your forum.
Users can chat without ever needing to reload the page.
Works with:
- RC7 (install instructions are for prosilver, but subsilver2 is included)
Features:
- AJAX Technology
- No page re-loading required
- Ability for Admins to delete posts in the Chat
- Shows who's online in the Chat
Licence: GNU General Public License v2
Screenshots: See the chat page or index page to see what it looks like.
Installation Level: Easy
Installation Time: ~3 Minutes
Format: MODX
Download File: http://startrekguide.com/mods/index.php ... ail&id=293
File Editor Notes
Make sure, when you edit the language file, that your text editor saves the language file as Unicode (UTF8) and WITHOUT a BOM signature.
If your text editor saves the language file with a BOM signature, you will see an error on your forums.
List of text editors that are capable of saving without BOM signature (this list is small since I just started compiling it)
note: if you are using a Mac, you can use almost any file editor available to you.
- ZEND
- Dreamweaver
- Rapid PHP 2007
Troubleshooting:
- Can't post bbcode or smilies in the chat -- Run the sql statement in the upgrade from beta 7 below.
- Forum header is included in the chat box when I make a post -- this is a problem with a few portals which annoyingly add their header/footer automatically to the template engine.
To fix it, replace the chat_body.html with this (subsilver2 style)Spoiler:- Code: Select all
<!-- IF S_GET_CHAT -->
<!-- IF S_READ or S_ADD -->
--!--
<!-- BEGIN chatrow -->
<div id="p{chatrow.MESSAGE_ID}">
<table class="tablebg" cellspacing="1" width="100%">
<tr>
<td class="<!-- IF chatrow.CLASS is even -->row2<!-- ELSEIF chatrow.CLASS is odd -->row1<!-- ENDIF -->" width="100%" align="left"><!-- IF U_ACP or U_MCP --> <a href="javascript:void({chatrow.MESSAGE_ID})" title="{L_DELETE_POST}" onClick="delete_post('{chatrow.MESSAGE_ID}')"><img src="{T_IMAGESET_LANG_PATH}/icon_post_delete.gif" /></a> <!-- ENDIF --> <b class="postauthor">{chatrow.USERNAME_FULL}</b> « {chatrow.TIME} » <span class="postbody">{chatrow.MESSAGE}</span> </td>
</tr>
</table>
</div>
<!-- END chatrow -->--!--{LAST_ID}
<!-- IF S_WHOISONLINE -->--!--
<!-- BEGIN whoisrow -->
<div><img src="{T_IMAGESET_PATH}/{whoisrow.USER_STATUS}.png" class="online_img" /> {whoisrow.USERNAME_FULL}</div>
<!-- END whoisrow -->--!--{LAST_TIME}--!--{DELAY}--!--{LAST_POST}
<!-- ENDIF -->
<!-- ENDIF -->
<!-- ELSE -->
<!-- IF S_CHAT -->
<!-- INCLUDE overall_header.html -->
<!-- ENDIF -->
<script type="text/javascript">
<!--
var fieldname = 'chat';
var last_time = 0;
var xmlHttp = http_object();
var last_id = {LAST_ID};
var type = 'receive';
var post_time = {TIME};
var read_interval = 15000;
var interval = setInterval('handle_send("read", last_id);', read_interval);
function handle_send(mode, f)
{
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
{
indicator_switch('on');
type = 'receive';
param = 'mode=' + mode;
param += '&last_id=' + last_id;
param += '&last_time=' + last_time;
param += '&last_post=' + post_time;
param += '&read_interval=' + read_interval;
if (mode == 'add' && document.text.message.value != '')
{
type = 'send';
for(var i = 0; i < f.elements.length; i++)
{
elem = f.elements[i];
param += '&' + elem.name + '=' + encodeURIComponent(elem.value);
}
document.text.message.value = '';
}
else if (mode == 'delete')
{
type = 'delete';
param += '&chat_id=' + f;
}
xmlHttp.open("POST", '{FILENAME}', true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = handle_return;
xmlHttp.send(param);
}
}
function handle_return()
{
if (xmlHttp.readyState == 4)
{
if (type != 'delete')
{
results = xmlHttp.responseText.split('--!--');
if (results[2])
{
if (last_id == 0)
{
document.getElementById(fieldname).innerHTML = results[1];
}
else
{
document.getElementById(fieldname).innerHTML = results[1] + document.getElementById(fieldname).innerHTML;
}
last_id = results[2];
if (results[3])
{
document.getElementById('whois_online').innerHTML = results[3];
last_time = results[4];
if (results[5] != read_interval * 1000)
{
window.clearInterval(interval);
read_interval = results[5] * 1000;
interval = setInterval('handle_send("read", last_id);', read_interval);
document.getElementById('update_seconds').innerHTML = results[5];
}
post_time = results[6];
}
}
}
indicator_switch('off');
}
}
function delete_post(chatid)
{
document.getElementById('p' + chatid).style.display = 'none';
handle_send('delete', chatid);
}
function indicator_switch(mode)
{
if(document.getElementById("act_indicator"))
{
var img = document.getElementById("act_indicator");
if(img.style.visibility == "hidden" && mode == 'on')
{
img.style.visibility = "visible";
}
else if (mode == 'off')
{
img.style.visibility = "hidden"
}
}
}
function http_object()
{
if (window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
document.getElementById('p_status').innerHTML = 'Status: Cound not create XmlHttpRequest Object. Consider upgrading your browser.';
}
}
-->
</script>
<style type="text/css">
<!--
.box
{
width: 100%;
margin-left: auto;
margin-right: auto;
}
.shouts {
width: 100%;
height:300px;
overflow:auto;
}
#chat {
width: 99%;
text-align:left;
}
#message {
width: 65%;
}
#whois_online{
vertical-align:text-top;
text-align:left;
}
.online_img {
vertical-align:middle;
}
#act_indicator {
visibility:hidden;
}
-->
</style>
<div class="box">
<br />
<table class="tablebg" cellspacing="1" width="100%">
<tr>
<td class="cat" width="100%" height="28" nowrap="nowrap">
<h4 align="center">{SITENAME} {L_CHAT_EXPLAIN}</h4>
</td>
</tr>
</table>
<table class="tablebg" cellspacing="1" width="100%">
<tr>
<th align="center" width="85%">
<!-- IF S_USER_LOGGED_IN -->
<form name="text" id="text" method="post" action="javascript:void(0);" onSubmit="handle_send('add', this)" autocomplete="off">{L_MESSAGE}:
<input type="text" tabindex="1" name="message" id="message" class="inputbox" size="28" />
<input class="btnmain" type="submit" name="submit" value="{L_SUBMIT}" />
</form>
<!-- ENDIF -->
</th>
<th align="center" width="15%" nowrap="nowrap">
{L_ONLINE_LIST}
</th>
</tr>
<tr>
<td class="row3" style="text-align:left;" height="220">
<div class="shouts">
<div id="chat">
<!-- BEGIN chatrow -->
<div id="p{chatrow.MESSAGE_ID}">
<table class="tablebg" cellspacing="1" width="100%">
<tr>
<td class="<!-- IF chatrow.CLASS is even -->row2<!-- ELSE -->row1<!-- ENDIF -->" align="left">
<!-- IF U_ACP or U_MCP -->
<a href="javascript:void({chatrow.MESSAGE_ID})" title="{L_DELETE_POST}" onClick="delete_post('{chatrow.MESSAGE_ID}')"><img src="{T_IMAGESET_LANG_PATH}/icon_post_delete.gif" /></a>
<!-- ENDIF -->
<b class="postauthor">{chatrow.USERNAME_FULL}</b> « {chatrow.TIME} » <span class="postbody">{chatrow.MESSAGE}</span>
</td>
</tr>
</table>
</div>
<!-- END chatrow -->
</div>
</div>
</td>
<td class="row1" width="15%" nowrap="nowrap">
<div class="shouts">
<div id="whois_online">
<!-- BEGIN whoisrow -->
<div>
<img src="{T_IMAGESET_PATH}/{whoisrow.USER_STATUS}.png" class="online_img" /> {whoisrow.USERNAME_FULL}
</div>
<!-- END whoisrow -->
</div>
</div>
</td>
</tr>
<tr>
<td class="cat" colspan="2" width="100%" height="28">
<div style="float: left;"> <img src="{T_THEME_PATH}/images/icon_mini_chat.png"> <a href="http://startrekguide.com/community/viewtopic.php?p=16364#p16364"><strong>AJAX Chat</strong></a> © 2007 <strong style="color: #7B95B2;">StarTrek</strong><strong style="color: #D98303;">Guide</strong></div><div style="float: right;"><img src="{T_IMAGESET_PATH}/act_indicator.gif" id="act_indicator" /> <strong>{L_UPDATES} <span id="update_seconds"> {DELAY} </span> {L_UNIT}</strong> </div>
</td>
</tr>
</table>
</div>
<!-- IF S_CHAT -->
<!-- ENDIF -->
<!-- ENDIF -->
Now for prosilver chat_body fix:Spoiler:<!-- IF S_GET_CHAT -->
<!-- IF S_READ or S_ADD -->
--!--
<!-- BEGIN chatrow -->
<div id="p{chatrow.MESSAGE_ID}" class="post bg{chatrow.CLASS}">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="postbody">
<!-- IF U_ACP or U_MCP -->
<ul class="profile-icons">
<li class="delete-icon"><a href="javascript:void({chatrow.MESSAGE_ID})" title="{L_DELETE_POST}" onClick="delete_post('{chatrow.MESSAGE_ID}')"><span>{L_DELETE_POST}</span></a></li>
</ul>
<!-- ENDIF -->
<div class="content">{chatrow.MESSAGE}</div></div>
<dl class="postprofile" id="profile{postrow.POST_ID}">
<dt>{chatrow.USERNAME_FULL}<br /><b style="font-size: 0.9em;">{chatrow.TIME}</b></dt>
</dl>
<span class="corners-bottom"><span></span></span>
</div>
</div>
<!-- END chatrow -->--!--{LAST_ID}
<!-- IF S_WHOISONLINE -->--!--
<!-- BEGIN whoisrow -->
<div>
<div class="inner">
<div class="user"><img src="{T_IMAGESET_PATH}/{whoisrow.USER_STATUS}.png" class="online_img" /> <span nowrap="nowrap">{whoisrow.USERNAME_FULL}</span></div>
</div>
</div>
<!-- END whoisrow -->--!--{LAST_TIME}--!--{DELAY}--!--{LAST_POST}
<!-- ENDIF -->
<!-- ENDIF -->
<!-- ELSE -->
<!-- IF S_CHAT -->
<!-- INCLUDE overall_header.html -->
<!-- IF S_DISPLAY_SEARCH or (S_USER_LOGGED_IN and not S_IS_BOT) -->
<ul class="forumlinklist">
<!-- IF S_DISPLAY_SEARCH -->
<li><img src="{T_THEME_PATH}/images/icon_pages.gif" alt="" /> <a href="{U_SEARCH_UNANSWERED}">{L_SEARCH_UNANSWERED}</a><!-- IF S_USER_LOGGED_IN --> • <img src="{T_THEME_PATH}/images/icon_pages.gif" alt="" /> <a href="{U_SEARCH_NEW}">{L_SEARCH_NEW}</a><!-- ENDIF --> • <img src="{T_THEME_PATH}/images/icon_topics.gif" alt="" /> <a href="{U_SEARCH_ACTIVE_TOPICS}">{L_SEARCH_ACTIVE_TOPICS}</a></li>
<!-- ENDIF -->
</ul>
<!-- ENDIF -->
<!-- ENDIF -->
<script type="text/javascript">
<!--
var fieldname = 'chat';
var last_time = 0;
var xmlHttp = http_object();
var last_id = {LAST_ID};
var type = 'receive';
var post_time = {TIME};
var read_interval = 15000;
var interval = setInterval('handle_send("read", last_id);', read_interval);
function handle_send(mode, f)
{
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
{
indicator_switch('on');
type = 'receive';
param = 'mode=' + mode;
param += '&last_id=' + last_id;
param += '&last_time=' + last_time;
param += '&last_post=' + post_time;
param += '&read_interval=' + read_interval;
if (mode == 'add' && document.text.message.value != '')
{
type = 'send';
for(var i = 0; i < f.elements.length; i++)
{
elem = f.elements[i];
param += '&' + elem.name + '=' + encodeURIComponent(elem.value);
}
document.text.message.value = '';
}
else if (mode == 'delete')
{
type = 'delete';
param += '&chat_id=' + f;
}
xmlHttp.open("POST", '{FILENAME}', true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = handle_return;
xmlHttp.send(param);
}
}
function handle_return()
{
if (xmlHttp.readyState == 4)
{
if (type != 'delete')
{
results = xmlHttp.responseText.split('--!--');
if (results[2])
{
if (last_id == 0)
{
document.getElementById(fieldname).innerHTML = results[1];
}
else
{
document.getElementById(fieldname).innerHTML = results[1] + document.getElementById(fieldname).innerHTML;
}
last_id = results[2];
if (results[3])
{
document.getElementById('whois_online').innerHTML = results[3];
last_time = results[4];
if (results[5] != read_interval * 1000)
{
window.clearInterval(interval);
read_interval = results[5] * 1000;
interval = setInterval('handle_send("read", last_id);', read_interval);
document.getElementById('update_seconds').innerHTML = results[5];
}
post_time = results[6];
}
}
}
indicator_switch('off');
}
}
function delete_post(chatid)
{
document.getElementById('p' + chatid).style.display = 'none';
handle_send('delete', chatid);
}
function indicator_switch(mode)
{
if(document.getElementById("act_indicator"))
{
var img = document.getElementById("act_indicator");
if(img.style.visibility == "hidden" && mode == 'on')
{
img.style.visibility = "visible";
}
else if (mode == 'off')
{
img.style.visibility = "hidden"
}
}
}
function http_object()
{
if (window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
document.getElementById('p_status').innerHTML = 'Status: Cound not create XmlHttpRequest Object. Consider upgrading your browser.';
}
}
-->
</script>
<style type="text/css">
<!--
#act_indicator {
visibility:hidden;
}
.shouts {
width: 84%;
height:328px;
overflow:auto;
float:left;
margin: 8px 0;
}
#chat {
width: 99%;
text-align:left;
}
.postprofile {
min-height: 5px !important;
}
.chatform {
color: white;
width: 96%;
text-align:center;
}
.onlinelist {
width: 16%;
overflow:auto;
height:300px;
}
.users {
width: 90%;
text-align: left;
margin-left:auto;
margin-right:auto;
}
.user {
width: 95%;
font-size: 1.1em;
font-family:Verdana, Arial, Helvetica, sans-serif;
}
#act_indicator {
visibility: hidden;
}
.chatinput {width: 60% !important;}
.online_img {
vertical-align:middle;
}
-->
</style>
<div class="forabg" style="margin-top: 8px;margin-bottom: 0;">
<div class="inner">
<span class="corners-top"><span></span></span>
<div class="header" style="float: left;">
<h4 style="color:white;"> <img src="{T_THEME_PATH}/images/icon_chat.gif" alt="" /> <!-- IF not S_CHAT --><a href="{U_CHAT_LINK}" alt="{L_CHAT_EXPLAIN}" title="{L_CHAT_EXPLAIN}" />{L_CHAT_EXPLAIN}</a><!-- ELSE -->{L_CHAT_EXPLAIN}<!-- ENDIF --></h4>
</div>
<div style="text-align: center;">
<!-- IF S_USER_LOGGED_IN -->
<form name="text" id="text" method="post" action="javascript:void(0);" onSubmit="handle_send('add', this)" autocomplete="off">
<strong style="color: white;">{L_MESSAGE}:</strong> <input type="text" tabindex="1" name="message" id="message" class="inputbox chatinput" />
<input type="submit" class="button1" value="{L_SUBMIT}" name="submit" tabindex="6" accesskey="s"/><br />
</form>
<!-- ELSE -->
<b style="color: white;">You must register to chat and registration is by invite only.</b>
<!-- ENDIF -->
</div>
<span class="corners-bottom"><span></span></span>
</div>
</div>
<div align="left">
<div class="shouts">
<div id="chat">
<!-- BEGIN chatrow -->
<div id="p{chatrow.MESSAGE_ID}" class="post bg{chatrow.CLASS}">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="postbody">
<!-- IF U_ACP or U_MCP -->
<ul class="profile-icons">
<li class="delete-icon">
<a href="javascript:void({chatrow.MESSAGE_ID})" title="{L_DELETE_POST}" onClick="delete_post('{chatrow.MESSAGE_ID}')"><span>{L_DELETE_POST}</span></a>
</li>
</ul>
<!-- ENDIF -->
<div class="content">{chatrow.MESSAGE}</div>
</div>
<dl class="postprofile" id="profile{postrow.POST_ID}">
<dt>{chatrow.USERNAME_FULL}<br /><b style="font-size: 0.9em;">{chatrow.TIME}</b></dt>
</dl>
<span class="corners-bottom"><span></span></span>
</div>
</div>
<!-- END chatrow -->
</div>
</div>
<h4> {L_ONLINE_LIST}:</h4>
<div class="onlinelist">
<div class="users" id="whois_online">
<!-- BEGIN whoisrow -->
<div>
<div class="inner">
<div class="user"><img src="{T_IMAGESET_PATH}/{whoisrow.USER_STATUS}.png" class="online_img" /> <span nowrap="nowrap">{whoisrow.USERNAME_FULL}</span></div>
</div>
</div>
<!-- END whoisrow -->
</div>
</div>
</div>
<div class="forabg">
<div class="inner">
<span class="corners-top"><span></span></span>
<div class="chatform" align="center">
{L_DETAILS} <img src="{T_IMAGESET_PATH}/act_indicator.gif" id="act_indicator" /> <strong>{L_UPDATES} <span id="update_seconds">{DELAY}</span> {L_UNIT}</strong>
</div>
<span class="corners-bottom"><span></span></span>
</div>
</div>
<!-- IF S_CHAT -->
<!-- IF S_DISPLAY_ONLINE_LIST -->
<div style="float: left;"><img src="{T_THEME_PATH}/images/whosonline.gif" alt="" /> </div><!-- IF U_VIEWONLINE --><h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3><!-- ELSE --><h3>{L_WHO_IS_ONLINE}</h3><!-- ENDIF -->
<p style="margin-bottom:4px;">{TOTAL_USERS_ONLINE}<br />{LOGGED_IN_USER_LIST}
<!-- IF LEGEND --><br /><em>{L_LEGEND}: {LEGEND}</em><!-- ENDIF --></p>
<!-- ENDIF -->
<!-- INCLUDE overall_footer.html --> <!-- ENDIF -->
<!-- ENDIF -->
Roadmap- Add smilies button
- Show smilies in chat room
- Multiple Rooms (Progress = 25%)
- Report Post/Users
- Add Quote Button
- Enable Author Delete
- Private Rooms
- Send Chat Requests
- Reset Chat button
- Avatar Thumbnails with Fullsize Rollovers.
- Chat Logs
Extra languages
Spoiler:
French Translation provided by Dace
Dutch Translation provided by eFantasy
http://startrekguide.com/forum/download.php?id=1564
Swedish Translation provided by [b]KJell
http://startrekguide.com/forum/f27-misc ... tml#p32498
french.txt- French Translation
- (396 Bytes) Downloaded 1320 times
Dutch Translation provided by eFantasy
http://startrekguide.com/forum/download.php?id=1564
Swedish Translation provided by [b]KJell
http://startrekguide.com/forum/f27-misc ... tml#p32498
Here's a small add-on to redirect users to the login page if they get logged out during a conversation.
Spoiler:
open chat.php
FIND case 'add':
After, add
save and upload
FIND case 'add':
After, add
- Code: Select all
if (!$user->data['is_registered'])
{
redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'));
}
save and upload
Beta 7 downloaded 7485 times.






