]> git.ktnx.net Git - mobile-ledger.git/blobdiff - app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailModel.java
Room-based profile management
[mobile-ledger.git] / app / src / main / java / net / ktnx / mobileledger / ui / profiles / ProfileDetailModel.java
index 92d1505fb0baa159bd38cf2e24b9f003d2ddfa4a..e1f956acb3b7e52ccde9ab59b2601ce4fcdeb0d6 100644 (file)
@@ -24,10 +24,11 @@ import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.Observer;
 import androidx.lifecycle.ViewModel;
 
-import net.ktnx.mobileledger.async.SendTransactionTask;
-import net.ktnx.mobileledger.model.Currency;
+import net.ktnx.mobileledger.App;
+import net.ktnx.mobileledger.db.Profile;
+import net.ktnx.mobileledger.json.API;
+import net.ktnx.mobileledger.model.FutureDates;
 import net.ktnx.mobileledger.model.HledgerVersion;
-import net.ktnx.mobileledger.model.MobileLedgerProfile;
 import net.ktnx.mobileledger.utils.Colors;
 import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.Misc;
@@ -47,20 +48,20 @@ public class ProfileDetailModel extends ViewModel {
     private static final String HTTPS_URL_START = "https://";
     private final MutableLiveData<String> profileName = new MutableLiveData<>();
     private final MutableLiveData<Boolean> postingPermitted = new MutableLiveData<>(true);
-    private final MutableLiveData<Currency> defaultCommodity = new MutableLiveData<>(null);
-    private final MutableLiveData<MobileLedgerProfile.FutureDates> futureDates =
-            new MutableLiveData<>(MobileLedgerProfile.FutureDates.None);
+    private final MutableLiveData<String> defaultCommodity = new MutableLiveData<>(null);
+    private final MutableLiveData<FutureDates> futureDates =
+            new MutableLiveData<>(FutureDates.None);
     private final MutableLiveData<Boolean> showCommodityByDefault = new MutableLiveData<>(false);
     private final MutableLiveData<Boolean> showCommentsByDefault = new MutableLiveData<>(true);
     private final MutableLiveData<Boolean> useAuthentication = new MutableLiveData<>(false);
-    private final MutableLiveData<SendTransactionTask.API> apiVersion =
-            new MutableLiveData<>(SendTransactionTask.API.auto);
+    private final MutableLiveData<API> apiVersion = new MutableLiveData<>(API.auto);
     private final MutableLiveData<String> url = new MutableLiveData<>(null);
     private final MutableLiveData<String> authUserName = new MutableLiveData<>(null);
     private final MutableLiveData<String> authPassword = new MutableLiveData<>(null);
     private final MutableLiveData<String> preferredAccountsFilter = new MutableLiveData<>(null);
     private final MutableLiveData<Integer> themeId = new MutableLiveData<>(-1);
     private final MutableLiveData<HledgerVersion> detectedVersion = new MutableLiveData<>(null);
+    private final MutableLiveData<Boolean> detectingHledgerVersion = new MutableLiveData<>(false);
     public int initialThemeHue = Colors.DEFAULT_HUE_DEG;
     private VersionDetectionThread versionDetectionThread;
     public ProfileDetailModel() {
@@ -96,24 +97,24 @@ public class ProfileDetailModel extends ViewModel {
     void observeShowCommentsByDefault(LifecycleOwner lfo, Observer<Boolean> o) {
         showCommentsByDefault.observe(lfo, o);
     }
-    MobileLedgerProfile.FutureDates getFutureDates() {
+    FutureDates getFutureDates() {
         return futureDates.getValue();
     }
-    void setFutureDates(MobileLedgerProfile.FutureDates newValue) {
+    void setFutureDates(FutureDates newValue) {
         if (newValue != futureDates.getValue())
             futureDates.setValue(newValue);
     }
-    void observeFutureDates(LifecycleOwner lfo, Observer<MobileLedgerProfile.FutureDates> o) {
+    void observeFutureDates(LifecycleOwner lfo, Observer<FutureDates> o) {
         futureDates.observe(lfo, o);
     }
-    Currency getDefaultCommodity() {
+    String getDefaultCommodity() {
         return defaultCommodity.getValue();
     }
-    void setDefaultCommodity(Currency newValue) {
-        if (newValue != defaultCommodity.getValue())
+    void setDefaultCommodity(String newValue) {
+        if (!Misc.equalStrings(newValue, defaultCommodity.getValue()))
             defaultCommodity.setValue(newValue);
     }
-    void observeDefaultCommodity(LifecycleOwner lfo, Observer<Currency> o) {
+    void observeDefaultCommodity(LifecycleOwner lfo, Observer<String> o) {
         defaultCommodity.observe(lfo, o);
     }
     Boolean getShowCommodityByDefault() {
@@ -126,7 +127,7 @@ public class ProfileDetailModel extends ViewModel {
     void observeShowCommodityByDefault(LifecycleOwner lfo, Observer<Boolean> o) {
         showCommodityByDefault.observe(lfo, o);
     }
-    Boolean getUseAuthentication() {
+    public Boolean getUseAuthentication() {
         return useAuthentication.getValue();
     }
     void setUseAuthentication(boolean newValue) {
@@ -136,14 +137,14 @@ public class ProfileDetailModel extends ViewModel {
     void observeUseAuthentication(LifecycleOwner lfo, Observer<Boolean> o) {
         useAuthentication.observe(lfo, o);
     }
-    SendTransactionTask.API getApiVersion() {
+    API getApiVersion() {
         return apiVersion.getValue();
     }
-    void setApiVersion(SendTransactionTask.API newValue) {
+    void setApiVersion(API newValue) {
         if (newValue != apiVersion.getValue())
             apiVersion.setValue(newValue);
     }
-    void observeApiVersion(LifecycleOwner lfo, Observer<SendTransactionTask.API> o) {
+    void observeApiVersion(LifecycleOwner lfo, Observer<API> o) {
         apiVersion.observe(lfo, o);
     }
     HledgerVersion getDetectedVersion() { return detectedVersion.getValue(); }
@@ -154,7 +155,7 @@ public class ProfileDetailModel extends ViewModel {
     void observeDetectedVersion(LifecycleOwner lfo, Observer<HledgerVersion> o) {
         detectedVersion.observe(lfo, o);
     }
-    String getUrl() {
+    public String getUrl() {
         return url.getValue();
     }
     void setUrl(String newValue) {
@@ -168,7 +169,7 @@ public class ProfileDetailModel extends ViewModel {
     void observeUrl(LifecycleOwner lfo, Observer<String> o) {
         url.observe(lfo, o);
     }
-    String getAuthUserName() {
+    public String getAuthUserName() {
         return authUserName.getValue();
     }
     void setAuthUserName(String newValue) {
@@ -182,7 +183,7 @@ public class ProfileDetailModel extends ViewModel {
     void observeUserName(LifecycleOwner lfo, Observer<String> o) {
         authUserName.observe(lfo, o);
     }
-    String getAuthPassword() {
+    public String getAuthPassword() {
         return authPassword.getValue();
     }
     void setAuthPassword(String newValue) {
@@ -219,11 +220,13 @@ public class ProfileDetailModel extends ViewModel {
     void observeThemeId(LifecycleOwner lfo, Observer<Integer> o) {
         themeId.observe(lfo, o);
     }
-    void setValuesFromProfile(MobileLedgerProfile mProfile, int newProfileHue) {
-        final int profileThemeId;
+    void observeDetectingHledgerVersion(LifecycleOwner lfo, Observer<Boolean> o) {
+        detectingHledgerVersion.observe(lfo, o);
+    }
+    void setValuesFromProfile(Profile mProfile) {
         if (mProfile != null) {
             profileName.setValue(mProfile.getName());
-            postingPermitted.setValue(mProfile.isPostingPermitted());
+            postingPermitted.setValue(mProfile.permitPosting());
             showCommentsByDefault.setValue(mProfile.getShowCommentsByDefault());
             showCommodityByDefault.setValue(mProfile.getShowCommodityByDefault());
             {
@@ -231,17 +234,21 @@ public class ProfileDetailModel extends ViewModel {
                 if (TextUtils.isEmpty(comm))
                     setDefaultCommodity(null);
                 else
-                    setDefaultCommodity(new Currency(-1, comm));
+                    setDefaultCommodity(comm);
             }
-            futureDates.setValue(mProfile.getFutureDates());
-            apiVersion.setValue(mProfile.getApiVersion());
+            futureDates.setValue(
+                    FutureDates.valueOf(mProfile.getFutureDates()));
+            apiVersion.setValue(API.valueOf(mProfile.getApiVersion()));
             url.setValue(mProfile.getUrl());
-            useAuthentication.setValue(mProfile.isAuthEnabled());
-            authUserName.setValue(mProfile.isAuthEnabled() ? mProfile.getAuthUserName() : "");
-            authPassword.setValue(mProfile.isAuthEnabled() ? mProfile.getAuthPassword() : "");
+            useAuthentication.setValue(mProfile.useAuthentication());
+            authUserName.setValue(mProfile.useAuthentication() ? mProfile.getAuthUser() : "");
+            authPassword.setValue(mProfile.useAuthentication() ? mProfile.getAuthPassword() : "");
             preferredAccountsFilter.setValue(mProfile.getPreferredAccountsFilter());
-            themeId.setValue(mProfile.getThemeHue());
-            detectedVersion.setValue(mProfile.getDetectedVersion());
+            themeId.setValue(mProfile.getTheme());
+            detectedVersion.setValue(mProfile.detectedVersionPre_1_19() ? new HledgerVersion(true)
+                                                                        : new HledgerVersion(
+                                                                                mProfile.getDetectedVersionMajor(),
+                                                                                mProfile.getDetectedVersionMinor()));
         }
         else {
             profileName.setValue(null);
@@ -249,32 +256,35 @@ public class ProfileDetailModel extends ViewModel {
             postingPermitted.setValue(true);
             showCommentsByDefault.setValue(true);
             showCommodityByDefault.setValue(false);
-            setFutureDates(MobileLedgerProfile.FutureDates.None);
-            setApiVersion(SendTransactionTask.API.auto);
+            setFutureDates(FutureDates.None);
+            setApiVersion(API.auto);
             useAuthentication.setValue(false);
             authUserName.setValue("");
             authPassword.setValue("");
             preferredAccountsFilter.setValue(null);
-            themeId.setValue(newProfileHue);
             detectedVersion.setValue(null);
         }
     }
-    void updateProfile(MobileLedgerProfile mProfile) {
+    void updateProfile(Profile mProfile) {
         mProfile.setName(profileName.getValue());
         mProfile.setUrl(url.getValue());
-        mProfile.setPostingPermitted(postingPermitted.getValue());
+        mProfile.setPermitPosting(postingPermitted.getValue());
         mProfile.setShowCommentsByDefault(showCommentsByDefault.getValue());
-        Currency c = defaultCommodity.getValue();
-        mProfile.setDefaultCommodity((c == null) ? null : c.getName());
+        mProfile.setDefaultCommodity(defaultCommodity.getValue());
         mProfile.setShowCommodityByDefault(showCommodityByDefault.getValue());
         mProfile.setPreferredAccountsFilter(preferredAccountsFilter.getValue());
-        mProfile.setAuthEnabled(useAuthentication.getValue());
-        mProfile.setAuthUserName(authUserName.getValue());
+        mProfile.setUseAuthentication(useAuthentication.getValue());
+        mProfile.setAuthUser(authUserName.getValue());
         mProfile.setAuthPassword(authPassword.getValue());
-        mProfile.setThemeHue(themeId.getValue());
-        mProfile.setFutureDates(futureDates.getValue());
-        mProfile.setApiVersion(apiVersion.getValue());
-        mProfile.setDetectedVersion(detectedVersion.getValue());
+        mProfile.setTheme(themeId.getValue());
+        mProfile.setFutureDates(futureDates.getValue()
+                                           .toInt());
+        mProfile.setApiVersion(apiVersion.getValue()
+                                         .toInt());
+        HledgerVersion version = detectedVersion.getValue();
+        mProfile.setDetectedVersionPre_1_19(version.isPre_1_20_1());
+        mProfile.setDetectedVersionMajor(version.getMajor());
+        mProfile.setDetectedVersionMinor(version.getMinor());
     }
     synchronized public void triggerVersionDetection() {
         if (versionDetectionThread != null)
@@ -284,29 +294,29 @@ public class ProfileDetailModel extends ViewModel {
         versionDetectionThread.start();
     }
     static class VersionDetectionThread extends Thread {
+        static final int TARGET_PROCESS_DURATION = 1000;
         private final Pattern versionPattern =
                 Pattern.compile("^\"(\\d+)\\.(\\d+)(?:\\.(\\d+))?\"$");
         private final ProfileDetailModel model;
         public VersionDetectionThread(ProfileDetailModel model) {
             this.model = model;
         }
-        @Override
-        public void run() {
+        private HledgerVersion detectVersion() {
+            App.setAuthenticationDataFromProfileModel(model);
+            HttpURLConnection http;
             try {
-                HttpURLConnection http = NetworkUtil.prepareConnection(model.getUrl(), "version",
+                http = NetworkUtil.prepareConnection(model.getUrl(), "version",
                         model.getUseAuthentication());
                 switch (http.getResponseCode()) {
                     case 200:
                         break;
                     case 404:
-                        model.detectedVersion.postValue(new HledgerVersion(true));
-                        return;
+                        return new HledgerVersion(true);
                     default:
                         Logger.debug("profile", String.format(Locale.US,
                                 "HTTP error detecting hledger-web version: [%d] %s",
                                 http.getResponseCode(), http.getResponseMessage()));
-                        model.detectedVersion.postValue(null);
-                        return;
+                        return null;
                 }
                 InputStream stream = http.getInputStream();
                 BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
@@ -318,17 +328,45 @@ public class ProfileDetailModel extends ViewModel {
                     final boolean hasPatch = m.groupCount() >= 3;
                     int patch = hasPatch ? Integer.parseInt(Objects.requireNonNull(m.group(3))) : 0;
 
-                    model.detectedVersion.postValue(
-                            hasPatch ? new HledgerVersion(major, minor, patch)
-                                     : new HledgerVersion(major, minor));
+                    return hasPatch ? new HledgerVersion(major, minor, patch)
+                                    : new HledgerVersion(major, minor);
                 }
                 else {
                     Logger.debug("profile",
                             String.format("Unrecognised version string '%s'", version));
+                    return null;
                 }
             }
             catch (IOException e) {
                 e.printStackTrace();
+                return null;
+            }
+            finally {
+                App.resetAuthenticationData();
+            }
+        }
+        @Override
+        public void run() {
+            model.detectingHledgerVersion.postValue(true);
+            try {
+                long startTime = System.currentTimeMillis();
+
+                final HledgerVersion version = detectVersion();
+
+                long elapsed = System.currentTimeMillis() - startTime;
+                Logger.debug("profile", "Detection duration " + elapsed);
+                if (elapsed < TARGET_PROCESS_DURATION) {
+                    try {
+                        Thread.sleep(TARGET_PROCESS_DURATION - elapsed);
+                    }
+                    catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+                model.detectedVersion.postValue(version);
+            }
+            finally {
+                model.detectingHledgerVersion.postValue(false);
             }
         }
     }