Список пользователей

1
Админ
Постов: 211
2
VIP
Постов: 72
3
Элита
Постов: 50
4
Проверенные
Постов: 35
5
VIP
Постов: 35
6
Проверенные
Постов: 32
7
Пользователи
Постов: 31
8
Проверенные
Постов: 29

  • Страница 1 из 1
  • 1
Плавающая панель сообщений uCoz 1.0
Дата: Вторник, 10.02.2026, 14:24 | Сообщение # 1 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:211
         Регистрация:20.10.2016

Описание работы скрипта «Плавающий помощник сообщений»

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



Принцип работы

Панель выполняет роль мини-центра сообщений:

Скрипт постоянно проверяет наличие новых личных сообщений

Панель появляется только если сообщений больше 5

Если сообщений нет , панель автоматически скрывается

Работает в фоне как «тихий помощник»

Поведение панели

Когда сообщений становится больше 5:

В правом нижнем углу появляется плавающая панель уведомлений

Показывается счётчик новых сообщений

Отображаются:

аватар отправителя

имя

текст сообщения

дата

Панель не мешает работе пользователя и остаётся поверх страницы.

Сворачивание / разворачивание

Скрипт работает как помощник просмотра:

Можно развернуть панель и посмотреть сообщения

Можно свернуть, чтобы она не мешала

Скрипт запоминает состояние (свернуто / открыто)

После обновления страницы панель остаётся в том же виде

То есть - открыл, посмотрел, свернул, живёшь дальше 👍

Код
<?if($USER_LOGGED_IN$)?>

<style>
/* ======= СТИЛЬ СТАРОГО ВК ======= */
/* ======= OLD VK STYLE REWORK ======= */

.vk-notify{
position:fixed;
right:20px;
bottom:20px;
width:300px;
font-family:Tahoma, Arial, sans-serif;
font-size:12px;
border-radius:8px;
overflow:hidden;
display:none;
z-index:9999;
background:#e9edf3;
box-shadow:0 8px 22px rgba(0,0,0,0.25);
transition:all .25s ease;
}

/* ===== ШАПКА ===== */

.vk-notify-header{
background:linear-gradient(#5b84b6,#4a76a8);
color:#fff;
padding:9px 10px;
font-weight:bold;
cursor:pointer;
display:flex;
justify-content:space-between;
align-items:center;
border-bottom:1px solid rgba(0,0,0,0.15);
}

.vk-notify-header b{
background:#fff;
color:#4a76a8;
border-radius:50px;
padding:1px 7px;
font-weight:bold;
box-shadow:0 1px 2px rgba(0,0,0,0.2);
}

#vkNotifyToggle{
background:none;
border:none;
color:#fff;
font-size:12px;
cursor:pointer;
opacity:.85;
transition:.15s;
}
#vkNotifyToggle:hover{
opacity:1;
transform:scale(1.1);
}

/* ===== ТЕЛО ===== */

.vk-notify-body{
max-height:365px;
overflow-y:auto;
background:#f0f3f7;
padding:4px;
}

/* СКРОЛЛ */
.vk-notify-body::-webkit-scrollbar{
width:6px;
}
.vk-notify-body::-webkit-scrollbar-thumb{
background:#c7ced8;
border-radius:10px;
}
.vk-notify-body::-webkit-scrollbar-track{
background:transparent;
}

/* ===== СООБЩЕНИЕ ===== */

.vk-item{
display:flex;
align-items:center;
gap:8px;
padding:8px 10px;
margin:4px 2px;
cursor:pointer;

/* форма: слева капсула, справа почти ровно */
border-radius:10px 10px 8px 10px;

/* мягкий светлый желтый */
background:linear-gradient(#fffbe6,#fff3b0);

border:1px solid #eadf9b;

/* объём */
box-shadow:
   inset 0 1px 0 rgba(255,255,255,0.75),
   0 1px 2px rgba(0,0,0,0.08);

transition:all .15s ease;
}

/* HOVER — мягкий old VK */
.vk-item:hover{
background:linear-gradient(#fff7c9,#ffe88c);
border-color:#e2d276;

box-shadow:
   inset 0 1px 0 rgba(255,255,255,0.85),
   0 2px 5px rgba(0,0,0,0.12);

transform:translateY(-1px);
}

/* HOVER как в старом VK */
.vk-item:hover{
background:linear-gradient(#fff7c9,#ffe88c);
border-color:#e2d276;
box-shadow:
   inset 0 1px 0 rgba(255,255,255,0.8),
   0 2px 5px rgba(0,0,0,0.12);
transform:translateY(-1px);
}

/* АВАТАР */
.vk-item img{
width:42px;
height:42px;
border-radius:50%;
object-fit:cover;
border:1px solid #cfd6e0;
background:#fff;
box-shadow:0 1px 2px rgba(0,0,0,0.2);
}

/* ТЕКСТ */

.vk-item-title{
font-weight:bold;
color:#2a5885;
margin-bottom:1px;
}

.vk-item-text{
color:#111;
font-size:13px;
line-height:1.25;
}

.vk-item-date{
color:#7c8796;
font-size:11px;
margin-top:2px;
}

.vk-notify-empty{
padding:12px;
text-align:center;
color:#6f7b8c;
}

/* ===== СВЕРНУТО ===== */

.vk-notify.collapsed .vk-notify-body{
max-height:0 !important;
padding:0 !important;
overflow:hidden;
}

</style>

<div id="vkNotifyPanel" class="vk-notify">
<div class="vk-notify-header">
<span>Личные сообщения <b id="vkNotifyBadge">0</b></span>
<button id="vkNotifyToggle">—</button>
</div>
<div class="vk-notify-body">
<div class="vk-notify-empty">Загрузка сообщений...</div>
</div>
</div>

<script>
window.friends = window.friends || {};

(function ($, friends) {

const DEFAULT_AVA = "/files/person.png";
const CHECK_DELAY = 20000;
const STORAGE_KEY = "vkNotifyCollapsed";
const avatarCache = {};

const panel = $("#vkNotifyPanel");
const body = panel.find(".vk-notify-body");
const badge = $("#vkNotifyBadge");
const toggleBtn = $("#vkNotifyToggle");

/* ================= СОСТОЯНИЕ ПАНЕЛИ ================= */

function setCollapsed(state){
if(state){
   panel.addClass("collapsed").removeClass("expanded");
   toggleBtn.text("+");
   localStorage.setItem(STORAGE_KEY, "1");
}else{
   panel.removeClass("collapsed").addClass("expanded");
   toggleBtn.text("—");
   localStorage.setItem(STORAGE_KEY, "0");
}
}

setCollapsed(localStorage.getItem(STORAGE_KEY) === "1");

toggleBtn.on("click", function(e){
e.stopPropagation();
setCollapsed(!panel.hasClass("collapsed"));
});

panel.find(".vk-notify-header").on("click", function(e){
if($(e.target).is("#vkNotifyToggle")) return;
toggleBtn.click();
});

/* ================= ПОЛУЧЕНИЕ АВАТАРА (С КЭШЕМ) ================= */

async function fetchAvatar(profileUrl){
if(!profileUrl) return DEFAULT_AVA;

if(avatarCache[profileUrl]) return avatarCache[profileUrl];

try{
   const html = await $.get(profileUrl + "?r=" + Math.random());
   const bg = $(html).find(".profile-photo").first().css("background-image") || "";
   const m = bg.match(/url\(['"]?(.*?)['"]?\)/i);
   avatarCache[profileUrl] = m ? m[1] : DEFAULT_AVA;
   return avatarCache[profileUrl];
}catch(e){
   return DEFAULT_AVA;
}
}

/* ================= ЗАГРУЗКА СООБЩЕНИЙ ================= */

async function loadMessages(){

try{

   const html = await $.get("/index/14?" + Math.random());
   const $dom = $("<div>").append($.parseHTML(html));
   const $msgs = $dom.find("b.unread");

   badge.text($msgs.length);

   if($msgs.length === 0){
     panel.fadeOut(200);
     body.html('<div class="vk-notify-empty">Нет новых сообщений</div>');
     return;
   }

   panel.fadeIn(200);

   const oldScroll = body.scrollTop();
   const atBottom = body[0].scrollHeight - body.innerHeight() - oldScroll < 15;

   body.empty();

   for(const el of $msgs.toArray()){

     const $msg = $(el);
     const $row = $msg.closest("tr, li, div");

     const title = $msg.text().trim() || "Новое сообщение";

     const $nick = $row.find("a[href*='/index/8-0-']").last();
     let sender = $nick.text().trim() || "Пользователь";
     let profile = $nick.attr("href");

     if(profile && profile.startsWith("/"))
       profile = location.origin + profile;

     const avatar = await fetchAvatar(profile);

     const dateText = $row.find("td:nth-child(3), .message-date, time")
                          .first().text().trim() || "";

     const link = $msg.parent().attr("href") || "#";

     body.append(`
       <div class="vk-item" onclick="window.location.href='${link}'">
         <img src="${avatar}" onerror="this.src='${DEFAULT_AVA}'">
         <div>
           <div class="vk-item-title">${sender}</div>
           <div class="vk-item-text">${title}</div>
           <div class="vk-item-date">${dateText}</div>
         </div>
       </div>
     `);
   }

   /* сохраняем позицию скролла */
   if(atBottom){
     body.scrollTop(body[0].scrollHeight);
   }else{
     body.scrollTop(oldScroll);
   }

}catch(e){
   console.error("PM Load Error:", e);
   body.html('<div class="vk-notify-empty">Ошибка загрузки</div>');
}

}

/* ================= АВТО ОБНОВЛЕНИЕ ================= */

friends.checkPm = function(){
loadMessages();
setTimeout(friends.checkPm, CHECK_DELAY);
};

friends.checkPm();

})(jQuery, window.friends);
</script>

<?else?>
<!-- Гости ничего не видят -->
<?endif?>


Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
  • Страница 1 из 1
  • 1
Поиск: