🧠 أولاً: وظيفة هذا الملف (خارج الكود)
هذا الملف مسؤول عن:
التواصل المباشر مع Supabase (قاعدة البيانات)Dart🎯 يعني باختصار:
👉 هو “الساعي” اللي يروح يجيب البيانات من السيرفر ويرجعها
❗ مهم جداً:
هذا الملف:
- ❌ لا يعرف Cubit
- ❌ لا يعرف UI
- ❌ لا يعرف UseCase
👉 يعرف فقط:
Supabase APIDart📄 الكود
import 'package:supabase_flutter/supabase_flutter.dart';
import '../models/note_model.dart';
class NotesRemoteDataSource {
final SupabaseClient client;
NotesRemoteDataSource(this.client);
Future<List<NoteModel>> getNotes() async {
final response = await client.from('notes').select();
print("🔥 RESPONSE: $response");
return response.map<NoteModel>((e) {
return NoteModel.fromJson(e);
}).toList();
}
}Dart🔍 الآن نشرح كل سطر بالتفصيل
🧱 1. import Supabase
import 'package:supabase_flutter/supabase_flutter.dart';Dart🧠 شو يعني؟
👉 جلب مكتبة Supabase
🎯 لماذا؟
حتى نستخدم:
SupabaseClientDart🧱 2. import model
import '../models/note_model.dart';Dart🧠 لماذا؟
لأننا سنحوّل:
JSON → NoteModelDart🧱 3. تعريف الكلاس
class NotesRemoteDataSource {Dart🧠 لماذا اسمه Remote؟
Remote = من الإنترنت (Supabase)Dart💡 ممكن لاحقاً يكون عندك:
LocalDataSource (SQLite)Dart🧱 4. المتغير client
final SupabaseClient client;Dart🧠 شو هذا؟
👉 object يمثل الاتصال مع Supabase
🎯 كيف يأتي؟
من:
SupabaseConfig.clientDart💡 ليش final؟
👉 لأنه لا يتغير
🧱 5. constructor
NotesRemoteDataSource(this.client);Dart🧠 هذا Dependency Injection
👉 نحن نمرر client من الخارج
🎯 لماذا مهم؟
- اختبار أسهل
- فصل الطبقات
- مرونةDart🧱 6. الدالة الأساسية 🔥
Future<List<NoteModel>> getNotes() asyncDart🧠 نشرحها كلمة كلمة:
🔹 Future
عملية غير متزامنة (async)Dart🔹 <List<NoteModel>
ترجع قائمة من الملاحظاتDart🔹 async
👉 نستخدم await داخلها
🧱 7. استدعاء Supabase
final response = await client.from('notes').select();Dart🧠 أهم سطر في الملف
🔍 تفكيك السطر:
🔹 client
👉 الاتصال مع Supabase
🔹 from(‘notes’)
👉 اختر جدول:
notesDart🔹 select()
👉 يعني:
SELECT * FROM notesDart🎯 النتيجة:
List<Map<String, dynamic>>Dart💡 مثال حقيقي:
[
{id: 1, title: "hello", content: "test"},
{id: 2, title: "hi", content: "world"}
]Dart🧱 8. print للتشخيص
print("🔥 RESPONSE: $response");Dart🧠 لماذا؟
👉 Debug فقط
🎯 فائدته:
- تعرف هل البيانات وصلت
- تشوف شكلها
🧱 9. التحويل 🔥🔥🔥
return response.map<NoteModel>((e) {
return NoteModel.fromJson(e);
}).toList();Dart🧠 هذا أهم جزء في الملف
🔍 خطوة خطوة:
🔹 response.map
👉 نمر على كل عنصر
🔹 e
e = {id: 1, title: ..., content: ...}Dart👉 عنصر واحد من JSON
🔹 NoteModel.fromJson(e)
👉 نحوّل:
Map → ObjectDart🔹 toList()
👉 نحول النتيجة إلى List
🔥 النتيجة النهائية:
List<NoteModel>Dart🧠 الدورة الكاملة
📥 من Supabase
Supabase → JSON → MapDart🔄 داخل DataSource
Map → NoteModelDart📤 إلى Repository
List<NoteModel>Dart🔗 كيف يرتبط بباقي المشروع؟
🟡 RepositoryImpl
remote.getNotes()Dart🟢 UseCase
repo.getNotes()Dart🔵 Cubit
fetchNotes()Dart🟣 UI
BlocBuilder(...)Dart💥 خلاصة قوية جداً
DataSource = المكان الوحيد الذي يتعامل مع SupabaseDart🧠 جملة تحفظها
DataSource brings raw data
Model converts it
Repository connects itDart