2 * Copyright © 2018 Damyan Ivanov.
3 * This file is part of Mobile-Ledger.
4 * Mobile-Ledger is free software: you can distribute it and/or modify it
5 * under the term of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your opinion), any later version.
9 * Mobile-Ledger is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License terms for details.
14 * You should have received a copy of the GNU General Public License
15 * along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
18 package net.ktnx.mobileledger;
20 import android.arch.lifecycle.ViewModelProviders;
21 import android.database.MatrixCursor;
22 import android.os.Build;
23 import android.os.Bundle;
24 import android.preference.PreferenceManager;
25 import android.support.v4.widget.SwipeRefreshLayout;
26 import android.support.v7.app.ActionBar;
27 import android.support.v7.app.AppCompatActivity;
28 import android.support.v7.widget.LinearLayoutManager;
29 import android.support.v7.widget.RecyclerView;
30 import android.support.v7.widget.Toolbar;
31 import android.util.Log;
32 import android.view.Menu;
33 import android.view.MenuItem;
34 import android.view.View;
35 import android.view.inputmethod.InputMethodManager;
36 import android.widget.AdapterView;
37 import android.widget.AutoCompleteTextView;
38 import android.widget.LinearLayout;
39 import android.widget.ProgressBar;
40 import android.widget.TextView;
42 import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
43 import net.ktnx.mobileledger.ui.transaction_list.TransactionListViewModel;
44 import net.ktnx.mobileledger.utils.MLDB;
46 import java.lang.ref.WeakReference;
47 import java.time.ZoneId;
48 import java.time.format.DateTimeFormatter;
49 import java.util.Date;
51 public class TransactionListActivity extends AppCompatActivity {
52 public TransactionListViewModel model;
53 private View bTransactionListCancelDownload;
54 private MenuItem menuTransactionListFilter;
55 private View vAccountFilter;
56 private SwipeRefreshLayout swiper;
57 private RecyclerView root;
58 private ProgressBar progressBar;
59 private LinearLayout progressLayout;
60 private TextView tvLastUpdate;
61 private TransactionListAdapter modelAdapter;
62 private RetrieveTransactionsTask retrieveTransactionsTask;
63 private AutoCompleteTextView accNameFilter;
65 protected void onCreate(Bundle savedInstanceState) {
66 super.onCreate(savedInstanceState);
67 setContentView(R.layout.transaction_list_activity);
69 Toolbar toolbar = findViewById(R.id.toolbar);
70 setSupportActionBar(toolbar);
74 swiper = findViewById(R.id.transaction_swipe);
75 if (swiper == null) throw new RuntimeException("Can't get hold on the swipe layout");
76 root = findViewById(R.id.transaction_root);
77 if (root == null) throw new RuntimeException("Can't get hold on the transaction list view");
78 progressBar = findViewById(R.id.transaction_list_progress_bar);
79 if (progressBar == null)
80 throw new RuntimeException("Can't get hold on the transaction list progress bar");
81 progressLayout = findViewById(R.id.transaction_progress_layout);
82 if (progressLayout == null) throw new RuntimeException(
83 "Can't get hold on the transaction list progress bar layout");
84 tvLastUpdate = findViewById(R.id.transactions_last_update);
85 updateLastUpdateText();
86 model = ViewModelProviders.of(this).get(TransactionListViewModel.class);
87 modelAdapter = new TransactionListAdapter(model);
89 RecyclerView root = findViewById(R.id.transaction_root);
90 root.setAdapter(modelAdapter);
92 LinearLayoutManager llm = new LinearLayoutManager(this);
94 llm.setOrientation(LinearLayoutManager.VERTICAL);
95 root.setLayoutManager(llm);
97 swiper.setOnRefreshListener(() -> {
98 Log.d("ui", "refreshing transactions via swipe");
99 update_transactions();
102 swiper.setColorSchemeResources(R.color.colorPrimary, R.color.colorAccent);
104 vAccountFilter = findViewById(R.id.transaction_list_account_name_filter);
105 accNameFilter = findViewById(R.id.transaction_filter_account_name);
106 bTransactionListCancelDownload = findViewById(R.id.transaction_list_cancel_download);
108 MLDB.hook_autocompletion_adapter(this, accNameFilter, "accounts", "name");
109 TransactionListActivity me = this;
110 accNameFilter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
112 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
113 Log.d("tmp", "direct onItemClick");
114 model.reloadTransactions(me);
115 MatrixCursor mc = (MatrixCursor) parent.getItemAtPosition(position);
116 modelAdapter.setBoldAccountName(mc.getString(1));
117 modelAdapter.notifyDataSetChanged();
118 me.hideSoftKeyboard();
122 updateLastUpdateText();
123 long last_update = MLDB.get_option_value(this, MLDB.OPT_TRANSACTION_LIST_STAMP, 0L);
124 Log.d("transactions", String.format("Last update = %d", last_update));
125 if (last_update == 0) {
126 update_transactions();
129 model.reloadTransactions(this);
132 private void setupActionBar() {
133 ActionBar actionBar = getSupportActionBar();
134 if (actionBar != null) {
135 // Show the Up button in the action bar.
136 actionBar.setDisplayHomeAsUpEnabled(true);
140 public void finish() {
142 Log.d("visuals", "finishing");
143 overridePendingTransition(R.anim.dummy, R.anim.slide_out_right);
145 private void update_transactions() {
146 retrieveTransactionsTask = new RetrieveTransactionsTask(new WeakReference<>(this));
148 RetrieveTransactionsTask.Params params = new RetrieveTransactionsTask.Params(
149 PreferenceManager.getDefaultSharedPreferences(this));
151 retrieveTransactionsTask.execute(params);
152 bTransactionListCancelDownload.setEnabled(true);
155 public void onRetrieveStart() {
156 progressBar.setIndeterminate(true);
157 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) progressBar.setProgress(0, false);
158 else progressBar.setProgress(0);
159 progressLayout.setVisibility(View.VISIBLE);
162 public boolean onCreateOptionsMenu(Menu menu) {
163 getMenuInflater().inflate(R.menu.transaction_list, menu);
164 menuTransactionListFilter = menu.findItem(R.id.menu_transaction_list_filter);
165 if ((menuTransactionListFilter == null)) throw new AssertionError();
169 public void onRetrieveProgress(RetrieveTransactionsTask.Progress progress) {
170 if ((progress.getTotal() == RetrieveTransactionsTask.Progress.INDETERMINATE) ||
171 (progress.getTotal() == 0))
173 progressBar.setIndeterminate(true);
176 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
177 progressBar.setMin(0);
179 progressBar.setMax(progress.getTotal());
180 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
181 progressBar.setProgress(progress.getProgress(), true);
183 else progressBar.setProgress(progress.getProgress());
184 progressBar.setIndeterminate(false);
188 public void onRetrieveDone(boolean success) {
189 progressLayout.setVisibility(View.GONE);
190 swiper.setRefreshing(false);
191 updateLastUpdateText();
193 Log.d("transactions", "calling notifyDataSetChanged()");
194 modelAdapter.notifyDataSetChanged();
197 private void updateLastUpdateText() {
199 long last_update = MLDB.get_option_value(this, MLDB.OPT_TRANSACTION_LIST_STAMP, 0L);
200 Log.d("transactions", String.format("Last update = %d", last_update));
201 if (last_update == 0) {
202 tvLastUpdate.setText(getString(R.string.transaction_last_update_never));
205 Date date = new Date(last_update);
206 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
207 tvLastUpdate.setText(date.toInstant().atZone(ZoneId.systemDefault())
208 .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
211 tvLastUpdate.setText(date.toLocaleString());
216 public void onClearAccountNameClick(View view) {
217 vAccountFilter.setVisibility(View.GONE);
218 menuTransactionListFilter.setVisible(true);
219 accNameFilter.setText(null);
220 model.reloadTransactions(this);
221 modelAdapter.resetBoldAccountName();
222 modelAdapter.notifyDataSetChanged();
225 private void hideSoftKeyboard() {
227 View v = getCurrentFocus();
229 InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
230 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
233 public void onShowFilterClick(MenuItem menuItem) {
234 vAccountFilter.setVisibility(View.VISIBLE);
235 menuTransactionListFilter.setVisible(false);
236 accNameFilter.requestFocus();
237 InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
238 imm.showSoftInput(accNameFilter, 0);
240 public void onStopTransactionRefreshClick(View view) {
241 Log.d("interactive", "Cancelling transactions refresh");
242 if (retrieveTransactionsTask != null) retrieveTransactionsTask.cancel(false);
243 bTransactionListCancelDownload.setEnabled(false);