]> git.ktnx.net Git - mobile-ledger.git/commitdiff
more asynchronous account list (re-)loading
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Thu, 16 Jul 2020 08:38:43 +0000 (08:38 +0000)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Thu, 16 Jul 2020 08:38:43 +0000 (08:38 +0000)
it was loaded from DB in a background thread already, but recycler view
now updates are also managed in a background thread

app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java
app/src/main/java/net/ktnx/mobileledger/async/UpdateAccountsTask.java [deleted file]
app/src/main/java/net/ktnx/mobileledger/model/Data.java
app/src/main/java/net/ktnx/mobileledger/model/LedgerAccount.java
app/src/main/java/net/ktnx/mobileledger/model/MobileLedgerProfile.java
app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryAdapter.java
app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java
app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryViewModel.java [deleted file]
app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java
app/src/main/res/values/ids.xml

index db8f8de76a9b7b4d328b4f82b48e636bcebefa60..86d4cc457f0155322808d720eb57074c5cdefce8 100644 (file)
@@ -206,7 +206,7 @@ public class RetrieveTransactionsTask
                                 // state of the database
                                 db.setTransactionSuccessful();
                                 db.endTransaction();
-                                Data.accounts.setList(accountList);
+                                profile.setAccounts(accountList);
                                 db.beginTransaction();
                                 continue;
                             }
@@ -527,16 +527,13 @@ public class RetrieveTransactionsTask
                 profile.deleteNotPresentAccounts(db);
                 throwIfCancelled();
                 db.setTransactionSuccessful();
-                listFilledOK = true;
             }
             finally {
                 db.endTransaction();
             }
         }
-        // should not be set in the DB transaction, because of a possible deadlock
-        // with the main and DbOpQueueRunner threads
-        if (listFilledOK)
-            Data.accounts.setList(accountList);
+
+        profile.setAccounts(accountList);
 
         return true;
     }
diff --git a/app/src/main/java/net/ktnx/mobileledger/async/UpdateAccountsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/UpdateAccountsTask.java
deleted file mode 100644 (file)
index 8beab18..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright © 2019 Damyan Ivanov.
- * This file is part of MoLe.
- * MoLe is free software: you can distribute it and/or modify it
- * under the term of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion), any later version.
- *
- * MoLe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License terms for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package net.ktnx.mobileledger.async;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.AsyncTask;
-
-import net.ktnx.mobileledger.App;
-import net.ktnx.mobileledger.model.Data;
-import net.ktnx.mobileledger.model.LedgerAccount;
-import net.ktnx.mobileledger.model.MobileLedgerProfile;
-
-import java.util.ArrayList;
-
-import static net.ktnx.mobileledger.utils.Logger.debug;
-
-public class UpdateAccountsTask extends AsyncTask<Void, Void, ArrayList<LedgerAccount>> {
-    protected ArrayList<LedgerAccount> doInBackground(Void... params) {
-        Data.backgroundTaskStarted();
-        try {
-            MobileLedgerProfile profile = Data.profile.getValue();
-            if (profile == null) throw new AssertionError();
-            String profileUUID = profile.getUuid();
-            ArrayList<LedgerAccount> newList = new ArrayList<>();
-
-            String sql = "SELECT a.name from accounts a WHERE a.profile = ?";
-            sql += " ORDER BY a.name";
-
-            SQLiteDatabase db = App.getDatabase();
-            try (Cursor cursor = db.rawQuery(sql, new String[]{profileUUID})) {
-                while (cursor.moveToNext()) {
-                    final String accName = cursor.getString(0);
-//                    debug("accounts",
-//                            String.format("Read account '%s' from DB [%s]", accName, profileUUID));
-                    LedgerAccount acc = profile.loadAccount(db, accName);
-                    if (acc.isVisible(newList)) newList.add(acc);
-                }
-            }
-
-            return newList;
-        }
-        finally {
-            debug("UAT", "decrementing background task count");
-            Data.backgroundTaskFinished();
-        }
-    }
-}
index 5764434f33b3dbb76f446d97cf9162986f98d1ec..a6d3fd9825dd4ce69e59712d1654986132d3ee9e 100644 (file)
@@ -50,8 +50,6 @@ public final class Data {
             new MutableLiveData<>(null);
     public static final MutableLiveData<SimpleDate> latestTransactionDate =
             new MutableLiveData<>(null);
-    public static final ObservableList<LedgerAccount> accounts =
-            new ObservableList<>(new ArrayList<>());
     public static final MutableLiveData<Boolean> backgroundTasksRunning =
             new MutableLiveData<>(false);
     public static final MutableLiveData<Date> lastUpdateDate = new MutableLiveData<>();
index 3bc01d1fecd852cc957aeb205640465dec80320f..11c1a16bfa097febf4361fb5c1e294cc4647269d 100644 (file)
@@ -66,13 +66,7 @@ public class LedgerAccount {
                name.equals(((LedgerAccount) obj).getName());
     }
     // an account is visible if:
-    //  - it is starred (not hidden by a star)
-    //  - and it has an expanded parent or is a top account
-    public boolean isVisible() {
-        if (level == 0) return true;
-
-        return isVisible(Data.accounts);
-    }
+    //  - it has an expanded parent or is a top account
     public boolean isVisible(List<LedgerAccount> list) {
         for (LedgerAccount acc : list) {
             if (acc.isParentOf(this)) {
index 21acf677ddc426fac048fb79937d2dbbb49a406e..fc940e9ad6f8850b33e4ee9dd118dafc746e1ac3 100644 (file)
@@ -24,11 +24,14 @@ import android.util.SparseArray;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
 
 import net.ktnx.mobileledger.App;
 import net.ktnx.mobileledger.R;
 import net.ktnx.mobileledger.async.DbOpQueue;
 import net.ktnx.mobileledger.async.SendTransactionTask;
+import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.MLDB;
 import net.ktnx.mobileledger.utils.Misc;
 
@@ -61,6 +64,9 @@ public final class MobileLedgerProfile {
     private SendTransactionTask.API apiVersion = SendTransactionTask.API.auto;
     private Calendar firstTransactionDate;
     private Calendar lastTransactionDate;
+    private MutableLiveData<ArrayList<LedgerAccount>> accounts =
+            new MutableLiveData<>(new ArrayList<>());
+    private AccountListLoader loader = null;
     public MobileLedgerProfile() {
         this.uuid = String.valueOf(UUID.randomUUID());
     }
@@ -141,6 +147,26 @@ public final class MobileLedgerProfile {
             db.endTransaction();
         }
     }
+    public LiveData<ArrayList<LedgerAccount>> getAccounts() {
+        return accounts;
+    }
+    synchronized public void scheduleAccountListReload() {
+        Logger.debug("async-acc", "scheduleAccountListReload() enter");
+        if ((loader != null) && loader.isAlive()) {
+            Logger.debug("async-acc", "returning early - loader already active");
+            return;
+        }
+
+        Logger.debug("async-acc", "Starting AccountListLoader");
+        loader = new AccountListLoader(this);
+        loader.start();
+    }
+    synchronized public void abortAccountListReload() {
+        if (loader == null)
+            return;
+        loader.interrupt();
+        loader = null;
+    }
     public boolean getShowCommentsByDefault() {
         return showCommentsByDefault;
     }
@@ -402,7 +428,7 @@ public final class MobileLedgerProfile {
     }
     @Nullable
     public LedgerAccount tryLoadAccount(SQLiteDatabase db, String accName) {
-        try (Cursor cursor = db.rawQuery("SELECT a.expanded, (select 1 from accounts a2 " +
+        try (Cursor cursor = db.rawQuery("SELECT a.expanded, a.amounts_expanded, (select 1 from accounts a2 " +
                                          "where a2.profile = a.profile and a2.name like a" +
                                          ".name||':%' limit 1) " +
                                          "FROM accounts a WHERE a.profile = ? and a.name=?",
@@ -411,7 +437,8 @@ public final class MobileLedgerProfile {
             if (cursor.moveToFirst()) {
                 LedgerAccount acc = new LedgerAccount(this, accName);
                 acc.setExpanded(cursor.getInt(0) == 1);
-                acc.setHasSubAccounts(cursor.getInt(1) == 1);
+                acc.setAmountsExpanded(cursor.getInt(1) == 1);
+                acc.setHasSubAccounts(cursor.getInt(2) == 1);
 
                 try (Cursor c2 = db.rawQuery(
                         "SELECT value, currency FROM account_values WHERE profile = ? " +
@@ -573,6 +600,9 @@ public final class MobileLedgerProfile {
     public Calendar getLastTransactionDate() {
         return lastTransactionDate;
     }
+    public void setAccounts(ArrayList<LedgerAccount> list) {
+        accounts.postValue(list);
+    }
     public enum FutureDates {
         None(0), OneWeek(7), TwoWeeks(14), OneMonth(30), TwoMonths(60), ThreeMonths(90),
         SixMonths(180), OneYear(365), All(-1);
@@ -617,4 +647,42 @@ public final class MobileLedgerProfile {
             }
         }
     }
+
+    static class AccountListLoader extends Thread {
+        MobileLedgerProfile profile;
+        AccountListLoader(MobileLedgerProfile profile) {
+            this.profile = profile;
+        }
+        @Override
+        public void run() {
+            Logger.debug("async-acc", "AccountListLoader::run() entered");
+            String profileUUID = profile.getUuid();
+            ArrayList<LedgerAccount> newList = new ArrayList<>();
+
+            String sql = "SELECT a.name from accounts a WHERE a.profile = ?";
+            sql += " ORDER BY a.name";
+
+            SQLiteDatabase db = App.getDatabase();
+            try (Cursor cursor = db.rawQuery(sql, new String[]{profileUUID})) {
+                while (cursor.moveToNext()) {
+                    if (isInterrupted())
+                        return;
+
+                    final String accName = cursor.getString(0);
+//                    debug("accounts",
+//                            String.format("Read account '%s' from DB [%s]", accName,
+//                            profileUUID));
+                    LedgerAccount acc = profile.loadAccount(db, accName);
+                    if (acc.isVisible(newList))
+                        newList.add(acc);
+                }
+            }
+
+            if (isInterrupted())
+                return;
+
+            Logger.debug("async-acc", "AccountListLoader::run() posting new list");
+            profile.accounts.postValue(newList);
+        }
+    }
 }
index 0540438ddcd6c47e4e7d9e873c393cd4a50cdb66..ee46b9c705dea401a2f1e7e1e00c689383cd273d 100644 (file)
@@ -19,6 +19,7 @@ package net.ktnx.mobileledger.ui.account_summary;
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -29,48 +30,45 @@ import android.widget.TextView;
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.recyclerview.widget.AsyncListDiffer;
+import androidx.recyclerview.widget.DiffUtil;
 import androidx.recyclerview.widget.RecyclerView;
 
 import net.ktnx.mobileledger.R;
-import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.async.DbOpQueue;
 import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
 import net.ktnx.mobileledger.ui.activity.MainActivity;
-import net.ktnx.mobileledger.utils.LockHolder;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+import static net.ktnx.mobileledger.utils.Logger.debug;
 
 public class AccountSummaryAdapter
         extends RecyclerView.Adapter<AccountSummaryAdapter.LedgerRowHolder> {
     public static final int AMOUNT_LIMIT = 3;
-
-    AccountSummaryAdapter() { }
+    private MobileLedgerProfile profile;
+    private AsyncListDiffer<LedgerAccount> listDiffer;
+    AccountSummaryAdapter() {
+        listDiffer = new AsyncListDiffer<>(this, new DiffUtil.ItemCallback<LedgerAccount>() {
+            @Override
+            public boolean areItemsTheSame(@NotNull LedgerAccount oldItem,
+                                           @NotNull LedgerAccount newItem) {
+                return TextUtils.equals(oldItem.getName(), newItem.getName());
+            }
+            @Override
+            public boolean areContentsTheSame(@NotNull LedgerAccount oldItem,
+                                              @NotNull LedgerAccount newItem) {
+                return (oldItem.isExpanded() == newItem.isExpanded()) &&
+                       (oldItem.amountsExpanded() == newItem.amountsExpanded());
+            }
+        });
+    }
 
     public void onBindViewHolder(@NonNull LedgerRowHolder holder, int position) {
-        try (LockHolder lh = Data.accounts.lockForReading()) {
-                LedgerAccount acc = Data.accounts.get(position);
-                Context ctx = holder.row.getContext();
-                Resources rm = ctx.getResources();
-
-                holder.row.setTag(acc);
-                holder.row.setVisibility(View.VISIBLE);
-                holder.tvAccountName.setText(acc.getShortName());
-                ConstraintLayout.LayoutParams lp =
-                        (ConstraintLayout.LayoutParams) holder.tvAccountName.getLayoutParams();
-                lp.setMarginStart(
-                        acc.getLevel() * rm.getDimensionPixelSize(R.dimen.thumb_row_height) / 3);
-                holder.expanderContainer.setVisibility(
-                        acc.hasSubAccounts() ? View.VISIBLE : View.GONE);
-                holder.expanderContainer.setRotation(acc.isExpanded() ? 0 : 180);
-                int amounts = acc.getAmountCount();
-                if ((amounts > AMOUNT_LIMIT) && !acc.amountsExpanded()) {
-                    holder.tvAccountAmounts.setText(acc.getAmountsString(AMOUNT_LIMIT));
-                    holder.accountExpanderContainer.setVisibility(View.VISIBLE);
-                }
-                else {
-                    holder.tvAccountAmounts.setText(acc.getAmountsString());
-                    holder.accountExpanderContainer.setVisibility(View.GONE);
-                }
-
-                holder.row.setTag(R.id.POS, position);
-        }
+        holder.bindToAccount(listDiffer.getCurrentList().get(position));
     }
 
     @NonNull
@@ -83,9 +81,13 @@ public class AccountSummaryAdapter
 
     @Override
     public int getItemCount() {
-        return Data.accounts.size();
+        return listDiffer.getCurrentList().size();
+    }
+    public void setAccounts(MobileLedgerProfile profile, ArrayList<LedgerAccount> newList) {
+        this.profile = profile;
+        listDiffer.submitList(newList);
     }
-    static class LedgerRowHolder extends RecyclerView.ViewHolder {
+    class LedgerRowHolder extends RecyclerView.ViewHolder {
         TextView tvAccountName, tvAccountAmounts;
         ConstraintLayout row;
         View expanderContainer;
@@ -93,12 +95,12 @@ public class AccountSummaryAdapter
         View accountExpanderContainer;
         public LedgerRowHolder(@NonNull View itemView) {
             super(itemView);
-            this.row = itemView.findViewById(R.id.account_summary_row);
-            this.tvAccountName = itemView.findViewById(R.id.account_row_acc_name);
-            this.tvAccountAmounts = itemView.findViewById(R.id.account_row_acc_amounts);
-            this.expanderContainer = itemView.findViewById(R.id.account_expander_container);
-            this.expander = itemView.findViewById(R.id.account_expander);
-            this.accountExpanderContainer =
+            row = itemView.findViewById(R.id.account_summary_row);
+            tvAccountName = itemView.findViewById(R.id.account_row_acc_name);
+            tvAccountAmounts = itemView.findViewById(R.id.account_row_acc_amounts);
+            expanderContainer = itemView.findViewById(R.id.account_expander_container);
+            expander = itemView.findViewById(R.id.account_expander);
+            accountExpanderContainer =
                     itemView.findViewById(R.id.account_row_amounts_expander_container);
 
             itemView.setOnLongClickListener(this::onItemLongClick);
@@ -107,6 +109,63 @@ public class AccountSummaryAdapter
             expanderContainer.setOnLongClickListener(this::onItemLongClick);
             expander.setOnLongClickListener(this::onItemLongClick);
             row.setOnLongClickListener(this::onItemLongClick);
+
+            tvAccountName.setOnClickListener(v -> toggleAccountExpanded());
+            expanderContainer.setOnClickListener(v -> toggleAccountExpanded());
+            expander.setOnClickListener(v -> toggleAccountExpanded());
+            tvAccountAmounts.setOnClickListener(v -> toggleAmountsExpanded());
+        }
+        private @NonNull
+        LedgerAccount getAccount() {
+            final ArrayList<LedgerAccount> accountList = profile.getAccounts()
+                                                                .getValue();
+            if (accountList == null)
+                throw new IllegalStateException("No account list");
+
+            return accountList.get(getAdapterPosition());
+        }
+        private void toggleAccountExpanded() {
+            LedgerAccount acc = getAccount();
+            if (!acc.hasSubAccounts())
+                return;
+            debug("accounts", "Account expander clicked");
+
+            acc.toggleExpanded();
+            expanderContainer.animate()
+                             .rotation(acc.isExpanded() ? 0 : 180);
+
+            MobileLedgerProfile profile = acc.getProfile();
+            if (profile == null)
+                return;
+
+            DbOpQueue.add("update accounts set expanded=? where name=? and profile=?",
+                    new Object[]{acc.isExpanded(), acc.getName(), profile.getUuid()
+                    }, profile::scheduleAccountListReload);
+
+        }
+        private void toggleAmountsExpanded() {
+            LedgerAccount acc = getAccount();
+            if (acc.getAmountCount() <= AMOUNT_LIMIT)
+                return;
+
+            acc.toggleAmountsExpanded();
+            if (acc.amountsExpanded()) {
+                tvAccountAmounts.setText(acc.getAmountsString());
+                accountExpanderContainer.setVisibility(View.GONE);
+            }
+            else {
+                tvAccountAmounts.setText(acc.getAmountsString(AMOUNT_LIMIT));
+                accountExpanderContainer.setVisibility(View.VISIBLE);
+            }
+
+            MobileLedgerProfile profile = acc.getProfile();
+            if (profile == null)
+                return;
+
+            DbOpQueue.add("update accounts set amounts_expanded=? where name=? and profile=?",
+                    new Object[]{acc.amountsExpanded(), acc.getName(), profile.getUuid()
+                    });
+
         }
         private boolean onItemLongClick(View v) {
             MainActivity activity = (MainActivity) v.getContext();
@@ -136,13 +195,13 @@ public class AccountSummaryAdapter
                             String.format("Don't know how to handle long click on id %d", id));
                     return false;
             }
-            LedgerAccount acc = (LedgerAccount) row.getTag();
+            LedgerAccount acc = getAccount();
             builder.setTitle(acc.getName());
             builder.setItems(R.array.acc_ctx_menu, (dialog, which) -> {
                 switch (which) {
                     case 0:
                         // show transactions
-                        activity.showAccountTransactions(acc);
+                        activity.showAccountTransactions(acc.getName());
                         break;
                 }
                 dialog.dismiss();
@@ -150,5 +209,36 @@ public class AccountSummaryAdapter
             builder.show();
             return true;
         }
+        public void bindToAccount(LedgerAccount acc) {
+            Context ctx = row.getContext();
+            Resources rm = ctx.getResources();
+
+            row.setTag(acc);
+
+            tvAccountName.setText(acc.getShortName());
+
+            ConstraintLayout.LayoutParams lp =
+                    (ConstraintLayout.LayoutParams) tvAccountName.getLayoutParams();
+            lp.setMarginStart(
+                    acc.getLevel() * rm.getDimensionPixelSize(R.dimen.thumb_row_height) / 3);
+
+            if (acc.hasSubAccounts()) {
+                expanderContainer.setVisibility(View.VISIBLE);
+                expanderContainer.setRotation(acc.isExpanded() ? 0 : 180);
+            }
+            else {
+                expanderContainer.setVisibility(View.GONE);
+            }
+
+            int amounts = acc.getAmountCount();
+            if ((amounts > AMOUNT_LIMIT) && !acc.amountsExpanded()) {
+                tvAccountAmounts.setText(acc.getAmountsString(AMOUNT_LIMIT));
+                accountExpanderContainer.setVisibility(View.VISIBLE);
+            }
+            else {
+                tvAccountAmounts.setText(acc.getAmountsString());
+                accountExpanderContainer.setVisibility(View.GONE);
+            }
+        }
     }
 }
index 79253bfb238faedd682e8dcdcefebca2ae96ca2c..9f2344fb605bbad3c2a09cc3a4110b9a64108592 100644 (file)
@@ -31,12 +31,17 @@ import androidx.recyclerview.widget.RecyclerView;
 
 import net.ktnx.mobileledger.R;
 import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
 import net.ktnx.mobileledger.ui.MobileLedgerListFragment;
 import net.ktnx.mobileledger.ui.activity.MainActivity;
 import net.ktnx.mobileledger.utils.Colors;
+import net.ktnx.mobileledger.utils.Logger;
 
 import org.jetbrains.annotations.NotNull;
 
+import java.util.ArrayList;
+
 import static net.ktnx.mobileledger.utils.Logger.debug;
 
 public class AccountSummaryFragment extends MobileLedgerListFragment {
@@ -90,7 +95,15 @@ public class AccountSummaryFragment extends MobileLedgerListFragment {
             Data.scheduleTransactionListRetrieval(mainActivity);
         });
 
-        Data.accounts.addObserver(
-                (o, arg) -> mainActivity.runOnUiThread(() -> modelAdapter.notifyDataSetChanged()));
+        Data.profile.observe(getViewLifecycleOwner(), profile -> profile.getAccounts()
+                                                                        .observe(
+                                                                                getViewLifecycleOwner(),
+                                                                                (accounts) -> onAccountsChanged(
+                                                                                        profile,
+                                                                                        accounts)));
+    }
+    private void onAccountsChanged(MobileLedgerProfile profile, ArrayList<LedgerAccount> accounts) {
+        Logger.debug("async-acc", "fragment: got new account list");
+        modelAdapter.setAccounts(profile, accounts);
     }
 }
diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryViewModel.java b/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryViewModel.java
deleted file mode 100644 (file)
index d7f4c61..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright © 2019 Damyan Ivanov.
- * This file is part of MoLe.
- * MoLe is free software: you can distribute it and/or modify it
- * under the term of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion), any later version.
- *
- * MoLe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License terms for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package net.ktnx.mobileledger.ui.account_summary;
-
-import android.os.AsyncTask;
-
-import androidx.lifecycle.ViewModel;
-
-import net.ktnx.mobileledger.async.UpdateAccountsTask;
-import net.ktnx.mobileledger.model.Data;
-import net.ktnx.mobileledger.model.LedgerAccount;
-
-import java.util.ArrayList;
-
-import static net.ktnx.mobileledger.utils.Logger.debug;
-
-public class AccountSummaryViewModel extends ViewModel {
-    static public void scheduleAccountListReload() {
-        if (Data.profile.getValue() == null) return;
-
-        UAT task = new UAT();
-        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
-    }
-
-    private static class UAT extends UpdateAccountsTask {
-        @Override
-        protected void onPostExecute(ArrayList<LedgerAccount> list) {
-            super.onPostExecute(list);
-            if (list != null) {
-                debug("acc", "setting updated account list");
-                Data.accounts.setList(list);
-            }
-        }
-    }
-
-}
-
index 8d9adfbed658011bf0aa73066fd671a4898f21cb..3a210ef07720d04b9396e5b36d37ca504952e987 100644 (file)
@@ -31,7 +31,6 @@ import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewPropertyAnimator;
 import android.view.animation.AnimationUtils;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
@@ -53,22 +52,18 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.google.android.material.snackbar.Snackbar;
 
 import net.ktnx.mobileledger.R;
-import net.ktnx.mobileledger.async.DbOpQueue;
 import net.ktnx.mobileledger.async.RefreshDescriptionsTask;
 import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
 import net.ktnx.mobileledger.model.Data;
 import net.ktnx.mobileledger.model.LedgerAccount;
 import net.ktnx.mobileledger.model.MobileLedgerProfile;
-import net.ktnx.mobileledger.ui.account_summary.AccountSummaryAdapter;
 import net.ktnx.mobileledger.ui.account_summary.AccountSummaryFragment;
-import net.ktnx.mobileledger.ui.account_summary.AccountSummaryViewModel;
 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.GetOptCallback;
-import net.ktnx.mobileledger.utils.LockHolder;
 import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.MLDB;
 
@@ -399,6 +394,10 @@ public class MainActivity extends ProfileThemedActivity {
         else
             setTitle(R.string.app_name);
 
+        if (this.profile != null)
+            this.profile.getAccounts()
+                        .removeObservers(this);
+
         this.profile = profile;
 
         int newProfileTheme = haveProfile ? profile.getThemeHue() : -1;
@@ -422,10 +421,9 @@ public class MainActivity extends ProfileThemedActivity {
         debug("transactions", "requesting list reload");
         TransactionListViewModel.scheduleTransactionListReload();
 
-        Data.accounts.clear();
-        AccountSummaryViewModel.scheduleAccountListReload();
-
         if (haveProfile) {
+            profile.scheduleAccountListReload();
+
             if (profile.isPostingPermitted()) {
                 mToolbar.setSubtitle(null);
                 fab.show();
@@ -529,16 +527,13 @@ public class MainActivity extends ProfileThemedActivity {
 
         showTransactionsFragment((String) null);
     }
-    private void showTransactionsFragment(String accName) {
+    public void showTransactionsFragment(String accName) {
         Data.accountFilter.setValue(accName);
         mViewPager.setCurrentItem(1, true);
     }
-    private void showTransactionsFragment(LedgerAccount account) {
-        showTransactionsFragment((account == null) ? null : account.getName());
-    }
-    public void showAccountTransactions(LedgerAccount account) {
+    public void showAccountTransactions(String accountName) {
         mBackMeansToAccountList = true;
-        showTransactionsFragment(account);
+        showTransactionsFragment(accountName);
     }
     @Override
     public void onBackPressed() {
@@ -658,87 +653,8 @@ public class MainActivity extends ProfileThemedActivity {
             case R.id.account_row_acc_name:
             case R.id.account_expander:
             case R.id.account_expander_container:
-                debug("accounts", "Account expander clicked");
-                if (!acc.hasSubAccounts())
-                    return;
-
-                boolean wasExpanded = acc.isExpanded();
-
-                View arrow = row.findViewById(R.id.account_expander_container);
-
-                arrow.clearAnimation();
-                ViewPropertyAnimator animator = arrow.animate();
-
-                acc.toggleExpanded();
-                DbOpQueue.add("update accounts set expanded=? where name=? and profile=?",
-                        new Object[]{acc.isExpanded(), acc.getName(), profile.getUuid()
-                        });
-
-                if (wasExpanded) {
-                    debug("accounts", String.format("Collapsing account '%s'", acc.getName()));
-                    arrow.setRotation(0);
-                    animator.rotationBy(180);
-
-                    // removing all child accounts from the view
-                    int start = -1, count = 0;
-                    try (LockHolder ignored = Data.accounts.lockForWriting()) {
-                        for (int i = 0; i < Data.accounts.size(); i++) {
-                            if (acc.isParentOf(Data.accounts.get(i))) {
-//                                debug("accounts", String.format("Found a child '%s' at position
-//                                %d",
-//                                        Data.accounts.get(i).getName(), i));
-                                if (start == -1) {
-                                    start = i;
-                                }
-                                count++;
-                            }
-                            else {
-                                if (start != -1) {
-//                                    debug("accounts",
-//                                            String.format("Found a non-child '%s' at position %d",
-//                                                    Data.accounts.get(i).getName(), i));
-                                    break;
-                                }
-                            }
-                        }
-
-                        if (start != -1) {
-                            for (int j = 0; j < count; j++) {
-//                                debug("accounts", String.format("Removing item %d: %s", start + j,
-//                                        Data.accounts.get(start).getName()));
-                                Data.accounts.removeQuietly(start);
-                            }
-
-                            mAccountSummaryFragment.modelAdapter.notifyItemRangeRemoved(start,
-                                    count);
-                        }
-                    }
-                }
-                else {
-                    debug("accounts", String.format("Expanding account '%s'", acc.getName()));
-                    arrow.setRotation(180);
-                    animator.rotationBy(-180);
-                    List<LedgerAccount> children = profile.loadVisibleChildAccountsOf(acc);
-                    try (LockHolder ignored = Data.accounts.lockForWriting()) {
-                        int parentPos = Data.accounts.indexOf(acc);
-                        if (parentPos != -1) {
-                            // may have disappeared in a concurrent refresh operation
-                            Data.accounts.addAllQuietly(parentPos + 1, children);
-                            mAccountSummaryFragment.modelAdapter.notifyItemRangeInserted(
-                                    parentPos + 1, children.size());
-                        }
-                    }
-                }
                 break;
             case R.id.account_row_acc_amounts:
-                if (acc.getAmountCount() > AccountSummaryAdapter.AMOUNT_LIMIT) {
-                    acc.toggleAmountsExpanded();
-                    DbOpQueue.add(
-                            "update accounts set amounts_expanded=? where name=? and profile=?",
-                            new Object[]{acc.amountsExpanded(), acc.getName(), profile.getUuid()
-                            });
-                    Data.accounts.triggerItemChangedNotification(acc);
-                }
                 break;
         }
     }
index a314e7acc06d1a926d23df02bc80e4bf6f35e349..09840becfe91f384456a4b98060f07cd32287b95 100644 (file)
@@ -18,6 +18,5 @@
 
 <resources>
     <item name="VH" type="id" />
-    <item name="POS" type="id" />
     <item name="SELECTING" type="id" />
 </resources>
\ No newline at end of file