Мини-чат на ajax

S

Sarymian

Гость
#1
Здравствуйте.

Решил внести свои 5 копеек плюс расширить аудиторию тестирующую мод.

Данный мод был доработан мною, за основу взят мод от

Please Login or Register to view hidden text.



Мод был доработан:
1) Вывод переведен в таблицу, чтобы избежать ситуаций когда "несколько" строк в сообщении выходили за пределы области печати сообщения (текст лез под аватар).

2) Доработан мульти-язык (все сообщения переведены на переменные типа $lang[]).

3) Доработан CSS, чтобы строки сообщений имели разный фон (чтоб не сливались).

4) Доработано удаление (по моим нуждам), сообщения не удаляются, а помечаются на удаление. За место сообщения выводится текст сообщающий об удаленном сообщении.

5) Доработано отображение чата с логическим разделением на админов и простых смертных (суть бага прошлого чата: когда админ писал сообщение кеш обновлялся и у ВСЕХ пользователей появлялся значек удаления сообщения, в противном случае если сообщение писал пользователь, то у администратора пропадали значки удаления сообщения).

#############################################################
## Название мода: Мини Чат на аякс / Mini Chat [ajax]
##Описание: это миничат который написанн на PHP и JavaScript , с использованием технологий Ajax для обмена данными,
## без необходимости перезагружать страницу.
## Используется база MySQL. Минимальная нагрузка на сервер (всё кешируется) поддержка смайлов, всех ббкодов и окраска ников. Аватарок, и отправка писем в личку.
##Автор: ??? адаптация TPII logon и PheRum ??? _Xz_ (в общем авторов больше чем строк кода.
##Доработал: Sarymian
##Сложность: легко
##Время установки: 3 мин
#############################################################


SQL

PHP:
CREATE TABLE IF NOT EXISTS `bb_shout` (
  `shout_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `shout_del` tinyint(1) NOT NULL DEFAULT '0',
  `shout_user_id` mediumint(8) NOT NULL DEFAULT '-1',
  `shout_session_time` int(11) NOT NULL DEFAULT '0',
  `shout_ip` char(8) NOT NULL DEFAULT '',
  `shout_text` varchar(1000) NOT NULL,
  PRIMARY KEY (`shout_id`),
  KEY `shout_id` (`shout_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
В файле index.php найти:
PHP:
$page_cfg['load_tpl_vars'] = array(
    'post_icons',
);
Ниже вставить
PHP:
$page_cfg['include_bbcode_js'] = true;
В файле Ajax.php найти:

PHP:
case 'view_post':
        require(INC_DIR .'bbcode.php');
    break;
Ниже вставить:
PHP:
case 'chat_message':
        require(INC_DIR .'functions_post.php');
        require(INC_DIR .'bbcode.php');
    break;
Найти:
PHP:
'view_post'        => array('guest'),
Ниже вставить:
PHP:
'shout_del'        => array('user'),
'chat_message'      => array('user'),
Перед последней скобкой }
PHP:
function chat_message()
  {
        global $bb_cache, $userdata, $bb_cfg, $lang;
        $mode = (int) $this->request['mode'];
        $message = (string) @$this->request['message'];
 
        if($mode==1)
        {
            if(!$message) $this->ajax_die($lang['SHOUTBOX_ERR']);
            $bbcode_on = $bb_cfg['allow_bbcode'];
            $smilies_on = $bb_cfg['allow_smilies'];
 
            if(!IS_ADMIN)
            {
                $chk = DB()->fetch_row('SELECT MAX(shout_session_time) AS last_post_time
                                        FROM bb_shout
                                        WHERE shout_user_id = '.$userdata['user_id']);
                if ( $chk['last_post_time'] > 0 && ( time() - $chk['last_post_time'] ) < $bb_cfg['flood_interval'] ) $this->ajax_die($lang['FLOOD_ERROR']);
            }
            if (!empty($message))
            {
                DB()->query('INSERT INTO bb_shout (shout_text, shout_session_time, shout_user_id, shout_ip)
                            VALUES ("'.DB()->escape($message).'", '.time().', '.$userdata['user_id'].', "'.USER_IP.'")');
                CACHE('bb_cache')->rm('shout_data_adm', 60);
                CACHE('bb_cache')->rm('shout_data', 60);
            }
        }
 
////////////////////////////////////////////////////////////////////////////////
          if (IS_AM)
          {
              if(!$shout_data = CACHE('bb_cache')->get('shout_data_adm', 60))
              {
                $shout_rows = DB()->fetch_rowset("SELECT s.*, u.username, u.user_level, u.user_rank, u.user_avatar, u.user_avatar_type
                                                  FROM bb_shout s, ".BB_USERS." u
                                                  WHERE s.shout_user_id=u.user_id AND u.user_id = u.user_id
                                                  ORDER BY s.shout_session_time DESC LIMIT 50");
                $i=0;
                $shout_data = '<table width="99%" cellspacing="0">';
                foreach ($shout_rows AS $shout_row)
                {
                    $row_class = !($i % 2) ? 'row1' : 'row2';
                    $user_level =  $shout_row['user_level'];
                    $username = ($user_level) ? profile_url($shout_row) : '<span>'.$shout_row['username'].'</span>' ;
 
                    $post_delete =($userdata['user_level'] == IS_AM ) ? '<img src="templates/default/images/shout/shout_delete.png" title ='.$lang['DEL_MASSAGE'].' class="clickable" onclick="ajax.shout_del('.$shout_row['shout_id'].'); ajax.chat_message(2); return false;" style="float:right">&nbsp;' : '';
 
                    $pm_link = ( !($shout_row['shout_user_id'] == $userdata['user_id']) && !($shout_row['shout_user_id'] < 0) ) ? '<a href="privmsg.php?mode=post&u='.$shout_row['shout_user_id'].'" target="_blank"><img title='.$lang['SEND_PRIVMSG'].' align="top" src="templates/default/images/shout/shout_mail.png" /></a>' : '';
 
                    $shout = $shout_row['shout_del']!=1 ? $shout_row['shout_text'] : $lang['SHOUT_CENSOR'];
                    $shout = str_replace("\n", "\n<br />\n", $shout);
                    $shout = ($user_level == ADMIN) ? '<span>'.$shout.'</span>' : $shout;
 
                    $shout_data .= '<tr id="shout_'.$shout_row['shout_id'].'" width:100%>
                                        <td class="chat-comment_'.$row_class.'" style="border-right: 1px solid #AED7FF;" valign="top" width="15%">
                                            <a href="profile.php?mode=viewprofile&u='.$shout_row['shout_user_id'].'" target="_blank" title='.$lang['SHOUT_VIEWPROFILE'].'>'.get_avatar($shout_row['user_avatar'], $shout_row['user_avatar_type'], !bf($userdata['user_opt'], 'user_opt', 'allow_avatar'), 32, 32).'</a>&nbsp;
                                            <span style="vertical-align:top"><a class="bold" title="'.$lang['SHOUTBOX_INSERT_NAME'].'" style="text-decoration: none;" href="javascript:add_nick(\'[b]'.addslashes($shout_row['username']).'[/b]\')">'.$username.' </a></span>&nbsp;
                                            '.$pm_link.'
                                            <div class="small" style="font-size: 9px; padding-left: 3px;">'.bb_date($shout_row['shout_session_time'], $bb_cfg['last_post_date_format']).'</div>
                                        </td>
 
                                        <td class="chat-comment_'.$row_class.'">
                                            <div style="float:right;">'.$post_delete.'</div>
                                            <span style="font-size: 11px;">'.bbcode2html($shout).'</span>
                                        </td>
                                  </tr>';
                    ++$i;
                }
                $shout_data .= '</table>';
                CACHE('bb_cache')->set('shout_data_adm', $shout_data);
                CACHE('bb_cache')->rm('shout_data');
              }
          }
////////////////////////////////////////////////////////////////////////////////
          else
          {
              if(!$shout_data = CACHE('bb_cache')->get('shout_data', 60))
              {
                $shout_rows = DB()->fetch_rowset("SELECT s.*, u.username, u.user_level, u.user_rank, u.user_avatar, u.user_avatar_type
                                                  FROM bb_shout s, ".BB_USERS." u
                                                  WHERE s.shout_user_id=u.user_id AND u.user_id = u.user_id
                                                  ORDER BY s.shout_session_time DESC LIMIT 50");
                $i=0;
                $shout_data = '<table width="99%" cellspacing="0">';
                foreach ($shout_rows AS $shout_row)
                {
                    $row_class = !($i % 2) ? 'row1' : 'row2';
                    $user_level =  $shout_row['user_level'];
                    $username = ($user_level) ? profile_url($shout_row) : '<span>'.$shout_row['username'].'</span>' ;
 
                    $post_delete = ($shout_row['shout_user_id'] == $userdata['user_id']) ? '<img src="templates/default/images/shout/shout_delete.png" title='.$lang['DEL_MASSAGE'].' class="clickable" onclick="ajax.shout_del('.$shout_row['shout_id'].'); ajax.chat_message(2); return false;" style="float:right">&nbsp;' : '';
 
                    $pm_link = ( !($shout_row['shout_user_id'] == $userdata['user_id']) && !($shout_row['shout_user_id'] < 0) ) ? '<a href="privmsg.php?mode=post&u='.$shout_row['shout_user_id'].'" target="_blank"><img title='.$lang['SEND_PRIVMSG'].' align="top" src="templates/default/images/shout/shout_mail.png" /></a>' : '';
 
                    $shout = $shout_row['shout_del']!=1 ? $shout_row['shout_text'] : $lang['SHOUT_CENSOR'];
                    $shout = str_replace("\n", "\n<br />\n", $shout);
                    $shout = ($user_level == ADMIN) ? '<span>'.$shout.'</span>' : $shout;
 
                    $shout_data .= '<tr id="shout_'.$shout_row['shout_id'].'" width:100%>
                                        <td class="chat-comment_'.$row_class.'" style="border-right: 1px solid #AED7FF;" valign="top" width="15%">
                                            <a href="profile.php?mode=viewprofile&u='.$shout_row['shout_user_id'].'" target="_blank" title='.$lang['SHOUT_VIEWPROFILE'].'>'.get_avatar($shout_row['user_avatar'], $shout_row['user_avatar_type'], !bf($userdata['user_opt'], 'user_opt', 'allow_avatar'), 32, 32).'</a>&nbsp;
                                            <span style="vertical-align:top"><a class="bold" title="'.$lang['SHOUTBOX_INSERT_NAME'].'" style="text-decoration: none;" href="javascript:add_nick(\'[b]'.addslashes($shout_row['username']).'[/b]\')">'.$username.' </a></span>&nbsp;
                                            '.$pm_link.'
                                            <div class="small" style="font-size: 9px; padding-left: 3px;">'.bb_date($shout_row['shout_session_time'], $bb_cfg['last_post_date_format']).'</div>
                                        </td>
 
                                        <td class="chat-comment_'.$row_class.'">
                                            <div style="float:right;">'.$post_delete.'</div>
                                            <span style="font-size: 11px;">'.bbcode2html($shout).'</span>
                                        </td>
                                  </tr>';
                    ++$i;
                }
                $shout_data .= '</table>';
                CACHE('bb_cache')->set('shout_data', $shout_data);
                CACHE('bb_cache')->rm('shout_data_adm');
              }
          }
        $this->response['message'] = $shout_data;
  }
 
  function shout_del()
    {
        global $bb_cache;
        $id = (int) $this->request['id'];
        DB()->query("UPDATE bb_shout SET `shout_del` = '1' WHERE shout_id =$id");
        $this->response['id'] = $id;
        CACHE('bb_cache')->rm('shout_data');
        CACHE('bb_cache')->rm('shout_data_adm');
    }
В файле index.tpl найти:
PHP:
<!-- IF TORHELP_TOPICS -->
    <!-- INCLUDE torhelp.tpl -->
    <div class="spacer_6"></div>
<!-- ENDIF / TORHELP_TOPICS -->
Вставить:
PHP:
<!-- IF LOGGED_IN -->
<script type="text/javascript">
    ajax.chat_message = function(mode) {
      ajax.exec({
        action : 'chat_message',
        mode : mode,
        message : $('#message').val()
      });
    };
    ajax.callback.chat_message = function(data) {
      if(data.message)
      {
        $('#chat').show();
        $('#chat').html(data.message);
        initPostBBCode('#chat');
      }
    };
    function submit_click(e) {
      e = e || window.event;
      if (e.keyCode == 13 && e.ctrlKey) {
        submit_chat();
      };
    }
    function add_nick(text){
      $('#message').attr('value', $('#message').val() + text +' ');
      $('#message').focus();
    }
    $(document).ready(function(){ajax.chat_message(2);});
    setInterval(function(){ajax.chat_message(2);}, 60000);
 
ajax.shout_del = function(id) {
  ajax.exec({
  action : 'shout_del',
  id : id
  });
  };
  ajax.callback.shout_del = function(data) {
  var id = data.id;
  $('td#shout_'+id).hide("slow");
  };
  </script>
 
<div class="category">
<div class="cat_title"><b>{L_MINI_CHAT}</b></div>
      <div class="f_tbl_wrap pad_4 tCenter">
        <form name="post">
        <textarea onkeydown="submit_click(event)" id="message" class="chat_message"></textarea>
<div class="buttons mrg_4 tLeft">
  <input class="button" type="button" value=" B " name="codeB" title="Bold (Ctrl+B)"  />&nbsp;
  <input class="button" type="button" value=" i " name="codeI" title="Italic (Ctrl+I)" style="font-style: italic;" />&nbsp;
  <input class="button" type="button" value=" u " name="codeU" title="Underline (Ctrl+U)" style="text-decoration: underline;" />&nbsp;
<input type="button" value="{L_QUOTE}" name="codeQuote" title="Quote (Ctrl+Q)" style="width: 60px;" />
  <input type="button" value="Img" name="codeImg" title="Image (Ctrl+R)" style="width: 40px;" />
 
<select name="codeColor" class="text_color">
  <option style="color: black; background: #fff;" value="black" selected="selected">{L_QR_COLOR_SEL}:</option>
  <option style="color: darkred;" value="darkred">{L_COLOR_DARK_RED}</option>
  <option style="color: brown;" value="brown">&nbsp;{L_COLOR_BROWN}</option>
  <option style="color: #996600;" value="#996600">&nbsp;{L_COLOR_ORANGE}</option>
  <option style="color: red;" value="red">&nbsp;{L_COLOR_RED}</option>
  <option style="color: #993399;" value="#993399">&nbsp;{L_COLOR_VIOLET}</option>
  <option style="color: green;" value="green">&nbsp;{L_COLOR_GREEN}</option>
  <option style="color: darkgreen;" value="darkgreen">&nbsp;{L_COLOR_DARK_GREEN}</option>
  <option style="color: gray;" value="gray">&nbsp;{L_COLOR_GRAY}</option>
  <option style="color: olive;" value="olive">&nbsp;{L_COLOR_OLIVE}</option>
  <option style="color: blue;" value="blue">&nbsp;{L_COLOR_BLUE}</option>
  <option style="color: darkblue;" value="darkblue">&nbsp;{L_COLOR_DARK_BLUE}</option>
  <option style="color: indigo;" value="indigo">&nbsp;{L_COLOR_INDIGO}</option>
  <option style="color: #006699;" value="#006699">&nbsp;{L_COLOR_STEEL_BLUE}</option>
</select>&nbsp;
 
<input type="submit"  name="usersubmit" class="lite" value="{L_UPDATE}" onclick="ajax.chat_message(2); return false;" title="{L_CHAT_UPDATE}"/>
<input type="button" name="usersubmit" class="lite" value="X" onclick="$('#message').attr('value', ''); $('#message').focus();" title="{L_MINI_CHAT_DROP}" />
<input type="button" name="usersubmit" class="lite" value="{L_EMOTICONS}"
onclick="window.open('posting.php?mode=smilies', '_phpbbsmilies', 'height=540, resizable=yes, scrollbars=yes ,width=620'); return false;" />
<input type="submit"  name="preview" class="lite" value="{L_SUBMIT}" onclick="ajax.chat_message(1); $('#message').attr('value', '');return false;" title="{L_SUBMIT}" />
      </div>
 
        <div class="clear"></div>
        <div class="spacer_2"></div>
        <div id="chat" class="tLeft hidden"></div>
        </form>
      </div>
    <div class="cat_footer"></div>
<script type="text/javascript">
var bbcode = new BBCode("message");
var ctrl = "ctrl";
 
bbcode.addTag("codeB", "b", null, "B", ctrl);
bbcode.addTag("codeI", "i", null, "I", ctrl);
bbcode.addTag("codeU", "u", null, "U", ctrl);
bbcode.addTag("codeQuote", "quote", null, "Q", ctrl);
bbcode.addTag("codeImg", "img", null, "R", ctrl);
 
 
bbcode.addTag("codeColor", function(e) { var v=e.value; e.selectedIndex=0; return "color="+v }, "/color");
 
 
</script>
  </div>
<div class="spacer" style="height:5px">&nbsp;</div>
<!-- ENDIF / LOGGED_IN-->
В файл Main.css в конец вставить:
PHP:
/*-- Чат --*/
  #chat { overflow: auto; width: 100%; height: 350px; }
  .chat-comment_row1 {
    min-height: 55px;
    height: auto;
    margin: 3px;
    padding: 4px;
    border: solid 1px #AED7FF;
    background-color: #ECF3FF;
    vertical-align:top;
  }
  .chat-comment_row2 {
    min-height: 55px;
    height: auto;
    margin: 3px;
    padding: 4px;
    border: solid 1px #AED7FF;
    background-color: #F9FCFF;
    vertical-align:top;
  }
  textarea.chat_message {
    height: 40px; width: 98%;
    border-radius: 5px;
    -moz-border-radius: 5px;
    font-size: 11px;
  }
  /*-- Чат конец--*/
В файл language/lang_russian/lang_main.php в конце вставить:
PHP:
//Chat lang
$lang['SHOUTBOX_INSERT_NAME'] = 'Вставить имя пользователя';
$lang['SHOUTBOX_ERR'] = 'Нужно ввести сообщение';
$lang['FLOOD_ERROR'] = 'Флуд запрещен!';
$lang['MINI_CHAT'] = 'Мини чат';
$lang['MINI_CHAT_DROP'] = 'Очистить поле ввода';
$lang['SHOUT_CENSOR'] = 'Сообщение удалено';
$lang['CHAT_UPDATE'] = 'Обновить чат';
$lang['DEL_MASSAGE'] = 'Удалить сообщение';
$lang['SEND_PRIVMSG'] = 'Послать личное сообщение';
$lang['SHOUT_VIEWPROFILE'] = 'Посмотреть профиль';
В файл language/lang_english/lang_main.php в конце вставить:
PHP:
//Chat lang
$lang['SHOUTBOX_INSERT_NAME'] = 'Insert username';
$lang['SHOUTBOX_ERR'] = 'You must enter a message';
$lang['FLOOD_ERROR'] = 'Flooding is prohibited';
$lang['MINI_CHAT'] = 'Mini Chat';
$lang['MINI_CHAT_DROP'] = 'Clear the input field';
$lang['SHOUT_CENSOR'] = 'Post deleted';
$lang['CHAT_UPDATE'] = 'Update Chat';
$lang['DEL_MASSAGE'] = 'Delete message';
$lang['SEND_PRIVMSG'] = 'Send private message';
$lang['SHOUT_VIEWPROFILE'] = 'View Profile';
Файл из архива залить в \templates\default\images


Скрин.JPG
 

Вложения

S

Sarymian

Гость
#2
Прошу отписываться по поводу недоработок, багов, фич и т.п. А так же пожелания, чтобы сделать.
 
S

Sarymian

Гость
#4
PheRum, простите но я не понял Вашего намека.

Я указал автора оригинального мода - в чем проблема? Мод в паблике, ни где не говорилось что ни кто не имеет права брать его и допиливать. Я считаю, что в некоторых моментах мод получился удачнее оригинал, почему бы его не выложить в паблик, чтобы каждый пользователь потом не изобретал велосипед?

Простите, но я абсолютно не понимаю к чему Ваше сообщение с "тонкими" намеком.
 
S

Sarymian

Гость
#6
Ну я как бы мысли читать не умею, тем более на расстоянии. Можно было прямо сказать, ни в одной ветке посвященной этому чату не говорилось про автора. Либо я упустил, т.к. в основном читал те сообщения где есть код.

Внес изменения, прошу прощения у автора (Roman) за недоразумение.
 

dredd

Пользователь
#8
Nikolaich, ну знаете. У меня никогда не было этого мода. Я знаю только о существовании чата от Exile и от Roman. Об этом чате никогда не слышал. Буду знать.
 
S

Sarymian

Гость
#9
Nikolaich, я вообще уже ни чего не понимаю. В теме от куда я взял код (указал в своём первом сообщении) говориться что чат взят из другой темы, в ней же Logon утверждает что портировал чат на TPII и помог ему PheRum. Сейчас Вы утверждаете, что это чат Лога. Так все же, этот чат достояния общественности (ибо я его взял свободно в теме которая есть на этом форуме), или у этого кода есть владелец который продает его (т.е. Лог и все предлагают купить чат у него).

В общем я запутался, я всего лишь хотел сделать доброе дело и выложить свои наработки. Посчитаете нужным удалить тему - пожалуйста.

З.Ы. я могу с чистой совестью сказать, что до текущего состояния чат довел я лично, ни тырил ни у кого код. Взял тот что был в свободном доступе на этом форуме (в паблике), и доработал его. Исходный од чата Лога я вообще ни разу не видел... собственно как и чат.

З.Ы.Ы. Nikolaich, если бы я хотел холывы и тырил чужие моды, разве я бы стал писать Вам, о том что мне предлагали в ЛС платные моды. В общем пускай, правообладатель появиться и скажет его это чат или нет.

а всего лишь хотел доброе дело сделать...
 

_Xz_

Пользователь
#10
правообладателю давно насрать на старые моды, он пишет только на заказ ©

ps также нет времени, желания, а главное стимула в этом году развивать проект...
 
Сверху