[FOSSOVERFLOW-26] UI skeleton for user has been added#2
[FOSSOVERFLOW-26] UI skeleton for user has been added#2Sri-Varshith wants to merge 12 commits intoOpenLake:mainfrom
Conversation
Merge pull request #1 from Sri-Varshith/main
WalkthroughThis PR introduces five new feature pages (AI chat, articles, mood tracker, stress check) with supporting widgets, integrates them into the homepage with navigation and Firestore-based user data streaming, and applies minor UI refinements. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
🤖 Fix all issues with AI agents
In `@flutter_app/lib/pages/ai_chat.dart`:
- Around line 91-111: The TextField currently sets maxLines: null so onSubmitted
will never fire; update the input handling for _messageController to call
_sendMessage on enter by either (A) making it single-line (set maxLines: 1 and
keep onSubmitted: (_) => _sendMessage()) or (B) keep multiline and wrap the
TextField in a RawKeyboardListener (or use onKey) to detect Enter (without
Shift) and call _sendMessage, ensuring you reference the existing _sendMessage
callback and _messageController when implementing the keyboard listener and
maintain multiline behavior and focus handling.
- Around line 36-43: The delayed callback uses setState to add to _messages
without ensuring the State is still mounted, causing setState() called after
dispose(); update the Future.delayed callback (the closure that currently calls
setState and modifies _messages) to first check mounted and only call setState
when mounted (or alternatively store the Timer/Future and cancel it in dispose),
ensuring no state mutation occurs after dispose.
- Around line 15-19: Remove the hardcoded test entries currently assigned to the
_messages list in ai_chat.dart; replace the placeholder initialization with an
empty list (or with logic to load persisted/history messages) so no debug texts
("message from ai", "message from user", etc.) are shown to end users on page
open, and update any code that assumes initial entries (e.g., UI rendering or
indices) to handle an empty _messages safely.
In `@flutter_app/lib/pages/article_page.dart`:
- Around line 64-70: The ArticleCard instance uses gibberish in the subtitle
field; replace the placeholder string ("Learn how anjdjaoijsaoidjoidjoi njkfkj")
with a meaningful user-facing subtitle (e.g., a concise summary like "Practical
strategies to manage anxiety in everyday situations") by updating the
ArticleCard construction in article_page.dart (look for the ArticleCard with
imagePath 'assets/images/music.jpg' and title "Understanding Anxiety in Daily
Life") so the subtitle is clear and readable for users.
- Around line 117-126: The unselected chip text uses Colors.white which is
unreadable on light backgrounds; update the Text color decision in the widget
that renders categories[index] (the Text with style using isSelected) to use a
high-contrast, theme-aware color instead of hardcoded white — for example use
Theme.of(context).colorScheme.onSurface (or
Theme.of(context).textTheme.bodyText1?.color) or fall back to Colors.black when
isSelected is false so the unselected label remains readable against
Colors.grey.withOpacity(0.15).
In `@flutter_app/lib/pages/homepage.dart`:
- Around line 54-67: The StreamBuilder<DocumentSnapshot> is unsafe: avoid
force-unwrapping FirebaseAuth.instance.currentUser!.uid by early-bailing when
currentUser is null (e.g., return a logged-out placeholder or SizedBox), add a
snapshot.hasError branch to show an error widget/message instead of the spinner,
and check snapshot.data!.exists (or snapshot.data?.exists) before accessing
fields so reading data['name'] won't throw; update the builder to handle
currentUser null, snapshot.hasError, !snapshot.hasData, and
!snapshot.data.exists and then safely read name from snapshot.data.
- Around line 86-93: The Text widget displaying the user's name in the
DrawerHeader (the Text with variable name and TextStyle fontSize: 44) can
overflow; wrap that Text in a Flexible or Expanded widget and set its Text
overflow property (overflow: TextOverflow.ellipsis) and maxLines: 1 to prevent
RenderFlex overflow for long names; update the widget tree around the Text
(inside the Row in homepage.dart) to use Flexible/Expanded and add
overflow/maxLines to the Text.
- Around line 29-30: The SafeArea wrapping the Scaffold causes an unnecessary
gap above the AppBar; move or remove that SafeArea so Scaffold is the root
widget in build (keep SafeArea only inside the Scaffold.body if you need to
protect content). Edit the widget returned by build (the HomePage/Homepage build
method) to remove the outer SafeArea and, if needed, wrap only the body content
in SafeArea so AppBar retains normal status-bar behavior.
- Around line 179-191: The subtitle string in the FeatureCard causes a syntax
error because the ASCII single quote in "you're" terminates the single-quoted
string; update the subtitle in the FeatureCard (the subtitle argument passed
when creating FeatureCard) to use a double-quoted string (or escape the
apostrophe) so it becomes valid Dart string syntax; verify the surrounding
Navigator.of(context).push and MoodTrackerPage usage remains unchanged.
In `@flutter_app/lib/pages/stress_check_page.dart`:
- Line 13: Change the default selection to a sentinel value instead of
pre-selecting option 1: set selectedOption to -1 (symbol: selectedOption) and
update the UI logic that controls the "Next" button to be disabled unless
selectedOption >= 0; also ensure any code paths that read selectedOption handle
the sentinel (e.g., show no selection state and prevent progressing until a real
option is chosen).
In `@flutter_app/lib/widgets/article_card.dart`:
- Around line 19-82: The card is overflowing because the SizedBox height (250)
is too small for the Image.asset height (180) plus the padded text block; update
the layout in ArticleCard: either increase the outer SizedBox height (e.g., to
~300) or reduce the Image.asset height (e.g., to ~140) and/or reduce Padding
(from 16 to 12) so that Image.asset, Padding, and text (title/subtitle) fit
within the total height; adjust the constants referenced (SizedBox height,
Image.asset height, Padding) and verify no RenderFlex overflow occurs at
runtime.
🧹 Nitpick comments (6)
flutter_app/lib/pages/ai_chat.dart (1)
92-98: Hardcoded colors reduce theme adaptability.
TextStyle(color: Colors.black)on both the input text and hint won't work well with a dark theme. Prefer usingTheme.of(context).colorSchemeor omit to inherit from the theme.flutter_app/lib/widgets/article_card.dart (1)
24-24:withOpacitycreates a newColoreach build — preferconst Color.fromRGBOor theme tokens.Minor performance nit;
Colors.black.withOpacity(0.2)allocates a new object on every rebuild.flutter_app/lib/pages/stress_check_page.dart (1)
36-67: Extract repeatedonChangedcallback to reduce duplication.All four
StyledRadioTilewidgets share an identicalonChangedhandler. Consider extracting it.♻️ Suggested refactor
Define once in the state class:
void _onOptionChanged(int? value) { if (value != null) setState(() => selectedOption = value); }Then use
onChanged: _onOptionChangedon each tile, which also avoids the force-unwrapvalue!.flutter_app/lib/pages/mood_tracker.dart (1)
130-224: Consider extracting the repeated section container decoration into a helper.The same
BoxDecorationwith rounded corners and grey border is used for all four sections. A small helper widget or method would reduce duplication and make styling changes easier.flutter_app/lib/pages/homepage.dart (2)
141-168: Duplicate Firestore stream and same null-safety issues as the Drawer.This
StreamBuilderopens a second real-time listener to the exact sameusers/{uid}document already streamed in the Drawer (Line 54). It also repeats thecurrentUser!force-unwrap, missinghasError, and missingdata.existsproblems.Consider extracting a single
StreamProvider(you already have Riverpod) or hoisting the stream to thebuildmethod once and sharing it:final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) { // redirect to login or show unauthenticated state } final userStream = FirebaseFirestore.instance .collection('users').doc(uid).snapshots();Then pass
userStreamto bothStreamBuilders — or better, use a RiverpodStreamProviderso the data is shared across the widget tree.
170-229: Inconsistent navigation call style and minor cleanup.Navigation is invoked two different ways across the cards:
Navigator.of(context).push(...)(Lines 185, 221, 241)Navigator.push(context, ...)(Line 207)Both work, but pick one style for consistency. Also, Line 192 has a commented-out
SizedBoxthat can be removed.
| final List<Map<String, dynamic>> _messages = [ | ||
| {"text": "message from ai", "isUser": false}, | ||
| {"text": "message from user", "isUser": true}, | ||
| {"text": "message from ai but this is longer to check ui wrapping properly", "isUser": false}, | ||
| ]; |
There was a problem hiding this comment.
Remove hardcoded test messages before merging.
The initial _messages list contains debug placeholder strings ("message from ai", "message from user", etc.) that will appear to end users on every page open.
- final List<Map<String, dynamic>> _messages = [
- {"text": "message from ai", "isUser": false},
- {"text": "message from user", "isUser": true},
- {"text": "message from ai but this is longer to check ui wrapping properly", "isUser": false},
- ];
+ final List<Map<String, dynamic>> _messages = [];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| final List<Map<String, dynamic>> _messages = [ | |
| {"text": "message from ai", "isUser": false}, | |
| {"text": "message from user", "isUser": true}, | |
| {"text": "message from ai but this is longer to check ui wrapping properly", "isUser": false}, | |
| ]; | |
| final List<Map<String, dynamic>> _messages = []; |
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/ai_chat.dart` around lines 15 - 19, Remove the
hardcoded test entries currently assigned to the _messages list in ai_chat.dart;
replace the placeholder initialization with an empty list (or with logic to load
persisted/history messages) so no debug texts ("message from ai", "message from
user", etc.) are shown to end users on page open, and update any code that
assumes initial entries (e.g., UI rendering or indices) to handle an empty
_messages safely.
| Future.delayed(const Duration(milliseconds: 600), () { | ||
| setState(() { | ||
| _messages.add({ | ||
| "text": "AI response placeholder", | ||
| "isUser": false, | ||
| }); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
setState called after dispose — will crash if user navigates away within 600ms.
The Future.delayed callback invokes setState without checking whether the widget is still mounted. If the user pops this page before the delay completes, this throws a setState() called after dispose() exception.
🐛 Proposed fix
Future.delayed(const Duration(milliseconds: 600), () {
+ if (!mounted) return;
setState(() {
_messages.add({
"text": "AI response placeholder",
"isUser": false,
});
});
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Future.delayed(const Duration(milliseconds: 600), () { | |
| setState(() { | |
| _messages.add({ | |
| "text": "AI response placeholder", | |
| "isUser": false, | |
| }); | |
| }); | |
| }); | |
| Future.delayed(const Duration(milliseconds: 600), () { | |
| if (!mounted) return; | |
| setState(() { | |
| _messages.add({ | |
| "text": "AI response placeholder", | |
| "isUser": false, | |
| }); | |
| }); | |
| }); |
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/ai_chat.dart` around lines 36 - 43, The delayed
callback uses setState to add to _messages without ensuring the State is still
mounted, causing setState() called after dispose(); update the Future.delayed
callback (the closure that currently calls setState and modifies _messages) to
first check mounted and only call setState when mounted (or alternatively store
the Timer/Future and cancel it in dispose), ensuring no state mutation occurs
after dispose.
| child: TextField( | ||
| style: TextStyle(color: Colors.black), | ||
| controller: _messageController, | ||
| maxLines: null, | ||
| textCapitalization: TextCapitalization.sentences, | ||
| decoration: InputDecoration( | ||
| hintText: "Type your message...", | ||
| hintStyle: TextStyle(color: Colors.black), | ||
| contentPadding: const EdgeInsets.symmetric( | ||
| horizontal: 16, | ||
| vertical: 12, | ||
| ), | ||
| border: OutlineInputBorder( | ||
| borderRadius: BorderRadius.circular(24), | ||
| borderSide: BorderSide.none, | ||
| ), | ||
| filled: true, | ||
| fillColor: Colors.grey.shade200, | ||
| ), | ||
| onSubmitted: (_) => _sendMessage(), | ||
| ), |
There was a problem hiding this comment.
onSubmitted will never fire when maxLines: null.
In Flutter, onSubmitted is only triggered for single-line TextFields. With maxLines: null, pressing Enter inserts a newline instead of calling _sendMessage. Either cap maxLines to 1 (losing multiline input) or use a keyboard action approach / send-on-enter detection via onKey or a RawKeyboardListener.
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/ai_chat.dart` around lines 91 - 111, The TextField
currently sets maxLines: null so onSubmitted will never fire; update the input
handling for _messageController to call _sendMessage on enter by either (A)
making it single-line (set maxLines: 1 and keep onSubmitted: (_) =>
_sendMessage()) or (B) keep multiline and wrap the TextField in a
RawKeyboardListener (or use onKey) to detect Enter (without Shift) and call
_sendMessage, ensuring you reference the existing _sendMessage callback and
_messageController when implementing the keyboard listener and maintain
multiline behavior and focus handling.
| return ArticleCard( | ||
| imagePath: 'assets/images/music.jpg', | ||
| title: "Understanding Anxiety in Daily Life", | ||
| subtitle: | ||
| "Learn how anjdjaoijsaoidjoidjoi njkfkj", | ||
| onTap: () {}, | ||
| ); |
There was a problem hiding this comment.
Placeholder gibberish in subtitle — clean up before merging.
"Learn how anjdjaoijsaoidjoidjoi njkfkj" appears to be debug filler text that will be visible to users.
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/article_page.dart` around lines 64 - 70, The
ArticleCard instance uses gibberish in the subtitle field; replace the
placeholder string ("Learn how anjdjaoijsaoidjoidjoi njkfkj") with a meaningful
user-facing subtitle (e.g., a concise summary like "Practical strategies to
manage anxiety in everyday situations") by updating the ArticleCard construction
in article_page.dart (look for the ArticleCard with imagePath
'assets/images/music.jpg' and title "Understanding Anxiety in Daily Life") so
the subtitle is clear and readable for users.
| child: Text( | ||
| categories[index], | ||
| style: TextStyle( | ||
| color: isSelected | ||
| ? Colors.black | ||
| : Colors.white, | ||
| fontWeight: FontWeight.bold, | ||
| fontSize: 14 | ||
| ), | ||
| ), |
There was a problem hiding this comment.
Unselected chip text color Colors.white is invisible on light backgrounds.
When isSelected is false, the background is nearly transparent grey (Colors.grey.withOpacity(0.15)) but the text is white. On a light theme this will be unreadable.
🐛 Proposed fix
child: Text(
categories[index],
style: TextStyle(
color: isSelected
? Colors.black
- : Colors.white,
+ : Colors.grey.shade800,
fontWeight: FontWeight.bold,
fontSize: 14
),
),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| child: Text( | |
| categories[index], | |
| style: TextStyle( | |
| color: isSelected | |
| ? Colors.black | |
| : Colors.white, | |
| fontWeight: FontWeight.bold, | |
| fontSize: 14 | |
| ), | |
| ), | |
| child: Text( | |
| categories[index], | |
| style: TextStyle( | |
| color: isSelected | |
| ? Colors.black | |
| : Colors.grey.shade800, | |
| fontWeight: FontWeight.bold, | |
| fontSize: 14 | |
| ), | |
| ), |
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/article_page.dart` around lines 117 - 126, The
unselected chip text uses Colors.white which is unreadable on light backgrounds;
update the Text color decision in the widget that renders categories[index] (the
Text with style using isSelected) to use a high-contrast, theme-aware color
instead of hardcoded white — for example use
Theme.of(context).colorScheme.onSurface (or
Theme.of(context).textTheme.bodyText1?.color) or fall back to Colors.black when
isSelected is false so the unselected label remains readable against
Colors.grey.withOpacity(0.15).
| child: StreamBuilder<DocumentSnapshot>( | ||
| stream: FirebaseFirestore.instance | ||
| .collection('users') | ||
| .doc(FirebaseAuth.instance.currentUser!.uid) | ||
| .snapshots(), | ||
| builder: (context, snapshot) { | ||
| if (!snapshot.hasData) { | ||
| return const Center( | ||
| child: CircularProgressIndicator(color: Colors.white), | ||
| ); | ||
| } | ||
|
|
||
| final data = snapshot.data!; | ||
| final name = data['name'] ?? 'User'; |
There was a problem hiding this comment.
Null-safety and error handling gaps in the Drawer's StreamBuilder.
Three issues in this block:
- Force-unwrap on
currentUser(Line 57): If the user signs out (or auth state is briefly null),currentUser!.uidwill throw at runtime. Guard with a null check or bail out early. - No
snapshot.hasErrorbranch (Line 60): If the Firestore stream errors, the widget stays on the loading spinner forever. Handle errors explicitly. - No
data.existscheck (Lines 66-67): If the user's document is missing,data['name']on a non-existentDocumentSnapshotthrows aStateError.
Proposed fix
child: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
- .doc(FirebaseAuth.instance.currentUser!.uid)
+ .doc(FirebaseAuth.instance.currentUser?.uid)
.snapshots(),
builder: (context, snapshot) {
+ if (snapshot.hasError) {
+ return const Center(
+ child: Text('Error loading profile',
+ style: TextStyle(color: Colors.white)),
+ );
+ }
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(color: Colors.white),
);
}
final data = snapshot.data!;
- final name = data['name'] ?? 'User';
+ final name = data.exists ? (data['name'] ?? 'User') : 'User';🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/homepage.dart` around lines 54 - 67, The
StreamBuilder<DocumentSnapshot> is unsafe: avoid force-unwrapping
FirebaseAuth.instance.currentUser!.uid by early-bailing when currentUser is null
(e.g., return a logged-out placeholder or SizedBox), add a snapshot.hasError
branch to show an error widget/message instead of the spinner, and check
snapshot.data!.exists (or snapshot.data?.exists) before accessing fields so
reading data['name'] won't throw; update the builder to handle currentUser null,
snapshot.hasError, !snapshot.hasData, and !snapshot.data.exists and then safely
read name from snapshot.data.
| Text( | ||
| name, | ||
| style: const TextStyle( | ||
| color: Colors.black, | ||
| fontSize: 44, | ||
| fontWeight: FontWeight.bold | ||
| ), | ||
| ), |
There was a problem hiding this comment.
Name text can overflow the DrawerHeader for longer names.
fontSize: 44 in a Row with no overflow handling will cause a RenderFlex overflow for users with longer names. Wrap the Text in Flexible or Expanded and add overflow: TextOverflow.ellipsis.
Proposed fix
const SizedBox(width: 12),
- Text(
- name,
- style: const TextStyle(
- color: Colors.black,
- fontSize: 44,
- fontWeight: FontWeight.bold
+ Flexible(
+ child: Text(
+ name,
+ overflow: TextOverflow.ellipsis,
+ style: const TextStyle(
+ color: Colors.black,
+ fontSize: 30,
+ fontWeight: FontWeight.bold,
+ ),
),
),🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/homepage.dart` around lines 86 - 93, The Text widget
displaying the user's name in the DrawerHeader (the Text with variable name and
TextStyle fontSize: 44) can overflow; wrap that Text in a Flexible or Expanded
widget and set its Text overflow property (overflow: TextOverflow.ellipsis) and
maxLines: 1 to prevent RenderFlex overflow for long names; update the widget
tree around the Text (inside the Row in homepage.dart) to use Flexible/Expanded
and add overflow/maxLines to the Text.
| FeatureCard( | ||
| imagePath: "assets/images/mood.jpg", | ||
| title: 'Track your mood', | ||
| subtitle: 'Log how you’re feeling today', | ||
| onTap: () { | ||
| // navigate to mood tracker page | ||
| Navigator.of(context).push( | ||
| MaterialPageRoute( | ||
| builder: (context) => const MoodTrackerPage(), | ||
| ), | ||
| ], | ||
| ); | ||
| ); | ||
| }, | ||
| ), |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Locate the file and examine line 182
if [ -f "flutter_app/lib/pages/homepage.dart" ]; then
echo "=== File found ==="
# Extract line 182 and show both readable and hex output
echo "=== Line 182 (readable) ==="
sed -n '182p' flutter_app/lib/pages/homepage.dart
echo ""
echo "=== Line 182 (hex dump) ==="
sed -n '182p' flutter_app/lib/pages/homepage.dart | od -An -tx1 -c | head -20
else
echo "File not found at flutter_app/lib/pages/homepage.dart"
echo "Searching for homepage.dart..."
find . -name "homepage.dart" -type f 2>/dev/null
fiRepository: OpenLake/GetWelPlus
Length of output: 255
🏁 Script executed:
#!/bin/bash
python3 << 'EOF'
# Read line 182 and inspect the apostrophe
with open('flutter_app/lib/pages/homepage.dart', 'r', encoding='utf-8') as f:
lines = f.readlines()
if len(lines) >= 182:
line_182 = lines[181] # 0-indexed
print("Line 182:", repr(line_182))
print("\nSearching for apostrophe characters:")
for i, char in enumerate(line_182):
if char in ["'", "'", "'"]: # ASCII single quote, right single quotation mark, left
code_point = ord(char)
byte_repr = char.encode('utf-8').hex()
print(f"Position {i}: '{char}' | Unicode: U+{code_point:04X} | UTF-8 bytes: {byte_repr}")
EOFRepository: OpenLake/GetWelPlus
Length of output: 278
Syntax error: unescaped apostrophe terminates string prematurely.
Line 182: 'Log how you're feeling today' — the apostrophe in "you're" is an ASCII single quote that terminates the string, leaving re feeling today as invalid syntax. Use double quotes instead:
Fix
- subtitle: 'Log how you're feeling today',
+ subtitle: "Log how you're feeling today",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| FeatureCard( | |
| imagePath: "assets/images/mood.jpg", | |
| title: 'Track your mood', | |
| subtitle: 'Log how you’re feeling today', | |
| onTap: () { | |
| // navigate to mood tracker page | |
| Navigator.of(context).push( | |
| MaterialPageRoute( | |
| builder: (context) => const MoodTrackerPage(), | |
| ), | |
| ], | |
| ); | |
| ); | |
| }, | |
| ), | |
| FeatureCard( | |
| imagePath: "assets/images/mood.jpg", | |
| title: 'Track your mood', | |
| subtitle: "Log how you're feeling today", | |
| onTap: () { | |
| // navigate to mood tracker page | |
| Navigator.of(context).push( | |
| MaterialPageRoute( | |
| builder: (context) => const MoodTrackerPage(), | |
| ), | |
| ); | |
| }, | |
| ), |
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/homepage.dart` around lines 179 - 191, The subtitle
string in the FeatureCard causes a syntax error because the ASCII single quote
in "you're" terminates the single-quoted string; update the subtitle in the
FeatureCard (the subtitle argument passed when creating FeatureCard) to use a
double-quoted string (or escape the apostrophe) so it becomes valid Dart string
syntax; verify the surrounding Navigator.of(context).push and MoodTrackerPage
usage remains unchanged.
| } | ||
|
|
||
| class _StressCheckPageState extends State<StressCheckPage> { | ||
| int selectedOption=0; |
There was a problem hiding this comment.
Default selection biases the questionnaire response.
selectedOption = 0 pre-selects "Option 1" when the page loads. For a stress-check questionnaire, this can bias responses. Consider using a sentinel value (e.g., -1) and disabling the "Next" button until an explicit selection is made.
♻️ Suggested approach
- int selectedOption=0;
+ int selectedOption = -1;Then conditionally enable the "Next" button based on selectedOption >= 0.
🤖 Prompt for AI Agents
In `@flutter_app/lib/pages/stress_check_page.dart` at line 13, Change the default
selection to a sentinel value instead of pre-selecting option 1: set
selectedOption to -1 (symbol: selectedOption) and update the UI logic that
controls the "Next" button to be disabled unless selectedOption >= 0; also
ensure any code paths that read selectedOption handle the sentinel (e.g., show
no selection state and prevent progressing until a real option is chosen).
| return SizedBox( | ||
| height: 250, | ||
| width: 250, | ||
| child: Card( | ||
| elevation: 4, | ||
| shadowColor: Colors.black.withOpacity(0.2), | ||
| shape: RoundedRectangleBorder( | ||
| borderRadius: BorderRadius.circular(20), | ||
| ), | ||
| child: InkWell( | ||
| borderRadius: BorderRadius.circular(20), | ||
| onTap: onTap, | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
|
|
||
| /// 🖼 Image on Top | ||
| ClipRRect( | ||
| borderRadius: const BorderRadius.vertical( | ||
| top: Radius.circular(20), | ||
| ), | ||
| child: Image.asset( | ||
| imagePath, | ||
| width: 250, | ||
| height: 180, | ||
| fit: BoxFit.cover, | ||
| ), | ||
| ), | ||
|
|
||
| /// Text Section | ||
| Padding( | ||
| padding: const EdgeInsets.all(16), | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
|
|
||
| /// Title (1 line only) | ||
| Text( | ||
| title, | ||
| maxLines: 1, | ||
| overflow: TextOverflow.ellipsis, | ||
| style: Theme.of(context) | ||
| .textTheme | ||
| .titleMedium | ||
| ?.copyWith(fontWeight: FontWeight.w600), | ||
| ), | ||
|
|
||
| const SizedBox(height: 8), | ||
|
|
||
| // / Description (2 lines max) | ||
| Text( | ||
| subtitle, | ||
| maxLines: 2, | ||
| overflow: TextOverflow.ellipsis, | ||
| style: Theme.of(context).textTheme.bodySmall, | ||
| ), | ||
| ], | ||
| ), | ||
| ), | ||
| ], | ||
| ), | ||
| ), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Likely RenderFlex overflow — content exceeds the 250px height constraint.
The image is 180px tall, and the text section with 16px padding on all sides plus title and subtitle text will exceed the remaining 70px. This will produce the yellow-black overflow stripe in Flutter. Either increase the SizedBox height or reduce the image height/padding.
🐛 Proposed fix (increase card height)
return SizedBox(
- height: 250,
+ height: 300,
width: 250,🤖 Prompt for AI Agents
In `@flutter_app/lib/widgets/article_card.dart` around lines 19 - 82, The card is
overflowing because the SizedBox height (250) is too small for the Image.asset
height (180) plus the padded text block; update the layout in ArticleCard:
either increase the outer SizedBox height (e.g., to ~300) or reduce the
Image.asset height (e.g., to ~140) and/or reduce Padding (from 16 to 12) so that
Image.asset, Padding, and text (title/subtitle) fit within the total height;
adjust the constants referenced (SizedBox height, Image.asset height, Padding)
and verify no RenderFlex overflow occurs at runtime.
The following changes have been done:
Summary by CodeRabbit