]> git.ktnx.net Git - mobile-ledger-staging.git/blobdiff - app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java
fix setup of theme when the last profile was removed
[mobile-ledger-staging.git] / app / src / main / java / net / ktnx / mobileledger / ui / activity / MainActivity.java
index 25fb12a2faf4b59423e1913ecb4bc3855480661c..c66f43c489a98328556edd196dcdec6580b92852 100644 (file)
 package net.ktnx.mobileledger.ui.activity;
 
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.content.res.ColorStateList;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
+import android.text.format.DateUtils;
 import android.util.Log;
 import android.view.View;
 import android.view.animation.AnimationUtils;
@@ -43,6 +42,7 @@ import androidx.drawerlayout.widget.DrawerLayout;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.lifecycle.ViewModelProvider;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.viewpager.widget.ViewPager;
@@ -51,28 +51,25 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.google.android.material.snackbar.Snackbar;
 
 import net.ktnx.mobileledger.R;
-import net.ktnx.mobileledger.async.RefreshDescriptionsTask;
 import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
 import net.ktnx.mobileledger.model.Data;
 import net.ktnx.mobileledger.model.MobileLedgerProfile;
+import net.ktnx.mobileledger.ui.MainModel;
 import net.ktnx.mobileledger.ui.account_summary.AccountSummaryFragment;
 import net.ktnx.mobileledger.ui.profiles.ProfileDetailFragment;
 import net.ktnx.mobileledger.ui.profiles.ProfilesRecyclerViewAdapter;
 import net.ktnx.mobileledger.ui.transaction_list.TransactionListFragment;
-import net.ktnx.mobileledger.ui.transaction_list.TransactionListViewModel;
 import net.ktnx.mobileledger.utils.Colors;
 import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.MLDB;
 
 import org.jetbrains.annotations.NotNull;
 
-import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
-
-import static net.ktnx.mobileledger.utils.Logger.debug;
+import java.util.Objects;
 
 /*
  * TODO: reports
@@ -82,7 +79,6 @@ public class MainActivity extends ProfileThemedActivity {
     public static final String STATE_CURRENT_PAGE = "current_page";
     public static final String BUNDLE_SAVED_STATE = "bundle_savedState";
     public static final String STATE_ACC_FILTER = "account_filter";
-    private static final String PREF_THEME_ID = "themeId";
     DrawerLayout drawer;
     private View profileListHeadMore, profileListHeadCancel, profileListHeadAddProfile;
     private View bTransactionListCancelDownload;
@@ -97,6 +93,7 @@ public class MainActivity extends ProfileThemedActivity {
     private ActionBarDrawerToggle barDrawerToggle;
     private ViewPager.SimpleOnPageChangeListener pageChangeListener;
     private MobileLedgerProfile profile;
+    private MainModel mainModel;
     @Override
     protected void onStart() {
         super.onStart();
@@ -109,8 +106,10 @@ public class MainActivity extends ProfileThemedActivity {
     protected void onSaveInstanceState(@NotNull Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putInt(STATE_CURRENT_PAGE, mViewPager.getCurrentItem());
-        if (Data.accountFilter.getValue() != null)
-            outState.putString(STATE_ACC_FILTER, Data.accountFilter.getValue());
+        if (mainModel.getAccountFilter()
+                     .getValue() != null)
+            outState.putString(STATE_ACC_FILTER, mainModel.getAccountFilter()
+                                                          .getValue());
     }
     @Override
     protected void onDestroy() {
@@ -131,13 +130,9 @@ public class MainActivity extends ProfileThemedActivity {
     }
     @Override
     protected void setupProfileColors() {
-        SharedPreferences prefs = getPreferences(MODE_PRIVATE);
-        int profileColor = prefs.getInt(PREF_THEME_ID, -2);
-        if (profileColor == -2)
-            profileColor = Data.retrieveCurrentThemeIdFromDb();
+        final int profileColor = Data.retrieveCurrentThemeIdFromDb();
         Colors.setupTheme(this, profileColor);
         Colors.profileThemeId = profileColor;
-        storeThemeIdInPrefs(profileColor);
     }
     @Override
     protected void onResume() {
@@ -146,11 +141,13 @@ public class MainActivity extends ProfileThemedActivity {
     }
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        debug("MainActivity", "onCreate()/entry");
+        Logger.debug("MainActivity", "onCreate()/entry");
         super.onCreate(savedInstanceState);
-        debug("MainActivity", "onCreate()/after super");
+        Logger.debug("MainActivity", "onCreate()/after super");
         setContentView(R.layout.activity_main);
 
+        mainModel = new ViewModelProvider(this).get(MainModel.class);
+
         fab = findViewById(R.id.btn_add_transaction);
         profileListHeadMore = findViewById(R.id.nav_profiles_start_edit);
         profileListHeadCancel = findViewById(R.id.nav_profiles_cancel_edit);
@@ -174,6 +171,7 @@ public class MainActivity extends ProfileThemedActivity {
 
         Data.profiles.observe(this, this::onProfileListChanged);
         Data.backgroundTaskProgress.observe(this, this::onRetrieveProgress);
+        Data.backgroundTasksRunning.observe(this, this::onRetrieveRunningChanged);
 
         if (barDrawerToggle == null) {
             barDrawerToggle = new ActionBarDrawerToggle(this, drawer, mToolbar,
@@ -227,11 +225,10 @@ public class MainActivity extends ProfileThemedActivity {
             if (currentPage != -1) {
                 mCurrentPage = currentPage;
             }
-            Data.accountFilter.setValue(savedInstanceState.getString(STATE_ACC_FILTER, null));
+            mainModel.getAccountFilter()
+                     .setValue(savedInstanceState.getString(STATE_ACC_FILTER, null));
         }
 
-        Data.lastUpdateDate.observe(this, this::updateLastUpdateDisplay);
-
         findViewById(R.id.btn_no_profiles_add).setOnClickListener(
                 v -> startEditProfileActivity(null));
 
@@ -320,18 +317,32 @@ public class MainActivity extends ProfileThemedActivity {
             else
                 drawer.close();
         });
+
+        mainModel.getUpdateError()
+                 .observe(this, (error) -> {
+                     if (error == null)
+                         return;
+
+                     Snackbar.make(mViewPager, error, Snackbar.LENGTH_LONG)
+                             .show();
+                     mainModel.clearUpdateError();
+                 });
+        Data.locale.observe(this, l -> refreshLastUpdateInfo());
+        Data.lastUpdateDate.observe(this, date -> refreshLastUpdateInfo());
+        Data.lastUpdateTransactionCount.observe(this, date -> refreshLastUpdateInfo());
+        Data.lastUpdateAccountCount.observe(this, date -> refreshLastUpdateInfo());
     }
-    private void scheduleDataRetrievalIfStale(Date lastUpdate) {
+    private void scheduleDataRetrievalIfStale(long lastUpdate) {
         long now = new Date().getTime();
-        if ((lastUpdate == null) || (now > (lastUpdate.getTime() + (24 * 3600 * 1000)))) {
-            if (lastUpdate == null)
-                debug("db::", "WEB data never fetched. scheduling a fetch");
+        if ((lastUpdate == 0) || (now > (lastUpdate + (24 * 3600 * 1000)))) {
+            if (lastUpdate == 0)
+                Logger.debug("db::", "WEB data never fetched. scheduling a fetch");
             else
-                debug("db", String.format(Locale.ENGLISH,
+                Logger.debug("db", String.format(Locale.ENGLISH,
                         "WEB data last fetched at %1.3f and now is %1.3f. re-fetching",
-                        lastUpdate.getTime() / 1000f, now / 1000f));
+                        lastUpdate / 1000f, now / 1000f));
 
-            Data.scheduleTransactionListRetrieval(this);
+            mainModel.scheduleTransactionListRetrieval();
         }
     }
     private void createShortcuts(List<MobileLedgerProfile> list) {
@@ -376,7 +387,7 @@ public class MainActivity extends ProfileThemedActivity {
         findViewById(R.id.nav_profile_list).setMinimumHeight(
                 (int) (getResources().getDimension(R.dimen.thumb_row_height) * newList.size()));
 
-        debug("profiles", "profile list changed");
+        Logger.debug("profiles", "profile list changed");
         mProfileListAdapter.notifyDataSetChanged();
 
         createShortcuts(newList);
@@ -401,15 +412,13 @@ public class MainActivity extends ProfileThemedActivity {
         else
             setTitle(R.string.app_name);
 
-        if (this.profile != null)
-            this.profile.getDisplayedAccounts()
-                        .removeObservers(this);
+        mainModel.setProfile(profile);
 
         this.profile = profile;
 
         int newProfileTheme = haveProfile ? profile.getThemeHue() : -1;
         if (newProfileTheme != Colors.profileThemeId) {
-            debug("profiles",
+            Logger.debug("profiles",
                     String.format(Locale.ENGLISH, "profile theme %d → %d", Colors.profileThemeId,
                             newProfileTheme));
             Colors.profileThemeId = newProfileTheme;
@@ -424,12 +433,13 @@ public class MainActivity extends ProfileThemedActivity {
 
         mProfileListAdapter.notifyDataSetChanged();
 
-        Data.transactions.clear();
-        debug("transactions", "requesting list reload");
-        TransactionListViewModel.scheduleTransactionListReload();
+        mainModel.clearAccounts();
+        mainModel.clearTransactions();
 
         if (haveProfile) {
-            profile.scheduleAccountListReload();
+            mainModel.scheduleAccountListReload();
+            Logger.debug("transactions", "requesting list reload");
+            mainModel.scheduleTransactionListReload();
 
             if (profile.isPostingPermitted()) {
                 mToolbar.setSubtitle(null);
@@ -447,40 +457,16 @@ public class MainActivity extends ProfileThemedActivity {
 
         updateLastUpdateTextFromDB();
     }
-    private void updateLastUpdateDisplay(Date newValue) {
-        LinearLayout l = findViewById(R.id.transactions_last_update_layout);
-        TextView v = findViewById(R.id.transactions_last_update);
-        if (newValue == null) {
-            l.setVisibility(View.INVISIBLE);
-            debug("main", "no last update date :(");
-        }
-        else {
-            final String text = DateFormat.getDateTimeInstance()
-                                          .format(newValue);
-            v.setText(text);
-            l.setVisibility(View.VISIBLE);
-            debug("main", String.format("Date formatted: %s", text));
-        }
-
-        scheduleDataRetrievalIfStale(newValue);
-    }
     private void profileThemeChanged() {
-        storeThemeIdInPrefs(profile.getThemeHue());
-
         // un-hook all observed LiveData
         Data.removeProfileObservers(this);
         Data.profiles.removeObservers(this);
+        Data.lastUpdateTransactionCount.removeObservers(this);
+        Data.lastUpdateAccountCount.removeObservers(this);
         Data.lastUpdateDate.removeObservers(this);
 
         recreate();
     }
-    private void storeThemeIdInPrefs(int themeId) {
-        // store the new theme id in the preferences
-        SharedPreferences prefs = getPreferences(MODE_PRIVATE);
-        SharedPreferences.Editor e = prefs.edit();
-        e.putInt(PREF_THEME_ID, themeId);
-        e.apply();
-    }
     public void startEditProfileActivity(MobileLedgerProfile profile) {
         Intent intent = new Intent(this, ProfileDetailActivity.class);
         Bundle args = new Bundle();
@@ -516,7 +502,8 @@ public class MainActivity extends ProfileThemedActivity {
     }
     private void showAccountSummaryFragment() {
         mViewPager.setCurrentItem(0, true);
-        Data.accountFilter.setValue(null);
+        mainModel.getAccountFilter()
+                 .setValue(null);
     }
     public void onLatestTransactionsClicked(View view) {
         drawer.closeDrawers();
@@ -524,7 +511,8 @@ public class MainActivity extends ProfileThemedActivity {
         showTransactionsFragment(null);
     }
     public void showTransactionsFragment(String accName) {
-        Data.accountFilter.setValue(accName);
+        mainModel.getAccountFilter()
+                 .setValue(accName);
         mViewPager.setCurrentItem(1, true);
     }
     public void showAccountTransactions(String accountName) {
@@ -539,12 +527,13 @@ public class MainActivity extends ProfileThemedActivity {
         }
         else {
             if (mBackMeansToAccountList && (mViewPager.getCurrentItem() == 1)) {
-                Data.accountFilter.setValue(null);
+                mainModel.getAccountFilter()
+                         .setValue(null);
                 showAccountSummaryFragment();
                 mBackMeansToAccountList = false;
             }
             else {
-                debug("fragments", String.format(Locale.ENGLISH, "manager stack: %d",
+                Logger.debug("fragments", String.format(Locale.ENGLISH, "manager stack: %d",
                         getSupportFragmentManager().getBackStackEntryCount()));
 
                 super.onBackPressed();
@@ -555,41 +544,78 @@ public class MainActivity extends ProfileThemedActivity {
         if (profile == null)
             return;
 
-        long last_update = profile.getLongOption(MLDB.OPT_LAST_SCRAPE, 0L);
+        long lastUpdate = profile.getLongOption(MLDB.OPT_LAST_SCRAPE, 0L);
 
-        debug("transactions", String.format(Locale.ENGLISH, "Last update = %d", last_update));
-        if (last_update == 0) {
+        Logger.debug("transactions", String.format(Locale.ENGLISH, "Last update = %d", lastUpdate));
+        if (lastUpdate == 0) {
             Data.lastUpdateDate.postValue(null);
         }
         else {
-            Data.lastUpdateDate.postValue(new Date(last_update));
+            Data.lastUpdateDate.postValue(new Date(lastUpdate));
+        }
+
+        scheduleDataRetrievalIfStale(lastUpdate);
+
+    }
+    private void refreshLastUpdateInfo() {
+        final int formatFlags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR |
+                                DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_NUMERIC_DATE;
+        String templateForTransactions =
+                getResources().getString(R.string.transaction_count_summary);
+        String templateForAccounts = getResources().getString(R.string.account_count_summary);
+        Integer accountCount = Data.lastUpdateAccountCount.getValue();
+        Integer transactionCount = Data.lastUpdateTransactionCount.getValue();
+        Date lastUpdate = Data.lastUpdateDate.getValue();
+        if (lastUpdate == null) {
+            Data.lastTransactionsUpdateText.set("----");
+            Data.lastAccountsUpdateText.set("----");
+        }
+        else {
+            Data.lastTransactionsUpdateText.set(
+                    String.format(Objects.requireNonNull(Data.locale.getValue()),
+                            templateForTransactions,
+                            transactionCount == null ? 0 : transactionCount,
+                            DateUtils.formatDateTime(this, lastUpdate.getTime(), formatFlags)));
+            Data.lastAccountsUpdateText.set(
+                    String.format(Objects.requireNonNull(Data.locale.getValue()),
+                            templateForAccounts, accountCount == null ? 0 : accountCount,
+                            DateUtils.formatDateTime(this, lastUpdate.getTime(), formatFlags)));
         }
     }
     public void onStopTransactionRefreshClick(View view) {
-        debug("interactive", "Cancelling transactions refresh");
-        Data.stopTransactionsRetrieval();
+        Logger.debug("interactive", "Cancelling transactions refresh");
+        mainModel.stopTransactionsRetrieval();
         bTransactionListCancelDownload.setEnabled(false);
     }
-    public void onRetrieveStart() {
-        ProgressBar progressBar = findViewById(R.id.transaction_list_progress_bar);
-        bTransactionListCancelDownload.setEnabled(true);
-        ColorStateList csl = Colors.getColorStateList();
-        progressBar.setIndeterminateTintList(csl);
-        progressBar.setProgressTintList(csl);
-        progressBar.setIndeterminate(true);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
-            progressBar.setProgress(0, false);
-        else
-            progressBar.setProgress(0);
-        findViewById(R.id.transaction_progress_layout).setVisibility(View.VISIBLE);
+    public void onRetrieveRunningChanged(Boolean running) {
+        final View progressLayout = findViewById(R.id.transaction_progress_layout);
+        if (running) {
+            ProgressBar progressBar = findViewById(R.id.transaction_list_progress_bar);
+            bTransactionListCancelDownload.setEnabled(true);
+            ColorStateList csl = Colors.getColorStateList();
+            progressBar.setIndeterminateTintList(csl);
+            progressBar.setProgressTintList(csl);
+            progressBar.setIndeterminate(true);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                progressBar.setProgress(0, false);
+            }
+            else {
+                progressBar.setProgress(0);
+            }
+            progressLayout.setVisibility(View.VISIBLE);
+        }
+        else {
+            progressLayout.setVisibility(View.GONE);
+        }
     }
     public void onRetrieveProgress(RetrieveTransactionsTask.Progress progress) {
         ProgressBar progressBar = findViewById(R.id.transaction_list_progress_bar);
 
         if (progress.getState() == RetrieveTransactionsTask.ProgressState.FINISHED) {
+            Logger.debug("progress", "Done");
             findViewById(R.id.transaction_progress_layout).setVisibility(View.GONE);
 
-            Data.transactionRetrievalDone();
+            mainModel.transactionRetrievalDone();
 
             if (progress.getError() != null) {
                 Snackbar.make(mViewPager, progress.getError(), Snackbar.LENGTH_LONG)
@@ -597,39 +623,38 @@ public class MainActivity extends ProfileThemedActivity {
                 return;
             }
 
-            updateLastUpdateTextFromDB();
-
-            new RefreshDescriptionsTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-            TransactionListViewModel.scheduleTransactionListReload();
-
             return;
         }
 
 
         bTransactionListCancelDownload.setEnabled(true);
-        ColorStateList csl = Colors.getColorStateList();
-        progressBar.setIndeterminateTintList(csl);
-        progressBar.setProgressTintList(csl);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
-            progressBar.setProgress(0, false);
-        else
-            progressBar.setProgress(0);
+//        ColorStateList csl = Colors.getColorStateList();
+//        progressBar.setIndeterminateTintList(csl);
+//        progressBar.setProgressTintList(csl);
+//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+//            progressBar.setProgress(0, false);
+//        else
+//            progressBar.setProgress(0);
         findViewById(R.id.transaction_progress_layout).setVisibility(View.VISIBLE);
 
-        if (progress.isIndeterminate() || (progress.getTotal() == 0)) {
+        if (progress.isIndeterminate() || (progress.getTotal() <= 0)) {
             progressBar.setIndeterminate(true);
+            Logger.debug("progress", "indeterminate");
         }
         else {
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-                progressBar.setMin(0);
+            if (progressBar.isIndeterminate()) {
+                progressBar.setIndeterminate(false);
             }
+//            Logger.debug("progress",
+//                    String.format(Locale.US, "%d/%d", progress.getProgress(), progress.getTotal
+//                    ()));
             progressBar.setMax(progress.getTotal());
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                progressBar.setProgress(progress.getProgress(), true);
-            }
+            // for some reason animation doesn't work - no progress is shown (stick at 0)
+            // on lineageOS 14.1 (Nougat, 7.1.2)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+                progressBar.setProgress(progress.getProgress(), false);
             else
                 progressBar.setProgress(progress.getProgress());
-            progressBar.setIndeterminate(false);
         }
     }
     public void fabShouldShow() {
@@ -651,7 +676,8 @@ public class MainActivity extends ProfileThemedActivity {
         @NotNull
         @Override
         public Fragment getItem(int position) {
-            debug("main", String.format(Locale.ENGLISH, "Switching to fragment %d", position));
+            Logger.debug("main",
+                    String.format(Locale.ENGLISH, "Switching to fragment %d", position));
             switch (position) {
                 case 0:
 //                    debug("flow", "Creating account summary fragment");