X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2Ftemplates%2FTemplateDetailsViewModel.java;h=414340cce7d73b5d29c2a183ab098909ade2be5d;hb=860e0419d619210bb59bcae1b64d8c5db90eef70;hp=bf1dc35a1d1c904c34c2613d20c4bdeb53cd140d;hpb=128cb44c82144c3bb2fcba8afba5636c0196b61d;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsViewModel.java b/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsViewModel.java index bf1dc35a..414340cc 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsViewModel.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsViewModel.java @@ -17,13 +17,13 @@ package net.ktnx.mobileledger.ui.templates; -import android.os.AsyncTask; - import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModel; +import net.ktnx.mobileledger.BuildConfig; +import net.ktnx.mobileledger.dao.BaseDAO; import net.ktnx.mobileledger.dao.TemplateAccountDAO; import net.ktnx.mobileledger.dao.TemplateHeaderDAO; import net.ktnx.mobileledger.db.DB; @@ -32,6 +32,7 @@ import net.ktnx.mobileledger.db.TemplateHeader; import net.ktnx.mobileledger.db.TemplateWithAccounts; import net.ktnx.mobileledger.model.TemplateDetailsItem; import net.ktnx.mobileledger.utils.Logger; +import net.ktnx.mobileledger.utils.Misc; import java.util.ArrayList; import java.util.Collections; @@ -41,46 +42,109 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; public class TemplateDetailsViewModel extends ViewModel { + static final String TAG = "template-details-model"; + static final String DB_TAG = TAG + "-db"; private final MutableLiveData> items = new MutableLiveData<>(Collections.emptyList()); + private final AtomicInteger syntheticItemId = new AtomicInteger(0); private Long mPatternId; - private String mDefaultPatternName; + private String mDefaultTemplateName; private boolean itemsLoaded = false; - private final AtomicInteger syntheticItemId = new AtomicInteger(0); - - public String getDefaultPatternName() { - return mDefaultPatternName; + public String getDefaultTemplateName() { + return mDefaultTemplateName; } - public void setDefaultPatternName(String name) { - mDefaultPatternName = name; + public void setDefaultTemplateName(String name) { + mDefaultTemplateName = name; } public void resetItems() { - checkItemConsistency(new ArrayList<>()); + applyList(new ArrayList<>()); } - public void checkItemConsistency(List list) { - if (list == null) - list = new ArrayList<>(items.getValue()); + public void applyList(List srcList) { + applyList(srcList, false); + } + public void applyList(List srcList, boolean async) { + boolean changes; + if (srcList == null) { + srcList = new ArrayList<>(items.getValue()); + changes = false; + } + else + changes = true; - boolean changes = false; - if (list.size() < 1) { + srcList = Collections.unmodifiableList(srcList); + + if (BuildConfig.DEBUG) { + Logger.debug(TAG, "Considering old list"); + for (TemplateDetailsItem item : srcList) + Logger.debug(TAG, String.format(Locale.US, " id %d pos %d", item.getId(), + item.getPosition())); + } + + ArrayList newList = new ArrayList<>(); + + boolean hasEmptyItem = false; + + if (srcList.size() < 1) { final TemplateDetailsItem.Header header = TemplateDetailsItem.createHeader(); - header.setName(mDefaultPatternName); header.setId(0); - list.add(header); + newList.add(header); changes = true; } + else { + newList.add(srcList.get(0)); + } - while (list.size() < 3) { + for (int i = 1; i < srcList.size(); i++) { + final TemplateDetailsItem.AccountRow accRow = srcList.get(i) + .asAccountRowItem(); + if (accRow.isEmpty()) { + // it is normal to have two empty rows if they are at the + // top (position 1 and 2) + if (!hasEmptyItem || i < 3) { + accRow.setPosition(newList.size()); + newList.add(accRow); + } + else + changes = true; // row skipped + + hasEmptyItem = true; + } + else { + accRow.setPosition(newList.size()); + newList.add(accRow); + } + } + + while (newList.size() < 3) { final TemplateDetailsItem.AccountRow accountRow = TemplateDetailsItem.createAccountRow(); accountRow.setId(genItemId()); - list.add(accountRow); + accountRow.setPosition(newList.size()); + newList.add(accountRow); changes = true; + hasEmptyItem = true; } - if (changes) - items.setValue(list); + if (!hasEmptyItem) { + final TemplateDetailsItem.AccountRow accountRow = + TemplateDetailsItem.createAccountRow(); + accountRow.setId(genItemId()); + accountRow.setPosition(newList.size()); + newList.add(accountRow); + changes = true; + } + + if (changes) { + Logger.debug(TAG, "Changes detected, applying new list"); + + if (async) + items.postValue(newList); + else + items.setValue(newList); + } + else + Logger.debug(TAG, "No changes, ignoring new list"); } public int genItemId() { return syntheticItemId.decrementAndGet(); @@ -109,15 +173,18 @@ public class TemplateDetailsViewModel extends ViewModel { ArrayList l = new ArrayList<>(); TemplateDetailsItem header = TemplateDetailsItem.fromRoomObject(src.header); + Logger.debug(DB_TAG, "Got header template item with id of " + header.getId()); l.add(header); + Collections.sort(src.accounts, + (o1, o2) -> Long.compare(o1.getPosition(), o2.getPosition())); for (TemplateAccount acc : src.accounts) { l.add(TemplateDetailsItem.fromRoomObject(acc)); } for (TemplateDetailsItem i : l) { - Logger.debug("patterns-db", "Loaded pattern item " + i); + Logger.debug(DB_TAG, "Loaded pattern item " + i); } - items.postValue(l); + applyList(l, true); itemsLoaded = true; dbList.removeObserver(this); @@ -140,16 +207,22 @@ public class TemplateDetailsViewModel extends ViewModel { Logger.debug("flow", "PatternDetailsViewModel.onSavePattern(); model=" + this); final List list = Objects.requireNonNull(items.getValue()); - AsyncTask.execute(() -> { + BaseDAO.runAsync(() -> { boolean newPattern = mPatternId == null || mPatternId <= 0; TemplateDetailsItem.Header modelHeader = list.get(0) .asHeaderItem(); + + modelHeader.setName(Misc.trim(modelHeader.getName())); + if (modelHeader.getName() + .isEmpty()) + modelHeader.setName(getDefaultTemplateName()); + TemplateHeaderDAO headerDAO = DB.get() .getTemplateDAO(); TemplateHeader dbHeader = modelHeader.toDBO(); if (newPattern) { - dbHeader.setId(null); + dbHeader.setId(0L); dbHeader.setId(mPatternId = headerDAO.insertSync(dbHeader)); } else @@ -170,7 +243,7 @@ public class TemplateDetailsViewModel extends ViewModel { dbAccount.setTemplateId(mPatternId); dbAccount.setPosition(i); if (dbAccount.getId() < 0) { - dbAccount.setId(null); + dbAccount.setId(0); dbAccount.setId(taDAO.insertSync(dbAccount)); } else @@ -186,6 +259,10 @@ public class TemplateDetailsViewModel extends ViewModel { } private ArrayList copyItems() { List oldList = items.getValue(); + + if (oldList == null) + return new ArrayList<>(); + ArrayList result = new ArrayList<>(oldList.size()); for (TemplateDetailsItem item : oldList) { @@ -200,15 +277,62 @@ public class TemplateDetailsViewModel extends ViewModel { return result; } public void moveItem(int sourcePos, int targetPos) { - ArrayList newList = new ArrayList<>(items.getValue()); - TemplateDetailsItem item = newList.remove(sourcePos); - newList.add(targetPos, item); + final List newList = copyItems(); + + if (BuildConfig.DEBUG) { + Logger.debug("drag", "Before move:"); + for (int i = 1; i < newList.size(); i++) { + final TemplateDetailsItem item = newList.get(i); + Logger.debug("drag", + String.format(Locale.US, " %d: id %d, pos %d", i, item.getId(), + item.getPosition())); + } + } + + { + TemplateDetailsItem item = newList.remove(sourcePos); + newList.add(targetPos, item); + } + + // adjust affected items' positions + { + int startPos, endPos; + if (sourcePos < targetPos) { + // moved down + startPos = sourcePos; + endPos = targetPos; + } + else { + // moved up + startPos = targetPos; + endPos = sourcePos; + } + + for (int i = startPos; i <= endPos; i++) { + newList.get(i) + .setPosition(i); + } + } + + if (BuildConfig.DEBUG) { + Logger.debug("drag", "After move:"); + for (int i = 1; i < newList.size(); i++) { + final TemplateDetailsItem item = newList.get(i); + Logger.debug("drag", + String.format(Locale.US, " %d: id %d, pos %d", i, item.getId(), + item.getPosition())); + } + } + items.setValue(newList); } public void removeItem(int position) { - ArrayList newList = new ArrayList<>(items.getValue()); + Logger.debug(TAG, "Removing item at position " + position); + ArrayList newList = copyItems(); newList.remove(position); - checkItemConsistency(newList); - items.setValue(newList); + for (int i = position; i < newList.size(); i++) + newList.get(i) + .setPosition(i); + applyList(newList); } } \ No newline at end of file