From 487c0418e301988e4807a3b541ae9254e548a05f Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Sat, 7 Mar 2026 00:44:02 +0530 Subject: [PATCH 1/2] feat: Indicate which button has been pressed #23 - Added optional textColor parameter to AppButton. - Session type initialized to none, reset on completion. - Active mode label (Start/Intro/Guided) turns blue when pressed, reverts to default when session ends. --- lib/widgets/app_button.dart | 16 +++++++++++----- lib/widgets/timer.dart | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/widgets/app_button.dart b/lib/widgets/app_button.dart index 70942af..52626ca 100644 --- a/lib/widgets/app_button.dart +++ b/lib/widgets/app_button.dart @@ -40,6 +40,7 @@ class AppButton extends StatelessWidget { this.backgroundColor = Colors.white, this.fontSize = 20, this.fontWeight = FontWeight.normal, + this.textColor, }); /// The text to be displayed on the button. @@ -67,6 +68,10 @@ class AppButton extends StatelessWidget { final FontWeight fontWeight; + /// The colour of the label text. + + final Color? textColor; + @override Widget build(BuildContext context) { bool isPrimary = backgroundColor != Colors.white; @@ -113,11 +118,12 @@ class AppButton extends StatelessWidget { style: TextStyle( fontSize: fontSize, fontWeight: isPrimary ? FontWeight.bold : fontWeight, - color: isPrimary - ? (Theme.of(context).brightness == Brightness.dark - ? Colors.white - : Colors.black87) - : const Color(0xFF5D4037), + color: textColor ?? + (isPrimary + ? (Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black87) + : const Color(0xFF5D4037)), letterSpacing: 0.5, ), ), diff --git a/lib/widgets/timer.dart b/lib/widgets/timer.dart index e183fad..c430466 100644 --- a/lib/widgets/timer.dart +++ b/lib/widgets/timer.dart @@ -88,7 +88,7 @@ class TimerState extends State { // Track the session type. - String _sessionType = 'bell'; + String _sessionType = 'none'; //////////////////////////////////////////////////////////////////////// // CONSTANTS @@ -175,6 +175,7 @@ class TimerState extends State { _controller.pause(); _isGuided = false; _isPaused = false; + _sessionType = 'none'; } //////////////////////////////////////////////////////////////////////// @@ -262,6 +263,8 @@ class TimerState extends State { logMessage('Session Completed'); + final typeToSave = _sessionType; + // Only play audio and wait if still mounted if (mounted) { await _play(dong); @@ -296,17 +299,17 @@ class TimerState extends State { // Always attempt to save the session, even if navigate away // _saveSession handles its own internal null checks - await _saveSession(); + await _saveSession(typeOverride: typeToSave); } - Future _saveSession() async { + Future _saveSession({String? typeOverride}) async { if (_startTime == null) return; final endTime = DateTime.now(); final session = { 'start': _startTime!.toIso8601String(), 'end': endTime.toIso8601String(), - 'type': _sessionType, + 'type': typeOverride ?? _sessionType, 'silenceDuration': _duration, 'title': _titleController.text, 'description': _descriptionController.text, @@ -335,7 +338,7 @@ class TimerState extends State { await getKeyFromUserIfRequired(context, widget); if (mounted) { // Retry saving session after popup closes - await _saveSession(); + await _saveSession(typeOverride: typeOverride); } } } catch (e) { @@ -387,6 +390,7 @@ circle indicates an active session. }, fontWeight: FontWeight.bold, backgroundColor: Colors.lightGreenAccent.shade100, + textColor: _sessionType == 'bell' ? Colors.blue : null, ); final pauseResumeButton = AppButton( @@ -437,6 +441,7 @@ three dings. The blue progress circle indicates an active session. onPressed: _intro, fontWeight: FontWeight.bold, backgroundColor: Colors.blue.shade100, + textColor: _sessionType == 'intro' ? Colors.blue : null, ); final guidedButton = AppButton( @@ -455,6 +460,7 @@ audio may take a little time to download for the Web version. onPressed: _guided, fontWeight: FontWeight.bold, backgroundColor: Colors.purple.shade100, + textColor: _sessionType == 'guided' ? Colors.blue : null, ); //////////////////////////////////// From 2a205a9bf21d525b99f33c3d02d3f4ddd7c958b8 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Wed, 25 Mar 2026 15:14:26 +0530 Subject: [PATCH 2/2] feat: add explicit login/logout and key buttons in app bar (#75) --- lib/home.dart | 40 ++++++++++++++++++++++++++++++++++++++++ pr_description_75.md | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 pr_description_75.md diff --git a/lib/home.dart b/lib/home.dart index 543e4d1..5adf560 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -29,6 +29,9 @@ import 'package:flutter/material.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:solidui/solidui.dart'; +import 'package:solidpod/solidpod.dart'; + + import 'package:url_launcher/url_launcher.dart'; import 'package:innerpod/constants/colours.dart'; @@ -162,6 +165,43 @@ class HomeState extends State { ), backgroundColor: border, actions: [ + FutureBuilder( + future: isUserLoggedIn(), + builder: (context, snapshot) { + final isLoggedIn = snapshot.data ?? false; + if (isLoggedIn) { + return IconButton( + icon: const Icon(Icons.logout, size: 24), + onPressed: () => logoutPopup(context, const InnerPod()), + tooltip: 'Logout', + ); + } else { + return IconButton( + icon: const Icon(Icons.login, size: 24), + onPressed: () => showDialog( + context: context, + builder: (context) => const SolidPopupLogin(), + ), + tooltip: 'Login', + ); + } + }, + ), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.key, size: 24), + onPressed: () => showDialog( + context: context, + builder: (context) => SolidSecurityKeyManager( + config: SolidSecurityKeyManagerConfig( + appWidget: widget, + ), + onKeyStatusChanged: (status) {}, + ), + ), + tooltip: 'Security Key', + ), + const SizedBox(width: 8), Center( child: GestureDetector( onTap: () async { diff --git a/pr_description_75.md b/pr_description_75.md new file mode 100644 index 0000000..82b502c --- /dev/null +++ b/pr_description_75.md @@ -0,0 +1,41 @@ +## Pull Request Details + +### Title +feat: add explicit login/logout and key buttons in app bar (#75) + +### Description +This PR addresses issue #75 by replacing the `SolidDynamicAuthButton` in the main app bar with dedicated, explicit buttons for user authentication and security key management. + +#### Key Enhancements: +- **Authentication Toggle**: Replaced the dynamic button with conditional `IconButton`s: + - `Icons.login` appears when the user is not authenticated. + - `Icons.logout` appears when the user is logged into their Solid server. +- **Reactive State Management**: Implemented a `FutureBuilder` to efficiently handle the asynchronous check of `isUserLoggedIn()`, ensuring the UI reflects the current session status immediately. +- **Key Management**: Added a persistent `Icons.key` button in the AppBar actions. This button triggers the `SolidSecurityKeyManager` popup, allowing users to view or change their pod encryption keys easily. +- **Improved UX**: Integrated `SolidPopupLogin` for a streamlined login experience and `logoutPopup` for a safe logout flow, providing users with clear visual feedback for their session status. + +### Related Issues +Closes #75 + +### Type of Change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [x] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +### How To Test? +1. Open InnerPod. +2. Observe the Login icon button in the AppBar. +3. Tap Login and complete the Solid Auth flow. +4. Verify the icon changes to Logout. +5. Tap the Key icon to verify the Security Key Manager popup appears. +6. Tap Logout to verify the session ends and the icon reverts to Login. + +### Checklist +- [x] Changes adhere to the [style and coding guidelines](https://survivor.togaware.com/gnulinux/flutter-style.html) +- [x] I have performed a self-review of my code +- [x] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [x] No lint check errors are related to these changes (`flutter analyze`) +- [x] All tests passed (`flutter test`) +- [x] Verified on Windows and verified logic consistency for other platforms.