Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class _OnboardingDialogState extends State<OnboardingDialog> {
ResponsiveDialogHelper.showResponsiveDialog(
context: context,
child: const PermissionsPage(),
size: DialogSize.large,
size: DialogSize.xLarge,
);
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib/presentation/ui/features/about/pages/about_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:whph/main.dart';
import 'package:whph/presentation/ui/features/about/components/app_about.dart';
import 'package:whph/presentation/ui/features/about/constants/about_translation_keys.dart';
import 'package:whph/presentation/ui/shared/constants/app_theme.dart';
import 'package:whph/presentation/ui/shared/services/abstraction/i_translation_service.dart';
import 'package:whph/presentation/ui/shared/constants/app_theme.dart';

class AboutPage extends StatefulWidget {
static const String route = '/about';
Expand All @@ -24,9 +24,9 @@ class _AboutPageState extends State<AboutPage> {
elevation: 0,
title: Text(_translationService.translate(AboutTranslationKeys.aboutTitle)),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(AppTheme.sizeLarge),
body: Padding(
padding: context.pageBodyPadding,
child: SingleChildScrollView(
child: AppAbout(),
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:whph/presentation/ui/shared/components/detail_table.dart';
import 'package:whph/presentation/ui/shared/constants/app_theme.dart';
import 'package:whph/presentation/ui/shared/constants/shared_translation_keys.dart';
import 'package:whph/presentation/ui/shared/constants/shared_ui_constants.dart';
import 'package:acore/acore.dart';
import 'package:acore/acore.dart' hide Container;
import 'package:whph/presentation/ui/shared/models/dropdown_option.dart';
import 'package:whph/presentation/ui/shared/utils/app_theme_helper.dart';
import 'package:whph/presentation/ui/shared/utils/async_error_handler.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,10 @@ class AppUsageListState extends State<AppUsageList> with PaginationMixin<AppUsag
_appUsageList!.hasNext && widget.paginationMode == PaginationMode.infinityScroll && isLoadingMore;
final extraItemCount = (showLoadMore || showInfinityLoading) ? 1 : 0;

return ListView.separated(
return ListView.builder(
controller: _scrollController,
physics: const AlwaysScrollableScrollPhysics(),
itemCount: _appUsageList!.items.length + extraItemCount,
separatorBuilder: (context, index) => const SizedBox(height: AppTheme.size3XSmall),
itemBuilder: (context, index) {
if (index == _appUsageList!.items.length && showLoadMore) {
return Padding(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'package:whph/main.dart';
import 'package:whph/presentation/ui/features/app_usages/constants/app_usage_translation_keys.dart';
import 'package:whph/presentation/ui/features/app_usages/components/daily_usage_chart.dart';
import 'package:whph/presentation/ui/features/app_usages/components/hourly_usage_chart.dart';
import 'package:whph/presentation/ui/features/app_usages/components/statistics_summary_cards.dart';
import 'package:whph/presentation/ui/shared/constants/app_theme.dart';
import 'package:whph/presentation/ui/shared/constants/shared_translation_keys.dart';
import 'package:whph/presentation/ui/shared/services/abstraction/i_translation_service.dart';
Expand All @@ -18,6 +17,7 @@ import 'package:whph/presentation/ui/shared/constants/setting_keys.dart';
import 'package:whph/presentation/ui/features/app_usages/models/app_usage_statistics_settings.dart';
import 'package:acore/acore.dart' hide Container;
import 'package:intl/intl.dart';
import 'package:whph/presentation/ui/shared/components/section_header.dart';

class AppUsageStatisticsView extends PersistentListOptionsBase {
final String appUsageId;
Expand Down Expand Up @@ -178,9 +178,72 @@ class _AppUsageStatisticsViewState extends PersistentListOptionsBaseState<AppUsa
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: AppTheme.sizeMedium,
children: [
_buildHeaderRow(),
SectionHeader(
title: _translationService.translate(SharedTranslationKeys.statisticsLabel),
expandTrailing: true,
trailing: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
DateRangeFilter(
dateFilterSetting: _dateFilterSetting,
selectedStartDate: _dateFilterSetting != null ? _startDate : null,
selectedEndDate: _dateFilterSetting != null ? _endDate : null,
onDateFilterChange: (start, end) {
setState(() {
_startDate = start;
_endDate = end;
_updateComparisonDates();
handleFilterChange();
});
_fetchStatistics();
},
onDateFilterSettingChange: (setting) {
setState(() {
_dateFilterSetting = setting;
if (setting?.isQuickSelection == true) {
final range = setting!.calculateCurrentDateRange();
_startDate = range.startDate;
_endDate = range.endDate;
} else if (setting != null) {
_startDate = setting.startDate;
_endDate = setting.endDate;
} else {
_startDate = null;
_endDate = null;
}
_updateComparisonDates();
handleFilterChange();
});
_fetchStatistics();
},
),
const SizedBox(width: AppTheme.sizeSmall),
IconButton(
icon: Icon(Icons.compare_arrows),
color: _showComparison ? Theme.of(context).colorScheme.primary : null,
tooltip: _translationService.translate(SharedTranslationKeys.compareWithPreviousLabel),
onPressed: () {
setState(() {
_showComparison = !_showComparison;
_updateComparisonDates();
handleFilterChange();
});
_fetchStatistics();
},
),
const SizedBox(width: AppTheme.sizeSmall),
SaveButton(
hasUnsavedChanges: hasUnsavedChanges,
showSavedMessage: showSavedMessage,
onSave: saveFilterSettings,
tooltip: _translationService.translate(SharedTranslationKeys.saveListOptions)),
],
),
),
),
if (_isLoading)
_buildLoadingState()
else if (_errorMessage != null)
Expand All @@ -189,74 +252,16 @@ class _AppUsageStatisticsViewState extends PersistentListOptionsBaseState<AppUsa
_buildEmptyState()
else if (_statistics != null) ...[
_buildSummaryCards(),
const SizedBox(height: AppTheme.sizeSmall),
_buildDailyChart(),
const SizedBox(height: AppTheme.sizeSmall),
_buildHourlyChart(),
],
],
),
);
}

Widget _buildHeaderRow() {
return Row(
children: [
DateRangeFilter(
dateFilterSetting: _dateFilterSetting,
selectedStartDate: _dateFilterSetting != null ? _startDate : null,
selectedEndDate: _dateFilterSetting != null ? _endDate : null,
onDateFilterChange: (start, end) {
setState(() {
_startDate = start;
_endDate = end;
_updateComparisonDates();
handleFilterChange();
});
_fetchStatistics();
},
onDateFilterSettingChange: (setting) {
setState(() {
_dateFilterSetting = setting;
if (setting?.isQuickSelection == true) {
final range = setting!.calculateCurrentDateRange();
_startDate = range.startDate;
_endDate = range.endDate;
} else if (setting != null) {
_startDate = setting.startDate;
_endDate = setting.endDate;
} else {
_startDate = null;
_endDate = null;
}
_updateComparisonDates();
handleFilterChange();
});
_fetchStatistics();
},
),
const SizedBox(width: AppTheme.sizeSmall),
IconButton(
icon: Icon(Icons.compare_arrows),
color: _showComparison ? Theme.of(context).colorScheme.primary : null,
tooltip: _translationService.translate(SharedTranslationKeys.compareWithPreviousLabel),
onPressed: () {
setState(() {
_showComparison = !_showComparison;
_updateComparisonDates();
handleFilterChange();
});
_fetchStatistics();
},
),
const SizedBox(width: AppTheme.sizeSmall),
SaveButton(
hasUnsavedChanges: hasUnsavedChanges,
showSavedMessage: showSavedMessage,
onSave: saveFilterSettings,
tooltip: _translationService.translate(SharedTranslationKeys.saveListOptions)),
],
);
}

Widget _buildLoadingState() => Center(
child: Padding(
padding: const EdgeInsets.all(AppTheme.size4XLarge),
Expand Down Expand Up @@ -307,13 +312,67 @@ class _AppUsageStatisticsViewState extends PersistentListOptionsBaseState<AppUsa
peakHour = h.hour;
}
}
return StatisticsSummaryCards(
totalUsage: _formatDuration(totalSeconds),
averageDaily: _formatDuration(avgDaily),
peakHour: _formatHour(peakHour),
totalUsageLabel: _translationService.translate(SharedTranslationKeys.totalUsageLabel),
averageDailyLabel: _translationService.translate(SharedTranslationKeys.averageDailyLabel),
peakHourLabel: _translationService.translate(SharedTranslationKeys.peakHourLabel),
return Row(
children: [
Expanded(
child: Column(
children: [
Row(
children: [
Expanded(
child: _buildStatCard(
_translationService.translate(SharedTranslationKeys.totalUsageLabel),
_formatDuration(totalSeconds),
),
),
const SizedBox(width: AppTheme.sizeSmall),
Expanded(
child: _buildStatCard(
_translationService.translate(SharedTranslationKeys.averageDailyLabel),
_formatDuration(avgDaily),
),
),
const SizedBox(width: AppTheme.sizeSmall),
Expanded(
child: _buildStatCard(
_translationService.translate(SharedTranslationKeys.peakHourLabel),
_formatHour(peakHour),
),
),
],
),
],
),
),
],
);
}

Widget _buildStatCard(String label, String value) {
return Card(
color: AppTheme.surface1,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: AppTheme.sizeMedium, horizontal: AppTheme.sizeSmall),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
label,
style: AppTheme.bodySmall,
textAlign: TextAlign.center,
),
const SizedBox(height: AppTheme.size2XSmall),
Text(
value,
style: AppTheme.bodyMedium.copyWith(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
],
),
),
),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class _DeviceSelectDropdownState extends State<DeviceSelectDropdown> {

await ResponsiveDialogHelper.showResponsiveDialog(
context: context,
size: DialogSize.large,
size: DialogSize.xLarge,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
final filteredDevices = _availableDevices.where((device) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:whph/core/application/features/app_usages/services/abstraction/i
import 'package:whph/core/application/features/app_usages/services/abstraction/i_app_usage_tag_rule_repository.dart';
import 'package:whph/core/application/features/app_usages/services/abstraction/i_app_usage_tag_repository.dart';
import 'package:whph/core/application/features/app_usages/services/abstraction/i_app_usage_filter_service.dart';
import 'package:whph/presentation/ui/shared/constants/app_theme.dart';

/// Debug screen to test and compare app usage calculation methods.
/// This helps identify why usage statistics are inflated compared to Digital Wellbeing.
Expand Down Expand Up @@ -91,7 +92,7 @@ class _AndroidAppUsageDebugPageState extends State<AndroidAppUsageDebugPage> {
title: const Text('App Usage Debug'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
padding: context.pageBodyPadding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import 'package:whph/presentation/ui/features/app_usages/components/app_usage_de
import 'package:whph/presentation/ui/features/app_usages/components/app_usage_statistics_view.dart';
import 'package:whph/presentation/ui/features/app_usages/services/app_usages_service.dart';
import 'package:whph/presentation/ui/shared/constants/app_theme.dart';
import 'package:whph/presentation/ui/shared/services/abstraction/i_translation_service.dart';
import 'package:whph/presentation/ui/shared/services/abstraction/i_theme_service.dart';
import 'package:whph/presentation/ui/shared/constants/shared_translation_keys.dart';
import 'package:whph/presentation/ui/shared/components/section_header.dart';

class AppUsageDetailsPage extends StatefulWidget {
static const String route = '/app-usages/details';
Expand All @@ -23,7 +20,6 @@ class AppUsageDetailsPage extends StatefulWidget {

class _AppUsageDetailsPageState extends State<AppUsageDetailsPage> {
final _appUsagesService = container.resolve<AppUsagesService>();
final _translationService = container.resolve<ITranslationService>();
final _themeService = container.resolve<IThemeService>();

bool _hasChanges = false;
Expand Down Expand Up @@ -102,9 +98,9 @@ class _AppUsageDetailsPageState extends State<AppUsageDetailsPage> {
),
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(AppTheme.sizeLarge),
body: Padding(
padding: context.pageBodyPadding,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expand All @@ -114,16 +110,9 @@ class _AppUsageDetailsPageState extends State<AppUsageDetailsPage> {
onAppUsageUpdated: _onAppUsageUpdated,
),

const SizedBox(height: 24),
const SizedBox(height: AppTheme.sizeMedium),

// App Usage Statistics Section
SectionHeader(
title: _translationService.translate(SharedTranslationKeys.statisticsLabel),
padding: EdgeInsets.zero,
titleStyle: AppTheme.bodyLarge,
),
const SizedBox(height: 16),

AppUsageStatisticsView(
appUsageId: widget.appUsageId,
onError: (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class _AppUsageRulesPageState extends State<AppUsageRulesPage> with SingleTicker
],
),
body: Padding(
padding: const EdgeInsets.all(AppTheme.sizeLarge),
padding: context.pageBodyPadding,
child: Column(
children: [
// Tab Selection
Expand Down
Loading