implemented Ticker page selection persistence and enhanced ProseMirror table display modes

This commit is contained in:
2026-07-10 19:15:52 +02:00
parent 0d01f6b631
commit 37608e59b3
10 changed files with 827 additions and 131 deletions
@@ -4,10 +4,10 @@ import '../../../../api/marianumconnect/queries/get_ticker_nav/get_ticker_nav_re
import '../../../../api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.dart';
import '../../../../theming/app_theme.dart';
/// Shared navigation list for the ticker module, used both as the phone drawer
/// and as the permanent tablet sidebar. Lists the "Aktuelles" home entry
/// followed by the section-grouped pages. [selectedSlug] is null while the home
/// surface is shown.
/// Shared navigation for the ticker module: the "Aktuelles" home entry followed
/// by the section-grouped pages. Used as the permanent tablet sidebar
/// ([TickerNavList]) and, via [tickerNavItems], inside the phone bottom sheet.
/// [selectedSlug] is null while the home surface is shown.
class TickerNavList extends StatelessWidget {
final List<TickerNavSection> sections;
final String? selectedSlug;
@@ -25,9 +25,9 @@ class TickerNavList extends StatelessWidget {
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final children = <Widget>[
Widget build(BuildContext context) => ListView(
padding: EdgeInsets.zero,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(
AppSpacing.md,
@@ -35,24 +35,41 @@ class TickerNavList extends StatelessWidget {
AppSpacing.md,
AppSpacing.sm,
),
child: Text('Ticker', style: theme.textTheme.titleLarge),
child: Text('Ticker', style: Theme.of(context).textTheme.titleLarge),
),
ListTile(
leading: const Icon(Icons.campaign_outlined),
title: const Text('Aktuelles'),
selected: selectedSlug == null,
selectedTileColor: theme.colorScheme.secondaryContainer,
onTap: onSelectHome,
...tickerNavItems(
context,
sections: sections,
selectedSlug: selectedSlug,
onSelectHome: onSelectHome,
onSelectPage: onSelectPage,
onRedirect: onRedirect,
),
for (final section in sections) ..._section(context, section),
];
],
);
}
return ListView(padding: EdgeInsets.zero, children: children);
}
List<Widget> _section(BuildContext context, TickerNavSection section) {
final theme = Theme.of(context);
return [
/// The ticker nav rows (Aktuelles home entry + section-grouped pages) as a flat
/// widget list, so they render both inside the sidebar's [ListView] and inside
/// the bottom sheet's shared [Column] without a bounded-height wrapper.
List<Widget> tickerNavItems(
BuildContext context, {
required List<TickerNavSection> sections,
required String? selectedSlug,
required VoidCallback onSelectHome,
required void Function(TickerNavPage page) onSelectPage,
required void Function(TickerNavPage page) onRedirect,
}) {
final theme = Theme.of(context);
return [
ListTile(
leading: const Icon(Icons.campaign_outlined),
title: const Text('Aktuelles'),
selected: selectedSlug == null,
selectedTileColor: theme.colorScheme.secondaryContainer,
onTap: onSelectHome,
),
for (final section in sections) ...[
Padding(
padding: const EdgeInsets.fromLTRB(
AppSpacing.md,
@@ -80,17 +97,17 @@ class TickerNavList extends StatelessWidget {
? onRedirect(page)
: onSelectPage(page),
),
];
}
],
];
}
IconData _iconFor(String kind) {
switch (kind) {
case TickerPageKind.redirect:
return Icons.link;
case TickerPageKind.proxiedFile:
return Icons.picture_as_pdf_outlined;
default:
return Icons.article_outlined;
}
IconData _iconFor(String kind) {
switch (kind) {
case TickerPageKind.redirect:
return Icons.link;
case TickerPageKind.proxiedFile:
return Icons.picture_as_pdf_outlined;
default:
return Icons.article_outlined;
}
}