Продолжаем развитие системы добавления в друзья. На этот раз реализован расширенный механизм подтверждения, делающий процесс более осмысленным и двусторонним.
Изначально пользователь отправляет запрос на добавление в друзья, который представляет собой структурированное уведомление с предложением установить контакт. На стороне получателя этот запрос отображается в виде письма, где он может внимательно ознакомиться с намерением.
Дальнейшее развитие сценария зависит исключительно от решения получателя. Если он не заинтересован в установлении дружеской связи, он просто отклоняет запрос в этом случае процесс завершается без каких-либо последствий, и добавление в список друзей не происходит.
Если же получатель подтверждает запрос, система автоматически инициирует взаимное добавление: он принимает вас в свой список друзей и одновременно отправляет встречный запрос, завершая тем самым цикл взаимного согласия.
Дополнительно реализована система предварительной классификации. При отправке запроса инициатор может выбрать категорию например, «друзья», «кумир» и другие обозначения. Эта информация передаётся адресату, который, в свою очередь, получает возможность изменить предложенную категорию в соответствии со своим восприятием.
После выбора или подтверждения категории инициатор получает финальное уведомление для подтверждения. На этом этапе он уже не может вносить изменения остаётся лишь согласиться с предложенной классификацией. В случае отказа взаимная дружба не устанавливается.
Таким образом, процесс становится более длительным и формализованным, но при этом обеспечивает главное , взаимное и осознанное согласие обеих сторон.
Есть ещё один важный момент, но объясню проще.
Скрипт работает через модуль блога, он создаёт и удаляет записи. Но у обычных пользователей по умолчанию нет прав это делать, поэтому скрипт может не работать.
Чтобы всё работало нормально, нужно зайти в настройки и отключить премодерацию (снять галочку) и разрешить удалять темы. Тогда скрипт сможет сам создавать и удалять записи, а значит корректно добавлять и удалять друзей.
html += '<div class="my-friend-card">'; html += '<div class="friend-avatar-friends" style="background-image:url(\''+f.ava+'\');" data-profile="'+f.profile+'"></div>'; html += '<div class="friend-nick-friends"><a href="'+f.profile+'" target="_blank">'+f.nick+'</a></div>'; if(f.group) html += '<div class="friend-group-friends">'+f.group+'</div>'; html += '</div>';
$.get(url).done(function(data){ var $data = $('<div>').append($.parseHTML(data)); var $items = $data.find(".friend, .fr, .друг, .friend-item, .fr-item"); if (!$items.length) $items = $data.find(".entry, .entry-card, .user-row");
var all = [];
$items.each(function(){ var $it = $(this);
// Пытаемся корректно достать аватар (несколько вариантов) var ava = ''; var $img = $it.find('img').first(); if ($img.length && ($img.attr('src') || '').match(/avatar/)) { ava = $img.attr('src'); if (ava && ava.indexOf('http') !== 0) ava = location.origin + ava; } else { var text = $it.text(); var avaMatch = text.match(/(\/avatar\/\d{2}\/\d{2}\/\d+\.(?:png|jpg))/); ava = avaMatch ? location.origin + avaMatch[0] : ''; }
// ← добавляем эту строку var DEFAULT_AVA = "/.s/src/profile/img/profile_photo_thumbnail.png"; if (!ava) ava = DEFAULT_AVA;
// ссылка на профиль var profileUrl = '#'; var hrefMatch = $it.html().match(/https?:\/\/[^\s"']+\/index\/8-(\d+)/); if (hrefMatch) { profileUrl = location.origin + '/index/8-' + parseInt(hrefMatch[1],10); } else { var $aProfile = $it.find('a[href*="/index/8-"]').first(); if ($aProfile.length) { profileUrl = $aProfile.attr('href'); if (profileUrl && profileUrl.indexOf('http') !== 0) profileUrl = location.origin + profileUrl; } }
// Ник и группы var textClean = $it.clone(); textClean.find('img, a, .ava, .del, .gr').remove(); var nick = (textClean.text() || '').trim().split('\n')[0] || 'Без имени'; nick = nick.replace(/\s{2,}/g,' ').trim(); var groupMatches = ($it.text().match(/(Кумир|Семья|Друг|Приятель|Коллега|Знакомый)/gi) || []); var groups = groupMatches;
// MODER_PANEL — ссылка удаления (если есть) var del = ''; var $delEl = $it.find('.del, .del-link').first(); if ($delEl.length) { del = ($delEl.text() || $delEl.attr('href') || '').trim(); } if (!del) { var delMatch = $it.html().match(/\/index\/92-3-\d+/); del = delMatch ? delMatch[0] : ''; }
// клик по аватару — открываем профиль $(document).on('click', '.friend-avatar-friends', function(){ var p = $(this).data('profile') || '#'; if (p && p !== '#') window.open(p, '_blank'); });
// Удаление крестиком — аккуратно формируем полный URL и шлём GET $(document).on('click', '.friend-delete-btn-friends', function(e){ e.preventDefault(); var $btn = $(this); var delUrl = decodeURIComponent($btn.data('del') || '');
if (!delUrl) { return alert('Ссылка удаления не найдена'); } if (!confirm('Вы уверены, что хотите удалить?')) return;
// если относительный — добавляем origin if (delUrl.indexOf('http') !== 0) { if (delUrl.charAt(0) !== '/') delUrl = '/' + delUrl; delUrl = location.origin + delUrl; }
<script type="text/javascript"> var othid = '$_USER_ID$'.trim(); var myid = '$USER_ID$'.trim();
$(document).ready(function(){
// Если мой ID = ID профиля, который смотрю → это я сам if (myid == othid) { $("#addFriendContainer").html(""); // делаем пустым, кнопка НЕ вставится return; // выходим и больше ничего не делаем }
// Иначе (это не я) → вставляем кнопку $("#addFriendContainer").html( '<a href="javascript:;" onclick="friends.sAdd(); return false;" class="btn-add">Добавить в друзья</a>' );
Пока у меня не было возможности полноценно протестировать скрипт например, на повторные клики, защиту от дублирующего добавления в друзья и другие ситуации, которые могут проявиться со временем. Проще говоря, я пока не могу точно сказать, насколько он надёжен и завершён.
В ближайших планах , внедрить на сайте систему уведомлений в формате «колокольчика»: заявки в друзья, подтверждения, сообщения от администрации. При этом хочется убрать личные сообщения из уведомлений и сделать всё более аккуратно, современно и удобно.
В целом, чем выше уровень продуманности функционала, тем более качественным и привлекательным будет выглядеть проект. Хотя, конечно, есть ограничения самой платформы uCoz , там особо не развернёшься.
Но я стараюсь находить нестандартные решения и добавлять интересные фишки.
Появилась ещё одна идея, довольно интересная, но при этом сложная в реализации. Насколько я знаю, многие пытались сделать нечто подобное на uCoz, но ни у кого не получилось. Посмотрим, может, я смогу что-то изменить.