main_dart

📁 lib/main.dart
🧠 شرح الملف

هذا الملف هو:

نقطة بداية التطبيق + ربط كل الطبقات مع بعض (Dependency Injection)
Dart
📄 الكود الكامل:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'core/supabase/supabase_client.dart';
import 'features/notes/data/datasource/notes_remote_datasource.dart';
import 'features/notes/data/repository/notes_repository_impl.dart';
import 'features/notes/domain/usecases/get_notes_usecase.dart';
import 'features/notes/presentation/cubit/notes_cubit.dart';
import 'features/notes/presentation/pages/notes_page.dart';

void main() async {
  /// لازم قبل أي async
  WidgetsFlutterBinding.ensureInitialized();  /// تهيئة Supabase
  await Supabase.initialize(
    url: 'YOUR_URL',
    anonKey: 'YOUR_ANON_KEY',
  );
  
    /// الحصول على client
final client = SupabaseConfig.client; 

   /// 🔗 ربط الطبقات (Dependency Injection)  /// DataSource
final dataSource = NotesRemoteDataSource(client); 
  
   /// Repository
final repo = NotesRepositoryImpl(dataSource);
  
  /// UseCase
final getNotes = GetNotesUseCase(repo); 
   /// تشغيل التطبيق
  runApp(MyApp(getNotes));
}
class MyApp extends StatelessWidget {
  final GetNotesUseCase getNotes; 
   const MyApp(this.getNotes, {super.key}); 
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
    
        /// إنشاء Cubit
      create: (_) => NotesCubit(getNotes)..fetchNotes(), 
      child: MaterialApp(
      debugShowCheckedModeBanner: false,
      home: NotesPage(),
      ),
    );
  }
}
Dart

🧠 أهم نقطة هنا

NotesCubit(getNotes)..fetchNotes()
Dart

👉 هذا يعني:

أنشئ Cubit → مباشرة نفّذ fetchNotes
Dart
الملف: main.dart
🧠 أولاً: ما وظيفة هذا الملف؟
تشغيل التطبيق + تهيئة الخدمات + ربط الطبقات (Dependency Injection)
Dart
📄 الكود
void main() async {
  WidgetsFlutterBinding.ensureInitialized(); 
   await Supabase.initialize(
    url: 'YOUR_URL',
    anonKey: 'YOUR_ANON_KEY',
  ); 
  
  final client = SupabaseConfig.client;
  final dataSource = NotesRemoteDataSource(client);
  final repo = NotesRepositoryImpl(dataSource);
  final getNotes = GetNotesUseCase(repo); 
   runApp(MyApp(getNotes));
}
Dart
🔍 نشرح خطوة خطوة
🧱 1. main()
void main() async
Dart
🧠 هذا:

👉 نقطة بداية التطبيق

🔥 async

👉 لأننا سنستخدم:

await Supabase.initialize()
Dart
🧱 2. ensureInitialized
WidgetsFlutterBinding.ensureInitialized();
Dart
🧠 معناها:
تأكد أن Flutter جاهز قبل أي async أو plugin
Dart
🎯 لماذا مهم هنا؟

لأن:

Supabase.initialize()
Dart

يحتاج Flutter يكون جاهز

🧱 3. تهيئة Supabase
await Supabase.initialize(
  url: 'YOUR_URL',
  anonKey: 'YOUR_ANON_KEY',
);
Dart
🧠 ماذا يحدث؟

👉 يتم ربط التطبيق مع Supabase

🎯 URL

👉 رابط المشروع

🎯 anonKey

👉 مفتاح الوصول

🧱 4. الحصول على client
final client = SupabaseConfig.client;
Dart
🧠 هذا:

👉 object يمثل الاتصال مع Supabase

💡 لماذا عبر class؟
حتى نستخدمه بكل المشروع بدون تكرار
Dart
🧱 5. DataSource
final dataSource = NotesRemoteDataSource(client);
Dart
🧠 ماذا فعلنا؟

👉 أنشأنا الطبقة التي تتواصل مع Supabase

🔗 العلاقة:
DataSourceSupabase
Dart
🧱 6. Repository
final repo = NotesRepositoryImpl(dataSource);
Dart
🧠 ماذا فعلنا؟

👉 ربطنا Domain مع Data

🔗 العلاقة:
RepositoryDataSource
Dart
🧱 7. UseCase
final getNotes = GetNotesUseCase(repo);
Dart
🧠 ماذا فعلنا؟

👉 أنشأنا عملية:

جلب الملاحظات
Dart
🔗 العلاقة:
UseCaseRepository
Dart
🧱 8. runApp
runApp(MyApp(getNotes));
Dart
🧠 ماذا يحدث؟

👉 تشغيل التطبيق

💡 تمرير getNotes

👉 حتى يصل إلى Cubit

🧱 الآن ننتقل إلى MyApp
📄 الكود
class MyApp extends StatelessWidget {
  final GetNotesUseCase getNotes; 
 const MyApp(this.getNotes, {super.key});
Dart
🧠 هذا:

👉 StatelessWidget

🎯 لماذا؟

لأن:

لا يوجد state داخلي هنا
Dart
💡 getNotes

👉 dependency تم تمريرها من main

🧱 build()
@override<br>Widget build(BuildContext context) {
Dart
🧠 هذه:

👉 تبني واجهة التطبيق

🧱 BlocProvider
return BlocProvider(
Dart
🧠 أهم Widget هنا

👉 مسؤول عن:

توفير Cubit لكل الشجرة
Dart
🧱 create
create: (_) => NotesCubit(getNotes)..fetchNotes(),
Dart
🔍 نفكها:
🔹 NotesCubit(getNotes)

👉 إنشاء Cubit

🔹 ..fetchNotes()
cascade operator
Dart
🧠 معناها:
NotesCubit(getNotes);
cubit.fetchNotes();
Dart
🎯 لماذا؟

👉 أول ما يشتغل التطبيق:

يجلب البيانات مباشرة
Dart
🧱 MaterialApp
child: MaterialApp(
Dart
🧠 هذا:

👉 أساس التطبيق

🎯 يحتوي:
  • routing
  • theme
  • home
🧱 debug banner
debugShowCheckedModeBanner: false,
Dart
🧠 إزالة:
شريط DEBUG
Dart
🧱 الصفحة الرئيسية
home: NotesPage(),
Dart

🧠 هذه:

👉 أول شاشة تظهر

🔁 التسلسل الكامل
main()

تهيئة Supabase

إنشاء DataSource

إنشاء Repository

إنشاء UseCase

runApp

BlocProvider

Cubit

fetchNotes()

UseCase

Repository

DataSource

Supabase

رجوع البيانات

UI
💥 لماذا هذا التصميم قوي؟
🎯 1. فصل الطبقات
كل طبقة لها وظيفة
Dart
🎯 2. مرونة
تبدل Supabase بدون كسر التطبيق
Dart
🎯 3. قابل للاختبار
تقدر تعمل Mock بسهولة
Dart
❗ المشكلة الحالية
🧠 main.dart فيه:
كثير dependencies
Dart
❌ مع 50 feature:
سيصبح فوضى
Dart
🚀 الخطوة القادمة (التطوير)
🎯 الحل:
نستخدم get_it (Dependency Injection Container)
Dart
🔥 ماذا سنفعل؟
  1. نقل كل هذا إلى injection.dart
  2. جعل main نظيف جداً
  3. استخدام sl() بدل التمرير اليدوي
💥 الخلاصة
🧠 هذا الملف حالياً:
Bootstrap + Wiring
Dart
🧠 الجملة الذهبية:
main.dart should connect, not contain logic
Dart