Skip to content
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ test/**/build/
*.pem

env_config.txt

# FVM Version Cache
.fvm/
17 changes: 10 additions & 7 deletions lib/about.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class AboutPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context, listen: false);
final textSizeOffset = Provider.of<AppState>(context, listen: false).getTextSizeOffset();
final textSizeOffset =
Provider.of<AppState>(context, listen: false).getTextSizeOffset();

return Scaffold(
appBar: AppBar(
Expand All @@ -27,7 +28,9 @@ class AboutPage extends StatelessWidget {
S.of(context).about,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 17 + Provider.of<AppState>(context, listen: false).getTextSizeOffset(),
fontSize: 17 +
Provider.of<AppState>(context, listen: false)
.getTextSizeOffset(),
),
),
),
Expand All @@ -42,15 +45,15 @@ class AboutPage extends StatelessWidget {
S.of(context).application,
textSizeOffset,
),

InfoCardWidgets.buildInfoCard(
context,
icon: CupertinoIcons.info_circle,
title: "Name",
subtitle: S.of(context).appName,
textSizeOffset: textSizeOffset,
),

FutureBuilder<String>(
future: _getAppVersion(),
builder: (context, snapshot) {
Expand All @@ -63,7 +66,7 @@ class AboutPage extends StatelessWidget {
);
},
),

InfoCardWidgets.buildInfoCard(
context,
icon: CupertinoIcons.person,
Expand All @@ -72,7 +75,7 @@ class AboutPage extends StatelessWidget {
textSizeOffset: textSizeOffset,
linkUrl: 'https://linktr.ee/byackee',
),

InfoCardWidgets.buildLinkCard(
context,
title: 'Linktree',
Expand All @@ -89,7 +92,7 @@ class AboutPage extends StatelessWidget {
S.of(context).thanks,
textSizeOffset,
),

InfoCardWidgets.buildThanksCard(
context,
title: S.of(context).thankYouMessage,
Expand Down
37 changes: 23 additions & 14 deletions lib/app_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {

// --- Gestion du compteur d'ouvertures de l'app pour la popup dons ---
int _appOpenCount = 0;
int _lastDonationPopupTimestamp = 0; // Timestamp de la dernière fois que la popup a été affichée
int _lastDonationPopupTimestamp =
0; // Timestamp de la dernière fois que la popup a été affichée
int get appOpenCount => _appOpenCount;

// Optimisation: Éviter les notifyListeners multiples
Expand All @@ -82,10 +83,10 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {
/// Retourne true si la popup dons doit être affichée (après 10 ouvertures ET au moins 1h depuis la dernière)
bool get shouldShowDonationPopup {
if (_appOpenCount < 10) return false;

final currentTimestamp = DateTime.now().millisecondsSinceEpoch;
final oneHourInMillis = 60 * 60 * 1000; // 1 heure en millisecondes

// Vérifier si au moins 1 heure s'est écoulée depuis la dernière popup
return (currentTimestamp - _lastDonationPopupTimestamp) >= oneHourInMillis;
}
Expand All @@ -95,12 +96,14 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {
loadAppOpenCount(); // Charger le compteur d'ouvertures
loadLastDonationPopupTimestamp(); // Charger le timestamp de la dernière popup
incrementAppOpenCount(); // Incrémenter à chaque lancement
WidgetsBinding.instance.addObserver(this); // Add observer to listen to system changes
WidgetsBinding.instance
.addObserver(this); // Add observer to listen to system changes
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this); // Remove observer when AppState is disposed
WidgetsBinding.instance
.removeObserver(this); // Remove observer when AppState is disposed
super.dispose();
}

Expand All @@ -117,26 +120,28 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {
// Load settings from SharedPreferences
Future<void> _loadSettings() async {
final prefs = await SharedPreferences.getInstance();

// Regrouper toutes les mises à jour pour éviter les notifications multiples
batchUpdate(() {
isDarkTheme = prefs.getBool('isDarkTheme') ?? false;
themeMode = prefs.getString('themeMode') ?? 'auto'; // Load theme mode
selectedTextSize = prefs.getString('textSize') ?? 'normal';
selectedLanguage = prefs.getString('language') ?? 'en';
evmAddresses = prefs.getStringList('evmAddresses'); // Load EVM addresses
_showAmounts = prefs.getBool('showAmounts') ?? true; // Charge la préférence du montant affiché
_showAmounts = prefs.getBool('showAmounts') ??
true; // Charge la préférence du montant affiché

// Charger les paramètres du portfolio
_showTotalInvested = prefs.getBool('showTotalInvested') ?? false;
_showNetTotal = prefs.getBool('showNetTotal') ?? true;
_manualAdjustment = prefs.getDouble('manualAdjustment') ?? 0.0;
_showYamProjection = prefs.getBool('showYamProjection') ?? true;
_initialInvestmentAdjustment = prefs.getDouble('initialInvestmentAdjustment') ?? 0.0;

_initialInvestmentAdjustment =
prefs.getDouble('initialInvestmentAdjustment') ?? 0.0;

_applyTheme(); // Apply the theme based on the loaded themeMode
});

// Charger la couleur primaire séparément car elle est asynchrone
_primaryColor = await getSavedPrimaryColor(); // Load primary color
_notifyListenersIfNeeded();
Expand All @@ -151,7 +156,8 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {
void toggleShowAmounts() async {
_showAmounts = !_showAmounts;
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('showAmounts', _showAmounts); // Sauvegarde la préférence utilisateur
await prefs.setBool(
'showAmounts', _showAmounts); // Sauvegarde la préférence utilisateur
_notifyListenersIfNeeded(); // Notifie les widgets dépendants
}

Expand Down Expand Up @@ -190,7 +196,8 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {
// Update dark/light theme directly and save to SharedPreferences (for manual switch)
void updateTheme(bool value) async {
isDarkTheme = value;
themeMode = value ? 'dark' : 'light'; // Set theme mode based on manual selection
themeMode =
value ? 'dark' : 'light'; // Set theme mode based on manual selection
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('isDarkTheme', value);
await prefs.setString('themeMode', themeMode); // Save theme mode
Expand Down Expand Up @@ -292,13 +299,15 @@ class AppState extends ChangeNotifier with WidgetsBindingObserver {

Future<void> loadLastDonationPopupTimestamp() async {
final prefs = await SharedPreferences.getInstance();
_lastDonationPopupTimestamp = prefs.getInt('lastDonationPopupTimestamp') ?? 0;
_lastDonationPopupTimestamp =
prefs.getInt('lastDonationPopupTimestamp') ?? 0;
}

Future<void> updateLastDonationPopupTimestamp() async {
final prefs = await SharedPreferences.getInstance();
_lastDonationPopupTimestamp = DateTime.now().millisecondsSinceEpoch;
await prefs.setInt('lastDonationPopupTimestamp', _lastDonationPopupTimestamp);
await prefs.setInt(
'lastDonationPopupTimestamp', _lastDonationPopupTimestamp);
}

// Méthode pour regrouper les mises à jour
Expand Down
51 changes: 28 additions & 23 deletions lib/components/charts/chart_builders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@ import 'package:realtoken_asset_tracker/app_state.dart';
import 'package:realtoken_asset_tracker/generated/l10n.dart';
import 'package:realtoken_asset_tracker/utils/currency_utils.dart';
import 'package:realtoken_asset_tracker/utils/date_utils.dart';
import 'package:realtoken_asset_tracker/models/apy_record.dart';
import 'package:provider/provider.dart';

/// Factory pour construire les éléments de graphiques de manière standardisée
/// Réduit la duplication dans GenericChartWidget
class ChartBuilders {

/// Construit les données de grille standardisées pour les graphiques
static FlGridData buildStandardGridData() {
return FlGridData(
show: true,
drawVerticalLine: false,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(0.15),
color: Colors.grey.withValues(alpha: 0.15),
strokeWidth: 1,
);
},
Expand Down Expand Up @@ -78,7 +76,8 @@ class ChartBuilders {
currencyUtils.currencySymbol,
);
} else {
formattedValue = '$valuePrefix${value.toStringAsFixed(1)}$valueSuffix';
formattedValue =
'$valuePrefix${value.toStringAsFixed(1)}$valueSuffix';
}

return Padding(
Expand Down Expand Up @@ -148,7 +147,8 @@ class ChartBuilders {
currencyUtils.currencySymbol,
);
} else {
formattedValue = '$valuePrefix${value.toStringAsFixed(1)}$valueSuffix';
formattedValue =
'$valuePrefix${value.toStringAsFixed(1)}$valueSuffix';
}

return Padding(
Expand Down Expand Up @@ -191,7 +191,8 @@ class ChartBuilders {
TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 12 + (Provider.of<AppState>(context, listen: false).getTextSizeOffset()),
fontSize: 12 +
(Provider.of<AppState>(context, listen: false).getTextSizeOffset()),
),
);
}
Expand Down Expand Up @@ -239,7 +240,7 @@ class ChartBuilders {
backDrawRodData: BackgroundBarChartRodData(
show: true,
toY: maxY,
color: Colors.grey.withOpacity(0.1),
color: Colors.grey.withValues(alpha: 0.1),
),
);
}
Expand Down Expand Up @@ -275,28 +276,30 @@ class ChartBuilders {
final isLast = spot.x == barData.spots.length - 1;
final int dataLength = barData.spots.length;
int step = 1;

if (dataLength > 20) {
step = (dataLength / 20).ceil();
} else if (dataLength > 10) {
step = 2;
}

final isInteresting = spot.x % step == 0;
return isFirst || isLast || isInteresting;
},
),
belowBarData: showArea ? BarAreaData(
show: true,
gradient: LinearGradient(
colors: [
color.withOpacity(0.3),
color.withOpacity(0.05),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
) : BarAreaData(show: false),
belowBarData: showArea
? BarAreaData(
show: true,
gradient: LinearGradient(
colors: [
color.withValues(alpha: 0.3),
color.withValues(alpha: 0.05),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
)
: BarAreaData(show: false),
);
}

Expand Down Expand Up @@ -325,7 +328,8 @@ class ChartBuilders {
}

/// Construit une clé de période standardisée pour le regroupement de données
static String buildPeriodKey(DateTime date, String selectedPeriod, BuildContext context) {
static String buildPeriodKey(
DateTime date, String selectedPeriod, BuildContext context) {
if (selectedPeriod == S.of(context).day) {
return DateFormat('yyyy/MM/dd').format(date);
} else if (selectedPeriod == S.of(context).week) {
Expand All @@ -346,7 +350,8 @@ class ChartBuilders {
}

/// Construit un widget de carte vide standardisé
static Widget buildEmptyCard(BuildContext context, AppState appState, String message) {
static Widget buildEmptyCard(
BuildContext context, AppState appState, String message) {
return Card(
elevation: 0,
shape: RoundedRectangleBorder(
Expand All @@ -367,4 +372,4 @@ class ChartBuilders {
),
);
}
}
}
Loading