قائمة الإشعارات الافتراضية في المنتديات تبدو بسيطة وجامدة، بينما اعتاد المستخدمون على شكل الإشعارات العصري في منصات التواصل. هذا الكود يغيّر مظهر الإشعارات ليصبح قريبًا من تصميم فيسبوك، دون أن يغير طريقة عملها. فهو يعرض الصورة الرمزية لكل عضو داخل الإشعار، ويضيف حولها إطارًا ملونًا يطابق لون اسم العضو، كما يضيف أيقونة خاصة لكل نوع من الإشعارات مثل التعليق والإعجاب وطلب الصداقة، بلون مميز يساعد على معرفة نوع الإشعار بمجرد النظر إليه. ويستبدل الكود أيضًا رمز الحذف "X" بأيقونة سلة مهملات أوضح.
لنسخ ModernBB - AwesomeBB
كود CSS
كود JavaScript
العنوان: اختيارك
المكان: جميع الصفحات
لنسخ phpBB2 - phpBB3 - PunBB - Invision
كود CSS
كود JavaScript
العنوان: اختيارك
المكان: جميع الصفحات
ثم اضغط على زر قدم.
تحديث بصري بسيط يمنح أعضاءك تجربة مألوفة وعصرية في متابعة إشعاراتهم. شكر خاص لصاحب الكود على هذا التصميم الأنيق الذي طوّره بالاستعانة بالذكاء الاصطناعي.
صاحب الكود: كونان2000
مثال على الكود
شرح تركيب الكود
اختر الأكواد المناسبة لنسخة منتداك.لنسخ ModernBB - AwesomeBB
كود CSS
CSS:
#fa_toolbar #fa_right #notif_list li .contentText {
float: right;
width: auto;
max-width: 100%;
}
#fa_toolbar #fa_right #notif_list li a.delete {
position: absolute;
left: 10px;
}
#fa_toolbar #fa_right #notif_list li {
padding: 0 0 10px!important;
border-bottom: dotted 1px #787f83;
}
i.fa-solid.fa-envelope {
background: #dd2a1d;
}
i.fa-solid.fa-comment {
background: #8BC34A;
}
i.fa-solid.fa-handshake {
background: #9C27B0;
left: 5px;
position: relative;
}
i.fa-solid.fa-tag {
background: #FF9800;
}
i.fa-solid.fa-thumbs-up {
background: #2196F3;
}
.fa-solid, .fas {
color: #efefef;
border-radius: 100px;
padding: 5px;
}
.notif_award {
border-radius: 100px;
float: none;
height: 40px;
position: relative;
width: 40px;
}
#fa_toolbar #fa_right #notif_list li a.delete:before,#notif-menu .delete:after {
content: "\f1f8";
font: normal normal normal 14px/1 FontAwesome;
font-weight: 400;
}كود JavaScript
العنوان: اختيارك
المكان: جميع الصفحات
JavaScript:
(function($){
$(function(){
console.log('[notifEnhancer V13] بدء التشغيل');
if (!$('link[href*="font-awesome"]').length) {
$('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">');
}
const iconsMap = {
'برسالة خاصة': '<i class="fa-solid fa-envelope"></i>',
'قام بالإعجاب': '<i class="fa-solid fa-thumbs-up"></i>',
'قام بوسمك': '<i class="fa-solid fa-tag"></i>',
'بطلب صداقة': '<i class="fa-solid fa-handshake"></i>',
'كتب رسالة': '<i class="fa-solid fa-comment"></i>'
};
const avatarCache = {};
function normalizeProfileUrl(href){
if (!href) return null;
if (href.startsWith('/')) return window.location.origin + href;
if (/^https?:\/\//i.test(href)) return href;
return window.location.origin + (href.startsWith('.') ? '' : '/') + href;
}
function fetchAvatarFromProfile(profileHref, callback){
if (!profileHref) return callback(null, null);
const norm = normalizeProfileUrl(profileHref);
if (avatarCache[norm] !== undefined) return callback(avatarCache[norm].src || null, avatarCache[norm].color || null);
$.ajax({
url: norm,
method: 'GET',
dataType: 'text',
success: function(html){
let imgMatch = html.match(/<div[^>]*class=["'][^"']*mod-login-avatar[^"']*["'][^>]*>\s*<img[^>]+src=["']([^"']+)["']/i);
let colorMatch = html.match(/<span[^>]+style=["'][^"']*color\s*:\s*(#[0-9A-Fa-f]{3,6})["'][^>]*>\s*<strong>/i);
const src = imgMatch ? imgMatch[1] : null;
const color = colorMatch ? colorMatch[1] : null;
avatarCache[norm] = { src: src || null, color: color || null };
callback(src || null, color || null);
},
error: function(){
avatarCache[norm] = { src: null, color: null };
callback(null, null);
}
});
}
function determineIcon(text){
for (const k in iconsMap){
if (text.includes(k)) return iconsMap[k];
}
return '';
}
function enhanceLi($li){
if (!$li || !$li.length || $li.hasClass('see_all') || $li.data('notif-enhanced')) return;
const $contentText = $li.find('.contentText').first();
if (!$contentText.length) return;
if ($li.find('.notif-avatar').length || $li.find('.notif-icon').length) {
$li.data('notif-enhanced', true);
return;
}
let $userLink = $contentText.find('a[href^="/u"]').first();
if (!$userLink.length) $userLink = $contentText.find('a[href*="member.php?u="]').first();
if (!$userLink.length) {
$li.data('notif-enhanced', true);
return;
}
const href = $userLink.attr('href');
const profileUrl = href;
fetchAvatarFromProfile(profileUrl, function(avatarSrc, userColor){
const fallback = ($('.mod-login-avatar img').first().attr('src') || '');
const finalSrc = avatarSrc || fallback || null;
if (!$li.find('> .content').length) {
const innerHtml = $li.html();
$li.empty().append(`<div class="content">${innerHtml}</div>`);
}
const $content = $li.find('> .content');
$content.css({'position':'relative','min-height':'50px','padding':'4px 60px'});
if (finalSrc && !$content.find('.notif-avatar').length) {
const $img = $('<img class="notif-avatar" />').attr('src', finalSrc)
.css({
'width':'50px',
'height':'50px',
'border-radius':'50%',
'margin-inline-end':'2px',
'vertical-align':'middle',
'position':'absolute',
'right':'0',
'object-fit':'cover',
'border': userColor ? `2px solid ${userColor}` : 'none'
});
$content.prepend($img);
}
const icon = determineIcon($contentText.text());
if (icon && !$content.find('.notif-icon').length) {
const $span = $('<span class="notif-icon" />').html(icon)
.css({
'vertical-align':'middle',
'font-size':'16px',
'position':'absolute',
'right':'33px',
'top':'33px',
'z-index':'888888'
});
$content.prepend($span);
}
$li.data('notif-enhanced', true);
});
}
function processNotifList($list){
if (!$list || !$list.length) return;
$list.find('> li').each(function(){
enhanceLi($(this));
});
}
let globalObserver = new MutationObserver(function(mutations){
for (const m of mutations){
for (const node of m.addedNodes){
if (!(node instanceof Element)) continue;
const $maybe = $(node).find('#notif_list').addBack('#notif_list');
if ($maybe.length){
attachListObserver($maybe.get(0));
processNotifList($maybe);
}
}
}
});
globalObserver.observe(document.body, { childList: true, subtree: true });
function attachListObserver(listNode){
if (!listNode || listNode.__notifEnhancerAttached) return;
listNode.__notifEnhancerAttached = true;
const listObserver = new MutationObserver(function(){
setTimeout(function(){
processNotifList($(listNode));
}, 0);
});
listObserver.observe(listNode, { childList: true, subtree: true });
}
$('#fa_notifications').on('click', function(){
setTimeout(function(){
const $list = $('#notif_list');
if ($list.length){
attachListObserver($list.get(0));
processNotifList($list);
}
}, 0);
});
$(document).ready(function(){
const $ls = $('#notif_list');
if ($ls.length){
attachListObserver($ls.get(0));
processNotifList($ls);
}
});
console.log('[notifEnhancer V13] جاهز — تم تفعيل الإطار اللوني للصورة ');
});
})(jQuery);لنسخ phpBB2 - phpBB3 - PunBB - Invision
كود CSS
CSS:
#fa_toolbar #fa_right #notif_list li .contentText a {
display: inline-block;
max-width: 50%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#fa_toolbar #fa_right.notification #notif_list {
right: 35px;
left: auto !important;
}
#fa_toolbar #fa_right #notif_list li .contentText {
float: right;
width: auto;
max-width: 100%;
height: auto;
}
#fa_toolbar #fa_right #notif_list li a.delete {
position: absolute;
left: 10px;
}
#fa_toolbar #fa_right #notif_list li {
padding: 0 0 10px!important;
border-bottom: dotted 1px #787f83;
}
i.fa-solid.fa-envelope {
background: #dd2a1d;
}
i.fa-solid.fa-comment {
background: #8BC34A;
}
i.fa-solid.fa-handshake {
background: #9C27B0;
right: 5px;
position: relative;
}
i.fa-solid.fa-tag {
background: #FF9800;
}
i.fa-solid.fa-thumbs-up {
background: #2196F3;
}
.fa-solid, .fas {
color: #efefef;
border-radius: 100px;
padding: 5px;
}
.notif_award {
border-radius: 100px;
float: none;
height: 40px;
position: relative;
width: 40px;
}
#fa_toolbar #fa_right #notif_list li a.delete:after {
content: "\f1f8";
font: normal normal normal 14px/1 FontAwesome;
font-weight: 400;
}
#fa_toolbar #fa_right #notif_list li a.delete {
color: #F44336;
width: 22px;
height: 2.4em;
background: none;
float: left;
}كود JavaScript
العنوان: اختيارك
المكان: جميع الصفحات
JavaScript:
(function($){
$(function(){
console.log('[notifEnhancer V13] بدء التشغيل');
if (!$('link[href*="font-awesome"]').length) {
$('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">');
}
const iconsMap = {
'برسالة خاصة': '<i class="fa-solid fa-envelope"></i>',
'قام بالإعجاب': '<i class="fa-solid fa-thumbs-up"></i>',
'قام بوسمك': '<i class="fa-solid fa-tag"></i>',
'بطلب صداقة': '<i class="fa-solid fa-handshake"></i>',
'كتب رسالة': '<i class="fa-solid fa-comment"></i>'
};
const avatarCache = {};
function normalizeProfileUrl(href){
if (!href) return null;
if (href.startsWith('/')) return window.location.origin + href;
if (/^https?:\/\//i.test(href)) return href;
return window.location.origin + (href.startsWith('.') ? '' : '/') + href;
}
function fetchAvatarFromProfile(profileHref, callback){
if (!profileHref) return callback(null, null);
const norm = normalizeProfileUrl(profileHref);
if (avatarCache[norm] !== undefined) return callback(avatarCache[norm].src || null, avatarCache[norm].color || null);
$.ajax({
url: norm,
method: 'GET',
dataType: 'text',
success: function(html){
// التقاط أول صورة فيها مسار /avatars/
let imgMatch = html.match(/<img[^>]+src=["']([^"']+\/avatars\/[^"']+)["'][^>]*>/i);
// التقاط اللون من ستايل inline في <span>
let colorMatch = html.match(/<span[^>]+style=["'][^"']*color\s*:\s*(#[0-9A-Fa-f]{3,6})["'][^>]*>\s*<strong>/i);
const src = imgMatch ? imgMatch[1] : null;
const color = colorMatch ? colorMatch[1] : null;
avatarCache[norm] = { src: src || null, color: color || null };
callback(src || null, color || null);
},
error: function(){
avatarCache[norm] = { src: null, color: null };
callback(null, null);
}
});
}
function determineIcon(text){
for (const k in iconsMap){
if (text.includes(k)) return iconsMap[k];
}
return '';
}
function enhanceLi($li){
if (!$li || !$li.length || $li.hasClass('see_all') || $li.data('notif-enhanced')) return;
const $contentText = $li.find('.contentText').first();
if (!$contentText.length) return;
if ($li.find('.notif-avatar').length || $li.find('.notif-icon').length) {
$li.data('notif-enhanced', true);
return;
}
let $userLink = $contentText.find('a[href^="/u"]').first();
if (!$userLink.length) $userLink = $contentText.find('a[href*="member.php?u="]').first();
if (!$userLink.length) {
$li.data('notif-enhanced', true);
return;
}
const href = $userLink.attr('href');
const profileUrl = href;
fetchAvatarFromProfile(profileUrl, function(avatarSrc, userColor){
const fallback = ($('.mod-login-avatar img').first().attr('src') || '');
const finalSrc = avatarSrc || fallback || null;
if (!$li.find('> .content').length) {
const innerHtml = $li.html();
$li.empty().append(`<div class="content">${innerHtml}</div>`);
}
const $content = $li.find('> .content');
$content.css({'position':'relative','min-height':'50px','padding':'4px 60px'});
if (finalSrc && !$content.find('.notif-avatar').length) {
const $img = $('<img class="notif-avatar" />').attr('src', finalSrc)
.css({
'width':'50px',
'height':'50px',
'border-radius':'50%',
'margin-inline-end':'2px',
'vertical-align':'middle',
'position':'absolute',
'right':'0',
'object-fit':'cover',
'border': userColor ? `2px solid ${userColor}` : 'none'
});
$content.prepend($img);
}
const icon = determineIcon($contentText.text());
if (icon && !$content.find('.notif-icon').length) {
const $span = $('<span class="notif-icon" />').html(icon)
.css({
'vertical-align':'middle',
'font-size':'16px',
'position':'absolute',
'right':'33px',
'top':'33px',
'z-index':'888888'
});
$content.prepend($span);
}
$li.data('notif-enhanced', true);
});
}
function processNotifList($list){
if (!$list || !$list.length) return;
$list.find('> li').each(function(){
enhanceLi($(this));
});
}
let globalObserver = new MutationObserver(function(mutations){
for (const m of mutations){
for (const node of m.addedNodes){
if (!(node instanceof Element)) continue;
const $maybe = $(node).find('#notif_list').addBack('#notif_list');
if ($maybe.length){
attachListObserver($maybe.get(0));
processNotifList($maybe);
}
}
}
});
globalObserver.observe(document.body, { childList: true, subtree: true });
function attachListObserver(listNode){
if (!listNode || listNode.__notifEnhancerAttached) return;
listNode.__notifEnhancerAttached = true;
const listObserver = new MutationObserver(function(){
setTimeout(function(){
processNotifList($(listNode));
}, 0);
});
listObserver.observe(listNode, { childList: true, subtree: true });
}
$('#fa_notifications').on('click', function(){
setTimeout(function(){
const $list = $('#notif_list');
if ($list.length){
attachListObserver($list.get(0));
processNotifList($list);
}
}, 0);
});
$(document).ready(function(){
const $ls = $('#notif_list');
if ($ls.length){
attachListObserver($ls.get(0));
processNotifList($ls);
}
});
console.log('[notifEnhancer V13] جاهز — تم تفعيل الإطار اللوني للصورة ');
});
})(jQuery);ثم اضغط على زر قدم.
تحديث بصري بسيط يمنح أعضاءك تجربة مألوفة وعصرية في متابعة إشعاراتهم. شكر خاص لصاحب الكود على هذا التصميم الأنيق الذي طوّره بالاستعانة بالذكاء الاصطناعي.
صاحب الكود: كونان2000