From 037b08ea2143588bf28c0a01b3faee4fbbfc676e Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Mon, 18 May 2026 23:12:52 +1000 Subject: [PATCH 1/4] Fix the note saving bug when not logged in --- lib/common/rest_api/file_helper.dart | 35 ++++++++ lib/widgets/login_required_dialog.dart | 111 +++++++++++++++++++++++++ pubspec.yaml | 18 +++- 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 lib/widgets/login_required_dialog.dart diff --git a/lib/common/rest_api/file_helper.dart b/lib/common/rest_api/file_helper.dart index b04cbc8..6f912f4 100644 --- a/lib/common/rest_api/file_helper.dart +++ b/lib/common/rest_api/file_helper.dart @@ -43,6 +43,7 @@ import 'package:notepod/services/operations.dart'; import 'package:notepod/utils/encryption.dart'; import 'package:notepod/widgets/err_dialogs.dart'; import 'package:notepod/widgets/loading_animation.dart' as loading; +import 'package:notepod/widgets/login_required_dialog.dart'; /// Helper class for note file operations. @@ -299,6 +300,11 @@ class NoteFileHelper with PodOperationsMixin { bool overwrite = false, bool isExternal = false, }) async { + // Tracks whether the `Saving the note!` animation is still on screen + // so we can guarantee it is dismissed exactly once on any code path. + + var loadingDialogShown = true; + try { // Encrypt note text using created time as the key // av: 20250519 - We need to encrypt the note text because @@ -340,16 +346,45 @@ class NoteFileHelper with PodOperationsMixin { Navigator.of(context, rootNavigator: true) .pop(); // Dismiss the saving note dialog + loadingDialogShown = false; scaffoldController.navigateToSubpage(childPage); if (!context.mounted) { throw Exception('Context not found'); } + } on NotLoggedInException catch (e) { + debugPrint( + 'NotLoggedInException (encrypting and saving note):\n $e', + ); + + // Dismiss the in-flight `Saving the note!` animation so the UI + // does not appear to hang while we prompt the user to log in. + + if (loadingDialogShown && context.mounted) { + Navigator.of(context, rootNavigator: true).pop(); + loadingDialogShown = false; + } + + if (!context.mounted) return; + + // Prompt the user to log in (or cancel back to the note editor), + // mirroring the security key cache login prompt in solidui for a + // consistent experience. + + await LoginRequiredDialog.showAndHandle(context); } on Exception catch (e) { debugPrint( 'Exception (encrypting and saving note, and navigating to return page):\n $e', ); + + // Make sure the loading dialog is always dismissed on failure so + // the UI never gets stuck on `Saving the note!`. + + if (loadingDialogShown && context.mounted) { + Navigator.of(context, rootNavigator: true).pop(); + loadingDialogShown = false; + } } } } diff --git a/lib/widgets/login_required_dialog.dart b/lib/widgets/login_required_dialog.dart new file mode 100644 index 0000000..c728449 --- /dev/null +++ b/lib/widgets/login_required_dialog.dart @@ -0,0 +1,111 @@ +/// Login required dialog. +/// +/// Copyright (C) 2026, Software Innovation Institute +/// +/// Licensed under the GNU General Public License, Version 3 (the "License"); +/// +/// License: https://opensource.org/license/gpl-3-0 +// +// Time-stamp: +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +import 'package:solidui/solidui.dart' show SolidAuthHandler; + +/// A dialog informing the user that they must log in to their POD before +/// continuing with the requested action. + +class LoginRequiredDialog { + /// Shows the `Login Required` dialog and returns `true` when the user + /// chooses to log in, or `false` (including dismissals) otherwise. + + static Future show( + BuildContext context, { + String message = 'Please log in to your POD first before saving the note.', + }) async { + final theme = Theme.of(context); + + final shouldLogin = await showDialog( + context: context, + barrierDismissible: false, + builder: (dialogContext) => AlertDialog( + backgroundColor: theme.colorScheme.surface, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + title: Text( + 'Login Required', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: theme.colorScheme.onSurface, + ), + ), + content: Text( + message, + style: TextStyle( + fontSize: 14, + color: theme.colorScheme.onSurfaceVariant, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(false), + child: Text( + 'Cancel', + style: TextStyle( + fontSize: 16, + color: theme.colorScheme.onSurfaceVariant, + ), + ), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: theme.colorScheme.primary, + foregroundColor: theme.colorScheme.onPrimary, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + onPressed: () => Navigator.of(dialogContext).pop(true), + child: const Text('Log In', style: TextStyle(fontSize: 16)), + ), + ], + ), + ); + + return shouldLogin ?? false; + } + + /// Convenience helper that displays the dialog and, when the user opts + /// to log in, delegates to [SolidAuthHandler] to start the standard + /// login flow. If the user cancels nothing further happens, leaving + /// them on the calling screen (e.g. the note editor). + + static Future showAndHandle( + BuildContext context, { + String message = 'Please log in to your POD first before saving the note.', + }) async { + final shouldLogin = await show(context, message: message); + if (shouldLogin && context.mounted) { + await SolidAuthHandler.instance.handleLogin(context); + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 944a03d..98f8b9d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,8 +33,8 @@ dependencies: markdown_widget: ^2.3.2+8 emacs_text_field: ^0.1.0 rdflib: ^0.2.12 - solidpod: ^0.12.5 - solidui: ^0.3.44 + solidpod: ^0.12.6 + solidui: ^0.3.45 universal_io: ^2.2.2 window_manager: ^0.5.1 @@ -43,6 +43,20 @@ dev_dependencies: flutter_launcher_icons: ^0.14.4 flutter_lints: ^6.0.0 +dependency_overrides: + solidui: + git: + url: https://github.com/anusii/solidui.git + ref: tony/630_try_another_webid + solid_auth: + git: + url: https://github.com/anusii/solid_auth.git + ref: tony/630_try_another_webid + solidpod: + git: + url: https://github.com/anusii/solidpod.git + ref: tony/630_try_another_webid + flutter: assets: - assets/images/ From e8f09cd55155e58bb96fffd6f598e65d0f48f584 Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Wed, 20 May 2026 00:46:08 +1000 Subject: [PATCH 2/4] Update the code after migrating Solid login required dialog to SolidUI --- lib/common/rest_api/file_helper.dart | 13 +-- lib/widgets/login_required_dialog.dart | 111 ------------------------- pubspec.yaml | 4 +- 3 files changed, 10 insertions(+), 118 deletions(-) delete mode 100644 lib/widgets/login_required_dialog.dart diff --git a/lib/common/rest_api/file_helper.dart b/lib/common/rest_api/file_helper.dart index 6f912f4..8279527 100644 --- a/lib/common/rest_api/file_helper.dart +++ b/lib/common/rest_api/file_helper.dart @@ -43,7 +43,6 @@ import 'package:notepod/services/operations.dart'; import 'package:notepod/utils/encryption.dart'; import 'package:notepod/widgets/err_dialogs.dart'; import 'package:notepod/widgets/loading_animation.dart' as loading; -import 'package:notepod/widgets/login_required_dialog.dart'; /// Helper class for note file operations. @@ -368,11 +367,15 @@ class NoteFileHelper with PodOperationsMixin { if (!context.mounted) return; - // Prompt the user to log in (or cancel back to the note editor), - // mirroring the security key cache login prompt in solidui for a - // consistent experience. + // Prompt the user to log in (or cancel back to the note editor). + // Using solidui's shared `SolidLoginRequiredDialog` keeps the + // look-and-feel — and the state-preserving login sub-flow — + // consistent with the rest of the Solid app suite. - await LoginRequiredDialog.showAndHandle(context); + await SolidLoginRequiredDialog.showAndHandle( + context, + message: 'Please log in to your POD first before saving the note.', + ); } on Exception catch (e) { debugPrint( 'Exception (encrypting and saving note, and navigating to return page):\n $e', diff --git a/lib/widgets/login_required_dialog.dart b/lib/widgets/login_required_dialog.dart deleted file mode 100644 index c728449..0000000 --- a/lib/widgets/login_required_dialog.dart +++ /dev/null @@ -1,111 +0,0 @@ -/// Login required dialog. -/// -/// Copyright (C) 2026, Software Innovation Institute -/// -/// Licensed under the GNU General Public License, Version 3 (the "License"); -/// -/// License: https://opensource.org/license/gpl-3-0 -// -// Time-stamp: -// -// This program is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or (at your option) any later -// version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along with -// this program. If not, see . -/// -/// Authors: Tony Chen - -library; - -import 'package:flutter/material.dart'; - -import 'package:solidui/solidui.dart' show SolidAuthHandler; - -/// A dialog informing the user that they must log in to their POD before -/// continuing with the requested action. - -class LoginRequiredDialog { - /// Shows the `Login Required` dialog and returns `true` when the user - /// chooses to log in, or `false` (including dismissals) otherwise. - - static Future show( - BuildContext context, { - String message = 'Please log in to your POD first before saving the note.', - }) async { - final theme = Theme.of(context); - - final shouldLogin = await showDialog( - context: context, - barrierDismissible: false, - builder: (dialogContext) => AlertDialog( - backgroundColor: theme.colorScheme.surface, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - title: Text( - 'Login Required', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: theme.colorScheme.onSurface, - ), - ), - content: Text( - message, - style: TextStyle( - fontSize: 14, - color: theme.colorScheme.onSurfaceVariant, - ), - ), - actions: [ - TextButton( - onPressed: () => Navigator.of(dialogContext).pop(false), - child: Text( - 'Cancel', - style: TextStyle( - fontSize: 16, - color: theme.colorScheme.onSurfaceVariant, - ), - ), - ), - ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: theme.colorScheme.primary, - foregroundColor: theme.colorScheme.onPrimary, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - onPressed: () => Navigator.of(dialogContext).pop(true), - child: const Text('Log In', style: TextStyle(fontSize: 16)), - ), - ], - ), - ); - - return shouldLogin ?? false; - } - - /// Convenience helper that displays the dialog and, when the user opts - /// to log in, delegates to [SolidAuthHandler] to start the standard - /// login flow. If the user cancels nothing further happens, leaving - /// them on the calling screen (e.g. the note editor). - - static Future showAndHandle( - BuildContext context, { - String message = 'Please log in to your POD first before saving the note.', - }) async { - final shouldLogin = await show(context, message: message); - if (shouldLogin && context.mounted) { - await SolidAuthHandler.instance.handleLogin(context); - } - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 98f8b9d..4099e4d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,7 +34,7 @@ dependencies: emacs_text_field: ^0.1.0 rdflib: ^0.2.12 solidpod: ^0.12.6 - solidui: ^0.3.45 + solidui: ^0.3.47 universal_io: ^2.2.2 window_manager: ^0.5.1 @@ -47,7 +47,7 @@ dependency_overrides: solidui: git: url: https://github.com/anusii/solidui.git - ref: tony/630_try_another_webid + ref: tony/351_not_logged_in solid_auth: git: url: https://github.com/anusii/solid_auth.git From 98a7d635e83759d822e80d7ce7277f31de58590f Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Wed, 20 May 2026 01:32:13 +1000 Subject: [PATCH 3/4] Show friendly message on notes list page when not logged in --- lib/common/rest_api/file_helper.dart | 4 +- lib/notes/list_my_notes_screen.dart | 45 +++++++++- lib/notes/list_notes_screen.dart | 70 ++++++++++++--- lib/widgets/not_logged_in_card.dart | 123 +++++++++++++++++++++++++++ 4 files changed, 226 insertions(+), 16 deletions(-) create mode 100644 lib/widgets/not_logged_in_card.dart diff --git a/lib/common/rest_api/file_helper.dart b/lib/common/rest_api/file_helper.dart index 8279527..f3c5734 100644 --- a/lib/common/rest_api/file_helper.dart +++ b/lib/common/rest_api/file_helper.dart @@ -369,8 +369,8 @@ class NoteFileHelper with PodOperationsMixin { // Prompt the user to log in (or cancel back to the note editor). // Using solidui's shared `SolidLoginRequiredDialog` keeps the - // look-and-feel — and the state-preserving login sub-flow — - // consistent with the rest of the Solid app suite. + // look-and-feel and the redirect-to-Solid-login-page behaviour + // consistent with the rest of the app. await SolidLoginRequiredDialog.showAndHandle( context, diff --git a/lib/notes/list_my_notes_screen.dart b/lib/notes/list_my_notes_screen.dart index 4b9f048..103e250 100644 --- a/lib/notes/list_my_notes_screen.dart +++ b/lib/notes/list_my_notes_screen.dart @@ -23,6 +23,7 @@ library; import 'package:flutter/material.dart'; +import 'package:solidpod/solidpod.dart' show isUserLoggedIn; import 'package:solidui/solidui.dart'; import 'package:notepod/constants/app.dart'; @@ -34,6 +35,7 @@ import 'package:notepod/notes/new_note.dart'; import 'package:notepod/services/note_service.dart'; import 'package:notepod/widgets/err_card.dart'; import 'package:notepod/widgets/msg_card.dart'; +import 'package:notepod/widgets/not_logged_in_card.dart'; import 'package:notepod/widgets/note_list_del_dialog.dart'; /// A [StatefulWidget] that fetches the user's notes in their app data folder @@ -59,7 +61,12 @@ class _ListMyNotesScreenState extends State { final GlobalKey _scaffoldKey = GlobalKey(); /// Future function to retrieve user's notes list - static Future? _asyncDataFetch; + Future? _asyncDataFetch; + + /// Tracks the user's login status. `null` while the asynchronous + /// check is in flight (used to show the loading screen), then + /// updated by [_checkLoginAndFetch] + bool? _isLoggedIn; /// Scroll controller for single child scroll view late final ScrollController _scrollController; @@ -71,8 +78,24 @@ class _ListMyNotesScreenState extends State { void initState() { super.initState(); _scaffoldController = widget.scaffoldController; - _asyncDataFetch = NoteService().getOwnNoteList(); _scrollController = ScrollController(); + _checkLoginAndFetch(); + } + + /// Confirms the user is logged in before triggering the POD fetch. + /// + /// When the user is not logged in we skip the fetch entirely and let + /// [build] render the [NotLoggedInCard] placeholder. Touching the POD + /// APIs without an authenticated session would otherwise produce a + /// cascade of rendering exceptions on this screen. + + Future _checkLoginAndFetch() async { + final loggedIn = await isUserLoggedIn(); + if (!mounted) return; + setState(() { + _isLoggedIn = loggedIn; + _asyncDataFetch = loggedIn ? NoteService().getOwnNoteList() : null; + }); } @override @@ -150,6 +173,24 @@ class _ListMyNotesScreenState extends State { @override Widget build(BuildContext context) { + // Show the loading screen until the asynchronous login check has + // returned. Once we know the user is logged out, render the + // friendly `Not logged in` placeholder rather than attempting to + // fetch notes from a POD we cannot read. + + if (_isLoggedIn == null) { + return Scaffold( + key: _scaffoldKey, + body: SafeArea(child: loadingScreen(normalLoadingScreenHeight)), + ); + } + if (_isLoggedIn == false) { + return Scaffold( + key: _scaffoldKey, + body: const SafeArea(child: NotLoggedInCard()), + ); + } + return Scaffold( key: _scaffoldKey, body: SafeArea( diff --git a/lib/notes/list_notes_screen.dart b/lib/notes/list_notes_screen.dart index 396b308..373caeb 100644 --- a/lib/notes/list_notes_screen.dart +++ b/lib/notes/list_notes_screen.dart @@ -23,6 +23,7 @@ library; import 'package:flutter/material.dart'; +import 'package:solidpod/solidpod.dart' show isUserLoggedIn; import 'package:solidui/solidui.dart'; import 'package:notepod/common/rest_api/rest_api.dart'; @@ -35,6 +36,7 @@ import 'package:notepod/notes/new_note.dart'; import 'package:notepod/services/note_service.dart'; import 'package:notepod/widgets/err_card.dart'; import 'package:notepod/widgets/msg_card.dart'; +import 'package:notepod/widgets/not_logged_in_card.dart'; import 'package:notepod/widgets/note_list_del_dialog.dart'; import 'package:notepod/widgets/note_list_revoke_dialog.dart'; @@ -60,13 +62,19 @@ class ListNotesScreen extends StatefulWidget { class _ListNotesScreenState extends State { final GlobalKey _scaffoldKey = GlobalKey(); - /// Future function to retrieve user's notes list - // static Future? _fetchOwnNotes; - late Future _fetchOwnNotes; + /// Future function to retrieve user's notes list. Initialised only + /// after we confirm the user is logged in (see [_checkLoginAndFetch]). - /// Future function to retrieve externally owned notes list - // static Future? _fetchExternalNotes; - late Future _fetchExternalNotes; + Future? _fetchOwnNotes; + + /// Future function to retrieve externally owned notes list. + + Future? _fetchExternalNotes; + + /// Tracks the user's login status. `null` while the asynchronous + /// check is in flight, then `true`/`false` once known. + + bool? _isLoggedIn; /// Scroll controller for single child scroll view late final ScrollController _scrollController; @@ -78,12 +86,30 @@ class _ListNotesScreenState extends State { void initState() { super.initState(); _scaffoldController = widget.scaffoldController; - _scrollController = ScrollController(); + _checkLoginAndFetch(); + } + + /// Confirms the user is logged in before triggering the POD fetches. + /// + /// When the user is not logged in we skip the fetches entirely and + /// let [build] render the [NotLoggedInCard] placeholder. This avoids + /// the cascade of layout exceptions that the fallback "no notes" + /// layout otherwise produces on an unauthenticated session. - // Set future functions to fetch owner's notes and external notes - _fetchOwnNotes = NoteService().getOwnNoteList(); - _fetchExternalNotes = getExternalNoteList(); + Future _checkLoginAndFetch() async { + final loggedIn = await isUserLoggedIn(); + if (!mounted) return; + setState(() { + _isLoggedIn = loggedIn; + if (loggedIn) { + _fetchOwnNotes = NoteService().getOwnNoteList(); + _fetchExternalNotes = getExternalNoteList(); + } else { + _fetchOwnNotes = null; + _fetchExternalNotes = null; + } + }); } @override @@ -189,6 +215,26 @@ class _ListNotesScreenState extends State { @override Widget build(BuildContext context) { + // Show the loading screen until the asynchronous login check has + // returned. Once we know the user is logged out, render the + // friendly `Not logged in` placeholder rather than attempting to + // fetch notes from a POD we cannot read. + + if (_isLoggedIn == null) { + return Scaffold( + key: _scaffoldKey, + body: SafeArea(child: loadingScreen(normalLoadingScreenHeight)), + ); + } + if (_isLoggedIn == false || + _fetchOwnNotes == null || + _fetchExternalNotes == null) { + return Scaffold( + key: _scaffoldKey, + body: const SafeArea(child: NotLoggedInCard()), + ); + } + return Scaffold( key: _scaffoldKey, body: SafeArea( @@ -196,9 +242,9 @@ class _ListNotesScreenState extends State { // future: _asyncFetchOwnNotes, future: Future.wait([ // Future result of fetching owner's notes list - _fetchOwnNotes, + _fetchOwnNotes!, // Future result of fetching externally owned notes list - _fetchExternalNotes, + _fetchExternalNotes!, ]), builder: (context, snapshot) { // if (!snapshot.hasData) { diff --git a/lib/widgets/not_logged_in_card.dart b/lib/widgets/not_logged_in_card.dart new file mode 100644 index 0000000..906c0a7 --- /dev/null +++ b/lib/widgets/not_logged_in_card.dart @@ -0,0 +1,123 @@ +/// `Not logged in` placeholder card for notes screens. +/// +/// Copyright (C) 2026, Software Innovation Institute, ANU +/// +/// Licensed under the GNU General Public License, Version 3 (the "License"); +/// +/// License: https://opensource.org/license/gpl-3-0 +// +// Time-stamp: +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +import 'package:solidui/solidui.dart' show SolidLoginRequiredDialog; + +/// A friendly placeholder shown on note list screens when the user is +/// not logged in. +/// +/// Rather than letting the screen try to fetch notes from the POD and +/// fall over with rendering or assertion errors, we present a clear +/// message and a `Log In` button. The button reuses solidui's shared +/// [SolidLoginRequiredDialog], which on confirmation navigates the +/// user back to the app's standard Solid login page. + +class NotLoggedInCard extends StatelessWidget { + /// Message displayed in the body of the card. + + final String message; + + /// Optional default message tailored to the notes listing screens. + + static const String defaultMessage = + 'You need to be logged in to your POD to view and manage your notes.'; + + const NotLoggedInCard({super.key, this.message = defaultMessage}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 480), + child: Card( + elevation: 4, + margin: const EdgeInsets.all(24), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: const EdgeInsets.fromLTRB(24, 28, 24, 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.lock_outline, + size: 56, + color: theme.colorScheme.primary, + ), + const SizedBox(height: 12), + Text( + 'Not logged in', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: theme.colorScheme.onSurface, + ), + ), + const SizedBox(height: 8), + Text( + message, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14, + color: theme.colorScheme.onSurfaceVariant, + ), + ), + const SizedBox(height: 20), + ElevatedButton.icon( + icon: const Icon(Icons.login), + label: const Text('Log In'), + style: ElevatedButton.styleFrom( + backgroundColor: theme.colorScheme.primary, + foregroundColor: theme.colorScheme.onPrimary, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 12, + ), + ), + onPressed: () => SolidLoginRequiredDialog.showAndHandle( + context, + message: + 'Please log in to your POD to view and manage your ' + 'notes.', + ), + ), + ], + ), + ), + ), + ), + ); + } +} From 77f0e09ff643bb09de6b0bf9e50ef860aacdd9de Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Wed, 20 May 2026 16:35:52 +1000 Subject: [PATCH 4/4] Update pubspec.yaml --- pubspec.yaml | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 4099e4d..cf5299b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,8 +33,8 @@ dependencies: markdown_widget: ^2.3.2+8 emacs_text_field: ^0.1.0 rdflib: ^0.2.12 - solidpod: ^0.12.6 - solidui: ^0.3.47 + solidpod: ^0.12.9 + solidui: ^0.3.49 universal_io: ^2.2.2 window_manager: ^0.5.1 @@ -43,20 +43,6 @@ dev_dependencies: flutter_launcher_icons: ^0.14.4 flutter_lints: ^6.0.0 -dependency_overrides: - solidui: - git: - url: https://github.com/anusii/solidui.git - ref: tony/351_not_logged_in - solid_auth: - git: - url: https://github.com/anusii/solid_auth.git - ref: tony/630_try_another_webid - solidpod: - git: - url: https://github.com/anusii/solidpod.git - ref: tony/630_try_another_webid - flutter: assets: - assets/images/