Przebudowanie aplikacji, usprawnione AI, dodanie combo buildera
Some checks failed
Build Linux App / build (push) Failing after 1m18s

This commit is contained in:
Kazimierz Ciołek
2026-07-06 23:44:17 +02:00
parent 9dcc4b87de
commit 6dd7213eb0
48 changed files with 3229 additions and 669 deletions

View File

@@ -1,10 +1,12 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:trainhub_flutter/core/constants/app_constants.dart';
import 'package:trainhub_flutter/core/constants/ui_constants.dart';
import 'package:trainhub_flutter/core/router/app_router.dart';
import 'package:trainhub_flutter/core/theme/app_colors.dart';
import 'package:trainhub_flutter/presentation/settings/ai_model_settings_controller.dart';
@RoutePage()
class ShellPage extends StatelessWidget {
@@ -113,21 +115,22 @@ class _Sidebar extends StatelessWidget {
decoration: BoxDecoration(
color: AppColors.accentMuted,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColors.accentBorder),
),
child: const Icon(
Icons.fitness_center,
Icons.sports_martial_arts,
color: AppColors.accent,
size: 18,
),
),
const SizedBox(width: 10),
Text(
'TrainHub',
style: GoogleFonts.inter(
'TRAINHUB',
style: GoogleFonts.chakraPetch(
fontSize: 15,
fontWeight: FontWeight.w700,
color: AppColors.textPrimary,
letterSpacing: -0.3,
letterSpacing: 1.5,
),
),
],
@@ -150,6 +153,9 @@ class _Sidebar extends StatelessWidget {
const Spacer(),
// --- AI model download progress (runs in the background) ---
const _DownloadIndicator(),
// --- Footer ---
Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 12, 12),
@@ -206,10 +212,10 @@ class _NavItemState extends State<_NavItem> {
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
decoration: BoxDecoration(
color: active
? AppColors.zinc800
? AppColors.accentMuted
: _isHovered
? AppColors.zinc900
: Colors.transparent,
? AppColors.surfaceContainerHigh
: Colors.transparent,
borderRadius: BorderRadius.circular(6),
),
child: Row(
@@ -229,19 +235,20 @@ class _NavItemState extends State<_NavItem> {
Icon(
active ? widget.data.activeIcon : widget.data.icon,
size: 17,
color: active ? AppColors.textPrimary : AppColors.textMuted,
color: active ? AppColors.accent : AppColors.textMuted,
),
const SizedBox(width: 9),
Text(
widget.data.label,
style: GoogleFonts.inter(
fontSize: 13,
fontWeight: active ? FontWeight.w600 : FontWeight.w400,
widget.data.label.toUpperCase(),
style: GoogleFonts.chakraPetch(
fontSize: 12,
fontWeight: active ? FontWeight.w600 : FontWeight.w500,
letterSpacing: 1.2,
color: active
? AppColors.textPrimary
: _isHovered
? AppColors.textSecondary
: AppColors.textMuted,
? AppColors.textSecondary
: AppColors.textMuted,
),
),
],
@@ -252,6 +259,61 @@ class _NavItemState extends State<_NavItem> {
}
}
// ---------------------------------------------------------------------------
// AI model download progress — visible from anywhere while a download runs
// ---------------------------------------------------------------------------
class _DownloadIndicator extends ConsumerWidget {
const _DownloadIndicator();
@override
Widget build(BuildContext context, WidgetRef ref) {
final modelState = ref.watch(aiModelSettingsControllerProvider);
if (!modelState.isDownloading) return const SizedBox.shrink();
return Container(
margin: const EdgeInsets.fromLTRB(12, 0, 12, 8),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: AppColors.accentMuted,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColors.accentBorder),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'DOWNLOADING AI',
style: GoogleFonts.jetBrainsMono(
fontSize: 9,
fontWeight: FontWeight.w600,
letterSpacing: 1.2,
color: AppColors.accent,
),
),
const SizedBox(height: 6),
ClipRRect(
borderRadius: BorderRadius.circular(2),
child: LinearProgressIndicator(
value: modelState.progress,
minHeight: 4,
backgroundColor: AppColors.surfaceContainerHigh,
valueColor: const AlwaysStoppedAnimation<Color>(AppColors.accent),
),
),
const SizedBox(height: 4),
Text(
'${(modelState.progress * 100).toStringAsFixed(0)}%',
style: GoogleFonts.jetBrainsMono(
fontSize: 10,
color: AppColors.textSecondary,
),
),
],
),
);
}
}
// ---------------------------------------------------------------------------
// Settings icon button in sidebar footer
// ---------------------------------------------------------------------------