fc / facebook-ui.js
Althnayi's picture
Upload 56 files
cca0cf3 verified
Raw
History Blame Contribute Delete
39.1 kB
/**
* @fileoverview Facebook Campaign Composer UI & Quick Reload History Registry
* @module ui/facebook-ui
* @description بناء واجهة محرر منشورات فيسبوك، رفع المرفقات، وسجل التعبئة السريعة للمنشورات السابقة.
*/
(global => {
'use strict';
let uploadedImages = [];
/**
* تعيين نص محرر المنشور وإطلاق حدث التحديث
* @param {string} text
*/
const setComposerText = (text) => {
const el = document.getElementById('nmr6mtwgan');
if (el) {
el.value = text;
el.dispatchEvent(new Event('input', { bubbles: true }));
}
};
/**
* بناء واجهة محرر منشورات فيسبوك بالـ DOM
*/
const buildComposerLayout = () => {
const sidebar = document.getElementById('bmh59axx92');
const contentArea = document.getElementById('s7ihkirolg');
if (!sidebar || !contentArea) return;
if (!sidebar.querySelector('[data-target="sf1xx5vcac"]')) {
const navItem = document.createElement('div');
navItem.className = 'f2rj8bz2yt';
navItem.setAttribute('data-target', 'sf1xx5vcac');
navItem.innerHTML = '<i class="fa-brands fa-facebook"></i> <span>منشورات فيسبوك</span>';
sidebar.appendChild(navItem);
navItem.addEventListener('click', () => {
window.location.hash = 'sf1xx5vcac';
});
}
const host = document.getElementById('fritree-dynamic-panes-host') || contentArea;
let pane = document.getElementById('sf1xx5vcac');
if (!pane) {
pane = document.createElement('section');
pane.className = 'rjiai07g77';
pane.id = 'sf1xx5vcac';
const monitor = document.getElementById('cxyr0eirov');
if (host === contentArea && monitor) {
contentArea.insertBefore(pane, monitor);
} else {
host.appendChild(pane);
}
} else if (pane.parentElement !== host) {
host.appendChild(pane);
}
let grid = pane.querySelector('.xd506q5mar');
if (!grid) {
grid = document.createElement('div');
grid.className = 'xd506q5mar';
grid.style.cssText = 'display: grid; grid-template-columns: repeat(auto-fit, minmax(clamp(280px, 40vw, 1fr), 1fr)); gap: var(--space-md); margin-bottom: 15px; width: 100%; box-sizing: border-box;';
pane.appendChild(grid);
}
let composerCol = grid.querySelector('#tm3qz6sfor');
if (composerCol) return;
composerCol = document.createElement('div');
composerCol.className = 'd5tp7way8h';
composerCol.id = 'tm3qz6sfor';
composerCol.style.cssText = 'display: flex; flex-direction: column; height: 100%; box-sizing: border-box;';
composerCol.innerHTML = `
<div class="cm41ch7urz">
<span><i class="fa-solid fa-pen-nib" style="color: var(--primary);"></i> <span>كتابة منشورات فيسبوك للحملات</span></span>
</div>
<!-- إشعار تشغيل وضع التدوير التلقائي -->
<div class="suxidgikgm" id="h6gj77qmi8" style="display: none; border: 1.5px dashed #0d9488; background: #f0fdfa; margin-bottom: 12px; padding: 12px 14px; border-radius: var(--radius-md);">
<div class="dcaynff6el" style="border-bottom: 1px solid #ccfbf1; padding-bottom: 6px; display: flex; justify-content: space-between; align-items: center; font-weight: 800; font-size: 12.5px;">
<span style="color: #0f766e;"><i class="fa-solid fa-arrows-spin"></i> <span>وضع التدوير التلقائي للمحتوى نشط الآن</span></span>
<button id="hf3fgtgsrm" class="ipxi2jz4g0" style="padding: 3px 8px; font-size: 10.5px; background: #ffffff; border: 1px solid #99f6e4; cursor: pointer; color: #0f766e;"><i class="fa-solid fa-link-slash"></i> <span>إيقاف التدوير</span></button>
</div>
<p style="font-size: 11px; margin-top: 5px; color: #115e59; font-weight: 600;"><i class="fa-solid fa-circle-info"></i> <span id="o6w2b9ltn6">يتم حالياً سحب وتوزيع <b id="g87druhllc" style="color: #047857;">0</b> منشوراً مؤرشفاً تلقائياً بنمط: <b id="c8zauwlfq4">البدائل العشوائية والتدوير المتوازن</b>.</span></p>
</div>
<div id="qw35f6nlli" style="flex: 1; display: flex; flex-direction: column; gap: 10px;">
<!-- فاحص الـ Spintax وأداة التمويه -->
<div class="suxidgikgm" style="margin-bottom: 4px;">
<div class="dcaynff6el">
<div class="ipbz1xlmff" style="font-size: 12px;"><i class="fa-solid fa-wand-magic-sparkles" style="color: #8b5cf6;"></i> <span>محرك تجهيز نصوص الـ Spintax والتمويه</span></div>
<button type="button" id="p4x864vzc8" class="ipxi2jz4g0" style="padding: 3px 8px; font-size: 10.5px; height: auto;"><i class="fa-solid fa-mask"></i> <span>معاينة التمويه</span></button>
</div>
<div class="whbqh37dm1" style="font-size: 10.5px; color: var(--text-muted);">
<span id="d79lt2ra3p"><i class="fa-solid fa-calculator"></i> <span>البدائل الفريدة للتوليد: 1</span></span>
<span id="d7wfdy3mv4"><i class="fa-solid fa-fingerprint"></i> <span>مستوى التفرد: 0%</span></span>
<span id="kheemkug1v"></span>
</div>
<div id="v0brh83759"></div>
<div id="dg3a5v2fam" style="display:none; margin-top: 8px; padding: 10px; background: var(--bg-subtle); border: 1px dashed var(--border-strong); border-radius: var(--radius-md); font-size: 11px; text-align: right; direction: rtl;">
<strong style="display: block; margin-bottom: 4px; color: var(--text-main);"><i class="fa-solid fa-eye"></i> <span>مظهر النص النهائي بعد التمويه وحقن البيانات:</span></strong>
<div id="xtl6n8x46j" style="white-space: pre-wrap; color: var(--text-secondary); background: var(--bg-card); padding: 8px 10px; border-radius: var(--radius-sm); border: 1px solid var(--border); max-height: 100px; overflow-y: auto; font-size: 11.5px; line-height: 1.5;"></div>
<span style="font-size: 9.5px; margin-top: 4px; display: block; color: var(--text-muted);"><i class="fa-solid fa-info-circle"></i> <span>يتم تطبيق الحروف المتجانسة والفواصل الصفرية لحماية منشورك من الرصد الآلي.</span></span>
</div>
</div>
<textarea id="nmr6mtwgan" class="f0ngq4vbzj" style="height: 110px; min-height: 90px;" placeholder="اكتب نص منشورك هنا... جرب استخدام صيغ الـ Spintax لتفادي الحظر مثل: {عرض خاص|خصم هائل|صفقة ممتازة} لخدماتنا المميزة..."></textarea>
<!-- أشرطة إدراج المتغيرات السريعة -->
<div style="display: flex; gap: 6px; flex-wrap: wrap; align-items: center; background: var(--bg-subtle); padding: 8px 10px; border-radius: var(--radius-md); border: 1px solid var(--border);">
<span style="font-size: 10.5px; font-weight: 700; color: var(--text-muted);"><i class="fa-solid fa-plus-circle"></i> <span>إدراج متغير:</span></span>
<button type="button" class="ipxi2jz4g0 btn-var-insert" data-var="{{RAN_T(5)}}" style="padding: 3px 8px; font-size: 10px; min-height: 28px;" title="إدراج نص عشوائي من 5 رموز"><i class="fa-solid fa-font"></i> <span>نص عشوائي (5 رموز)</span></button>
<button type="button" class="ipxi2jz4g0 btn-var-insert" data-var="{{RAN_D(6)}}" style="padding: 3px 8px; font-size: 10px; min-height: 28px;" title="إدراج أرقام عشوائية من 6 خانات لمنع التطابق"><i class="fa-solid fa-hashtag"></i> <span>أرقام عشوائية (6 خانات)</span></button>
<button type="button" class="ipxi2jz4g0 btn-var-insert" data-var="{{GROUP_NAME}}" style="padding: 3px 8px; font-size: 10px; min-height: 28px;" title="إدراج اسم الجروب الحالي تلقائياً داخل المنشور"><i class="fa-solid fa-users"></i> <span>اسم الجروب تلقائي</span></button>
</div>
<!-- منطقة رفع الصور والوسائط -->
<div style="margin-top: 4px;">
<label style="font-size: 12px; font-weight: 700; color: var(--text-main); display: block; margin-bottom: 6px;"><i class="fa-solid fa-photo-film"></i> <span>المرفقات والصور مع المنشور (صور / فيديو):</span></label>
<div class="jbhynmzpf2" id="mm0yx6izkd" style="padding: 18px 24px;">
<i class="fa-solid fa-cloud-arrow-up fa-2x" style="color: var(--primary); margin-bottom: 4px;"></i>
<span style="font-size: 11.5px;"><i class="fa-solid fa-folder-open"></i> اسحب وأفلت الصور والفيديوهات هنا أو اضغط لاختيار الملفات من جهازك...</span>
<input type="file" id="ftglpwfdd9" multiple accept="image/*,video/mp4,video/webm" style="display: none;">
</div>
<div class="dlk0zpo39e" id="b2162at4z7"></div>
</div>
<!-- إعدادات طريقة النشر والجدولة -->
<div class="d0uttwsjz2" style="margin-top: 4px;">
<label style="font-size: 11.5px; font-weight: 700; color: var(--text-secondary);"><i class="fa-solid fa-window-restore"></i> <span>طريقة فتح وتشغيل حملة فيسبوك:</span></label>
<select id="q2hxmk5c3l" class="xy26ymifmf">
<option value="tab" selected>فتح المجموعات في تبويبات خلفية (الوضع القياسي الآمن)</option>
<option value="window">فتح المجموعات في نوافذ معزولة (أمان فائق ومحاكاة)</option>
</select>
</div>
<div class="d0uttwsjz2" style="margin-top: 4px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-subtle);">
<div style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="k58hokq80h" style="width:16px; height:16px; cursor:pointer; accent-color: var(--primary);">
<label for="k58hokq80h" style="font-weight: 700; margin: 0; cursor:pointer; font-size: 11.5px;"><i class="fa-solid fa-calendar-check"></i> <span>جدولة حملة النشر التلقائي لموعد لاحق</span></label>
</div>
<div id="sed4iycyc5" style="display: none; margin-top: 8px;">
<label style="font-size: 10.5px; font-weight: 700; display: block; margin-bottom: 4px;"><i class="fa-solid fa-clock"></i> <span>تاريخ ووقت الانطلاق المجدول:</span></label>
<input type="datetime-local" id="b3qy01i1dm" class="xy26ymifmf" style="padding: 6px 8px; font-size: 11px;">
</div>
</div>
<div id="x3wr8goh1j"></div>
</div>
<!-- أزرار الإطلاق والتحكم في الحملة -->
<div class="h7cnzzqbdl" style="margin-top: 10px; padding-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; border-top: 1px solid var(--border);">
<button id="q0ilg5gt03" class="itdnt14mss" style="flex: 2; min-width: 140px;" disabled><i class="fa-solid fa-paper-plane"></i> <span>بدء إطلاق الحملة</span></button>
<button id="ctmo3psebt" class="ipxi2jz4g0" style="flex: 1; padding: 8px 12px;" disabled><i class="fa-solid fa-pause"></i> <span>إيقاف مؤقت</span></button>
<button id="te6ue1mcua" class="btn-danger" style="flex: 1; padding: 8px 12px;" disabled><i class="fa-solid fa-circle-stop"></i> <span>تجميد وإيقاف</span></button>
<button id="d376lqov4g" class="ipxi2jz4g0" style="flex: 0.3; min-width: 40px;" title="تعديل فترات الانتظار والتبريد لفيسبوك"><i class="fa-solid fa-clock"></i> </button>
</div>
`;
grid.appendChild(composerCol);
injectQuickReloadUISection(pane);
};
/**
* بناء قسم سجل التعبئة السريعة للمنشورات الأخيرة
*/
const injectQuickReloadUISection = (pane) => {
let recentSection = pane.querySelector('#tsh9o5nfi9');
if (!recentSection) {
recentSection = document.createElement('div');
recentSection.id = 'tsh9o5nfi9';
recentSection.className = 'd5tp7way8h';
recentSection.style.cssText = 'margin-top: 14px; display: flex; flex-direction: column; width: 100%; border: 1px solid var(--border); box-sizing: border-box;';
recentSection.innerHTML = `
<div class="cm41ch7urz" style="margin-bottom: 10px; border-bottom: 1px solid var(--border); padding-bottom: 8px;">
<span><i class="fa-solid fa-clock-rotate-left" style="color: var(--primary);"></i> <span>سجل التعبئة السريعة للمنشورات الأخيرة</span></span>
</div>
<div class="dlk0zpo39e" id="r7n5amvrzl" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(clamp(240px, 25vw, 320px), 1fr)); gap: 10px; width: 100%; box-sizing: border-box;">
<div style="font-size: 11px; color: var(--text-muted); padding: 15px; text-align: center; width: 100%;">
<i class="fa-solid fa-circle-info"></i> <span>لا توجد منشورات مسجلة حديثاً في سجل التعبئة السريعة.</span>
</div>
</div>
`;
pane.appendChild(recentSection);
}
renderRecentPublishedList();
};
/**
* حفظ المنشور المنشور حديثاً بسجل التعبئة السريعة
*/
const savePublishedPostToRecent = async (text, images, groupIds) => {
const recentList = await global.FritreeStorage.get('fbRecentPublishedPosts', []);
const recentId = 'recent_fb_' + Date.now() + '_' + Math.random().toString(36).substr(2, 4);
const newRecord = {
id: recentId,
text: text,
groupIds: groupIds,
images: images,
timestamp: new Date().toISOString()
};
for (const img of images) {
const blob = await global.FritreeStorage.get(`media_blob_${img.id}`);
if (blob) {
await global.FritreeStorage.set(`media_blob_recent_${recentId}_${img.id}`, blob);
}
}
recentList.unshift(newRecord);
if (recentList.length > 15) {
const popped = recentList.pop();
if (popped && popped.images) {
for (const img of popped.images) {
await global.FritreeStorage.remove(`media_blob_recent_${popped.id}_${img.id}`);
}
}
}
await global.FritreeStorage.set('fbRecentPublishedPosts', recentList);
renderRecentPublishedList();
if (global.FritreeCalendar && typeof global.FritreeCalendar.logActivity === 'function') {
const titleSnippet = text ? (text.length > 40 ? text.substring(0, 40) + '...' : text) : 'منشور وسائط وصور';
global.FritreeCalendar.logActivity({
title: `[منشور فيسبوك] ${titleSnippet}`,
type: 'campaign',
category: 'campaign',
notes: `حملة نشر فيسبوك فورية على عدد (${groupIds ? groupIds.length : 0}) مجموعة مستهدفة. المرفقات: ${images ? images.length : 0} صورة/فيديو.`,
priority: 'high'
});
}
};
/**
* رسم وعرض بطاقات المنشورات الأخيرة في سجل التعبئة السريعة
*/
const renderRecentPublishedList = async () => {
const container = document.getElementById('r7n5amvrzl');
if (!container) return;
container.innerHTML = '';
const recentList = await global.FritreeStorage.get('fbRecentPublishedPosts', []);
if (recentList.length === 0) {
container.innerHTML = `
<div style="font-size: 11px; color: var(--text-muted); padding: 15px; text-align: center; width:100%;">
<i class="fa-solid fa-circle-info"></i> <span>لا توجد منشورات مسجلة حديثاً في سجل التعبئة السريعة.</span>
</div>
`;
return;
}
recentList.forEach(item => {
const card = document.createElement('div');
card.style.cssText = 'background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px; display: flex; flex-direction: column; gap: 8px; text-align: right; direction: rtl; box-sizing: border-box; box-shadow: var(--shadow-xs);';
card.className = 'nip0io690t';
const excerpt = item.text ? (item.text.length > 50 ? item.text.substring(0, 50) + '...' : item.text) : '[صور/فيديو فقط بدون نص]';
const dateStr = new Date(item.timestamp).toLocaleTimeString('en-US', {hour: '2-digit', minute: '2-digit'}) + ' - ' + new Date(item.timestamp).toLocaleDateString();
card.innerHTML = `
<div style="font-size: 11px; font-weight: 700; display: flex; justify-content: space-between; align-items: center; direction: rtl;">
<span style="color: var(--text-main);"><i class="fa-solid fa-file-invoice" style="margin-left: 4px; color: var(--primary);"></i> <span>منشور محفوظ</span></span>
<span style="font-size: 9.5px; color: var(--text-muted); font-family: var(--font-code);"><i class="fa-regular fa-clock"></i> <span>${dateStr}</span></span>
</div>
<div style="font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-secondary); line-height: 1.4;">${excerpt}</div>
<div style="display: flex; justify-content: space-between; font-size: 10px; border-top: 1px dashed var(--border); padding-top: 6px; margin-top: 2px; color: var(--text-muted); font-weight: 600;">
<span><i class="fa-solid fa-users"></i> الجروبات: <b style="color:var(--text-main); font-family: var(--font-code);">${item.groupIds.length}</b></span>
<span><i class="fa-solid fa-images"></i> الصور: <b style="color:var(--text-main); font-family: var(--font-code);">${item.images ? item.images.length : 0}</b></span>
</div>
<div style="display: flex; gap: 4px; margin-top: 4px; border-top: 1px dashed var(--border); padding-top: 6px; flex-wrap: wrap;">
<button class="ipxi2jz4g0 zutkbm6ve4" style="padding: 4px 6px; font-size: 9.5px; flex: 1; min-height: 28px;" title="تحميل الجروبات المستهدفة فقط">
<i class="fa-solid fa-users"></i> <span>الجروبات</span>
</button>
<button class="ipxi2jz4g0 fat9x5gp73" style="padding: 4px 6px; font-size: 9.5px; flex: 1; min-height: 28px;" title="تحميل محتوى النص فقط">
<i class="fa-solid fa-pen-nib"></i> <span>النص</span>
</button>
<button class="itdnt14mss jh09fzoq3e" style="padding: 4px 8px; font-size: 9.5px; flex: 1.4; min-height: 28px;" title="تحميل النص والجروبات والمرفقات بالكامل">
<i class="fa-solid fa-file-import"></i> <span>تحميل الكل</span>
</button>
<button class="btn-danger uf24p49jg0" style="padding: 4px 6px; font-size: 9.5px; min-height: 28px;" title="حذف من السجل">
<i class="fa-solid fa-trash"></i>
</button>
</div>
`;
const groupsBtn = card.querySelector('.zutkbm6ve4');
const contentBtn = card.querySelector('.fat9x5gp73');
const allBtn = card.querySelector('.jh09fzoq3e');
const deleteBtn = card.querySelector('.uf24p49jg0');
if (groupsBtn) {
groupsBtn.addEventListener('click', (e) => {
e.stopPropagation();
loadRecentGroupsOnly(item.id);
});
}
if (contentBtn) {
contentBtn.addEventListener('click', (e) => {
e.stopPropagation();
loadRecentContentOnly(item.id);
});
}
if (allBtn) {
allBtn.addEventListener('click', (e) => {
e.stopPropagation();
loadRecentPublishedPost(item.id);
});
}
if (deleteBtn) {
deleteBtn.addEventListener('click', (e) => {
e.stopPropagation();
deleteRecentPublishedPost(item.id);
});
}
container.appendChild(card);
});
};
/**
* تعبئة المنشور بالكامل مع المجموعات المحددة في المحرر
*/
const loadRecentPublishedPost = async (recentId) => {
const recentList = await global.FritreeStorage.get('fbRecentPublishedPosts', []);
const item = recentList.find(c => c.id === recentId);
if (!item) return;
if (confirm("هل تريد تحميل نص الرسالة والمجموعات المحددة والمرفقات إلى المحرر؟")) {
setComposerText(item.text || '');
if (global.FritreeFacebook && typeof global.FritreeFacebook.setSelectedIds === 'function') {
global.FritreeFacebook.setSelectedIds(item.groupIds || []);
}
uploadedImages = [];
if (item.images && Array.isArray(item.images)) {
for (const img of item.images) {
const blob = await global.FritreeStorage.get(`media_blob_recent_${recentId}_${img.id}`);
if (blob) {
await global.FritreeStorage.set(`media_blob_${img.id}`, blob);
const previewUrl = URL.createObjectURL(blob);
uploadedImages.push({
id: img.id,
type: img.type,
blob: blob,
filename: img.name,
localPreviewUrl: previewUrl
});
}
}
}
renderComposerMediaPreviews();
if (typeof window.addLog === 'function') {
window.addLog(`تم تحميل المنشور والجروبات المحددة [${item.groupIds.length}] بنجاح في المحرر للإرسال.`, 'success');
}
window.scrollTo({ top: 0, behavior: 'smooth' });
}
};
const loadRecentGroupsOnly = async (recentId) => {
const recentList = await global.FritreeStorage.get('fbRecentPublishedPosts', []);
const item = recentList.find(c => c.id === recentId);
if (!item) return;
if (global.FritreeFacebook && typeof global.FritreeFacebook.setSelectedIds === 'function') {
global.FritreeFacebook.setSelectedIds(item.groupIds || []);
if (typeof window.addLog === 'function') {
window.addLog(`تم تحميل [${item.groupIds.length}] جروب من السجل بنجاح.`, "success");
}
}
};
const loadRecentContentOnly = async (recentId) => {
const recentList = await global.FritreeStorage.get('fbRecentPublishedPosts', []);
const item = recentList.find(c => c.id === recentId);
if (!item) return;
setComposerText(item.text || '');
uploadedImages = [];
if (item.images && Array.isArray(item.images)) {
for (const img of item.images) {
const blob = await global.FritreeStorage.get(`media_blob_recent_${recentId}_${img.id}`);
if (blob) {
await global.FritreeStorage.set(`media_blob_${img.id}`, blob);
const previewUrl = URL.createObjectURL(blob);
uploadedImages.push({
id: img.id,
type: img.type,
blob: blob,
filename: img.name,
localPreviewUrl: previewUrl
});
}
}
}
renderComposerMediaPreviews();
if (typeof window.addLog === 'function') {
window.addLog("تم تحميل محتوى نص المنشور والصور المرفقة في المحرر بنجاح.", "success");
}
};
const deleteRecentPublishedPost = async (recentId) => {
if (confirm("هل أنت متأكد من حذف هذا المنشور نهائياً من سجل التعبئة السريعة؟")) {
let recentList = await global.FritreeStorage.get('fbRecentPublishedPosts', []);
const item = recentList.find(c => c.id === recentId);
if (item && item.images) {
for (const img of item.images) {
await global.FritreeStorage.remove(`media_blob_recent_${recentId}_${img.id}`);
}
}
recentList = recentList.filter(c => c.id !== recentId);
await global.FritreeStorage.set('fbRecentPublishedPosts', recentList);
renderRecentPublishedList();
if (typeof window.addLog === 'function') {
window.addLog("تم حذف المنشور وإزالته من سجل التعبئة السريعة بنجاح.", "warn");
}
}
};
/**
* معالجة ورفع وضغط ملفات الصور
*/
const processIncomingMediaFiles = async (files) => {
if (typeof window.addLog === 'function') {
window.addLog("جاري معالجة وتأمين المرفقات لحمايتها أثناء الرفع السريع...", "info");
}
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (file.size > 25 * 1024 * 1024) {
alert(`حجم الملف ${file.name} كبير جداً، الحد الأقصى للمرفق هو 25 ميجابايت.`);
continue;
}
if (!file.type.startsWith('image/')) continue;
const binaryHash = 'composer_' + Date.now() + "_" + Math.random().toString(36).substr(2, 4);
let compressedBlob = file;
if (global.FritreeImageCompressor) {
compressedBlob = await global.FritreeImageCompressor.compressImage(file);
}
const config = await global.FritreeStorage.get('local_shield_config_matrix', { exifCleansingActive: true });
if (config.exifCleansingActive && global.FritreeStealthLinguisticEngine && typeof global.FritreeStealthLinguisticEngine.cleanImageExif === 'function') {
compressedBlob = await global.FritreeStealthLinguisticEngine.cleanImageExif(compressedBlob);
}
const thumbUrl = URL.createObjectURL(compressedBlob);
if (global.FritreeStorage) {
await global.FritreeStorage.set(`media_blob_${binaryHash}`, compressedBlob);
}
uploadedImages.push({
id: binaryHash,
type: "image/jpeg",
blob: compressedBlob,
filename: file.name,
localPreviewUrl: thumbUrl
});
}
renderComposerMediaPreviews();
};
const renderComposerMediaPreviews = () => {
const container = document.getElementById('b2162at4z7');
if (!container) return;
container.innerHTML = '';
uploadedImages.forEach((img, idx) => {
const box = document.createElement('div');
box.className = 'evr435qzb2';
const el = document.createElement('img');
el.src = img.localPreviewUrl;
el.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius-sm);';
const closeBtn = document.createElement('button');
closeBtn.setAttribute('type', 'button');
closeBtn.innerHTML = '<i class="fa-solid fa-trash-can"></i> ';
closeBtn.addEventListener('click', async () => {
URL.revokeObjectURL(img.localPreviewUrl);
if (global.FritreeStorage) {
await global.FritreeStorage.remove(`media_blob_${img.id}`);
}
uploadedImages.splice(idx, 1);
renderComposerMediaPreviews();
});
box.appendChild(el);
box.appendChild(closeBtn);
container.appendChild(box);
});
};
/**
* ربط أحداث المحرر والمتغيرات
*/
const bindComposerEventListeners = () => {
const dropzone = document.getElementById('mm0yx6izkd');
const fileInput = document.getElementById('ftglpwfdd9');
const postTextarea = document.getElementById('nmr6mtwgan');
if (dropzone && fileInput) {
dropzone.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
processIncomingMediaFiles(e.target.files);
}
});
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.style.borderColor = 'var(--primary)';
dropzone.style.background = 'var(--primary-light)';
});
dropzone.addEventListener('dragleave', () => {
dropzone.style.borderColor = 'var(--border-strong)';
dropzone.style.background = 'var(--bg-subtle)';
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.style.borderColor = 'var(--border-strong)';
dropzone.style.background = 'var(--bg-subtle)';
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
processIncomingMediaFiles(e.dataTransfer.files);
}
});
}
if (postTextarea) {
postTextarea.addEventListener('input', () => {
if (global.FritreeRules && typeof global.FritreeRules.updateStats === 'function') {
global.FritreeRules.updateStats();
}
});
}
const scheduleCheck = document.getElementById('k58hokq80h');
const scheduleWrapper = document.getElementById('sed4iycyc5');
const launchBtn = document.getElementById('q0ilg5gt03');
if (scheduleCheck && scheduleWrapper && launchBtn) {
scheduleCheck.addEventListener('change', (e) => {
const checked = e.target.checked;
scheduleWrapper.style.display = checked ? 'block' : 'none';
if (checked) {
launchBtn.innerHTML = '<i class="fa-solid fa-calendar-plus"></i> <span>جدولة تشغيل الحملة</span>';
} else {
launchBtn.innerHTML = '<i class="fa-solid fa-paper-plane"></i> <span>بدء إطلاق الحملة</span>';
}
});
}
const exitRotationBtn = document.getElementById('hf3fgtgsrm');
if (exitRotationBtn) {
exitRotationBtn.addEventListener('click', (e) => {
e.preventDefault();
if (global.FritreeRotation && typeof global.FritreeRotation.disableRotation === 'function') {
global.FritreeRotation.disableRotation();
}
});
}
const pacingBtn = document.getElementById('d376lqov4g');
if (pacingBtn) {
pacingBtn.addEventListener('click', (e) => {
e.preventDefault();
if (global.FritreePacingUI && typeof global.FritreePacingUI.openModal === 'function') {
global.FritreePacingUI.openModal('fb');
}
});
}
const btnStealth = document.getElementById('p4x864vzc8');
const previewBlock = document.getElementById('dg3a5v2fam');
const previewBox = document.getElementById('xtl6n8x46j');
if (btnStealth && previewBlock && previewBox) {
btnStealth.addEventListener('click', async () => {
const textVal = document.getElementById('nmr6mtwgan').value;
if (!textVal) {
alert("يرجى كتابة نص المنشور أولاً لمعاينة التمويه!");
return;
}
if (previewBlock.style.display === 'none') {
if (global.FritreeTextCompiler && typeof global.FritreeTextCompiler.compileAndObfuscate === 'function') {
const obfuscated = await global.FritreeTextCompiler.compileAndObfuscate(textVal, "مجموعة_المثال");
previewBox.textContent = obfuscated;
previewBlock.style.display = 'block';
}
} else {
previewBlock.style.display = 'none';
}
});
}
document.querySelectorAll('.btn-var-insert').forEach(btn => {
btn.addEventListener('click', (e) => {
const varTag = e.currentTarget.getAttribute('data-var');
if (postTextarea) {
const start = postTextarea.selectionStart;
const end = postTextarea.selectionEnd;
const text = postTextarea.value;
postTextarea.value = text.substring(0, start) + varTag + text.substring(end);
postTextarea.focus();
postTextarea.selectionStart = postTextarea.selectionEnd = start + varTag.length;
postTextarea.dispatchEvent(new Event('input', { bubbles: true }));
}
});
});
};
/**
* استخراج إعدادات التبريد والانتظار لفيسبوك من التخزين والمدخلات
*/
const getFacebookDelayConfig = () => {
const getVal = id => document.getElementById(id)?.value;
const mode = getVal('l37axh2l1n') || 'continuous';
const minSec = parseInt(getVal('fcdd19jd0b'), 10) || 45;
const maxSec = parseInt(getVal('nypjlieshn'), 10) || 120;
const fixedSec = parseInt(getVal('nmngttm14l'), 10) || 60;
const burstCount = parseInt(getVal('er9a6wk592'), 10) || 5;
const burstPause = parseInt(getVal('f85bxwyms9'), 10) || 300;
const longBreakCount = parseInt(getVal('oifuahm7ox'), 10) || 15;
const longBreakPause = parseInt(getVal('l1mxkqhsts'), 10) || 900;
return {
mode,
minSeconds: minSec,
maxSeconds: maxSec,
fixedSeconds: fixedSec,
burstCount,
burstPause,
longBreakCount,
longBreakPause
};
};
/**
* تهيئة المحرر
*/
const initComposer = () => {
const sidebar = document.getElementById('bmh59axx92');
const mainContentArea = document.getElementById('s7ihkirolg');
if (!sidebar || !mainContentArea) return false;
buildComposerLayout();
bindComposerEventListeners();
renderComposerMediaPreviews();
return true;
};
/**
* تصدير وحدة محرر فيسبوك
*/
global.FritreeFacebookComposer = {
init: initComposer,
getUploadedImages: () => {
return Promise.resolve(uploadedImages.map(img => ({
id: img.id,
name: img.filename,
type: img.type
})));
},
clearComposerImages: async () => {
for (const img of uploadedImages) {
URL.revokeObjectURL(img.localPreviewUrl);
if (global.FritreeStorage) {
await global.FritreeStorage.remove(`media_blob_${img.id}`);
}
}
uploadedImages = [];
renderComposerMediaPreviews();
},
getComposerText: () => {
const el = document.getElementById('nmr6mtwgan');
return el ? el.value : '';
},
setComposerText,
savePublishedPostToRecent,
getDelayConfig: getFacebookDelayConfig
};
if (typeof document !== 'undefined') {
if (!initComposer()) {
document.addEventListener('DOMContentLoaded', initComposer);
window.addEventListener('load', initComposer);
}
}
})(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);