This commit is contained in:
Leon Bösche
2026-01-09 22:11:15 +01:00
parent bb33ad1241
commit cfeae0a199

View File

@@ -293,283 +293,302 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
child: BlocBuilder<AuthBloc, AuthState>( child: BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) { builder: (context, state) {
final isLoggedIn = state is AuthAuthenticated; final isLoggedIn = state is AuthAuthenticated;
if (isLoggedIn && !_animationController.isAnimating) { if (isLoggedIn && !_animationController.isAnimating) {
_animationController.forward(); _animationController.forward();
} else if (!isLoggedIn) { } else if (!isLoggedIn) {
_animationController.reverse(); _animationController.reverse();
} }
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width < 600 ? 60.0 : 78.0, top: MediaQuery.of(context).size.width < 600
), ? 60.0
child: AnimatedContainer( : 78.0,
duration: const Duration(milliseconds: 350), ),
curve: Curves.easeInOut, child: AnimatedContainer(
width: isLoggedIn duration: const Duration(milliseconds: 350),
? MediaQuery.of(context).size.width * 0.9 curve: Curves.easeInOut,
: 340, width: isLoggedIn
height: isLoggedIn ? MediaQuery.of(context).size.width * 0.9
? MediaQuery.of(context).size.height * 0.9 : 340,
: (_isSignupMode height: isLoggedIn
? 400 ? MediaQuery.of(context).size.height * 0.9
: (_usePasswordMode ? 350 : 280)), : (_isSignupMode
child: ClipRRect( ? 400
borderRadius: BorderRadius.circular(16), : (_usePasswordMode ? 350 : 280)),
child: BackdropFilter( child: ClipRRect(
filter: ui.ImageFilter.blur(sigmaX: 10, sigmaY: 10), borderRadius: BorderRadius.circular(16),
child: Stack( child: BackdropFilter(
children: [ filter: ui.ImageFilter.blur(sigmaX: 10, sigmaY: 10),
Container( child: Stack(
decoration: AppTheme.glassDecoration, children: [
child: isLoggedIn Container(
? BlocListener< decoration: AppTheme.glassDecoration,
OrganizationBloc, child: isLoggedIn
OrganizationState ? BlocListener<
>( OrganizationBloc,
listener: (context, state) { OrganizationState
if (state is OrganizationLoaded) { >(
final orgId = state.selectedOrg?.id ?? ''; listener: (context, state) {
// Reload file browser when org changes (or when falling back to personal workspace) if (state is OrganizationLoaded) {
context.read<FileBrowserBloc>().add( final orgId =
LoadDirectory( state.selectedOrg?.id ?? '';
orgId: orgId, // Reload file browser when org changes (or when falling back to personal workspace)
path: '/', context.read<FileBrowserBloc>().add(
), LoadDirectory(
); orgId: orgId,
} path: '/',
}, ),
child: );
BlocBuilder< }
OrganizationBloc, },
OrganizationState child:
>( BlocBuilder<
builder: (context, orgState) { OrganizationBloc,
if (orgState OrganizationState
is OrganizationInitial) { >(
builder: (context, orgState) {
if (orgState
is OrganizationInitial) {
WidgetsBinding.instance WidgetsBinding.instance
.addPostFrameCallback((_) { .addPostFrameCallback((
_,
) {
// Kick off org fetch and immediately show personal workspace // Kick off org fetch and immediately show personal workspace
// while org data loads. // while org data loads.
context.read<OrganizationBloc>().add( context
.read<
OrganizationBloc
>()
.add(
LoadOrganizations(), LoadOrganizations(),
); );
context.read<FileBrowserBloc>().add( context
.read<
FileBrowserBloc
>()
.add(
const LoadDirectory( const LoadDirectory(
orgId: '', orgId: '',
path: '/', path: '/',
), ),
); );
}); });
} }
return Column( return Column(
children: [ children: [
const SizedBox(height: 80), const SizedBox(height: 80),
_buildOrgRow(context), _buildOrgRow(context),
Expanded( Expanded(
child: _buildDrive( child: _buildDrive(
orgState, orgState,
state, state,
),
), ),
), ],
], );
); },
}, ),
), )
) : LoginForm(
: LoginForm( onSignupModeChanged: _setSignupMode,
onSignupModeChanged: _setSignupMode, onPasswordModeChanged: _setPasswordMode,
onPasswordModeChanged: _setPasswordMode, ),
),
),
// Top-left radial glow - primary accent light
AnimatedPositioned(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
top: isLoggedIn ? -180 : -120,
left: isLoggedIn ? -180 : -120,
child: IgnorePointer(
child: AnimatedContainer(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
width: isLoggedIn ? 550 : 400,
height: isLoggedIn ? 550 : 400,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [
AppTheme.accentColor.withValues(
alpha: isLoggedIn ? 0.12 : 0.15,
),
AppTheme.accentColor.withValues(
alpha: 0.04,
),
Colors.transparent,
],
stops: const [0.0, 0.6, 1.0],
),
),
),
), ),
), // Top-left radial glow - primary accent light
// Bottom-right warm glow - complementary lighting AnimatedPositioned(
AnimatedPositioned( duration: const Duration(milliseconds: 350),
duration: const Duration(milliseconds: 350), curve: Curves.easeInOut,
curve: Curves.easeInOut, top: isLoggedIn ? -180 : -120,
bottom: isLoggedIn ? -200 : -140, left: isLoggedIn ? -180 : -120,
right: isLoggedIn ? -200 : -140, child: IgnorePointer(
child: IgnorePointer( child: AnimatedContainer(
child: AnimatedContainer( duration: const Duration(milliseconds: 350),
duration: const Duration(milliseconds: 350), curve: Curves.easeInOut,
curve: Curves.easeInOut, width: isLoggedIn ? 550 : 400,
width: isLoggedIn ? 530 : 380, height: isLoggedIn ? 550 : 400,
height: isLoggedIn ? 530 : 380,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [
Colors.cyan.withValues(
alpha: isLoggedIn ? 0.06 : 0.08,
),
Colors.transparent,
],
),
),
),
),
),
// Top edge subtle highlight
Positioned(
top: 0,
left: 0,
right: 0,
child: IgnorePointer(
child: Container(
height: 60,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white.withValues(alpha: 0.05),
Colors.transparent,
],
),
),
),
),
),
// Left edge subtle side lighting
Positioned(
left: 0,
top: 0,
bottom: 0,
child: IgnorePointer(
child: Container(
width: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
AppTheme.accentColor.withValues(
alpha: 0.04,
),
Colors.transparent,
],
),
),
),
),
),
// Diagonal shimmer overlay
Positioned(
top: 0,
left: 0,
child: IgnorePointer(
child: Transform.rotate(
angle: 0.785,
child: Container(
width: 600,
height: 100,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( shape: BoxShape.circle,
gradient: RadialGradient(
colors: [ colors: [
Colors.white.withValues(alpha: 0), AppTheme.accentColor.withValues(
Colors.white.withValues(alpha: 0.06), alpha: isLoggedIn ? 0.12 : 0.15,
Colors.white.withValues(alpha: 0), ),
AppTheme.accentColor.withValues(
alpha: 0.04,
),
Colors.transparent,
],
stops: const [0.0, 0.6, 1.0],
),
),
),
),
),
// Bottom-right warm glow - complementary lighting
AnimatedPositioned(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
bottom: isLoggedIn ? -200 : -140,
right: isLoggedIn ? -200 : -140,
child: IgnorePointer(
child: AnimatedContainer(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
width: isLoggedIn ? 530 : 380,
height: isLoggedIn ? 530 : 380,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [
Colors.cyan.withValues(
alpha: isLoggedIn ? 0.06 : 0.08,
),
Colors.transparent,
], ],
), ),
), ),
), ),
), ),
), ),
), // Top edge subtle highlight
], Positioned(
top: 0,
left: 0,
right: 0,
child: IgnorePointer(
child: Container(
height: 60,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white.withValues(alpha: 0.05),
Colors.transparent,
],
),
),
),
),
),
// Left edge subtle side lighting
Positioned(
left: 0,
top: 0,
bottom: 0,
child: IgnorePointer(
child: Container(
width: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
AppTheme.accentColor.withValues(
alpha: 0.04,
),
Colors.transparent,
],
),
),
),
),
),
// Diagonal shimmer overlay
Positioned(
top: 0,
left: 0,
child: IgnorePointer(
child: Transform.rotate(
angle: 0.785,
child: Container(
width: 600,
height: 100,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.white.withValues(alpha: 0),
Colors.white.withValues(
alpha: 0.06,
),
Colors.white.withValues(alpha: 0),
],
),
),
),
),
),
),
],
),
), ),
), ),
), ),
),
);
},
),
),
Positioned(
top: 0,
left: 0,
right: 0,
child: Center(
child: Builder(
builder: (context) {
final screenWidth = MediaQuery.of(context).size.width;
final fontSize = screenWidth < 600 ? 24.0 : 48.0;
return Text(
'b0esche.cloud',
style: TextStyle(
fontFamily: 'PixelatedElegance',
fontSize: fontSize,
color: AppTheme.primaryText,
decoration: TextDecoration.underline,
decorationColor: AppTheme.primaryText,
fontFeatures: const [FontFeature.slashedZero()],
),
); );
}, },
), ),
), ),
), Positioned(
Positioned( top: 0,
top: MediaQuery.of(context).size.width < 600 ? 40 : 10, left: 0,
right: 20, right: 0,
child: BlocBuilder<AuthBloc, AuthState>( child: Center(
builder: (context, state) { child: Builder(
final isLoggedIn = state is AuthAuthenticated; builder: (context) {
if (!isLoggedIn) { final screenWidth = MediaQuery.of(context).size.width;
return const SizedBox.shrink(); final fontSize = screenWidth < 600 ? 24.0 : 48.0;
} return Text(
return ScaleTransition( 'b0esche.cloud',
scale: Tween<double>(begin: 0, end: 1).animate( style: TextStyle(
CurvedAnimation( fontFamily: 'PixelatedElegance',
parent: _animationController, fontSize: fontSize,
curve: Curves.easeOutBack, color: AppTheme.primaryText,
), decoration: TextDecoration.underline,
), decorationColor: AppTheme.primaryText,
child: Row( fontFeatures: const [FontFeature.slashedZero()],
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),
],
),
);
},
), ),
), Positioned(
], top: MediaQuery.of(context).size.width < 600 ? 40 : 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,
),
],
),
);
},
),
),
],
),
), ),
); );
} }