Refactor HomePage layout to separate title and audio player bar, enhancing clarity and organization

This commit is contained in:
Leon Bösche
2026-01-17 01:51:43 +01:00
parent 2c565c3b50
commit a219b8c1a2
2 changed files with 48 additions and 47 deletions

View File

@@ -405,7 +405,7 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
backgroundColor: AppTheme.primaryBackground, backgroundColor: AppTheme.primaryBackground,
body: Stack( body: Stack(
children: [ children: [
// Top bar: title, audio bar (if visible), nav buttons, all in a centered row // Top bar: title and nav buttons
Positioned( Positioned(
top: 0, top: 0,
left: 0, left: 0,
@@ -417,51 +417,25 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
children: [ children: [
// Left spacer // Left spacer
const Expanded(child: SizedBox()), const Expanded(child: SizedBox()),
// Center: title and audio bar // Center: title only
Expanded( Expanded(
flex: 2, flex: 2,
child: Row( child: Builder(
mainAxisAlignment: MainAxisAlignment.center, builder: (context) {
crossAxisAlignment: CrossAxisAlignment.center, final screenWidth = MediaQuery.of(context).size.width;
children: [ final fontSize = screenWidth < 600 ? 24.0 : 48.0;
Builder( return Text(
builder: (context) { 'b0esche.cloud',
final screenWidth = MediaQuery.of( style: TextStyle(
context, fontFamily: 'PixelatedElegance',
).size.width; fontSize: fontSize,
final fontSize = screenWidth < 600 ? 24.0 : 48.0; color: AppTheme.primaryText,
return Text( decoration: TextDecoration.underline,
'b0esche.cloud', decorationColor: AppTheme.primaryText,
style: TextStyle( fontFeatures: const [FontFeature.slashedZero()],
fontFamily: 'PixelatedElegance',
fontSize: fontSize,
color: AppTheme.primaryText,
decoration: TextDecoration.underline,
decorationColor: AppTheme.primaryText,
fontFeatures: const [
FontFeature.slashedZero(),
],
),
);
},
),
if (_showAudioBar &&
_audioFileName != null &&
_audioFileUrl != null) ...[
const SizedBox(width: 24),
SlideTransition(
position: _audioBarOffset,
child: AudioPlayerBar(
fileName: _audioFileName!,
fileUrl: _audioFileUrl!,
onClose: () {
_audioBarController.reverse();
setState(() => _showAudioBar = false);
},
),
), ),
], );
], },
), ),
), ),
// Right: nav buttons // Right: nav buttons
@@ -498,6 +472,28 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
), ),
), ),
), ),
// Audio player bar (absolute, below title)
if (_showAudioBar &&
_audioFileName != null &&
_audioFileUrl != null)
Positioned(
top: 56, // adjust as needed for spacing below top bar
left: 0,
right: 0,
child: SlideTransition(
position: _audioBarOffset,
child: Center(
child: AudioPlayerBar(
fileName: _audioFileName!,
fileUrl: _audioFileUrl!,
onClose: () {
_audioBarController.reverse();
setState(() => _showAudioBar = false);
},
),
),
),
),
Center( Center(
child: BlocBuilder<AuthBloc, AuthState>( child: BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) { builder: (context, state) {

View File

@@ -50,11 +50,16 @@ class _AudioPlayerBarState extends State<AudioPlayerBar>
Future<void> _initAudio() async { Future<void> _initAudio() async {
try { try {
await _audioPlayer.setUrl(widget.fileUrl); await _audioPlayer.setUrl(widget.fileUrl);
setState(() { // Wait until duration is available
_duration = _audioPlayer.duration ?? Duration.zero; _audioPlayer.durationStream.firstWhere((d) => d != null).then((d) async {
_isLoading = false; setState(() {
_duration = d ?? Duration.zero;
_isLoading = false;
});
await _audioPlayer.play(); // Start playback automatically
// Animate play icon
if (mounted) _iconController.forward();
}); });
_audioPlayer.play(); // Start playback automatically
_audioPlayer.positionStream.listen((pos) { _audioPlayer.positionStream.listen((pos) {
setState(() { setState(() {
_position = pos; _position = pos;