refactored and condensed technical documentation and comments across the codebase to improve readability
This commit is contained in:
@@ -79,13 +79,9 @@ class _LoginState extends State<Login> with SingleTickerProviderStateMixin {
|
||||
minHeight: constraints.maxHeight,
|
||||
maxWidth: 420,
|
||||
),
|
||||
// spaceBetween statt Spacer-in-IntrinsicHeight: bei jeder
|
||||
// Inhaltsänderung im unteren Block (z.B. EndpointLink mit
|
||||
// dynamischem Label) würde IntrinsicHeight sonst die Column
|
||||
// an die intrinsic-Höhe pinnen und ein paar Pixel Overflow
|
||||
// produzieren. spaceBetween fügt nur den verbleibenden Gap
|
||||
// ein und schrumpft sauber auf 0, wenn der Inhalt zu hoch
|
||||
// wird — dann übernimmt der äußere ScrollView.
|
||||
// spaceBetween statt Spacer-in-IntrinsicHeight: Letzteres würde
|
||||
// die Column bei Inhaltsänderungen im unteren Block auf die
|
||||
// intrinsic-Höhe pinnen und ein paar Pixel Overflow erzeugen.
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
@@ -54,14 +54,12 @@ IconData? _iconForMime(String mime) {
|
||||
const map = <String, IconData>{
|
||||
'application/pdf': Icons.picture_as_pdf_outlined,
|
||||
|
||||
// Word processing
|
||||
'application/msword': Icons.description_outlined,
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
|
||||
Icons.description_outlined,
|
||||
'application/vnd.oasis.opendocument.text': Icons.description_outlined,
|
||||
'application/rtf': Icons.description_outlined,
|
||||
|
||||
// Spreadsheets
|
||||
'application/vnd.ms-excel': Icons.table_chart_outlined,
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
|
||||
Icons.table_chart_outlined,
|
||||
@@ -70,13 +68,11 @@ IconData? _iconForMime(String mime) {
|
||||
'application/vnd.ms-excel.sheet.macroenabled.12':
|
||||
Icons.table_chart_outlined,
|
||||
|
||||
// Presentations
|
||||
'application/vnd.ms-powerpoint': Icons.slideshow_outlined,
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation':
|
||||
Icons.slideshow_outlined,
|
||||
'application/vnd.oasis.opendocument.presentation': Icons.slideshow_outlined,
|
||||
|
||||
// Archives
|
||||
'application/zip': Icons.folder_zip_outlined,
|
||||
'application/x-zip-compressed': Icons.folder_zip_outlined,
|
||||
'application/x-rar-compressed': Icons.folder_zip_outlined,
|
||||
@@ -88,7 +84,6 @@ IconData? _iconForMime(String mime) {
|
||||
'application/x-xz': Icons.folder_zip_outlined,
|
||||
'application/zstd': Icons.folder_zip_outlined,
|
||||
|
||||
// Code / structured data
|
||||
'application/json': Icons.code,
|
||||
'application/ld+json': Icons.code,
|
||||
'application/xml': Icons.code,
|
||||
@@ -96,26 +91,21 @@ IconData? _iconForMime(String mime) {
|
||||
'application/javascript': Icons.code,
|
||||
'application/x-sh': Icons.terminal,
|
||||
|
||||
// Calendar / contacts
|
||||
'text/calendar': Icons.calendar_month_outlined,
|
||||
'text/vcard': Icons.contact_page_outlined,
|
||||
|
||||
// E-books
|
||||
'application/epub+zip': Icons.menu_book_outlined,
|
||||
'application/x-mobipocket-ebook': Icons.menu_book_outlined,
|
||||
|
||||
// Executables / installers
|
||||
'application/x-msdownload': Icons.terminal,
|
||||
'application/x-msi': Icons.terminal,
|
||||
'application/x-apple-diskimage': Icons.album_outlined,
|
||||
'application/vnd.android.package-archive': Icons.android_outlined,
|
||||
'application/octet-stream': Icons.insert_drive_file_outlined,
|
||||
|
||||
// Databases
|
||||
'application/x-sqlite3': Icons.storage_outlined,
|
||||
'application/vnd.sqlite3': Icons.storage_outlined,
|
||||
|
||||
// 3D
|
||||
'model/gltf-binary': Icons.view_in_ar_outlined,
|
||||
'model/gltf+json': Icons.view_in_ar_outlined,
|
||||
'model/stl': Icons.view_in_ar_outlined,
|
||||
@@ -125,7 +115,6 @@ IconData? _iconForMime(String mime) {
|
||||
}
|
||||
|
||||
const _extensionIcons = <String, IconData>{
|
||||
// Images
|
||||
'jpg': Icons.image_outlined, 'jpeg': Icons.image_outlined,
|
||||
'png': Icons.image_outlined, 'gif': Icons.image_outlined,
|
||||
'webp': Icons.image_outlined, 'bmp': Icons.image_outlined,
|
||||
@@ -137,7 +126,6 @@ const _extensionIcons = <String, IconData>{
|
||||
'svg': Icons.gesture_outlined, 'eps': Icons.gesture_outlined,
|
||||
'ai': Icons.gesture_outlined,
|
||||
|
||||
// Video
|
||||
'mp4': Icons.movie_outlined, 'm4v': Icons.movie_outlined,
|
||||
'mov': Icons.movie_outlined, 'mkv': Icons.movie_outlined,
|
||||
'avi': Icons.movie_outlined, 'webm': Icons.movie_outlined,
|
||||
@@ -145,7 +133,6 @@ const _extensionIcons = <String, IconData>{
|
||||
'3gp': Icons.movie_outlined, 'mpg': Icons.movie_outlined,
|
||||
'mpeg': Icons.movie_outlined, 'ogv': Icons.movie_outlined,
|
||||
|
||||
// Audio
|
||||
'mp3': Icons.audiotrack, 'm4a': Icons.audiotrack, 'aac': Icons.audiotrack,
|
||||
'wav': Icons.audiotrack, 'flac': Icons.audiotrack, 'ogg': Icons.audiotrack,
|
||||
'oga': Icons.audiotrack, 'opus': Icons.audiotrack, 'wma': Icons.audiotrack,
|
||||
@@ -156,31 +143,25 @@ const _extensionIcons = <String, IconData>{
|
||||
'musicxml': Icons.music_note, 'mxl': Icons.music_note,
|
||||
'midi': Icons.music_note, 'mid': Icons.music_note,
|
||||
|
||||
// PDF
|
||||
'pdf': Icons.picture_as_pdf_outlined,
|
||||
|
||||
// Word
|
||||
'doc': Icons.description_outlined, 'docx': Icons.description_outlined,
|
||||
'odt': Icons.description_outlined, 'rtf': Icons.description_outlined,
|
||||
'pages': Icons.description_outlined,
|
||||
|
||||
// Spreadsheets
|
||||
'xls': Icons.table_chart_outlined, 'xlsx': Icons.table_chart_outlined,
|
||||
'xlsm': Icons.table_chart_outlined, 'ods': Icons.table_chart_outlined,
|
||||
'csv': Icons.table_chart_outlined, 'tsv': Icons.table_chart_outlined,
|
||||
'numbers': Icons.table_chart_outlined,
|
||||
|
||||
// Presentations
|
||||
'ppt': Icons.slideshow_outlined, 'pptx': Icons.slideshow_outlined,
|
||||
'pps': Icons.slideshow_outlined, 'odp': Icons.slideshow_outlined,
|
||||
'key': Icons.slideshow_outlined,
|
||||
|
||||
// Plain text / notes
|
||||
'txt': Icons.article_outlined, 'md': Icons.article_outlined,
|
||||
'markdown': Icons.article_outlined, 'log': Icons.article_outlined,
|
||||
'rst': Icons.article_outlined,
|
||||
|
||||
// Code
|
||||
'html': Icons.code, 'htm': Icons.code, 'xhtml': Icons.code,
|
||||
'css': Icons.code, 'scss': Icons.code, 'sass': Icons.code, 'less': Icons.code,
|
||||
'js': Icons.code, 'mjs': Icons.code, 'cjs': Icons.code,
|
||||
@@ -195,12 +176,10 @@ const _extensionIcons = <String, IconData>{
|
||||
'json': Icons.code, 'json5': Icons.code, 'xml': Icons.code,
|
||||
'yaml': Icons.code, 'yml': Icons.code,
|
||||
|
||||
// Shell
|
||||
'sh': Icons.terminal, 'bash': Icons.terminal, 'zsh': Icons.terminal,
|
||||
'fish': Icons.terminal, 'ps1': Icons.terminal, 'bat': Icons.terminal,
|
||||
'cmd': Icons.terminal,
|
||||
|
||||
// Archives
|
||||
'zip': Icons.folder_zip_outlined, 'rar': Icons.folder_zip_outlined,
|
||||
'7z': Icons.folder_zip_outlined, 'tar': Icons.folder_zip_outlined,
|
||||
'gz': Icons.folder_zip_outlined, 'bz2': Icons.folder_zip_outlined,
|
||||
@@ -218,26 +197,21 @@ const _extensionIcons = <String, IconData>{
|
||||
'dockerignore': Icons.settings_outlined,
|
||||
'dockerfile': Icons.settings_outlined,
|
||||
|
||||
// Fonts
|
||||
'ttf': Icons.font_download_outlined, 'otf': Icons.font_download_outlined,
|
||||
'woff': Icons.font_download_outlined, 'woff2': Icons.font_download_outlined,
|
||||
'eot': Icons.font_download_outlined,
|
||||
|
||||
// Calendar / contacts
|
||||
'ics': Icons.calendar_month_outlined, 'ical': Icons.calendar_month_outlined,
|
||||
'vcf': Icons.contact_page_outlined, 'vcard': Icons.contact_page_outlined,
|
||||
|
||||
// E-books
|
||||
'epub': Icons.menu_book_outlined, 'mobi': Icons.menu_book_outlined,
|
||||
'azw': Icons.menu_book_outlined, 'azw3': Icons.menu_book_outlined,
|
||||
|
||||
// 3D
|
||||
'stl': Icons.view_in_ar_outlined, 'obj': Icons.view_in_ar_outlined,
|
||||
'fbx': Icons.view_in_ar_outlined, 'blend': Icons.view_in_ar_outlined,
|
||||
'glb': Icons.view_in_ar_outlined, 'gltf': Icons.view_in_ar_outlined,
|
||||
'3ds': Icons.view_in_ar_outlined,
|
||||
|
||||
// Executables / packages
|
||||
'exe': Icons.terminal, 'msi': Icons.terminal,
|
||||
'app': Icons.terminal, 'deb': Icons.terminal, 'rpm': Icons.terminal,
|
||||
'apk': Icons.android_outlined, 'ipa': Icons.terminal,
|
||||
@@ -247,7 +221,6 @@ const _extensionIcons = <String, IconData>{
|
||||
'iso': Icons.album_outlined, 'img': Icons.album_outlined,
|
||||
'dmg': Icons.album_outlined,
|
||||
|
||||
// Databases
|
||||
'db': Icons.storage_outlined, 'sqlite': Icons.storage_outlined,
|
||||
'sqlite3': Icons.storage_outlined,
|
||||
};
|
||||
|
||||
@@ -19,12 +19,10 @@ class QrShareView extends StatefulWidget {
|
||||
|
||||
class _QrShareViewState extends State<QrShareView>
|
||||
with SingleTickerProviderStateMixin {
|
||||
// Owning the TabController explicitly (instead of DefaultTabController) is
|
||||
// a workaround for a Flutter framework bug where TabBarView's
|
||||
// didChangeDependencies issues a jumpToPage mid-build, whose scroll
|
||||
// notification then calls setState on _TabStyle while the frame is still
|
||||
// being built — only reproduces reliably with a bottomNavigationBar in the
|
||||
// Scaffold underneath.
|
||||
// Own the TabController explicitly (not DefaultTabController) to dodge a
|
||||
// Flutter bug: TabBarView's didChangeDependencies fires jumpToPage mid-build,
|
||||
// whose scroll notification then calls setState on _TabStyle during the frame
|
||||
// — only reproduces with a bottomNavigationBar in the Scaffold underneath.
|
||||
late final TabController _tabController = TabController(
|
||||
length: 2,
|
||||
vsync: this,
|
||||
|
||||
@@ -174,12 +174,10 @@ class _AccountSectionState extends State<AccountSection> {
|
||||
}
|
||||
|
||||
Future<void> _showLogoutDialog(BuildContext context) async {
|
||||
// Sequential logout flow: dialog wipes secure storage, dialog closes
|
||||
// (single Navigator.pop), then we flip the AccountBloc state. The bloc
|
||||
// listener in main.dart pops the Settings route and runs the in-memory
|
||||
// wipe. Triggering setStatus from inside removeData (the previous
|
||||
// approach) raced AsyncDialogAction's pop(true) against popUntil(isFirst)
|
||||
// and could leave the navigator in an inconsistent state.
|
||||
// Flip AccountBloc state only after the dialog fully closes: doing it from
|
||||
// inside removeData (the previous approach) raced AsyncDialogAction's
|
||||
// pop(true) against the listener's popUntil(isFirst) and could leave the
|
||||
// navigator in an inconsistent state.
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (dialogContext) => ConfirmDialog(
|
||||
|
||||
@@ -114,12 +114,8 @@ class _ChatTextfieldState extends State<ChatTextfield> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// Clear the published bar height only after this unmount completes. Setting
|
||||
// the shared notifier synchronously here fires its listener (the download
|
||||
// tray's AnimatedBuilder → setState) while the element tree is locked during
|
||||
// teardown, throwing "setState() called when widget tree was locked".
|
||||
// Running it at the end of the frame lets the reset land once the tree is
|
||||
// writable again; a newly opened chat re-publishes its own height afterwards.
|
||||
// Defer to end-of-frame: resetting the shared notifier synchronously during
|
||||
// teardown fires setState while the tree is locked ("widget tree was locked").
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => downloadChipBottomObstruction.value = 0,
|
||||
);
|
||||
|
||||
@@ -281,11 +281,8 @@ class _CustomEventEditDialogState extends State<CustomEventEditDialog> {
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
// The RRuleGenerator widget has zero outer padding while every
|
||||
// surrounding ListTile uses the default 16px horizontal indent.
|
||||
// Wrap it to match — keeps the rule editor visually aligned with
|
||||
// the date/time/color rows above instead of hugging the dialog
|
||||
// border.
|
||||
// RRuleGenerator has zero outer padding; wrap it in the ListTile
|
||||
// default 16px indent so it aligns with the rows above.
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
child: RRuleGenerator(
|
||||
@@ -309,12 +306,9 @@ class _CustomEventEditDialogState extends State<CustomEventEditDialog> {
|
||||
],
|
||||
);
|
||||
|
||||
/// Maps the rrule_generator widget onto Marianum's Material theme so its
|
||||
/// pickers blend in with the rest of the form (the package's defaults
|
||||
/// have an out-of-place red switch outline and bold ALL-CAPS-feeling
|
||||
/// headers). Layout itself stays as the package provides — fully custom
|
||||
/// styling beyond what `RRuleGeneratorConfig` exposes isn't possible
|
||||
/// without forking it.
|
||||
/// Maps the rrule_generator widget onto the app's Material theme so its
|
||||
/// pickers blend in. Styling is limited to what `RRuleGeneratorConfig`
|
||||
/// exposes — fully custom styling isn't possible without forking it.
|
||||
RRuleGeneratorConfig _rruleConfig(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final cs = theme.colorScheme;
|
||||
|
||||
Reference in New Issue
Block a user