fix: msg 기본 동작

This commit is contained in:
2021-08-28 17:25:33 +09:00
parent de48651ae7
commit 7bd8a7ff35
4 changed files with 23 additions and 583 deletions
+1 -1
View File
@@ -107,7 +107,7 @@ $serverCnt = $gameStor->server_cnt;
<?=WebUtil::printJS('js/main.js')?>
<?=WebUtil::printJS('d_shared/base_map.js')?>
<?=WebUtil::printJS('dist_js/map.js')?>
<?=WebUtil::printJS('js/msg.js')?>
<?=WebUtil::printJS('dist_js/msg.js')?>
<script>
window.serverNick = '<?=DB::prefix()?>';
window.serverID = '<?=UniqueConst::$serverID?>';
-562
View File
@@ -1,562 +0,0 @@
var messageTemplate = '';
var myGeneralID=null;
var isChief = false;
var lastSequence = 0;
var myNation = null;
var minMsgSeq = {
'private':0x7fffffff,
'public':0x7fffffff,
'national':0x7fffffff,
'diplomacy':0x7fffffff,
}
var generalList = {};
function responseMessage(msgID, response){
$.ajax({
url: 'j_msg_decide_opt.php',
type: 'post',
dataType:'json',
data: {
data: JSON.stringify({
msgID:msgID,
response:response
})
}
}).then(function(result){
if(result && !result.result){
alert(result.reason);
}
location.reload();
});
}
function deleteMessage(msgID){
$.ajax({
url: 'j_msg_delete.php',
type: 'post',
dataType:'json',
data: {
msgID:msgID
}
}).then(refreshMsg);
}
function refreshMsg(result){
if(result && !result.result){
alert(result.reason);
}
return redrawMsg(fetchRecentMsg(), true);
}
function fetchRecentMsg(){
return $.ajax({
url: 'j_msg_get_recent.php',
type: 'post',
dataType:'json',
data: {
sequence:lastSequence
}
});
}
function showOldMsg(msgType){
var oldMsg = $.ajax({
url: 'j_msg_get_old.php',
type: 'post',
dataType:'json',
data: {
to:minMsgSeq[msgType],
type:msgType,
}
});
redrawMsg(oldMsg, false);
}
function redrawMsg(deferred, addFront){
function checkErasable(obj){
var now = moment().format('YYYY-MM-DD HH:mm:ss');
$('.btn-delete-msg').each(function(){
var $btn = $(this);
var eraseUntil = $btn.data('erase_until');
if(eraseUntil < now){
$btn.detach();
}
})
return obj;
}
function checkClear(obj){
if(!obj.result){
var t = $.Deferred();
t.reject();
return t;
}
if(!obj.keepRecent){
var t = $.Deferred();
$('.msg_plate').detach();
lastSequence = null;
console.log('refresh!');
redrawMsg(fetchRecentMsg(), true);
t.reject();
return t;
}
return obj;
}
function registerSequence(obj){
if(!obj.result){
var t = $.Deferred();
t.reject();
return t;
}
lastSequence = Math.max(lastSequence, obj.sequence);
$.each(['public', 'private', 'national', 'diplomacy'], function (_, msgType) {
var msgList = obj[msgType];
if(msgList === undefined || msgList.length == 0){
return true;
}
var lastMsg = msgList[msgList.length - 1];
minMsgSeq[msgType] = Math.min(minMsgSeq[msgType], lastMsg.id);
});
return obj;
}
function refineMessageObjs(obj){
var msgList = [obj.public, obj.private, obj.diplomacy, obj.national];
$.each(msgList, function(){
if(!this){
return true;
}
$.each(this, function(){
var msg = this;
if(!msg.src.nation){
msg.src.nation = '재야';
msg.src.color = '#000000';
}
if(!msg.dest.nation){
msg.dest.nation = '재야';
msg.dest.color = '#000000';
}
msg.src.colorType = isBrightColor(msg.src.color)?'bright':'dark';
msg.dest.colorType = isBrightColor(msg.dest.color)?'bright':'dark';
});
});
return obj;
}
function printTemplate(obj){
var printList = [
[obj.public, $('#message_board .public_message'), 'public'],
[obj.private, $('#message_board .private_message'), 'private'],
[obj.diplomacy, $('#message_board .diplomacy_message'), 'diplomacy'],
[obj.national, $('#message_board .national_message'), 'national'],
];
$.each(printList, function(){
var msgSource = this[0];
var $msgBoard = this[1];
var msgType = this[2];
if(!msgSource || $msgBoard.length == 0){
console.log('No Items', msgSource, $msgBoard);
return true;
}
var needRefreshLastContact = (msgType == 'private');
var now = moment().format('YYYY-MM-DD HH:mm:ss');
//list의 맨 앞이 가장 최신 메시지임.
var $msgs = msgSource.map(function(msg){
var contactTarget = (msg.src.id != myGeneralID) ? msg.src.id : msg.dest.id;
if(needRefreshLastContact && contactTarget != myGeneralID && contactTarget in generalList)
{
needRefreshLastContact = false;
$('#last_contact').val(contactTarget).html(generalList[contactTarget].textName).show();
}
msg.nationID = obj.nationID;
msg.generalName = obj.generalName;
msg.msgType = msgType;
if(msg.src.nation_id == msg.dest.nation_id){
msg.nationType = 'local';
}
else if(msg.nationID == msg.src.nation_id){
msg.nationType = 'src';
}
else{
msg.nationType = 'dest';
}
msg.defaultIcon = pathConfig.sharedIcon+'/default.jpg';
if(msgType == 'diplomacy'){
msg.allowButton = permissionLevel>=4;
}
else{
msg.allowButton = true;
}
msg.myGeneralID = myGeneralID;
msg.last5min = moment(msg.time).add(5, 'minute').format('YYYY-MM-DD HH:mm:ss');
msg.now = now;
if(msg.option && msg.option.invalid){
msg.invalidType = 'msg_invalid';
}
else{
msg.invalidType = 'msg_valid';
}
if(msg.option && !msg.option.deletable){
msg.deletable = false;
}
else{
msg.deletable = true;
}
var msgHtml = TemplateEngine(messageTemplate, msg);
//만약 이전 메시지와 같은 id가 온 경우 덮어씌운다.
//NOTE:현 프로세스 상에서는 같은 id가 와선 안된다.
var $existMsg = $('#msg_{0}'.format(msg.id));
var $msg = $(msgHtml);
if($existMsg.length){
console.log('메시지 충돌', $msg, $existMsg);
$existMsg.html($msg.html());
$msg = $existMsg;
}
var hideMsg = false;
if(msg.option){
if(msg.option.delete !== undefined){
//delete는 삭제.
$('#msg_{0}'.format(msg.option.delete)).detach();
}
if(msg.option.overwrite !== undefined){
//overwrite는 숨기기.
$.map(msg.option.overwrite, function (overwriteID) {
var $msg = $('#msg_{0}'.format(overwriteID));
$msg.find('.btn-delete-msg').detach();
$msg.find('.msg_content').html('삭제된 메시지입니다.').removeClass('msg_valid').addClass('msg_invalid');
});
}
if(msg.option.hide){
hideMsg = true;
}
}
if(hideMsg){
return null;
}
$msg.find('.btn-delete-msg').click(function(){
if(!confirm("삭제하시겠습니까?")){
return false;
}
deleteMessage(msg.id);
});
$msg.find('button.prompt_yes').click(function(){
if(!confirm("수락하시겠습니까?")){
return false;
}
responseMessage(msg.id, true);
});
$msg.find('button.prompt_no').click(function(){
if(!confirm("거절하시겠습니까?")){
return false;
}
responseMessage(msg.id, false);
});
if($existMsg.length){
return null;
}
else{
return $msg;
}
});
if(addFront){
$msgBoard.prepend($msgs);
}
else{
$msgBoard.find('.load_old_message').before($msgs);
}
});
}
deferred
.then(checkErasable)
.then(checkClear)
.then(registerSequence)
.then(refineMessageObjs)
.then(printTemplate);
}
function refreshMailboxList(obj){
//$.ajax는 data, textStatus, jqXHR를 가진다
//when으로 묶었으므로 data를 풀어야함.
obj = obj[0];
var $mailboxList = $('#mailbox_list');
$mailboxList.change(function(){
console.log($(this).val());
})
var oldSelected = $mailboxList.val();
$mailboxList.empty();
var $lastContact = $('#last_contact');
var lastContact = null;
if($lastContact.length > 0 && $lastContact.val()>=0){
lastContact = {
id:$lastContact.val(),
textName:$lastContact.html()
};
$lastContact = null;
}
generalList = {};
obj.nation.sort(function(lhs, rhs){
if(lhs.mailbox == myNation.mailbox){
return -1;
}
if(rhs.mailbox == myNation.mailbox){
return 1;
}
return lhs.mailbox - rhs.mailbox;
})
$.each(obj.nation, function(){
var nation = this;
//console.log(nation);
var $optgroup = $('<optgroup label="{0}"></optgroup>'.format(nation.name));
$optgroup.css('background-color', nation.color);
if(myNation.mailbox == nation.mailbox){
myNation.color = nation.color;
}
if(isBrightColor(nation.color)){
$optgroup.css('color', 'black');
}
else{
$optgroup.css('color', 'white');
}
nation.general.sort(function(lhs, rhs){
if(lhs[1] < rhs[1]){
return -1;
}
if(lhs[1] > rhs[1]){
return 1;
}
return 0;
});
$.each(nation.general, function(){
var generalID = this[0];
var generalName = this[1];
var isNPC = !!(this[2] & 0x2);
var isRuler = !!(this[2] & 0x1);
var isAmbassador = !!(this[2] & 0x4);
if(generalID == myGeneralID){
return true;
}
var textName = generalName;
if(isRuler){
textName = '*{0}*'.format(textName);
}
else if(isAmbassador){
textName = '#{0}#'.format(textName);
}
generalList[generalID] = {
id:generalID,
name:generalName,
textName:textName,
isRuler:isRuler,
nation:nation.nationID,
color:nation.color
};
var $item = $('<option value="{0}">{1}</option>'.format(generalID, textName));
if(permissionLevel == 4 && isAmbassador && myNation.mailbox != nation.mailbox){
$item.prop('disabled', true);
}
$optgroup.append($item);
});
$mailboxList.append($optgroup);
});
var $favorite = $('<optgroup label="즐겨찾기"></optgroup>');
//아국메시지, 전체메시지
var $ourCountry = $('<option value="{0}">【 아국 메세지 】</option>'.format(myNation.mailbox))
.css({'background-color':myNation.color, 'color':isBrightColor(myNation.color)?'black':'white'});
var $toPublic = $('<option value="9999">【 전체 메세지 】</option>');
$favorite.append($ourCountry);
$favorite.append($toPublic);
$lastContact = $('<option id="last_contact" value="-1"></option>').hide();
if(lastContact){
$lastContact.show().val(lastContact.id).html(lastContact.textName);
}
$favorite.append($lastContact);
//TODO:운영자를 추가하는 코드도 넣을 것.
if(permissionLevel >= 4){
$.each(obj.nation, function(){
var nation = this;
//console.log(nation);
var $nation = $('<option value="{0}">{1}</option>'.format(nation.mailbox,nation.name));
$nation.css('background-color', nation.color);
if(isBrightColor(nation.color)){
$nation.css('color', 'black');
}
else{
$nation.css('color', 'white');
}
$favorite.append($nation);
});
}
$mailboxList.prepend($favorite);
if(!oldSelected){
$mailboxList.val(myNation.mailbox);
}
else{
$mailboxList.val(oldSelected);
}
}
function registerGlobal(basicInfo){
window.myNation = {
'id':basicInfo.myNationID,
'mailbox':basicInfo.myNationID+9000,
'color':'#000000',
'nation':'재야'
};
window.myGeneralID = basicInfo.generalID;
window.isChief = basicInfo.isChief;
window.myOfficerLevel = basicInfo.officerLevel;
window.permissionLevel = basicInfo.permission;
}
function activateMessageForm(){
var $msgInput = $('#msg_input');
var $msgSubmit = $('#msg_submit');
var $mailboxList = $('#mailbox_list');
$msgInput.keypress(function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) {
$msgSubmit.trigger('click');
return true;
}
});
$msgSubmit.click(function(){
var text = $.trim($msgInput.val());
$msgInput.val('').focus();
var targetMailbox = $mailboxList.val();
console.log(targetMailbox, text);
var deferred;
if(text){
deferred = $.ajax({
url:'j_msg_submit.php',
type: 'post',
dataType:'json',
data: {
data: JSON.stringify({
mailbox:parseInt(targetMailbox),
text:text
})
}
});
}
else{
deferred = $.Deferred();
deferred.resolve({
result:true,
reason:'no_text'
});
}
deferred.then(refreshMsg);
});
}
jQuery(function($){
//tmp_template.html은 추후 msg.js에 통합될 수 있음
var getTemplate = $.get('js/templates/message.html?12',function(obj){
messageTemplate = obj;
});
//basic_info.json은 세션값에 따라 동적으로 바뀌는 데이터임.
var basicInfo = $.ajax({
url:'j_basic_info.php',
type: 'post',
dataType:'json',
}).then(registerGlobal);
//sender_list.json 은 서버측에선 캐시 가능한 데이터임.
var senderList = $.ajax({
url: 'j_msg_contact_list.php',
type: 'post',
dataType:'json',
});
var MessageList = fetchRecentMsg();
senderList = $.when(senderList, basicInfo)
.then(refreshMailboxList)
.then(activateMessageForm);
$.when(MessageList, getTemplate, basicInfo, senderList)
.then(function(){
redrawMsg(MessageList, true);
}).then(function(){
$('.load_old_message').click(function(){
var $this = $(this);
var msgType = $this.data('msg_type');
showOldMsg(msgType);
})
});
});
+13 -13
View File
@@ -17,7 +17,7 @@ class Message
public $isInboxMail = false;
protected $sendCnt = 0;
public $msgType;
/** @var \sammo\MessageTarget */
public $src;
@@ -28,7 +28,7 @@ class Message
public $date;
/** @var \DateTime */
public $validUntil;
public $msgOption;
public function __construct(
@@ -107,7 +107,7 @@ class Message
public function toArray():array{
if($this->msgType === Message::MSGTYPE_PUBLIC){
$src = $this->src->toArray();
$dest = [];
$dest = null;
}
else if($this->msgType === Message::MSGTYPE_NATIONAL || $this->msgType === Message::MSGTYPE_DIPLOMACY){
$src = $this->src->toArray();
@@ -235,7 +235,7 @@ class Message
* @param int $mailbox 메일 사서함.
* @param string $msgType 메일 타입. MSGTYPE 중 하나.
* @param int $toSeq 가져오고자 하는 위치. $toSeq보다 '작은' seq만 가져온다.
* @param int $limit 가져오고자 하는 수.
* @param int $limit 가져오고자 하는 수.
* @return Message[]
*/
public static function getMessagesFromMailBoxOld(int $mailbox, string $msgType, int $toSeq, int $limit = 20)
@@ -291,7 +291,7 @@ class Message
}
$msgOption = [
'hide'=>true,
'hide'=>true,
'silence'=>true,
'overwrite'=>[$msgObj->id]
];
@@ -305,15 +305,15 @@ class Message
$msgOption['overwrite'][] = [$msgObj2->id];
}
}
}
$in1min = new \DateTime();
$in1min->add(new \DateInterval('PT1M'));
$newMsg = new Message(
$msgObj->msgType,
$msgObj->src,
$msgObj->dest,
$msgObj->msgType,
$msgObj->src,
$msgObj->dest,
"req_del_msg",
new \DateTime(),
$in1min,
@@ -381,7 +381,7 @@ class Message
else{
return $this->sendRaw($this->src->nationID + self::MAILBOX_NATIONAL);
}
}
return [0, 0];
}
@@ -443,7 +443,7 @@ class Message
$this->sendCnt = 2;
}
}
return $receiveID;
}
@@ -463,8 +463,8 @@ class Message
}
$this->msg = '삭제된 메시지입니다.';
}
$db = DB::db();
$db->update('message', [
'message' => Json::encode([
+9 -7
View File
@@ -14,6 +14,7 @@ import { TemplateEngine } from './util/TemplateEngine';
import { isNotNull } from './util/isNotNull';
import { unwrap_any } from './util/unwrap_any';
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
import { exportWindow } from './util/exportWindow';
let messageTemplate: string | undefined;
let myGeneralID: number | undefined;
//let isChief: boolean | undefined;
@@ -48,7 +49,7 @@ type MsgItem = {
id: number,
msgType: MsgType;
src: MsgTarget;
dest: MsgTarget;
dest?: MsgTarget;
text: string,
option: Record<string, string | number>;
time: string;
@@ -150,10 +151,11 @@ async function deleteMessage(msgID: number): Promise<MsgResponse> {
return await refreshMsg();
}
async function refreshMsg(): Promise<MsgResponse> {
export async function refreshMsg(): Promise<MsgResponse> {
const value = await fetchRecentMsg();
return redrawMsg(value, true);
}
exportWindow(refreshMsg, 'refreshMsg');
async function fetchRecentMsg(): Promise<MsgResponse> {
const response = await axios({
@@ -218,7 +220,7 @@ function redrawMsg(msgResponse: MsgResponse, addFront: boolean): MsgResponse {
lastSequence = Math.max(lastSequence ?? 0, obj.sequence);
for (const msgType of ['public', 'private', 'national', 'diplomacy'] as MsgType[]) {
const msgList = obj[msgType];
if (!msgList) {
if (!msgList || msgList.length == 0) {
continue;
}
const lastMsg = unwrap(_.last(msgList));
@@ -248,7 +250,7 @@ function redrawMsg(msgResponse: MsgResponse, addFront: boolean): MsgResponse {
//list의 맨 앞이 가장 최신 메시지임.
const $msgs: JQuery<HTMLElement>[] = msgSource.map(function (msg) {
const contactTarget = (msg.src.id != myGeneralID) ? msg.src.id : msg.dest.id;
const contactTarget = (msg.src.id != myGeneralID || msg.msgType === 'public') ? msg.src.id : unwrap(msg.dest).id;
if (needRefreshLastContact && contactTarget != myGeneralID && contactTarget in generalList) {
needRefreshLastContact = false;
$('#last_contact').val(contactTarget).html(generalList[contactTarget].textName).show();
@@ -269,8 +271,8 @@ function redrawMsg(msgResponse: MsgResponse, addFront: boolean): MsgResponse {
}
const dest = {
...msg.dest,
colorType: isBrightColor(msg.dest.color) ? 'bright' as const : 'dark' as const,
...(msg.dest??msg.src),
colorType: isBrightColor((msg.dest??msg.src).color) ? 'bright' as const : 'dark' as const,
};
if (!dest.nation) {
@@ -612,7 +614,7 @@ function activateMessageForm() {
})
const result: InvalidResponse = response.data;
if (!result.result) {
throw result.reason;
alert(result.reason);
}
await refreshMsg();
});