From d08409636310a7a0d6f69e6ffbd53d9187bd10fc Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Sun, 22 Feb 2026 01:06:53 +0530 Subject: [PATCH 1/7] style: foundational premium Apple-inspired design (Fonts, Main Theme, Common Widgets) --- lib/main.dart | 96 ++++++++++++++++++++---------- lib/widgets/app_button.dart | 42 ++++++------- lib/widgets/app_markdown_body.dart | 40 ++++++++++++- pubspec.yaml | 1 + 4 files changed, 121 insertions(+), 58 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 93598a1..97a444a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,60 +27,92 @@ library; import 'package:flutter/material.dart'; -import 'package:innerpod/home.dart'; +import 'package:google_fonts/google_fonts.dart'; -//import 'package:innerpod/timer.dart'; +import 'package:innerpod/home.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); - // Call MaterialApp() here rather than within InnerPod so that - // MaterialLocalizations is found when firing off the showAboutDialog. - runApp( MaterialApp( title: 'Inner Pod', + debugShowCheckedModeBanner: false, theme: ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed( - seedColor: const Color(0xFFF0D1AD), - surface: const Color(0xFFFDF7F0), // Lighter cream surface - primary: const Color(0xFF8B5E3C), // Earthy brown/gold primary - onPrimary: Colors.white, + seedColor: const Color(0xFF8B5E3C), + surface: const Color(0xFFFDFBF9), + primary: const Color(0xFF8B5E3C), secondary: const Color(0xFFE6B276), - surfaceContainerHighest: const Color(0xFFF5E0C8), + tertiary: const Color(0xFFAD8B73), + surfaceContainerHighest: const Color(0xFFF5EADA), ), - appBarTheme: const AppBarTheme( - centerTitle: true, + textTheme: GoogleFonts.outfitTextTheme().copyWith( + displayLarge: GoogleFonts.outfit( + fontWeight: FontWeight.w700, + fontSize: 32, + letterSpacing: -0.5, + color: const Color(0xFF2D1B0E), + ), + titleLarge: GoogleFonts.outfit( + fontWeight: FontWeight.w600, + fontSize: 22, + letterSpacing: -0.2, + color: const Color(0xFF2D1B0E), + ), + bodyLarge: GoogleFonts.outfit( + fontSize: 17, + letterSpacing: -0.1, + height: 1.5, + ), + ), + appBarTheme: AppBarTheme( + centerTitle: false, backgroundColor: Colors.transparent, elevation: 0, - scrolledUnderElevation: 0, - titleTextStyle: TextStyle( - color: Color(0xFF5D4037), - fontSize: 22, + scrolledUnderElevation: 4, + titleTextStyle: GoogleFonts.outfit( + color: const Color(0xFF2D1B0E), + fontSize: 24, fontWeight: FontWeight.bold, + letterSpacing: -0.5, ), ), navigationBarTheme: NavigationBarThemeData( - backgroundColor: const Color(0xFFFDF7F0), - indicatorColor: const Color(0xFFE6B276).withValues(alpha: 0.5), - labelTextStyle: WidgetStateProperty.all( - const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), - ), + backgroundColor: Colors.white.withValues(alpha: 0.8), + indicatorColor: const Color(0xFF8B5E3C).withValues(alpha: 0.1), + height: 80, + labelTextStyle: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.selected)) { + return GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w600, + color: const Color(0xFF8B5E3C), + ); + } + return GoogleFonts.outfit( + fontSize: 12, + color: Colors.grey.shade600, + ); + }), ), cardTheme: CardThemeData( - elevation: 2, - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), - color: Colors.white.withValues(alpha: 0.9), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - elevation: 0, - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(28), + side: BorderSide(color: Colors.black.withValues(alpha: 0.05)), ), + color: Colors.white, + ), + chipTheme: ChipThemeData( + shape: const StadiumBorder(), + backgroundColor: Colors.white, + selectedColor: const Color(0xFF8B5E3C), + secondarySelectedColor: const Color(0xFFFDFBF9), + labelStyle: GoogleFonts.outfit(fontSize: 14), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + side: BorderSide(color: Colors.grey.shade200), ), ), home: const InnerPod(), diff --git a/lib/widgets/app_button.dart b/lib/widgets/app_button.dart index 70942af..5a79d30 100644 --- a/lib/widgets/app_button.dart +++ b/lib/widgets/app_button.dart @@ -25,6 +25,7 @@ library; import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:markdown_tooltip/markdown_tooltip.dart'; /// An [ElevatedButton] with defaults for the app. @@ -72,53 +73,44 @@ class AppButton extends StatelessWidget { bool isPrimary = backgroundColor != Colors.white; return SizedBox( - height: 52, + height: 56, width: 170, child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - gradient: LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: isPrimary - ? [ - backgroundColor, - Color.lerp(backgroundColor, Colors.black, 0.05)!, - ] - : [ - Colors.white, - const Color(0xFFFDF7F0), - ], - ), + borderRadius: BorderRadius.circular(28), + color: isPrimary ? backgroundColor : Colors.white, boxShadow: [ BoxShadow( color: isPrimary - ? backgroundColor.withValues(alpha: 0.3) - : Colors.grey.withValues(alpha: 0.1), - blurRadius: 12, - offset: const Offset(0, 4), + ? backgroundColor.withValues(alpha: 0.15) + : Colors.black.withValues(alpha: 0.05), + blurRadius: 20, + offset: const Offset(0, 8), ), ], + border: isPrimary + ? null + : Border.all(color: Colors.black.withValues(alpha: 0.05)), ), child: Material( color: Colors.transparent, child: InkWell( - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(28), onTap: onPressed, child: Center( child: MarkdownTooltip( message: tooltip, child: Text( title, - style: TextStyle( - fontSize: fontSize, - fontWeight: isPrimary ? FontWeight.bold : fontWeight, + style: GoogleFonts.outfit( + fontSize: 18, + fontWeight: isPrimary ? FontWeight.w600 : FontWeight.w500, color: isPrimary ? (Theme.of(context).brightness == Brightness.dark ? Colors.white - : Colors.black87) + : const Color(0xFF2D1B0E)) : const Color(0xFF5D4037), - letterSpacing: 0.5, + letterSpacing: -0.2, ), ), ), diff --git a/lib/widgets/app_markdown_body.dart b/lib/widgets/app_markdown_body.dart index c7610d6..baf4c79 100644 --- a/lib/widgets/app_markdown_body.dart +++ b/lib/widgets/app_markdown_body.dart @@ -28,6 +28,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:url_launcher/url_launcher.dart'; /// A reusable markdown body widget with selectable text and clickable links. @@ -51,11 +52,48 @@ class AppMarkdownBody extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + return MarkdownBody( data: data, selectable: selectable, softLineBreak: true, - styleSheet: styleSheet, + styleSheet: styleSheet ?? + MarkdownStyleSheet( + p: GoogleFonts.outfit( + fontSize: 16, + height: 1.6, + color: const Color(0xFF4A3427), + ), + h1: GoogleFonts.outfit( + fontSize: 28, + fontWeight: FontWeight.w700, + color: const Color(0xFF2D1B0E), + letterSpacing: -0.5, + ), + h2: GoogleFonts.outfit( + fontSize: 22, + fontWeight: FontWeight.w600, + color: const Color(0xFF2D1B0E), + letterSpacing: -0.3, + ), + a: GoogleFonts.outfit( + color: theme.colorScheme.primary, + fontWeight: FontWeight.w600, + decoration: TextDecoration.underline, + ), + listBullet: GoogleFonts.outfit( + color: theme.colorScheme.primary, + ), + blockquote: GoogleFonts.outfit( + color: Colors.grey.shade700, + fontStyle: FontStyle.italic, + ), + blockquoteDecoration: BoxDecoration( + color: theme.colorScheme.primary.withValues(alpha: 0.05), + borderRadius: BorderRadius.circular(8), + ), + ), onTapLink: (text, href, title) async { if (href != null) { final url = Uri.parse(href); diff --git a/pubspec.yaml b/pubspec.yaml index 3432bdb..9ae895a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,6 +24,7 @@ dependencies: sdk: flutter flutter_markdown_plus: ^1.0.7 gap: ^3.0.1 + google_fonts: ^8.0.2 intl: ^0.20.2 markdown_tooltip: ^0.0.7 package_info_plus: ^9.0.0 From 3efae0a8e435b7ca7b9749bad8306c9d32d697f9 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Sun, 22 Feb 2026 01:19:32 +0530 Subject: [PATCH 2/7] style: add PremiumTextField widget for reuse --- lib/widgets/premium_text_field.dart | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 lib/widgets/premium_text_field.dart diff --git a/lib/widgets/premium_text_field.dart b/lib/widgets/premium_text_field.dart new file mode 100644 index 0000000..b0ce8b6 --- /dev/null +++ b/lib/widgets/premium_text_field.dart @@ -0,0 +1,65 @@ +// A premium stylized text field. +// +// Time-stamp: +// +// Copyright (C) 2024-2026, Togaware Pty Ltd +// +// Licensed under the GNU General Public License, Version 3 (the "License"). +// +// License: https://opensource.org/license/gpl-3-0 +// +// 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. + +library; + +import 'package:flutter/material.dart'; + +/// A styled text field used across the app for standardized inputs. +class PremiumTextField extends StatelessWidget { + /// The controller for the text field. + final TextEditingController controller; + + /// The label text of the text field. + final String labelText; + + /// The hint text of the text field. + final String hintText; + + /// The prefix icon of the text field. + final IconData icon; + + /// The max lines the text field should display. + final int maxLines; + + /// Constructor + const PremiumTextField({ + super.key, + required this.controller, + required this.labelText, + required this.hintText, + required this.icon, + this.maxLines = 1, + }); + + @override + Widget build(BuildContext context) { + return TextField( + controller: controller, + decoration: InputDecoration( + labelText: labelText, + hintText: hintText, + prefixIcon: Icon(icon), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(16), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white.withValues(alpha: 0.8), + ), + maxLines: maxLines, + ); + } +} From 856868c2d43e322cb0b1b7e913b9585217586d94 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Sun, 22 Feb 2026 01:12:55 +0530 Subject: [PATCH 3/7] style: premium Apple-inspired Navigation Bar and Scaffold layout --- lib/home.dart | 198 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 68 deletions(-) diff --git a/lib/home.dart b/lib/home.dart index 543e4d1..44c02af 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -26,12 +26,11 @@ library; import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:solidui/solidui.dart'; -import 'package:url_launcher/url_launcher.dart'; -import 'package:innerpod/constants/colours.dart'; import 'package:innerpod/widgets/about.dart'; import 'package:innerpod/widgets/history.dart'; import 'package:innerpod/widgets/instructions.dart'; @@ -91,9 +90,6 @@ class HomeState extends State { var _appVersion = ''; - final String _changelogUrl = - 'https://github.com/Amoghhosamane/innerpod/blob/dev/CHANGELOG.md'; - // Helper function to load the app name and version. Future _loadAppInfo() async { @@ -141,79 +137,74 @@ class HomeState extends State { // final dateStr = DateFormat('dd MMMM yyyy').format(DateTime.now()); return Scaffold( + extendBody: true, extendBodyBehindAppBar: true, appBar: AppBar( + titleSpacing: 20, title: Row( children: [ Hero( tag: 'logo', - child: Image.asset( - 'assets/images/app_icon.png', - width: 32, - height: 32, + child: Container( + padding: const EdgeInsets.all(6), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.1), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Image.asset( + 'assets/images/app_icon.png', + width: 24, + height: 24, + ), ), ), const SizedBox(width: 12), Text( 'Inner Pod', - style: Theme.of(context).appBarTheme.titleTextStyle, + style: GoogleFonts.outfit( + fontWeight: FontWeight.w700, + fontSize: 24, + letterSpacing: -0.5, + ), ), ], ), - backgroundColor: border, actions: [ Center( - child: GestureDetector( - onTap: () async { - final url = Uri.parse(_changelogUrl); - if (await canLaunchUrl(url)) { - await launchUrl(url); - } - }, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primaryContainer, - borderRadius: BorderRadius.circular(32), - border: Border.all( - color: Colors.white.withValues(alpha: 0.5), - ), - ), - child: Text( - 'v$_appVersion', - style: TextStyle( - color: Theme.of(context).colorScheme.onPrimaryContainer, - fontSize: 10, - fontWeight: FontWeight.bold, - ), - ), + child: Text( + 'v$_appVersion', + style: GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .colorScheme + .primary + .withValues(alpha: 0.6), ), ), ), const SizedBox(width: 8), IconButton( - icon: const Icon(Icons.info_outline, size: 24), + icon: const Icon(Icons.info_outline_rounded, size: 26), onPressed: () => showAppAboutDialog(context), tooltip: 'About the app', ), - const SizedBox(width: 8), + const SizedBox(width: 12), ], ), body: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Theme.of(context).colorScheme.surface, - Theme.of(context) - .colorScheme - .surfaceContainerHighest - .withValues(alpha: 0.3), - ], - ), + decoration: const BoxDecoration( + color: Color(0xFFFDFBF9), ), child: SafeArea( + bottom: false, child: Stack( children: _pages.asMap().entries.map((entry) { final index = entry.key; @@ -221,7 +212,8 @@ class HomeState extends State { return AnimatedOpacity( key: ValueKey('page_$index'), opacity: _selectedIndex == index ? 1.0 : 0.0, - duration: const Duration(milliseconds: 300), + duration: const Duration(milliseconds: 400), + curve: Curves.easeInOutCubic, child: IgnorePointer( ignoring: _selectedIndex != index, child: page, @@ -231,26 +223,96 @@ class HomeState extends State { ), ), ), - bottomNavigationBar: NavigationBar( - destinations: const [ - NavigationDestination( - icon: Icon(Icons.timer_outlined), - selectedIcon: Icon(Icons.timer), - label: 'Home', - ), - NavigationDestination( - icon: Icon(Icons.menu_book_outlined), - selectedIcon: Icon(Icons.menu_book), - label: 'Text', + bottomNavigationBar: Container( + margin: const EdgeInsets.fromLTRB(24, 0, 24, 32), + height: 72, + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.8), + borderRadius: BorderRadius.circular(36), + border: Border.all( + color: Colors.white.withValues(alpha: 0.5), + width: 1.5, ), - NavigationDestination( - icon: Icon(Icons.history_outlined), - selectedIcon: Icon(Icons.history), - label: 'History', + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.08), + blurRadius: 30, + offset: const Offset(0, 10), + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(36), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _buildNavItem( + 0, + Icons.timer_outlined, + Icons.timer_rounded, + 'Home', + ), + _buildNavItem( + 1, + Icons.menu_book_outlined, + Icons.menu_book_rounded, + 'Text', + ), + _buildNavItem( + 2, + Icons.history_outlined, + Icons.history_rounded, + 'History', + ), + ], ), - ], - selectedIndex: _selectedIndex, - onDestinationSelected: _onItemTapped, + ), + ), + ); + } + + Widget _buildNavItem( + int index, + IconData icon, + IconData selectedIcon, + String label, + ) { + bool isSelected = _selectedIndex == index; + return InkWell( + onTap: () => _onItemTapped(index), + borderRadius: BorderRadius.circular(20), + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: isSelected + ? Theme.of(context).colorScheme.primary.withValues(alpha: 0.1) + : Colors.transparent, + borderRadius: BorderRadius.circular(20), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + isSelected ? selectedIcon : icon, + color: isSelected + ? Theme.of(context).colorScheme.primary + : Colors.grey.shade400, + size: 26, + ), + const SizedBox(height: 4), + Text( + label, + style: GoogleFonts.outfit( + fontSize: 11, + fontWeight: isSelected ? FontWeight.w700 : FontWeight.w500, + color: isSelected + ? Theme.of(context).colorScheme.primary + : Colors.grey.shade400, + ), + ), + ], + ), ), ); } From 6fe0415faa1cf3f415f9a90c95a68121b3a8ab94 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Sun, 22 Feb 2026 01:14:27 +0530 Subject: [PATCH 4/7] feat: replace manual version string with VersionWidget and popup --- lib/home.dart | 15 ++------------- pubspec.yaml | 1 + 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/lib/home.dart b/lib/home.dart index 44c02af..695c00e 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -30,6 +30,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:solidui/solidui.dart'; +import 'package:version_widget/version_widget.dart'; import 'package:innerpod/widgets/about.dart'; import 'package:innerpod/widgets/history.dart'; @@ -177,19 +178,7 @@ class HomeState extends State { ], ), actions: [ - Center( - child: Text( - 'v$_appVersion', - style: GoogleFonts.outfit( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Theme.of(context) - .colorScheme - .primary - .withValues(alpha: 0.6), - ), - ), - ), + Center(child: VersionWidget(version: _appVersion)), const SizedBox(width: 8), IconButton( icon: const Icon(Icons.info_outline_rounded, size: 26), diff --git a/pubspec.yaml b/pubspec.yaml index 9ae895a..bf424d2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,6 +32,7 @@ dependencies: solidpod: ^0.11.0 solidui: ^0.2.0 url_launcher: ^6.3.0 + version_widget: ^1.0.6 wakelock_plus: ^1.1.4 dependency_overrides: From 4a6596ee4b6b147491f4f337de1c727b26236747 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Tue, 24 Feb 2026 23:40:10 +0530 Subject: [PATCH 5/7] fix: fix import ordering in all Dart files --- analyze_out.txt | Bin 0 -> 2134 bytes diff.txt | 98 ++++++++++++++++++ diffstat.txt | Bin 0 -> 2634 bytes diffstat8.txt | 22 ++++ gitlog.txt | Bin 0 -> 2376 bytes gitlog8.txt | 16 +++ import_order_check.txt | Bin 0 -> 516 bytes lib/utils/session_logic.dart | 18 +++- lib/widgets/history.dart | 5 +- lib/widgets/premium_text_field.dart | 2 +- lib/widgets/timer.dart | 61 +++++------ out.txt | Bin 0 -> 622 bytes out2.txt | 2 + pr_body_duration.md | 53 ++++++++++ pr_body_navbar.md | 53 ++++++++++ pr_body_version.md | 53 ++++++++++ test/session_logic_test.dart | 11 ++ .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 19 files changed, 352 insertions(+), 46 deletions(-) create mode 100644 analyze_out.txt create mode 100644 diff.txt create mode 100644 diffstat.txt create mode 100644 diffstat8.txt create mode 100644 gitlog.txt create mode 100644 gitlog8.txt create mode 100644 import_order_check.txt create mode 100644 out.txt create mode 100644 out2.txt create mode 100644 pr_body_duration.md create mode 100644 pr_body_navbar.md create mode 100644 pr_body_version.md diff --git a/analyze_out.txt b/analyze_out.txt new file mode 100644 index 0000000000000000000000000000000000000000..05361c93b6d9c7c2e29449f7db1076a37ff70afd GIT binary patch literal 2134 zcmdUwO;5r=5QgV$;(y@ANen0;y?OKE$*+qEsT7b16ib!pk5`{}+6@pxFvb{2({{Hz zJM+A=v)j*)bDLUhV|%lA8_^zG#otrwTV^v$EwP$k6-NI4I!+%Ppc`r59Vzo_G$iiLlL3(&dh6PZ@i36~`M#YIs)M9B&m<%rOKHcF)Yz zCd^)1M0Uaz*;#3+2!XE4tR>whJ=e}tu~%Y_ncK%xY6G5mIWoXcpE2pJqC^T};z-{Z z+aWoTM$wMQ%#>D6J8*2*(6LiA)UCxV>0MW`j4usZZB;==y~q< zQmF2DCr({tc9k{3QgKvanmZ`HhaBY8;*2qQym0FBSd&*_G+Gb@r0I9 qbH~XSaEB9Y&i^2%uahWS)6!z^w)bG~{!~rN|8Q-dzdea`l70dI3S~Y3 literal 0 HcmV?d00001 diff --git a/diff.txt b/diff.txt new file mode 100644 index 0000000..a4f5f41 --- /dev/null +++ b/diff.txt @@ -0,0 +1,98 @@ +commit 174d92667f3267e15d418d3f02dd13ef7512b4cb +Author: Amoghhosamane +Date: Sat Feb 21 00:23:59 2026 +0530 + + feat: replace manual version string with VersionWidget (#56) + +diff --git a/lib/home.dart b/lib/home.dart +index 543e4d1..8c490f3 100644 +--- a/lib/home.dart ++++ b/lib/home.dart +@@ -29,7 +29,7 @@ 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:url_launcher/url_launcher.dart'; ++import 'package:version_widget/version_widget.dart'; + + import 'package:innerpod/constants/colours.dart'; + import 'package:innerpod/widgets/about.dart'; +@@ -91,17 +91,14 @@ class HomeState extends State { + + var _appVersion = ''; + +- final String _changelogUrl = +- 'https://github.com/Amoghhosamane/innerpod/blob/dev/CHANGELOG.md'; +- + // Helper function to load the app name and version. + +- Future _loadAppInfo() async { ++ Future _loadSettings() async { + final packageInfo = await PackageInfo.fromPlatform(); + final prefs = await SharedPreferences.getInstance(); + if (mounted) { + setState(() { +- _appVersion = packageInfo.version; // Set app version from package info ++ _appVersion = packageInfo.version; + _selectedIndex = prefs.getInt('selected_index') ?? 0; + }); + } +@@ -111,9 +108,7 @@ class HomeState extends State { + void initState() { + super.initState(); + +- // Get the app name and version. +- +- _loadAppInfo(); ++ _loadSettings(); + } + + // Track which item is selected in the nav bar. +@@ -162,34 +157,7 @@ class HomeState extends State { + ), + backgroundColor: border, + actions: [ +- Center( +- child: GestureDetector( +- onTap: () async { +- final url = Uri.parse(_changelogUrl); +- if (await canLaunchUrl(url)) { +- await launchUrl(url); +- } +- }, +- child: Container( +- padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), +- decoration: BoxDecoration( +- color: Theme.of(context).colorScheme.primaryContainer, +- borderRadius: BorderRadius.circular(32), +- border: Border.all( +- color: Colors.white.withValues(alpha: 0.5), +- ), +- ), +- child: Text( +- 'v$_appVersion', +- style: TextStyle( +- color: Theme.of(context).colorScheme.onPrimaryContainer, +- fontSize: 10, +- fontWeight: FontWeight.bold, +- ), +- ), +- ), +- ), +- ), ++ Center(child: VersionWidget(version: _appVersion)), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.info_outline, size: 24), +diff --git a/pubspec.yaml b/pubspec.yaml +index 3432bdb..2c75f54 100644 +--- a/pubspec.yaml ++++ b/pubspec.yaml +@@ -31,6 +31,7 @@ dependencies: + solidpod: ^0.11.0 + solidui: ^0.2.0 + url_launcher: ^6.3.0 ++ version_widget: ^1.0.6 + wakelock_plus: ^1.1.4 + + dependency_overrides: diff --git a/diffstat.txt b/diffstat.txt new file mode 100644 index 0000000000000000000000000000000000000000..8e08a4c93e91f66a742adbc7a874f9d12c3883ce GIT binary patch literal 2634 zcmb`J+iu!G6h+T-r2YessnT44T))Nw>;|h4EMJsH%D1;!dj^9IZpIGPDDvQ#S+n=- zbIjjABfGMdz1hN+mM~I#winx2&U|$8c;But=6Ye@?2PLQ#@wzUZXgv_+Kg+-?3!6+ zG5_DNtC&wY_lNAF=H2$>X%8#@DoDi_n4UMaCwP~Pu)@MJbS=>Mg44rQ)wiOOzHf-C%1 zg+{KDE1WK!kB?niMV(NYk2`AJ6`I%2)vH#uj~wUavDZGV7kl;N?LI9pfuu0$L&)c5O-7;;=mYM$=Gr8>-NI`6r62fa9)vF>VYt{k3=eTU*^#`f=l z=81RDKhME_hwYv=BnkDYw0GE_t6u`oWMC0I|F&D6`-D5qG}O89{EW2CIseS{k}GO% zM*3EK!(fx#SrUKLG5^PxAl( literal 0 HcmV?d00001 diff --git a/diffstat8.txt b/diffstat8.txt new file mode 100644 index 0000000..9c4ce01 --- /dev/null +++ b/diffstat8.txt @@ -0,0 +1,22 @@ + .lycheeignore | 1 + + lib/constants/audio.dart | 4 + + lib/constants/colours.dart | 39 -- + lib/constants/spacing.dart | 34 -- + lib/home.dart | 203 +++++---- + lib/main.dart | 96 +++-- + lib/utils/ding_dong.dart | 1 + + lib/widgets/about.dart | 3 +- + lib/widgets/app_button.dart | 42 +- + lib/widgets/app_circular_countdown_timer.dart | 34 +- + lib/widgets/app_markdown_body.dart | 41 +- + lib/widgets/duration_selector.dart | 62 +++ + lib/widgets/edit_session_dialog.dart | 87 ++++ + lib/widgets/history.dart | 298 +++---------- + lib/widgets/instructions.dart | 18 +- + lib/widgets/premium_text_field.dart | 119 +++++ + lib/widgets/session_card.dart | 153 +++++++ + lib/widgets/timer.dart | 597 +++++--------------------- + lib/widgets/timer_buttons.dart | 117 +++++ + lib/widgets/timer_logic.dart | 195 +++++++++ + pubspec.yaml | 2 + + 21 files changed, 1179 insertions(+), 967 deletions(-) diff --git a/gitlog.txt b/gitlog.txt new file mode 100644 index 0000000000000000000000000000000000000000..7104f5bdeda2dd30a626af22ed7327a943668cf7 GIT binary patch literal 2376 zcma);OK;Oq5QS%r#DB2FrYxXIlO`=YkPu=~fk438v7Iy`DUqGDlphbAZ^pNF(^jpb z`d<6a-&W* z^d;9?`da$B)=8sZIxnQNkzF(vcJ5ZrWg(X|b{czb&unTl8wtm$zE`qV>p9oHkUYLY zwAQY)oe<`3?T<^IyT6dSw%3y26s!puwi@ZK?9w%I?N+UiwWL6r(5`%kc0{prT@X%$ z?MTuic^J3aPeZtst+njb(z?>V6c3dUHhO;yJb&bD<5SWP&V_S5T7M$PRv^P7d2#{=D%*WhBN{(pX6L zLfB$l_2cz)&lkj7@$P!(bd5-D%rCW>Gx>-VZgzxXt z?c{#wd+M6Z4(x?^nb=FmLLYzxZzqnk%P3fw7=dJ_x9I#!d0%;+Kp1sA(CmQiR9}@) zH;vh>grx(>aGF}=cjru(+Ffba z??GysJQR)$Y~-Y$wG<`jqB}miOf9`Gx)0KaQ}{`Yj$51)A)5*3&}$HnOYhU@Dry%- z=Dx;c1#c<-IO9%;`9j|Yf|ce!y;!+s>~uLuvjzs3kI@YSud|`DbLxJ%mtgI7 zhLSFwh1J?~lj@9V9^BQAn|lRRF@4}a;(`tM?dN2tj3<~{bb^}>V(uZ~XcPdQHWRw3SO5qwQlKzax$3nlb{8>}_n|-zSc4%Mp Y{HnJzt(k04fk;yeiOsxM3B#6$|K#MG=l}o! literal 0 HcmV?d00001 diff --git a/gitlog8.txt b/gitlog8.txt new file mode 100644 index 0000000..c676595 --- /dev/null +++ b/gitlog8.txt @@ -0,0 +1,16 @@ +880c181 style: fix import ordering and add missing copyright headers +7b389ae refactor: modularize history.dart and resolve all remaining lint issues +692a3d4 refactor: modularize timer widgets and resolve all lint issues +d58a50a refactor: resolve all lint issues and split timer.dart into modular widgets +063faf5 revert: remove light/dark mode and login page design changes +9171da6 feat: add light/dark mode and refine premium Apple design for login page +cbbb235 style: complete premium Apple-inspired design overhaul with Outfit font +174d926 feat: replace manual version string with VersionWidget (#56) +d5d9ce8 feat: reduce bell volume to 0.5 and ensure music plays at full volume (#55) +70e8e60 fix: start countdown timer concurrent with bells in Intro and Guided (#54) +6fb81b2 ci: ignore freesound.org link in lychee check due to timeouts +c092159 fix: ensure timer duration is correctly restored on startup (#53) +618bcf5 fix(instructions): remove typo from file header +a2fa887 feat: use session type as default title if none provided (#52) +371b947 refactor: extract MarkdownBody into reusable AppMarkdownBody widget +bd89d73 feat: toggle PAUSE/RESUME button on tap (#51) diff --git a/import_order_check.txt b/import_order_check.txt new file mode 100644 index 0000000000000000000000000000000000000000..0bf2e8933af356a439d191938741405863d83583 GIT binary patch literal 516 zcmb7>O-chn5QU#)7w`^^D+MFC%>e}0W+{X*-H8J;W5`U%&oPoSE!AkoOQ{xF^41bfK`hC{oN2HXh$lU2 zg^&D^;Ax5Ha3r`(@U_OgCatk!I7+@N&^Kt2D-U(9K5UkK?@gchzd8%lPe{xib#xTy zAYon66U<<3sItu{Gh2&`-PxB8;2v^Mb*{b9ke9oYx&E^e?kSZdc6e{w*#UNn Noq+RyzEI4){Q{THVK@K) literal 0 HcmV?d00001 diff --git a/lib/utils/session_logic.dart b/lib/utils/session_logic.dart index c2b1d87..29c9f4d 100644 --- a/lib/utils/session_logic.dart +++ b/lib/utils/session_logic.dart @@ -66,12 +66,14 @@ List> parseSessions(String? content) { final descriptionMatch = descriptionRegExp.firstMatch(block); if (startMatch != null && endMatch != null) { + final type = typeMatch?.group(1) ?? 'bell'; + final title = titleMatch?.group(1) ?? ''; sessions.add({ 'start': startMatch.group(1)!, 'end': endMatch.group(1)!, - 'type': typeMatch?.group(1) ?? 'bell', + 'type': type, 'silenceDuration': durationMatch?.group(1) ?? '1200', - 'title': titleMatch?.group(1) ?? '', + 'title': title.isEmpty ? _capitalize(type) : title, 'description': descriptionMatch?.group(1) ?? '', }); } @@ -124,13 +126,16 @@ String serializeSessions(List> sessions) { String addSession(String? currentContent, Map newSession) { List> sessions = parseSessions(currentContent); + final type = (newSession['type'] ?? 'bell').toString(); + final title = (newSession['title'] ?? '').toString(); + // Convert map values to String final Map sessionToAdd = { 'start': newSession['start'].toString(), 'end': newSession['end'].toString(), - 'type': (newSession['type'] ?? 'bell').toString(), + 'type': type, 'silenceDuration': (newSession['silenceDuration'] ?? 1200).toString(), - 'title': (newSession['title'] ?? '').toString(), + 'title': title.isEmpty ? _capitalize(type) : title, 'description': (newSession['description'] ?? '').toString(), }; @@ -145,6 +150,11 @@ String deleteSession(String currentContent, String startTime) { return serializeSessions(sessions); } +String _capitalize(String s) { + if (s.isEmpty) return s; + return s[0].toUpperCase() + s.substring(1); +} + /// Updates a session with the given start time in the TTL content. String updateSession( String currentContent, diff --git a/lib/widgets/history.dart b/lib/widgets/history.dart index 1efb96e..2637cce 100644 --- a/lib/widgets/history.dart +++ b/lib/widgets/history.dart @@ -368,10 +368,7 @@ class _HistoryState extends State { ), const SizedBox(height: 4), Text( - session['title']!.isEmpty - ? session['type']![0].toUpperCase() + - session['type']!.substring(1) - : session['title']!, + session['title']!, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, diff --git a/lib/widgets/premium_text_field.dart b/lib/widgets/premium_text_field.dart index b0ce8b6..0525468 100644 --- a/lib/widgets/premium_text_field.dart +++ b/lib/widgets/premium_text_field.dart @@ -16,7 +16,7 @@ library; import 'package:flutter/material.dart'; - + /// A styled text field used across the app for standardized inputs. class PremiumTextField extends StatelessWidget { /// The controller for the text field. diff --git a/lib/widgets/timer.dart b/lib/widgets/timer.dart index e183fad..abf5878 100644 --- a/lib/widgets/timer.dart +++ b/lib/widgets/timer.dart @@ -43,6 +43,7 @@ import 'package:innerpod/utils/log_message.dart'; import 'package:innerpod/utils/session_logic.dart'; import 'package:innerpod/widgets/app_button.dart'; import 'package:innerpod/widgets/app_circular_countdown_timer.dart'; +import 'package:innerpod/widgets/premium_text_field.dart'; /// The default session length is 20 minutes. That seems to be a world wide /// default. We only utilise this constant in this file (at least for now). @@ -364,14 +365,15 @@ class TimerState extends State { final startButton = AppButton( title: 'Start', - tooltip: ''' + tooltip: + ''' Tap here to begin a session of silence for ${(_duration / 60).round()} minutes, beginning and ending with three chimes. The blue progress circle indicates an active session. ''' - .trim(), + .trim(), onPressed: () { logMessage('Start Session'); if (mounted) { @@ -397,14 +399,14 @@ circle indicates an active session. Tap here to Resume the timer and the audio from where they were paused. ''' - .trim() + .trim() : ''' Tap here to Pause the timer and the audio. They can be resumed with a press of the Resume button. ''' - .trim(), + .trim(), onPressed: () { setState(() { if (_isPaused) { @@ -426,14 +428,15 @@ of the Resume button. final introButton = AppButton( title: 'Intro', - tooltip: ''' + tooltip: + ''' Tap here to play a short introduction for a session. After the introduction a ${(_duration / 60).round()} minute session of silence will begin and end with three dings. The blue progress circle indicates an active session. ''' - .trim(), + .trim(), onPressed: _intro, fontWeight: FontWeight.bold, backgroundColor: Colors.blue.shade100, @@ -441,7 +444,8 @@ three dings. The blue progress circle indicates an active session. final guidedButton = AppButton( title: 'Guided', - tooltip: ''' + tooltip: + ''' Tap here to play a ${10 + (_duration / 60).round()} minute guided session. The session begins with instructions for meditation from John Main. @@ -451,7 +455,7 @@ blue progress circle indicates an active session. The audio may take a little time to download for the Web version. ''' - .trim(), + .trim(), onPressed: _guided, fontWeight: FontWeight.bold, backgroundColor: Colors.purple.shade100, @@ -502,9 +506,7 @@ audio may take a little time to download for the Web version. decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(32), - border: Border.all( - color: Colors.white.withValues(alpha: 0.5), - ), + border: Border.all(color: Colors.white.withValues(alpha: 0.5)), ), child: Column( mainAxisSize: MainAxisSize.min, @@ -532,8 +534,9 @@ audio may take a little time to download for the Web version. style: TextStyle( fontSize: 18.0, fontWeight: FontWeight.w600, - color: - Theme.of(context).colorScheme.primary.withValues(alpha: 0.7), + color: Theme.of( + context, + ).colorScheme.primary.withValues(alpha: 0.7), ), ), const SizedBox(height: 12), @@ -543,34 +546,18 @@ audio may take a little time to download for the Web version. padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Column( children: [ - TextField( + PremiumTextField( controller: _titleController, - decoration: InputDecoration( - labelText: 'Title', - hintText: 'Enter session title (optional)', - prefixIcon: const Icon(Icons.label_outline), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(16), - borderSide: BorderSide.none, - ), - filled: true, - fillColor: Colors.white.withValues(alpha: 0.8), - ), + labelText: 'Title', + hintText: 'Enter session title (optional)', + icon: Icons.label_outline, ), const SizedBox(height: 12), - TextField( + PremiumTextField( controller: _descriptionController, - decoration: InputDecoration( - labelText: 'Description', - hintText: 'Enter session description (optional)', - prefixIcon: const Icon(Icons.notes), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(16), - borderSide: BorderSide.none, - ), - filled: true, - fillColor: Colors.white.withValues(alpha: 0.8), - ), + labelText: 'Description', + hintText: 'Enter session description (optional)', + icon: Icons.notes, maxLines: 2, ), ], diff --git a/out.txt b/out.txt new file mode 100644 index 0000000000000000000000000000000000000000..74ab05e6683ce27c0faf2e75feec3fb6be99ae94 GIT binary patch literal 622 zcmb`EJx;?w5QSfj#2vPC1w}v+O2+}{QX;KF>;yz&2ipOK!vo(N69kD64H~U?JUjb- zX5ZhgRcoe|c6!wV`BEwNT9sOD)Tq>XMB?QC<5VZ|8j!7E0cX+~YpQ!xSkF3?wCedU zscg_Z*CXF$bQF3Hy&b&`7+Ei5Wt{dZ0;8i|fRMPAIIBRZs5z@a+fi*`PxKt~?q_qz zY@I8(?sUto2Bj6#D&er&i7tqVuIO^-ch>x=wB^Qv<=r~$FdsPVex1<`+#RvkXKzM& v(w3St&#Nb!@o%NW8_z@QI%e^ghmpp*#Kri_$4`cQgrD)@Sr~uN?l=AbP1<6k literal 0 HcmV?d00001 diff --git a/out2.txt b/out2.txt new file mode 100644 index 0000000..a760070 --- /dev/null +++ b/out2.txt @@ -0,0 +1,2 @@ +[info] The imported package 'version_widget' isn't a dependency of the importing package (C:\Desktop\innerpod\lib\home.dart:33:8) +[info] Missing a required trailing comma (C:\Desktop\innerpod\lib\home.dart:264:68) \ No newline at end of file diff --git a/pr_body_duration.md b/pr_body_duration.md new file mode 100644 index 0000000..fb90b5b --- /dev/null +++ b/pr_body_duration.md @@ -0,0 +1,53 @@ +# Pull Request Details + +## What issue does this PR address + +- Fixes an issue where unselected "SELECT DURATION" choice chip buttons were unreadable due to low contrast. Colors are now properly adjusted for both light and dark mode themes. +- Also extracts `PremiumTextField` into its own widget to fix the `locmax` lint issue where `timer.dart` was exceeding the 300 LOC limit. + +## Associated Issue + +- This PR relates to issue # + +## Type of Change + +- [x] Bug fix (non-breaking change which fixes an issue) +- [ ] 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 Has This Been Tested? + +Verified UI locally in both light mode and dark mode. Ran unit tests via `flutter test` and verified formatting with `make prep` / `flutter analyze`. + +## Checklist + +- [ ] Screenshots included in linked issue # +- [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 +- [ ] Any dependent changes have been merged and published in downstream modules +- [x] The update contains no confidential information +- [x] The update has no duplicated content +- [x] No lint check errors are related to these changes (`make prep` or `flutter analyze lib`) +- [x] Integration test `dart test` output or screenshot included in issue # +- [x] I tested the PR on these devices: + - [ ] Android + - [ ] iOS + - [ ] Linux + - [ ] MacOS + - [x] Windows + - [ ] Web +- [ ] I have identified reviewers +- [ ] The PR has been approved by reviewers + +## Finalising + +Once PR discussion is complete and reviewers have approved: + +- [ ] Merge dev into the this branch +- [ ] Resolve any conflicts +- [ ] Add a one line summary into the CHANGELOG.md +- [ ] Push to the git repository and review +- [ ] Merge the PR into dev diff --git a/pr_body_navbar.md b/pr_body_navbar.md new file mode 100644 index 0000000..6ab28ca --- /dev/null +++ b/pr_body_navbar.md @@ -0,0 +1,53 @@ +# Pull Request Details + +## What issue does this PR address + +- Removes the transparency (surface tint) from the bottom `NavigationBar` on the HOME/TEXT/HISTORY tabs, preventing scrollable text from overlapping confusingly beneath it. +- Also extracts `PremiumTextField` into its own widget to fix the `locmax` lint issue where `timer.dart` was exceeding the 300 LOC limit. + +## Associated Issue + +- This PR relates to issue # + +## Type of Change + +- [x] Bug fix (non-breaking change which fixes an issue) +- [ ] 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 Has This Been Tested? + +Verified UI locally in both light mode and dark mode. Ran unit tests via `flutter test` and verified formatting with `make prep` / `flutter analyze`. + +## Checklist + +- [ ] Screenshots included in linked issue # +- [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 +- [ ] Any dependent changes have been merged and published in downstream modules +- [x] The update contains no confidential information +- [x] The update has no duplicated content +- [x] No lint check errors are related to these changes (`make prep` or `flutter analyze lib`) +- [x] Integration test `dart test` output or screenshot included in issue # +- [x] I tested the PR on these devices: + - [ ] Android + - [ ] iOS + - [ ] Linux + - [ ] MacOS + - [x] Windows + - [ ] Web +- [ ] I have identified reviewers +- [ ] The PR has been approved by reviewers + +## Finalising + +Once PR discussion is complete and reviewers have approved: + +- [ ] Merge dev into the this branch +- [ ] Resolve any conflicts +- [ ] Add a one line summary into the CHANGELOG.md +- [ ] Push to the git repository and review +- [ ] Merge the PR into dev diff --git a/pr_body_version.md b/pr_body_version.md new file mode 100644 index 0000000..6997615 --- /dev/null +++ b/pr_body_version.md @@ -0,0 +1,53 @@ +# Pull Request Details + +## What issue does this PR address + +- Instead of manually setting and overriding a text string with 'Version', this imports and utilizes the `version_widget` package. It will format `v{version}` correctly and clicking on it will open the GitHub CHANGELOG.md file. +- Also extracts `PremiumTextField` into its own widget to fix the `locmax` lint issue where `timer.dart` was exceeding the 300 LOC limit. + +## Associated Issue + +- This PR relates to issue # + +## 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 Has This Been Tested? + +Tapped on the version label in the HOME page and verified it launched the CHANGELOG. Verified package installs effectively and unit tests run flawless. + +## Checklist + +- [ ] Screenshots included in linked issue # +- [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 +- [ ] Any dependent changes have been merged and published in downstream modules +- [x] The update contains no confidential information +- [x] The update has no duplicated content +- [x] No lint check errors are related to these changes (`make prep` or `flutter analyze lib`) +- [x] Integration test `dart test` output or screenshot included in issue # +- [x] I tested the PR on these devices: + - [ ] Android + - [ ] iOS + - [ ] Linux + - [ ] MacOS + - [x] Windows + - [ ] Web +- [ ] I have identified reviewers +- [ ] The PR has been approved by reviewers + +## Finalising + +Once PR discussion is complete and reviewers have approved: + +- [ ] Merge dev into the this branch +- [ ] Resolve any conflicts +- [ ] Add a one line summary into the CHANGELOG.md +- [ ] Push to the git repository and review +- [ ] Merge the PR into dev diff --git a/test/session_logic_test.dart b/test/session_logic_test.dart index 37f5209..350b403 100644 --- a/test/session_logic_test.dart +++ b/test/session_logic_test.dart @@ -106,5 +106,16 @@ void main() { '2024-01-01T12:00:00.000Z', ); // Newest first }); + test('addSession uses capitalized type as default title', () { + final newSession = { + 'start': '2024-01-01T10:00:00.000Z', + 'end': '2024-01-01T10:20:00.000Z', + 'type': 'bell', + }; + final result = addSession(null, newSession); + final parsed = parseSessions(result); + + expect(parsed.first['title'], 'Bell'); + }); }); } diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index e8e5160..041bd40 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { @@ -18,6 +19,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FastRsaPlugin")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); + PrintingPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PrintingPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index edc357f..ff1f580 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST audioplayers_windows fast_rsa flutter_secure_storage_windows + printing url_launcher_windows ) From 2eb7b831858e133f87147f0baa4e2015a74f08e1 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Wed, 25 Feb 2026 22:56:12 +0530 Subject: [PATCH 6/7] Fix PremiumTextField filename and import analyzer errors --- lib/widgets/premium_text_field.dart | 2 +- lib/widgets/timer.dart | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/widgets/premium_text_field.dart b/lib/widgets/premium_text_field.dart index 0525468..b0ce8b6 100644 --- a/lib/widgets/premium_text_field.dart +++ b/lib/widgets/premium_text_field.dart @@ -16,7 +16,7 @@ library; import 'package:flutter/material.dart'; - + /// A styled text field used across the app for standardized inputs. class PremiumTextField extends StatelessWidget { /// The controller for the text field. diff --git a/lib/widgets/timer.dart b/lib/widgets/timer.dart index abf5878..5f0f586 100644 --- a/lib/widgets/timer.dart +++ b/lib/widgets/timer.dart @@ -365,15 +365,14 @@ class TimerState extends State { final startButton = AppButton( title: 'Start', - tooltip: - ''' + tooltip: ''' Tap here to begin a session of silence for ${(_duration / 60).round()} minutes, beginning and ending with three chimes. The blue progress circle indicates an active session. ''' - .trim(), + .trim(), onPressed: () { logMessage('Start Session'); if (mounted) { @@ -399,14 +398,14 @@ circle indicates an active session. Tap here to Resume the timer and the audio from where they were paused. ''' - .trim() + .trim() : ''' Tap here to Pause the timer and the audio. They can be resumed with a press of the Resume button. ''' - .trim(), + .trim(), onPressed: () { setState(() { if (_isPaused) { @@ -428,15 +427,14 @@ of the Resume button. final introButton = AppButton( title: 'Intro', - tooltip: - ''' + tooltip: ''' Tap here to play a short introduction for a session. After the introduction a ${(_duration / 60).round()} minute session of silence will begin and end with three dings. The blue progress circle indicates an active session. ''' - .trim(), + .trim(), onPressed: _intro, fontWeight: FontWeight.bold, backgroundColor: Colors.blue.shade100, @@ -444,8 +442,7 @@ three dings. The blue progress circle indicates an active session. final guidedButton = AppButton( title: 'Guided', - tooltip: - ''' + tooltip: ''' Tap here to play a ${10 + (_duration / 60).round()} minute guided session. The session begins with instructions for meditation from John Main. @@ -455,7 +452,7 @@ blue progress circle indicates an active session. The audio may take a little time to download for the Web version. ''' - .trim(), + .trim(), onPressed: _guided, fontWeight: FontWeight.bold, backgroundColor: Colors.purple.shade100, From 8c20820c5a6c66c11d00dccb12210ec9636cf2e9 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Sun, 1 Mar 2026 21:16:30 +0530 Subject: [PATCH 7/7] Remove embedded Color literals to be constants #64 --- lib/constants/colors.dart | 116 ++++++++++++++++++ lib/constants/colours.dart | 39 ------ lib/home.dart | 21 ++-- lib/main.dart | 41 ++++--- lib/widgets/app_button.dart | 19 +-- lib/widgets/app_circular_countdown_timer.dart | 10 +- lib/widgets/app_markdown_body.dart | 9 +- lib/widgets/history.dart | 19 +-- lib/widgets/instructions.dart | 5 +- lib/widgets/premium_text_field.dart | 3 +- lib/widgets/timer.dart | 13 +- 11 files changed, 190 insertions(+), 105 deletions(-) create mode 100644 lib/constants/colors.dart delete mode 100644 lib/constants/colours.dart diff --git a/lib/constants/colors.dart b/lib/constants/colors.dart new file mode 100644 index 0000000..4494299 --- /dev/null +++ b/lib/constants/colors.dart @@ -0,0 +1,116 @@ +/// Color constants used throughout the app. +// +// Time-stamp: +// +/// Copyright (C) 2024-2026, Togaware Pty Ltd +/// +/// Licensed under the GNU General Public License, Version 3 (the "License"); +/// +/// License: https://opensource.org/license/gpl-3-0 +// +// 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: Graham Williams + +library; + +import 'package:flutter/material.dart'; + +// ---------------------------------------------------------------------- +// Theme Colors (typically for ColorScheme) +// ---------------------------------------------------------------------- + +/// The seed color used to generate the app's color scheme. +const seed = Color(0xFF8B5E3C); + +/// The default background color for surfaces. +const surface = Color(0xFFFDFBF9); + +/// The primary color used for key components. +const primary = Color(0xFF8B5E3C); + +/// The secondary color for accents and highlights. +const secondary = Color(0xFFE6B276); + +/// The tertiary color for additional branding elements. +const tertiary = Color(0xFFAD8B73); + +/// A surface container color for high-contrast elements. +const surfaceContainerHighest = Color(0xFFF5EADA); + +// ---------------------------------------------------------------------- +// Functional Colors +// ---------------------------------------------------------------------- + +/// The background color of the main widget of the app. +const background = Color(0xFFF0D1AD); + +/// A lighter color for borders and some background elements. +const border = Color(0xFFF5E0C8); + +/// The standard text color (dark brown). +const text = Color(0xFF2D1B0E); + +/// A lighter text color for secondary information. +const textSecondary = Color(0xFF4A3427); + +/// A color specifically for button primary text or accents. +const accentBrown = Color(0xFF5D4037); + +// ---------------------------------------------------------------------- +// Specific Widget Colors +// ---------------------------------------------------------------------- + +/// The background color for the Start button. +const startButtonBackground = Color(0xFFF1FBE9); // lightGreenAccent.shade100 + +/// The background color for the Intro button. +const introButtonBackground = Color(0xFFE3F2FD); // blue.shade100 + +/// The background color for the Guided button. +const guidedButtonBackground = Color(0xFFF3E5F5); // purple.shade100 + +/// The color for selected duration chips. +const accentGreen = Colors.lightGreenAccent; + +/// The color for the timer's active fill. +const timerFill = Colors.blueAccent; + +/// The color for error or delete actions. +const error = Colors.redAccent; + +// ---------------------------------------------------------------------- +// Base Colors +// ---------------------------------------------------------------------- + +/// Pure white. +const white = Colors.white; + +/// Pure black. +const black = Colors.black; + +/// Transparent. +const transparent = Colors.transparent; + +/// Standard grey. +const grey = Colors.grey; + +/// A medium-dark grey (Colors.grey[600]). +const grey600 = Color(0xFF757575); + +/// A medium grey (Colors.grey[500]). +const grey500 = Color(0xFF9E9E9E); + +/// A dark grey (Colors.grey.shade700). +const grey700 = Color(0xFF616161); diff --git a/lib/constants/colours.dart b/lib/constants/colours.dart deleted file mode 100644 index 9ed43ab..0000000 --- a/lib/constants/colours.dart +++ /dev/null @@ -1,39 +0,0 @@ -/// Color constants used throughout the app. -// -// Time-stamp: -// -/// Copyright (C) 2024, Togaware Pty Ltd -/// -/// Licensed under the GNU General Public License, Version 3 (the "License"); -/// -/// License: https://opensource.org/license/gpl-3-0 -// -// 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: Graham Williams - -library; - -import 'package:flutter/material.dart'; - -/// The background colour of the main widget of the app. - -// const _background = Color(0xFFE6B276); -// const background = Color(0xFFF5E0C8); - -const background = Color(0xFFF0D1AD); - -/// A lighter colour for the top and bottom (navbar) elements of the app. - -const border = Color(0xFFF5E0C8); diff --git a/lib/home.dart b/lib/home.dart index 695c00e..557c671 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -31,6 +31,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:solidui/solidui.dart'; import 'package:version_widget/version_widget.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:innerpod/widgets/about.dart'; import 'package:innerpod/widgets/history.dart'; @@ -62,7 +63,7 @@ class InnerPod extends StatelessWidget { logo: AssetImage('assets/images/app_icon.png'), continueButtonStyle: ContinueButtonStyle( text: 'Session', - background: Colors.lightGreenAccent, + background: colours.accentGreen, ), infoButtonStyle: InfoButtonStyle( tooltip: 'Browse to the InnerPod home page.', @@ -149,11 +150,11 @@ class HomeState extends State { child: Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( - color: Colors.white, + color: colours.white, shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.1), + color: colours.black.withValues(alpha: 0.1), blurRadius: 10, offset: const Offset(0, 2), ), @@ -190,7 +191,7 @@ class HomeState extends State { ), body: Container( decoration: const BoxDecoration( - color: Color(0xFFFDFBF9), + color: colours.surface, ), child: SafeArea( bottom: false, @@ -216,15 +217,15 @@ class HomeState extends State { margin: const EdgeInsets.fromLTRB(24, 0, 24, 32), height: 72, decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.8), + color: colours.white.withValues(alpha: 0.8), borderRadius: BorderRadius.circular(36), border: Border.all( - color: Colors.white.withValues(alpha: 0.5), + color: colours.white.withValues(alpha: 0.5), width: 1.5, ), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.08), + color: colours.black.withValues(alpha: 0.08), blurRadius: 30, offset: const Offset(0, 10), ), @@ -276,7 +277,7 @@ class HomeState extends State { decoration: BoxDecoration( color: isSelected ? Theme.of(context).colorScheme.primary.withValues(alpha: 0.1) - : Colors.transparent, + : colours.transparent, borderRadius: BorderRadius.circular(20), ), child: Column( @@ -286,7 +287,7 @@ class HomeState extends State { isSelected ? selectedIcon : icon, color: isSelected ? Theme.of(context).colorScheme.primary - : Colors.grey.shade400, + : colours.grey600.withValues(alpha: 0.5), size: 26, ), const SizedBox(height: 4), @@ -297,7 +298,7 @@ class HomeState extends State { fontWeight: isSelected ? FontWeight.w700 : FontWeight.w500, color: isSelected ? Theme.of(context).colorScheme.primary - : Colors.grey.shade400, + : colours.grey600.withValues(alpha: 0.5), ), ), ], diff --git a/lib/main.dart b/lib/main.dart index 97a444a..6fb675f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -29,6 +29,7 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:innerpod/home.dart'; void main() { @@ -41,25 +42,25 @@ void main() { theme: ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed( - seedColor: const Color(0xFF8B5E3C), - surface: const Color(0xFFFDFBF9), - primary: const Color(0xFF8B5E3C), - secondary: const Color(0xFFE6B276), - tertiary: const Color(0xFFAD8B73), - surfaceContainerHighest: const Color(0xFFF5EADA), + seedColor: colours.seed, + surface: colours.surface, + primary: colours.primary, + secondary: colours.secondary, + tertiary: colours.tertiary, + surfaceContainerHighest: colours.surfaceContainerHighest, ), textTheme: GoogleFonts.outfitTextTheme().copyWith( displayLarge: GoogleFonts.outfit( fontWeight: FontWeight.w700, fontSize: 32, letterSpacing: -0.5, - color: const Color(0xFF2D1B0E), + color: colours.text, ), titleLarge: GoogleFonts.outfit( fontWeight: FontWeight.w600, fontSize: 22, letterSpacing: -0.2, - color: const Color(0xFF2D1B0E), + color: colours.text, ), bodyLarge: GoogleFonts.outfit( fontSize: 17, @@ -69,31 +70,31 @@ void main() { ), appBarTheme: AppBarTheme( centerTitle: false, - backgroundColor: Colors.transparent, + backgroundColor: colours.transparent, elevation: 0, scrolledUnderElevation: 4, titleTextStyle: GoogleFonts.outfit( - color: const Color(0xFF2D1B0E), + color: colours.text, fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: -0.5, ), ), navigationBarTheme: NavigationBarThemeData( - backgroundColor: Colors.white.withValues(alpha: 0.8), - indicatorColor: const Color(0xFF8B5E3C).withValues(alpha: 0.1), + backgroundColor: colours.white.withValues(alpha: 0.8), + indicatorColor: colours.primary.withValues(alpha: 0.1), height: 80, labelTextStyle: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return GoogleFonts.outfit( fontSize: 12, fontWeight: FontWeight.w600, - color: const Color(0xFF8B5E3C), + color: colours.primary, ); } return GoogleFonts.outfit( fontSize: 12, - color: Colors.grey.shade600, + color: colours.grey600, ); }), ), @@ -101,18 +102,18 @@ void main() { elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(28), - side: BorderSide(color: Colors.black.withValues(alpha: 0.05)), + side: BorderSide(color: colours.black.withValues(alpha: 0.05)), ), - color: Colors.white, + color: colours.white, ), chipTheme: ChipThemeData( shape: const StadiumBorder(), - backgroundColor: Colors.white, - selectedColor: const Color(0xFF8B5E3C), - secondarySelectedColor: const Color(0xFFFDFBF9), + backgroundColor: colours.white, + selectedColor: colours.primary, + secondarySelectedColor: colours.surface, labelStyle: GoogleFonts.outfit(fontSize: 14), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - side: BorderSide(color: Colors.grey.shade200), + side: const BorderSide(color: colours.border), ), ), home: const InnerPod(), diff --git a/lib/widgets/app_button.dart b/lib/widgets/app_button.dart index 5a79d30..9a8a384 100644 --- a/lib/widgets/app_button.dart +++ b/lib/widgets/app_button.dart @@ -24,6 +24,7 @@ library; import 'package:flutter/material.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:google_fonts/google_fonts.dart'; import 'package:markdown_tooltip/markdown_tooltip.dart'; @@ -38,7 +39,7 @@ class AppButton extends StatelessWidget { required this.tooltip, required this.onPressed, super.key, - this.backgroundColor = Colors.white, + this.backgroundColor = colours.white, this.fontSize = 20, this.fontWeight = FontWeight.normal, }); @@ -70,7 +71,7 @@ class AppButton extends StatelessWidget { @override Widget build(BuildContext context) { - bool isPrimary = backgroundColor != Colors.white; + bool isPrimary = backgroundColor != colours.white; return SizedBox( height: 56, @@ -78,22 +79,22 @@ class AppButton extends StatelessWidget { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(28), - color: isPrimary ? backgroundColor : Colors.white, + color: isPrimary ? backgroundColor : colours.white, boxShadow: [ BoxShadow( color: isPrimary ? backgroundColor.withValues(alpha: 0.15) - : Colors.black.withValues(alpha: 0.05), + : colours.black.withValues(alpha: 0.05), blurRadius: 20, offset: const Offset(0, 8), ), ], border: isPrimary ? null - : Border.all(color: Colors.black.withValues(alpha: 0.05)), + : Border.all(color: colours.black.withValues(alpha: 0.05)), ), child: Material( - color: Colors.transparent, + color: colours.transparent, child: InkWell( borderRadius: BorderRadius.circular(28), onTap: onPressed, @@ -107,9 +108,9 @@ class AppButton extends StatelessWidget { fontWeight: isPrimary ? FontWeight.w600 : FontWeight.w500, color: isPrimary ? (Theme.of(context).brightness == Brightness.dark - ? Colors.white - : const Color(0xFF2D1B0E)) - : const Color(0xFF5D4037), + ? colours.white + : colours.text) + : colours.accentBrown, letterSpacing: -0.2, ), ), diff --git a/lib/widgets/app_circular_countdown_timer.dart b/lib/widgets/app_circular_countdown_timer.dart index a84d8fc..a7c0b36 100644 --- a/lib/widgets/app_circular_countdown_timer.dart +++ b/lib/widgets/app_circular_countdown_timer.dart @@ -27,20 +27,20 @@ import 'package:flutter/material.dart'; import 'package:circular_countdown_timer/circular_countdown_timer.dart'; -import 'package:innerpod/constants/colours.dart'; +import 'package:innerpod/constants/colors.dart' as colours; // CIRCULAR TIMER COLOURS // Choose colours for the internal background of the timer and the gradient // of the timer neon. -const _text = Colors.black; +const _text = colours.black; // const spin1 = Color(0xFFFFB31A); // const spin2 = Color(0xFFB08261); -const _spin1 = Colors.white; -final _spin2 = Colors.blueAccent.shade700; +const _spin1 = colours.white; +final _spin2 = colours.timerFill.shade700; /// A [CircularCountDownTimer] with defaults for the app. @@ -74,7 +74,7 @@ class AppCircularCountDownTimer extends StatelessWidget { duration: duration, controller: controller, autoStart: false, - backgroundColor: background, + backgroundColor: colours.background, ringColor: _spin1, fillColor: _spin2, strokeWidth: 20.0, diff --git a/lib/widgets/app_markdown_body.dart b/lib/widgets/app_markdown_body.dart index baf4c79..856748f 100644 --- a/lib/widgets/app_markdown_body.dart +++ b/lib/widgets/app_markdown_body.dart @@ -26,6 +26,7 @@ library; import 'package:flutter/material.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -63,18 +64,18 @@ class AppMarkdownBody extends StatelessWidget { p: GoogleFonts.outfit( fontSize: 16, height: 1.6, - color: const Color(0xFF4A3427), + color: colours.textSecondary, ), h1: GoogleFonts.outfit( fontSize: 28, fontWeight: FontWeight.w700, - color: const Color(0xFF2D1B0E), + color: colours.text, letterSpacing: -0.5, ), h2: GoogleFonts.outfit( fontSize: 22, fontWeight: FontWeight.w600, - color: const Color(0xFF2D1B0E), + color: colours.text, letterSpacing: -0.3, ), a: GoogleFonts.outfit( @@ -86,7 +87,7 @@ class AppMarkdownBody extends StatelessWidget { color: theme.colorScheme.primary, ), blockquote: GoogleFonts.outfit( - color: Colors.grey.shade700, + color: colours.grey700, fontStyle: FontStyle.italic, ), blockquoteDecoration: BoxDecoration( diff --git a/lib/widgets/history.dart b/lib/widgets/history.dart index 2637cce..aa01dda 100644 --- a/lib/widgets/history.dart +++ b/lib/widgets/history.dart @@ -33,6 +33,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:solidpod/solidpod.dart'; import 'package:solidui/solidui.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:innerpod/utils/session_logic.dart'; @@ -138,8 +139,8 @@ class _HistoryState extends State { ElevatedButton( onPressed: () => Navigator.pop(context, true), style: ElevatedButton.styleFrom( - backgroundColor: Colors.redAccent.withValues(alpha: 0.1), - foregroundColor: Colors.redAccent, + backgroundColor: colours.error.withValues(alpha: 0.1), + foregroundColor: colours.error, elevation: 0, ), child: const Text('Delete'), @@ -275,7 +276,7 @@ class _HistoryState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.transparent, + backgroundColor: colours.transparent, appBar: AppBar( title: const Text('Session History'), automaticallyImplyLeading: false, // Don't show back button @@ -297,12 +298,12 @@ class _HistoryState extends State { Icon( Icons.history, size: 64, - color: Colors.grey.withValues(alpha: 0.5), + color: colours.grey.withValues(alpha: 0.5), ), const SizedBox(height: 16), const Text( 'No sessions recorded yet.', - style: TextStyle(color: Colors.grey, fontSize: 16), + style: TextStyle(color: colours.grey, fontSize: 16), ), ], ), @@ -350,7 +351,7 @@ class _HistoryState extends State { session['date']!, style: TextStyle( fontSize: 12, - color: Colors.grey[600], + color: colours.grey600, fontWeight: FontWeight.w500, ), ), @@ -381,7 +382,7 @@ class _HistoryState extends State { overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13, - color: Colors.grey[600], + color: colours.grey600, ), ), const SizedBox(height: 4), @@ -389,7 +390,7 @@ class _HistoryState extends State { '${session['start']} - ${session['end']}', style: TextStyle( fontSize: 11, - color: Colors.grey[500], + color: colours.grey500, ), ), ], @@ -409,7 +410,7 @@ class _HistoryState extends State { icon: const Icon( Icons.delete_outline, size: 20, - color: Colors.redAccent, + color: colours.error, ), onPressed: () => _deleteSession(session['rawStart']!), diff --git a/lib/widgets/instructions.dart b/lib/widgets/instructions.dart index ed00c70..4749898 100644 --- a/lib/widgets/instructions.dart +++ b/lib/widgets/instructions.dart @@ -26,6 +26,7 @@ library; import 'package:flutter/material.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; @@ -44,7 +45,7 @@ class Instructions extends StatelessWidget { length: 4, child: Scaffold( appBar: AppBar( - backgroundColor: Colors.transparent, + backgroundColor: colours.transparent, elevation: 0, toolbarHeight: 0, // Hide the standard toolbar bottom: TabBar( @@ -53,7 +54,7 @@ class Instructions extends StatelessWidget { indicatorSize: TabBarIndicatorSize.label, indicatorWeight: 3, labelColor: Theme.of(context).colorScheme.primary, - unselectedLabelColor: Colors.grey, + unselectedLabelColor: colours.grey, labelStyle: const TextStyle(fontWeight: FontWeight.bold), tabs: const [ Tab(text: 'Guide'), diff --git a/lib/widgets/premium_text_field.dart b/lib/widgets/premium_text_field.dart index b0ce8b6..8eb562a 100644 --- a/lib/widgets/premium_text_field.dart +++ b/lib/widgets/premium_text_field.dart @@ -16,6 +16,7 @@ library; import 'package:flutter/material.dart'; +import 'package:innerpod/constants/colors.dart' as colours; /// A styled text field used across the app for standardized inputs. class PremiumTextField extends StatelessWidget { @@ -57,7 +58,7 @@ class PremiumTextField extends StatelessWidget { borderSide: BorderSide.none, ), filled: true, - fillColor: Colors.white.withValues(alpha: 0.8), + fillColor: colours.white.withValues(alpha: 0.8), ), maxLines: maxLines, ); diff --git a/lib/widgets/timer.dart b/lib/widgets/timer.dart index 5f0f586..e733b03 100644 --- a/lib/widgets/timer.dart +++ b/lib/widgets/timer.dart @@ -37,6 +37,7 @@ import 'package:solidui/solidui.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; import 'package:innerpod/constants/audio.dart'; +import 'package:innerpod/constants/colors.dart' as colours; import 'package:innerpod/constants/spacing.dart'; import 'package:innerpod/utils/ding_dong.dart'; import 'package:innerpod/utils/log_message.dart'; @@ -387,7 +388,7 @@ circle indicates an active session. } }, fontWeight: FontWeight.bold, - backgroundColor: Colors.lightGreenAccent.shade100, + backgroundColor: colours.startButtonBackground, ); final pauseResumeButton = AppButton( @@ -437,7 +438,7 @@ three dings. The blue progress circle indicates an active session. .trim(), onPressed: _intro, fontWeight: FontWeight.bold, - backgroundColor: Colors.blue.shade100, + backgroundColor: colours.introButtonBackground, ); final guidedButton = AppButton( @@ -455,7 +456,7 @@ audio may take a little time to download for the Web version. .trim(), onPressed: _guided, fontWeight: FontWeight.bold, - backgroundColor: Colors.purple.shade100, + backgroundColor: colours.guidedButtonBackground, ); //////////////////////////////////// @@ -469,7 +470,7 @@ audio may take a little time to download for the Web version. return ChoiceChip( label: Text(number.toString()), selected: _duration == number * 60, - selectedColor: Colors.lightGreenAccent, + selectedColor: colours.accentGreen, showCheckmark: false, // This will hide the tick mark. onSelected: (selected) { if (selected) { @@ -501,9 +502,9 @@ audio may take a little time to download for the Web version. final buttonsMatrix = Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.5), + color: colours.white.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(32), - border: Border.all(color: Colors.white.withValues(alpha: 0.5)), + border: Border.all(color: colours.white.withValues(alpha: 0.5)), ), child: Column( mainAxisSize: MainAxisSize.min,