import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:media_kit/media_kit.dart'; import 'package:veloe_kemono_party_flutter/app_layout.dart'; import 'package:veloe_kemono_party_flutter/kemono_client.dart'; import 'package:veloe_kemono_party_flutter/models/creator.dart'; import 'package:veloe_kemono_party_flutter/models/nav_item.dart'; import 'package:veloe_kemono_party_flutter/models/post.dart'; import 'package:veloe_kemono_party_flutter/pages/cache_settings_screen.dart'; import 'package:veloe_kemono_party_flutter/pages/home_screen.dart'; import 'package:veloe_kemono_party_flutter/pages/posts_screen.dart'; import 'package:veloe_kemono_party_flutter/posts_notifier.dart'; // Providers final searchQueryProvider = StateProvider((ref) => ''); final selectedCreatorProvider = StateProvider((ref) => null); final postsPageProvider = StateProvider((ref) => 0); enum KemonoSource { kemono, coomer } final sourceProvider = StateProvider((ref) => KemonoSource.kemono); final kemonoClientProvider = Provider((ref) { final source = ref.watch(sourceProvider); final baseUrl = source == KemonoSource.kemono ? 'https://kemono.su' : 'https://coomer.su'; return KemonoClient(baseUrl); }); final creatorsProvider = FutureProvider>((ref) async { final query = ref.watch(searchQueryProvider); final client = ref.watch(kemonoClientProvider); final creators = await client.getCreators(); return creators.where((creator) => creator.name.toLowerCase().contains(query.toLowerCase()) || creator.service.toLowerCase().contains(query.toLowerCase()) ).toList(); }); final sourceChangeProvider = Provider((ref) { // This will trigger rebuilds when source changes ref.watch(sourceProvider); }); final postsProvider = StateNotifierProvider.autoDispose .family>, (String, String, String)>((ref, args) { final (creatorId, service, query) = args; return PostsNotifier( creatorId: creatorId, service: service, query: query, client: ref.read(kemonoClientProvider), ); }); final httpFileService = HttpFileService(); // Image Caching final imageCacheManager = CacheManager( Config( 'kemono_images', stalePeriod: const Duration(days: 30), maxNrOfCacheObjects: 1024, fileService: httpFileService, ), ); final videoCacheManager = CacheManager( Config( 'kemono_videos', stalePeriod: const Duration(days: 30), maxNrOfCacheObjects: 1024, fileService: httpFileService, ), ); final iconsCacheManager = CacheManager( Config( 'kemono_icons', stalePeriod: const Duration(days: 30), maxNrOfCacheObjects: 1024, fileService: HttpFileService(), ), ); // Main Application void main() { httpFileService.concurrentFetches = 2; MediaKit.ensureInitialized(); runApp( const ProviderScope( child: MaterialApp( home: AppLayout( navItems: [ NavItem( label: 'Home', icon: Icons.home, page: HomeScreen(), ), NavItem( label: 'Global Feed (Rukis)', icon: Icons.public, page: PostsScreen( creatorId:'82522', service: 'patreon', withAppBar: false,), ), NavItem( label: 'Settings', icon: Icons.settings, page: CacheSettingsScreen(), ), ], ), ), ), ); }