b0-cloud first commit

This commit is contained in:
Leon Bösche
2025-12-16 18:09:20 +01:00
parent fcac7ac69f
commit 7d372a1aac
60 changed files with 3760 additions and 10 deletions

View File

@@ -0,0 +1,175 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../blocs/auth/auth_bloc.dart';
import '../blocs/auth/auth_state.dart';
import 'login_form.dart';
import 'file_explorer.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
late String _selectedTab = 'Drive';
late AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 400),
vsync: this,
);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
children: [
Center(
child: BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) {
final isLoggedIn = state is AuthAuthenticated;
if (isLoggedIn && !_animationController.isAnimating) {
_animationController.forward();
} else if (!isLoggedIn) {
_animationController.reverse();
}
return AnimatedContainer(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
width: isLoggedIn
? MediaQuery.of(context).size.width * 0.9
: 340,
height: isLoggedIn
? MediaQuery.of(context).size.height * 0.9
: 280,
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Colors.white.withValues(alpha: 0.2),
),
),
child: isLoggedIn
? const FileExplorer()
: const LoginForm(),
),
),
),
);
},
),
),
Positioned(
top: 10,
left: 0,
right: 0,
child: Center(
child: Text(
'b0esche.cloud',
style: TextStyle(
fontFamily: 'PixelatedElegance',
fontSize: 42,
color: Colors.white,
decoration: TextDecoration.underline,
decorationColor: Colors.white,
fontFeatures: [const FontFeature.slashedZero()],
),
),
),
),
Positioned(
top: 10,
right: 20,
child: BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) {
final isLoggedIn = state is AuthAuthenticated;
if (!isLoggedIn) {
return const SizedBox.shrink();
}
return ScaleTransition(
scale: Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(
parent: _animationController,
curve: Curves.easeOutBack,
),
),
child: Row(
children: [
_buildNavButton('Drive', Icons.cloud),
const SizedBox(width: 16),
_buildNavButton('Mail', Icons.mail),
const SizedBox(width: 16),
_buildNavButton('Add', Icons.add),
const SizedBox(width: 16),
_buildNavButton('Profile', Icons.person, isAvatar: true),
],
),
);
},
),
),
],
),
);
}
Widget _buildNavButton(String label, IconData icon, {bool isAvatar = false}) {
final isSelected = _selectedTab == label;
final highlightColor = Color.fromARGB(255, 100, 200, 255);
final defaultColor = Colors.white70;
return GestureDetector(
onTap: () {
setState(() {
_selectedTab = label;
});
},
child: isAvatar
? CircleAvatar(
backgroundColor: isSelected ? highlightColor : defaultColor,
child: Icon(icon, color: Colors.black),
)
: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon,
color: isSelected ? highlightColor : defaultColor,
size: 24,
),
const SizedBox(height: 4),
Text(
label,
style: TextStyle(
color: isSelected ? highlightColor : defaultColor,
fontSize: 12,
fontWeight: isSelected
? FontWeight.bold
: FontWeight.normal,
),
),
],
),
);
}
}