Skip to content
This repository was archived by the owner on Jul 17, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/controllers/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart' show Uint8List, kIsWeb;
import 'package:image_picker/image_picker.dart';
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:openwardrobe/repositories/app_repository.dart';

class CameraController {
final AppRepository _appRepository = GetIt.instance<AppRepository>();
final AppRepository _appRepository;

CameraController(this._appRepository);

Future<List<File>> pickImages({bool fromGallery = false}) async {
if (kIsWeb) {
Expand Down
14 changes: 5 additions & 9 deletions lib/controllers/home_controller.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:openwardrobe/repositories/app_repository.dart';
import 'package:openwardrobe/brick/models/user_profile.model.dart';
import 'package:supabase_flutter/supabase_flutter.dart';


class HomeController {
final AppRepository _appRepository = GetIt.instance<AppRepository>();

final AppRepository _appRepository;

HomeController(this._appRepository);

Stream<List<UserProfile>> fetchUserProfile() {
final usersStream = _appRepository.subscribe<UserProfile>();

return usersStream;

final usersStream = _appRepository.subscribe<UserProfile>();
return usersStream;
}

}
6 changes: 4 additions & 2 deletions lib/controllers/lookbook_controller.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:openwardrobe/repositories/app_repository.dart';
import 'package:openwardrobe/brick/models/lookbook.model.dart';

class LookbookController {
final AppRepository _appRepository = GetIt.instance<AppRepository>();
final AppRepository _appRepository;

LookbookController(this._appRepository);

Future<List<Lookbook>> fetchLookbookItems() async {
try {
Expand Down
6 changes: 4 additions & 2 deletions lib/controllers/settings_account_controller.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import 'dart:io';
import 'package:flutter/foundation.dart' show Uint8List, kIsWeb;
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:openwardrobe/brick/models/user_profile.model.dart';
import 'package:openwardrobe/repositories/app_repository.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class SettingsAccountController {
final AppRepository _appRepository = GetIt.instance<AppRepository>();
final AppRepository _appRepository;

SettingsAccountController(this._appRepository);

Future<UserProfile> fetchUserProfile() async {
try {
Expand Down
6 changes: 4 additions & 2 deletions lib/controllers/settings_controller.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:openwardrobe/repositories/app_repository.dart';

class SettingsController {
final AppRepository _appRepository = GetIt.instance<AppRepository>();
final AppRepository _appRepository;

SettingsController(this._appRepository);

Future<Map<String, dynamic>> fetchSettings() async {
try {
Expand Down
7 changes: 4 additions & 3 deletions lib/controllers/wardrobe_controller.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'package:brick_core/core.dart';
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:openwardrobe/brick/models/outfit.model.dart';
import 'package:openwardrobe/repositories/app_repository.dart';
import 'package:openwardrobe/brick/models/wardrobe_item.model.dart';

class WardrobeController {
final AppRepository _appRepository = GetIt.instance<AppRepository>();
final AppRepository _appRepository;

WardrobeController(this._appRepository);

Future<List<WardrobeItem>> fetchWardrobeItems() async {
try {
Expand All @@ -19,7 +21,6 @@ class WardrobeController {
Future<List<Outfit>> fetchOutfits() async {
try {
return await _appRepository.get<Outfit>();

} catch (e) {
// Handle error
throw Exception('Failed to fetch outfits: $e');
Expand Down
22 changes: 0 additions & 22 deletions lib/di/service_locator.dart

This file was deleted.

47 changes: 22 additions & 25 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,21 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:openwardrobe/repositories/app_repository.dart';
import 'router/app_router.dart';

import 'package:openwardrobe/di/service_locator.dart';

// sqflite_common_ffi_web
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:sqflite/sqflite.dart' show databaseFactory;


Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();

if (kIsWeb) {
databaseFactory = databaseFactoryFfiWeb;
}

await AppRepository.configure(databaseFactory);



if (kIsWeb) {
databaseFactory = databaseFactoryFfiWeb;
}

await AppRepository().initialize();
await AppRepository.configure(databaseFactory);

setupLocator();
await AppRepository().initialize();

runApp(const MyApp());
}
Expand All @@ -36,16 +26,23 @@ class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'OpenWardrobe',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color.fromARGB(255, 33, 243, 163)),
useMaterial3: true, // Enable Material 3 (modern UI)
return MultiBlocProvider(
providers: [
BlocProvider<AppRepository>(
create: (context) => AppRepository(),
),
// Add other BlocProviders here as needed
],
child: MaterialApp.router(
title: 'OpenWardrobe',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color.fromARGB(255, 33, 243, 163)),
useMaterial3: true, // Enable Material 3 (modern UI)
),
darkTheme: ThemeData.dark(), // Support dark mode
themeMode: ThemeMode.system, // Automatically switch theme
routerConfig: AppRouter.router,
),
darkTheme: ThemeData.dark(), // Support dark mode
themeMode: ThemeMode.system, // Automatically switch theme

routerConfig: AppRouter.router,
);
}
}
13 changes: 10 additions & 3 deletions lib/repositories/app_repository.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Saved in my_app/lib/src/brick/repository.dart
import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart';
import 'package:brick_sqlite/brick_sqlite.dart';
import 'package:brick_sqlite/memory_cache_provider.dart';
// This hide is for Brick's @Supabase annotation; in most cases,
// supabase_flutter **will not** be imported in application code.
import 'package:brick_supabase/brick_supabase.dart' hide Supabase;
import 'package:openwardrobe/brick/db/schema.g.dart';
import 'package:sqflite_common/sqlite_api.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;

import 'package:openwardrobe/brick/brick.g.dart';

Expand Down Expand Up @@ -40,6 +40,13 @@ class AppRepository extends OfflineFirstWithSupabaseRepository {
modelDictionary: supabaseModelDictionary,
);

final storageDirectory = await getApplicationDocumentsDirectory();
final storagePath = p.join(storageDirectory.path, 'hydrated_bloc');

HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: Directory(storagePath),
);

_instance = AppRepository._(
supabaseProvider: provider,
sqliteProvider: SqliteProvider(
Expand Down
16 changes: 13 additions & 3 deletions lib/router/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:openwardrobe/ui/screens/camera/page.dart';
import 'package:openwardrobe/ui/screens/lookbook/page.dart';
import 'package:openwardrobe/ui/screens/wardrobe/settings/page.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../ui/screens/auth/page.dart';
import '../ui/screens/home/page.dart';
Expand Down Expand Up @@ -59,7 +60,10 @@ class AppRouter {
GoRoute(
path: '/',
name: 'Home',
builder: (context, state) => HomeScreen(),
builder: (context, state) => BlocProvider(
create: (context) => HomeController(context.read<AppRepository>()),
child: HomeScreen(),
),
),
],
),
Expand All @@ -69,7 +73,10 @@ class AppRouter {
GoRoute(
path: '/wardrobe',
name: 'Wardrobe',
builder: (context, state) => WardrobeScreen(),
builder: (context, state) => BlocProvider(
create: (context) => WardrobeController(context.read<AppRepository>()),
child: WardrobeScreen(),
),
),
],
),
Expand All @@ -79,7 +86,10 @@ class AppRouter {
GoRoute(
path: '/lookbook',
name: 'Lookbook',
builder: (context, state) => LookbookScreen(),
builder: (context, state) => BlocProvider(
create: (context) => LookbookController(context.read<AppRepository>()),
child: LookbookScreen(),
),
),
],
),
Expand Down
27 changes: 9 additions & 18 deletions lib/ui/screens/home/page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:openwardrobe/brick/models/user_profile.model.dart';
import 'package:openwardrobe/controllers/home_controller.dart';
Expand All @@ -9,8 +9,6 @@ import 'package:openwardrobe/ui/widgets/user_profile/user_profile_component.dart
class HomeScreen extends StatelessWidget {
HomeScreen({super.key});

final HomeController homeController = GetIt.instance<HomeController>();

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -26,22 +24,15 @@ class HomeScreen extends StatelessWidget {
const SizedBox(height: 20),
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: StreamBuilder<List<UserProfile>>(
stream: homeController.fetchUserProfile(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
child: BlocBuilder<HomeController, List<UserProfile>>(
builder: (context, userProfile) {
if (userProfile.isEmpty) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Center(child: Text('No profile found'));
}

final userProfile = snapshot.data!.first; // Assuming there is always one user profile

return UserProfileComponent(item: userProfile);
},
),
} else {
return UserProfileComponent(item: userProfile.first);
}
},
),
),
const SizedBox(height: 20),
ConstrainedBox(
Expand Down
20 changes: 5 additions & 15 deletions lib/ui/screens/lookbook/page.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:openwardrobe/brick/models/lookbook.model.dart';
import 'package:get_it/get_it.dart';
import 'package:openwardrobe/ui/widgets/lookbook/lookbook_component.dart';
import 'package:openwardrobe/controllers/lookbook_controller.dart';

class LookbookScreen extends StatelessWidget {
LookbookScreen({super.key});

final LookbookController lookbookController = GetIt.instance<LookbookController>();

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -25,25 +23,17 @@ class LookbookScreen extends StatelessWidget {
Expanded(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: FutureBuilder<List<Lookbook>>(
future: lookbookController.fetchLookbookItems(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
child: BlocBuilder<LookbookController, List<Lookbook>>(
builder: (context, lookbookItems) {
if (lookbookItems.isEmpty) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(
child: Text('Error: ${snapshot.error}'),
);
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Center(child: Text('No items found'));
} else {
final items = snapshot.data!;
return SingleChildScrollView(
child: Wrap(
spacing: 8.0,
runSpacing: 8.0,
alignment: WrapAlignment.start,
children: items.map((item) =>
children: lookbookItems.map((item) =>
Container(
width: 150,
child: LookbookComponent(item: item),
Expand Down
Loading
Loading