Compare commits
	
		
			5 Commits
		
	
	
		
			0.1.2
			...
			c5f1a4e9ba
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c5f1a4e9ba | |||
| 538a298acd | |||
| cce878ccaa | |||
| 147178e4dd | |||
| c39e09b2b6 | 
| @@ -2,6 +2,7 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import '/models/item_type.dart'; | ||||
| import 'dart:io'; | ||||
| import 'package:package_info_plus/package_info_plus.dart'; | ||||
|  | ||||
| // Local | ||||
| import '/pages/tracked_item.dart'; | ||||
| @@ -26,10 +27,32 @@ class _HomePageState extends State<HomePage> { | ||||
|     setState(() {}); | ||||
|   } | ||||
|  | ||||
|   PackageInfo _packageInfo = PackageInfo( | ||||
|     appName: 'Unknown', | ||||
|     packageName: 'Unknown', | ||||
|     version: 'Unknown', | ||||
|     buildNumber: 'Unknown', | ||||
|   ); | ||||
|  | ||||
|   Future _initPackageInfo() async { | ||||
|     final PackageInfo info = await PackageInfo.fromPlatform(); | ||||
|     setState(() { | ||||
|       _packageInfo = info; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     // Get package details | ||||
|     _initPackageInfo(); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     Widget page; | ||||
|     Widget? dialog; | ||||
|  | ||||
|     switch (pageSelected) { | ||||
|       case 0: | ||||
|         page = TrackedItemPage( | ||||
| @@ -129,6 +152,8 @@ class _HomePageState extends State<HomePage> { | ||||
|           } | ||||
|         }); | ||||
|       }, | ||||
|       leading: Text("Menu"), | ||||
|       trailing: Text("v${_packageInfo.version}"), | ||||
|     ); | ||||
|  | ||||
|     Widget main = Container( | ||||
|   | ||||
| @@ -48,15 +48,15 @@ class _ProjectionPageState extends State<ProjectionPage> { | ||||
|     // Summaries for display as well as calculation of totals for projections. | ||||
|     Widget expenseSummary = SummaryCardForTotals( | ||||
|       list: DatabaseHelper.instance.getExpenses(), | ||||
|       summaryTypeLabel: ItemType.expense.title, | ||||
|       itemType: ItemType.expense, | ||||
|     ); | ||||
|     Widget incomeSummary = SummaryCardForTotals( | ||||
|       list: DatabaseHelper.instance.getIncomes(), | ||||
|       summaryTypeLabel: ItemType.income.title, | ||||
|       itemType: ItemType.income, | ||||
|     ); | ||||
|     Widget assetSummary = SummaryCardForTotals( | ||||
|       list: DatabaseHelper.instance.getAssets(), | ||||
|       summaryTypeLabel: ItemType.asset.title, | ||||
|       itemType: ItemType.asset, | ||||
|     ); | ||||
|  | ||||
|     // Calculations for the projections. | ||||
| @@ -155,14 +155,16 @@ class SummaryCardForTotals extends StatelessWidget { | ||||
|   const SummaryCardForTotals({ | ||||
|     super.key, | ||||
|     required this.list, | ||||
|     required this.summaryTypeLabel, | ||||
|     required this.itemType, | ||||
|   }); | ||||
|  | ||||
|   final Future<List<TrackedItem>> list; | ||||
|   final String summaryTypeLabel; | ||||
|   final ItemType itemType; | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     String summaryTypeLabel = itemType.title.toString(); | ||||
|  | ||||
|     return FutureBuilder<List<TrackedItem>>( | ||||
|         future: list, | ||||
|         builder: ( | ||||
| @@ -175,12 +177,9 @@ class SummaryCardForTotals extends StatelessWidget { | ||||
|  | ||||
|           // Calculate the total fields based on item type. | ||||
|           double dailyTotal = 0, monthlyTotal = 0, yearlyTotal = 0; | ||||
|           ItemType? itemType; | ||||
|           for (TrackedItem e in snapshot.data!) { | ||||
|             if (itemType == null) { | ||||
|               itemType = e.type!; | ||||
|             } else if (itemType != e.type) { | ||||
|               throw "List in SummaryCardForTotals has multiple item types, abort!"; | ||||
|             if (e.type != itemType) { | ||||
|               throw "List in SummaryCardForTotals has incorrect item types, abort!"; | ||||
|             } | ||||
|  | ||||
|             if (e.type == ItemType.asset) { | ||||
| @@ -194,9 +193,6 @@ class SummaryCardForTotals extends StatelessWidget { | ||||
|  | ||||
|           /* Load page variables based on calculated totals. */ | ||||
|           switch (itemType) { | ||||
|             case null: | ||||
|               break; | ||||
|  | ||||
|             case ItemType.asset: | ||||
|               _assetTotal = monthlyTotal; | ||||
|               break; | ||||
|   | ||||
| @@ -297,6 +297,21 @@ class _TrackedItemInputDialogState extends State<TrackedItemInputDialog> { | ||||
|     String amountText = | ||||
|         widget.amountText != null ? widget.amountText! : TrackedItem.amountText; | ||||
|  | ||||
|     Future<List<TrackedItem>> items; | ||||
|     switch (_type) { | ||||
|       case ItemType.expense: | ||||
|         items = DatabaseHelper.instance.getExpenses(); | ||||
|         break; | ||||
|       case ItemType.income: | ||||
|         items = DatabaseHelper.instance.getIncomes(); | ||||
|         break; | ||||
|       case ItemType.asset: | ||||
|         items = DatabaseHelper.instance.getAssets(); | ||||
|         break; | ||||
|       default: | ||||
|         throw UnimplementedError("Cannot find unimplemented type."); | ||||
|     } | ||||
|  | ||||
|     return Column( | ||||
|       // prevent AlertDialog from taking full vertical height. | ||||
|       mainAxisSize: MainAxisSize.min, | ||||
| @@ -336,15 +351,15 @@ class _TrackedItemInputDialogState extends State<TrackedItemInputDialog> { | ||||
|                 ? Text("New ${_type!.title}") | ||||
|                 : Text("Edit ${_type!.title}"), | ||||
|           ), | ||||
|           content: FutureBuilder<List<Expense>>( | ||||
|           content: FutureBuilder<List<TrackedItem>>( | ||||
|               // TODO / TBD -- This should no longer only be Expenses. | ||||
|               future: DatabaseHelper.instance.getExpenses(), | ||||
|               future: items, | ||||
|               builder: (BuildContext context, | ||||
|                   AsyncSnapshot<List<Expense>> snapshot) { | ||||
|                   AsyncSnapshot<List<TrackedItem>> snapshot) { | ||||
|                 if (!snapshot.hasData) { | ||||
|                   return Center(child: Text('Loading...')); | ||||
|                 } | ||||
|                 List<Expense> expenses = snapshot.data!; | ||||
|                 List<TrackedItem> expenses = snapshot.data!; | ||||
|                 return Form( | ||||
|                   key: _formKey, | ||||
|                   child: Column( | ||||
| @@ -392,7 +407,16 @@ class _TrackedItemInputDialogState extends State<TrackedItemInputDialog> { | ||||
|                             return "$amountText must be a valid number."; | ||||
|                           } | ||||
|                           if (double.parse(value) < 0) { | ||||
|                             return "Please use the Income page rather than having negative expenses."; | ||||
|                             switch (_type) { | ||||
|                               case ItemType.expense: | ||||
|                                 return "Please use the Income page."; | ||||
|  | ||||
|                               case ItemType.income: | ||||
|                                 return "Please use the Expense page."; | ||||
|  | ||||
|                               default: | ||||
|                                 break; | ||||
|                             } | ||||
|                           } | ||||
|                           if (double.parse(value) < 0.01) { | ||||
|                             return "$amountText must be one hundreth (0.01) or higher."; | ||||
|   | ||||
| @@ -5,11 +5,13 @@ | ||||
| import FlutterMacOS | ||||
| import Foundation | ||||
|  | ||||
| import package_info_plus | ||||
| import path_provider_foundation | ||||
| import sqflite_darwin | ||||
| import url_launcher_macos | ||||
|  | ||||
| func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { | ||||
|   FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) | ||||
|   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) | ||||
|   SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) | ||||
|   UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) | ||||
|   | ||||
							
								
								
									
										40
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -80,6 +80,22 @@ packages: | ||||
|     description: flutter | ||||
|     source: sdk | ||||
|     version: "0.0.0" | ||||
|   http: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: http | ||||
|       sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.0" | ||||
|   http_parser: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: http_parser | ||||
|       sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.1.2" | ||||
|   leak_tracker: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -136,6 +152,22 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.16.0" | ||||
|   package_info_plus: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: package_info_plus | ||||
|       sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "8.3.0" | ||||
|   package_info_plus_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: package_info_plus_platform_interface | ||||
|       sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.2.0" | ||||
|   path: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -421,6 +453,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.1" | ||||
|   win32: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: win32 | ||||
|       sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "5.12.0" | ||||
|   xdg_directories: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| name: expense_tracker | ||||
| homepage: https://git.hyperling.com/me/flutter-expense-tracker | ||||
| description: Track recurring expenses against income and liquid assets. | ||||
| publish_to: 'none' | ||||
| version: 0.1.2 | ||||
| version: 0.1.3 | ||||
|  | ||||
| environment: | ||||
|   sdk: ^3.6.1 | ||||
| @@ -9,6 +10,7 @@ environment: | ||||
| dependencies: | ||||
|   flutter: | ||||
|     sdk: flutter | ||||
|   package_info_plus: ^8.3.0 | ||||
|   path: ^1.9.0 | ||||
|   path_provider: ^2.1.5 | ||||
|   sqflite: ^2.4.1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user