由于重复 Ajax 调用,无法正确复制文本
Cannot copy text correctly due to repeating Ajax call
我有一个简单的聊天网络应用程序,一切正常。但是,有两个问题:
1) 当我尝试复制文本时,重复的 Ajax 调用会导致所有文本被选中,如果 GIF 比间隔长,则它们会循环 运行。
2) 新消息通知有效,但为了看到新消息,您必须单击发件人,即使您当前正在与他们交谈。
这是我尝试复制单个消息时发生的情况:
我不知道如何在不单击用户 link 的情况下显示新消息。
这是主页,chat.php:
<?php
//error_reporting(E_ERROR);
//ini_set('display_errors', 1);
include 'includes/header.php';
include 'includes/DB.php';
try {
$db = new DB();
} catch (Exception $e) {
}
$username = $_SESSION['logged_in'];
$short_name = substr($username, 0, strpos($username, '.'));
?>
<div id="page-wrap">
<h2 id="chat_title_h2">IT Chat</h2>
<p id="name-area">Hello, <?= $short_name ?></p>
<div id="chat-wrap">
<div id="user-list">
<p style="color:white;font: bold 12px 'Lucida Grande', Sans-Serif;margin-top:10px; margin-left:10px;">
Conversations</p>
<?php
//Populate the user list
foreach ($users_result = $db->getRows('SELECT * FROM users ORDER BY username', ['']) as $user) {
$username = $user['username'];
$short_list_name = substr($username, 0, strpos($username, '.'));
echo '<p style="margin-left:10px;color:white;"><a class="link" style="color:white!important;" href=' . $username . '>' . $short_list_name . '</a><span class="dot" data-name="' . $username . '"</p>';
}
?>
</div>
<div id="chat-area"></div>
</div>
</div>
<div id="wrapper">
<form name="message-form" id="message-form" method="post" enctype="multipart/form-data">
<div class="input-group">
<span class="input-group-addon" style="background-color:darkorange;color:white;font-size:18px;border:none;border-radius:0;">
<label for="upload" style="margin-top:5px;font-size:20px;">
<span class="fa fa-paperclip"></span>
<input type="file" id="upload" name="upload" style="display:none;">
</label>
</span>
<textarea id="message" class="form-control" rows="3" maxlength="50000" style="resize:none;margin:0;height:50px;"></textarea>
<span class="input-group-addon btn btn-primary" id="send-button" style="background-color:darkorange!important;box-shadow:none!important;">Send</span>
</div>
</form>
</div>
<p class="input--error" style="visibility:hidden;">Error Uploading File</p>
<script>
//var links = '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">' + '<link rel="stylesheet" href="css/chat.css">';
//$('head').append(links);
//Disable send and upload buttons until user is clicked
$('#message').prop('disabled', true);
$('#upload').prop('disabled', true);
$('#send-button').css('pointer-events', 'none');
var userLink = '';
document.title = 'Chat';
//Check messges and notifications every 1000 ms
setInterval(function () {
getMessages();
}, 1000); //<----- THE PROBLEM
setInterval(function () {
checkNotifications();
}, 1000);
$(function() {
//Function that defines what happens when a file is chosen from file chooser
$('input:file').change(function () {
var file_data = $('#upload').prop('files')[0];
var form_data = new FormData();
form_data.append('upload', file_data);
$.ajax({
url: 'includes/chat/upload.php?userLink='+userLink,
type: 'post',
data: form_data,
contentType: false,
cache: false,
processData: false,
success:function(data) {
if(data === 'Error') {
$('.input--error').css('visibility','visible');
$('.input--error').delay(3000).hide(0);
} else {
$('#chat-area').append(data);
var chatarea = $('#chat-area');
var height = chatarea[0].scrollHeight;
chatarea.scrollTop(height);
}
},
error:function(data) {
console.log(data);
}
})
});
});
//Get messages to refresh chat window
function getMessages() {
if (userLink.length > 0) {
$.ajax({
url: 'includes/chat/get_messages.php?userLink=' + userLink,
type: 'post',
dataType: 'html',
success: function (data) {
$('#chat-area').html(data);
}
})
}
}
//If user's link is clicked, notification goes away and font changes to show which conversation you're on
$(document).on('click', '.link', function (event) {
event.preventDefault();
//Scroll to the bottom when a user's link is clicked to read messages
setTimeout(function() {
var chatarea = $('#chat-area');
var height = chatarea[0].scrollHeight;
chatarea.scrollTop(height);
}, 500);
$('#message').prop('disabled', false);
$('#upload').prop('disabled', false);
$('#send-button').css('pointer-events', 'auto');
userLink = $(this).attr('href');
var name = userLink.substring(0, userLink.indexOf('.'));
$('#message').attr('placeholder', 'Send message to ' + name);
$('#message').addClass('message-placeholder');
$('.message-placeholder').css('fontSize', 16);
$('#chat_title_h2').text(name);
$(this).parent().find('span').css('visibility', 'hidden');
$(this).css({
'font-weight': 'bold',
fontSize: 18
});
$('.link').each(function () {
if ($(this).attr('href') !== userLink) {
$(this).css({
'font-weight': 'normal',
fontSize: 14
})
}
});
//Ajax call to get messages. Populate chat window with returned data
$.ajax({
type: 'post',
url: 'includes/chat/show_conversation.php',
data: {
link: $(this).attr('href'),
},
dataType: 'html',
success: function (data) {
$('#chat-area').html(data);
}
})
});
//Button is not a 'button', but a span. Can't have a .submit() function here.
$('#send-button').on('click', function () {
var text = $('#message').val(); //Get what is in the textarea
var maxLength = $('#message').attr('maxlength');
console.log(text);
var length = text.length;
if (length <= maxLength + 1) { //Make sure it's not over the max length
sendChat();
$('#message').val('');
} else {
$('#message').val(text.substring(0, maxLength));
}
});
//Ajax call to send the textarea data to the server. If overflow-y is present, auto-scroll to bottom
function sendChat() {
var text = $('#message').val();
//Check to see if someone sent a link and format accordingly
if (validURL(text)) {
text = '<a target="_blank" href=' + text + '>' + text + '</a>';
}
$.ajax({
url: 'includes/chat/send_message.php',
type: 'post',
data: {message: text, link: userLink},
dataType: 'html',
success: function (data) {
getMessages();
$('#chat-area').append(data);
var chatarea = $('#chat-area');
var height = chatarea[0].scrollHeight;
chatarea.scrollTop(height);
}
});
}
//Check for new messages. Changes CSS of notification span to visible if new message is present.
function checkNotifications() {
$.ajax({
url: 'includes/chat/check_notifications.php',
type: 'post',
dataType: 'json',
success: function (data) {
$.each(data, function (i, item) {
console.log(item);
$('.link').each(function () {
if ($(this).parent().find('span').data('name') === item) {
$(this).parent().find('span').css('visibility', 'visible');
}
})
})
}
})
}
//Check if the message is a url so <a> tags can be added to the text
function validURL(str) {
var pattern = new RegExp('^((news|(ht|f)tp(s?)):\/\/)' + // protocol
'((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|' + // domain name
'((\d{1,3}\.){3}\d{1,3}))' + // OR ip (v4) address
'(\:\d+)?(\/[-a-z\d%_.~+]*)*' + // port and path
'(\?[;&a-z\d%_.~+=-]*)?' + // query string
'(\#[-a-z\d_]*)?$', 'i'); // fragment locater
if (!pattern.test(str)) {
console.log('Not a valid URL');
return false;
} else {
console.log('Valid URL');
return true;
}
}
</script>
</body>
</html>
check_notifications.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
session_start();
//This script checks for unread messages and shows notifications accordingly.
if(isset($_SESSION['logged_in'])) {
$username = $_SESSION['logged_in'];
$data = array();
foreach($results = $db->getRows('SELECT user1, user2read FROM pm WHERE user2=?',[$username]) as $result) {
$user2read = $result['user2read'];
$user1 = $result['user1'];
if($user2read === 'yes') {
continue;
}
$data[] = $result['user1'];
}
echo json_encode($data);
}
get_messages.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
session_start();
if(isset($_SESSION['logged_in'])) {
$sender = $_SESSION['logged_in'];
$recipient = $_GET['userLink'];
foreach($results = $db->getRows('SELECT user1, user2, timestamp, message, user1read, user2read FROM pm WHERE (user1=? AND user2=?) OR (user1=? AND user2=?) ORDER BY id', [$sender, $recipient, $recipient, $sender]) as $result) {
$user1 = $result['user1'];
$user2 = $result['user2'];
$short_name_1 = substr($user1, 0, strpos($user1, '.'));
$message = $result['message'];
$time = $result['timestamp'];
$user1read = $result['user1read'];
$user2read = $result['user2read'];
echo '<p><strong>' . $short_name_1 . '</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">' . $message . '</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">' . $time . '</p>';
}
}
show_conversation.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
//This script shows the conversation when a user's link is clicked
session_start();
if($_SERVER['REQUEST_METHOD'] === 'POST') {
if(isset($_SESSION['logged_in'])) {
$username = $_SESSION['logged_in'];
$recipient = $_POST['link'];
foreach($results = $db->getRows('SELECT user1, user2, timestamp, message FROM pm WHERE (user1=? AND user2=?) OR (user1=? AND user2=?) ORDER BY id', [$username, $recipient, $recipient, $username]) as $result) {
$user1 = $result['user1'];
$user2 = $result['user2'];
$short_name_1 = substr($user1, 0, strpos($user1, '.'));
$message = $result['message'];
$time = $result['timestamp'];
echo '<p><strong>'.$short_name_1.'</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">'.$message .'</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">'.$time.'</p>';
}
$read_status_result = $db->updateRow('UPDATE pm SET user2read=? WHERE user2=?',['yes',$username]);
}
}
send_message.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
session_start();
if($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_SESSION['logged_in'])) {
$user = $_SESSION['logged_in'];
$message = $_POST['message'];
$recipient = $_POST['link'];
$timestamp = date('Y-m-d H:i:s');
$short_name_1 = substr($user, 0, strpos($user, '.'));
$short_name_2 = substr($recipient, 0, strpos($recipient, '.'));
$result = $db->insertRow('INSERT INTO pm (user1, user2, message, timestamp, user1read, user2read) VALUES (?,?,?,?,?,?)', [$user, $recipient, $message, $timestamp, 'yes', 'yes']);
echo '<p><strong>'.$short_name_1.'</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">'.$message .'</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">'.$timestamp.'</p>';
$set_read_status_result = $db->updateRow('UPDATE pm SET user1read=?, user2read=? WHERE user1=? AND user2=?',['yes', 'no', $user, $recipient]);
}
}
还有另一个文件 upload.php,但它不相关(如果您在查询字符串中看到 link 并想知道它去了哪里)。
最后,这是我的 pm 和用户表的架构:
pm 架构
mysql> describe pm;
+-----------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user1 | varchar(30) | NO | | NULL | |
| user2 | varchar(30) | NO | | NULL | |
| message | text | YES | | NULL | |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| user1read | varchar(3) | YES | | NULL | |
| user2read | varchar(3) | YES | | NULL | |
+-----------+-------------+------+-----+-------------------+-----------------------------+
7 rows in set (0.01 sec)
用户
mysql> describe users;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(6) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
基本上,最好不必每秒检查消息并在发送消息时填充它。这对这个项目没有害处。它更像是一个便利因素,但我相信一些用户会想要这个功能。
如果有任何地方太含糊,或者我没有对某些内容发表足够好的评论,请告诉我,我会进行编辑。
重新加载动画 (selection/gif-animation) 的解决方案是只加载新条目并保留旧条目。所以不会进行重写。只是追加。
好吧,我不得不做一些代码杂耍,但我做到了现在可以在需要时复制文本的地方,我只是禁用了上传 GIF 的选项,因为动画很糟糕,setInterval 是每个第二。这是目前的解决方法,直到我回到它以找到更永久的解决方案。
我为 getMessages() setInterval 分配了一个变量并编写了一个 mouseup 和 mousedown 函数:
//Check messges and notifications every 1000 ms
var get_messages = setInterval(function () { //<-- Made this a variable
getMessages();
}, 1000);
setInterval(function () {
checkNotifications();
}, 1000);
$(function () {
//Get the current mouse state to allow copying of text
$('#chat-area').on('mousedown mouseup', function mouseState(e) {
switch (e.type) {
case 'mousedown':
clearInterval(get_messages); //<-- Stop getting messages temporarily
clearInterval(get_messages_again); //<-- Had to do it again with another variable
console.log('Mouse down');
break;
case 'mouseup':
console.log('Mouse up');
setTimeout(function () { //<-- Give a few seconds to right click and Copy text, then go back to getting messages.
get_messages_again = setInterval(function () {
getMessages();
}, 1000);
},3000);
break;
}
});
如果用户已经在与所选名称的对话中,我还设置了通知将消失的位置。我刚刚将 if/else 添加到我的 checkNotifications() 函数中,如下所示:
//Check for new messages. Changes CSS of notification span to visible if new message is present.
function checkNotifications() {
$.ajax({
url: 'includes/chat/check_notifications.php',
type: 'post',
dataType: 'json',
success: function (data) {
$.each(data, function (i, item) {
console.log(item);
$('.link').each(function () {
//Get the current font-weight.
//If it's above the norm, that means the user
//is currently viewing messages and a notification
//isn't needed.
if($(this).css('font-weight') > 400) {
$(this).parent().find('span').css('visibility', 'hidden');
} else {
//This code was already here.
//Just made it part of the else statement
if ($(this).parent().find('span').data('name') === item) {
$(this).parent().find('span').css('visibility', 'visible');
}
}
})
})
}
})
}
我有一个简单的聊天网络应用程序,一切正常。但是,有两个问题: 1) 当我尝试复制文本时,重复的 Ajax 调用会导致所有文本被选中,如果 GIF 比间隔长,则它们会循环 运行。 2) 新消息通知有效,但为了看到新消息,您必须单击发件人,即使您当前正在与他们交谈。
这是我尝试复制单个消息时发生的情况:
我不知道如何在不单击用户 link 的情况下显示新消息。
这是主页,chat.php:
<?php
//error_reporting(E_ERROR);
//ini_set('display_errors', 1);
include 'includes/header.php';
include 'includes/DB.php';
try {
$db = new DB();
} catch (Exception $e) {
}
$username = $_SESSION['logged_in'];
$short_name = substr($username, 0, strpos($username, '.'));
?>
<div id="page-wrap">
<h2 id="chat_title_h2">IT Chat</h2>
<p id="name-area">Hello, <?= $short_name ?></p>
<div id="chat-wrap">
<div id="user-list">
<p style="color:white;font: bold 12px 'Lucida Grande', Sans-Serif;margin-top:10px; margin-left:10px;">
Conversations</p>
<?php
//Populate the user list
foreach ($users_result = $db->getRows('SELECT * FROM users ORDER BY username', ['']) as $user) {
$username = $user['username'];
$short_list_name = substr($username, 0, strpos($username, '.'));
echo '<p style="margin-left:10px;color:white;"><a class="link" style="color:white!important;" href=' . $username . '>' . $short_list_name . '</a><span class="dot" data-name="' . $username . '"</p>';
}
?>
</div>
<div id="chat-area"></div>
</div>
</div>
<div id="wrapper">
<form name="message-form" id="message-form" method="post" enctype="multipart/form-data">
<div class="input-group">
<span class="input-group-addon" style="background-color:darkorange;color:white;font-size:18px;border:none;border-radius:0;">
<label for="upload" style="margin-top:5px;font-size:20px;">
<span class="fa fa-paperclip"></span>
<input type="file" id="upload" name="upload" style="display:none;">
</label>
</span>
<textarea id="message" class="form-control" rows="3" maxlength="50000" style="resize:none;margin:0;height:50px;"></textarea>
<span class="input-group-addon btn btn-primary" id="send-button" style="background-color:darkorange!important;box-shadow:none!important;">Send</span>
</div>
</form>
</div>
<p class="input--error" style="visibility:hidden;">Error Uploading File</p>
<script>
//var links = '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">' + '<link rel="stylesheet" href="css/chat.css">';
//$('head').append(links);
//Disable send and upload buttons until user is clicked
$('#message').prop('disabled', true);
$('#upload').prop('disabled', true);
$('#send-button').css('pointer-events', 'none');
var userLink = '';
document.title = 'Chat';
//Check messges and notifications every 1000 ms
setInterval(function () {
getMessages();
}, 1000); //<----- THE PROBLEM
setInterval(function () {
checkNotifications();
}, 1000);
$(function() {
//Function that defines what happens when a file is chosen from file chooser
$('input:file').change(function () {
var file_data = $('#upload').prop('files')[0];
var form_data = new FormData();
form_data.append('upload', file_data);
$.ajax({
url: 'includes/chat/upload.php?userLink='+userLink,
type: 'post',
data: form_data,
contentType: false,
cache: false,
processData: false,
success:function(data) {
if(data === 'Error') {
$('.input--error').css('visibility','visible');
$('.input--error').delay(3000).hide(0);
} else {
$('#chat-area').append(data);
var chatarea = $('#chat-area');
var height = chatarea[0].scrollHeight;
chatarea.scrollTop(height);
}
},
error:function(data) {
console.log(data);
}
})
});
});
//Get messages to refresh chat window
function getMessages() {
if (userLink.length > 0) {
$.ajax({
url: 'includes/chat/get_messages.php?userLink=' + userLink,
type: 'post',
dataType: 'html',
success: function (data) {
$('#chat-area').html(data);
}
})
}
}
//If user's link is clicked, notification goes away and font changes to show which conversation you're on
$(document).on('click', '.link', function (event) {
event.preventDefault();
//Scroll to the bottom when a user's link is clicked to read messages
setTimeout(function() {
var chatarea = $('#chat-area');
var height = chatarea[0].scrollHeight;
chatarea.scrollTop(height);
}, 500);
$('#message').prop('disabled', false);
$('#upload').prop('disabled', false);
$('#send-button').css('pointer-events', 'auto');
userLink = $(this).attr('href');
var name = userLink.substring(0, userLink.indexOf('.'));
$('#message').attr('placeholder', 'Send message to ' + name);
$('#message').addClass('message-placeholder');
$('.message-placeholder').css('fontSize', 16);
$('#chat_title_h2').text(name);
$(this).parent().find('span').css('visibility', 'hidden');
$(this).css({
'font-weight': 'bold',
fontSize: 18
});
$('.link').each(function () {
if ($(this).attr('href') !== userLink) {
$(this).css({
'font-weight': 'normal',
fontSize: 14
})
}
});
//Ajax call to get messages. Populate chat window with returned data
$.ajax({
type: 'post',
url: 'includes/chat/show_conversation.php',
data: {
link: $(this).attr('href'),
},
dataType: 'html',
success: function (data) {
$('#chat-area').html(data);
}
})
});
//Button is not a 'button', but a span. Can't have a .submit() function here.
$('#send-button').on('click', function () {
var text = $('#message').val(); //Get what is in the textarea
var maxLength = $('#message').attr('maxlength');
console.log(text);
var length = text.length;
if (length <= maxLength + 1) { //Make sure it's not over the max length
sendChat();
$('#message').val('');
} else {
$('#message').val(text.substring(0, maxLength));
}
});
//Ajax call to send the textarea data to the server. If overflow-y is present, auto-scroll to bottom
function sendChat() {
var text = $('#message').val();
//Check to see if someone sent a link and format accordingly
if (validURL(text)) {
text = '<a target="_blank" href=' + text + '>' + text + '</a>';
}
$.ajax({
url: 'includes/chat/send_message.php',
type: 'post',
data: {message: text, link: userLink},
dataType: 'html',
success: function (data) {
getMessages();
$('#chat-area').append(data);
var chatarea = $('#chat-area');
var height = chatarea[0].scrollHeight;
chatarea.scrollTop(height);
}
});
}
//Check for new messages. Changes CSS of notification span to visible if new message is present.
function checkNotifications() {
$.ajax({
url: 'includes/chat/check_notifications.php',
type: 'post',
dataType: 'json',
success: function (data) {
$.each(data, function (i, item) {
console.log(item);
$('.link').each(function () {
if ($(this).parent().find('span').data('name') === item) {
$(this).parent().find('span').css('visibility', 'visible');
}
})
})
}
})
}
//Check if the message is a url so <a> tags can be added to the text
function validURL(str) {
var pattern = new RegExp('^((news|(ht|f)tp(s?)):\/\/)' + // protocol
'((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|' + // domain name
'((\d{1,3}\.){3}\d{1,3}))' + // OR ip (v4) address
'(\:\d+)?(\/[-a-z\d%_.~+]*)*' + // port and path
'(\?[;&a-z\d%_.~+=-]*)?' + // query string
'(\#[-a-z\d_]*)?$', 'i'); // fragment locater
if (!pattern.test(str)) {
console.log('Not a valid URL');
return false;
} else {
console.log('Valid URL');
return true;
}
}
</script>
</body>
</html>
check_notifications.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
session_start();
//This script checks for unread messages and shows notifications accordingly.
if(isset($_SESSION['logged_in'])) {
$username = $_SESSION['logged_in'];
$data = array();
foreach($results = $db->getRows('SELECT user1, user2read FROM pm WHERE user2=?',[$username]) as $result) {
$user2read = $result['user2read'];
$user1 = $result['user1'];
if($user2read === 'yes') {
continue;
}
$data[] = $result['user1'];
}
echo json_encode($data);
}
get_messages.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
session_start();
if(isset($_SESSION['logged_in'])) {
$sender = $_SESSION['logged_in'];
$recipient = $_GET['userLink'];
foreach($results = $db->getRows('SELECT user1, user2, timestamp, message, user1read, user2read FROM pm WHERE (user1=? AND user2=?) OR (user1=? AND user2=?) ORDER BY id', [$sender, $recipient, $recipient, $sender]) as $result) {
$user1 = $result['user1'];
$user2 = $result['user2'];
$short_name_1 = substr($user1, 0, strpos($user1, '.'));
$message = $result['message'];
$time = $result['timestamp'];
$user1read = $result['user1read'];
$user2read = $result['user2read'];
echo '<p><strong>' . $short_name_1 . '</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">' . $message . '</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">' . $time . '</p>';
}
}
show_conversation.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
//This script shows the conversation when a user's link is clicked
session_start();
if($_SERVER['REQUEST_METHOD'] === 'POST') {
if(isset($_SESSION['logged_in'])) {
$username = $_SESSION['logged_in'];
$recipient = $_POST['link'];
foreach($results = $db->getRows('SELECT user1, user2, timestamp, message FROM pm WHERE (user1=? AND user2=?) OR (user1=? AND user2=?) ORDER BY id', [$username, $recipient, $recipient, $username]) as $result) {
$user1 = $result['user1'];
$user2 = $result['user2'];
$short_name_1 = substr($user1, 0, strpos($user1, '.'));
$message = $result['message'];
$time = $result['timestamp'];
echo '<p><strong>'.$short_name_1.'</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">'.$message .'</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">'.$time.'</p>';
}
$read_status_result = $db->updateRow('UPDATE pm SET user2read=? WHERE user2=?',['yes',$username]);
}
}
send_message.php
<?php
include '../DB.php';
try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
session_start();
if($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_SESSION['logged_in'])) {
$user = $_SESSION['logged_in'];
$message = $_POST['message'];
$recipient = $_POST['link'];
$timestamp = date('Y-m-d H:i:s');
$short_name_1 = substr($user, 0, strpos($user, '.'));
$short_name_2 = substr($recipient, 0, strpos($recipient, '.'));
$result = $db->insertRow('INSERT INTO pm (user1, user2, message, timestamp, user1read, user2read) VALUES (?,?,?,?,?,?)', [$user, $recipient, $message, $timestamp, 'yes', 'yes']);
echo '<p><strong>'.$short_name_1.'</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">'.$message .'</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">'.$timestamp.'</p>';
$set_read_status_result = $db->updateRow('UPDATE pm SET user1read=?, user2read=? WHERE user1=? AND user2=?',['yes', 'no', $user, $recipient]);
}
}
还有另一个文件 upload.php,但它不相关(如果您在查询字符串中看到 link 并想知道它去了哪里)。
最后,这是我的 pm 和用户表的架构:
pm 架构
mysql> describe pm;
+-----------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user1 | varchar(30) | NO | | NULL | |
| user2 | varchar(30) | NO | | NULL | |
| message | text | YES | | NULL | |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| user1read | varchar(3) | YES | | NULL | |
| user2read | varchar(3) | YES | | NULL | |
+-----------+-------------+------+-----+-------------------+-----------------------------+
7 rows in set (0.01 sec)
用户
mysql> describe users;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(6) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
基本上,最好不必每秒检查消息并在发送消息时填充它。这对这个项目没有害处。它更像是一个便利因素,但我相信一些用户会想要这个功能。
如果有任何地方太含糊,或者我没有对某些内容发表足够好的评论,请告诉我,我会进行编辑。
重新加载动画 (selection/gif-animation) 的解决方案是只加载新条目并保留旧条目。所以不会进行重写。只是追加。
好吧,我不得不做一些代码杂耍,但我做到了现在可以在需要时复制文本的地方,我只是禁用了上传 GIF 的选项,因为动画很糟糕,setInterval 是每个第二。这是目前的解决方法,直到我回到它以找到更永久的解决方案。
我为 getMessages() setInterval 分配了一个变量并编写了一个 mouseup 和 mousedown 函数:
//Check messges and notifications every 1000 ms
var get_messages = setInterval(function () { //<-- Made this a variable
getMessages();
}, 1000);
setInterval(function () {
checkNotifications();
}, 1000);
$(function () {
//Get the current mouse state to allow copying of text
$('#chat-area').on('mousedown mouseup', function mouseState(e) {
switch (e.type) {
case 'mousedown':
clearInterval(get_messages); //<-- Stop getting messages temporarily
clearInterval(get_messages_again); //<-- Had to do it again with another variable
console.log('Mouse down');
break;
case 'mouseup':
console.log('Mouse up');
setTimeout(function () { //<-- Give a few seconds to right click and Copy text, then go back to getting messages.
get_messages_again = setInterval(function () {
getMessages();
}, 1000);
},3000);
break;
}
});
如果用户已经在与所选名称的对话中,我还设置了通知将消失的位置。我刚刚将 if/else 添加到我的 checkNotifications() 函数中,如下所示:
//Check for new messages. Changes CSS of notification span to visible if new message is present.
function checkNotifications() {
$.ajax({
url: 'includes/chat/check_notifications.php',
type: 'post',
dataType: 'json',
success: function (data) {
$.each(data, function (i, item) {
console.log(item);
$('.link').each(function () {
//Get the current font-weight.
//If it's above the norm, that means the user
//is currently viewing messages and a notification
//isn't needed.
if($(this).css('font-weight') > 400) {
$(this).parent().find('span').css('visibility', 'hidden');
} else {
//This code was already here.
//Just made it part of the else statement
if ($(this).parent().find('span').data('name') === item) {
$(this).parent().find('span').css('visibility', 'visible');
}
}
})
})
}
})
}