Skip to content

Commit

Permalink
Merge pull request #36 from nullhandler/search-fn
Browse files Browse the repository at this point in the history
Added search txns , Play store redirect
  • Loading branch information
nullhandler authored Apr 10, 2024
2 parents 48f4a4a + 41c4082 commit da09a4a
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 27 deletions.
1 change: 1 addition & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flutter build apk
1 change: 1 addition & 0 deletions lib/const.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Const {
static const successTitle = "Success!";
static const git = "https://github.com/nullhandler/vase";
static const tg = "https://t.me/vase_flutter";
static const ps = 'https://play.google.com/store/apps/details?id=com.github.nullhandler.vase';
static const flaticonURL = "https://www.flaticon.com/authors/kiranshastry";
static const updateCheck =
'https://raw.githubusercontent.com/nullhandler/vase/main/update.json';
Expand Down
1 change: 1 addition & 0 deletions lib/screens/accounts/account_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AccountList extends StatelessWidget {
Card(
margin: const EdgeInsets.all(0),
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: accounts.length,
shrinkWrap: true,
itemBuilder: (context, pos) {
Expand Down
39 changes: 29 additions & 10 deletions lib/screens/transactions/date_list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,27 @@ import 'trans_model.dart';
class DateListItem extends StatelessWidget {
final String date;
final List<Transaction> transactions;
final bool isSearch;

const DateListItem({Key? key, required this.date, required this.transactions})
const DateListItem(
{Key? key,
required this.date,
required this.transactions,
this.isSearch = false})
: super(key: key);

@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
child: DateChip(
label: date,
transStats: Get.find<TransController>().dailyStats[date],
if (!isSearch)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
child: DateChip(
label: date,
transStats: Get.find<TransController>().dailyStats[date],
),
),
),
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ListView.builder(
Expand All @@ -49,8 +55,17 @@ class DateListItem extends StatelessWidget {
}
return ListTile(
onTap: () {
Get.to(NewTransaction(),
arguments: {"edit": true, "transaction": transaction});
if (isSearch) {
Get.off(() => NewTransaction(), arguments: {
"edit": true,
"transaction": transaction
});
} else {
Get.to(() => NewTransaction(), arguments: {
"edit": true,
"transaction": transaction
});
}
},
leading: CircleAvatar(
child: SizedBox(
Expand Down Expand Up @@ -96,7 +111,11 @@ class DateListItem extends StatelessWidget {
showDynamicColor: transaction.toAccountId == null,
),
Text(
DateFormat.jm('en_US').format(transaction.createdAt),
isSearch
? DateFormat('dd-MM-yyyy | hh:mm a')
.format(transaction.createdAt)
: DateFormat.jm('en_US')
.format(transaction.createdAt),
style: secondaryTextStyle,
)
],
Expand Down
71 changes: 71 additions & 0 deletions lib/screens/transactions/search_trans.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vase/enums.dart';
import 'package:vase/screens/transactions/date_list_item.dart';
import 'package:vase/screens/transactions/trans_controller.dart';
import 'package:vase/screens/widgets/empty.dart';

class CustomSearchDelegate extends SearchDelegate<String> {
final TransController _controller = Get.find<TransController>();

Widget results() {
return Obx(() {
_controller.query.value = query;
_controller.searchTransactions();
if (_controller.searchTxns.isEmpty &&
_controller.searchTransState.value != VaseState.loading ||
query == '') {
return const EmptyWidget(
assetName: "assets/img/no_txn.svg",
label: "No Transactions Found !");
} else if (_controller.searchTxns.isEmpty &&
_controller.transState.value == VaseState.loading) {
return const Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(top: 20),
shrinkWrap: true,
itemCount: _controller.searchTxns.length,
itemBuilder: (context, pos) {
return DateListItem(
isSearch: true,
date: _controller.searchTxns.keys.elementAt(pos),
transactions: _controller.searchTxns.values.elementAt(pos));
});
});
}

@override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
query = '';
_controller.query.value = '';
},
),
];
}

@override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Get.back(),
);
}

@override
Widget buildResults(BuildContext context) {
return results();
}

@override
Widget buildSuggestions(BuildContext context) {
return results();
}
}
56 changes: 41 additions & 15 deletions lib/screens/transactions/trans_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ import 'trans_model.dart';
class TransController extends GetxController {
Rx<DateTime> currentDate = DateTime.now().obs;
DbController dbController = Get.find();
RxString query = ''.obs;
Rx<VaseState> transState = VaseState.loading.obs;
Rx<VaseState> searchTransState = VaseState.loading.obs;
RxMap<String, List<Transaction>> transactions =
<String, List<Transaction>>{}.obs;
RxMap<String, List<Transaction>> searchTxns =
<String, List<Transaction>>{}.obs;
Rx<TransStats> monthlyStats = TransStats(0, 0, 0).obs;
RxMap<String, TransStats> dailyStats = <String, TransStats>{}.obs;

Expand All @@ -34,11 +38,25 @@ class TransController extends GetxController {
WHERE created_at BETWEEN ${Utils.getFirstDate(currentDate.value)} AND ${Utils.getLastDate(currentDate.value)}
ORDER BY created_at DESC''',
);
parseTransactions(transList);
parseTransactions(transList, false);
transState.value = VaseState.loaded;
}

void parseTransactions(List<Map<String, Object?>> list) {
Future<void> searchTransactions() async {
// monthlyStats.value = TransStats(0, 0, 0);
// dailyStats.clear();
searchTransState.value = VaseState.loading;
var sTransList = await dbController.db
.rawQuery('''SELECT * from ${Const.trans} LEFT JOIN ${Const.transLinks}
on ${Const.transLinks}.trans_id = ${Const.trans}.id
WHERE created_at BETWEEN ${Utils.getFirstDate(currentDate.value)} AND ${Utils.getLastDate(currentDate.value)}
AND desc LIKE ?
ORDER BY created_at DESC''', ['%${query.value}%']);
parseTransactions(sTransList, true);
searchTransState.value = VaseState.loaded;
}

void parseTransactions(List<Map<String, Object?>> list, bool isSearch) {
Map<String, List<Transaction>> dateWiseTransactions =
<String, List<Transaction>>{};
Map<String, List<Map<String, Object?>>> dateWiseRaw =
Expand All @@ -64,29 +82,37 @@ class TransController extends GetxController {
} else {
tempList.addAll(txnList.map<Transaction>((rawTrans) {
Transaction trans = Transaction.fromJson(rawTrans);
(dailyStats[date] ??= TransStats(0, 0, 0)).total += trans.amount;
if (trans.amount.isNegative) {
(dailyStats[date] ??= TransStats(0, 0, 0)).expense +=
trans.amount;
} else {
(dailyStats[date] ??= TransStats(0, 0, 0)).income += trans.amount;
}
monthlyStats.update((stats) {
stats?.total += trans.amount;
if (!isSearch) {
(dailyStats[date] ??= TransStats(0, 0, 0)).total += trans.amount;
if (trans.amount.isNegative) {
stats?.expense += trans.amount;
(dailyStats[date] ??= TransStats(0, 0, 0)).expense +=
trans.amount;
} else {
stats?.income += trans.amount;
(dailyStats[date] ??= TransStats(0, 0, 0)).income +=
trans.amount;
}
});
monthlyStats.update((stats) {
stats?.total += trans.amount;
if (trans.amount.isNegative) {
stats?.expense += trans.amount;
} else {
stats?.income += trans.amount;
}
});
}

return trans;
}));
}
});
tempList.sort((a, b) => b.createdAt.compareTo(a.createdAt));
dateWiseTransactions[date] = tempList;
});
transactions.value = dateWiseTransactions;
if (isSearch) {
searchTxns.value = dateWiseTransactions;
} else {
transactions.value = dateWiseTransactions;
}
}

void refreshListIfNeeded(DateTime dateTime) {
Expand Down
14 changes: 13 additions & 1 deletion lib/screens/transactions/transactions_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:vase/enums.dart';
import 'package:vase/screens/dashboard/dashboard_screen.dart';
import 'package:vase/screens/transactions/date_list_item.dart';
import 'package:vase/screens/transactions/monthly_stats_widget.dart';
import 'package:vase/screens/transactions/search_trans.dart';
import 'package:vase/screens/widgets/empty.dart';
import 'package:vase/widgets/wrapper.dart';

Expand Down Expand Up @@ -39,7 +40,18 @@ class Transactions extends StatelessWidget {
icon: const Icon(Icons.line_axis_outlined)),
),
),
)
),
Padding(
padding: const EdgeInsets.only(right: 10),
child: IconButton(
onPressed: () async {
await showSearch(
context: context,
delegate: CustomSearchDelegate(),
);
},
icon: const Icon(Icons.search_rounded)),
),
],
),
body: Obx(() {
Expand Down
5 changes: 5 additions & 0 deletions lib/screens/user/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ class UserSettings extends StatelessWidget {
title: const Text("Github Repository"),
trailing: const Icon(Icons.code_outlined),
),
ListTile(
onTap: () => Utils.openLink(Const.ps),
title: const Text("Play Store"),
trailing: const Icon(Icons.link),
),
],
),
),
Expand Down
16 changes: 16 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
url: "https://pub.dev"
source: hosted
version: "11.10.0"
web:
dependency: transitive
description:
Expand All @@ -668,6 +676,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.3.0"
webdriver:
dependency: transitive
description:
name: webdriver
sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
win32:
dependency: transitive
description:
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.0+6
version: 1.2.0+7

environment:
sdk: ">=2.19.0 <3.0.0"
Expand Down

0 comments on commit da09a4a

Please sign in to comment.