b0-cloud first commit
This commit is contained in:
175
b0esche_cloud/lib/pages/home_page.dart
Normal file
175
b0esche_cloud/lib/pages/home_page.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user