All users may message each other with an Ajax enabled message tool.
-cannot use "enter" key for login credentials form
-cannot recover password for students
+Cannot use "enter" key for login credentials form
+
+Users cannot recover password for themselves.
Email for created or modified assignments
+
Email for late assignments
+
Email (to instructor) for comment from student
+Create management console that can look at all users's messages
+
+ Should include search to view only a particular user's chats.
+
+Allow users to see past chats anytime - everything is recorded
+
+Create private chat rooms between two people and a public room as well.
+
+Add sound for user entering chat and another for a user logging off.
+
+Create a message board for each assignment in system.
+
+Empty chat updates should not send any return at all - to reduce bandwidth.
+
+Noises made in chat are not what is needed. Need a knock sound and a send and receive sound.
+
+Users in chat should have different color chats to make the messages more readable.
+
+Need a place for students and faculty to share code outside of assignments.
+
+Need logoff button instead of name to click on.
@@ -28,8 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// if waitMessage not sent, content will not "blink"
// callBack = javascript function name to run after data has been returned from server
function getPage( url, pageElement, waitMessage, callBack ) {
-
- // START TIMER
var timer = new Date();
var t_start = timer.getTime();
//debugEvent(url, "get");
@@ -96,3 +94,59 @@ function getPage( url, pageElement, waitMessage, callBack ) {
}
if (callBack != null ) { eval(callBack+'()'); }
}
+
+function sendData(url){
+ // START TIMER
+ var timer = new Date();
+ var t_start = timer.getTime();
+// WE USE A JAVASCRIPT FEATURE HERE CALLED "INNER FUNCTIONS"
+// USING THESE MEANS THE LOCAL VARIABLES RETAIN THEIR VALUES AFTER THE OUTER FUNCTION
+// HAS RETURNED. THIS IS USEFUL FOR THREAD SAFETY, SO
+// REASSIGNING THE ONREADYSTATECHANGE FUNCTION DOESN'T STOMP OVER EARLIER REQUESTS.
+ function ajaxBindCallback(){
+ if(ajaxRequest.readyState == 0) { window.status = "Waiting..."; }
+ if(ajaxRequest.readyState == 1) { window.status = "Loading Page..."; }
+ if(ajaxRequest.readyState == 2) { window.status = "Data Received...";}
+ if(ajaxRequest.readyState == 3) { window.status = "Interactive..."; }
+ if(ajaxRequest.readyState == 4) {
+ window.status = "Transaction Complete...";
+
+ // STOP TIMER AND FIND DIFFERENCE
+ // MUST CREATE NEW TIMER INSTANCE :)
+ var timer2 = new Date();
+ var t_end = timer2.getTime();
+ var t_diff = t_end - t_start;
+
+ // TEST HTTP STATUS CODE - DISPLAY IN DUBUGGER AND STATUS
+ switch (ajaxRequest.status.toString()) {
+ case "200" :
+ debugEvent(url, "got", ajaxRequest.responseText, t_diff);
+ break;
+ case "403" :
+ debugEvent(url, "error_403", ajaxRequest.responseText, t_diff);
+ break;
+ case "404" :
+ debugEvent(url, "error_404", ajaxRequest.responseText, t_diff);
+ break;
+ case "500" :
+ debugEvent(url, "error_500", ajaxRequest.responseText, t_diff);
+ break;
+ }
+ }
+ }
+ var ajaxRequest = null;
+ // BIND OUR CALLBACK THEN HIT THE SERVER...
+ if (window.XMLHttpRequest) {
+ ajaxRequest = new XMLHttpRequest();
+ ajaxRequest.onreadystatechange = ajaxBindCallback;
+ ajaxRequest.open("GET", url, true);
+ ajaxRequest.send(null);
+ } else if (window.ActiveXObject) {
+ ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
+ if (ajaxRequest) {
+ ajaxRequest.onreadystatechange = ajaxBindCallback;
+ ajaxRequest.open("GET", url, true);
+ ajaxRequest.send();
+ }
+ }
+}
<?php
-
+ob_start("ob_gzhandler");
include_once("conn.php");
/* verify username and password - do not pass if incorrect */
@@ -47,6 +47,11 @@ $user_name = $row[3];
$first_login = $row[4];
$user_email = $row[5];
+/* update user status to indcate that this user is online - used mostly for chat features */
+$sql = "update users set last_click = NOW() where user_id = ".$user_id;
+
+$result = mysql_query($sql);
+
/* if this is your first login, you MUST change password */
if($first_login == 1) { include("password_change.php"); exit; }
@@ -105,6 +105,14 @@ CREATE TABLE files (
PRIMARY KEY (file_id)
);
+CREATE TABLE chat (
+ chat_id int NOT NULL AUTO_INCREMENT,
+ user_id int NOT NULL,
+ content varchar(256) NOT NULL,
+ chat_time timestamp NOT NULL,
+ PRIMARY KEY(chat_id)
+);
+
CREATE TABLE users (
user_id int NOT NULL AUTO_INCREMENT, #
email varchar(128) NOT NULL, #
@@ -113,6 +121,7 @@ CREATE TABLE users (
attempts int NOT NULL, # number of bad attempts to login
role int NOT NULL, # 0 is prof, 1 is student
first_login int NOT NULL, # 0 is false, 1 is true
+ last_click timestamp,
PRIMARY KEY (user_id)
);
@@ -7,27 +7,26 @@ header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
if($user_id != '') {
- if($role == 0) {
- //$menu = '<a href="index.php">Classes</a> | <a href="manage.php">Manage Accounts</a> | <a href="workflow.php">Workflows</a> | '.$_COOKIE["username"].' | <a href="#" onClick="logout();">Logout</a>';
-
- $menu = '<div class="menu">
- <ul>
- <li><a href="classes.php">Classes</a></li>
+ if($role == 0) {
+ $menu = '<ul>
+ <li><a href="javascript:void(0);" target="_blank" onClick="window.open(\'im.php\', \'Chat Room\', \'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=0,width=700,height=400,left = 310,top = 275\');">Chat</a></li>
+ <li><a href=#>Chat Log</a>
+ <li><a href="classes.php">Classes</a></li>
+ <li><a href="#">Discussion Board</a></li>
<li><a href="index.php">Messages</a></li>
- <li><a href="manage.php">Manage Accounts</a></li>
- <li><a href="#" onClick="logout();">'.$_COOKIE["username"].'</a></li>
- </ul></div>';
-
+ <li><a href="manage.php">Manage Accounts</a></li>
+ <li><a href="#">Search</a></li>
+ </ul><div class="login_menu">'.$_COOKIE["username"].' <button class="logout_button" onClick="logout();">Logout</button></div>';
} else {
- //$menu = '<a href="index.php">Classes</a> | <a href="manage.php">Manage Account</a> | '.$_COOKIE["username"].' | <a href="#" onClick="logout();">Logout</a>';
- $menu = '<div class="menu">
- <ul>
- <li><a href="classes.php">Classes</a></li>
+ $menu = '<ul>
+ <li><a href="javascript:void(0);" target="_blank" onClick="window.open(\'im.php\', \'Chat Room\', \'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=0,width=700,height=400,left = 310,top = 275\');">Chat</a></li>
+ <li><a href=#>Chat Log</a>
+ <li><a href="classes.php">Classes</a></li>
+ <li><a href="#">Discussion Board</a></li>
<li><a href="index.php">Messages</a></li>
- <li><a href="manage.php">Manage Account</a></li>
- <li><a href="#" onClick="logout();">'.$_COOKIE["username"].'</a></li>
- </ul></div>';
-
+ <li><a href="manage.php">Manage Account</a></li>
+ <li><a href="#">Search</a></li>
+ </ul><div class="login_menu">'.$_COOKIE["username"].' <button class="logout_button" onClick="logout();">Logout</button></div>';
}
} else {
$menu = '';
@@ -54,14 +53,7 @@ if($user_id != '') {
</head>
<body onload="sh_highlightDocument();">
-<table> <tr><td><img src="gfx/bricks.png"></td><td class="banner_header">Assignment Trapper</td></tr></table>
-
-
-<div class="header">
- <div class="menu">
- <?php echo $menu; ?>
- </div>
-</div>
-
+<div class="main_menu"><?php echo $menu; ?></div><br>
+<table><tr><td><img src="gfx/bricks.png"></td><td class="banner_header">Assignment Trapper</td></tr></table>
<br>
--- /dev/null
+<?php
+
+include_once("auth.php");
+
+?>
+
+<html>
+<script type="text/javascript" src="ajax.js"></script>
+<script type="text/javascript" src="debugger.js"></script>
+<script>
+var last_chat_id = 0;
+var chat_div;
+var chat_json = new Object();
+var chat_ping = null;
+
+if(document.layers)
+ document.captureEvents(Event.KEYDOWN);
+ document.onkeydown =
+ function (evt) {
+ var keyCode = evt ? (evt.which ? evt.which : evt.keyCode) : event.keyCode;
+ if (keyCode == 13) {
+ document.getElementById('send').click();
+ } else return true;
+ };
+
+function parse_message_response(){
+ var message_count = chat_json.m.length;
+ if(message_count > 0) { beep_sound.play(); }
+ var message_text = "";
+ for(var i = 0; i < message_count; i++){
+ message_text += '<div><font color="red">' + chat_json.m[i].t + '</font> ';
+ message_text += '<font color="blue">' + chat_json.m[i].n + '</font> ';
+ message_text += chat_json.m[i].c + '</div>';
+ last_chat_id = chat_json.m[i].id;
+ }
+ document.getElementById("chat_window").innerHTML += message_text;
+}
+
+function update_ping(){
+ if(chat_ping > 2000){ document.getElementById("chat_status").innerHTML = "<img src='./gfx/bullet_red.png'>"; }
+ else if (chat_ping > 1000){ document.getElementById("chat_status").innerHTML = "<img src='./gfx/bullet_yellow.png'>"; }
+ else { document.getElementById("chat_status").innerHTML = "<img src='./gfx/bullet_green.png'>"; }
+}
+
+function getChat(url, pageElement){
+ // START TIMER
+ var timer = new Date();
+ var t_start = timer.getTime();
+ //debugEvent(url, "get");
+
+ // WE USE A JAVASCRIPT FEATURE HERE CALLED "INNER FUNCTIONS"
+ // USING THESE MEANS THE LOCAL VARIABLES RETAIN THEIR VALUES AFTER THE OUTER FUNCTION
+ // HAS RETURNED. THIS IS USEFUL FOR THREAD SAFETY, SO
+ // REASSIGNING THE ONREADYSTATECHANGE FUNCTION DOESN'T STOMP OVER EARLIER REQUESTS.
+ function ajaxBindCallback(){
+ if(ajaxRequest.readyState == 0) { window.status = "Waiting..."; }
+ if(ajaxRequest.readyState == 1) { window.status = "Loading Page..."; }
+ if(ajaxRequest.readyState == 2) { window.status = "Data Received...";}
+ if(ajaxRequest.readyState == 3) { window.status = "Interactive..."; }
+ if(ajaxRequest.readyState == 4) {
+ window.status = "Transaction Complete...";
+
+ // STOP TIMER AND FIND DIFFERENCE
+ // MUST CREATE NEW TIMER INSTANCE :)
+ var timer2 = new Date();
+ var t_end = timer2.getTime();
+ var t_diff = t_end - t_start;
+ chat_ping = t_diff;
+ update_ping();
+
+ // TEST HTTP STATUS CODE - DISPLAY IN DUBUGGER AND STATUS
+ switch (ajaxRequest.status.toString()) {
+ case "200" :
+ window.status = "Page Loaded Sucessfully";
+ chat_json = JSON.parse(ajaxRequest.response);
+ parse_message_response();
+ debugEvent(url, "got", ajaxRequest.responseText, t_diff);
+ break;
+ case "403" :
+ window.status = "Forbidden...";
+ debugEvent(url, "error_403", ajaxRequest.responseText, t_diff);
+ break;
+ case "404" :
+ window.status = "File Not Found...";
+ debugEvent(url, "error_404", ajaxRequest.responseText, t_diff);
+ break;
+ case "500" :
+ window.status = "File Not Found...";
+ debugEvent(url, "error_500", ajaxRequest.responseText, t_diff);
+ break;
+ default :
+ window.status = "Unknown Ajax Error..."+ajaxRequest.status.toString();
+ }
+ }
+ }
+ var ajaxRequest = null;
+ // BIND OUR CALLBACK THEN HIT THE SERVER...
+ if (window.XMLHttpRequest) {
+ ajaxRequest = new XMLHttpRequest();
+ ajaxRequest.onreadystatechange = ajaxBindCallback;
+ ajaxRequest.open("GET", url, true);
+ ajaxRequest.send(null);
+ } else if (window.ActiveXObject) {
+ ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
+ if (ajaxRequest) {
+ ajaxRequest.onreadystatechange = ajaxBindCallback;
+ ajaxRequest.open("GET", url, true);
+ ajaxRequest.send();
+ }
+ }
+}
+
+function start_updates(){
+ beep_sound = document.getElementById('beep_sound');
+ beep_sound.src = 'sfx/beep.wav';
+ click_sound = document.getElementById('click_sound');
+ click_sound.src = 'sfx/click.wav';
+ document.getElementById('message').focus();
+ chat_div = document.getElementById("chat_window");
+ getChat( "im_chat_update.php?id=-1", "chat_window");
+ setInterval(update_chat_messages, 2000);
+ update_users_online();
+ setInterval(update_users_online, 15000);
+}
+
+function update_chat_messages(){
+ getChat( "im_chat_update.php?id="+last_chat_id, "chat_window");
+ chat_window.scrollTop = chat_window.scrollHeight;
+}
+
+function update_users_online(){
+ getPage("im_user_update.php", "chat_users", "");
+}
+
+function send_message(){
+ sendData("im_send_message.php?message="+document.getElementById("message").value);
+ click_sound.play();
+ document.getElementById("message").value = '';
+}
+
+function disable_sound(){
+ beep_sound.src = '';
+ click_sound.src = '';
+}
+
+</script>
+
+<style>
+
+body {
+ font-family: Tahoma, sans-serif;
+ font-size: 14px;
+ background-color: #c5bcff;
+}
+#chat_window {
+ border: solid 1px #000;
+ background-color: #fff;
+ float: left;
+ width: 490px;
+ padding-left: 10px;
+ overflow:hidden;
+ height:300px;
+}
+#chat_users {
+ border: solid 1px #000;
+ background-color: #dedede;
+ float: right;
+ width: 150px;
+ padding-left: 10px;
+ overflow:hidden;
+ height:300px;
+}
+#users_list {
+ list-style-type: none;
+}
+#users_list li {
+ padding-top: 5px;
+}
+#send {
+ padding: 10px;
+}
+</style>
+<body onLoad="start_updates();">
+<audio id="beep_sound" style="display: none;"></audio>
+<audio id="click_sound" style="display: none;"></audio>
+<div id=chat_window></div>
+<div id=chat_users></div>
+<div id=chat_input>
+ <table><tr>
+ <td><textarea id="message" cols=65 rows=1></textarea></td>
+ <td><button id="send" onCLick="send_message();">Send</button></td>
+ <td><div id=chat_status><img src="./gfx/bullet_green.png"></div></td>
+ <tr><td><button onCLick="openDebug();">Debug</button></td><td></td></tr>
+ </tr></table>
+</div>
+</body>
+</html>
--- /dev/null
+<?php
+include_once("auth.php");
+//sleep(1);
+$_GET["user"] = mysql_real_escape_string($_GET["user"]);
+if($_GET["id"] == -1) {
+ $sql = "select chat_id, time(chat_time) as short_chat_time, name, content from chat, users where users.user_id = chat.user_id and chat_time > NOW() - interval 5 minute";
+ } else {
+ $sql = "select chat_id, time(chat_time) as short_chat_time, name, content from chat, users where users.user_id = chat.user_id and chat_id > ".$_GET["id"]." limit 100";
+ }
+$result = mysql_query($sql);
+$chat_data = '{"m":[';
+if(mysql_num_rows($result)){
+ while($row = mysql_fetch_array($result)){
+ $chat_data .= '{"id": '.$row[chat_id].',"t":"'.$row[short_chat_time].'","n":"'.$row[name].'","c":"'.$row[content].'"},';
+ }
+ $chat_data = substr($chat_data, 0, -1);
+ $chat_data .= ']}';
+} else $chat_data .= "]}";
+echo $chat_data;
+?>
--- /dev/null
+<?php
+include_once("auth.php");
+if (!$_GET["message"]) { die("No Chat Message Sent"); }
+$_GET["message"] = mysql_real_escape_string($_GET["message"]);
+$sql = 'insert into chat values ("", '.$user_id.', "'.$_GET["message"].'", NOW())';
+$result = mysql_query($sql);
+echo $sql;
+?>
--- /dev/null
+<?php
+
+include_once("conn.php");
+
+/* get list of users that are currently looged in */
+$sql = "select name from users where last_click > NOW()-300 order by name";
+
+$result = mysql_query($sql);
+$users_online = "";
+while($row = mysql_fetch_array($result))
+{
+ $users_online .= '<div>'.$row['name'].'</div>';
+}
+
+echo $users_online;
+
+?>
@@ -39,7 +39,6 @@ if($comment_count == 0) {
$comment_time = absHumanTiming($comment_max);
}
-
$sql = 'select count(*), max(timeposted) from filecom';
$result = mysql_query($sql);
@@ -53,7 +52,6 @@ if($filecomm_count == 0) {
$filecomm_time = absHumanTiming($filecomm_max);
}
-
$sql = 'select count(*), max(time_post) from files';
$result = mysql_query($sql);
@@ -75,6 +73,21 @@ $result = mysql_query($sql);
$row = mysql_fetch_row($result);
$std_locked = $row[0];
+$sql = 'select max(chat_time) from chat';
+
+$result = mysql_query($sql);
+$row = mysql_fetch_row($result);
+$chat_max = $row[0];
+$chat_max_time = absHumanTiming($chat_max);
+
+$sql = 'select count(*) from chat';
+$result = mysql_query($sql);
+$row = mysql_fetch_row($result);
+$chat_count = $row[0];
+
+// number of chat messages by hour
+//$sql = 'select hour(chat_time) as chat_hour, count(*) from chat group by chat_hour order by chat_hour';
+
// ADIMINISTRATOR MENU
?>
<div class="col2">
@@ -113,7 +126,8 @@ $std_locked = $row[0];
<div class="col">
<table class="gridtable">
<tr><th>Stat</th><th>Value</th><th>Human Time</th><th>Last Updated</th></tr>
- <tr><td>Files:</td><td><?php echo $file_count; ?></td><td><?php echo $file_time; ?></td><td><?php echo $file_time; ?></td></tr>
+ <tr><td>Chat Messages:</td><td><?php echo $chat_count ?></td><td><?php echo $chat_max_time ?></td><td><?php echo $chat_max ?></td></tr>
+ <tr><td>Files:</td><td><?php echo $file_count; ?></td><td><?php echo $file_time; ?></td><td><?php echo $file_max; ?></td></tr>
<tr><td>File Comments:</td><td><?php echo $filecomm_count; ?></td><td><?php echo $filecomm_time; ?></td><td><?php echo $filecomm_max; ?></td></tr>
<tr><td>Comments:</td><td><?php echo $comment_count; ?></td><td><?php echo $comment_time; ?></td><td><?php echo $comment_max; ?></td></tr>
<tr><td>Assignments:</td><td><?php echo $assignment_count; ?></td><td><?php echo $assignment_time; ?></td><td><?php echo $assignment_max; ?></td></tr>
@@ -62,32 +62,57 @@ table.gridtable td {
border-color: #666666;
background-color: #ffffff;
}
-.menu {
- /*background-color: #333;*/
+
+.login_menu {
+ position: relative;
+ float: right;
+ top: 0px;
+ right: 0px;
+ padding-right: 10px;
}
-.menu ul {
+.logout_button {
+ background-color: #f00;
+ color: #fff;
+}
+
+.logout_button:hover {
+ background-color: #000;
+ color: #f00;
+}
+
+.main_menu {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ background-color: #ececec;
+ border-bottom: 2px solid #000;
+ width: 100%;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+.main_menu ul {
margin: 0;
padding: 0;
- float: left;
}
-.menu ul li {
+.main_menu ul li {
display: inline;
}
-.menu ul li a {
+.main_menu ul li a {
float: left;
text-decoration: none;
margin-left: 25px;
}
-.menu ul li a:visited {
+.main_menu ul li a:visited {
text-decoration: none;
}
-.menu ul li a:hover, .menu ul li .current {
+.main_menu ul li a:hover, .menu ul li .current {
color: #000;
border-bottom: 2px solid #000;
}
@@ -120,12 +145,6 @@ table.gridtable td {
}
*/
-
-.header {
- position: absolute;
- top: 5px;
- right: 20px;
-}
.highlight { background: #fff }
.line_numbers {
background-color: #ececec;