diff --git a/app/build.gradle b/app/build.gradle
index ecbd4dbc..a1c8c82c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,5 +1,7 @@
import groovy.json.JsonSlurper
+apply from: 'gradle/grgit.gradle'
+
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
@@ -11,9 +13,12 @@ android {
applicationId "gr.thmmy.mthmmy"
minSdkVersion 19
targetSdkVersion 28
- versionCode 14
- versionName "1.5.0"
+ versionCode 15
+ versionName "1.6.0"
archivesBaseName = "mTHMMY-v$versionName"
+ buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\""
+ buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\""
+ buildConfigField "boolean", "IS_CLEAN", String.valueOf(isClean())
}
buildTypes {
@@ -41,43 +46,50 @@ tasks.whenTaskAdded { task ->
task.getDependsOn().add({
def inputFile = new File("app/google-services.json")
def json = new JsonSlurper().parseText(inputFile.text)
- if(json.project_info.project_id != "mthmmy-release-3aef0")
- throw new GradleException('Please supply the correct google-services.json for release or manually change the id above!')
+ if (json.project_info.project_id != "mthmmy-release-3aef0")
+ throw new GradleException('Please supply the correct google-services.json for release (or manually change the id above)!')
+ })
+ } else if (task.name.contains("assembleDebug")) {
+ task.getDependsOn().add({
+ def inputFile = new File("app/google-services.json")
+ def json = new JsonSlurper().parseText(inputFile.text)
+ if (json.project_info.project_id == "mthmmy-release-3aef0")
+ throw new GradleException('Please replace the release google-services.json with a debug one!')
})
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support:design:28.0.0'
- implementation 'com.android.support:preference-v7:28.0.0'
- implementation 'com.android.support:preference-v14:28.0.0'
- implementation 'com.android.support:support-v4:28.0.0'
- implementation 'com.android.support:cardview-v7:28.0.0'
- implementation 'com.android.support:recyclerview-v7:28.0.0'
- implementation 'com.google.firebase:firebase-core:16.0.4'
- implementation 'com.google.firebase:firebase-messaging:17.3.3'
- implementation 'com.crashlytics.sdk.android:crashlytics:2.9.5'
- implementation 'com.squareup.okhttp3:okhttp:3.11.0'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.preference:preference:1.1.0-alpha01'
+ implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation 'com.google.firebase:firebase-core:16.0.6'
+ implementation 'com.google.firebase:firebase-messaging:17.3.4'
+ implementation 'com.crashlytics.sdk.android:crashlytics:2.9.7'
+ implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
implementation 'org.jsoup:jsoup:1.10.3' //TODO: Warning: upgrading from 1.10.3 will break stuff!
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
- implementation("com.mikepenz:materialdrawer:6.0.7@aar") {
- transitive = true
- }
+ implementation 'com.mikepenz:materialdrawer:6.1.1'
implementation 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar'
implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'//TODO: deprecated!
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
implementation 'com.jakewharton.timber:timber:4.7.1'
- implementation "ru.noties:markwon:2.0.0"
+ implementation 'ru.noties:markwon:2.0.0'
implementation 'net.gotev:uploadservice:3.4.2'
implementation 'net.gotev:uploadservice-okhttp:3.4.2'
- implementation 'android.arch.lifecycle:extensions:1.1.1'
+ implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.4' //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler
}
apply plugin: 'com.google.gms.google-services'
diff --git a/app/gradle/grgit.gradle b/app/gradle/grgit.gradle
new file mode 100644
index 00000000..dc0d5e7f
--- /dev/null
+++ b/app/gradle/grgit.gradle
@@ -0,0 +1,51 @@
+import org.ajoberstar.grgit.Grgit
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'org.ajoberstar.grgit:grgit-core:3.0.0'
+ }
+}
+
+static def getCurrentBranch() {
+ try {
+ def grgit = Grgit.open()
+ def currentBranch = grgit.branch.getCurrent().name
+ grgit.close()
+ return currentBranch
+ } catch (Exception ignored) {
+ return ""
+ }
+}
+
+static def getCommitHash() {
+ try {
+ def grgit = Grgit.open()
+ def commitHash = grgit.head().id
+ grgit.close()
+ return commitHash
+ } catch (Exception ignored) {
+ return ""
+ }
+}
+
+//Will return true if there are no uncommitted changes
+static def isClean() {
+ try {
+ def grgit = Grgit.open()
+ def isClean = grgit.status().isClean()
+ grgit.close()
+ return isClean
+ } catch (Exception ignored) {
+ return true
+ }
+}
+
+ext {
+ getCurrentBranch = this.&getCurrentBranch
+ getCommitHash = this.&getCommitHash
+ isClean = this.&isClean
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 19f47c62..7620bcf7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,11 +17,18 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
-
-
-
-
-
+
+
+
+
@@ -158,6 +165,14 @@
android:configChanges="orientation|screenSize"
android:parentActivityName=".activities.main.MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/apache_libraries.html b/app/src/main/assets/apache_libraries.html
index a8ff5d90..b0e33882 100644
--- a/app/src/main/assets/apache_libraries.html
+++ b/app/src/main/assets/apache_libraries.html
@@ -39,7 +39,7 @@
-
-
OkHttp v3.11.0 (Copyright ©2016 Square, Inc.)
+ OkHttp v3.12.0 (Copyright ©2016 Square, Inc.)
-
Picasso v2.5.2 (Copyright ©2013 Square, Inc.)
@@ -51,7 +51,7 @@
MPAndroidChart v3.0.3 (Copyright ©2018 Philipp Jahoda)
-
-
MaterialDrawer v6.0.7 (Copyright ©2018 Mike Penz)
+ MaterialDrawer v6.1.1 (Copyright ©2018 Mike Penz)
-
Android-Iconics v2.9.5 (Copyright ©2016 Mike Penz)
@@ -68,6 +68,12 @@
-
Markwon v2.0.0 (Copyright ©2017 Dimitry Ivanov)
+ -
+
Grgit v3.0.0 (Copyright ©2018 Andrew Oberstar)
+
+ -
+
+
diff --git a/app/src/main/assets/style.css b/app/src/main/assets/style.css
index d870a911..7415c141 100644
--- a/app/src/main/assets/style.css
+++ b/app/src/main/assets/style.css
@@ -520,4 +520,21 @@ img
.customSignature{
background: #323232;
-}
\ No newline at end of file
+}
+
+[style="color: blue;"]
+{
+ color: #3452fe !important;
+}
+
+[style="color: purple;"]
+{
+ color: #a511a5 !important;
+}
+
+[style="color: maroon;"]
+{
+ color: #a51111 !important;
+}
+
+
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java
index 34ed4c32..77a6aebd 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java
@@ -1,11 +1,9 @@
package gr.thmmy.mthmmy.activities;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.net.Uri;
import android.os.Bundle;
-import android.support.design.widget.AppBarLayout;
-import android.support.design.widget.CoordinatorLayout;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.AlertDialog;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.style.UnderlineSpan;
@@ -16,6 +14,11 @@ import android.widget.FrameLayout;
import android.widget.ScrollView;
import android.widget.TextView;
+import com.google.android.material.appbar.AppBarLayout;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import androidx.drawerlayout.widget.DrawerLayout;
import gr.thmmy.mthmmy.BuildConfig;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
@@ -37,6 +40,20 @@ public class AboutActivity extends BaseActivity {
setContentView(R.layout.activity_about);
String versionName = BuildConfig.VERSION_NAME;
+ boolean gitExists = true;
+
+ String commitHash = BuildConfig.COMMIT_HASH;
+ if (commitHash.length() > 8)
+ commitHash = commitHash.substring(0, 8);
+ else
+ gitExists = false;
+
+ String versionInfo = "";
+ if(gitExists)
+ versionInfo = "-" + BuildConfig.CURRENT_BRANCH + "-" + commitHash
+ + (BuildConfig.IS_CLEAN ? "" : "-dirty")
+ + " "; // Avoid last letter being cut in italics styled TextView
+
//Initialize appbar
appBar = findViewById(R.id.appbar);
coordinatorLayout = findViewById(R.id.main_content);
@@ -58,14 +75,19 @@ public class AboutActivity extends BaseActivity {
TextView tv = findViewById(R.id.version);
if (tv != null) {
if (BuildConfig.DEBUG)
- tv.setText(getString(R.string.version, versionName + "-debug"));
+ tv.setText(getString(R.string.version, versionName + versionInfo));
else
tv.setText(getString(R.string.version, versionName));
- tv.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
+ if(BuildConfig.DEBUG && gitExists){
+ tv.setOnClickListener(view -> {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/ThmmyNoLife/mTHMMY/commit/" + BuildConfig.COMMIT_HASH));
+ startActivity(intent);
+ });
+ }
+ else{ // Easter Egg
+ tv.setOnClickListener(view -> {
if (mVersionLastPressedTime + TIME_INTERVAL > System.currentTimeMillis()) {
if (mVersionPressedCounter == TIMES_TO_PRESS) {
appBar.setVisibility(View.INVISIBLE);
@@ -80,8 +102,8 @@ public class AboutActivity extends BaseActivity {
mVersionLastPressedTime = System.currentTimeMillis();
mVersionPressedCounter = 0;
}
- }
- });
+ });
+ }
}
TextView privacyPolicy = findViewById(R.id.privacy_policy_header);
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
index 1a5ad05f..29ab9b1b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
@@ -3,8 +3,6 @@ package gr.thmmy.mthmmy.activities;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.preference.PreferenceManager;
-import android.support.v7.widget.AppCompatButton;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
@@ -14,6 +12,8 @@ import android.widget.Toast;
import com.google.firebase.analytics.FirebaseAnalytics;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.preference.PreferenceManager;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.main.MainActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
index d3a74098..61fc45e6 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
@@ -4,15 +4,12 @@ import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
@@ -20,6 +17,10 @@ import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.Objects;
+import androidx.appcompat.app.AlertDialog;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.create_content.CreateContentActivity;
@@ -124,7 +125,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
});
}
- boardAdapter = new BoardAdapter(getApplicationContext(), parsedSubBoards, parsedTopics);
+ boardAdapter = new BoardAdapter(this, parsedSubBoards, parsedTopics);
RecyclerView mainContent = findViewById(R.id.board_recycler_view);
mainContent.setAdapter(boardAdapter);
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
@@ -148,7 +149,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
});
boardTask = new BoardTask();
- boardTask.execute(boardUrl);
+ boardTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, boardUrl);
}
@Override
@@ -196,9 +197,9 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
tempSubboards.addAll(parsedSubBoards);
tempTopics.addAll(parsedTopics);
//Removes loading item
- if (isLoadingMore) {
- if (tempTopics.size() > 0) tempTopics.remove(tempTopics.size() - 1);
- }
+ if (isLoadingMore && tempTopics.size() > 0)
+ tempTopics.remove(tempTopics.size() - 1);
+
parsedTitle = boardPage.select("div.nav a.nav").last().text();
//Finds number of pages
@@ -223,8 +224,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (newTopicButton == null)
newTopicButton = boardPage.select("a:has(img[alt=Νέο θέμα])").first();
if (newTopicButton != null) newTopicUrl = newTopicButton.attr("href");
-
- { //Finds sub boards
+ if(pagesLoaded == 0) { //Finds sub boards
Elements subBoardRows = boardPage.select("div.tborder>table>tbody>tr");
if (subBoardRows != null && !subBoardRows.isEmpty()) {
for (Element subBoardRow : subBoardRows) {
@@ -268,46 +268,46 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
}
}
}
- { //Finds topics
- Elements topicRows = boardPage.select("table.bordercolor>tbody>tr");
- if (topicRows != null && !topicRows.isEmpty()) {
- for (Element topicRow : topicRows) {
- if (!Objects.equals(topicRow.className(), "titlebg")) {
- String pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl, pStats;
- boolean pLocked = false, pSticky = false, pUnread = false;
- Elements topicColumns = topicRow.select(">td");
- {
- Element column = topicColumns.get(2);
- Element tmp = column.select("span[id^=msg_] a").first();
- pTopicUrl = tmp.attr("href");
- pSubject = tmp.text();
- if (column.select("img[id^=stickyicon]").first() != null)
- pSticky = true;
- if (column.select("img[id^=lockicon]").first() != null)
- pLocked = true;
- if (column.select("a[id^=newicon]").first() != null)
- pUnread = true;
- }
- pStartedBy = topicColumns.get(3).text();
- pStats = "Replies " + topicColumns.get(4).text() + ", Views " + topicColumns.get(5).text();
-
- pLastPost = topicColumns.last().text();
- if (pLastPost.contains("by")) {
- pLastPost = pLastPost.substring(0, pLastPost.indexOf("by")) +
- "\n" + pLastPost.substring(pLastPost.indexOf("by"));
- } else if (pLastPost.contains("από")) {
- pLastPost = pLastPost.substring(0, pLastPost.indexOf("από")) +
- "\n" + pLastPost.substring(pLastPost.indexOf("από"));
- } else {
- Timber.wtf("Board parsing about to fail. pLastPost came with: %s", pLastPost);
- }
- pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href");
- tempTopics.add(new Topic(pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl,
- pStats, pLocked, pSticky, pUnread));
+ //Finds topics
+ Elements topicRows = boardPage.select("table.bordercolor>tbody>tr");
+ if (topicRows != null && !topicRows.isEmpty()) {
+ for (Element topicRow : topicRows) {
+ if (!Objects.equals(topicRow.className(), "titlebg")) {
+ String pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl, pStats;
+ boolean pLocked = false, pSticky = false, pUnread = false;
+ Elements topicColumns = topicRow.select(">td");
+ {
+ Element column = topicColumns.get(2);
+ Element tmp = column.select("span[id^=msg_] a").first();
+ pTopicUrl = tmp.attr("href");
+ pSubject = tmp.text();
+ if (column.select("img[id^=stickyicon]").first() != null)
+ pSticky = true;
+ if (column.select("img[id^=lockicon]").first() != null)
+ pLocked = true;
+ if (column.select("a[id^=newicon]").first() != null)
+ pUnread = true;
}
+ pStartedBy = topicColumns.get(3).text();
+ pStats = "Replies: " + topicColumns.get(4).text() + ", Views: " + topicColumns.get(5).text();
+
+ pLastPost = topicColumns.last().text();
+ if (pLastPost.contains("by")) {
+ pLastPost = pLastPost.substring(0, pLastPost.indexOf("by")) +
+ "\n" + pLastPost.substring(pLastPost.indexOf("by"));
+ } else if (pLastPost.contains("από")) {
+ pLastPost = pLastPost.substring(0, pLastPost.indexOf("από")) +
+ "\n" + pLastPost.substring(pLastPost.indexOf("από"));
+ } else {
+ Timber.wtf("Board parsing about to fail. pLastPost came with: %s", pLastPost);
+ }
+ pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href");
+ tempTopics.add(new Topic(pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl,
+ pStats, pLocked, pSticky, pUnread));
}
}
}
+
}
@Override
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java
index 09734606..6c5e50db 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java
@@ -5,7 +5,6 @@ import android.content.Intent;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -16,13 +15,13 @@ import android.widget.TextView;
import java.util.ArrayList;
import java.util.Objects;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.model.Board;
import gr.thmmy.mthmmy.model.Topic;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE;
import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE;
@@ -91,7 +90,7 @@ class BoardAdapter extends RecyclerView.Adapter {
return new TitlesViewHolder(subBoardTitle);
} else if (viewType == VIEW_TYPE_SUB_BOARD) {
View subBoard = LayoutInflater.from(parent.getContext()).
- inflate(R.layout.activity_board_sub_board, parent, false);
+ inflate(R.layout.activity_board_sub_board_row, parent, false);
return new SubBoardViewHolder(subBoard);
} else if (viewType == VIEW_TYPE_TOPIC_TITLE) {
TextView topicTitle = new TextView(context);
@@ -112,7 +111,7 @@ class BoardAdapter extends RecyclerView.Adapter {
return new TitlesViewHolder(topicTitle);
} else if (viewType == VIEW_TYPE_TOPIC) {
View topic = LayoutInflater.from(parent.getContext()).
- inflate(R.layout.activity_board_topic, parent, false);
+ inflate(R.layout.activity_board_topic_row, parent, false);
return new TopicViewHolder(topic);
} else if (viewType == VIEW_TYPE_LOADING) {
View loading = LayoutInflater.from(parent.getContext()).
@@ -133,17 +132,14 @@ class BoardAdapter extends RecyclerView.Adapter {
boardExpandableVisibility.add(false);
}
- subBoardViewHolder.boardRow.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(context, BoardActivity.class);
- Bundle extras = new Bundle();
- extras.putString(BUNDLE_BOARD_URL, subBoard.getUrl());
- extras.putString(BUNDLE_BOARD_TITLE, subBoard.getTitle());
- intent.putExtras(extras);
- intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
- }
+ subBoardViewHolder.boardRow.setOnClickListener(view -> {
+ Intent intent = new Intent(context, BoardActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_BOARD_URL, subBoard.getUrl());
+ extras.putString(BUNDLE_BOARD_TITLE, subBoard.getTitle());
+ intent.putExtras(extras);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
});
if (boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition() - 1)) {
subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE);
@@ -152,36 +148,30 @@ class BoardAdapter extends RecyclerView.Adapter {
subBoardViewHolder.boardExpandable.setVisibility(View.GONE);
subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
}
- subBoardViewHolder.showHideExpandable.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- final boolean visible = boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition() - 1);
- if (visible) {
- subBoardViewHolder.boardExpandable.setVisibility(View.GONE);
- subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
- } else {
- subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE);
- subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
- }
- boardExpandableVisibility.set(subBoardViewHolder.getAdapterPosition() - 1, !visible);
+ subBoardViewHolder.showHideExpandable.setOnClickListener(view -> {
+ final boolean visible = boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition() - 1);
+ if (visible) {
+ subBoardViewHolder.boardExpandable.setVisibility(View.GONE);
+ subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
+ } else {
+ subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE);
+ subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
}
+ boardExpandableVisibility.set(subBoardViewHolder.getAdapterPosition() - 1, !visible);
});
subBoardViewHolder.boardTitle.setText(subBoard.getTitle());
subBoardViewHolder.boardMods.setText(subBoard.getMods());
subBoardViewHolder.boardStats.setText(subBoard.getStats());
subBoardViewHolder.boardLastPost.setText(subBoard.getLastPost());
if (!Objects.equals(subBoard.getLastPostUrl(), "")) {
- subBoardViewHolder.boardLastPost.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(context, TopicActivity.class);
- Bundle extras = new Bundle();
- extras.putString(BUNDLE_TOPIC_URL, subBoard.getLastPostUrl());
- //Doesn't put an already ellipsized topic title in Bundle
- intent.putExtras(extras);
- intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
- }
+ subBoardViewHolder.boardLastPost.setOnClickListener(view -> {
+ Intent intent = new Intent(context, TopicActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_TOPIC_URL, subBoard.getLastPostUrl());
+ //Doesn't put an already ellipsized topic title in Bundle
+ intent.putExtras(extras);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ context.startActivity(intent);
});
}
} else if (holder instanceof TopicViewHolder) {
@@ -193,17 +183,14 @@ class BoardAdapter extends RecyclerView.Adapter {
topicExpandableVisibility.add(false);
}
- topicViewHolder.topicRow.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(context, TopicActivity.class);
- Bundle extras = new Bundle();
- extras.putString(BUNDLE_TOPIC_URL, topic.getUrl());
- extras.putString(BUNDLE_TOPIC_TITLE, topic.getSubject());
- intent.putExtras(extras);
- intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
- }
+ topicViewHolder.topicRow.setOnClickListener(view -> {
+ Intent intent = new Intent(context, TopicActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_TOPIC_URL, topic.getUrl());
+ extras.putString(BUNDLE_TOPIC_TITLE, topic.getSubject());
+ intent.putExtras(extras);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ context.startActivity(intent);
});
if (topicExpandableVisibility.get(topicViewHolder.getAdapterPosition() - parsedSubBoards
.size() - 2)) {
@@ -213,21 +200,18 @@ class BoardAdapter extends RecyclerView.Adapter {
topicViewHolder.topicExpandable.setVisibility(View.GONE);
topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
}
- topicViewHolder.showHideExpandable.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- final boolean visible = topicExpandableVisibility.get(topicViewHolder.
- getAdapterPosition() - parsedSubBoards.size() - 2);
- if (visible) {
- topicViewHolder.topicExpandable.setVisibility(View.GONE);
- topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
- } else {
- topicViewHolder.topicExpandable.setVisibility(View.VISIBLE);
- topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
- }
- topicExpandableVisibility.set(topicViewHolder.getAdapterPosition() -
- parsedSubBoards.size() - 2, !visible);
+ topicViewHolder.showHideExpandable.setOnClickListener(view -> {
+ final boolean visible = topicExpandableVisibility.get(topicViewHolder.
+ getAdapterPosition() - parsedSubBoards.size() - 2);
+ if (visible) {
+ topicViewHolder.topicExpandable.setVisibility(View.GONE);
+ topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
+ } else {
+ topicViewHolder.topicExpandable.setVisibility(View.VISIBLE);
+ topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
}
+ topicExpandableVisibility.set(topicViewHolder.getAdapterPosition() -
+ parsedSubBoards.size() - 2, !visible);
});
topicViewHolder.topicSubject.setTypeface(Typeface.createFromAsset(context.getAssets()
, "fonts/fontawesome-webfont.ttf"));
@@ -248,17 +232,14 @@ class BoardAdapter extends RecyclerView.Adapter {
topicViewHolder.topicStartedBy.setText(context.getString(R.string.topic_started_by, topic.getStarter()));
topicViewHolder.topicStats.setText(topic.getStats());
topicViewHolder.topicLastPost.setText(context.getString(R.string.topic_last_post, topic.getLastPostDateAndTime()));
- topicViewHolder.topicLastPost.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(context, TopicActivity.class);
- Bundle extras = new Bundle();
- extras.putString(BUNDLE_TOPIC_URL, topic.getLastPostUrl());
- //Doesn't put an already ellipsized topic title in Bundle
- intent.putExtras(extras);
- intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
- }
+ topicViewHolder.topicLastPost.setOnClickListener(view -> {
+ Intent intent = new Intent(context, TopicActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_TOPIC_URL, topic.getLastPostUrl());
+ //Doesn't put an already ellipsized topic title in Bundle
+ intent.putExtras(extras);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ context.startActivity(intent);
});
} else if (holder instanceof LoadingViewHolder) {
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarkActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
similarity index 78%
rename from app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarkActivity.java
rename to app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
index 164e8f3f..0a65da94 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarkActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
@@ -2,16 +2,18 @@ package gr.thmmy.mthmmy.activities.bookmarks;
import android.content.Intent;
import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
import android.widget.Toast;
+import com.google.android.material.tabs.TabLayout;
+
import java.util.ArrayList;
import java.util.List;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+import androidx.viewpager.widget.ViewPager;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.board.BoardActivity;
import gr.thmmy.mthmmy.activities.topic.TopicActivity;
@@ -25,11 +27,11 @@ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
//TODO proper handling with adapter etc.
//TODO after clicking bookmark and then back button should return to this activity
-public class BookmarkActivity extends BaseActivity {
+public class BookmarksActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_bookmark);
+ setContentView(R.layout.activity_bookmarks);
//Initialize toolbar
toolbar = findViewById(R.id.toolbar);
@@ -45,8 +47,8 @@ public class BookmarkActivity extends BaseActivity {
//Creates the adapter that will return a fragment for each section of the activity
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
- sectionsPagerAdapter.addFragment(TopicBookmarksFragment.newInstance(1, Bookmark.arrayToString(getTopicsBookmarked())), "Topics");
- sectionsPagerAdapter.addFragment(BoardBookmarksFragment.newInstance(2, Bookmark.arrayToString(getBoardsBookmarked())), "Boards");
+ sectionsPagerAdapter.addFragment(BookmarksTopicFragment.newInstance(1, Bookmark.arrayToString(getTopicsBookmarked())), "Topics");
+ sectionsPagerAdapter.addFragment(BookmarksBoardFragment.newInstance(2, Bookmark.arrayToString(getBoardsBookmarked())), "Boards");
//Sets up the ViewPager with the sections adapter.
ViewPager viewPager = findViewById(R.id.bookmarks_container);
@@ -64,21 +66,20 @@ public class BookmarkActivity extends BaseActivity {
public boolean onTopicInteractionListener(String interactionType, Bookmark bookmarkedTopic) {
switch (interactionType) {
- case TopicBookmarksFragment.INTERACTION_CLICK_TOPIC_BOOKMARK:
- Intent intent = new Intent(BookmarkActivity.this, TopicActivity.class);
+ case BookmarksTopicFragment.INTERACTION_CLICK_TOPIC_BOOKMARK:
+ Intent intent = new Intent(BookmarksActivity.this, TopicActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_TOPIC_URL, "https://www.thmmy.gr/smf/index.php?topic="
+ bookmarkedTopic.getId() + "." + 2147483647);
extras.putString(BUNDLE_TOPIC_TITLE, bookmarkedTopic.getTitle());
intent.putExtras(extras);
startActivity(intent);
- finish();
break;
- case TopicBookmarksFragment.INTERACTION_TOGGLE_TOPIC_NOTIFICATION:
+ case BookmarksTopicFragment.INTERACTION_TOGGLE_TOPIC_NOTIFICATION:
return toggleNotification(bookmarkedTopic);
- case TopicBookmarksFragment.INTERACTION_REMOVE_TOPIC_BOOKMARK:
+ case BookmarksTopicFragment.INTERACTION_REMOVE_TOPIC_BOOKMARK:
removeBookmark(bookmarkedTopic);
- Toast.makeText(BookmarkActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show();
+ Toast.makeText(BookmarksActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show();
break;
}
return true;
@@ -86,21 +87,20 @@ public class BookmarkActivity extends BaseActivity {
public boolean onBoardInteractionListener(String interactionType, Bookmark bookmarkedBoard) {
switch (interactionType) {
- case BoardBookmarksFragment.INTERACTION_CLICK_BOARD_BOOKMARK:
- Intent intent = new Intent(BookmarkActivity.this, BoardActivity.class);
+ case BookmarksBoardFragment.INTERACTION_CLICK_BOARD_BOOKMARK:
+ Intent intent = new Intent(BookmarksActivity.this, BoardActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_BOARD_URL, "https://www.thmmy.gr/smf/index.php?board="
+ bookmarkedBoard.getId() + ".0");
extras.putString(BUNDLE_BOARD_TITLE, bookmarkedBoard.getTitle());
intent.putExtras(extras);
startActivity(intent);
- finish();
break;
- case BoardBookmarksFragment.INTERACTION_TOGGLE_BOARD_NOTIFICATION:
+ case BookmarksBoardFragment.INTERACTION_TOGGLE_BOARD_NOTIFICATION:
return toggleNotification(bookmarkedBoard);
- case BoardBookmarksFragment.INTERACTION_REMOVE_BOARD_BOOKMARK:
+ case BookmarksBoardFragment.INTERACTION_REMOVE_BOARD_BOOKMARK:
removeBookmark(bookmarkedBoard);
- Toast.makeText(BookmarkActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show();
+ Toast.makeText(BookmarksActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show();
break;
}
return true;
@@ -110,7 +110,7 @@ public class BookmarkActivity extends BaseActivity {
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages. If it becomes too memory intensive,
* it may be best to switch to a
- * {@link android.support.v4.app.FragmentStatePagerAdapter}.
+ * {@link FragmentStatePagerAdapter}.
*/
private class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List fragmentList = new ArrayList<>();
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BoardBookmarksFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java
similarity index 78%
rename from app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BoardBookmarksFragment.java
rename to app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java
index 6c7db47f..a73bbe6a 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BoardBookmarksFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java
@@ -5,9 +5,6 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.graphics.drawable.VectorDrawableCompat;
-import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -17,30 +14,32 @@ import android.widget.TextView;
import java.util.ArrayList;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.model.Bookmark;
/**
* A {@link Fragment} subclass.
- * Use the {@link BoardBookmarksFragment#newInstance} factory method to
+ * Use the {@link BookmarksBoardFragment#newInstance} factory method to
* create an instance of this fragment.
*/
-public class BoardBookmarksFragment extends Fragment {
- protected static final String ARG_SECTION_NUMBER = "SECTION_NUMBER";
- protected static final String ARG_BOARD_BOOKMARKS = "BOARD_BOOKMARKS";
+public class BookmarksBoardFragment extends Fragment {
+ private static final String ARG_SECTION_NUMBER = "SECTION_NUMBER";
+ private static final String ARG_BOARD_BOOKMARKS = "BOARD_BOOKMARKS";
- public static final String INTERACTION_CLICK_BOARD_BOOKMARK = "CLICK_BOARD_BOOKMARK";
- public static final String INTERACTION_TOGGLE_BOARD_NOTIFICATION = "TOGGLE_BOARD_NOTIFICATION";
- public static final String INTERACTION_REMOVE_BOARD_BOOKMARK= "REMOVE_BOARD_BOOKMARK";
+ static final String INTERACTION_CLICK_BOARD_BOOKMARK = "CLICK_BOARD_BOOKMARK";
+ static final String INTERACTION_TOGGLE_BOARD_NOTIFICATION = "TOGGLE_BOARD_NOTIFICATION";
+ static final String INTERACTION_REMOVE_BOARD_BOOKMARK= "REMOVE_BOARD_BOOKMARK";
- ArrayList boardBookmarks = null;
+ private ArrayList boardBookmarks = null;
private static Drawable notificationsEnabledButtonImage;
private static Drawable notificationsDisabledButtonImage;
// Required empty public constructor
- public BoardBookmarksFragment() {
- }
+ public BookmarksBoardFragment() { }
/**
* Use ONLY this factory method to create a new instance of
@@ -48,8 +47,8 @@ public class BoardBookmarksFragment extends Fragment {
*
* @return A new instance of fragment Forum.
*/
- public static BoardBookmarksFragment newInstance(int sectionNumber, String boardBookmarks) {
- BoardBookmarksFragment fragment = new BoardBookmarksFragment();
+ public static BookmarksBoardFragment newInstance(int sectionNumber, String boardBookmarks) {
+ BookmarksBoardFragment fragment = new BookmarksBoardFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putString(ARG_BOARD_BOOKMARKS, boardBookmarks);
@@ -93,8 +92,8 @@ public class BoardBookmarksFragment extends Fragment {
R.layout.fragment_bookmarks_row, bookmarksLinearView, false);
row.setOnClickListener(view -> {
Activity activity = getActivity();
- if (activity instanceof BookmarkActivity){
- ((BookmarkActivity) activity).onBoardInteractionListener(INTERACTION_CLICK_BOARD_BOOKMARK, bookmarkedBoard);
+ if (activity instanceof BookmarksActivity){
+ ((BookmarksActivity) activity).onBoardInteractionListener(INTERACTION_CLICK_BOARD_BOOKMARK, bookmarkedBoard);
}
});
((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedBoard.getTitle());
@@ -106,8 +105,8 @@ public class BoardBookmarksFragment extends Fragment {
notificationsEnabledButton.setOnClickListener(view -> {
Activity activity = getActivity();
- if (activity instanceof BookmarkActivity) {
- if (((BookmarkActivity) activity).onBoardInteractionListener(INTERACTION_TOGGLE_BOARD_NOTIFICATION, bookmarkedBoard)) {
+ if (activity instanceof BookmarksActivity) {
+ if (((BookmarksActivity) activity).onBoardInteractionListener(INTERACTION_TOGGLE_BOARD_NOTIFICATION, bookmarkedBoard)) {
notificationsEnabledButton.setImageDrawable(notificationsEnabledButtonImage);
} else {
notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage);
@@ -117,8 +116,8 @@ public class BoardBookmarksFragment extends Fragment {
(row.findViewById(R.id.remove_bookmark)).setOnClickListener(view -> {
Activity activity = getActivity();
- if (activity instanceof BookmarkActivity){
- ((BookmarkActivity) activity).onBoardInteractionListener(INTERACTION_REMOVE_BOARD_BOOKMARK, bookmarkedBoard);
+ if (activity instanceof BookmarksActivity){
+ ((BookmarksActivity) activity).onBoardInteractionListener(INTERACTION_REMOVE_BOARD_BOOKMARK, bookmarkedBoard);
boardBookmarks.remove(bookmarkedBoard);
}
row.setVisibility(View.GONE);
@@ -130,10 +129,8 @@ public class BoardBookmarksFragment extends Fragment {
bookmarksLinearView.addView(row);
}
}
- } else {
-
+ } else
bookmarksLinearView.addView(bookmarksListEmptyMessage());
- }
return rootView;
}
@@ -146,9 +143,9 @@ public class BoardBookmarksFragment extends Fragment {
emptyBookmarksCategory.setLayoutParams(params);
emptyBookmarksCategory.setText(getString(R.string.empty_board_bookmarks));
emptyBookmarksCategory.setTypeface(emptyBookmarksCategory.getTypeface(), Typeface.BOLD);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
emptyBookmarksCategory.setTextColor(this.getContext().getColor(R.color.primary_text));
- } else {
+ else {
//noinspection deprecation
emptyBookmarksCategory.setTextColor(this.getContext().getResources().getColor(R.color.primary_text));
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/TopicBookmarksFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java
similarity index 80%
rename from app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/TopicBookmarksFragment.java
rename to app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java
index 54659baa..5c6232b7 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/TopicBookmarksFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java
@@ -5,9 +5,6 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.graphics.drawable.VectorDrawableCompat;
-import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -17,21 +14,24 @@ import android.widget.TextView;
import java.util.ArrayList;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.model.Bookmark;
/**
* A {@link Fragment} subclass.
- * Use the {@link TopicBookmarksFragment#newInstance} factory method to
+ * Use the {@link BookmarksTopicFragment#newInstance} factory method to
* create an instance of this fragment.
*/
-public class TopicBookmarksFragment extends Fragment {
- protected static final String ARG_SECTION_NUMBER = "SECTION_NUMBER";
- protected static final String ARG_TOPIC_BOOKMARKS = "TOPIC_BOOKMARKS";
+public class BookmarksTopicFragment extends Fragment {
+ private static final String ARG_SECTION_NUMBER = "SECTION_NUMBER";
+ private static final String ARG_TOPIC_BOOKMARKS = "TOPIC_BOOKMARKS";
- public static final String INTERACTION_CLICK_TOPIC_BOOKMARK = "CLICK_TOPIC_BOOKMARK";
- public static final String INTERACTION_TOGGLE_TOPIC_NOTIFICATION = "TOGGLE_TOPIC_NOTIFICATION";
- public static final String INTERACTION_REMOVE_TOPIC_BOOKMARK = "REMOVE_TOPIC_BOOKMARK";
+ static final String INTERACTION_CLICK_TOPIC_BOOKMARK = "CLICK_TOPIC_BOOKMARK";
+ static final String INTERACTION_TOGGLE_TOPIC_NOTIFICATION = "TOGGLE_TOPIC_NOTIFICATION";
+ static final String INTERACTION_REMOVE_TOPIC_BOOKMARK = "REMOVE_TOPIC_BOOKMARK";
ArrayList topicBookmarks = null;
@@ -39,7 +39,7 @@ public class TopicBookmarksFragment extends Fragment {
private static Drawable notificationsDisabledButtonImage;
// Required empty public constructor
- public TopicBookmarksFragment() {
+ public BookmarksTopicFragment() {
}
/**
@@ -48,8 +48,8 @@ public class TopicBookmarksFragment extends Fragment {
*
* @return A new instance of fragment Forum.
*/
- public static TopicBookmarksFragment newInstance(int sectionNumber, String topicBookmarks) {
- TopicBookmarksFragment fragment = new TopicBookmarksFragment();
+ public static BookmarksTopicFragment newInstance(int sectionNumber, String topicBookmarks) {
+ BookmarksTopicFragment fragment = new BookmarksTopicFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putString(ARG_TOPIC_BOOKMARKS, topicBookmarks);
@@ -93,8 +93,8 @@ public class TopicBookmarksFragment extends Fragment {
R.layout.fragment_bookmarks_row, bookmarksLinearView, false);
row.setOnClickListener(view -> {
Activity activity = getActivity();
- if (activity instanceof BookmarkActivity) {
- ((BookmarkActivity) activity).onTopicInteractionListener(INTERACTION_CLICK_TOPIC_BOOKMARK, bookmarkedTopic);
+ if (activity instanceof BookmarksActivity) {
+ ((BookmarksActivity) activity).onTopicInteractionListener(INTERACTION_CLICK_TOPIC_BOOKMARK, bookmarkedTopic);
}
});
((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedTopic.getTitle());
@@ -106,8 +106,8 @@ public class TopicBookmarksFragment extends Fragment {
notificationsEnabledButton.setOnClickListener(view -> {
Activity activity = getActivity();
- if (activity instanceof BookmarkActivity) {
- if (((BookmarkActivity) activity).onTopicInteractionListener(INTERACTION_TOGGLE_TOPIC_NOTIFICATION, bookmarkedTopic)) {
+ if (activity instanceof BookmarksActivity) {
+ if (((BookmarksActivity) activity).onTopicInteractionListener(INTERACTION_TOGGLE_TOPIC_NOTIFICATION, bookmarkedTopic)) {
notificationsEnabledButton.setImageDrawable(notificationsEnabledButtonImage);
} else {
notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage);
@@ -116,8 +116,8 @@ public class TopicBookmarksFragment extends Fragment {
});
(row.findViewById(R.id.remove_bookmark)).setOnClickListener(view -> {
Activity activity = getActivity();
- if (activity instanceof BookmarkActivity) {
- ((BookmarkActivity) activity).onTopicInteractionListener(INTERACTION_REMOVE_TOPIC_BOOKMARK, bookmarkedTopic);
+ if (activity instanceof BookmarksActivity) {
+ ((BookmarksActivity) activity).onTopicInteractionListener(INTERACTION_REMOVE_TOPIC_BOOKMARK, bookmarkedTopic);
topicBookmarks.remove(bookmarkedTopic);
}
row.setVisibility(View.GONE);
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java
index b770b7b5..920a03b9 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java
@@ -4,13 +4,14 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.design.widget.TextInputLayout;
import android.text.InputType;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Toast;
+import com.google.android.material.textfield.TextInputLayout;
+
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.settings.SettingsActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java
index 076cefe9..addccf35 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java
@@ -1,14 +1,8 @@
package gr.thmmy.mthmmy.activities.downloads;
-import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.Menu;
-import android.view.MenuItem;
import android.widget.ProgressBar;
import android.widget.Toast;
@@ -19,8 +13,10 @@ import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.Objects;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
-import gr.thmmy.mthmmy.activities.upload.UploadActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.model.Download;
@@ -33,8 +29,6 @@ import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
-import static gr.thmmy.mthmmy.activities.upload.UploadActivity.BUNDLE_UPLOAD_CATEGORY;
-
public class DownloadsActivity extends BaseActivity implements DownloadsAdapter.OnLoadMoreListener {
/**
* The key to use when putting download's url String to {@link DownloadsActivity}'s Bundle.
@@ -124,7 +118,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter.
// uploadFAB.hide();
parseDownloadPageTask = new ParseDownloadPageTask();
- parseDownloadPageTask.execute(downloadsUrl);
+ parseDownloadPageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, downloadsUrl);
}
// @Override
@@ -160,9 +154,9 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter.
//Load data
parseDownloadPageTask = new ParseDownloadPageTask();
if (downloadsUrl.contains("tpstart"))
- parseDownloadPageTask.execute(downloadsUrl.substring(0
+ parseDownloadPageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, downloadsUrl.substring(0
, downloadsUrl.lastIndexOf(";tpstart=")) + ";tpstart=" + pagesLoaded * 10);
- else parseDownloadPageTask.execute(downloadsUrl + ";tpstart=" + pagesLoaded * 10);
+ else parseDownloadPageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, downloadsUrl + ";tpstart=" + pagesLoaded * 10);
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java
index 34a583e0..5b6ec26e 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java
@@ -5,7 +5,6 @@ import android.content.Intent;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -18,6 +17,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Objects;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.Download;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
index 67f99897..af1a4cf2 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
@@ -3,18 +3,22 @@ package gr.thmmy.mthmmy.activities.main;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.support.v7.preference.PreferenceManager;
import android.widget.Toast;
+import com.google.android.material.tabs.TabLayout;
+
import java.util.ArrayList;
import java.util.List;
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+import androidx.preference.PreferenceManager;
+import androidx.viewpager.widget.ViewPager;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.board.BoardActivity;
@@ -23,6 +27,7 @@ import gr.thmmy.mthmmy.activities.main.forum.ForumFragment;
import gr.thmmy.mthmmy.activities.main.recent.RecentFragment;
import gr.thmmy.mthmmy.activities.main.unread.UnreadFragment;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
+import gr.thmmy.mthmmy.activities.settings.SettingsActivity;
import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.Board;
@@ -37,7 +42,6 @@ import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWN
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME;
-import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DEFAULT_HOME_TAB;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
@@ -50,6 +54,14 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
private long mBackPressed;
private SectionsPagerAdapter sectionsPagerAdapter;
private ViewPager viewPager;
+ private TabLayout tabLayout;
+
+ //Fix for vector drawables on android <21
+ static {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
+ }
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -67,11 +79,15 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
startActivity(intent);
finish();
overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
+ return; //Avoid executing the code below
}
//Initialize drawer
createDrawer();
+ tabLayout = findViewById(R.id.tabs);
+ viewPager = findViewById(R.id.container);
+
//Create the adapter that will return a fragment for each section of the activity
sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
sectionsPagerAdapter.addFragment(RecentFragment.newInstance(1), "RECENT");
@@ -80,17 +96,16 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
sectionsPagerAdapter.addFragment(UnreadFragment.newInstance(3), "UNREAD");
//Set up the ViewPager with the sections adapter.
- viewPager = findViewById(R.id.container);
viewPager.setAdapter(sectionsPagerAdapter);
-
- TabLayout tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- int preferredTab = Integer.parseInt(sharedPrefs.getString(DEFAULT_HOME_TAB, "0"));
- if (preferredTab != 3 || sessionManager.isLoggedIn()) {
+ int preferredTab = Integer.parseInt(sharedPrefs.getString(SettingsActivity.DEFAULT_HOME_TAB, "0"));
+ if ((preferredTab != 3 && preferredTab != 4) || sessionManager.isLoggedIn())
tabLayout.getTabAt(preferredTab).select();
- }
+
+ for (int i = 0; i < tabLayout.getTabCount(); i++)
+ updateTabIcon(i);
setMainActivity(this);
}
@@ -105,7 +120,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
@Override
protected void onResume() {
drawer.setSelection(HOME_ID);
- if(!sharedPrefs.getBoolean(DRAWER_INTRO, false)){
+ if (!sharedPrefs.getBoolean(DRAWER_INTRO, false)) {
drawer.openDrawer();
sharedPrefs.edit().putBoolean(DRAWER_INTRO, true).apply();
}
@@ -133,6 +148,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
Intent i = new Intent(MainActivity.this, TopicActivity.class);
i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl());
i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getSubject());
+ i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
}
@@ -150,6 +166,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
Intent i = new Intent(MainActivity.this, TopicActivity.class);
i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl());
i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getSubject());
+ i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
} else
Timber.e("onUnreadFragmentInteraction TopicSummary came without a link");
@@ -161,7 +178,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages. If it becomes too memory intensive,
* it may be best to switch to a
- * {@link android.support.v4.app.FragmentStatePagerAdapter}.
+ * {@link FragmentStatePagerAdapter}.
*/
private class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List fragmentList = new ArrayList<>();
@@ -175,9 +192,11 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
fragmentList.add(fragment);
fragmentTitleList.add(title);
notifyDataSetChanged();
+ updateTabIcon(fragmentList.size() - 1);
}
void removeFragment(int position) {
+ getSupportFragmentManager().beginTransaction().remove(fragmentList.get(position)).commit();
fragmentList.remove(position);
fragmentTitleList.remove(position);
notifyDataSetChanged();
@@ -208,11 +227,25 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
}
}
+ public void updateTabIcon(int position) {
+ if (position >= tabLayout.getTabCount()) return;
+ if (position == 0)
+ tabLayout.getTabAt(0).setIcon(getResources().getDrawable(R.drawable.ic_access_time_white_24dp));
+ else if (position == 1)
+ tabLayout.getTabAt(1).setIcon(getResources().getDrawable(R.drawable.ic_forum_white_24dp));
+ else if (position == 2)
+ tabLayout.getTabAt(2).setIcon(getResources().getDrawable(R.drawable.ic_fiber_new_white_24dp));
+ }
+
+
public void updateTabs() {
if (!sessionManager.isLoggedIn() && sectionsPagerAdapter.getCount() == 3)
sectionsPagerAdapter.removeFragment(2);
else if (sessionManager.isLoggedIn() && sectionsPagerAdapter.getCount() == 2)
sectionsPagerAdapter.addFragment(UnreadFragment.newInstance(3), "UNREAD");
+
+ for (int i = 0; i < tabLayout.getTabCount(); i++)
+ updateTabIcon(i);
}
//-------------------------------FragmentPagerAdapter END-------------------------------------------
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java
index 5b2f4c93..718c1b8d 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java
@@ -1,8 +1,6 @@
package gr.thmmy.mthmmy.activities.main.forum;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -14,6 +12,8 @@ import com.bignerdranch.expandablerecyclerview.ParentViewHolder;
import java.util.List;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.Board;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
index a85eca23..70e78af5 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
@@ -2,9 +2,6 @@ package gr.thmmy.mthmmy.activities.main.forum;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -22,6 +19,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
@@ -90,7 +90,7 @@ public class ForumFragment extends BaseFragment {
super.onActivityCreated(savedInstanceState);
if (categories.isEmpty()) {
forumTask = new ForumTask(this::onForumTaskStarted, this::onForumTaskFinished);
- forumTask.execute();
+ forumTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
Timber.d("onActivityCreated");
@@ -114,7 +114,7 @@ public class ForumFragment extends BaseFragment {
forumTask.cancel(true);
forumTask = new ForumTask(ForumFragment.this::onForumTaskStarted, ForumFragment.this::onForumTaskFinished);
forumTask.setUrl(categories.get(parentPosition).getCategoryURL());
- forumTask.execute();
+ forumTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@@ -125,7 +125,7 @@ public class ForumFragment extends BaseFragment {
forumTask.cancel(true);
forumTask = new ForumTask(ForumFragment.this::onForumTaskStarted, ForumFragment.this::onForumTaskFinished);
forumTask.setUrl(categories.get(parentPosition).getCategoryURL());
- forumTask.execute();
+ forumTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
});
@@ -145,7 +145,7 @@ public class ForumFragment extends BaseFragment {
if (forumTask != null && forumTask.getStatus() != AsyncTask.Status.RUNNING) {
forumTask = new ForumTask(ForumFragment.this::onForumTaskStarted, ForumFragment.this::onForumTaskFinished);
//forumTask.execute(SessionManager.indexUrl.toString());
- forumTask.execute();
+ forumTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
);
@@ -176,6 +176,9 @@ public class ForumFragment extends BaseFragment {
forumAdapter.notifyParentDataSetChanged(false);
} else if (resultCode == NetworkResultCodes.NETWORK_ERROR) {
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Network error", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Unexpected error," +
+ " please contact the developers with the details", Toast.LENGTH_LONG).show();
}
progressBar.setVisibility(ProgressBar.INVISIBLE);
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java
index de128cb1..31871069 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java
@@ -1,8 +1,6 @@
package gr.thmmy.mthmmy.activities.main.recent;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,6 +8,8 @@ import android.widget.TextView;
import java.util.List;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
index 65b0d315..6c194c0e 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
@@ -2,9 +2,6 @@ package gr.thmmy.mthmmy.activities.main.recent;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,8 +17,10 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import gr.thmmy.mthmmy.R;
-import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.session.SessionManager;
@@ -55,8 +54,7 @@ public class RecentFragment extends BaseFragment {
private RecentTask recentTask;
// Required empty public constructor
- public RecentFragment() {
- }
+ public RecentFragment() {}
/**
* Use ONLY this factory method to create a new instance of
@@ -84,7 +82,7 @@ public class RecentFragment extends BaseFragment {
super.onActivityCreated(savedInstanceState);
if (topicSummaries.isEmpty()) {
recentTask = new RecentTask(this::onRecentTaskStarted, this::onRecentTaskFinished);
- recentTask.execute(SessionManager.indexUrl.toString());
+ recentTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.indexUrl.toString());
}
Timber.d("onActivityCreated");
@@ -114,9 +112,9 @@ public class RecentFragment extends BaseFragment {
swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.primary);
swipeRefreshLayout.setColorSchemeResources(R.color.accent);
swipeRefreshLayout.setOnRefreshListener(() -> {
- if (recentTask != null && recentTask.getStatus() != AsyncTask.Status.RUNNING) {
+ if (!recentTask.isRunning()) {
recentTask = new RecentTask(this::onRecentTaskStarted, this::onRecentTaskFinished);
- recentTask.execute(SessionManager.indexUrl.toString());
+ recentTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.indexUrl.toString());
}
}
);
@@ -128,7 +126,7 @@ public class RecentFragment extends BaseFragment {
@Override
public void onDestroy() {
super.onDestroy();
- if (recentTask != null && recentTask.getStatus() != AsyncTask.Status.RUNNING)
+ if (recentTask.isRunning())
recentTask.cancel(true);
}
@@ -147,7 +145,10 @@ public class RecentFragment extends BaseFragment {
topicSummaries.addAll(fetchedRecent);
recentAdapter.notifyDataSetChanged();
} else if (resultCode == NetworkResultCodes.NETWORK_ERROR) {
- Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Network error", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(getContext(), "Unexpected error," +
+ " please contact the developers with the details", Toast.LENGTH_LONG).show();
}
progressBar.setVisibility(ProgressBar.INVISIBLE);
@@ -157,8 +158,8 @@ public class RecentFragment extends BaseFragment {
//---------------------------------------ASYNC TASK-----------------------------------
private class RecentTask extends NewParseTask> {
- public RecentTask(OnTaskStartedListener onTaskStartedListener,
- OnNetworkTaskFinishedListener> onParseTaskFinishedListener) {
+ RecentTask(OnTaskStartedListener onTaskStartedListener,
+ OnNetworkTaskFinishedListener> onParseTaskFinishedListener) {
super(onTaskStartedListener, onParseTaskFinishedListener);
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java
index 65100922..8810da1a 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java
@@ -1,7 +1,5 @@
package gr.thmmy.mthmmy.activities.main.unread;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -9,6 +7,8 @@ import android.widget.TextView;
import java.util.List;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
index 0747b4bf..0c47bac5 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
@@ -1,11 +1,8 @@
+
package gr.thmmy.mthmmy.activities.main.unread;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -21,8 +18,11 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import gr.thmmy.mthmmy.R;
-import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.session.SessionManager;
@@ -59,8 +59,7 @@ public class UnreadFragment extends BaseFragment {
private MarkReadTask markReadTask;
// Required empty public constructor
- public UnreadFragment() {
- }
+ public UnreadFragment() {}
/**
* Use ONLY this factory method to create a new instance of
@@ -89,7 +88,7 @@ public class UnreadFragment extends BaseFragment {
if (topicSummaries.isEmpty()) {
unreadTask = new UnreadTask(this::onUnreadTaskStarted, this::onUnreadTaskFinished);
assert SessionManager.unreadUrl != null;
- unreadTask.execute(SessionManager.unreadUrl.toString());
+ unreadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.unreadUrl.toString());
}
markReadTask = new MarkReadTask();
Timber.d("onActivityCreated");
@@ -107,11 +106,11 @@ public class UnreadFragment extends BaseFragment {
progressBar = rootView.findViewById(R.id.progressBar);
unreadAdapter = new UnreadAdapter(topicSummaries,
fragmentInteractionListener, markReadLinkUrl -> {
- if (markReadTask != null && markReadTask.getStatus() != AsyncTask.Status.RUNNING) {
- markReadTask = new MarkReadTask();
- markReadTask.execute(markReadLinkUrl);
- }
- });
+ if (!markReadTask.isRunning() && !unreadTask.isRunning()) {
+ markReadTask = new MarkReadTask();
+ markReadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, markReadLinkUrl);
+ }
+ });
CustomRecyclerView recyclerView = rootView.findViewById(R.id.list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(recyclerView.getContext());
@@ -126,13 +125,12 @@ public class UnreadFragment extends BaseFragment {
swipeRefreshLayout.setColorSchemeResources(R.color.accent);
swipeRefreshLayout.setOnRefreshListener(
() -> {
- if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) {
- topicSummaries.clear();
+ if (!unreadTask.isRunning()) {
numberOfPages = 0;
loadedPages = 0;
unreadTask = new UnreadTask(this::onUnreadTaskStarted, this::onUnreadTaskFinished);
assert SessionManager.unreadUrl != null;
- unreadTask.execute(SessionManager.unreadUrl.toString());
+ unreadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.unreadUrl.toString());
}
}
);
@@ -144,10 +142,11 @@ public class UnreadFragment extends BaseFragment {
@Override
public void onDestroy() {
super.onDestroy();
- if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING)
+ if (unreadTask.isRunning())
unreadTask.cancel(true);
- if (markReadTask != null && markReadTask.getStatus() != AsyncTask.Status.RUNNING)
+ if (markReadTask.isRunning())
markReadTask.cancel(true);
+ topicSummaries.clear();
}
public interface UnreadFragmentInteractionListener extends FragmentInteractionListener {
@@ -160,15 +159,19 @@ public class UnreadFragment extends BaseFragment {
progressBar.setVisibility(ProgressBar.VISIBLE);
}
- private void onUnreadTaskFinished(int resultCode, Void data) {
+ private void onUnreadTaskFinished(int resultCode, ArrayList fetchedUnread) {
if (resultCode == NetworkResultCodes.SUCCESSFUL) {
- unreadAdapter.notifyDataSetChanged();
-
- ++loadedPages;
+ if(fetchedUnread!=null && !fetchedUnread.isEmpty()){
+ if(loadedPages==0)
+ topicSummaries.clear();
+ topicSummaries.addAll(fetchedUnread);
+ unreadAdapter.notifyDataSetChanged();
+ }
+ loadedPages++;
if (loadedPages < numberOfPages) {
unreadTask = new UnreadTask(this::onUnreadTaskStarted, this::onUnreadTaskFinished);
assert SessionManager.unreadUrl != null;
- unreadTask.execute(SessionManager.unreadUrl.toString() + ";start=" + loadedPages * 20);
+ unreadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.unreadUrl.toString() + ";start=" + loadedPages * 20);
}
else {
progressBar.setVisibility(ProgressBar.INVISIBLE);
@@ -179,19 +182,23 @@ public class UnreadFragment extends BaseFragment {
progressBar.setVisibility(ProgressBar.INVISIBLE);
swipeRefreshLayout.setRefreshing(false);
if (resultCode == NetworkResultCodes.NETWORK_ERROR)
- Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Network error", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
+ else
+ Toast.makeText(getContext(), "Unexpected error," +
+ " please contact the developers with the details", Toast.LENGTH_LONG).show();
}
}
- private class UnreadTask extends NewParseTask {
+ private class UnreadTask extends NewParseTask> {
- UnreadTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
+ UnreadTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener> onParseTaskFinishedListener) {
super(onTaskStartedListener, onParseTaskFinishedListener);
}
@Override
- protected Void parse(Document document, Response response) throws ParseException {
+ protected ArrayList parse(Document document, Response response) throws ParseException {
Elements unread = document.select("table.bordercolor[cellspacing=1] tr:not(.titlebg)");
+ ArrayList fetchedTopicSummaries = new ArrayList<>();
if (!unread.isEmpty()) {
//topicSummaries.clear();
for (Element row : unread) {
@@ -207,16 +214,14 @@ public class UnreadFragment extends BaseFragment {
dateTime = dateTime.replace("", "");
dateTime = dateTime.replace("", "");
if (dateTime.contains(" am") || dateTime.contains(" pm") ||
- dateTime.contains(" πμ") || dateTime.contains(" μμ")) {
+ dateTime.contains(" πμ") || dateTime.contains(" μμ"))
dateTime = dateTime.replaceAll(":[0-5][0-9] ", " ");
- } else {
+ else
dateTime = dateTime.substring(0, dateTime.lastIndexOf(":"));
- }
- if (!dateTime.contains(",")) {
+ if (!dateTime.contains(","))
dateTime = dateTime.replaceAll(".+? ([0-9])", "$1");
- }
- topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime));
+ fetchedTopicSummaries.add(new TopicSummary(link, title, lastUser, dateTime));
}
Element topBar = document.select("table:not(.bordercolor):not(#bodyarea):has(td.middletext)").first();
@@ -230,31 +235,29 @@ public class UnreadFragment extends BaseFragment {
if (numberOfPages == 0 && pagesElement != null) {
Elements pages = pagesElement.select("a");
- if (!pages.isEmpty()) {
+ if (!pages.isEmpty())
numberOfPages = Integer.parseInt(pages.last().text());
- } else {
+ else
numberOfPages = 1;
- }
}
if (markRead != null && loadedPages == numberOfPages - 1)
- topicSummaries.add(new TopicSummary(markRead.attr("href"), markRead.text(), null,
+ fetchedTopicSummaries.add(new TopicSummary(markRead.attr("href"), markRead.text(), null,
null));
} else {
- topicSummaries.clear();
String message = document.select("table.bordercolor[cellspacing=1]").first().text();
if (message.contains("No messages")) { //It's english
message = "No unread posts!";
} else { //It's greek
- message = "Δεν υπάρχουν μη διαβασμένα μηνύματα!";
+ message = "Δεν υπάρχουν μη αναγνωσμένα μηνύματα!";
}
- topicSummaries.add(new TopicSummary(null, null, null, message));
+ fetchedTopicSummaries.add(new TopicSummary(null, null, null, message));
}
- return null;
+ return fetchedTopicSummaries;
}
@Override
- protected int getResultCode(Response response, Void data) {
+ protected int getResultCode(Response response, ArrayList data) {
return NetworkResultCodes.SUCCESSFUL;
}
}
@@ -298,12 +301,19 @@ public class UnreadFragment extends BaseFragment {
Toast.makeText(getContext()
, "Fatal error!\n Task aborted...", Toast.LENGTH_LONG).show();
} else {
- if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) {
+ if (!unreadTask.isRunning()) {
+ numberOfPages = 0;
+ loadedPages = 0;
unreadTask = new UnreadTask(UnreadFragment.this::onUnreadTaskStarted, UnreadFragment.this::onUnreadTaskFinished);
assert SessionManager.unreadUrl != null;
- unreadTask.execute(SessionManager.unreadUrl.toString());
+ unreadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.unreadUrl.toString());
}
}
}
+
+ //TODO: Maybe extend this task and use isRunning() from ExternalAsyncTask instead (?)
+ public boolean isRunning(){
+ return getStatus() == AsyncTask.Status.RUNNING;
+ }
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
index 19680329..247365c8 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
@@ -7,14 +7,6 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.TabLayout;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.content.res.ResourcesCompat;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.AppCompatDelegate;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -26,6 +18,8 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.tabs.TabLayout;
import com.squareup.picasso.Picasso;
import org.jsoup.Jsoup;
@@ -37,8 +31,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import javax.net.ssl.SSLHandshakeException;
-
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.viewpager.widget.ViewPager;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment;
import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment;
@@ -49,8 +47,11 @@ import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.utils.CenterVerticalSpan;
import gr.thmmy.mthmmy.utils.CircleTransform;
+import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.Parcel;
+import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
+import gr.thmmy.mthmmy.utils.parsing.ParseException;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
@@ -78,10 +79,9 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
* If username is not available put an empty string or leave it null.
*/
public static final String BUNDLE_PROFILE_USERNAME = "USERNAME";
- private static final int THUMBNAIL_SIZE = 200;
private TextView usernameView;
- private ImageView thumbnailView;
+ private ImageView avatarView;
private TextView personalTextView;
private MaterialProgressBar progressBar;
private FloatingActionButton pmFAB;
@@ -90,7 +90,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
private ProfileTask profileTask;
private String personalText;
private String profileUrl;
- private String thumbnailUrl;
+ private String avatarUrl;
private String username;
private int tabSelect;
@@ -107,8 +107,8 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
setContentView(R.layout.activity_profile);
Bundle extras = getIntent().getExtras();
- thumbnailUrl = extras.getString(BUNDLE_PROFILE_THUMBNAIL_URL);
- if (thumbnailUrl == null) thumbnailUrl = "";
+ avatarUrl = extras.getString(BUNDLE_PROFILE_THUMBNAIL_URL);
+ if (avatarUrl == null) avatarUrl = "";
username = extras.getString(BUNDLE_PROFILE_USERNAME);
profileUrl = extras.getString(BUNDLE_PROFILE_URL);
@@ -125,19 +125,12 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
progressBar = findViewById(R.id.progressBar);
- thumbnailView = findViewById(R.id.user_thumbnail);
- if (!Objects.equals(thumbnailUrl, ""))
+ avatarView = findViewById(R.id.user_thumbnail);
+ if (!Objects.equals(avatarUrl, ""))
//noinspection ConstantConditions
- Picasso.with(this)
- .load(thumbnailUrl)
- .resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
- .centerCrop()
- .error(ResourcesCompat.getDrawable(this.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .placeholder(ResourcesCompat.getDrawable(this.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .transform(new CircleTransform())
- .into(thumbnailView);
+ loadAvatar();
+ else
+ loadDefaultAvatar();
usernameView = findViewById(R.id.profile_activity_username);
usernameView.setTypeface(Typeface.createFromAsset(this.getAssets()
, "fonts/fontawesome-webfont.ttf"));
@@ -194,7 +187,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
}
profileTask = new ProfileTask();
- profileTask.execute(profileUrl); //Attempts data parsing
+ profileTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileUrl + ";wap"); //Attempts data parsing
}
@Override
@@ -213,6 +206,37 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
startActivity(i);
}
+ public void onProfileTaskStarted() {
+ progressBar.setVisibility(ProgressBar.VISIBLE);
+ if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(false);
+ }
+
+ private void loadAvatar(){
+ Picasso.with(this)
+ .load(avatarUrl)
+ .fit()
+ .centerCrop()
+ .error(Objects.requireNonNull(ResourcesCompat.getDrawable(this.getResources()
+ , R.drawable.ic_default_user_avatar, null)))
+ .placeholder(Objects.requireNonNull(ResourcesCompat.getDrawable(this.getResources()
+ , R.drawable.ic_default_user_avatar, null)))
+ .transform(new CircleTransform())
+ .into(avatarView);
+ }
+
+ private void loadDefaultAvatar(){
+ Picasso.with(this)
+ .load(R.drawable.ic_default_user_avatar)
+ .fit()
+ .centerCrop()
+ .error(Objects.requireNonNull(ResourcesCompat.getDrawable(this.getResources()
+ , R.drawable.ic_default_user_avatar, null)))
+ .placeholder(Objects.requireNonNull(ResourcesCompat.getDrawable(this.getResources()
+ , R.drawable.ic_default_user_avatar, null)))
+ .transform(new CircleTransform())
+ .into(avatarView);
+ }
+
/**
* An {@link AsyncTask} that handles asynchronous fetching of a profile page and parsing this
* user's personal text. The {@link Document} resulting from the parse is stored for use in
@@ -222,120 +246,108 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
*
* @see Jsoup
*/
- public class ProfileTask extends AsyncTask {
+ public class ProfileTask extends NewParseTask {
//Class variables
Document profilePage;
Spannable usernameSpan;
Boolean isOnline = false;
- protected void onPreExecute() {
- progressBar.setVisibility(ProgressBar.VISIBLE);
- if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(false);
+ ProfileTask() {
+ super(ProfileActivity.this::onProfileTaskStarted, null);
}
- protected Boolean doInBackground(String... profileUrl) {
- String pageUrl = profileUrl[0] + ";wap"; //Profile's page wap url
-
- Request request = new Request.Builder()
- .url(pageUrl)
- .build();
- try {
- Response response = client.newCall(request).execute();
- profilePage = Jsoup.parse(response.body().string());
- Elements contentsTable = profilePage.
- select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) tbody");
-
- //Finds username if missing
- if (username == null || Objects.equals(username, "")) {
- username = contentsTable.select("tr").first().select("td").last().text();
- }
- if (thumbnailUrl == null || Objects.equals(thumbnailUrl, "")) { //Maybe there is an avatar
- Element profileAvatar = profilePage.select("img.avatar").first();
- if (profileAvatar != null) thumbnailUrl = profileAvatar.attr("abs:src");
- }
- { //Finds personal text
- Element tmpEl = profilePage.select("td.windowbg:nth-child(2)").first();
- if (tmpEl != null) {
- personalText = tmpEl.text().trim();
- } else {
- //Should never get here!
- //Something is wrong.
- Timber.e("An error occurred while trying to find profile's personal text.");
- personalText = null;
- }
+ @Override
+ protected Void parse(Document document, Response response) throws ParseException {
+ profilePage = document;
+ Elements contentsTable = profilePage.
+ select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) tbody");
+
+ //Finds username if missing
+ if (username == null || Objects.equals(username, "")) {
+ username = contentsTable.select("tr").first().select("td").last().text();
+ }
+ if (avatarUrl == null || Objects.equals(avatarUrl, "")) { //Maybe there is an avatar
+ Element profileAvatar = profilePage.select("img.avatar").first();
+ if (profileAvatar != null) avatarUrl = profileAvatar.attr("abs:src");
+ }
+ { //Finds personal text
+ Element tmpEl = profilePage.select("td.windowbg:nth-child(2)").first();
+ if (tmpEl != null) {
+ personalText = tmpEl.text().trim();
+ } else {
+ //Should never get here!
+ //Something is wrong.
+ Timber.e("An error occurred while trying to find profile's personal text.");
+ personalText = null;
}
- { //Finds status
- usernameSpan = new SpannableString(getResources()
- .getString(R.string.fa_circle) + " " + username);
- usernameSpan.setSpan(new CenterVerticalSpan(), 0, 2,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- usernameSpan.setSpan(new RelativeSizeSpan(0.45f)
- , 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-
- if (contentsTable.toString().contains("Online")
- || contentsTable.toString().contains("Συνδεδεμένος")) {
- isOnline = true;
+ }
+ { //Finds status
+ usernameSpan = new SpannableString(getResources()
+ .getString(R.string.fa_circle) + " " + username);
+ usernameSpan.setSpan(new CenterVerticalSpan(), 0, 2,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ usernameSpan.setSpan(new RelativeSizeSpan(0.45f)
+ , 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ /*usernameSpan.setSpan(new ForegroundColorSpan(Color.GRAY)
+ , 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);*/
+ isOnline = contentsTable.toString().contains("Online")
+ || contentsTable.toString().contains("Συνδεδεμένος");
+ usernameSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#26A69A"))
+ , 2, usernameSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Parcel parcel) {
+ int result = parcel.getResultCode();
+ if (result == NetworkResultCodes.SUCCESSFUL) {
+ //Parse was successful
+ if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(true);
+ progressBar.setVisibility(ProgressBar.INVISIBLE);
+
+ if (usernameSpan != null) {
+ if (isOnline) {
+ usernameView.setTextColor(Color.parseColor("#4CAF50"));
} else {
- isOnline = false;
- /*usernameSpan.setSpan(new ForegroundColorSpan(Color.GRAY)
- , 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);*/
+ usernameView.setTextColor(Color.GRAY);
}
- usernameSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#26A69A"))
- , 2, usernameSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ usernameView.setText(usernameSpan);
+ } else if (usernameView.getText() != username) usernameView.setText(username);
+ if (avatarUrl != null && !Objects.equals(avatarUrl, ""))
+ //noinspection ConstantConditions
+ loadAvatar();
+ else
+ loadDefaultAvatar();
+ if (personalText != null) {
+ personalTextView.setText(personalText);
+ personalTextView.setVisibility(View.VISIBLE);
}
- return true;
- } catch (SSLHandshakeException e) {
- Timber.w("Certificate problem (please switch to unsafe connection).");
- } catch (Exception e) {
- Timber.e(e, "Exception");
- }
- return false;
- }
- //TODO: better parse error handling (ParseException etc.)
- protected void onPostExecute(Boolean result) {
- if (!result) { //Parse failed! //TODO report as ParseException?
+ setupViewPager(viewPager, profilePage);
+ TabLayout tabLayout = findViewById(R.id.profile_tabs);
+ tabLayout.setupWithViewPager(viewPager);
+ if (tabSelect != 0) {
+ TabLayout.Tab tab = tabLayout.getTabAt(tabSelect);
+ if (tab != null) tab.select();
+ }
+ } else if (result == NetworkResultCodes.NETWORK_ERROR) {
+ Timber.w("Network error while excecuting profile activity");
+ Toast.makeText(getBaseContext(), "Network error"
+ , Toast.LENGTH_LONG).show();
+ finish();
+ } else {
Timber.d("Parse failed!");
Toast.makeText(getBaseContext(), "Fatal error!\n Aborting..."
, Toast.LENGTH_LONG).show();
finish();
}
- //Parse was successful
- if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(true);
- progressBar.setVisibility(ProgressBar.INVISIBLE);
-
- if (usernameSpan != null) {
- if (isOnline) {
- usernameView.setTextColor(Color.parseColor("#4CAF50"));
- } else {
- usernameView.setTextColor(Color.GRAY);
- }
- usernameView.setText(usernameSpan);
- } else if (usernameView.getText() != username) usernameView.setText(username);
- if (thumbnailUrl != null && !Objects.equals(thumbnailUrl, ""))
- //noinspection ConstantConditions
- Picasso.with(getApplicationContext())
- .load(thumbnailUrl)
- .resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
- .centerCrop()
- .error(ResourcesCompat.getDrawable(getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .placeholder(ResourcesCompat.getDrawable(getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .transform(new CircleTransform())
- .into(thumbnailView);
- if (personalText != null) {
- personalTextView.setText(personalText);
- personalTextView.setVisibility(View.VISIBLE);
- }
+ }
- setupViewPager(viewPager, profilePage);
- TabLayout tabLayout = findViewById(R.id.profile_tabs);
- tabLayout.setupWithViewPager(viewPager);
- if (tabSelect != 0) {
- TabLayout.Tab tab = tabLayout.getTabAt(tabSelect);
- if (tab != null) tab.select();
- }
+ @Override
+ protected int getResultCode(Response response, Void data) {
+ return NetworkResultCodes.SUCCESSFUL;
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java
index b7162495..6054a05f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java
@@ -1,6 +1,6 @@
package gr.thmmy.mthmmy.activities.profile.latestPosts;
-import android.support.v7.widget.RecyclerView;
+import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,6 +10,7 @@ import android.widget.TextView;
import java.util.ArrayList;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.PostSummary;
@@ -21,10 +22,10 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
* specified {@link LatestPostsFragment.LatestPostsFragmentInteractionListener}.
*/
class LatestPostsAdapter extends RecyclerView.Adapter {
- private final int VIEW_TYPE_EMPTY = -1;
- private final int VIEW_TYPE_ITEM = 0;
- private final int VIEW_TYPE_LOADING = 1;
- final private LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener;
+ private static final int VIEW_TYPE_EMPTY = -1;
+ private static final int VIEW_TYPE_ITEM = 0;
+ private static final int VIEW_TYPE_LOADING = 1;
+ private final LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener;
private final ArrayList parsedTopicSummaries;
LatestPostsAdapter(BaseFragment.FragmentInteractionListener interactionListener,
@@ -70,19 +71,16 @@ class LatestPostsAdapter extends RecyclerView.Adapter {
latestPostViewHolder.postTitle.setText(topic.getSubject());
latestPostViewHolder.postDate.setText(topic.getDateTime());
+ latestPostViewHolder.post.setBackgroundColor(Color.argb(1, 255, 255, 255));
latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/"
, topic.getPost(), "text/html", "UTF-8", null);
- latestPostViewHolder.latestPostsRow.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (interactionListener != null) {
- // Notify the active callbacks interface (the activity, if the
- // fragment is attached to one) that a post has been selected.
- interactionListener.onLatestPostsFragmentInteraction(
- parsedTopicSummaries.get(holder.getAdapterPosition()));
- }
-
+ latestPostViewHolder.latestPostsRow.setOnClickListener(v -> {
+ if (interactionListener != null) {
+ // Notify the active callbacks interface (the activity, if the
+ // fragment is attached to one) that a post has been selected.
+ interactionListener.onLatestPostsFragmentInteraction(
+ parsedTopicSummaries.get(holder.getAdapterPosition()));
}
});
} else if (holder instanceof LoadingViewHolder) {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
index 277b01a0..f2c17ff2 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
@@ -2,9 +2,6 @@ package gr.thmmy.mthmmy.activities.profile.latestPosts;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,6 +17,9 @@ import java.util.ArrayList;
import javax.net.ssl.SSLHandshakeException;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseFragment;
@@ -30,6 +30,8 @@ import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
+import static gr.thmmy.mthmmy.utils.parsing.ParseHelpers.deobfuscateElements;
+
/**
* Use the {@link LatestPostsFragment#newInstance} factory method to create an instance of this fragment.
*/
@@ -120,7 +122,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
//Load data
profileLatestPostsTask = new LatestPostsTask();
- profileLatestPostsTask.execute(profileUrl + ";sa=showPosts;start=" + pagesLoaded * 15);
+ profileLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileUrl + ";sa=showPosts;start=" + pagesLoaded * 15);
++pagesLoaded;
}
}
@@ -130,10 +132,9 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
super.onActivityCreated(savedInstanceState);
if (parsedTopicSummaries.isEmpty() && userHasPosts) {
profileLatestPostsTask = new LatestPostsTask();
- profileLatestPostsTask.execute(profileUrl + ";sa=showPosts");
+ profileLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileUrl + ";sa=showPosts");
pagesLoaded = 1;
}
- Timber.d("onActivityCreated");
}
@Override
@@ -191,14 +192,13 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
//td:contains( Sorry, no matches were found)
Elements latestPostsRows = latestPostsPage.
select("td:has(table:Contains(Show Posts)):not([style]) > table");
- if (latestPostsRows.isEmpty()) {
+ if (latestPostsRows.isEmpty())
latestPostsRows = latestPostsPage.
select("td:has(table:Contains(Εμφάνιση μηνυμάτων)):not([style]) > table");
- }
+
//Removes loading item
- if (isLoadingMore) {
+ if (isLoadingMore)
parsedTopicSummaries.remove(parsedTopicSummaries.size() - 1);
- }
if (!latestPostsRows.select("td:contains(Sorry, no matches were found)").isEmpty() ||
!latestPostsRows.select("td:contains(Δυστυχώς δεν βρέθηκε τίποτα)").isEmpty()){
@@ -207,6 +207,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
return true;
}
+ deobfuscateElements(latestPostsRows, false);
for (Element row : latestPostsRows) {
String pTopicUrl, pTopicTitle, pDateTime, pPost;
if (Integer.parseInt(row.attr("cellpadding")) == 4) {
@@ -219,10 +220,10 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
}
} else {
Elements rowHeader = row.select("td.middletext");
- if (rowHeader.size() != 2) {
+ if (rowHeader.size() != 2)
return false;
- } else {
- pTopicTitle = rowHeader.first().text().trim();
+ else {
+ pTopicTitle = rowHeader.first().text().replaceAll("\\u00a0","").trim();
pTopicUrl = rowHeader.first().select("a").last().attr("href");
pDateTime = rowHeader.last().text();
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
index 5822d635..fbf498c5 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
@@ -4,7 +4,6 @@ import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -38,6 +37,7 @@ import java.util.List;
import javax.net.ssl.SSLHandshakeException;
+import androidx.fragment.app.Fragment;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
@@ -45,6 +45,8 @@ import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
+import static gr.thmmy.mthmmy.utils.parsing.ParseHelpers.deobfuscateElements;
+
public class StatsFragment extends Fragment {
/**
* The key to use when putting profile's url String to {@link StatsFragment}'s Bundle.
@@ -103,7 +105,7 @@ public class StatsFragment extends Fragment {
super.onActivityCreated(savedInstanceState);
if (!haveParsed) {
profileStatsTask = new ProfileStatsTask();
- profileStatsTask.execute(profileUrl + ";sa=statPanel");
+ profileStatsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileUrl + ";sa=statPanel");
}
Timber.d("onActivityCreated");
}
@@ -173,6 +175,7 @@ public class StatsFragment extends Fragment {
return false;
{
Elements titleRows = statsPage.select("table.bordercolor[align]>tbody>tr.titlebg");
+ deobfuscateElements(titleRows, false);
generalStatisticsTitle = titleRows.first().text();
if (userHasPosts) {
postingActivityByTimeTitle = titleRows.get(1).text();
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
index 76380576..12e93a60 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
@@ -4,7 +4,6 @@ import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
@@ -22,10 +21,13 @@ import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.Objects;
+import androidx.fragment.app.Fragment;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import timber.log.Timber;
+import static gr.thmmy.mthmmy.utils.parsing.ParseHelpers.deobfuscateElements;
+
/**
* Use the {@link SummaryFragment#newInstance} factory method to create an instance of this fragment.
@@ -88,7 +90,7 @@ public class SummaryFragment extends Fragment {
super.onActivityCreated(savedInstanceState);
if (parsedProfileSummaryData.isEmpty()) {
summaryTask = new SummaryTask();
- summaryTask.execute(profileSummaryDocument);
+ summaryTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileSummaryDocument);
}
Timber.d("onActivityCreated");
}
@@ -132,6 +134,7 @@ public class SummaryFragment extends Fragment {
//Contains all summary's rows
Elements summaryRows = profile.select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) tr");
+ deobfuscateElements(summaryRows, false);
for (Element summaryRow : summaryRows) {
String rowText = summaryRow.text(), pHtml = "";
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java
index 4383732b..a884d3a6 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java
@@ -1,8 +1,8 @@
package gr.thmmy.mthmmy.activities.settings;
import android.os.Bundle;
-import android.support.v4.app.FragmentTransaction;
+import androidx.fragment.app.FragmentTransaction;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java
index df97ad07..a66f91ae 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java
@@ -8,15 +8,15 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceFragmentCompat;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
+import androidx.annotation.NonNull;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseApplication;
import timber.log.Timber;
@@ -28,7 +28,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
NOT_SET, USER, GUEST
}
- public static final String ARG_IS_LOGGED_IN = "selectedRingtoneKey";
+ private static final String ARG_IS_LOGGED_IN = "selectedRingtoneKey";
//Preferences xml keys
private static final String SELECTED_NOTIFICATIONS_SOUND = "pref_notifications_select_sound_key";
@@ -44,7 +44,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
private SharedPreferences settingsFile;
private PREFS_TYPE prefs_type = PREFS_TYPE.NOT_SET;
- private boolean isLoggedIn = false;
+ private boolean isLoggedIn;
private ArrayList defaultHomeTabEntries = new ArrayList<>();
private ArrayList defaultHomeTabValues = new ArrayList<>();
@@ -161,7 +161,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
}
}
- public void updateUserLoginState(boolean isLoggedIn) {
+ void updateUserLoginState(boolean isLoggedIn) {
this.isLoggedIn = isLoggedIn;
updatePreferenceVisibility();
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/SendShoutTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/SendShoutTask.java
new file mode 100644
index 00000000..3b2af22f
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/SendShoutTask.java
@@ -0,0 +1,50 @@
+package gr.thmmy.mthmmy.activities.shoutbox;
+
+import org.jsoup.nodes.Document;
+
+import java.io.IOException;
+
+import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.NetworkTask;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+public class SendShoutTask extends NetworkTask {
+
+ public SendShoutTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onNetworkTaskFinishedListener) {
+ super(onTaskStartedListener, onNetworkTaskFinishedListener);
+ }
+
+ @Override
+ protected Response sendRequest(OkHttpClient client, String... input) throws IOException {
+ MultipartBody.Builder postBodyBuilder = new MultipartBody.Builder()
+ .setType(MultipartBody.FORM)
+ .addFormDataPart("sc", input[2])
+ .addFormDataPart("tp-shout", input[1])
+ .addFormDataPart("tp-shout-name", input[3])
+ .addFormDataPart("shout_send", input[4])
+ .addFormDataPart("tp-shout-url", input[5]);
+
+ Request voteRequest = new Request.Builder()
+ .url(input[0])
+ .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36")
+ .post(postBodyBuilder.build())
+ .build();
+ client.newCall(voteRequest).execute();
+ return client.newCall(voteRequest).execute();
+ }
+
+
+
+ @Override
+ protected Void performTask(Document document, Response response) {
+ return null;
+ }
+
+ @Override
+ protected int getResultCode(Response response, Void data) {
+ return NetworkResultCodes.SUCCESSFUL;
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java
new file mode 100644
index 00000000..82a3389e
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java
@@ -0,0 +1,155 @@
+package gr.thmmy.mthmmy.activities.shoutbox;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import gr.thmmy.mthmmy.R;
+import gr.thmmy.mthmmy.activities.board.BoardActivity;
+import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
+import gr.thmmy.mthmmy.activities.topic.TopicActivity;
+import gr.thmmy.mthmmy.model.Shout;
+import gr.thmmy.mthmmy.model.ThmmyPage;
+import gr.thmmy.mthmmy.utils.CustomRecyclerView;
+
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE;
+import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL;
+import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL;
+import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL;
+import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME;
+import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
+
+public class ShoutAdapter extends CustomRecyclerView.Adapter {
+ private Context context;
+ private Shout[] shouts;
+
+ ShoutAdapter(Context context, Shout[] shouts) {
+ this.context = context;
+ this.shouts = shouts;
+ }
+
+ void setShouts(Shout[] shouts) {
+ this.shouts = shouts;
+ }
+
+ @NonNull
+ @Override
+ public ShoutViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.fragment_shoutbox_shout_row, parent, false);
+ return new ShoutViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ShoutViewHolder holder, int position) {
+ Shout currentShout = shouts[position];
+ holder.author.setText(currentShout.getShouter());
+ if (currentShout.isMemberOfTheMonth()) holder.author.setTextColor(context.getResources().getColor(R.color.member_of_the_month));
+ else holder.author.setTextColor(context.getResources().getColor(R.color.accent));
+ holder.author.setOnClickListener(view -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_PROFILE_URL, shouts[holder.getAdapterPosition()].getShouterProfileURL());
+ extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, "");
+ extras.putString(BUNDLE_PROFILE_USERNAME, "");
+ intent.putExtras(extras);
+ intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ });
+ holder.dateTime.setText(currentShout.getDate());
+ holder.shoutContent.setClickable(true);
+ holder.shoutContent.setWebViewClient(new LinkLauncher());
+ holder.shoutContent.loadDataWithBaseURL("file:///android_asset/", currentShout.getShout(),
+ "text/html", "UTF-8", null);
+ }
+
+ @Override
+ public int getItemCount() {
+ return shouts.length;
+ }
+
+ static class ShoutViewHolder extends CustomRecyclerView.ViewHolder {
+
+ TextView author, dateTime;
+ WebView shoutContent;
+
+ ShoutViewHolder(@NonNull View itemView) {
+ super(itemView);
+ author = itemView.findViewById(R.id.author_textview);
+ dateTime = itemView.findViewById(R.id.date_time_textview);
+ shoutContent = itemView.findViewById(R.id.shout_content);
+ shoutContent.setBackgroundColor(Color.argb(1, 255, 255, 255));
+ }
+ }
+
+ class LinkLauncher extends WebViewClient {
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
+ final Uri uri = request.getUrl();
+ return handleUri(uri);
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ final Uri uri = Uri.parse(url);
+ return handleUri(uri);
+ }
+
+ private boolean handleUri(Uri uri) {
+ final String uriString = uri.toString();
+
+ ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(uri);
+ if (target.is(ThmmyPage.PageCategory.TOPIC)) {
+ //This url points to a topic
+ Intent intent = new Intent(context, TopicActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_TOPIC_URL, uriString);
+ intent.putExtras(extras);
+ intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ } else if (target.is(ThmmyPage.PageCategory.BOARD)) {
+ Intent intent = new Intent(context, BoardActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_BOARD_URL, uriString);
+ extras.putString(BUNDLE_BOARD_TITLE, "");
+ intent.putExtras(extras);
+ intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ } else if (target.is(ThmmyPage.PageCategory.PROFILE)) {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_PROFILE_URL, uriString);
+ extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, "");
+ extras.putString(BUNDLE_PROFILE_USERNAME, "");
+ intent.putExtras(extras);
+ intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+
+ //Method always returns true as no url should be loaded in the WebViews
+ return true;
+ }
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxActivity.java
new file mode 100644
index 00000000..bdd026ad
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxActivity.java
@@ -0,0 +1,54 @@
+package gr.thmmy.mthmmy.activities.shoutbox;
+
+import android.os.Bundle;
+
+import gr.thmmy.mthmmy.R;
+import gr.thmmy.mthmmy.base.BaseActivity;
+
+public class ShoutboxActivity extends BaseActivity {
+
+ private ShoutboxFragment shoutboxFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_shoutbox);
+
+ //Initialize toolbar
+ toolbar = findViewById(R.id.toolbar);
+ toolbar.setTitle("Shoutbox");
+ setSupportActionBar(toolbar);
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayShowHomeEnabled(true);
+ }
+
+ createDrawer();
+ drawer.setSelection(SHOUTBOX_ID);
+
+ if (savedInstanceState == null) {
+ shoutboxFragment = ShoutboxFragment.newInstance();
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.container, shoutboxFragment)
+ .commitNow();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ drawer.setSelection(SHOUTBOX_ID);
+ super.onResume();
+ }
+
+ @Override
+ public void onBackPressed() {
+ int count = getSupportFragmentManager().getBackStackEntryCount();
+
+ if (count == 0) {
+ if (!shoutboxFragment.onBackPressed())
+ super.onBackPressed();
+ } else {
+ getSupportFragmentManager().popBackStack();
+ }
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
new file mode 100644
index 00000000..0c2d8ae5
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
@@ -0,0 +1,173 @@
+package gr.thmmy.mthmmy.activities.shoutbox;
+
+import android.app.Activity;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProviders;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import gr.thmmy.mthmmy.R;
+import gr.thmmy.mthmmy.editorview.EditorView;
+import gr.thmmy.mthmmy.editorview.EmojiKeyboard;
+import gr.thmmy.mthmmy.model.Shout;
+import gr.thmmy.mthmmy.model.Shoutbox;
+import gr.thmmy.mthmmy.session.SessionManager;
+import gr.thmmy.mthmmy.utils.CustomRecyclerView;
+import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.viewmodel.ShoutboxViewModel;
+import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
+import timber.log.Timber;
+
+public class ShoutboxFragment extends Fragment {
+
+ private MaterialProgressBar progressBar;
+ private ShoutboxTask shoutboxTask;
+ private ShoutAdapter shoutAdapter;
+ private EmojiKeyboard emojiKeyboard;
+ private EditorView editorView;
+
+ private ShoutboxViewModel shoutboxViewModel;
+
+ public static ShoutboxFragment newInstance() {
+ return new ShoutboxFragment();
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ final View rootView = inflater.inflate(R.layout.fragment_shoutbox, container, false);
+ setHasOptionsMenu(true);
+
+ progressBar = rootView.findViewById(R.id.progressBar);
+ CustomRecyclerView recyclerView = rootView.findViewById(R.id.shoutbox_recyclerview);
+ shoutAdapter = new ShoutAdapter(getContext(), new Shout[0]);
+ recyclerView.setAdapter(shoutAdapter);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
+ layoutManager.setReverseLayout(true);
+ recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setOnTouchListener((view, motionEvent) -> {
+ editorView.hideMarkdown();
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editorView.getWindowToken(), 0);
+ return false;
+ });
+
+ emojiKeyboard = rootView.findViewById(R.id.emoji_keyboard);
+ editorView = rootView.findViewById(R.id.edior_view);
+ editorView.setEmojiKeyboard(emojiKeyboard);
+ emojiKeyboard.registerEmojiInputField(editorView);
+ editorView.setOnSubmitListener(view -> {
+ if (shoutboxViewModel.getShoutboxMutableLiveData().getValue() == null) return;
+ if (editorView.getText().toString().isEmpty()) {
+ editorView.setError("Required");
+ return;
+ }
+ shoutboxViewModel.sendShout(editorView.getText().toString());
+ });
+ editorView.hideMarkdown();
+ editorView.showMarkdownOnfocus();
+
+ return rootView;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.shoutbox_menu, menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.menu_refresh) {
+ shoutboxViewModel.loadShoutbox();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ shoutboxViewModel = ViewModelProviders.of(this).get(ShoutboxViewModel.class);
+ shoutboxViewModel.getShoutboxMutableLiveData().observe(this, shoutbox -> {
+ if (shoutbox != null) {
+ Timber.i("Shoutbox loaded successfully");
+ shoutAdapter.setShouts(shoutbox.getShouts());
+ shoutAdapter.notifyDataSetChanged();
+ }
+ });
+ shoutboxViewModel.setOnShoutboxTaskStarted(this::onShoutboxTaskSarted);
+ shoutboxViewModel.setOnShoutboxTaskFinished(this::onShoutboxTaskFinished);
+ shoutboxViewModel.setOnSendShoutTaskStarted(this::onSendShoutTaskStarted);
+ shoutboxViewModel.setOnSendShoutTaskFinished(this::onSendShoutTaskFinished);
+
+ shoutboxViewModel.loadShoutbox();
+ }
+
+ private void onShoutboxTaskSarted() {
+ Timber.i("Starting shoutbox task...");
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ private void onSendShoutTaskStarted() {
+ Timber.i("Start sending a shout...");
+ editorView.setAlpha(0.5f);
+ editorView.setEnabled(false);
+ if (emojiKeyboard.isVisible())
+ emojiKeyboard.setVisibility(View.GONE);
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ private void onSendShoutTaskFinished(int resultCode, Void ignored) {
+ editorView.setAlpha(1f);
+ editorView.setEnabled(true);
+ progressBar.setVisibility(View.INVISIBLE);
+ if (resultCode == NetworkResultCodes.SUCCESSFUL) {
+ Timber.i("Shout was sent successfully");
+ editorView.getEditText().getText().clear();
+ shoutboxTask = new ShoutboxTask(ShoutboxFragment.this::onShoutboxTaskSarted, ShoutboxFragment.this::onShoutboxTaskFinished);
+ shoutboxTask.execute(SessionManager.shoutboxUrl.toString());
+ } else if (resultCode == NetworkResultCodes.NETWORK_ERROR) {
+ Timber.w("Failed to send shout");
+ Toast.makeText(getContext(), "NetworkError", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void onShoutboxTaskFinished(int resultCode, Shoutbox shoutbox) {
+ progressBar.setVisibility(View.INVISIBLE);
+ if (resultCode == NetworkResultCodes.SUCCESSFUL) {
+ shoutboxViewModel.setShoutbox(shoutbox);
+ if (shoutbox.getShoutSend() != null)
+ editorView.setVisibility(View.VISIBLE);
+ } else if (resultCode == NetworkResultCodes.NETWORK_ERROR) {
+ Timber.w("Failed to retreive shoutbox due to network error");
+ Toast.makeText(getContext(), "NetworkError", Toast.LENGTH_SHORT).show();
+ } else {
+ Timber.wtf("Failed to retreive shoutbox due to unknown error");
+ Toast.makeText(getContext(), "Failed to retrieve shoutbox, please contact mthmmy developer team", Toast.LENGTH_LONG).show();
+ }
+ }
+
+ /**
+ * @return whether or not {@link ShoutboxFragment#onBackPressed()} consumed the event or not
+ */
+ public boolean onBackPressed() {
+ if (emojiKeyboard.isVisible()) {
+ emojiKeyboard.setVisibility(View.GONE);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxTask.java
new file mode 100644
index 00000000..59797774
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxTask.java
@@ -0,0 +1,61 @@
+package gr.thmmy.mthmmy.activities.shoutbox;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.util.ArrayList;
+
+import gr.thmmy.mthmmy.model.Shout;
+import gr.thmmy.mthmmy.model.Shoutbox;
+import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
+import gr.thmmy.mthmmy.utils.parsing.ParseException;
+import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
+import okhttp3.Response;
+
+public class ShoutboxTask extends NewParseTask {
+
+ public ShoutboxTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
+ super(onTaskStartedListener, onParseTaskFinishedListener);
+ }
+
+ @Override
+ protected Shoutbox parse(Document document, Response response) throws ParseException {
+ // fragment_shoutbox_shout_row container: document.select("div[class=smalltext]" && div.text().contains("Τελευταίες 75 φωνές:") η στα αγγλικα
+ Element shoutboxContainer = document.select("table.windowbg").first();
+ ArrayList shouts = new ArrayList<>();
+ for (Element shout : shoutboxContainer.select("div[style=margin: 4px;]")) {
+ Element user = shout.child(0);
+ Element link = user.select("a").first();
+ String profileUrl = link.attr("href");
+ String profileName = link.text();
+ boolean memberOfTheMonth = link.attr("style").contains("#EA00FF");
+
+ Element date = shout.child(1);
+ String dateString = date.text();
+
+ Element content = shout.child(2);
+ content.removeAttr("style");
+ String shoutContent = "" +
+ ParseHelpers.youtubeEmbeddedFix(content);
+ shouts.add(new Shout(profileName, profileUrl, dateString, shoutContent, memberOfTheMonth));
+ }
+
+ Element shoutboxForm = document.select("form[name=tp-shoutbox]").first();
+ String formUrl = shoutboxForm.attr("action");
+ String sc = shoutboxForm.select("input[name=sc]").first().attr("value");
+ String shoutName = shoutboxForm.select("input[name=tp-shout-name]").first().attr("value");
+ // TODO: make shout send nullable and disable shouting
+ Element shoutSendInput = shoutboxForm.select("input[name=shout_send]").first();
+ String shoutSend = null;
+ if (shoutSendInput != null)
+ shoutSend = shoutSendInput.attr("value");
+ String shoutUrl = shoutboxForm.select("input[name=tp-shout-url]").first().attr("value");
+ return new Shoutbox(shouts.toArray(new Shout[0]), sc, formUrl, shoutName, shoutSend, shoutUrl);
+ }
+
+ @Override
+ protected int getResultCode(Response response, Shoutbox data) {
+ return NetworkResultCodes.SUCCESSFUL;
+ }
+}
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 4d03649d..639ab3c7 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
@@ -2,20 +2,14 @@ package gr.thmmy.mthmmy.activities.topic;
import android.annotation.SuppressLint;
import android.app.NotificationManager;
-import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.graphics.Rect;
import android.net.Uri;
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.v4.content.res.ResourcesCompat;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatDelegate;
-import android.support.v7.widget.RecyclerView;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@@ -34,8 +28,16 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.snackbar.Snackbar;
+
import java.util.ArrayList;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.lifecycle.ViewModelProviders;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.topic.tasks.EditTask;
import gr.thmmy.mthmmy.activities.topic.tasks.PrepareForEditTask;
@@ -183,13 +185,17 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
replyFAB = findViewById(R.id.topic_fab);
replyFAB.hide();
+ replyFAB.setTag(false);
bottomNavBar = findViewById(R.id.bottom_navigation_bar);
- if (!sessionManager.isLoggedIn()) replyFAB.hide();
- else {
+ if (!sessionManager.isLoggedIn()) {
+ replyFAB.hide();
+ replyFAB.setTag(false);
+ } else {
replyFAB.setOnClickListener(view -> {
if (sessionManager.isLoggedIn())
viewModel.prepareForReply();
});
+ replyFAB.setTag(true);
}
//Sets bottom navigation bar
@@ -269,11 +275,17 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
emojiKeyboard.setVisibility(View.GONE);
return;
} else if (viewModel.isWritingReply()) {
+ // persist reply
+ SharedPreferences drafts = getSharedPreferences(getString(R.string.pref_topic_drafts_key), MODE_PRIVATE);
+ Post reply = (Post) topicItems.get(topicItems.size() - 1);
+ drafts.edit().putString(String.valueOf(viewModel.getTopicId()), reply.getBbContent()).apply();
+
topicItems.remove(topicItems.size() - 1);
topicAdapter.notifyItemRemoved(topicItems.size());
topicAdapter.setBackButtonHidden();
viewModel.setWritingReply(false);
replyFAB.show();
+ replyFAB.setTag(true);
bottomNavBar.setVisibility(View.VISIBLE);
return;
} else if (viewModel.isEditingPost()) {
@@ -282,6 +294,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
topicAdapter.setBackButtonHidden();
viewModel.setEditingPost(false);
replyFAB.show();
+ replyFAB.setTag(true);
bottomNavBar.setVisibility(View.VISIBLE);
return;
}
@@ -302,6 +315,17 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
viewModel.stopLoading();
}
+ @Override
+ protected void onStop() {
+ super.onStop();
+ // persist reply
+ if (viewModel.isWritingReply()) {
+ SharedPreferences drafts = getSharedPreferences(getString(R.string.pref_topic_drafts_key), MODE_PRIVATE);
+ Post reply = (Post) topicItems.get(topicItems.size() - 1);
+ drafts.edit().putString(String.valueOf(viewModel.getTopicId()), reply.getBbContent()).apply();
+ }
+ }
+
@Override
public void onPostFocusChange(int position) {
recyclerView.scrollToPosition(position);
@@ -504,8 +528,14 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_creation", null);
Timber.i("Post reply successful");
replyFAB.show();
+ replyFAB.setTag(true);
bottomNavBar.setVisibility(View.VISIBLE);
viewModel.setWritingReply(false);
+
+ SharedPreferences drafts = getSharedPreferences(getString(R.string.pref_topic_drafts_key),
+ Context.MODE_PRIVATE);
+ drafts.edit().remove(String.valueOf(viewModel.getTopicId())).apply();
+
if ((((Post) topicItems.get(topicItems.size() - 1)).getPostNumber() + 1) % 15 == 0) {
Timber.i("Reply was posted in new page. Switching to last page.");
viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
@@ -515,35 +545,31 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
break;
case NEW_REPLY_WHILE_POSTING:
Timber.i("New reply while writing a reply");
- TopicAdapter.QuickReplyViewHolder replyHolder = (TopicAdapter.QuickReplyViewHolder)
- recyclerView.findViewHolderForAdapterPosition(topicItems.size() - 1);
- String subject = replyHolder.quickReplySubject.getText().toString();
- String message = replyHolder.replyEditor.getText().toString();
+
+ //cache reply
+ if (viewModel.isWritingReply()) {
+ SharedPreferences drafts2 = getSharedPreferences(getString(R.string.pref_topic_drafts_key), MODE_PRIVATE);
+ Post reply = (Post) topicItems.get(topicItems.size() - 1);
+ drafts2.edit().putString(String.valueOf(viewModel.getTopicId()), reply.getBbContent()).apply();
+ viewModel.setWritingReply(false);
+ }
+
Runnable addReply = () -> {
- viewModel.setWritingReply(true);
- topicItems.add(Post.newQuickReply());
- topicAdapter.notifyItemInserted(topicItems.size());
- recyclerView.scrollToPosition(topicItems.size() - 1);
- replyFAB.hide();
- bottomNavBar.setVisibility(View.GONE);
- TopicAdapter.QuickReplyViewHolder newReplyHolder = (TopicAdapter.QuickReplyViewHolder)
- recyclerView.findViewHolderForAdapterPosition(topicItems.size() - 1);
- newReplyHolder.quickReplySubject.setText(subject);
- newReplyHolder.replyEditor.setText(message);
AlertDialog.Builder builder = new AlertDialog.Builder(TopicActivity.this,
- R.style.AppCompatAlertDialogStyleAccent);
+ R.style.AppTheme_Dark_Dialog);
builder.setMessage("A new reply was posted before you completed your new post." +
" Please review it and send your reply again")
.setNeutralButton(getString(R.string.ok), (dialog, which) -> dialog.dismiss())
.show();
+ viewModel.prepareForReply();
};
- viewModel.reloadPageThen(addReply);
+ viewModel.resetPageThen(addReply);
break;
default:
Timber.w("Post reply unsuccessful");
Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show();
- recyclerView.getChildAt(topicItems.size() - 1).setAlpha(1);
- recyclerView.getChildAt(topicItems.size() - 1).setEnabled(true);
+ recyclerView.getChildAt(recyclerView.getChildCount() - 1).setAlpha(1f);
+ recyclerView.getChildAt(recyclerView.getChildCount() - 1).setEnabled(true);
}
}
});
@@ -579,6 +605,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
((Post) topicItems.get(position)).setPostType(Post.TYPE_POST);
topicAdapter.notifyItemChanged(position);
replyFAB.show();
+ replyFAB.setTag(true);
bottomNavBar.setVisibility(View.VISIBLE);
viewModel.setEditingPost(false);
viewModel.reloadPage();
@@ -645,10 +672,13 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
}
});
viewModel.getReplyPageUrl().observe(this, replyPageUrl -> {
- if (replyPageUrl == null)
+ if (replyPageUrl == null) {
replyFAB.hide();
- else
+ replyFAB.setTag(false);
+ } else {
replyFAB.show();
+ replyFAB.setTag(true);
+ }
});
viewModel.getTopicItems().observe(this, postList -> {
if (postList == null) progressBar.setVisibility(ProgressBar.VISIBLE);
@@ -666,7 +696,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar.setVisibility(ProgressBar.GONE);
switch (resultCode) {
case SUCCESS:
- Timber.i("Successfully loaded topic with URL %s", viewModel.getTopicUrl());
+ Timber.i("Successfully loaded a topic");
paginationEnabled(true);
break;
case NETWORK_ERROR:
@@ -733,6 +763,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
topicAdapter.notifyItemInserted(topicItems.size());
recyclerView.scrollToPosition(topicItems.size() - 1);
replyFAB.hide();
+ replyFAB.setTag(false);
bottomNavBar.setVisibility(View.GONE);
} else {
Timber.i("Prepare for reply unsuccessful");
@@ -748,6 +779,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
topicAdapter.notifyItemChanged(result.getPosition());
recyclerView.scrollToPosition(result.getPosition());
replyFAB.hide();
+ replyFAB.setTag(false);
bottomNavBar.setVisibility(View.GONE);
} else {
Timber.i("Prepare for edit unsuccessful");
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 bfc26961..345fa9e2 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
@@ -2,25 +2,23 @@ package gr.thmmy.mthmmy.activities.topic;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
-import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.content.res.ResourcesCompat;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.content.res.AppCompatResources;
-import android.support.v7.widget.AppCompatButton;
-import android.support.v7.widget.RecyclerView;
+import android.text.Editable;
import android.text.Html;
import android.text.InputType;
+import android.text.SpannableString;
import android.text.TextUtils;
+import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
+import android.text.style.StyleSpan;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
@@ -49,10 +47,19 @@ import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.squareup.picasso.Picasso;
+import java.text.DecimalFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.content.res.AppCompatResources;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.lifecycle.ViewModelProviders;
+import androidx.recyclerview.widget.RecyclerView;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.board.BoardActivity;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
@@ -66,6 +73,7 @@ import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.utils.CircleTransform;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
+import gr.thmmy.mthmmy.utils.parsing.ThmmyParser;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
import timber.log.Timber;
@@ -81,13 +89,12 @@ import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_YELLOW;
import static gr.thmmy.mthmmy.base.BaseActivity.getSessionManager;
/**
- * Custom {@link android.support.v7.widget.RecyclerView.Adapter} used for topics.
+ * Custom {@link RecyclerView.Adapter} used for topics.
*/
class TopicAdapter extends RecyclerView.Adapter {
/**
* Int that holds thumbnail's size defined in R.dimen
*/
- private static int THUMBNAIL_SIZE;
private final Context context;
private final OnPostFocusChangeListener postFocusListener;
private final IEmojiKeyboard emojiKeyboard;
@@ -105,8 +112,6 @@ class TopicAdapter extends RecyclerView.Adapter {
this.emojiKeyboard = emojiKeyboard;
viewModel = ViewModelProviders.of(context).get(TopicViewModel.class);
-
- THUMBNAIL_SIZE = (int) context.getResources().getDimension(R.dimen.thumbnail_size);
}
@Override
@@ -165,31 +170,63 @@ class TopicAdapter extends RecyclerView.Adapter {
Poll poll = (Poll) topicItems.get(position);
Poll.Entry[] entries = poll.getEntries();
PollViewHolder holder = (PollViewHolder) currentHolder;
+
+ boolean pollSupported = true;
+ for (Poll.Entry entry : entries) {
+ if (ThmmyParser.containsHtml(entry.getEntryName())) {
+ pollSupported = false;
+ break;
+ }
+ }
+ if (ThmmyParser.containsHtml(poll.getQuestion()))
+ pollSupported = false;
+ if (entries.length > 30)
+ pollSupported = false;
+ if (!pollSupported) {
+ holder.optionsLayout.setVisibility(View.GONE);
+ holder.voteChart.setVisibility(View.GONE);
+ holder.selectedEntry.setVisibility(View.GONE);
+ holder.removeVotesButton.setVisibility(View.GONE);
+ holder.showPollResultsButton.setVisibility(View.GONE);
+ holder.hidePollResultsButton.setVisibility(View.GONE);
+ // use the submit vote button to open poll on browser
+ holder.submitButton.setText("Open in browser");
+ holder.submitButton.setOnClickListener(v -> {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(viewModel.getTopicUrl()));
+ context.startActivity(browserIntent);
+ });
+ holder.submitButton.setVisibility(View.VISIBLE);
+ // put a warning instead of a question
+ holder.question.setText("This topic contains a poll that is not supported in mTHMMY");
+ return;
+ }
+
holder.question.setText(poll.getQuestion());
holder.optionsLayout.removeAllViews();
- holder.errorTooManySelected.setVisibility(View.GONE);
+ holder.errorTextview.setVisibility(View.GONE);
+
+ final int primaryTextColor = context.getResources().getColor(R.color.primary_text);
+ final int accentColor = context.getResources().getColor(R.color.accent);
+
if (poll.getAvailableVoteCount() > 1) {
+ // vote multiple options
for (Poll.Entry entry : entries) {
- LinearLayout container = new LinearLayout(context);
- container.setOrientation(LinearLayout.HORIZONTAL);
CheckBox checkBox = new CheckBox(context);
- TextView label = new TextView(context);
- label.setTextColor(context.getResources().getColor(R.color.primary_text));
- label.setMovementMethod(LinkMovementMethod.getInstance());
+ checkBox.setMovementMethod(LinkMovementMethod.getInstance());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- label.setText(Html.fromHtml(entry.getEntryName(), Html.FROM_HTML_MODE_LEGACY));
+ checkBox.setText(Html.fromHtml(entry.getEntryName(), Html.FROM_HTML_MODE_LEGACY));
} else {
//noinspection deprecation
- label.setText(Html.fromHtml(entry.getEntryName()));
+ checkBox.setText(Html.fromHtml(entry.getEntryName()));
}
- checkBox.setTextColor(context.getResources().getColor(R.color.primary_text));
- container.addView(checkBox);
- container.addView(label);
- holder.optionsLayout.addView(container);
+ checkBox.setTextColor(primaryTextColor);
+ holder.optionsLayout.addView(checkBox);
}
holder.voteChart.setVisibility(View.GONE);
+ holder.selectedEntry.setVisibility(View.GONE);
holder.optionsLayout.setVisibility(View.VISIBLE);
} else if (poll.getAvailableVoteCount() == 1) {
+ // vote single option
RadioGroup radioGroup = new RadioGroup(context);
for (int i = 0; i < entries.length; i++) {
RadioButton radioButton = new RadioButton(context);
@@ -201,48 +238,94 @@ class TopicAdapter extends RecyclerView.Adapter {
//noinspection deprecation
radioButton.setText(Html.fromHtml(entries[i].getEntryName()));
}
- radioButton.setTextColor(context.getResources().getColor(R.color.primary_text));
+ radioButton.setText(ThmmyParser.html2span(context, entries[i].getEntryName()));
+ radioButton.setTextColor(primaryTextColor);
radioGroup.addView(radioButton);
}
holder.optionsLayout.addView(radioGroup);
holder.voteChart.setVisibility(View.GONE);
+ holder.selectedEntry.setVisibility(View.GONE);
+ holder.optionsLayout.setVisibility(View.VISIBLE);
+ } else if (poll.isPollResultsHidden()) {
+ // vote already submitted but results are hidden
+ Poll.Entry[] entries1 = poll.getEntries();
+ for (int i = 0; i < entries1.length; i++) {
+ Poll.Entry entry = entries1[i];
+ TextView textView = new TextView(context);
+ textView.setMovementMethod(LinkMovementMethod.getInstance());
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ textView.setText(Html.fromHtml(entry.getEntryName(), Html.FROM_HTML_MODE_LEGACY));
+ } else {
+ //noinspection deprecation
+ textView.setText(Html.fromHtml(entry.getEntryName()));
+ }
+ textView.setTextColor(primaryTextColor);
+ if (poll.getSelectedEntryIndex() == i) {
+ // apply bold to the selected entry
+ SpannableString spanString = new SpannableString(textView.getText() + " ✓");
+ spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), 0);
+ textView.setText(spanString);
+ textView.setTextColor(accentColor);
+ }
+ holder.optionsLayout.addView(textView);
+ }
+ holder.voteChart.setVisibility(View.GONE);
+ holder.selectedEntry.setVisibility(View.GONE);
holder.optionsLayout.setVisibility(View.VISIBLE);
} else {
- //Showing results
+ // Showing results
holder.optionsLayout.setVisibility(View.GONE);
+ Arrays.sort(entries, (p1, p2) -> p1.getVotes() - p2.getVotes());
List valuesToCompare = new ArrayList<>();
+ int totalVotes = 0;
for (int i = 0; i < entries.length; i++) {
valuesToCompare.add(new BarEntry(i, entries[i].getVotes()));
+ totalVotes += entries[i].getVotes();
}
- BarDataSet data = new BarDataSet(valuesToCompare, "Vote Results");
- data.setColor(context.getResources().getColor(R.color.accent));
+ BarDataSet dataSet = new BarDataSet(valuesToCompare, "Vote Results");
+ dataSet.setColor(accentColor);
+ dataSet.setValueTextColor(accentColor);
YAxis yAxisLeft = holder.voteChart.getAxisLeft();
yAxisLeft.setGranularity(1);
- yAxisLeft.setTextColor(context.getResources().getColor(R.color.primary_text));
+ yAxisLeft.setTextColor(primaryTextColor);
yAxisLeft.setAxisMinimum(0);
+ yAxisLeft.setSpaceTop(40f);
YAxis yAxisRight = holder.voteChart.getAxisRight();
yAxisRight.setEnabled(false);
XAxis xAxis = holder.voteChart.getXAxis();
xAxis.setValueFormatter((value, axis) -> Html.fromHtml(entries[(int) value].getEntryName()).toString());
- xAxis.setTextColor(context.getResources().getColor(R.color.primary_text));
+ xAxis.setTextColor(primaryTextColor);
xAxis.setGranularity(1f);
xAxis.setLabelCount(entries.length);
xAxis.setDrawGridLines(false);
xAxis.setDrawAxisLine(false);
- xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
-
- BarData barData = new BarData(data);
- barData.setValueTextColor(context.getResources().getColor(R.color.accent));
+ xAxis.setPosition(XAxis.XAxisPosition.TOP_INSIDE);
+
+ BarData barData = new BarData(dataSet);
+ int finalSum = totalVotes;
+ barData.setValueFormatter((value, entry, dataSetIndex, viewPortHandler) -> {
+ DecimalFormat format = new DecimalFormat("###.#%");
+ double percentage = 0;
+ if (finalSum != 0)
+ percentage = ((double) value / (double) finalSum);
+ return "" + (int) value + " (" + format.format(percentage) + ")";
+ });
holder.voteChart.setData(barData);
holder.voteChart.getLegend().setEnabled(false);
holder.voteChart.getDescription().setEnabled(false);
- int chartHeightdp = 10 + 30 * entries.length;
+ int chartHeightDp = 10 + 30 * entries.length;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
- holder.voteChart.setMinimumHeight((int) (chartHeightdp * (metrics.densityDpi / 160f)));
+ holder.voteChart.setMinimumHeight((int) (chartHeightDp * (metrics.densityDpi / 160f)));
holder.voteChart.invalidate();
holder.voteChart.setVisibility(View.VISIBLE);
+
+ if (poll.getSelectedEntryIndex() != -1) {
+ holder.selectedEntry.setText("You voted \"" +
+ poll.getEntries()[poll.getSelectedEntryIndex()].getEntryName() + "\"");
+ holder.selectedEntry.setVisibility(View.VISIBLE);
+ }
}
if (poll.getRemoveVoteUrl() != null) {
holder.removeVotesButton.setOnClickListener(v -> viewModel.removeVote());
@@ -260,10 +343,10 @@ class TopicAdapter extends RecyclerView.Adapter {
if (poll.getPollFormUrl() != null) {
holder.submitButton.setOnClickListener(v -> {
if (!viewModel.submitVote(holder.optionsLayout)) {
- holder.errorTooManySelected.setText(context.getResources()
+ holder.errorTextview.setText(context.getResources()
.getQuantityString(R.plurals.error_too_many_checked, poll.getAvailableVoteCount(),
poll.getAvailableVoteCount()));
- holder.errorTooManySelected.setVisibility(View.VISIBLE);
+ holder.errorTextview.setVisibility(View.VISIBLE);
}
});
holder.submitButton.setVisibility(View.VISIBLE);
@@ -277,24 +360,8 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.post.setClickable(true);
holder.post.setWebViewClient(new LinkLauncher());
- //Avoids errors about layout having 0 width/height
- holder.thumbnail.setMinimumWidth(1);
- holder.thumbnail.setMinimumHeight(1);
- //Sets thumbnail size
- holder.thumbnail.setMaxWidth(THUMBNAIL_SIZE);
- holder.thumbnail.setMaxHeight(THUMBNAIL_SIZE);
-
//noinspection ConstantConditions
- Picasso.with(context)
- .load(currentPost.getThumbnailURL())
- .resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
- .centerCrop()
- .error(ResourcesCompat.getDrawable(context.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .placeholder(ResourcesCompat.getDrawable(context.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .transform(new CircleTransform())
- .into(holder.thumbnail);
+ loadAvatar(currentPost.getThumbnailURL(), holder.thumbnail);
//Sets username,submit date, index number, subject, post's and attached files texts
holder.username.setText(currentPost.getAuthor());
@@ -398,11 +465,11 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.personalText.setVisibility(View.VISIBLE);
} else
holder.personalText.setVisibility(View.GONE);
- if (mUserColor != USER_COLOR_YELLOW) {
+ if (mUserColor != USER_COLOR_YELLOW)
holder.username.setTextColor(mUserColor);
- } else {
+ else
holder.username.setTextColor(USER_COLOR_WHITE);
- }
+
if (mNumberOfStars > 0) {
holder.stars.setTypeface(Typeface.createFromAsset(context.getAssets()
, "fonts/fontawesome-webfont.ttf"));
@@ -495,9 +562,9 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.overflowButton.setOnClickListener(view -> {
//Inflates the popup menu content
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- if (layoutInflater == null) {
+ if (layoutInflater == null)
return;
- }
+
View popUpContent = layoutInflater.inflate(R.layout.activity_topic_overflow_menu, null);
//Creates the PopupWindow
@@ -522,9 +589,9 @@ class TopicAdapter extends RecyclerView.Adapter {
Drawable editStartDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_edit_white_24dp);
editPostButton.setCompoundDrawablesRelativeWithIntrinsicBounds(editStartDrawable, null, null, null);
- if (viewModel.isEditingPost() || currentPost.getPostEditURL() == null || currentPost.getPostEditURL().equals("")) {
+ if (viewModel.isEditingPost() || currentPost.getPostEditURL() == null || currentPost.getPostEditURL().equals(""))
editPostButton.setVisibility(View.GONE);
- } else {
+ else {
editPostButton.setOnClickListener(v -> {
viewModel.prepareForEdit(position, currentPost.getPostEditURL());
popUp.dismiss();
@@ -533,9 +600,9 @@ class TopicAdapter extends RecyclerView.Adapter {
TextView deletePostButton = popUpContent.findViewById(R.id.delete_post);
- if (currentPost.getPostDeleteURL() == null || currentPost.getPostDeleteURL().equals("")) {
+ if (currentPost.getPostDeleteURL() == null || currentPost.getPostDeleteURL().equals(""))
deletePostButton.setVisibility(View.GONE);
- } else {
+ else {
Drawable deleteStartDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_delete_white_24dp);
deletePostButton.setCompoundDrawablesRelativeWithIntrinsicBounds(deleteStartDrawable, null, null, null);
popUpContent.findViewById(R.id.delete_post).setOnClickListener(v -> {
@@ -554,9 +621,9 @@ class TopicAdapter extends RecyclerView.Adapter {
});
//noinspection PointlessBooleanExpression,ConstantConditions
- if (!BaseActivity.getSessionManager().isLoggedIn() || !viewModel.canReply()) {
+ if (!BaseActivity.getSessionManager().isLoggedIn() || !viewModel.canReply())
holder.quoteToggle.setVisibility(View.GONE);
- } else {
+ else {
if (viewModel.getToQuoteList().contains(currentPost.getPostIndex()))
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked_accent_24dp);
else
@@ -572,20 +639,19 @@ class TopicAdapter extends RecyclerView.Adapter {
}
} else if (currentHolder instanceof QuickReplyViewHolder) {
final QuickReplyViewHolder holder = (QuickReplyViewHolder) currentHolder;
+ Post reply = (Post) topicItems.get(position);
//noinspection ConstantConditions
- Picasso.with(context)
- .load(getSessionManager().getAvatarLink())
- .resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
- .centerCrop()
- .error(ResourcesCompat.getDrawable(context.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .placeholder(ResourcesCompat.getDrawable(context.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .transform(new CircleTransform())
- .into(holder.thumbnail);
+ loadAvatar(getSessionManager().getAvatarLink(), holder.thumbnail);
+
holder.username.setText(getSessionManager().getUsername());
- holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle().getValue());
+ holder.itemView.setAlpha(1f);
+ holder.itemView.setEnabled(true);
+ if (reply.getSubject() != null) {
+ holder.quickReplySubject.setText(reply.getSubject());
+ } else {
+ holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle().getValue());
+ }
holder.quickReplySubject.setRawInputType(InputType.TYPE_CLASS_TEXT);
holder.quickReplySubject.setImeOptions(EditorInfo.IME_ACTION_DONE);
@@ -593,7 +659,6 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.replyEditor.requestEditTextFocus();
emojiKeyboard.registerEmojiInputField(holder.replyEditor);
- holder.replyEditor.setText(viewModel.getBuildedQuotes());
holder.replyEditor.setOnSubmitListener(view -> {
if (holder.quickReplySubject.getText().toString().isEmpty()) return;
if (holder.replyEditor.getText().toString().isEmpty()) {
@@ -606,29 +671,71 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.itemView.setEnabled(false);
emojiKeyboard.hide();
+ SharedPreferences drafts = context.getSharedPreferences(context.getString(R.string.pref_topic_drafts_key),
+ Context.MODE_PRIVATE);
+ drafts.edit().remove(String.valueOf(viewModel.getTopicId())).apply();
+
viewModel.postReply(context, holder.quickReplySubject.getText().toString(),
holder.replyEditor.getText().toString());
});
holder.replyEditor.setOnClickListener(view -> holder.replyEditor.setError(null));
+ String replyText = "";
+
+ if (reply.getBbContent() != null)
+ replyText += reply.getBbContent();
+ else {
+ SharedPreferences drafts = context.getSharedPreferences(context.getString(R.string.pref_topic_drafts_key),
+ Context.MODE_PRIVATE);
+ replyText += drafts.getString(String.valueOf(viewModel.getTopicId()), "");
+ if (viewModel.getBuildedQuotes() != null && !viewModel.getBuildedQuotes().isEmpty())
+ replyText += viewModel.getBuildedQuotes();
+ }
+ holder.replyEditor.setText(replyText);
+ holder.replyEditor.getEditText().setSelection(holder.replyEditor.getText().length());
+ holder.replyEditor.getEditText().addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ ((Post) topicItems.get(holder.getAdapterPosition())).setBbContent(charSequence.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+
+ }
+ });
+
if (backPressHidden) {
- holder.replyEditor.requestFocus();
+ holder.replyEditor.requestEditTextFocus();
backPressHidden = false;
}
+ holder.quickReplySubject.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ ((Post) topicItems.get(holder.getAdapterPosition())).setSubject(charSequence.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+
+ }
+ });
} else if (currentHolder instanceof EditMessageViewHolder) {
final EditMessageViewHolder holder = (EditMessageViewHolder) currentHolder;
//noinspection ConstantConditions
- Picasso.with(context)
- .load(getSessionManager().getAvatarLink())
- .resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
- .centerCrop()
- .error(ResourcesCompat.getDrawable(context.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .placeholder(ResourcesCompat.getDrawable(context.getResources()
- , R.drawable.ic_default_user_thumbnail_white_24dp, null))
- .transform(new CircleTransform())
- .into(holder.thumbnail);
+ loadAvatar(getSessionManager().getAvatarLink(), holder.thumbnail);
+
holder.username.setText(getSessionManager().getUsername());
holder.editSubject.setText(currentPost.getSubject());
holder.editSubject.setRawInputType(InputType.TYPE_CLASS_TEXT);
@@ -637,7 +744,11 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.editEditor.setEmojiKeyboard(emojiKeyboard);
holder.editEditor.requestEditTextFocus();
emojiKeyboard.registerEmojiInputField(holder.editEditor);
- holder.editEditor.setText(viewModel.getPostBeingEditedText());
+ if (currentPost.getBbContent() == null)
+ holder.editEditor.setText(viewModel.getPostBeingEditedText());
+ else
+ holder.editEditor.setText(currentPost.getBbContent());
+ holder.editEditor.getEditText().setSelection(holder.editEditor.getText().length());
holder.editEditor.setOnSubmitListener(view -> {
if (holder.editSubject.getText().toString().isEmpty()) return;
if (holder.editEditor.getText().toString().isEmpty()) {
@@ -653,14 +764,59 @@ class TopicAdapter extends RecyclerView.Adapter {
viewModel.editPost(position, holder.editSubject.getText().toString(), holder.editEditor.getText().toString());
});
+ holder.editSubject.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ ((Post) topicItems.get(holder.getAdapterPosition())).setSubject(charSequence.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+
+ }
+ });
+ holder.editEditor.getEditText().addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ ((Post) topicItems.get(holder.getAdapterPosition())).setBbContent(charSequence.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+
+ }
+ });
if (backPressHidden) {
- holder.editEditor.requestFocus();
+ holder.editEditor.requestEditTextFocus();
backPressHidden = false;
}
}
}
}
+ private void loadAvatar(String imageUrl, ImageView imageView) {
+ Picasso.with(context)
+ .load(imageUrl)
+ .fit()
+ .centerCrop()
+ .error(Objects.requireNonNull(ResourcesCompat.getDrawable(context.getResources()
+ , R.drawable.ic_default_user_avatar_darker, null)))
+ .placeholder(Objects.requireNonNull(ResourcesCompat.getDrawable(context.getResources()
+ , R.drawable.ic_default_user_avatar_darker, null)))
+ .transform(new CircleTransform())
+ .into(imageView);
+ }
+
@Override
public int getItemCount() {
return topicItems.size();
@@ -753,7 +909,7 @@ class TopicAdapter extends RecyclerView.Adapter {
}
static class PollViewHolder extends RecyclerView.ViewHolder {
- final TextView question, errorTooManySelected;
+ final TextView question, errorTextview, selectedEntry;
final LinearLayout optionsLayout;
final AppCompatButton submitButton;
final AppCompatButton removeVotesButton, showPollResultsButton, hidePollResultsButton;
@@ -768,8 +924,11 @@ class TopicAdapter extends RecyclerView.Adapter {
removeVotesButton = itemView.findViewById(R.id.remove_vote_button);
showPollResultsButton = itemView.findViewById(R.id.show_poll_results_button);
hidePollResultsButton = itemView.findViewById(R.id.show_poll_options_button);
- errorTooManySelected = itemView.findViewById(R.id.error_too_many_checked);
+ errorTextview = itemView.findViewById(R.id.error_too_many_checked);
voteChart = itemView.findViewById(R.id.vote_chart);
+ selectedEntry = itemView.findViewById(R.id.selected_entry_textview);
+ voteChart.setScaleYEnabled(false);
+ voteChart.setDoubleTapToZoomEnabled(false);
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
index 5a411e12..1a7922ff 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
@@ -37,7 +37,7 @@ import timber.log.Timber;
public class TopicParser {
private static Pattern mentionsPattern = Pattern.
compile("