Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added search txns , Play store redirect #36

Merged
merged 3 commits into from
Apr 10, 2024
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
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: {
Copy link
Owner

Choose a reason for hiding this comment

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

same code in if and else

"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