استلهمت هذا التطبيق من منشور على فيسبوك للدكتورة وفاء عرابي شرحت فيه آلية حفظ تعتمد على التعزيز المستمر للذاكرة بدلاً من التكرار التقليدي، وكيف يمكن لطريقة الحفظ هذه أن تساهم في حفظ المعلومة لفترات طويلة.
أرفقت الدكتورة في قناتها على تلغرام شرحاً مفصلاً لجدولٍ لحفظ القرآن الكريم بناءً على آلية الحفظ هذه، وخطر ببالي بدلاً من اعتماد جدولٍ قد يضيع الحافظ أثناء استخدامه وينسى ما عليه أن يقوم به، لماذا لا أحوّله لتطبيق صغير يمكن الاستعانة به لمراقبة المهام وما يجب حفظه؟ ومن هنا جاءت فكرة هذا البرنامج.
ميزة البرنامج الرئيسية أنّه يعمل بشكل بسيط على الهاتف المحمول سواء من خلال تثبيته كـ PWA أو من خلال استخدامه من الموقع مباشرة، وهو مناسب للأجهزة الضعيفة ولاتصال الإنترنت المحدود أيضاً، ويحفظ البيانات على الجهاز مباشرة مع إمكانية التصدير والاستيراد.

تجربة البرنامج: من هنا
الكود المصدري" من غيتهب
دعم PWA (Progressive Web App)
التطبيق يعمل كتطبيق ويب تقدمي، مما يعني أنه يمكن تثبيته على الأجهزة المحمولة والوصول إليه من اختصار في شاشة الهاتف ودون اتصال إنترنت، لكن في نفس الوقت، يزيل عنّي هذا همّ محاولة تطوير البرنامج للهاتف المحمول ومحاولة نشره في متاجر التطبيقات.
ملف Manifest
يتم تعريف التطبيق كـ PWA من خلال ملف manifest.json الذي يحتوي على:
- اسم التطبيق والأيقونات
- لون الخلفية والثيم
- وضع العرض (
standalone لعرضه كتطبيق مستقل)
{
"name": "Monthly Quran - Memorization Tracker",
"display": "standalone",
"start_url": "./",
"icons": [...]
}
Service Worker
Service Worker هو سكريبت يعمل في الخلفية بشكل منفصل عن صفحة الويب، ويعمل حتى عند إغلاق الصفحة. يتم تسجيل Service Worker في index.html عند تحميل الصفحة:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
}
لماذا نحتاج Service Worker؟
Service Worker ضروري لعدة أسباب:
التخزين المؤقت (Caching): يحفظ الملفات الأساسية (HTML، CSS، JavaScript) محلياً في المتصفح، مما يسمح بتحميل الموقع بسرعة في الزيارات التالية للزيارة الأولى.
العمل بدون إنترنت: بعد التحميل الأولي، يمكن للتطبيق العمل بالكامل بدون اتصال بالإنترنت لأن الملفات محفوظة محلياً.
متطلبات PWA: تضمين Service Worker هو أحد المتطلبات الأساسية لجعل التطبيق يعمل كـ PWA ويمكن تثبيته على الجهاز.
التخزين المحلي (LocalStorage)
جميع بيانات المستخدم تُحفظ محلياً في المتصفح باستخدام LocalStorage API. لا توجد قاعدة بيانات خارجية أو خادم. لكن في حال أراد أحدٌ مستقبلاً أن يضيف ميزة التخزين السحابيّ للتطبيق، فهيكل البيانات يمكن تحويله بسهولة ليتم تخزينه في قاعدة بيانات تقليدية، وربطها بنظام حسابات فرديّ.
هيكل التخزين
يتم تخزين البيانات في مفاتيح محددة:
quran_memorization_config: إعدادات المستخدم
quran_memorization_items: عناصر الحفظ والمراجعات
quran_surah_metadata: بيانات السور من API
مثال على الحفظ
Storage.saveConfig(config) {
localStorage.setItem(STORAGE_KEYS.CONFIG, JSON.stringify(configData));
}
تصدير واستيراد البيانات
يمكن للمستخدم تصدير بياناته كملف JSON واستيرادها لاحقاً، مما يسمح بنقل البيانات بين الأجهزة أو عمل نسخ احتياطية.
الاستضافة على GitHub Pages
التطبيق يستضاف مجاناً على GitHub Pages بدون الحاجة لخادم أو قاعدة بيانات.
الخطوات
- رفع الكود إلى مستودع GitHub
- تفعيل GitHub Pages من Settings > Pages
- اختيار الفرع والمجلد (root)
- التطبيق يصبح متاحاً على
https://username.github.io/repository-name
ملاحظات تقنية
جميع المسارات في التطبيق نسبية (مثل ./js/app.js) لتعمل بشكل صحيح على GitHub Pages.
استخدام API للحصول على بيانات السور
التطبيق يستخدم Al-Quran Cloud API للحصول على بيانات السور.
الحصول على بيانات السور
يتم حفظ بيانات السور محلياً بعد تحميلها من الAPI كي يتم إعادة استخدامها عند الحاجة.
async fetchSurahMetadata() {
// التحقق من التخزين المحلي أولاً
const cached = localStorage.getItem(this.STORAGE_KEY);
if (cached) return JSON.parse(cached);
// جلب من API إذا لم تكن موجودة محلياً
const response = await fetch(`${this.API_BASE_URL}/meta`);
const data = await response.json();
// حفظ في LocalStorage للاستخدام لاحقاً
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data));
return data;
}
الاستراتيجية
- التحقق من التخزين المحلي أولاً
- إذا لم تكن موجودة وكان المستخدم متصل بالإنترنت، يتم الجلب من API
- حفظ البيانات في LocalStorage للاستخدام لاحقاً
- إذا كان المستخدم غير متصل، استخدام البيانات المحفوظة
الحصول على نص السورة
async fetchSurahText(surahNumber, edition = 'quran-uthmani') {
const response = await fetch(`${this.API_BASE_URL}/surah/${surahNumber}/${edition}`);
return await response.json();
}
دعم العمل بدون إنترنت (Offline Support)
التطبيق يعمل بدون إنترنت بعد التحميل الأولي.
Service Worker للكاش
ملف sw.js يحتوي على منطق التخزين المؤقت:
const CACHE_NAME = 'monthly-quran-v1';
const urlsToCache = [
'./',
'./index.html',
'./css/themes.css',
'./js/app.js',
// ... الملفات الأخرى
];
نضيف كلّ الملفات التي نرغب بتخزينها محلياً إلى هذا المتغيّر.
آلية العمل
- عند التثبيت: يتم حفظ الملفات الأساسية في الكاش
- عند الطلب: يتم التحقق من الكاش أولاً، ثم الشبكة
- عند عدم الاتصال: يتم استخدام الملفات من الكاش
البيانات المحلية
بما أن جميع البيانات محفوظة في LocalStorage، يمكن للمستخدم:
- عرض مهام اليوم
- تحديث المراجعات
- عرض التقدم
- استخدام جميع الميزات الأساسية
قيود وضع عدم الاتصال
- لا يمكن جلب نصوص السور الجديدة من API
- يمكن استخدام البيانات المحفوظة مسبقاً فقط
أين يمكن أن يصل هذا البرنامج
كالمعتاد، أردت صراحة أن أنشئ هذا التطبيق لأتعلم أمراً جديداً وفي نفس الوقت لأثبت إمكانيّة تطبيق الفكرة، هذا التطبيق قد لا يكون مثالياً للاستخدام اليومي في حالته الآن، لكن يمكن التطوير عليه أو أخذ الخوارزمية منه واستخدامها في سياقات أخرى أو حتى الاستلهام منه لبناء أدوات أخرى.
ما أراه شخصياً: الأسلم في هذا النوع من التطبيقات أن يكون تطبيقاً تقليدياً مع إمكانيّة إرسال الإشعارات للمستخدم، وربما إمكانيّة المزامنة مع حساب على الشبكة، استضافة سيرفر لتخزين هذه البيانات ومزامنتها لن يكلف كثيراً برأيي، وهو أمر يمكن لأيّ أحدٍ إنجازه.
أعلم أيضاً أن تطبيقات PWA اليوم ليست شائعة بعد توقف دعمها على فايرفوكس وانخفاض التركيز عليها من غوغل كروم، لكن أردت شخصياً تجربة طريقة عملها وربما في المستقبل أستخدمها في مشاريع شخصية، وسبب فضولي حولها هو موضوع الأخ @عادل بن يحي الذي شرح فيه بشكل عام طريقة عمل هذه التقنيّة.