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>(
builder: (context, state) {
final isLoggedIn = state is AuthAuthenticated;
if (isLoggedIn && !_animationController.isAnimating) {
_animationController.forward();
} else if (!isLoggedIn) {
_animationController.reverse();
}
return Padding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width < 600 ? 60.0 : 78.0,
),
child: 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
: (_isSignupMode
? 400
: (_usePasswordMode ? 350 : 280)),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: BackdropFilter(
filter: ui.ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Stack(
children: [
Container(
decoration: AppTheme.glassDecoration,
child: isLoggedIn
? BlocListener<
OrganizationBloc,
OrganizationState
>(
listener: (context, state) {
if (state is OrganizationLoaded) {
final orgId = state.selectedOrg?.id ?? '';
// Reload file browser when org changes (or when falling back to personal workspace)
context.read<FileBrowserBloc>().add(
LoadDirectory(
orgId: orgId,
path: '/',
),
);
}
},
child:
BlocBuilder<
OrganizationBloc,
OrganizationState
>(
builder: (context, orgState) {
if (orgState
is OrganizationInitial) {
if (isLoggedIn && !_animationController.isAnimating) {
_animationController.forward();
} else if (!isLoggedIn) {
_animationController.reverse();
}
return Padding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width < 600
? 60.0
: 78.0,
),
child: 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
: (_isSignupMode
? 400
: (_usePasswordMode ? 350 : 280)),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: BackdropFilter(
filter: ui.ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Stack(
children: [
Container(
decoration: AppTheme.glassDecoration,
child: isLoggedIn
? BlocListener<
OrganizationBloc,
OrganizationState
>(
listener: (context, state) {
if (state is OrganizationLoaded) {
final orgId =
state.selectedOrg?.id ?? '';
// Reload file browser when org changes (or when falling back to personal workspace)
context.read<FileBrowserBloc>().add(
LoadDirectory(
orgId: orgId,
path: '/',
),
);
}
},
child:
BlocBuilder<
OrganizationBloc,
OrganizationState
>(
builder: (context, orgState) {
if (orgState
is OrganizationInitial) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
.addPostFrameCallback((
_,
) {
// Kick off org fetch and immediately show personal workspace
// while org data loads.
context.read<OrganizationBloc>().add(
context
.read<
OrganizationBloc
>()
.add(
LoadOrganizations(),
);
context.read<FileBrowserBloc>().add(
context
.read<
FileBrowserBloc
>()
.add(
const LoadDirectory(
orgId: '',
path: '/',
),
);
});
}
return Column(
children: [
const SizedBox(height: 80),
_buildOrgRow(context),
Expanded(
child: _buildDrive(
orgState,
state,
}
return Column(
children: [
const SizedBox(height: 80),
_buildOrgRow(context),
Expanded(
child: _buildDrive(
orgState,
state,
),
),
),
],
);
},
),
)
: LoginForm(
onSignupModeChanged: _setSignupMode,
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],
),
),
),
],
);
},
),
)
: LoginForm(
onSignupModeChanged: _setSignupMode,
onPasswordModeChanged: _setPasswordMode,
),
),
),
// 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,
// 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(
gradient: LinearGradient(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [
Colors.white.withValues(alpha: 0),
Colors.white.withValues(alpha: 0.06),
Colors.white.withValues(alpha: 0),
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],
),
),
),
),
),
// 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(
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),
],
),
);
},
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(
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,
),
],
),
);
},
),
),
],
),
),
);
}