Files
tcna-packages/packages/flatpak/example/lib/presentation/screens/home_screen.dart
T
2026-04-06 05:09:51 +00:00

182 lines
5.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../../../data/models/application_model.dart';
import '../../business_logic/app_launch/app_launch_cubit.dart';
import '../../business_logic/app_status/app_status_cubit.dart';
import '../../business_logic/app_status/app_status_state.dart';
import '../../business_logic/discovery/discovery_cubit.dart';
import '../../business_logic/discovery/discovery_state.dart';
import '../../business_logic/installation/installation_cubit.dart';
import '../widgets/category_section.dart';
import '../widgets/hero_widget.dart';
import '../widgets/top_bar.dart';
import '../../app_router.dart';
import '../../responsive.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with AutomaticKeepAliveClientMixin, RouteAware {
static const List<String> categoryOrder = [
'Popular Apps',
'Productivity',
'Development',
'Graphics & Photography',
'Audio & Video',
'Gaming',
];
@override
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_loadData();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
final route = ModalRoute.of(context);
if (route is PageRoute) {
routeObserver.subscribe(this, route);
}
}
@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}
@override
void didPopNext() {
debugPrint('[HomeScreen] Returned to screen - refreshing data');
_refreshData();
}
void _loadData() {
context.read<DiscoveryCubit>().initialize();
context.read<AppStatusCubit>().loadAppStatus();
}
void _refreshData() {
context.read<AppStatusCubit>().refresh();
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: const AppTopBar(),
body: BlocBuilder<DiscoveryCubit, DiscoveryState>(
builder: (context, state) {
if (state is DiscoveryLoading && state.category == null) {
return const Center(child: CircularProgressIndicator());
}
if (state is DiscoveryError) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error, size: Responsive.scale(context, 64), color: Colors.red),
Responsive.vGap(context, 16),
Text('Error: ${state.message}'),
Responsive.vGap(context, 16),
ElevatedButton(
onPressed: _loadData,
child: const Text('Retry'),
),
],
),
);
}
if (state is DiscoveryLoaded) {
return RefreshIndicator(
onRefresh: () async {
await context.read<DiscoveryCubit>().initialize();
context.read<AppStatusCubit>().refresh();
},
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [
SliverToBoxAdapter(
child: HeroWidget(
title: "Discover, Install, and Enjoy Apps on AGL Store.",
imageUrl: 'assets/images/Hero.png',
subtitle:
"Explore a wide range of applications available through Flatpak.",
),
),
// Category sections
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final categoryName = categoryOrder[index];
final apps = state.categoryApps[categoryName] ?? [];
final isLoading = context
.read<DiscoveryCubit>()
.isCategoryLoading(categoryName);
return Column(
children: [
CategorySection(
category_heading: categoryName,
apps: apps,
isLoading: isLoading,
onTap: (app) => _navigateToApp(app, context),
onInstall: (app) => _handleInstall(app, context),
),
Responsive.vGap(context, 32),
],
);
},
childCount: categoryOrder.length,
),
),
],
),
);
}
return const Center(child: Text('Initializing...'));
},
),
);
}
void _navigateToApp(Application app, BuildContext context) {
context.push('/app/${app.shortId}');
}
Future<void> _handleInstall(Application app, BuildContext context) async {
final appStatusCubit = context.read<AppStatusCubit>();
final installationCubit = context.read<InstallationCubit>();
final launchCubit = context.read<AppLaunchCubit>();
final status = appStatusCubit.getAppStatus(app.id);
if (status == AppStatus.installed) {
// Launch the app
await launchCubit.launchApp(app.id);
} else if (status == AppStatus.needsUpdate) {
// Update the app
await installationCubit.updateApp(app.id);
} else if (status == AppStatus.notInstalled) {
// Install the app
await installationCubit.installApp(app.id);
}
}
}