Skip to content

Conversation

@ahmet-cetinkaya
Copy link
Owner

@ahmet-cetinkaya ahmet-cetinkaya commented Dec 22, 2025

🚀 Motivation and Context

Simplify complex UI structures by removing tab-based interfaces in favor of scrollable layouts. Introduce theme extension system for consistent page-level padding across the application. Consolidate inline component implementations to reduce architectural complexity while maintaining visual consistency.

⚙️ Implementation Details

This commit introduces a centralized theme-based spacing system and streamlines UI component layouts:

Theme Extension System:

  • Added PagePaddingTheme extension to ThemeData for consistent page-level padding
  • Implemented theme_service with centralized padding configuration
  • Updated app_theme.dart with new theme extension support

UI Layout Improvements:

  • Removed tab-based interfaces in favor of scrollable layouts
  • Simplified tag_details_page.dart (353 → reduced lines) by extracting components
  • Refactored today_page.dart for cleaner layout structure
  • Streamlined settings_page.dart and component layouts

Component Consolidation:

  • Extracted tag_statistics_view.dart as new shared component
  • Updated responsive_scaffold_layout.dart for better consistency
  • Standardized section_header.dart spacing

Affected Areas:

  • 32 files changed with 819 insertions and 884 deletions (net code reduction)
  • Features updated: app_usages, calendar, habits, notes, settings, sync, tags, tasks

📋 Checklist for Reviewer

  • Tests passed locally.
  • Commit history is clean and descriptive.
  • Documentation updated (if applicable).
  • Code quality standards were met (e.g., linter passed).

🔗 Related

No related issues or PRs.

Summary by Sourcery

Introduce a centralized theme-based page padding system and streamline multiple feature pages to use consistent scrollable layouts and simplified section headers.

New Features:

  • Add PagePaddingTheme extension and BuildContext helper to provide theme-driven page-level padding.
  • Create TagStatisticsView as a reusable tag statistics component used by the tag details page.

Enhancements:

  • Refine many feature pages (tags, app usages, habits, notes, tasks, settings, sync, about, marathon) to rely on centralized page padding instead of hard-coded paddings.
  • Simplify TagDetailsPage layout by replacing tabbed content with a scrollable view that embeds shared tag statistics.
  • Update tags, app usage, and statistics UIs to use inline text+options headers instead of the generic SectionHeader component in several places.
  • Adjust TagTimeBarChart and app usage lists for better embedding in scrollable parents and more consistent spacing.
  • Improve TagCard layout with minimum height constraints and better alignment in dense and non-dense modes.
  • Simplify SectionHeader API by removing custom padding support and standardizing its internal padding.

…e-based spacing

Simplify complex UI structures by removing tab-based interfaces in favor of scrollable layouts. Introduce theme extension system for consistent page-level padding across the application. Consolidate inline component implementations to reduce architectural complexity while maintaining visual consistency.
@ahmet-cetinkaya ahmet-cetinkaya added the enhancement New feature or request label Dec 22, 2025
@ahmet-cetinkaya ahmet-cetinkaya self-assigned this Dec 22, 2025
@ahmet-cetinkaya ahmet-cetinkaya added the enhancement New feature or request label Dec 22, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ahmet-cetinkaya, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refines the application's user interface by implementing a centralized, theme-based spacing system for consistent page layouts. It streamlines navigation by replacing tab-based interfaces with more flexible scrollable designs and consolidates UI logic by extracting shared components and standardizing existing ones. These changes aim to improve visual consistency, reduce code complexity, and enhance maintainability across various features including app usages, calendar, habits, notes, settings, sync, tags, and tasks.

Highlights

  • Centralized Theme-Based Spacing: Introduced a 'PagePaddingTheme' extension to 'ThemeData' and a 'pageBodyPadding' 'BuildContext' extension for consistent, responsive page-level padding across the application, dynamically adjusting for screen size.
  • Streamlined UI Layouts: Replaced tab-based interfaces with scrollable layouts in several pages, notably 'tag_details_page.dart' and 'today_page.dart', to simplify complex UI structures and improve user experience.
  • Component Consolidation and Refactoring: Extracted 'tag_statistics_view.dart' as a new shared component, refactored existing components like 'app_usage_statistics_view.dart', and standardized 'SectionHeader' spacing, leading to cleaner code and reduced architectural complexity.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@sourcery-ai
Copy link

sourcery-ai bot commented Dec 22, 2025

Reviewer's Guide

Introduces a centralized theme-based page padding system via a ThemeExtension and refactors multiple feature pages to use it, while simplifying several UI layouts (notably tag details, tags list, app usage, sync, and settings) away from tabbed/over-padded structures into scrollable, section-based views with standardized headers and spacing.

Sequence diagram for page-level padding resolution via theme extension

sequenceDiagram
  participant User
  participant Widget as FeaturePageState
  participant Ctx as BuildContext
  participant Theme as ThemeData
  participant Ext as PagePaddingTheme
  participant AppTheme

  User->>Widget: navigate to page
  Widget->>Ctx: build(context)
  Widget->>Ctx: pageBodyPadding
  activate Ctx
  Ctx->>Theme: Theme.of(context)
  activate Theme
  Theme-->>Ctx: themeData
  Ctx->>Theme: extension<PagePaddingTheme>()
  Theme-->>Ctx: Ext
  alt PagePaddingTheme present
    Ctx->>Ctx: check MediaQuery.sizeOf(context).width
    Ctx->>AppTheme: read screenSmall
    AppTheme-->>Ctx: screenSmall
    alt width <= screenSmall
      Ctx-->>Widget: EdgeInsets.symmetric(horizontal: AppTheme.sizeSmall, vertical: Ext.vertical)
    else width > screenSmall
      Ctx-->>Widget: EdgeInsets.symmetric(horizontal: Ext.horizontal, vertical: Ext.vertical)
    end
  else extension missing
    Ctx-->>Widget: EdgeInsets.zero
  end
  deactivate Ctx

  Widget->>Widget: build layout with Padding(padding: pageBodyPadding)
  Widget-->>User: rendered page with consistent spacing
Loading

Class diagram for centralized page padding theme and consumers

classDiagram
  class ThemeDataBuilder {
    +ThemeData buildThemeData()
    -ThemeData _createThemeData()
    -PagePaddingTheme _buildPagePaddingTheme()
  }

  class PagePaddingTheme {
    +double horizontal
    +double vertical
    +PagePaddingTheme(horizontal, vertical)
    +EdgeInsets padding
    +PagePaddingTheme copyWith(horizontal, vertical)
    +PagePaddingTheme lerp(other, t)
    +double lerpDouble(a, b, t)
  }

  class BuildContext {
  }

  class PagePaddingContext {
    +EdgeInsets pageBodyPadding
  }

  class AppTheme {
    +double screenSmall
    +double sizeSmall
    +ThemeData themeData
  }

  class TagDetailsPage {
    +String route
  }

  class _TagDetailsPageState {
    -ITranslationService _translationService
    -IThemeService _themeService
    +Widget build(context)
    -void _goBack()
  }

  class TagStatisticsView {
    +String tagId
    +TagStatisticsView(tagId)
  }

  class _TagStatisticsViewState {
    -ITranslationService _translationService
    -IThemeService _themeService
    -GlobalKey barChartKey
    -DateFilterSetting dateFilterSetting
    -DateTime startDate
    -DateTime endDate
    -Set~TagTimeCategory~ selectedCategories
    +Widget build(context)
  }

  class SectionHeader {
    +String title
    +IconData icon
    +Widget trailing
    +VoidCallback onTap
    +TextStyle titleStyle
    +Widget build(context)
  }

  ThemeDataBuilder --> PagePaddingTheme : builds
  AppTheme --> ThemeDataBuilder : used by
  ThemeDataBuilder --> AppTheme : uses sizeSmall
  BuildContext <|.. PagePaddingContext : extension
  PagePaddingContext --> PagePaddingTheme : reads extension
  PagePaddingContext --> AppTheme : uses screenSmall, sizeSmall

  TagDetailsPage --> _TagDetailsPageState : creates state
  _TagDetailsPageState --> TagStatisticsView : composes
  _TagDetailsPageState --> BuildContext : uses pageBodyPadding

  TagStatisticsView --> _TagStatisticsViewState : creates state
  _TagStatisticsViewState --> TagTimeBarChart : composes
  _TagStatisticsViewState --> TagTimeChartOptions : composes
  _TagStatisticsViewState --> ITranslationService : uses
  _TagStatisticsViewState --> IThemeService : uses

  SectionHeader --> AppTheme : uses spacing and text styles
Loading

File-Level Changes

Change Details Files
Centralized theme-based page padding via ThemeExtension and BuildContext extension, wired into ThemeData builder.
  • Added PagePaddingTheme ThemeExtension to represent horizontal/vertical page padding and support lerp/copyWith.
  • Exposed a BuildContext.pageBodyPadding extension that reads PagePaddingTheme from ThemeData and adapts horizontal padding on small screens.
  • Updated ThemeDataBuilder to register PagePaddingTheme in ThemeData.extensions with density-aware spacing values.
src/lib/presentation/ui/shared/services/theme_service/page_padding_theme.dart
src/lib/presentation/ui/shared/constants/app_theme.dart
src/lib/presentation/ui/shared/services/theme_service/theme_data_builder.dart
Refactored multiple pages to use centralized pageBodyPadding instead of ad-hoc Padding and adjusted layouts to scrollable, section-based structures.
  • Wrapped main bodies of details and settings-like pages (habits, notes, tasks, app usages, about, permissions, sync add/device list, debug, marathon, responsive scaffold layout) in Padding using context.pageBodyPadding.
  • Removed or simplified inner Padding/margin on headers, error/empty states, and lists to avoid double horizontal padding.
  • Adjusted some containers to SizedBox where only width constraints were needed, and removed redundant per-widget padding in favor of page-level padding.
src/lib/presentation/ui/features/sync/pages/add_sync_device_page/add_sync_device_page.dart
src/lib/presentation/ui/features/sync/pages/sync_devices_page/sync_devices_page.dart
src/lib/presentation/ui/shared/components/responsive_scaffold_layout.dart
src/lib/presentation/ui/features/about/pages/about_page.dart
src/lib/presentation/ui/features/habits/pages/habit_details_page.dart
src/lib/presentation/ui/features/notes/pages/note_details_page.dart
src/lib/presentation/ui/features/settings/pages/permissions_page.dart
src/lib/presentation/ui/features/app_usages/pages/app_usage_details_page.dart
src/lib/presentation/ui/features/app_usages/pages/app_usage_rules_page.dart
src/lib/presentation/ui/features/app_usages/pages/android_app_usage_debug_page.dart
src/lib/presentation/ui/features/tasks/pages/marathon_page.dart
src/lib/presentation/ui/features/sync/pages/add_sync_device_page/add_sync_device_page.dart
Simplified tag-related UIs by extracting a shared TagStatisticsView and converting TagDetailsPage to a scrollable, non-tabbed layout.
  • Removed TabController, tab bar, and notes/tasks/statistics tabs from TagDetailsPage in favor of a single-column scroll view using context.pageBodyPadding.
  • Extracted tag time statistics (date/category filters + TagTimeBarChart) into new TagStatisticsView with its own local date/category state and card presentation.
  • Adjusted TagTimeBarChart to be non-scrollable and shrink-wrapped so it fits inside outer scroll views without nested scrolling issues.
src/lib/presentation/ui/features/tags/pages/tag_details_page.dart
src/lib/presentation/ui/features/tags/components/tag_statistics_view.dart
src/lib/presentation/ui/features/tags/components/tag_time_bar_chart.dart
Standardized section headers and list option rows away from SectionHeader padding customization to simpler text+options rows.
  • Simplified SectionHeader by removing the configurable padding parameter and hard-coding a consistent left/right padding scheme.
  • Replaced SectionHeader usages that relied on custom padding (tags page list/time sections, app usage statistics header, habit records header, theme/language dialog headers, task details sub-tasks header, habit statistics header, etc.) with either plain Text+options rows or default SectionHeader.
  • Updated tests to drop assertions that depended on SectionHeader.custom padding behavior.
src/lib/presentation/ui/shared/components/section_header.dart
src/lib/presentation/ui/features/tags/pages/tags_page.dart
src/lib/presentation/ui/features/app_usages/components/app_usage_statistics_view.dart
src/lib/presentation/ui/features/habits/components/habit_details_content/components/habit_records_section.dart
src/lib/presentation/ui/features/habits/components/habit_details_content/habit_details_content.dart
src/lib/presentation/ui/features/settings/components/language_settings.dart
src/lib/presentation/ui/features/settings/components/theme_settings.dart
src/lib/presentation/ui/features/tasks/pages/task_details_page.dart
src/lib/presentation/ui/features/habits/components/habit_statistics_view.dart
src/test/presentation/ui/shared/components/section_header_test.dart
Layout and UX tweaks for feature pages (today calendar, tags list, app usages, sync, settings) to improve consistency and scroll behavior.
  • On TodayPage, removed outer Padding around habits/tasks sections so AnimatedSize wraps full section content; left inner structure intact while preserving filters and lists.
  • On TagsPage, replaced SectionHeader-based option bars with inline Row-based headers (title text + TagTimeChartOptions/TagListOptions) using left padding only.
  • In AppUsageStatisticsView, inlined the header row into the main build (with label, filters, compare toggle, save button) and replaced the custom StatisticsSummaryCards component with local Card-based summary tiles.
  • Adjusted TagCard to wrap ListTile in a constrained Container and added minTileHeight and consistent contentPadding to align list density.
  • Converted AppUsageList from ListView.separated to ListView.builder and moved vertical spacing concerns elsewhere if needed.
  • Enabled demo mode shortcut in AppUsageViewPage by skipping permission checks when DemoConfig.isDemoModeEnabled is true.
src/lib/presentation/ui/features/calendar/pages/today_page.dart
src/lib/presentation/ui/features/tags/components/tag_card.dart
src/lib/presentation/ui/features/tags/pages/tags_page.dart
src/lib/presentation/ui/features/app_usages/components/app_usage_statistics_view.dart
src/lib/presentation/ui/features/app_usages/components/app_usage_list.dart
src/lib/presentation/ui/features/app_usages/pages/app_usage_view_page.dart

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In AppUsageList, switching from ListView.separated to ListView.builder removes the inter-item spacing that was previously provided by separatorBuilder; if the tighter layout is not intentional, consider adding equivalent vertical spacing via item padding or explicit SizedBox widgets.
  • The new pattern of a left-aligned section label followed by horizontally scrollable/filter controls (e.g., in AppUsageStatisticsView, TagsPage, and TagStatisticsView) is implemented in several places with nearly identical Padding/Row structures; consider extracting a small reusable widget to avoid duplication and keep these headers visually consistent.
  • In TagStatisticsView, _themeService is only used to obtain a primary color for the icon background; you can simplify this by dropping the injected IThemeService and using Theme.of(context).colorScheme.primary instead, which reduces coupling to the theme service.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AppUsageList`, switching from `ListView.separated` to `ListView.builder` removes the inter-item spacing that was previously provided by `separatorBuilder`; if the tighter layout is not intentional, consider adding equivalent vertical spacing via item padding or explicit `SizedBox` widgets.
- The new pattern of a left-aligned section label followed by horizontally scrollable/filter controls (e.g., in `AppUsageStatisticsView`, `TagsPage`, and `TagStatisticsView`) is implemented in several places with nearly identical `Padding`/`Row` structures; consider extracting a small reusable widget to avoid duplication and keep these headers visually consistent.
- In `TagStatisticsView`, `_themeService` is only used to obtain a primary color for the icon background; you can simplify this by dropping the injected `IThemeService` and using `Theme.of(context).colorScheme.primary` instead, which reduces coupling to the theme service.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new PagePaddingTheme extension for consistent page-level padding across the application, automatically adjusting horizontal padding for small screens. This change involved updating numerous page and component files (e.g., AboutPage, AppUsageDetailsPage, HabitDetailsPage, NoteDetailsPage, PermissionsPage, MarathonPage, TaskDetailsPage, ResponsiveScaffoldLayout, AddSyncDevicePage, SyncDevicesPage) to utilize context.pageBodyPadding instead of hardcoded EdgeInsets.all or EdgeInsets.symmetric values. Consequently, the SectionHeader widget was refactored to remove its padding property, as padding is now managed by the parent context. Additionally, the AppUsageStatisticsView was updated to embed its header and filter options directly, replacing a StatisticsSummaryCards widget with a custom _buildStatCard implementation for displaying usage statistics. The AppUsageList was changed from ListView.separated to ListView.builder, removing explicit separators. A new TagStatisticsView component was introduced to TagDetailsPage to display tag-specific time statistics, replacing a tabbed interface that previously included tasks and notes. The TagTimeBarChart was updated to use shrinkWrap and NeverScrollableScrollPhysics. A Container wrapping ListTile in TagCard was deemed redundant and could be removed, and a custom lerpDouble implementation in PagePaddingTheme was noted as duplicative of dart:ui's version. Finally, a demo mode check was added to AppUsageViewPage to bypass permission checks, and an import for acore.dart was modified to hide Container to resolve a naming conflict.

@ahmet-cetinkaya
Copy link
Owner Author

Code review

Found 1 issue:

  1. Hardcoded spacing value instead of theme constant (CLAUDE.md says: "Use theme constants from src/lib/presentation/ui/shared/constants/app_theme.dart")

children: [
Expanded(
child: _buildStatCard(
_translationService.translate(SharedTranslationKeys.totalUsageLabel),
_formatDuration(totalSeconds),
),
),
const SizedBox(width: 8),

The same issue occurs at:

const SizedBox(width: 8),
Expanded(
child: _buildStatCard(
_translationService.translate(SharedTranslationKeys.averageDailyLabel),
_formatDuration(avgDaily),
),
),
const SizedBox(width: 8),


Both instances of const SizedBox(width: 8) should use AppTheme.sizeSmall for consistency with the project's theme-based spacing system.

@ahmet-cetinkaya ahmet-cetinkaya merged commit fc61806 into main Dec 22, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants