From ee78d9acfeeae6f7ce6ccc65b468dc674045ab1d Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Sun, 5 Aug 2018 19:41:27 +0300
Subject: [PATCH 01/10] fix page indicator issue (needs cleanup)
---
 .../activities/topic/TopicActivity.java       | 55 +++++++------------
 .../mthmmy/viewmodel/TopicViewModel.java      | 34 +++++++++++-
 2 files changed, 52 insertions(+), 37 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index e2f92054..4af5a99f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -103,11 +103,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
      * long click is held in either first or last buttons
      */
     private static final int LARGE_STEP = 10;
-    /**
-     * Holds the value (index) of the page to be requested when a user interaction with bottom
-     * navigation bar occurs
-     */
-    private Integer pageRequestValue;
 
     //Bottom navigation bar graphics related
     private LinearLayout bottomNavBar;
@@ -206,6 +201,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
 
         paginationEnabled(false);
 
+        viewModel.getPageIndicatorIndex().observe(this, pageIndicatorIndex -> {
+            if (pageIndicatorIndex == null) return;
+            pageIndicator.setText(String.valueOf(pageIndicatorIndex) + "/" +
+                    String.valueOf(viewModel.getPageCount()));
+        });
         viewModel.getTopicTaskResult().observe(this, topicTaskResult -> {
             if (topicTaskResult == null) {
                 progressBar.setVisibility(ProgressBar.VISIBLE);
@@ -222,9 +222,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                         postsList.addAll(topicTaskResult.getNewPostsList());
                         topicAdapter.notifyDataSetChanged();
 
-                        pageIndicator.setText(String.valueOf(topicTaskResult.getCurrentPageIndex()) + "/" +
-                                String.valueOf(topicTaskResult.getPageCount()));
-                        pageRequestValue = topicTaskResult.getCurrentPageIndex();
                         paginationEnabled(true);
 
                         if (topicTaskResult.getCurrentPageIndex() == topicTaskResult.getPageCount()) {
@@ -400,10 +397,10 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         public void run() {
             long REPEAT_DELAY = 250;
             if (autoIncrement) {
-                incrementPageRequestValue(step);
+                viewModel.incrementPageRequestValue(step);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             } else if (autoDecrement) {
-                decrementPageRequestValue(step);
+                viewModel.decrementPageRequestValue(step);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             }
         }
@@ -443,11 +440,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Increment once for a click
         increment.setOnClickListener(v -> {
             if (!autoIncrement && step == LARGE_STEP) {
-                incrementPageRequestValue(viewModel.getPageCount());
+                viewModel.incrementPageRequestValue(viewModel.getPageCount());
                 viewModel.changePage(viewModel.getPageCount() - 1);
             } else if (!autoIncrement) {
-                incrementPageRequestValue(step);
-                viewModel.changePage(pageRequestValue - 1);
+                viewModel.incrementPageRequestValue(step);
+                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
             }
         });
 
@@ -471,11 +468,12 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_UP && autoIncrement) {
                     autoIncrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(pageRequestValue - 1);
+                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        decrementPageRequestValue(pageRequestValue - viewModel.getCurrentPageIndex());
+                        viewModel.decrementPageRequestValue(viewModel.getPageIndicatorIndex().getValue()
+                                - viewModel.getCurrentPageIndex());
                         paginationEnabled(true);
                     }
                 }
@@ -489,11 +487,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Decrement once for a click
         decrement.setOnClickListener(v -> {
             if (!autoDecrement && step == LARGE_STEP) {
-                decrementPageRequestValue(viewModel.getPageCount());
+                viewModel.decrementPageRequestValue(viewModel.getPageCount());
                 viewModel.changePage(0);
             } else if (!autoDecrement) {
-                decrementPageRequestValue(step);
-                viewModel.changePage(pageRequestValue - 1);
+                viewModel.decrementPageRequestValue(step);
+                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
             }
         });
 
@@ -517,12 +515,13 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) {
                     autoDecrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(pageRequestValue - 1);
+                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
                 } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (rect != null &&
                             !rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        incrementPageRequestValue(viewModel.getCurrentPageIndex() - pageRequestValue);
+                        viewModel.incrementPageRequestValue(viewModel.getCurrentPageIndex()
+                                - viewModel.getPageIndicatorIndex().getValue());
                         paginationEnabled(true);
                     }
                 }
@@ -531,22 +530,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         });
     }
 
-    private void incrementPageRequestValue(int step) {
-        if (pageRequestValue < viewModel.getPageCount() - step) {
-            pageRequestValue = pageRequestValue + step;
-        } else
-            pageRequestValue = viewModel.getPageCount();
-        pageIndicator.setText(pageRequestValue + "/" + String.valueOf(viewModel.getPageCount()));
-    }
-
-    private void decrementPageRequestValue(int step) {
-        if (pageRequestValue > step)
-            pageRequestValue = pageRequestValue - step;
-        else
-            pageRequestValue = 1;
-        pageIndicator.setText(pageRequestValue + "/" + String.valueOf(viewModel.getPageCount()));
-    }
-
     //------------------------------------BOTTOM NAV BAR METHODS END------------------------------------
 
     @Override
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 1fb97407..ae1ed048 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -54,6 +54,11 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     private EditTask.EditTaskCallbacks editTaskCallbacks;
     private PrepareForReply.PrepareForReplyCallbacks prepareForReplyCallbacks;
 
+    /**
+     * Holds the value (index) of the page to be requested when a user interaction with bottom
+     * navigation bar occurs, aka the value that the page indicator shows
+     */
+    private MutableLiveData pageIndicatorIndex = new MutableLiveData<>();
     private MutableLiveData topicTaskResult = new MutableLiveData<>();
     private MutableLiveData prepareForReplyResult = new MutableLiveData<>();
     private MutableLiveData prepareForEditResult = new MutableLiveData<>();
@@ -81,8 +86,10 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void changePage(int pageRequested) {
         if (topicTaskResult.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
-        if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1)
+        if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1) {
             loadUrl(topicTaskResult.getValue().getPagesUrls().get(pageRequested));
+            pageIndicatorIndex.setValue(pageRequested + 1);
+        }
     }
 
     public void prepareForReply() {
@@ -140,6 +147,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void stopLoading() {
         if (currentTopicTask != null && currentTopicTask.getStatus() == AsyncTask.Status.RUNNING) {
             currentTopicTask.cancel(true);
+            pageIndicatorIndex.setValue(getCurrentPageIndex());
             topicTaskObserver.onTopicTaskCancelled();
         }
         if (currentPrepareForEditTask != null && currentPrepareForEditTask.getStatus() == AsyncTask.Status.RUNNING) {
@@ -159,6 +167,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void onTopicTaskCompleted(TopicTaskResult result) {
         topicTaskResult.setValue(result);
         if (result.getResultCode() == TopicTask.ResultCode.SUCCESS) {
+            pageIndicatorIndex.setValue(result.getCurrentPageIndex());
             isUserExtraInfoVisibile.clear();
             for (int i = 0; i < result.getNewPostsList().size(); i++) {
                 isUserExtraInfoVisibile.add(false);
@@ -179,8 +188,31 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         prepareForEditResult.setValue(result);
     }
 
+    public void incrementPageRequestValue(int step) {
+        if (pageIndicatorIndex.getValue() < getPageCount() - step)
+            pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() - step);
+        else
+            pageIndicatorIndex.setValue(getPageCount());
+    }
+
+    public void decrementPageRequestValue(int step) {
+        if (pageIndicatorIndex.getValue() > step)
+            pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() - step);
+        else
+            pageIndicatorIndex.setValue(1);
+    }
+
     // <-------------Just getters, setters and helper methods below here---------------->
 
+
+    public MutableLiveData getPageIndicatorIndex() {
+        return pageIndicatorIndex;
+    }
+
+    public void setPageIndicatorIndex(Integer pageIndicatorIndex) {
+        this.pageIndicatorIndex.setValue(pageIndicatorIndex);
+    }
+
     public boolean isUserExtraInfoVisible(int position) {
         return isUserExtraInfoVisibile.get(position);
     }
From dfcd595596ff01fd4df227aeed8707f036320a96 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Sun, 5 Aug 2018 19:41:27 +0300
Subject: [PATCH 02/10] fix page indicator issue (needs cleanup)
---
 .../activities/topic/TopicActivity.java       | 55 +++++++------------
 .../mthmmy/viewmodel/TopicViewModel.java      | 34 +++++++++++-
 2 files changed, 52 insertions(+), 37 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index e2f92054..4af5a99f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -103,11 +103,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
      * long click is held in either first or last buttons
      */
     private static final int LARGE_STEP = 10;
-    /**
-     * Holds the value (index) of the page to be requested when a user interaction with bottom
-     * navigation bar occurs
-     */
-    private Integer pageRequestValue;
 
     //Bottom navigation bar graphics related
     private LinearLayout bottomNavBar;
@@ -206,6 +201,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
 
         paginationEnabled(false);
 
+        viewModel.getPageIndicatorIndex().observe(this, pageIndicatorIndex -> {
+            if (pageIndicatorIndex == null) return;
+            pageIndicator.setText(String.valueOf(pageIndicatorIndex) + "/" +
+                    String.valueOf(viewModel.getPageCount()));
+        });
         viewModel.getTopicTaskResult().observe(this, topicTaskResult -> {
             if (topicTaskResult == null) {
                 progressBar.setVisibility(ProgressBar.VISIBLE);
@@ -222,9 +222,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                         postsList.addAll(topicTaskResult.getNewPostsList());
                         topicAdapter.notifyDataSetChanged();
 
-                        pageIndicator.setText(String.valueOf(topicTaskResult.getCurrentPageIndex()) + "/" +
-                                String.valueOf(topicTaskResult.getPageCount()));
-                        pageRequestValue = topicTaskResult.getCurrentPageIndex();
                         paginationEnabled(true);
 
                         if (topicTaskResult.getCurrentPageIndex() == topicTaskResult.getPageCount()) {
@@ -400,10 +397,10 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         public void run() {
             long REPEAT_DELAY = 250;
             if (autoIncrement) {
-                incrementPageRequestValue(step);
+                viewModel.incrementPageRequestValue(step);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             } else if (autoDecrement) {
-                decrementPageRequestValue(step);
+                viewModel.decrementPageRequestValue(step);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             }
         }
@@ -443,11 +440,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Increment once for a click
         increment.setOnClickListener(v -> {
             if (!autoIncrement && step == LARGE_STEP) {
-                incrementPageRequestValue(viewModel.getPageCount());
+                viewModel.incrementPageRequestValue(viewModel.getPageCount());
                 viewModel.changePage(viewModel.getPageCount() - 1);
             } else if (!autoIncrement) {
-                incrementPageRequestValue(step);
-                viewModel.changePage(pageRequestValue - 1);
+                viewModel.incrementPageRequestValue(step);
+                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
             }
         });
 
@@ -471,11 +468,12 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_UP && autoIncrement) {
                     autoIncrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(pageRequestValue - 1);
+                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        decrementPageRequestValue(pageRequestValue - viewModel.getCurrentPageIndex());
+                        viewModel.decrementPageRequestValue(viewModel.getPageIndicatorIndex().getValue()
+                                - viewModel.getCurrentPageIndex());
                         paginationEnabled(true);
                     }
                 }
@@ -489,11 +487,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Decrement once for a click
         decrement.setOnClickListener(v -> {
             if (!autoDecrement && step == LARGE_STEP) {
-                decrementPageRequestValue(viewModel.getPageCount());
+                viewModel.decrementPageRequestValue(viewModel.getPageCount());
                 viewModel.changePage(0);
             } else if (!autoDecrement) {
-                decrementPageRequestValue(step);
-                viewModel.changePage(pageRequestValue - 1);
+                viewModel.decrementPageRequestValue(step);
+                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
             }
         });
 
@@ -517,12 +515,13 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) {
                     autoDecrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(pageRequestValue - 1);
+                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
                 } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (rect != null &&
                             !rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        incrementPageRequestValue(viewModel.getCurrentPageIndex() - pageRequestValue);
+                        viewModel.incrementPageRequestValue(viewModel.getCurrentPageIndex()
+                                - viewModel.getPageIndicatorIndex().getValue());
                         paginationEnabled(true);
                     }
                 }
@@ -531,22 +530,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         });
     }
 
-    private void incrementPageRequestValue(int step) {
-        if (pageRequestValue < viewModel.getPageCount() - step) {
-            pageRequestValue = pageRequestValue + step;
-        } else
-            pageRequestValue = viewModel.getPageCount();
-        pageIndicator.setText(pageRequestValue + "/" + String.valueOf(viewModel.getPageCount()));
-    }
-
-    private void decrementPageRequestValue(int step) {
-        if (pageRequestValue > step)
-            pageRequestValue = pageRequestValue - step;
-        else
-            pageRequestValue = 1;
-        pageIndicator.setText(pageRequestValue + "/" + String.valueOf(viewModel.getPageCount()));
-    }
-
     //------------------------------------BOTTOM NAV BAR METHODS END------------------------------------
 
     @Override
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 1fb97407..e4c7ec55 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -54,6 +54,11 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     private EditTask.EditTaskCallbacks editTaskCallbacks;
     private PrepareForReply.PrepareForReplyCallbacks prepareForReplyCallbacks;
 
+    /**
+     * Holds the value (index) of the page to be requested when a user interaction with bottom
+     * navigation bar occurs, aka the value that the page indicator shows
+     */
+    private MutableLiveData pageIndicatorIndex = new MutableLiveData<>();
     private MutableLiveData topicTaskResult = new MutableLiveData<>();
     private MutableLiveData prepareForReplyResult = new MutableLiveData<>();
     private MutableLiveData prepareForEditResult = new MutableLiveData<>();
@@ -81,8 +86,10 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void changePage(int pageRequested) {
         if (topicTaskResult.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
-        if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1)
+        if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1) {
             loadUrl(topicTaskResult.getValue().getPagesUrls().get(pageRequested));
+            pageIndicatorIndex.setValue(pageRequested + 1);
+        }
     }
 
     public void prepareForReply() {
@@ -140,6 +147,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void stopLoading() {
         if (currentTopicTask != null && currentTopicTask.getStatus() == AsyncTask.Status.RUNNING) {
             currentTopicTask.cancel(true);
+            pageIndicatorIndex.setValue(getCurrentPageIndex());
             topicTaskObserver.onTopicTaskCancelled();
         }
         if (currentPrepareForEditTask != null && currentPrepareForEditTask.getStatus() == AsyncTask.Status.RUNNING) {
@@ -159,6 +167,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void onTopicTaskCompleted(TopicTaskResult result) {
         topicTaskResult.setValue(result);
         if (result.getResultCode() == TopicTask.ResultCode.SUCCESS) {
+            pageIndicatorIndex.setValue(result.getCurrentPageIndex());
             isUserExtraInfoVisibile.clear();
             for (int i = 0; i < result.getNewPostsList().size(); i++) {
                 isUserExtraInfoVisibile.add(false);
@@ -179,8 +188,31 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         prepareForEditResult.setValue(result);
     }
 
+    public void incrementPageRequestValue(int step) {
+        if (pageIndicatorIndex.getValue() < getPageCount() - step)
+            pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() + step);
+        else
+            pageIndicatorIndex.setValue(getPageCount());
+    }
+
+    public void decrementPageRequestValue(int step) {
+        if (pageIndicatorIndex.getValue() > step)
+            pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() - step);
+        else
+            pageIndicatorIndex.setValue(1);
+    }
+
     // <-------------Just getters, setters and helper methods below here---------------->
 
+
+    public MutableLiveData getPageIndicatorIndex() {
+        return pageIndicatorIndex;
+    }
+
+    public void setPageIndicatorIndex(Integer pageIndicatorIndex) {
+        this.pageIndicatorIndex.setValue(pageIndicatorIndex);
+    }
+
     public boolean isUserExtraInfoVisible(int position) {
         return isUserExtraInfoVisibile.get(position);
     }
From fa8bb29d9d03a73143cb8e43e52bc5a46513371c Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Sun, 5 Aug 2018 23:37:30 +0300
Subject: [PATCH 03/10] minor improvements
---
 .../main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java   | 4 ----
 1 file changed, 4 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index e4c7ec55..3f5ad4cf 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -209,10 +209,6 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         return pageIndicatorIndex;
     }
 
-    public void setPageIndicatorIndex(Integer pageIndicatorIndex) {
-        this.pageIndicatorIndex.setValue(pageIndicatorIndex);
-    }
-
     public boolean isUserExtraInfoVisible(int position) {
         return isUserExtraInfoVisibile.get(position);
     }
From ffb80f0986160458f7c955bb5239dd8f4d511755 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Mon, 6 Aug 2018 16:42:18 +0300
Subject: [PATCH 04/10] cleanup
---
 .../activities/topic/TopicActivity.java       | 26 +++++++---------
 .../mthmmy/viewmodel/TopicViewModel.java      | 30 +++++++++++++------
 2 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index 4af5a99f..2ed8e25b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -397,10 +397,10 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         public void run() {
             long REPEAT_DELAY = 250;
             if (autoIncrement) {
-                viewModel.incrementPageRequestValue(step);
+                viewModel.incrementPageRequestValue(step, false);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             } else if (autoDecrement) {
-                viewModel.decrementPageRequestValue(step);
+                viewModel.decrementPageRequestValue(step, false);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             }
         }
@@ -440,11 +440,9 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Increment once for a click
         increment.setOnClickListener(v -> {
             if (!autoIncrement && step == LARGE_STEP) {
-                viewModel.incrementPageRequestValue(viewModel.getPageCount());
-                viewModel.changePage(viewModel.getPageCount() - 1);
+                viewModel.setPageIndicatorIndex(viewModel.getPageCount(), true);
             } else if (!autoIncrement) {
-                viewModel.incrementPageRequestValue(step);
-                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                viewModel.incrementPageRequestValue(step, true);
             }
         });
 
@@ -468,12 +466,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_UP && autoIncrement) {
                     autoIncrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                    viewModel.performPageChange();
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        viewModel.decrementPageRequestValue(viewModel.getPageIndicatorIndex().getValue()
-                                - viewModel.getCurrentPageIndex());
+                        viewModel.setPageIndicatorIndex(viewModel.getCurrentPageIndex(), false);
                         paginationEnabled(true);
                     }
                 }
@@ -487,11 +484,9 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Decrement once for a click
         decrement.setOnClickListener(v -> {
             if (!autoDecrement && step == LARGE_STEP) {
-                viewModel.decrementPageRequestValue(viewModel.getPageCount());
-                viewModel.changePage(0);
+                viewModel.setPageIndicatorIndex(1, true);
             } else if (!autoDecrement) {
-                viewModel.decrementPageRequestValue(step);
-                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                viewModel.decrementPageRequestValue(step, true);
             }
         });
 
@@ -515,13 +510,12 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) {
                     autoDecrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                    viewModel.performPageChange();
                 } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (rect != null &&
                             !rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        viewModel.incrementPageRequestValue(viewModel.getCurrentPageIndex()
-                                - viewModel.getPageIndicatorIndex().getValue());
+                        viewModel.setPageIndicatorIndex(viewModel.getCurrentPageIndex(), false);
                         paginationEnabled(true);
                     }
                 }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 3f5ad4cf..7442f4d9 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -83,9 +83,10 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         loadUrl(topicTaskResult.getValue().getLastPageLoadAttemptedUrl());
     }
 
-    public void changePage(int pageRequested) {
-        if (topicTaskResult.getValue() == null)
+    public void performPageChange() {
+        if (topicTaskResult.getValue() == null || pageIndicatorIndex.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
+        int pageRequested = pageIndicatorIndex.getValue() - 1;
         if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1) {
             loadUrl(topicTaskResult.getValue().getPagesUrls().get(pageRequested));
             pageIndicatorIndex.setValue(pageRequested + 1);
@@ -96,7 +97,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         if (topicTaskResult.getValue() == null)
             throw new NullPointerException("Topic task has not finished yet!");
         stopLoading();
-        changePage(topicTaskResult.getValue().getPageCount() - 1);
+        setPageIndicatorIndex(getPageCount(), true);
         currentPrepareForReplyTask = new PrepareForReply(prepareForReplyCallbacks, this,
                 topicTaskResult.getValue().getReplyPageUrl());
         currentPrepareForReplyTask.execute(toQuoteList.toArray(new Integer[0]));
@@ -188,20 +189,31 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         prepareForEditResult.setValue(result);
     }
 
-    public void incrementPageRequestValue(int step) {
-        if (pageIndicatorIndex.getValue() < getPageCount() - step)
+    public void incrementPageRequestValue(int step, boolean changePage) {
+        if (pageIndicatorIndex.getValue() == null)
+            throw new NullPointerException("No page has been loaded yet!");
+        if (pageIndicatorIndex.getValue() <= getPageCount() - step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() + step);
-        else
+            if (changePage) performPageChange();
+        } else
             pageIndicatorIndex.setValue(getPageCount());
     }
 
-    public void decrementPageRequestValue(int step) {
-        if (pageIndicatorIndex.getValue() > step)
+    public void decrementPageRequestValue(int step, boolean changePage) {
+        if (pageIndicatorIndex.getValue() == null)
+            throw new NullPointerException("No page has been loaded yet!");
+        if (pageIndicatorIndex.getValue() >= step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() - step);
-        else
+            if (changePage) performPageChange();
+        } else
             pageIndicatorIndex.setValue(1);
     }
 
+    public void setPageIndicatorIndex(int pageIndicatorIndex, boolean changePage) {
+        this.pageIndicatorIndex.setValue(pageIndicatorIndex);
+        if (changePage) performPageChange();
+    }
+
     // <-------------Just getters, setters and helper methods below here---------------->
 
 
From aeb7a370744fbf60c3233bc8fb578a487af6fd69 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Mon, 6 Aug 2018 16:42:18 +0300
Subject: [PATCH 05/10] cleanup
---
 .../activities/topic/TopicActivity.java       | 26 +++++++---------
 .../mthmmy/viewmodel/TopicViewModel.java      | 30 +++++++++++++------
 2 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index 4af5a99f..2ed8e25b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -397,10 +397,10 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         public void run() {
             long REPEAT_DELAY = 250;
             if (autoIncrement) {
-                viewModel.incrementPageRequestValue(step);
+                viewModel.incrementPageRequestValue(step, false);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             } else if (autoDecrement) {
-                viewModel.decrementPageRequestValue(step);
+                viewModel.decrementPageRequestValue(step, false);
                 repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
             }
         }
@@ -440,11 +440,9 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Increment once for a click
         increment.setOnClickListener(v -> {
             if (!autoIncrement && step == LARGE_STEP) {
-                viewModel.incrementPageRequestValue(viewModel.getPageCount());
-                viewModel.changePage(viewModel.getPageCount() - 1);
+                viewModel.setPageIndicatorIndex(viewModel.getPageCount(), true);
             } else if (!autoIncrement) {
-                viewModel.incrementPageRequestValue(step);
-                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                viewModel.incrementPageRequestValue(step, true);
             }
         });
 
@@ -468,12 +466,11 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_UP && autoIncrement) {
                     autoIncrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                    viewModel.performPageChange();
                 } else if (rect != null && event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        viewModel.decrementPageRequestValue(viewModel.getPageIndicatorIndex().getValue()
-                                - viewModel.getCurrentPageIndex());
+                        viewModel.setPageIndicatorIndex(viewModel.getCurrentPageIndex(), false);
                         paginationEnabled(true);
                     }
                 }
@@ -487,11 +484,9 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
         // Decrement once for a click
         decrement.setOnClickListener(v -> {
             if (!autoDecrement && step == LARGE_STEP) {
-                viewModel.decrementPageRequestValue(viewModel.getPageCount());
-                viewModel.changePage(0);
+                viewModel.setPageIndicatorIndex(1, true);
             } else if (!autoDecrement) {
-                viewModel.decrementPageRequestValue(step);
-                viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                viewModel.decrementPageRequestValue(step, true);
             }
         });
 
@@ -515,13 +510,12 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 } else if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) {
                     autoDecrement = false;
                     paginationEnabled(true);
-                    viewModel.changePage(viewModel.getPageIndicatorIndex().getValue() - 1);
+                    viewModel.performPageChange();
                 } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                     if (rect != null &&
                             !rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
                         autoIncrement = false;
-                        viewModel.incrementPageRequestValue(viewModel.getCurrentPageIndex()
-                                - viewModel.getPageIndicatorIndex().getValue());
+                        viewModel.setPageIndicatorIndex(viewModel.getCurrentPageIndex(), false);
                         paginationEnabled(true);
                     }
                 }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 3f5ad4cf..6416a85d 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -83,9 +83,10 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         loadUrl(topicTaskResult.getValue().getLastPageLoadAttemptedUrl());
     }
 
-    public void changePage(int pageRequested) {
-        if (topicTaskResult.getValue() == null)
+    public void performPageChange() {
+        if (topicTaskResult.getValue() == null || pageIndicatorIndex.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
+        int pageRequested = pageIndicatorIndex.getValue() - 1;
         if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1) {
             loadUrl(topicTaskResult.getValue().getPagesUrls().get(pageRequested));
             pageIndicatorIndex.setValue(pageRequested + 1);
@@ -96,7 +97,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         if (topicTaskResult.getValue() == null)
             throw new NullPointerException("Topic task has not finished yet!");
         stopLoading();
-        changePage(topicTaskResult.getValue().getPageCount() - 1);
+        setPageIndicatorIndex(getPageCount(), true);
         currentPrepareForReplyTask = new PrepareForReply(prepareForReplyCallbacks, this,
                 topicTaskResult.getValue().getReplyPageUrl());
         currentPrepareForReplyTask.execute(toQuoteList.toArray(new Integer[0]));
@@ -188,18 +189,29 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         prepareForEditResult.setValue(result);
     }
 
-    public void incrementPageRequestValue(int step) {
-        if (pageIndicatorIndex.getValue() < getPageCount() - step)
+    public void incrementPageRequestValue(int step, boolean changePage) {
+        if (pageIndicatorIndex.getValue() == null)
+            throw new NullPointerException("No page has been loaded yet!");
+        if (pageIndicatorIndex.getValue() <= getPageCount() - step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() + step);
-        else
+        } else
             pageIndicatorIndex.setValue(getPageCount());
+        if (changePage) performPageChange();
     }
 
-    public void decrementPageRequestValue(int step) {
-        if (pageIndicatorIndex.getValue() > step)
+    public void decrementPageRequestValue(int step, boolean changePage) {
+        if (pageIndicatorIndex.getValue() == null)
+            throw new NullPointerException("No page has been loaded yet!");
+        if (pageIndicatorIndex.getValue() >= step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() - step);
-        else
+        } else
             pageIndicatorIndex.setValue(1);
+        if (changePage) performPageChange();
+    }
+
+    public void setPageIndicatorIndex(int pageIndicatorIndex, boolean changePage) {
+        this.pageIndicatorIndex.setValue(pageIndicatorIndex);
+        if (changePage) performPageChange();
     }
 
     // <-------------Just getters, setters and helper methods below here---------------->
From 9f3d0be3c91842c2d11f4a04f6b24a501bec60b8 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Tue, 7 Aug 2018 22:38:44 +0300
Subject: [PATCH 06/10] fix issues with topic, cleanup
---
 .../activities/topic/TopicActivity.java       | 118 ++++++++--------
 .../mthmmy/activities/topic/TopicAdapter.java |  11 +-
 .../activities/topic/tasks/TopicTask.java     |  53 +++----
 .../topic/tasks/TopicTaskResult.java          |  31 +----
 .../mthmmy/utils/parsing/ParseHelpers.java    |  20 +++
 .../mthmmy/viewmodel/TopicViewModel.java      | 131 ++++++++++--------
 6 files changed, 179 insertions(+), 185 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index 2ed8e25b..ddf5f0d7 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -45,6 +45,7 @@ import gr.thmmy.mthmmy.model.Post;
 import gr.thmmy.mthmmy.model.ThmmyPage;
 import gr.thmmy.mthmmy.utils.CustomLinearLayoutManager;
 import gr.thmmy.mthmmy.utils.HTMLUtils;
+import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
 import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
 import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
 import timber.log.Timber;
@@ -206,53 +207,56 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
             pageIndicator.setText(String.valueOf(pageIndicatorIndex) + "/" +
                     String.valueOf(viewModel.getPageCount()));
         });
-        viewModel.getTopicTaskResult().observe(this, topicTaskResult -> {
-            if (topicTaskResult == null) {
-                progressBar.setVisibility(ProgressBar.VISIBLE);
-            } else {
-                switch (topicTaskResult.getResultCode()) {
-                    case SUCCESS:
-                        if (topicTitle == null || Objects.equals(topicTitle, "")
-                                || !Objects.equals(topicTitle, topicTaskResult.getTopicTitle())) {
-                            toolbarTitle.setText(topicTaskResult.getTopicTitle());
-                        }
-
-                        recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug
-                        postsList.clear();
-                        postsList.addAll(topicTaskResult.getNewPostsList());
-                        topicAdapter.notifyDataSetChanged();
-
-                        paginationEnabled(true);
-
-                        if (topicTaskResult.getCurrentPageIndex() == topicTaskResult.getPageCount()) {
-                            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-                            if (notificationManager != null)
-                                notificationManager.cancel(NEW_POST_TAG, topicTaskResult.getLoadedPageTopicId());
-                        }
-
-                        progressBar.setVisibility(ProgressBar.GONE);
-                        if (topicTaskResult.getReplyPageUrl() == null)
-                            replyFAB.hide();
-                        else
-                            replyFAB.show();
-                        recyclerView.scrollToPosition(topicTaskResult.getFocusedPostIndex());
-                        break;
-                    case NETWORK_ERROR:
-                        Toast.makeText(getBaseContext(), "Network Error", Toast.LENGTH_SHORT).show();
-                        break;
-                    case UNAUTHORIZED:
-                        progressBar.setVisibility(ProgressBar.GONE);
-                        Toast.makeText(getBaseContext(), "This topic is either missing or off limits to you", Toast.LENGTH_SHORT).show();
-                        break;
-                    default:
-                        //Parse failed - should never happen
-                        Timber.d("Parse failed!");  //TODO report ParseException!!!
-                        Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show();
-                        finish();
-                        break;
-                }
+        viewModel.getTopicTitle().observe(this, newTopicTitle -> {
+            if (newTopicTitle == null) return;
+            toolbarTitle.setText(newTopicTitle);
+        });
+        viewModel.getPageTopicId().observe(this, pageTopicId -> {
+            if (pageTopicId == null) return;
+            if (viewModel.getCurrentPageIndex() == viewModel.getPageCount()) {
+                NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+                if (notificationManager != null)
+                    notificationManager.cancel(NEW_POST_TAG, pageTopicId);
+            }
+        });
+        viewModel.getReplyPageUrl().observe(this, replyPageUrl -> {
+            if (replyPageUrl == null)
+                replyFAB.hide();
+            else
+                replyFAB.show();
+        });
+        viewModel.getPostsList().observe(this, postList -> {
+            if (postList == null) onTopicTaskStarted();
+            recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug
+            postsList.clear();
+            postsList.addAll(postList);
+            topicAdapter.notifyDataSetChanged();
+        });
+        viewModel.getFocusedPostIndex().observe(this, focusedPostIndex -> {
+            if (focusedPostIndex == null) return;
+            recyclerView.scrollToPosition(focusedPostIndex);
+        });
+        viewModel.getTopicTaskResultCode().observe(this, resultCode -> {
+            if (resultCode == null) return;
+            switch (resultCode) {
+                case SUCCESS:
+                    paginationEnabled(true);
+                    progressBar.setVisibility(ProgressBar.GONE);
+                    break;
+                case NETWORK_ERROR:
+                    Toast.makeText(getBaseContext(), "Network Error", Toast.LENGTH_SHORT).show();
+                    break;
+                case UNAUTHORIZED:
+                    progressBar.setVisibility(ProgressBar.GONE);
+                    Toast.makeText(getBaseContext(), "This topic is either missing or off limits to you", Toast.LENGTH_SHORT).show();
+                    break;
+                default:
+                    //Parse failed - should never happen
+                    Timber.d("Parse failed!");  //TODO report ParseException!!!
+                    Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show();
+                    finish();
+                    break;
             }
-
         });
         viewModel.getPrepareForReplyResult().observe(this, prepareForReplyResult -> {
             if (prepareForReplyResult != null) {
@@ -277,7 +281,7 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 bottomNavBar.setVisibility(View.GONE);
             }
         });
-        viewModel.initialLoad(topicPageUrl);
+        viewModel.loadUrl(topicPageUrl);
     }
 
     @Override
@@ -307,18 +311,14 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
                 TextView usersViewing = infoDialog.findViewById(R.id.users_viewing);
                 usersViewing.setText(new SpannableStringBuilder("Loading..."));
                 usersViewing.setMovementMethod(LinkMovementMethod.getInstance());
-                viewModel.getTopicTaskResult().observe(this, topicTaskResult -> {
-                    if (topicTaskResult == null) {
-                        usersViewing.setText(new SpannableStringBuilder("Loading..."));
-                        treeAndMods.setText(new SpannableStringBuilder("Loading..."));
-                    } else {
-                        String treeAndModsString = topicTaskResult.getTopicTreeAndMods();
-                        treeAndMods.setText(HTMLUtils.getSpannableFromHtml(this, treeAndModsString));
-                        String topicViewersString = topicTaskResult.getTopicViewers();
-                        usersViewing.setText(HTMLUtils.getSpannableFromHtml(this, topicViewersString));
-                    }
+                viewModel.getTopicTreeAndMods().observe(this, topicTreeAndMods -> {
+                    if (topicTreeAndMods == null) return;
+                    treeAndMods.setText(HTMLUtils.getSpannableFromHtml(this, topicTreeAndMods));
+                });
+                viewModel.getTopicViewers().observe(this, topicViewers -> {
+                    if (topicViewers == null) return;
+                    usersViewing.setText(HTMLUtils.getSpannableFromHtml(this, topicViewers));
                 });
-
                 builder.setView(infoDialog);
                 AlertDialog dialog = builder.create();
                 dialog.show();
@@ -559,7 +559,7 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
 
         if (success) {
             if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) {
-                viewModel.loadUrl(viewModel.getBaseUrl() + "." + 2147483647);
+                viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
             } else {
                 viewModel.reloadPage();
             }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
index 1bc85acc..783c741f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
@@ -46,6 +46,7 @@ import gr.thmmy.mthmmy.model.Post;
 import gr.thmmy.mthmmy.model.ThmmyFile;
 import gr.thmmy.mthmmy.model.ThmmyPage;
 import gr.thmmy.mthmmy.utils.CircleTransform;
+import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
 import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
 import timber.log.Timber;
 
@@ -628,8 +629,7 @@ class TopicAdapter extends RecyclerView.Adapter {
             if (target.is(ThmmyPage.PageCategory.TOPIC)) {
                 //This url points to a topic
                 //Checks if the page to be loaded is the one already shown
-                if (uriString.contains(viewModel.getBaseUrl())) {
-                    Timber.e("reached here!");
+                if (uriString.contains(ParseHelpers.getBaseURL(viewModel.getTopicUrl()))) {
                     if (uriString.contains("topicseen#new") || uriString.contains("#new")) {
                         if (viewModel.getCurrentPageIndex() == viewModel.getPageCount()) {
                             //same page
@@ -643,7 +643,6 @@ class TopicAdapter extends RecyclerView.Adapter {
                         if (tmpUrlSbstr.contains("msg"))
                             tmpUrlSbstr = tmpUrlSbstr.substring(0, tmpUrlSbstr.indexOf("msg") - 1);
                         int testAgainst = Integer.parseInt(tmpUrlSbstr);
-                        Timber.e("reached tthere! %s", testAgainst);
                         for (int i = 0; i < postsList.size(); i++) {
                             if (postsList.get(i).getPostIndex() == testAgainst) {
                                 //same page
@@ -652,11 +651,11 @@ class TopicAdapter extends RecyclerView.Adapter {
                                 return true;
                             }
                         }
-                    } else if ((Objects.equals(uriString, viewModel.getBaseUrl()) && viewModel.getCurrentPageIndex() == 1) ||
-                            Integer.parseInt(uriString.substring(viewModel.getBaseUrl().length() + 1)) / 15 + 1 ==
+                    } else if ((Objects.equals(uriString, ParseHelpers.getBaseURL(viewModel.getTopicUrl())) &&
+                            viewModel.getCurrentPageIndex() == 1) ||
+                            Integer.parseInt(uriString.substring(ParseHelpers.getBaseURL(viewModel.getTopicUrl()).length() + 1)) / 15 + 1 ==
                                     viewModel.getCurrentPageIndex()) {
                         //same page
-                        Timber.e("ha");
                         return true;
                     }
                 }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
index e233ae1c..28446874 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
@@ -43,18 +43,6 @@ public class TopicTask extends AsyncTask {
 
     @Override
     protected TopicTaskResult doInBackground(String... strings) {
-        String topicTitle = null;
-        String topicTreeAndMods = "";
-        String topicViewers = "";
-        ArrayList newPostsList = null;
-        int loadedPageTopicId = -1;
-        int focusedPostIndex = 0;
-        SparseArray pagesUrls = new SparseArray<>();
-        int currentPageIndex = 1;
-        int pageCount = 1;
-        String baseUrl = "";
-        String lastPageLoadAttemptedUrl = "";
-
         Document topic = null;
         String newPageUrl = strings[0];
 
@@ -70,14 +58,9 @@ public class TopicTask extends AsyncTask {
             }
         }
 
-        lastPageLoadAttemptedUrl = newPageUrl;
-        if (strings[0].substring(0, strings[0].lastIndexOf(".")).contains("topic="))
-            baseUrl = strings[0].substring(0, strings[0].lastIndexOf(".")); //New topic's base url
-        String replyPageUrl = null;
         Request request = new Request.Builder()
                 .url(newPageUrl)
                 .build();
-        ResultCode resultCode;
         try {
             Response response = BaseApplication.getInstance().getClient().newCall(request).execute();
             topic = Jsoup.parse(response.body().string());
@@ -85,17 +68,18 @@ public class TopicTask extends AsyncTask {
             ParseHelpers.Language language = ParseHelpers.Language.getLanguage(topic);
 
             //Finds topic's tree, mods and users viewing
-            topicTreeAndMods = topic.select("div.nav").first().html();
-            topicViewers = TopicParser.parseUsersViewingThisTopic(topic, language);
+            String topicTreeAndMods = topic.select("div.nav").first().html();
+            String topicViewers = TopicParser.parseUsersViewingThisTopic(topic, language);
 
             //Finds reply page url
+            String replyPageUrl = null;
             Element replyButton = topic.select("a:has(img[alt=Reply])").first();
             if (replyButton == null)
                 replyButton = topic.select("a:has(img[alt=Απάντηση])").first();
             if (replyButton != null) replyPageUrl = replyButton.attr("href");
 
             //Finds topic title if missing
-            topicTitle = topic.select("td[id=top_subject]").first().text();
+            String topicTitle = topic.select("td[id=top_subject]").first().text();
             if (topicTitle.contains("Topic:")) {
                 topicTitle = topicTitle.substring(topicTitle.indexOf("Topic:") + 7
                         , topicTitle.indexOf("(Read") - 2);
@@ -106,42 +90,39 @@ public class TopicTask extends AsyncTask {
             }
 
             //Finds current page's index
-            currentPageIndex = TopicParser.parseCurrentPageIndex(topic, language);
+            int currentPageIndex = TopicParser.parseCurrentPageIndex(topic, language);
 
             //Finds number of pages
-            pageCount = TopicParser.parseTopicNumberOfPages(topic, currentPageIndex, language);
-
-            for (int i = 0; i < pageCount; i++) {
-                //Generate each page's url from topic's base url +".15*numberOfPage"
-                pagesUrls.put(i, baseUrl + "." + String.valueOf(i * 15));
-            }
+            int pageCount = TopicParser.parseTopicNumberOfPages(topic, currentPageIndex, language);
 
-            newPostsList = TopicParser.parseTopic(topic, language);
+            ArrayList newPostsList = TopicParser.parseTopic(topic, language);
 
-            loadedPageTopicId = Integer.parseInt(ThmmyPage.getTopicId(lastPageLoadAttemptedUrl));
+            int loadedPageTopicId = Integer.parseInt(ThmmyPage.getTopicId(newPageUrl));
 
             //Finds the position of the focused message if present
+            int focusedPostIndex = 0;
             for (int i = 0; i < newPostsList.size(); ++i) {
                 if (newPostsList.get(i).getPostIndex() == postFocus) {
                     focusedPostIndex = i;
                     break;
                 }
             }
-            resultCode = ResultCode.SUCCESS;
+            return new TopicTaskResult(ResultCode.SUCCESS, topicTitle, replyPageUrl, newPostsList, loadedPageTopicId,
+                    currentPageIndex, pageCount, focusedPostIndex, topicTreeAndMods, topicViewers);
         } catch (IOException e) {
             Timber.i(e, "IO Exception");
-            resultCode = ResultCode.NETWORK_ERROR;
+            return new TopicTaskResult(ResultCode.NETWORK_ERROR, null, null, null,
+                    0, 0, 0, 0, null, null);
         } catch (Exception e) {
             if (isUnauthorized(topic)) {
-                resultCode = ResultCode.UNAUTHORIZED;
+                return new TopicTaskResult(ResultCode.UNAUTHORIZED, null, null, null,
+                        0, 0, 0, 0, null, null);
             } else {
                 Timber.e(e, "Parsing Error");
-                resultCode = ResultCode.PARSING_ERROR;
+                return new TopicTaskResult(ResultCode.PARSING_ERROR, null, null, null,
+                        0, 0, 0, 0, null, null);
             }
         }
-        return new TopicTaskResult(resultCode, baseUrl, topicTitle, replyPageUrl, newPostsList,
-                loadedPageTopicId, currentPageIndex, pageCount, focusedPostIndex, topicTreeAndMods,
-                topicViewers, lastPageLoadAttemptedUrl, pagesUrls);
     }
 
     private boolean isUnauthorized(Document document) {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java
index f9b76736..570160d3 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java
@@ -9,13 +9,6 @@ import gr.thmmy.mthmmy.model.Post;
 
 public class TopicTaskResult {
     private final TopicTask.ResultCode resultCode;
-    /**
-     * Holds this topic's base url. For example a topic with url similar to
-     * "https://www.thmmy.gr/smf/index.php?topic=1.15;topicseen" or
-     * "https://www.thmmy.gr/smf/index.php?topic=1.msg1#msg1"
-     * has the base url "https://www.thmmy.gr/smf/index.php?topic=1"
-     */
-    private final String baseUrl;
     /**
      * Holds this topic's title. At first this gets the value of the topic title that came with
      * bundle and is rendered in the toolbar while parsing this topic. Later, if a different topic
@@ -46,18 +39,12 @@ public class TopicTaskResult {
     //Topic's info related
     private final String topicTreeAndMods;
     private final String topicViewers;
-    /**
-     * The url of the last page that was attempted to be loaded
-     */
-    private final String lastPageLoadAttemptedUrl;
-    private final SparseArray pagesUrls;
 
-    public TopicTaskResult(TopicTask.ResultCode resultCode, String baseUrl, String topicTitle,
+    public TopicTaskResult(TopicTask.ResultCode resultCode, String topicTitle,
                            String replyPageUrl, ArrayList newPostsList, int loadedPageTopicId,
                            int currentPageIndex, int pageCount, int focusedPostIndex, String topicTreeAndMods,
-                           String topicViewers, String lastPageLoadAttemptedUrl, SparseArray pagesUrls) {
+                           String topicViewers) {
         this.resultCode = resultCode;
-        this.baseUrl = baseUrl;
         this.topicTitle = topicTitle;
         this.replyPageUrl = replyPageUrl;
         this.newPostsList = newPostsList;
@@ -67,18 +54,12 @@ public class TopicTaskResult {
         this.focusedPostIndex = focusedPostIndex;
         this.topicTreeAndMods = topicTreeAndMods;
         this.topicViewers = topicViewers;
-        this.lastPageLoadAttemptedUrl = lastPageLoadAttemptedUrl;
-        this.pagesUrls = pagesUrls;
     }
 
     public TopicTask.ResultCode getResultCode() {
         return resultCode;
     }
 
-    public String getBaseUrl() {
-        return baseUrl;
-    }
-
     public String getTopicTitle() {
         return topicTitle;
     }
@@ -114,12 +95,4 @@ public class TopicTaskResult {
     public String getTopicViewers() {
         return topicViewers;
     }
-
-    public String getLastPageLoadAttemptedUrl() {
-        return lastPageLoadAttemptedUrl;
-    }
-
-    public SparseArray getPagesUrls() {
-        return pagesUrls;
-    }
 }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
index 307efab0..0034ffc4 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
@@ -6,6 +6,8 @@ import org.jsoup.select.Elements;
 
 import java.util.ArrayList;
 
+import timber.log.Timber;
+
 /**
  * This class consists exclusively of static classes (enums) and methods (excluding methods of inner
  * classes). It can be used to resolve a page's language and state or fix embedded videos html code.
@@ -166,4 +168,22 @@ public class ParseHelpers {
         }
         return fixed;
     }
+
+    /**
+     * Method that extracts the base URL from a topic's page URL. For example a topic with url similar to
+     * "https://www.thmmy.gr/smf/index.php?topic=1.15;topicseen" or
+     * "https://www.thmmy.gr/smf/index.php?topic=1.msg1#msg1"
+     * has the base url "https://www.thmmy.gr/smf/index.php?topic=1"
+     *
+     * @param topicURL a topic's page URL
+     * @return the base URL of the given topic
+     */
+    public static String getBaseURL(String topicURL) {
+        if (topicURL.substring(0, topicURL.lastIndexOf(".")).contains("topic="))
+            return topicURL.substring(0, topicURL.lastIndexOf("."));
+        else {
+            Timber.wtf(new ParseException("Could not parse base URL of topic"));
+            return "";
+        }
+    }
 }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 6416a85d..b74a63a2 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -21,6 +21,7 @@ import gr.thmmy.mthmmy.activities.topic.tasks.TopicTaskResult;
 import gr.thmmy.mthmmy.base.BaseActivity;
 import gr.thmmy.mthmmy.model.Post;
 import gr.thmmy.mthmmy.session.SessionManager;
+import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
 
 public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTaskCompleted,
         PrepareForReply.OnPrepareForReplyFinished, PrepareForEditTask.OnPrepareEditFinished {
@@ -59,47 +60,53 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
      * navigation bar occurs, aka the value that the page indicator shows
      */
     private MutableLiveData pageIndicatorIndex = new MutableLiveData<>();
-    private MutableLiveData topicTaskResult = new MutableLiveData<>();
-    private MutableLiveData prepareForReplyResult = new MutableLiveData<>();
-    private MutableLiveData prepareForEditResult = new MutableLiveData<>();
 
-    private String firstTopicUrl;
+    private MutableLiveData replyPageUrl = new MutableLiveData<>();
+    private MutableLiveData pageTopicId = new MutableLiveData<>();
+    private MutableLiveData topicTitle = new MutableLiveData<>();
+    private MutableLiveData> postsList = new MutableLiveData<>();
+    private MutableLiveData focusedPostIndex = new MutableLiveData<>();
+    private MutableLiveData topicTaskResultCode = new MutableLiveData<>();
+    private MutableLiveData topicTreeAndMods = new MutableLiveData<>();
+    private MutableLiveData topicViewers = new MutableLiveData<>();
+    private String topicUrl;
+    private int currentPageIndex;
+    private int pageCount;
 
-    public void initialLoad(String pageUrl) {
-        firstTopicUrl = pageUrl;
-        currentTopicTask = new TopicTask(topicTaskObserver, this);
-        currentTopicTask.execute(pageUrl);
-    }
+    private MutableLiveData prepareForReplyResult = new MutableLiveData<>();
+    private MutableLiveData prepareForEditResult = new MutableLiveData<>();
 
     public void loadUrl(String pageUrl) {
         stopLoading();
+        topicUrl = pageUrl;
         currentTopicTask = new TopicTask(topicTaskObserver, this);
         currentTopicTask.execute(pageUrl);
     }
 
     public void reloadPage() {
-        if (topicTaskResult.getValue() == null)
-            throw new NullPointerException("No topic task has finished yet!");
-        loadUrl(topicTaskResult.getValue().getLastPageLoadAttemptedUrl());
+        if (topicUrl == null) throw new NullPointerException("No topic task has finished yet!");
+        loadUrl(topicUrl);
     }
 
     public void performPageChange() {
-        if (topicTaskResult.getValue() == null || pageIndicatorIndex.getValue() == null)
+        if (pageIndicatorIndex.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
         int pageRequested = pageIndicatorIndex.getValue() - 1;
-        if (pageRequested != topicTaskResult.getValue().getCurrentPageIndex() - 1) {
-            loadUrl(topicTaskResult.getValue().getPagesUrls().get(pageRequested));
+        if (pageRequested != currentPageIndex - 1) {
+            loadUrl(ParseHelpers.getBaseURL(topicUrl) + "." + String.valueOf(pageRequested * 15));
             pageIndicatorIndex.setValue(pageRequested + 1);
+        } else {
+            stopLoading();
         }
     }
 
     public void prepareForReply() {
-        if (topicTaskResult.getValue() == null)
+        if (replyPageUrl.getValue() == null)
             throw new NullPointerException("Topic task has not finished yet!");
         stopLoading();
         setPageIndicatorIndex(getPageCount(), true);
         currentPrepareForReplyTask = new PrepareForReply(prepareForReplyCallbacks, this,
-                topicTaskResult.getValue().getReplyPageUrl());
+                replyPageUrl.getValue());
         currentPrepareForReplyTask.execute(toQuoteList.toArray(new Integer[0]));
     }
 
@@ -124,11 +131,11 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     }
 
     public void prepareForEdit(int position, String postEditURL) {
-        if (topicTaskResult.getValue() == null)
+        if (replyPageUrl.getValue() == null)
             throw new NullPointerException("Topic task has not finished yet!");
         stopLoading();
         currentPrepareForEditTask = new PrepareForEditTask(prepareForEditCallbacks, this, position,
-                topicTaskResult.getValue().getReplyPageUrl());
+                replyPageUrl.getValue());
         currentPrepareForEditTask.execute(postEditURL);
     }
 
@@ -166,14 +173,23 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     // callbacks for viewmodel
     @Override
     public void onTopicTaskCompleted(TopicTaskResult result) {
-        topicTaskResult.setValue(result);
         if (result.getResultCode() == TopicTask.ResultCode.SUCCESS) {
+            currentPageIndex = result.getCurrentPageIndex();
+            pageCount = result.getPageCount();
+            topicTreeAndMods.setValue(result.getTopicTreeAndMods());
+            topicViewers.setValue(result.getTopicViewers());
+            pageTopicId.setValue(result.getLoadedPageTopicId());
+            replyPageUrl.setValue(result.getReplyPageUrl());
+            topicTitle.setValue(result.getTopicTitle());
             pageIndicatorIndex.setValue(result.getCurrentPageIndex());
+            postsList.setValue(result.getNewPostsList());
+            focusedPostIndex.setValue(result.getFocusedPostIndex());
             isUserExtraInfoVisibile.clear();
             for (int i = 0; i < result.getNewPostsList().size(); i++) {
                 isUserExtraInfoVisibile.add(false);
             }
         }
+        topicTaskResultCode.setValue(result.getResultCode());
     }
 
     @Override
@@ -216,6 +232,41 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
 
     // <-------------Just getters, setters and helper methods below here---------------->
 
+    public MutableLiveData getTopicViewers() {
+        return topicViewers;
+    }
+
+    public MutableLiveData getTopicTreeAndMods() {
+        return topicTreeAndMods;
+    }
+
+    public MutableLiveData getTopicTaskResultCode() {
+        return topicTaskResultCode;
+    }
+
+    public MutableLiveData getFocusedPostIndex() {
+        return focusedPostIndex;
+    }
+
+    public MutableLiveData> getPostsList() {
+        return postsList;
+    }
+
+    public MutableLiveData getReplyPageUrl() {
+        return replyPageUrl;
+    }
+
+    public MutableLiveData getPageTopicId() {
+        return pageTopicId;
+    }
+
+    public MutableLiveData getTopicTitle() {
+        return topicTitle;
+    }
+
+    public String getTopicUrl() {
+        return topicUrl;
+    }
 
     public MutableLiveData getPageIndicatorIndex() {
         return pageIndicatorIndex;
@@ -268,10 +319,6 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         this.prepareForReplyCallbacks = prepareForReplyCallbacks;
     }
 
-    public MutableLiveData getTopicTaskResult() {
-        return topicTaskResult;
-    }
-
     public MutableLiveData getPrepareForReplyResult() {
         return prepareForReplyResult;
     }
@@ -293,7 +340,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     }
 
     public boolean canReply() {
-        return topicTaskResult.getValue() != null && topicTaskResult.getValue().getReplyPageUrl() != null;
+        return replyPageUrl.getValue() != null;
     }
 
     public boolean isWritingReply() {
@@ -304,40 +351,14 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         this.writingReply = writingReply;
     }
 
-    public String getBaseUrl() {
-        if (topicTaskResult.getValue() != null) {
-            return topicTaskResult.getValue().getBaseUrl();
-        } else {
-            return "";
-        }
-    }
-
-    public String getTopicUrl() {
-        if (topicTaskResult.getValue() != null) {
-            return topicTaskResult.getValue().getLastPageLoadAttemptedUrl();
-        } else {
-            // topic task has not finished yet (log? disable menu button until load is finished?)
-            return firstTopicUrl;
-        }
-    }
-
-    public String getTopicTitle() {
-        if (topicTaskResult.getValue() == null)
-            throw new NullPointerException("Topic task has not finished yet!");
-        return topicTaskResult.getValue().getTopicTitle();
-    }
-
     public int getCurrentPageIndex() {
-        if (topicTaskResult.getValue() == null)
-            throw new NullPointerException("No page has been loaded yet!");
-        return topicTaskResult.getValue().getCurrentPageIndex();
+        if (currentPageIndex == 0) throw  new NullPointerException("No page has been loaded yet!");
+        return currentPageIndex;
     }
 
     public int getPageCount() {
-        if (topicTaskResult.getValue() == null)
-            throw new NullPointerException("No page has been loaded yet!");
-
-        return topicTaskResult.getValue().getPageCount();
+        if (pageCount == 0) throw  new NullPointerException("No page has been loaded yet!");
+        return pageCount;
     }
 
     public String getPostBeingEditedText() {
From 299f0b5afc414c86ed66c9dc5f7d5f002f75b8d0 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Wed, 8 Aug 2018 13:16:52 +0300
Subject: [PATCH 07/10] reply subject fix, cleanup
---
 .../activities/topic/TopicActivity.java       | 365 +++++++++---------
 .../mthmmy/activities/topic/TopicAdapter.java |   4 +-
 2 files changed, 188 insertions(+), 181 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index ddf5f0d7..234edef0 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -59,9 +59,7 @@ import static gr.thmmy.mthmmy.services.NotificationService.NEW_POST_TAG;
  * key {@link #BUNDLE_TOPIC_TITLE} for faster title rendering.
  */
 @SuppressWarnings("unchecked")
-public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskObserver,
-        DeleteTask.DeleteTaskCallbacks, ReplyTask.ReplyTaskCallbacks, PrepareForEditTask.PrepareForEditCallbacks,
-        EditTask.EditTaskCallbacks, PrepareForReply.PrepareForReplyCallbacks, TopicAdapter.OnPostFocusChangeListener {
+public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFocusChangeListener {
     //Activity's variables
     /**
      * The key to use when putting topic's url String to {@link TopicActivity}'s Bundle.
@@ -125,14 +123,9 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_topic);
-
+        // get TopicViewModel instance
         viewModel = ViewModelProviders.of(this).get(TopicViewModel.class);
-        viewModel.setTopicTaskObserver(this);
-        viewModel.setDeleteTaskCallbacks(this);
-        viewModel.setReplyFinishListener(this);
-        viewModel.setPrepareForEditCallbacks(this);
-        viewModel.setEditTaskCallbacks(this);
-        viewModel.setPrepareForReplyCallbacks(this);
+        subscribeUI();
 
         Bundle extras = getIntent().getExtras();
         String topicTitle = extras.getString(BUNDLE_TOPIC_TITLE);
@@ -202,85 +195,6 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
 
         paginationEnabled(false);
 
-        viewModel.getPageIndicatorIndex().observe(this, pageIndicatorIndex -> {
-            if (pageIndicatorIndex == null) return;
-            pageIndicator.setText(String.valueOf(pageIndicatorIndex) + "/" +
-                    String.valueOf(viewModel.getPageCount()));
-        });
-        viewModel.getTopicTitle().observe(this, newTopicTitle -> {
-            if (newTopicTitle == null) return;
-            toolbarTitle.setText(newTopicTitle);
-        });
-        viewModel.getPageTopicId().observe(this, pageTopicId -> {
-            if (pageTopicId == null) return;
-            if (viewModel.getCurrentPageIndex() == viewModel.getPageCount()) {
-                NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-                if (notificationManager != null)
-                    notificationManager.cancel(NEW_POST_TAG, pageTopicId);
-            }
-        });
-        viewModel.getReplyPageUrl().observe(this, replyPageUrl -> {
-            if (replyPageUrl == null)
-                replyFAB.hide();
-            else
-                replyFAB.show();
-        });
-        viewModel.getPostsList().observe(this, postList -> {
-            if (postList == null) onTopicTaskStarted();
-            recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug
-            postsList.clear();
-            postsList.addAll(postList);
-            topicAdapter.notifyDataSetChanged();
-        });
-        viewModel.getFocusedPostIndex().observe(this, focusedPostIndex -> {
-            if (focusedPostIndex == null) return;
-            recyclerView.scrollToPosition(focusedPostIndex);
-        });
-        viewModel.getTopicTaskResultCode().observe(this, resultCode -> {
-            if (resultCode == null) return;
-            switch (resultCode) {
-                case SUCCESS:
-                    paginationEnabled(true);
-                    progressBar.setVisibility(ProgressBar.GONE);
-                    break;
-                case NETWORK_ERROR:
-                    Toast.makeText(getBaseContext(), "Network Error", Toast.LENGTH_SHORT).show();
-                    break;
-                case UNAUTHORIZED:
-                    progressBar.setVisibility(ProgressBar.GONE);
-                    Toast.makeText(getBaseContext(), "This topic is either missing or off limits to you", Toast.LENGTH_SHORT).show();
-                    break;
-                default:
-                    //Parse failed - should never happen
-                    Timber.d("Parse failed!");  //TODO report ParseException!!!
-                    Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show();
-                    finish();
-                    break;
-            }
-        });
-        viewModel.getPrepareForReplyResult().observe(this, prepareForReplyResult -> {
-            if (prepareForReplyResult != null) {
-                //prepare for a reply
-                postsList.add(Post.newQuickReply());
-                topicAdapter.notifyItemInserted(postsList.size());
-                recyclerView.scrollToPosition(postsList.size() - 1);
-                progressBar.setVisibility(ProgressBar.GONE);
-                replyFAB.hide();
-                bottomNavBar.setVisibility(View.GONE);
-            }
-
-        });
-        viewModel.getPrepareForEditResult().observe(this, result -> {
-            if (result != null && result.isSuccessful()) {
-                viewModel.setEditingPost(true);
-                postsList.get(result.getPosition()).setPostType(Post.TYPE_EDIT);
-                topicAdapter.notifyItemChanged(result.getPosition());
-                recyclerView.scrollToPosition(result.getPosition());
-                progressBar.setVisibility(ProgressBar.GONE);
-                replyFAB.hide();
-                bottomNavBar.setVisibility(View.GONE);
-            }
-        });
         viewModel.loadUrl(topicPageUrl);
     }
 
@@ -526,108 +440,201 @@ public class TopicActivity extends BaseActivity implements TopicTask.TopicTaskOb
 
     //------------------------------------BOTTOM NAV BAR METHODS END------------------------------------
 
-    @Override
-    public void onTopicTaskStarted() {
-        progressBar.setVisibility(ProgressBar.VISIBLE);
-    }
-
-    @Override
-    public void onTopicTaskCancelled() {
-        progressBar.setVisibility(ProgressBar.GONE);
-    }
-
-    @Override
-    public void onReplyTaskStarted() {
-        progressBar.setVisibility(ProgressBar.VISIBLE);
-    }
-
-    @Override
-    public void onReplyTaskFinished(boolean success) {
-        View view = getCurrentFocus();
-        if (view != null) {
-            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
-        }
-
-        postsList.remove(postsList.size() - 1);
-        topicAdapter.notifyItemRemoved(postsList.size());
-
-        progressBar.setVisibility(ProgressBar.GONE);
-        replyFAB.show();
-        bottomNavBar.setVisibility(View.VISIBLE);
-        viewModel.setWritingReply(false);
+    /**
+     * Binds the UI to its data
+     */
+    private void subscribeUI() {
+        // Implement async task callbacks
+        viewModel.setTopicTaskObserver(new TopicTask.TopicTaskObserver() {
+            @Override
+            public void onTopicTaskStarted() {
+                progressBar.setVisibility(ProgressBar.VISIBLE);
+            }
 
-        if (success) {
-            if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) {
-                viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
-            } else {
-                viewModel.reloadPage();
+            @Override
+            public void onTopicTaskCancelled() {
+                progressBar.setVisibility(ProgressBar.GONE);
+            }
+        });
+        viewModel.setDeleteTaskCallbacks(new DeleteTask.DeleteTaskCallbacks() {
+            @Override
+            public void onDeleteTaskStarted() {
+                progressBar.setVisibility(ProgressBar.VISIBLE);
             }
-        } else {
-            Toast.makeText(TopicActivity.this, "Post failed!", Toast.LENGTH_SHORT).show();
-        }
-    }
 
-    @Override
-    public void onPrepareForReplyStarted() {
-        progressBar.setVisibility(ProgressBar.VISIBLE);
-    }
+            @Override
+            public void onDeleteTaskFinished(boolean result) {
+                progressBar.setVisibility(ProgressBar.GONE);
 
-    @Override
-    public void onPrepareForReplyCancelled() {
-        progressBar.setVisibility(ProgressBar.GONE);
-    }
+                if (result)
+                    viewModel.reloadPage();
+                else
+                    Toast.makeText(TopicActivity.this, "Post deleted!", Toast.LENGTH_SHORT).show();
+            }
+        });
+        viewModel.setReplyFinishListener(new ReplyTask.ReplyTaskCallbacks() {
+            @Override
+            public void onReplyTaskStarted() {
+                progressBar.setVisibility(ProgressBar.VISIBLE);
+            }
 
-    @Override
-    public void onDeleteTaskStarted() {
-        progressBar.setVisibility(ProgressBar.VISIBLE);
-    }
+            @Override
+            public void onReplyTaskFinished(boolean success) {
+                View view = getCurrentFocus();
+                if (view != null) {
+                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+                }
 
-    @Override
-    public void onDeleteTaskFinished(boolean result) {
-        progressBar.setVisibility(ProgressBar.GONE);
+                postsList.remove(postsList.size() - 1);
+                topicAdapter.notifyItemRemoved(postsList.size());
 
-        if (result) {
-            viewModel.reloadPage();
-        } else {
-            Toast.makeText(TopicActivity.this, "Post deleted!", Toast.LENGTH_SHORT).show();
-        }
-    }
+                progressBar.setVisibility(ProgressBar.GONE);
+                replyFAB.show();
+                bottomNavBar.setVisibility(View.VISIBLE);
+                viewModel.setWritingReply(false);
+
+                if (success) {
+                    if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) {
+                        viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
+                    } else {
+                        viewModel.reloadPage();
+                    }
+                } else {
+                    Toast.makeText(TopicActivity.this, "Post failed!", Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+        viewModel.setPrepareForEditCallbacks(new PrepareForEditTask.PrepareForEditCallbacks() {
+            @Override
+            public void onPrepareEditStarted() {
+                progressBar.setVisibility(ProgressBar.VISIBLE);
+            }
 
-    @Override
-    public void onPrepareEditStarted() {
-        progressBar.setVisibility(ProgressBar.VISIBLE);
-    }
+            @Override
+            public void onPrepareEditCancelled() {
+                progressBar.setVisibility(ProgressBar.GONE);
+            }
+        });
+        viewModel.setEditTaskCallbacks(new EditTask.EditTaskCallbacks() {
+            @Override
+            public void onEditTaskStarted() {
+                progressBar.setVisibility(ProgressBar.VISIBLE);
+            }
 
-    @Override
-    public void onPrepareEditCancelled() {
-        progressBar.setVisibility(ProgressBar.GONE);
-    }
+            @Override
+            public void onEditTaskFinished(boolean result, int position) {
+                View view = getCurrentFocus();
+                if (view != null) {
+                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+                }
 
-    @Override
-    public void onEditTaskStarted() {
-        progressBar.setVisibility(ProgressBar.VISIBLE);
-    }
+                postsList.get(position).setPostType(Post.TYPE_POST);
+                topicAdapter.notifyItemChanged(position);
+                viewModel.setEditingPost(false);
+                progressBar.setVisibility(ProgressBar.GONE);
+                replyFAB.show();
+                bottomNavBar.setVisibility(View.VISIBLE);
 
-    @Override
-    public void onEditTaskFinished(boolean result, int position) {
-        View view = getCurrentFocus();
-        if (view != null) {
-            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
-        }
+                if (result) {
+                    viewModel.reloadPage();
+                } else {
+                    Toast.makeText(TopicActivity.this, "Edit failed!", Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+        viewModel.setPrepareForReplyCallbacks(new PrepareForReply.PrepareForReplyCallbacks() {
+            @Override
+            public void onPrepareForReplyStarted() {
+                progressBar.setVisibility(ProgressBar.VISIBLE);
+            }
 
-        postsList.get(position).setPostType(Post.TYPE_POST);
-        topicAdapter.notifyItemChanged(position);
-        viewModel.setEditingPost(false);
-        progressBar.setVisibility(ProgressBar.GONE);
-        replyFAB.show();
-        bottomNavBar.setVisibility(View.VISIBLE);
+            @Override
+            public void onPrepareForReplyCancelled() {
+                progressBar.setVisibility(ProgressBar.GONE);
+            }
+        });
+        // observe the chages in data
+        viewModel.getPageIndicatorIndex().observe(this, pageIndicatorIndex -> {
+            if (pageIndicatorIndex == null) return;
+            pageIndicator.setText(String.valueOf(pageIndicatorIndex) + "/" +
+                    String.valueOf(viewModel.getPageCount()));
+        });
+        viewModel.getTopicTitle().observe(this, newTopicTitle -> {
+            if (newTopicTitle == null) return;
+            if (!TextUtils.equals(toolbarTitle.getText(), newTopicTitle))
+                toolbarTitle.setText(newTopicTitle);
+        });
+        viewModel.getPageTopicId().observe(this, pageTopicId -> {
+            if (pageTopicId == null) return;
+            if (viewModel.getCurrentPageIndex() == viewModel.getPageCount()) {
+                NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+                if (notificationManager != null)
+                    notificationManager.cancel(NEW_POST_TAG, pageTopicId);
+            }
+        });
+        viewModel.getReplyPageUrl().observe(this, replyPageUrl -> {
+            if (replyPageUrl == null)
+                replyFAB.hide();
+            else
+                replyFAB.show();
+        });
+        viewModel.getPostsList().observe(this, postList -> {
+            if (postList == null) progressBar.setVisibility(ProgressBar.VISIBLE);
+            recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug
+            postsList.clear();
+            postsList.addAll(postList);
+            topicAdapter.notifyDataSetChanged();
+        });
+        viewModel.getFocusedPostIndex().observe(this, focusedPostIndex -> {
+            if (focusedPostIndex == null) return;
+            recyclerView.scrollToPosition(focusedPostIndex);
+        });
+        viewModel.getTopicTaskResultCode().observe(this, resultCode -> {
+            if (resultCode == null) return;
+            switch (resultCode) {
+                case SUCCESS:
+                    paginationEnabled(true);
+                    progressBar.setVisibility(ProgressBar.GONE);
+                    break;
+                case NETWORK_ERROR:
+                    Toast.makeText(getBaseContext(), "Network Error", Toast.LENGTH_SHORT).show();
+                    break;
+                case UNAUTHORIZED:
+                    progressBar.setVisibility(ProgressBar.GONE);
+                    Toast.makeText(getBaseContext(), "This topic is either missing or off limits to you", Toast.LENGTH_SHORT).show();
+                    break;
+                default:
+                    //Parse failed - should never happen
+                    Timber.d("Parse failed!");  //TODO report ParseException!!!
+                    Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show();
+                    finish();
+                    break;
+            }
+        });
+        viewModel.getPrepareForReplyResult().observe(this, prepareForReplyResult -> {
+            if (prepareForReplyResult != null) {
+                //prepare for a reply
+                postsList.add(Post.newQuickReply());
+                topicAdapter.notifyItemInserted(postsList.size());
+                recyclerView.scrollToPosition(postsList.size() - 1);
+                progressBar.setVisibility(ProgressBar.GONE);
+                replyFAB.hide();
+                bottomNavBar.setVisibility(View.GONE);
+            }
 
-        if (result) {
-            viewModel.reloadPage();
-        } else {
-            Toast.makeText(TopicActivity.this, "Edit failed!", Toast.LENGTH_SHORT).show();
-        }
+        });
+        viewModel.getPrepareForEditResult().observe(this, result -> {
+            if (result != null && result.isSuccessful()) {
+                viewModel.setEditingPost(true);
+                postsList.get(result.getPosition()).setPostType(Post.TYPE_EDIT);
+                topicAdapter.notifyItemChanged(result.getPosition());
+                recyclerView.scrollToPosition(result.getPosition());
+                progressBar.setVisibility(ProgressBar.GONE);
+                replyFAB.hide();
+                bottomNavBar.setVisibility(View.GONE);
+            }
+        });
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
index 783c741f..e2b98cfe 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
@@ -445,7 +445,7 @@ class TopicAdapter extends RecyclerView.Adapter {
                     .transform(new CircleTransform())
                     .into(holder.thumbnail);
             holder.username.setText(getSessionManager().getUsername());
-            holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle());
+            holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle().getValue());
 
             holder.quickReply.setText(viewModel.getBuildedQuotes());
 
@@ -459,7 +459,7 @@ class TopicAdapter extends RecyclerView.Adapter {
                         holder.quickReply.getText().toString());
 
                 holder.quickReplySubject.getText().clear();
-                holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle());
+                holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle().getValue());
                 holder.quickReply.getText().clear();
                 holder.submitButton.setEnabled(true);
             });
From f97c2d881135c0cdfb0b0d834837c3bbd91e3734 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Wed, 8 Aug 2018 18:08:19 +0300
Subject: [PATCH 08/10] crash fix when topic is destroyed before a first load,
 minor improvements
---
 .../thmmy/mthmmy/viewmodel/TopicViewModel.java   | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index b74a63a2..02319e9e 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -104,7 +104,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
         if (replyPageUrl.getValue() == null)
             throw new NullPointerException("Topic task has not finished yet!");
         stopLoading();
-        setPageIndicatorIndex(getPageCount(), true);
+        setPageIndicatorIndex(pageCount, true);
         currentPrepareForReplyTask = new PrepareForReply(prepareForReplyCallbacks, this,
                 replyPageUrl.getValue());
         currentPrepareForReplyTask.execute(toQuoteList.toArray(new Integer[0]));
@@ -155,7 +155,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void stopLoading() {
         if (currentTopicTask != null && currentTopicTask.getStatus() == AsyncTask.Status.RUNNING) {
             currentTopicTask.cancel(true);
-            pageIndicatorIndex.setValue(getCurrentPageIndex());
+            pageIndicatorIndex.setValue(currentPageIndex);
             topicTaskObserver.onTopicTaskCancelled();
         }
         if (currentPrepareForEditTask != null && currentPrepareForEditTask.getStatus() == AsyncTask.Status.RUNNING) {
@@ -208,10 +208,10 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void incrementPageRequestValue(int step, boolean changePage) {
         if (pageIndicatorIndex.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
-        if (pageIndicatorIndex.getValue() <= getPageCount() - step) {
+        if (pageIndicatorIndex.getValue() <= pageCount - step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() + step);
         } else
-            pageIndicatorIndex.setValue(getPageCount());
+            pageIndicatorIndex.setValue(pageCount);
         if (changePage) performPageChange();
     }
 
@@ -368,10 +368,8 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     }
 
     public String getBuildedQuotes() {
-        if (prepareForReplyResult.getValue() != null) {
-            return prepareForReplyResult.getValue().getBuildedQuotes();
-        } else {
-            return "";
-        }
+        if (prepareForReplyResult.getValue() == null)
+            throw new NullPointerException("Reply preparation was not found");
+        return prepareForReplyResult.getValue().getBuildedQuotes();
     }
 }
From c0f4edab6959f3ba66ce723c24c8adc56cd1cd6c Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Fri, 10 Aug 2018 12:17:22 +0300
Subject: [PATCH 09/10] change submit button behaviour when replying/editing
 post
---
 .../activities/topic/TopicActivity.java       | 23 ++++++++++---------
 .../mthmmy/activities/topic/TopicAdapter.java | 19 +++++++--------
 .../mthmmy/viewmodel/TopicViewModel.java      |  1 -
 3 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index 234edef0..f755838a 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -486,15 +486,12 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
                     imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                 }
 
-                postsList.remove(postsList.size() - 1);
-                topicAdapter.notifyItemRemoved(postsList.size());
-
                 progressBar.setVisibility(ProgressBar.GONE);
-                replyFAB.show();
-                bottomNavBar.setVisibility(View.VISIBLE);
-                viewModel.setWritingReply(false);
 
                 if (success) {
+                    replyFAB.show();
+                    bottomNavBar.setVisibility(View.VISIBLE);
+                    viewModel.setWritingReply(false);
                     if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) {
                         viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
                     } else {
@@ -502,6 +499,8 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
                     }
                 } else {
                     Toast.makeText(TopicActivity.this, "Post failed!", Toast.LENGTH_SHORT).show();
+                    recyclerView.getChildAt(postsList.size() - 1).setAlpha(1);
+                    recyclerView.getChildAt(postsList.size() - 1).setEnabled(true);
                 }
             }
         });
@@ -530,17 +529,19 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
                     imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                 }
 
-                postsList.get(position).setPostType(Post.TYPE_POST);
-                topicAdapter.notifyItemChanged(position);
-                viewModel.setEditingPost(false);
                 progressBar.setVisibility(ProgressBar.GONE);
-                replyFAB.show();
-                bottomNavBar.setVisibility(View.VISIBLE);
 
                 if (result) {
+                    postsList.get(position).setPostType(Post.TYPE_POST);
+                    topicAdapter.notifyItemChanged(position);
+                    replyFAB.show();
+                    bottomNavBar.setVisibility(View.VISIBLE);
+                    viewModel.setEditingPost(false);
                     viewModel.reloadPage();
                 } else {
                     Toast.makeText(TopicActivity.this, "Edit failed!", Toast.LENGTH_SHORT).show();
+                    recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setAlpha(1);
+                    recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setEnabled(true);
                 }
             }
         });
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
index e2b98cfe..b45a44bd 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
@@ -453,15 +453,13 @@ class TopicAdapter extends RecyclerView.Adapter {
             holder.submitButton.setOnClickListener(view -> {
                 if (holder.quickReplySubject.getText().toString().isEmpty()) return;
                 if (holder.quickReply.getText().toString().isEmpty()) return;
-                holder.submitButton.setEnabled(false);
+                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+                holder.itemView.setAlpha(0.5f);
+                holder.itemView.setEnabled(false);
 
                 viewModel.postReply(context, holder.quickReplySubject.getText().toString(),
                         holder.quickReply.getText().toString());
-
-                holder.quickReplySubject.getText().clear();
-                holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle().getValue());
-                holder.quickReply.getText().clear();
-                holder.submitButton.setEnabled(true);
             });
 
 
@@ -491,13 +489,12 @@ class TopicAdapter extends RecyclerView.Adapter {
             holder.submitButton.setOnClickListener(view -> {
                 if (holder.editSubject.getText().toString().isEmpty()) return;
                 if (holder.editMessage.getText().toString().isEmpty()) return;
-                holder.submitButton.setEnabled(false);
+                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+                holder.itemView.setAlpha(0.5f);
+                holder.itemView.setEnabled(false);
 
                 viewModel.editPost(position, holder.editSubject.getText().toString(), holder.editMessage.getText().toString());
-
-                holder.editSubject.getText().clear();
-                holder.editSubject.setText(postsList.get(position).getSubject());
-                holder.submitButton.setEnabled(true);
             });
 
             if (backPressHidden) {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 02319e9e..abc9ac09 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -200,7 +200,6 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
 
     @Override
     public void onPrepareEditFinished(PrepareForEditResult result, int position) {
-        editingPost = true;
         postBeingEditedPosition = position;
         prepareForEditResult.setValue(result);
     }
From 55afa63852df304110b36af1063043b83227ce23 Mon Sep 17 00:00:00 2001
From: Thodoris1999 
Date: Fri, 10 Aug 2018 15:26:16 +0300
Subject: [PATCH 10/10] add/improve topic's behavior on network errors
---
 .../activities/topic/TopicActivity.java       | 50 ++++++++++++++-----
 .../activities/topic/tasks/DeleteTask.java    |  2 +-
 .../topic/tasks/PrepareForReply.java          | 13 ++---
 .../topic/tasks/PrepareForReplyResult.java    |  8 ++-
 .../mthmmy/utils/ScrollAwareFABBehavior.java  | 15 +++++-
 .../utils/ScrollAwareLinearBehavior.java      | 17 ++++++-
 .../mthmmy/viewmodel/TopicViewModel.java      | 18 ++++---
 app/src/main/res/layout/activity_topic.xml    | 10 ++++
 app/src/main/res/values/strings.xml           |  4 ++
 9 files changed, 106 insertions(+), 31 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
index f755838a..c4dff2d7 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -11,6 +11,7 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AppCompatDelegate;
 import android.support.v7.widget.RecyclerView;
@@ -30,7 +31,6 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import java.util.ArrayList;
-import java.util.Objects;
 
 import gr.thmmy.mthmmy.R;
 import gr.thmmy.mthmmy.activities.topic.tasks.DeleteTask;
@@ -110,6 +110,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
     private TextView pageIndicator;
     private ImageButton nextPage;
     private ImageButton lastPage;
+    private Snackbar snackbar;
     private TopicViewModel viewModel;
 
     //Fix for vector drawables on android <21
@@ -449,6 +450,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
             @Override
             public void onTopicTaskStarted() {
                 progressBar.setVisibility(ProgressBar.VISIBLE);
+                if (snackbar != null) snackbar.dismiss();
             }
 
             @Override
@@ -469,7 +471,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
                 if (result)
                     viewModel.reloadPage();
                 else
-                    Toast.makeText(TopicActivity.this, "Post deleted!", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(getBaseContext(), "Delete failed!", Toast.LENGTH_SHORT).show();
             }
         });
         viewModel.setReplyFinishListener(new ReplyTask.ReplyTaskCallbacks() {
@@ -498,7 +500,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
                         viewModel.reloadPage();
                     }
                 } else {
-                    Toast.makeText(TopicActivity.this, "Post failed!", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show();
                     recyclerView.getChildAt(postsList.size() - 1).setAlpha(1);
                     recyclerView.getChildAt(postsList.size() - 1).setEnabled(true);
                 }
@@ -539,7 +541,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
                     viewModel.setEditingPost(false);
                     viewModel.reloadPage();
                 } else {
-                    Toast.makeText(TopicActivity.this, "Edit failed!", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(getBaseContext(), "Edit failed!", Toast.LENGTH_SHORT).show();
                     recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setAlpha(1);
                     recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setEnabled(true);
                 }
@@ -594,17 +596,37 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
         });
         viewModel.getTopicTaskResultCode().observe(this, resultCode -> {
             if (resultCode == null) return;
+            progressBar.setVisibility(ProgressBar.GONE);
             switch (resultCode) {
                 case SUCCESS:
                     paginationEnabled(true);
-                    progressBar.setVisibility(ProgressBar.GONE);
                     break;
                 case NETWORK_ERROR:
-                    Toast.makeText(getBaseContext(), "Network Error", Toast.LENGTH_SHORT).show();
+                    if (viewModel.getPostsList().getValue() == null) {
+                        // no page has been loaded yet. Give user the ability to refresh
+                        recyclerView.setVisibility(View.GONE);
+                        TextView errorTextview = findViewById(R.id.error_textview);
+                        errorTextview.setText(getString(R.string.network_error_retry_prompt));
+                        errorTextview.setVisibility(View.VISIBLE);
+                        errorTextview.setOnClickListener(view -> {
+                            viewModel.reloadPage();
+                            errorTextview.setVisibility(View.GONE);
+                            recyclerView.setVisibility(View.VISIBLE);
+                        });
+                    } else {
+                        // a page has already been loaded
+                        viewModel.setPageIndicatorIndex(viewModel.getCurrentPageIndex(), false);
+                        snackbar = Snackbar.make(findViewById(R.id.main_content),
+                                R.string.generic_network_error, Snackbar.LENGTH_INDEFINITE);
+                        snackbar.setAction(R.string.retry, view -> viewModel.reloadPage());
+                        snackbar.show();
+                    }
                     break;
                 case UNAUTHORIZED:
-                    progressBar.setVisibility(ProgressBar.GONE);
-                    Toast.makeText(getBaseContext(), "This topic is either missing or off limits to you", Toast.LENGTH_SHORT).show();
+                    recyclerView.setVisibility(View.GONE);
+                    TextView errorTextview = findViewById(R.id.error_textview);
+                    errorTextview.setText(getString(R.string.unauthorized_topic_error));
+                    errorTextview.setVisibility(View.VISIBLE);
                     break;
                 default:
                     //Parse failed - should never happen
@@ -615,26 +637,30 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
             }
         });
         viewModel.getPrepareForReplyResult().observe(this, prepareForReplyResult -> {
-            if (prepareForReplyResult != null) {
+            progressBar.setVisibility(ProgressBar.GONE);
+            if (prepareForReplyResult != null && prepareForReplyResult.isSuccessful()) {
                 //prepare for a reply
+                viewModel.setWritingReply(true);
                 postsList.add(Post.newQuickReply());
                 topicAdapter.notifyItemInserted(postsList.size());
                 recyclerView.scrollToPosition(postsList.size() - 1);
-                progressBar.setVisibility(ProgressBar.GONE);
                 replyFAB.hide();
                 bottomNavBar.setVisibility(View.GONE);
+            } else {
+                Snackbar.make(findViewById(R.id.main_content), getString(R.string.generic_network_error), Snackbar.LENGTH_SHORT).show();
             }
-
         });
         viewModel.getPrepareForEditResult().observe(this, result -> {
+            progressBar.setVisibility(ProgressBar.GONE);
             if (result != null && result.isSuccessful()) {
                 viewModel.setEditingPost(true);
                 postsList.get(result.getPosition()).setPostType(Post.TYPE_EDIT);
                 topicAdapter.notifyItemChanged(result.getPosition());
                 recyclerView.scrollToPosition(result.getPosition());
-                progressBar.setVisibility(ProgressBar.GONE);
                 replyFAB.hide();
                 bottomNavBar.setVisibility(View.GONE);
+            } else {
+                Snackbar.make(findViewById(R.id.main_content), getString(R.string.generic_network_error), Snackbar.LENGTH_SHORT).show();
             }
         });
     }
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
index 5d4a0531..f3523953 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
@@ -41,7 +41,7 @@ public class DeleteTask extends AsyncTask {
                     return true;
                 default:
                     Timber.e("Something went wrong. Request string: %s", delete.toString());
-                    return true;
+                    return false;
             }
         } catch (IOException e) {
             Timber.e(e, "Delete failed.");
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReply.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReply.java
index 42ea2774..2e0d7148 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReply.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReply.java
@@ -33,18 +33,13 @@ public class PrepareForReply extends AsyncTask {
@@ -48,4 +49,16 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.BehaviorWhen a nested ScrollView is scrolled down, the view will disappear.
- * When the ScrollView is scrolled back up, the view will reappear.
+ * When the ScrollView is scrolled back up, the view will reappear. It also pushes the
+ * {@link android.widget.LinearLayout} up when a {@link Snackbar} is shown
+ * 
  */
 @SuppressWarnings("unused")
 public class ScrollAwareLinearBehavior extends CoordinatorLayout.Behavior {
@@ -111,4 +114,16 @@ public class ScrollAwareLinearBehavior extends CoordinatorLayout.Behavior
 
         animator.start();
     }
+
+    @Override
+    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
+        return dependency instanceof Snackbar.SnackbarLayout;
+    }
+
+    @Override
+    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
+        float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
+        child.setTranslationY(translationY);
+        return true;
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index abc9ac09..080414ab 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -84,7 +84,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     }
 
     public void reloadPage() {
-        if (topicUrl == null) throw new NullPointerException("No topic task has finished yet!");
+        if (topicUrl == null) throw new NullPointerException("No topic task has been requested yet!");
         loadUrl(topicUrl);
     }
 
@@ -194,7 +194,6 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
 
     @Override
     public void onPrepareForReplyFinished(PrepareForReplyResult result) {
-        writingReply = true;
         prepareForReplyResult.setValue(result);
     }
 
@@ -207,26 +206,31 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
     public void incrementPageRequestValue(int step, boolean changePage) {
         if (pageIndicatorIndex.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
-        if (pageIndicatorIndex.getValue() <= pageCount - step) {
+        int oldIndicatorIndex = pageIndicatorIndex.getValue();
+        if (oldIndicatorIndex <= pageCount - step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() + step);
         } else
             pageIndicatorIndex.setValue(pageCount);
-        if (changePage) performPageChange();
+        if (changePage && oldIndicatorIndex != pageIndicatorIndex.getValue()) performPageChange();
     }
 
     public void decrementPageRequestValue(int step, boolean changePage) {
         if (pageIndicatorIndex.getValue() == null)
             throw new NullPointerException("No page has been loaded yet!");
-        if (pageIndicatorIndex.getValue() >= step) {
+        int oldIndicatorIndex = pageIndicatorIndex.getValue();
+        if (oldIndicatorIndex > step) {
             pageIndicatorIndex.setValue(pageIndicatorIndex.getValue() - step);
         } else
             pageIndicatorIndex.setValue(1);
-        if (changePage) performPageChange();
+        if (changePage && oldIndicatorIndex != pageIndicatorIndex.getValue()) performPageChange();
     }
 
     public void setPageIndicatorIndex(int pageIndicatorIndex, boolean changePage) {
+        if (this.pageIndicatorIndex.getValue() == null)
+            throw new NullPointerException("No page has been loaded yet!");
+        int oldIndicatorIndex = this.pageIndicatorIndex.getValue();
         this.pageIndicatorIndex.setValue(pageIndicatorIndex);
-        if (changePage) performPageChange();
+        if (changePage && oldIndicatorIndex != this.pageIndicatorIndex.getValue()) performPageChange();
     }
 
     // <-------------Just getters, setters and helper methods below here---------------->
diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml
index cb98088e..cb3a1072 100644
--- a/app/src/main/res/layout/activity_topic.xml
+++ b/app/src/main/res/layout/activity_topic.xml
@@ -47,6 +47,16 @@
         app:layout_behavior="@string/appbar_scrolling_view_behavior">
     
 
+    
+
     Subject…
     Submit
     Message…
+    Could not connect to thmmy.gr \n\n Tap to retry
+    Network error
+    retry
+    This topic is either missing or off limits to you
 
     
     Username