import com.google.android.material.snackbar.Snackbar;
+import net.ktnx.mobileledger.BackupsActivity;
import net.ktnx.mobileledger.R;
import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
import net.ktnx.mobileledger.async.TransactionAccumulator;
import net.ktnx.mobileledger.ui.transaction_list.TransactionListFragment;
import net.ktnx.mobileledger.utils.Colors;
import net.ktnx.mobileledger.utils.Logger;
+import net.ktnx.mobileledger.utils.Misc;
import org.jetbrains.annotations.NotNull;
public static final String STATE_ACC_FILTER = "account_filter";
private static final boolean FAB_HIDDEN = false;
private static final boolean FAB_SHOWN = true;
+ private ConverterThread converterThread = null;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ProfilesRecyclerViewAdapter mProfileListAdapter;
private int mCurrentPage;
Data.backgroundTasksRunning.observe(this, this::onRetrieveRunningChanged);
if (barDrawerToggle == null) {
- barDrawerToggle = new ActionBarDrawerToggle(this, b.drawerLayout, b.toolbar,
- R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+ barDrawerToggle = new ActionBarDrawerToggle(this, b.drawerLayout, b.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
b.drawerLayout.addDrawerListener(barDrawerToggle);
}
barDrawerToggle.syncState();
PackageInfo pi = getApplicationContext().getPackageManager()
.getPackageInfo(getPackageName(), 0);
((TextView) b.navUpper.findViewById(R.id.drawer_version_text)).setText(pi.versionName);
- ((TextView) b.noProfilesLayout.findViewById(R.id.drawer_version_text)).setText(
- pi.versionName);
+ ((TextView) b.noProfilesLayout.findViewById(R.id.drawer_version_text)).setText(pi.versionName);
}
catch (Exception e) {
e.printStackTrace();
}
b.btnNoProfilesAdd.setOnClickListener(v -> ProfileDetailActivity.start(this, null));
+ b.btnRestore.setOnClickListener(v -> BackupsActivity.start(this));
b.btnAddTransaction.setOnClickListener(this::fabNewTransactionClicked);
b.navProfileList.setLayoutManager(llm);
b.navProfilesStartEdit.setOnClickListener((v) -> mProfileListAdapter.flipEditingProfiles());
- b.navProfilesCancelEdit.setOnClickListener(
- (v) -> mProfileListAdapter.flipEditingProfiles());
- b.navProfileListHeadButtons.setOnClickListener(
- (v) -> mProfileListAdapter.flipEditingProfiles());
+ b.navProfilesCancelEdit.setOnClickListener((v) -> mProfileListAdapter.flipEditingProfiles());
+ b.navProfileListHeadButtons.setOnClickListener((v) -> mProfileListAdapter.flipEditingProfiles());
if (drawerListener == null) {
drawerListener = new DrawerLayout.SimpleDrawerListener() {
@Override
b.navAccountSummary.setOnClickListener(this::onAccountSummaryClicked);
b.navLatestTransactions.setOnClickListener(this::onLatestTransactionsClicked);
b.navPatterns.setOnClickListener(this::onPatternsClick);
+ b.navBackupRestore.setOnClickListener(this::onBackupRestoreClick);
+ }
+ private void onBackupRestoreClick(View view) {
+ Intent intent = new Intent(this, BackupsActivity.class);
+ startActivity(intent);
}
private void onPatternsClick(View view) {
Intent intent = new Intent(this, TemplatesActivity.class);
mainModel.scheduleTransactionListRetrieval();
}
}
- private void createShortcuts(List<Profile> list) {
+ private void createShortcuts(@NotNull List<Profile> list) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1)
return;
}
sm.setDynamicShortcuts(shortcuts);
}
- private void onProfileListChanged(List<Profile> newList) {
- if ((newList == null) || newList.isEmpty()) {
+ private void onProfileListChanged(@NotNull List<Profile> newList) {
+ createShortcuts(newList);
+
+ if (newList.isEmpty()) {
b.noProfilesLayout.setVisibility(View.VISIBLE);
b.mainAppLayout.setVisibility(View.GONE);
return;
Logger.debug("profiles", "profile list changed");
mProfileListAdapter.setProfileList(newList);
- createShortcuts(newList);
+ final Profile currentProfile = Data.getProfile();
+ Profile replacementProfile = null;
+ if (currentProfile != null) {
+ for (Profile p : newList) {
+ if (p.getId() == currentProfile.getId()) {
+ replacementProfile = p;
+ break;
+ }
+ }
+ }
- Profile currentProfile = Data.getProfile();
- if (currentProfile == null || !newList.contains(currentProfile)) {
+ if (replacementProfile == null) {
Logger.debug(TAG, "Switching profile because the current is no longer available");
Data.setCurrentProfile(newList.get(0));
}
+ else {
+ Data.setCurrentProfile(replacementProfile);
+ }
}
/**
* called when the current profile has changed
*/
private void onProfileChanged(@Nullable Profile newProfile) {
- if (this.profile == null) {
- if (newProfile == null)
- return;
- }
- else {
+ if (this.profile != null) {
if (this.profile.equals(newProfile))
return;
}
else
setTitle(R.string.app_name);
- int newProfileTheme = haveProfile ? newProfile.getTheme() : -1;
+ int newProfileTheme = haveProfile ? newProfile.getTheme() : Colors.DEFAULT_HUE_DEG;
if (newProfileTheme != Colors.profileThemeId) {
Logger.debug("profiles",
String.format(Locale.ENGLISH, "profile theme %d → %d", Colors.profileThemeId,
}
mainModel.getAccountFilter()
- .observe(this, accFilter -> {
- Logger.debug(TAG, "account filter changed, reloading transactions");
-// mainModel.scheduleTransactionListReload();
- LiveData<List<TransactionWithAccounts>> transactions =
- new MutableLiveData<>(new ArrayList<TransactionWithAccounts>());
- if (profile != null) {
- if (accFilter == null || accFilter.isEmpty()) {
- transactions = DB.get()
- .getTransactionDAO()
- .getAllWithAccounts(profile.getId());
- }
- else {
- transactions = DB.get()
- .getTransactionDAO()
- .getAllWithAccountsFiltered(profile.getId(),
- accFilter);
- }
- }
-
- transactions.observe(this, list -> {
- TransactionAccumulator accumulator = new TransactionAccumulator(accFilter);
-
- for (TransactionWithAccounts tr : list)
- accumulator.put(new LedgerTransaction(tr));
-
- accumulator.publishResults(mainModel);
- });
- });
+ .observe(this, this::onAccountFilterChanged);
mainModel.stopTransactionsRetrieval();
mainModel.clearTransactions();
}
+ private void onAccountFilterChanged(String accFilter) {
+ Logger.debug(TAG, "account filter changed, reloading transactions");
+// mainModel.scheduleTransactionListReload();
+ LiveData<List<TransactionWithAccounts>> transactions =
+ new MutableLiveData<>(new ArrayList<>());
+ if (profile != null) {
+ if (accFilter == null || accFilter.isEmpty()) {
+ transactions = DB.get()
+ .getTransactionDAO()
+ .getAllWithAccounts(profile.getId());
+ }
+ else {
+ transactions = DB.get()
+ .getTransactionDAO()
+ .getAllWithAccountsFiltered(profile.getId(), accFilter);
+ }
+ }
+
+ transactions.observe(this, list -> {
+ Logger.debug(TAG,
+ String.format(Locale.ROOT, "got transaction list from DB (%d transactions)",
+ list.size()));
+
+ if (converterThread != null)
+ converterThread.interrupt();
+ converterThread = new ConverterThread(mainModel, list, accFilter);
+ converterThread.start();
+ });
+ }
private void profileThemeChanged() {
// un-hook all observed LiveData
Data.removeProfileObservers(this);
return 2;
}
}
+
+ static private class ConverterThread extends Thread {
+ private final List<TransactionWithAccounts> list;
+ private final MainModel model;
+ private final String accFilter;
+ public ConverterThread(@NonNull MainModel model,
+ @NonNull List<TransactionWithAccounts> list, String accFilter) {
+ this.model = model;
+ this.list = list;
+ this.accFilter = accFilter;
+ }
+ @Override
+ public void run() {
+ TransactionAccumulator accumulator = new TransactionAccumulator(accFilter, accFilter);
+
+ for (TransactionWithAccounts tr : list) {
+ if (isInterrupted()) {
+ Logger.debug(TAG, "ConverterThread bailing out on interrupt");
+ return;
+ }
+ accumulator.put(new LedgerTransaction(tr));
+ }
+
+ if (isInterrupted()) {
+ Logger.debug(TAG, "ConverterThread bailing out on interrupt");
+ return;
+ }
+
+ Logger.debug(TAG, "ConverterThread publishing results");
+
+ Misc.onMainThread(() -> accumulator.publishResults(model));
+ }
+ }
}