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

1
Админ
Постов: 162
2
Элита
Постов: 45
3
VIP
Постов: 35
4
Проверенные
Постов: 31
5
Проверенные
Постов: 30
6
Пользователи
Постов: 27
7
VIP
Постов: 26
8
Пользователи
Постов: 24

  • Страница 1 из 1
  • 1
Финальная версия- модуль ВК «Друзья» для Ucoz v5.0
Дата: Четверг, 08.01.2026, 06:39 | Сообщение # 1 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:162
         Регистрация:20.10.2016

Минимальные доработки CSS и скрипта сделали модуль более функциональный инструмент. Встроенный поиск друзей делает его удобным, когда количество контактов велико.

Но, как мне кажется, есть явный прогресс. Модули постоянно совершенствуются, становятся удобнее, растет их функционал, вносятся новые изменения. Со временем можно будет добавить ещё больше инструментов: фотографии, видео и другие модули.

Если учитывать скорость разработки и время на доработку, реализация всех планов может занять полгода и более. Тем не менее, шаблон получится уникальным в своём роде.

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



Мини-модуль "Друзья" для сайта: удобство, функционал и прогресс

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

Структура модуля

Модуль состоит из нескольких ключевых элементов:

Мини-блок друзей
Это компактный блок, который отображает аватарки друзей в сетке 3 на 2. Каждый друг представлен картой с изображением и именем. Внизу блока показывается общее количество друзей, которое также служит кнопкой для открытия расширенного списка.

Popup с полным списком друзей

При клике на нижнюю часть мини-блока открывается всплывающее окно. В нём выводятся все друзья пользователя с аватаркой, статусом (например, "Друг" или "Кумир") и возможностью перейти на их профиль.

Поиск по друзьям
Нововведением стала строка поиска прямо в popup. Если у пользователя много друзей, поиск позволяет быстро найти нужного по имени. Это очень удобная фишка, повышающая юзабилити модуля.

Визуальные эффекты

CSS модуля тщательно продуман для удобного взаимодействия:

Аватарки друзей круглые, с тенями и аккуратной обводкой.

При наведении на мини-карточку друга она слегка увеличивается и становится ярче — это улучшает визуальный отклик.

Popup имеет стеклянный эффект заголовка, а список друзей прокручивается внутри с плавными стилями.

Скриптовая логика

JavaScript обеспечивает:

Подгрузку друзей с кэшем в localStorage для ускорения работы.

Рендеринг мини-сетки и полного списка друзей.

Фильтрацию друзей по имени через строку поиска в реальном времени.

Актуальное отображение количества друзей в кружке рядом с заголовком.

Пример функционала:

Код
// Минимальная демонстрация поиска
$('#friend-search').on('input', function(){
    renderList($(this).val());
});


Прогресс и перспективы

Модуль постоянно развивается:

Улучшаются стили и визуальные эффекты.

Добавляются новые функции, например, поиск по друзьям.

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

Сейчас модуль выполняет роль тренировочной площадки для более сложных проектов.

Исходной код.

Код
<!-- MINI BLOCK ДРУЗЬЯ -->
<div class="vk-old-block">
  <div class="vk-old-header">Друзья</div>
  <div class="vk-old-footer" id="friends-count">0 друзей</div>
  <div class="vk-old-content">
    <div class="vk-friends"></div>
  </div>
</div>

<style>
/* ================= MINI BLOCK ================= */
.vk-old-block {
  max-width:420px;
  background:#fff;
  border:1px solid #d1d5da;
  font-family:Tahoma,Arial,sans-serif;
  font-size:12px;
  border-radius:16px;
  overflow:hidden;
}

.vk-old-header {
  background:linear-gradient(180deg,#5d82b9,#4a6fa8);
  color:#fff;
  font-weight:bold;
  font-size:16px;
  padding:10px 12px;
  text-align:left;
  border-bottom:1px solid #d1d5da;
  border-top-left-radius:16px;
  border-top-right-radius:16px;
}

.vk-old-content {
  padding:10px;
}

.vk-old-footer {
  background:#f7f7f7;
  border-top:1px solid #d1d5da;
  padding:6px 12px;
  color:#666;
  font-size:12px;
  cursor:pointer;
  text-align:left;
  border-bottom-left-radius:0px;
  border-bottom-right-radius:0px;
}

/* ================= MINI FRIENDS GRID ================= */
.vk-friends {
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:10px 10px;
  justify-items:center;
}

.vk-friend {
  text-align:center;
  cursor:pointer;
}

.vk-friend img {
  width:82px;
  height:82px;
  border-radius:50%;
  object-fit:cover;
}

.vk-friend span {
  display:block;
  margin-top:4px;
  font-size:12px;
  color:#1d2c45;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

/* При наведении — слегка больше яркости */
.vk-friend:hover {
  filter: brightness(1.45); /* затемнение */
  transform: scale(1.00);   /* лёгкое увеличение */
}

/* ================= OVERLAY ================= */
.vk-ui-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.15);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.vk-ui-popup {
  width: 400px;            /* чуть уже */
  max-height: 190vh;         /* максимум по высоте экрана */
  height: auto;             /* автоматическая высота */
  background: #f5f6f8;
  border-radius: 24px;
  display: flex;
  flex-direction: column;
  overflow: visible;        /* важно */
  box-shadow: 0 30px 70px rgba(0,0,0,0.25);
  font-family: system-ui, -apple-system, Arial, sans-serif;
  border: 1px solid #d1d5da;
  padding: 0;
}

/* ================= HEADER ================= */
.vk-ui-header {
  padding: 18px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between; /* "Друзья" слева, поиск справа */
  background: rgba(93,130,185,0.9); /* стеклянный синий */
  backdrop-filter: blur(14px) saturate(180%) brightness(1.05);
  -webkit-backdrop-filter: blur(14px) saturate(180%) brightness(1.05);
  border-bottom: 1px solid rgba(0,0,0,0.12);
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
}

/* Заголовок "Друзья" */
.vk-ui-title {
  font-size: 20px;
  font-weight: 600;
  margin: 0;
  color: #ffffff;
}

/* Поиск справа */
.vk-ui-search {
  flex-shrink: 0;
}

.vk-ui-search input {
  width: 160px;
  padding: 8px 14px 8px 36px; /* минимальные отступы */
  border-radius: 14px;
  border: none;
  outline: none;
  font-size: 15px;
  background: rgba(255,255,255,0.95);
  color: #1d2c45;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='%2390a4c0'%3E%3Cpath d='M17.5 16l-4.3-4.3a7 7 0 1 0-1.4 1.4L16 17.5zM7 12a5 5 0 1 1 0-10 5 5 0 0 1 0 10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 10px center;
  background-size: 18px 18px;
}

/* ================= INNER BLOCK ================= */
.vk-ui-inner {
  background: #f9f9f9; /* светло-серый фон для внутреннего блока */
  padding: 14px; /* отступы внутри popup */
}

/* Внутренний белый блок */
.vk-ui-inner .vk-ui-subblock {
  background: #ffffff; /* сам белый блок внутри */
  padding: 12px; /* отступы внутри блока */
  border-radius: 12px;
  border: 1px solid #e4e8f0;
  margin-top: 12px; /* небольшой отступ от верхнего серого фона */
}

/* ================= FRIEND LIST ================= */
.vk-ui-list {
  max-height: 62vh;        /* больше места */
  overflow-y: auto;         /* прокрутка внутри */
  padding: 12px;
  margin: 12px;
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e4e8f0;
  box-sizing: border-box;
  flex: 1;                  /* тянется на всю доступную высоту */
}

/* Скрываем скролл для Webkit-браузеров (Chrome, Edge, Safari) */
.vk-ui-list::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* ROW */
.vk-ui-row {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e4e8f0;
  cursor: pointer;
  transition: background 0.2s ease;
}

.vk-ui-row:last-child {
  border-bottom: none;
}

.vk-ui-row:hover {
  background: #f5f7fb;
}

/* AVATAR */
.vk-ui-ava {
  position: relative;
  width: 88px;
  height: 88px;
}

.vk-ui-ava img {
  width: 88px;
  height: 88px;
  border-radius: 14px;
  object-fit: cover;
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}

/* STATUS LETTER */
.vk-ui-letter {
  position: absolute;
  bottom: -4px;
  left: -4px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 14px;
  color: #fff;
}

.vk-ui-letter.friend { background: #6b93c7; }
.vk-ui-letter.idol   { background: #c84b4b; }

/* INFO */
.vk-ui-info {
  flex: 1;
  margin-left: 14px;
}

.vk-ui-name {
  font-size: 20px;
  font-weight: 600;
  color: #1d2c45;
}

.vk-ui-badge {
  margin-top: 6px;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 14px;
  display: inline-block;
  color: #fff;
}

.vk-ui-badge.friend { background: #6b93c7; }
.vk-ui-badge.idol   { background: #c84b4b; }
.vk-ui-badge.nostatus { background: #8a8a8a; }

/* ARROW */
.vk-ui-arrow {
  font-size: 28px;
  color: #b6bfd6;
}

/* Кружок с числом друзей */
.vk-ui-title-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 27px;       /* размер кружка */
  height: 27px;
  margin-left: 0px;  /* отступ от слова "Друзья" */
  border-radius: 50%;
  background: #fff;  /* белый фон */
  border: 1px solid #7e7f80; /* белая обводка */
  color: #7e7f80;   /* серый цвет текста */
  font-size: 14px;
  font-weight: 700;
}

</style>

<script>
$(function(){
<?if(!$USER_LOGGED_IN$)?>

$('#friends-count').text('Друзей нет');
$('.vk-friends').empty();
return;

<?else?>

const USER_ID = '$_USER_ID$';
const CACHE_KEY = 'friends_' + USER_ID;
const CACHE_TIME_KEY = CACHE_KEY + '_time';
const CACHE_TTL = 24*60*60*1000;

const $container = $('.vk-friends');
const $counter = $('#friends-count');
const DEFAULT_AVA = '/.s/src/profile/img/profile_photo_thumbnail.png';

let allFriends = [];

/* ==== MINI GRID ==== */
function renderMini(friends){
  $container.empty();
  friends.slice(0,6).forEach(f=>{
    const card = $(`
      <div class="vk-friend">
        <img src="${f.ava}">
        <span>${f.nick}</span>
      </div>
    `);
    card.on('click',()=>location.href=f.profile);
    $container.append(card);
  });
  $counter.html(`${friends.length} друзей`);
}

/* ==== POPUP ==== */
function showPopup(){
  if(!allFriends.length) return;

  const overlay = $('<div class="vk-ui-overlay"></div>');

  const popup = $(`
    <div class="vk-ui-popup">
      <div class="vk-ui-header">
        <div class="vk-ui-title">
          Друзья
          <span class="vk-ui-title-count">${allFriends.length}</span>
        </div>
        <div class="vk-ui-search">
          <input type="text" placeholder="Поиск друзей" id="friend-search">
        </div>
      </div>
      <div class="vk-ui-list"></div>
    </div>
  `);

  const list = popup.find('.vk-ui-list');

  function renderList(filter=''){
    list.empty();
    allFriends
      .filter(f=>f.nick.toLowerCase().includes(filter.toLowerCase()))
      .forEach(f=>{
        let badge='Без статуса', cls='nostatus', letter='';
        const g=f.group.toLowerCase();
        if(g.includes('кумир')) { badge='Кумир'; cls='idol'; letter='К'; }
        else if(g.includes('друг')) { badge='Друг'; cls='friend'; letter='Д'; }

        const row=$(`
          <div class="vk-ui-row">
            <div class="vk-ui-ava">
              <img src="${f.ava}">
              ${letter?`<span class="vk-ui-letter ${cls}">${letter}</span>`:''}
            </div>
            <div class="vk-ui-info">
              <div class="vk-ui-name">${f.nick}</div>
              <div class="vk-ui-badge ${cls}">${badge}</div>
            </div>
            <div class="vk-ui-arrow">›</div>
          </div>
        `);
        row.on('click',()=>location.href=f.profile);
        list.append(row);
      });
  }

  renderList();

  // Поиск по вводу
  popup.find('#friend-search').on('input', function(){
    renderList($(this).val());
  });

  overlay.on('click', e => { if(e.target===overlay[0]) overlay.remove(); });
  overlay.append(popup);
  $('body').append(overlay);
}

/* ==== LOAD FRIENDS ==== */
function fetchFriends(){
  const cached = localStorage.getItem(CACHE_KEY);
  const time = localStorage.getItem(CACHE_TIME_KEY);

  if(cached && time && Date.now()-time<CACHE_TTL){
    allFriends = JSON.parse(cached);
    renderMini(allFriends);
  }

  $.get('/blog/0-0-1-0-17-'+USER_ID, html=>{
    const $tmp = $('<div>').html(html);
    allFriends = [];
    $tmp.find('.friend').each(function(){
      const $el=$(this);
      allFriends.push({
        nick: $el.find('.nick').text().trim(),
        ava: $el.find('.ava').text().trim()||DEFAULT_AVA,
        profile: $el.find('.url').text().trim(),
        group: $el.find('.gr').text().trim()||'Без статуса'
      });
    });
    localStorage.setItem(CACHE_KEY, JSON.stringify(allFriends));
    localStorage.setItem(CACHE_TIME_KEY, Date.now());
    renderMini(allFriends);
  });
}

$counter.on('click', showPopup);
fetchFriends();

<?endif?>
});
</script>


Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
Дата: Четверг, 08.01.2026, 08:34 | Сообщение # 2 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:162
         Регистрация:20.10.2016

Исправленная версия 2

Код
<!-- MINI BLOCK ДРУЗЬЯ -->
<div class="vk-old-block">
<div class="vk-old-header">Друзья</div>
<div class="vk-old-footer" id="friends-count">0 друзей</div>
<div class="vk-old-content">
<div class="vk-friends"></div>
</div>
</div>

<style>
/* ================= MINI BLOCK ================= */
.vk-old-block {
max-width:420px;
background:#fff;
border:1px solid #d1d5da;
font-family:Tahoma,Arial,sans-serif;
font-size:12px;
border-radius:16px;
overflow:hidden;
}

.vk-old-header {
background:linear-gradient(180deg,#5d82b9,#4a6fa8);
color:#fff;
font-weight:bold;
font-size:16px;
padding:10px 12px;
text-align:left;
border-bottom:1px solid #d1d5da;
border-top-left-radius:16px;
border-top-right-radius:16px;
}

.vk-old-content {
padding:10px;
}

.vk-old-footer {
background:#f7f7f7;
border-top:1px solid #d1d5da;
padding:6px 12px;
color:#666;
font-size:12px;
cursor:pointer;
text-align:left;
border-bottom-left-radius:0px;
border-bottom-right-radius:0px;
}

/* ================= MINI FRIENDS GRID ================= */
.vk-friends {
display:grid;
grid-template-columns:repeat(3, 1fr);
gap:10px 10px;
justify-items:center;
}

.vk-friend {
text-align:center;
cursor:pointer;
}

.vk-friend img {
width:82px;
height:82px;
border-radius:50%;
object-fit:cover;
}

.vk-friend span {
display:block;
margin-top:4px;
font-size:12px;
color:#1d2c45;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}

/* При наведении — слегка больше яркости */
.vk-friend:hover {
filter: brightness(1.45); /* затемнение */
transform: scale(1.00); /* лёгкое увеличение */
}

/* ================= OVERLAY ================= */
.vk-ui-overlay {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.15);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}

.vk-ui-popup {
width: 400px; /* чуть уже */
max-height: 190vh; /* максимум по высоте экрана */
height: auto; /* автоматическая высота */
background: #f5f6f8;
border-radius: 24px;
display: flex;
flex-direction: column;
overflow: visible; /* важно */
box-shadow: 0 30px 70px rgba(0,0,0,0.25);
font-family: system-ui, -apple-system, Arial, sans-serif;
border: 1px solid #d1d5da;
padding: 0;
}

/* ================= HEADER ================= */
.vk-ui-header {
padding: 18px 24px;
display: flex;
align-items: center;
justify-content: space-between; /* "Друзья" слева, поиск справа */
background: rgba(93,130,185,0.9); /* стеклянный синий */
backdrop-filter: blur(14px) saturate(180%) brightness(1.05);
-webkit-backdrop-filter: blur(14px) saturate(180%) brightness(1.05);
border-bottom: 1px solid rgba(0,0,0,0.12);
border-top-left-radius: 24px;
border-top-right-radius: 24px;
}

/* Заголовок "Друзья" */
.vk-ui-title {
font-size: 20px;
font-weight: 600;
margin: 0;
color: #ffffff;
}

/* Поиск справа */
.vk-ui-search {
flex-shrink: 0;
}

.vk-ui-search input {
width: 160px;
padding: 8px 14px 8px 36px; /* минимальные отступы */
border-radius: 14px;
border: none;
outline: none;
font-size: 15px;
background: rgba(255,255,255,0.95);
color: #1d2c45;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='%2390a4c0'%3E%3Cpath d='M17.5 16l-4.3-4.3a7 7 0 1 0-1.4 1.4L16 17.5zM7 12a5 5 0 1 1 0-10 5 5 0 0 1 0 10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: 10px center;
background-size: 18px 18px;
}

/* ================= INNER BLOCK ================= */
.vk-ui-inner {
background: #f9f9f9; /* светло-серый фон для внутреннего блока */
padding: 14px; /* отступы внутри popup */
}

/* Внутренний белый блок */
.vk-ui-inner .vk-ui-subblock {
background: #ffffff; /* сам белый блок внутри */
padding: 12px; /* отступы внутри блока */
border-radius: 12px;
border: 1px solid #e4e8f0;
margin-top: 12px; /* небольшой отступ от верхнего серого фона */
}

/* ================= FRIEND LIST ================= */
.vk-ui-list {
max-height: 62vh; /* больше места */
overflow-y: auto; /* прокрутка внутри */
padding: 12px;
margin: 12px;
background: #fff;
border-radius: 12px;
border: 1px solid #e4e8f0;
box-sizing: border-box;
flex: 1; /* тянется на всю доступную высоту */
}

/* Скрываем скролл для Webkit-браузеров (Chrome, Edge, Safari) */
.vk-ui-list::-webkit-scrollbar {
width: 0;
height: 0;
}

/* ROW */
.vk-ui-row {
display: flex;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid #e4e8f0;
cursor: pointer;
transition: background 0.2s ease;
}

.vk-ui-row:last-child {
border-bottom: none;
}

.vk-ui-row:hover {
background: #f5f7fb;
}

/* AVATAR */
.vk-ui-ava {
position: relative;
width: 88px;
height: 88px;
}

.vk-ui-ava img {
width: 88px;
height: 88px;
border-radius: 14px;
object-fit: cover;
box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}

/* STATUS LETTER (кружок с буквой) */
.vk-ui-letter.friend { background: #6b93c7; }      /* Друг */
.vk-ui-letter.idol { background: #c84b4b; }        /* Кумир */
.vk-ui-letter.family { background: #4a9e4a; }      /* Семья */
.vk-ui-letter.acquaintance { background: #8a8a8a; }/* Знакомый */
.vk-ui-letter.buddy { background: #d18c3b; }       /* Приятель */
.vk-ui-letter.nostatus { background: #bbbbbb; }    /* Без статуса */

/* BADGE (текстовый статус) */
.vk-ui-badge.friend { background: #6b93c7; }      
.vk-ui-badge.idol { background: #c84b4b; }
.vk-ui-badge.family { background: #4a9e4a; }
.vk-ui-badge.acquaintance { background: #8a8a8a; }
.vk-ui-badge.buddy { background: #d18c3b; }
.vk-ui-badge.nostatus { background: #bbbbbb; }

/* STATUS LETTER-2 */
.vk-ui-letter {
position: absolute;
bottom: -4px;
left: -4px;
width: 26px;
height: 26px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 14px;
color: #fff;
}

.vk-ui-letter.friend { background: #6b93c7; }
.vk-ui-letter.idol { background: #c84b4b; }

/* INFO */
.vk-ui-info {
flex: 1;
margin-left: 14px;
}

.vk-ui-name {
font-size: 20px;
font-weight: 600;
color: #1d2c45;
}

.vk-ui-badge {
margin-top: 6px;
padding: 6px 14px;
border-radius: 999px;
font-size: 14px;
display: inline-block;
color: #fff;
}

.vk-ui-badge.friend { background: #6b93c7; }
.vk-ui-badge.idol { background: #c84b4b; }
.vk-ui-badge.nostatus { background: #8a8a8a; }

/* ARROW */
.vk-ui-arrow {
font-size: 28px;
color: #b6bfd6;
}

/* Кружок с числом друзей */
.vk-ui-title-count {
display: inline-flex;
align-items: center;
justify-content: center;
width: 27px; /* размер кружка */
height: 27px;
margin-left: 0px; /* отступ от слова "Друзья" */
border-radius: 50%;
background: #fff; /* белый фон */
border: 1px solid #7e7f80; /* белая обводка */
color: #7e7f80; /* серый цвет текста */
font-size: 14px;
font-weight: 700;
}

</style>

<script>
$(function(){

<?if(!$USER_LOGGED_IN$)?>
    $('#friends-count').text('Друзей нет');
    $('.vk-friends').empty();
    return;
<?else?>

const USER_ID = '$_USER_ID$';
const CACHE_KEY = 'friends_' + USER_ID;
const CACHE_TIME_KEY = CACHE_KEY + '_time';
const CACHE_TTL = 24*60*60*1000;

const $container = $('.vk-friends');
const $counter = $('#friends-count');
const DEFAULT_AVA = '/.s/src/profile/img/profile_photo_thumbnail.png';

let allFriends = [];

/* ==== MINI GRID ==== */
function renderMini(friends){
    $container.empty();
    friends.slice(0,6).forEach(f=>{
        const card = $(`
            <div class="vk-friend" title="${f.nick}">
                <img src="${f.ava}">
                <span>${f.nick}</span>
            </div>
        `);
        card.on('click',()=>location.href=f.profile);
        $container.append(card);
    });
    $counter.html(`${friends.length} друзей`);
}

/* ==== POPUP ==== */
function showPopup(){
    if(!allFriends.length) return;

    const overlay = $('<div class="vk-ui-overlay"></div>');

    const popup = $(`
        <div class="vk-ui-popup">
            <div class="vk-ui-header">
                <div class="vk-ui-title">
                    Друзья <span class="vk-ui-title-count">${allFriends.length}</span>
                </div>
                <div class="vk-ui-search">
                    <input type="text" placeholder="Поиск друзей" id="friend-search">
                </div>
            </div>
            <div class="vk-ui-list"></div>
        </div>
    `);

    const list = popup.find('.vk-ui-list');

    function renderList(filter=''){
        list.empty();
        allFriends
            .filter(f => f.nick.toLowerCase().includes(filter.toLowerCase()))
            .forEach((f,i)=>{
                let badge = 'Без статуса', cls = 'nostatus', letter = '';
                const g = f.group.toLowerCase();

                // Определяем группу и статус
                if(g.includes('кумир')) { badge='Кумир'; cls='idol'; letter='К'; }
                else if(g.includes('друг')) { badge='Друг'; cls='friend'; letter='Д'; }
                else if(g.includes('сем')) { badge='Семья'; cls='family'; letter='С'; }
                else if(g.includes('знаком')) { badge='Знакомый'; cls='acquaintance'; letter='З'; }
                else if(g.includes('прият')) { badge='Приятель'; cls='buddy'; letter='П'; }
                else { badge = f.group || 'Без статуса'; cls='nostatus'; letter=''; }

                // Создаём строку друга
                const row = $(`
                    <div class="vk-ui-row ${cls}">
                        <div class="vk-ui-ava">
                            <img src="${f.ava}">
                            ${letter?`<span class="vk-ui-letter ${cls}">${letter}</span>`:''}
                        </div>
                        <div class="vk-ui-info">
                            <div class="vk-ui-name">${f.nick}</div>
                            <div class="vk-ui-badge ${cls}">${badge}</div>
                        </div>
                        <div class="vk-ui-arrow">›</div>
                    </div>
                `);

                row.on('click',()=>location.href=f.profile);
                list.append(row);
            });
    }

    renderList();

    // Поиск по вводу
    popup.find('#friend-search').on('input', function(){
        renderList($(this).val());
    });

    overlay.on('click', e => { if(e.target===overlay[0]) overlay.remove(); });
    overlay.append(popup);
    $('body').append(overlay);
}

/* ==== LOAD FRIENDS ==== */
function fetchFriends(){
    const cached = localStorage.getItem(CACHE_KEY);
    const time = localStorage.getItem(CACHE_TIME_KEY);

    if(cached && time && Date.now()-time < CACHE_TTL){
        allFriends = JSON.parse(cached);
        renderMini(allFriends);
    }

    $.get('/blog/0-0-1-0-17-'+USER_ID, html=>{
        const $tmp = $('<div>').html(html);
        allFriends = [];
        $tmp.find('.friend').each(function(){
            const $el=$(this);
            let group = $el.find('.gr').text().trim() || 'Без статуса';
            
            // Если группы новые, добавляем их
            const g = group.toLowerCase();
            if(!['друг','кумир','семья','знакомый','приятель'].some(k => g.includes(k))) {
                group = 'Приятель';
            }

            allFriends.push({
                nick: $el.find('.nick').text().trim(),
                ava: $el.find('.ava').text().trim() || DEFAULT_AVA,
                profile: $el.find('.url').text().trim(),
                group: group
            });
        });
        localStorage.setItem(CACHE_KEY, JSON.stringify(allFriends));
        localStorage.setItem(CACHE_TIME_KEY, Date.now());
        renderMini(allFriends);
    });
}

// Инициализация
$counter.css('cursor','pointer').attr('title','Показать всех друзей').on('click', showPopup);
fetchFriends();

<?endif?>

});
</script>

Мурчанн

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