From f2b9c86ccbef84b9f984a8779360697317d902bb Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Mon, 8 Jun 2020 18:47:47 +0300
Subject: [PATCH 01/21] Migration to Firebase Crashlytics SDK
---
app/build.gradle | 12 ++--
.../activities/settings/SettingsFragment.java | 5 +-
.../gr/thmmy/mthmmy/base/BaseActivity.java | 4 +-
.../gr/thmmy/mthmmy/base/BaseApplication.java | 56 +++++++++++--------
.../utils/crashreporting/CrashReporter.java | 13 +++--
.../crashreporting/CrashReportingTree.java | 16 ++++--
build.gradle | 4 +-
7 files changed, 65 insertions(+), 45 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index afd40760..e2eb5c50 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -3,7 +3,8 @@ import groovy.json.JsonSlurper
apply from: 'gradle/grgit.gradle'
apply plugin: 'com.android.application'
-apply plugin: 'io.fabric'
+apply plugin: 'com.google.gms.google-services'
+apply plugin: 'com.google.firebase.crashlytics'
android {
compileSdkVersion 29
@@ -33,8 +34,9 @@ android {
multiDexEnabled true
def date = new Date().format('ddMMyy_HHmmss')
archivesBaseName = archivesBaseName + "-$date"
- // Disable fabric build ID generation for debug builds
- ext.enableCrashlytics = false
+ firebaseCrashlytics {
+ mappingFileUploadEnabled false // Disable mapping file uploading for debug builds
+ }
}
}
@@ -87,8 +89,8 @@ dependencies {
implementation 'androidx.multidex:multidex:2.0.1' //TODO: Remove when minSdkVersion >= 21
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.google.firebase:firebase-analytics:17.4.3'
+ implementation 'com.google.firebase:firebase-crashlytics:17.0.1'
implementation 'com.google.firebase:firebase-messaging:20.2.0'
- implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation 'com.snatik:storage:2.1.0'
implementation ('com.squareup.okhttp3:okhttp:3.12.12') { //TODO: Warning: OkHttp has dropped support for Android 19 since OkHttp 3.13!
force = true //TODO: Remove when minSdkVersion >= 21
@@ -116,5 +118,3 @@ dependencies {
testImplementation 'org.powermock:powermock-api-mockito2:2.0.2'
testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
}
-
-apply plugin: 'com.google.gms.google-services'
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 edd06356..ef2d1693 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
@@ -200,14 +200,15 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
if (key.equals(getString(R.string.pref_privacy_crashlytics_enable_key))) {
enabled = sharedPreferences.getBoolean(key, false);
if(enabled)
- BaseApplication.getInstance().startFirebaseCrashlyticsCollection();
+ BaseApplication.getInstance().setFirebaseCrashlyticsEnabled(true);
else {
Timber.i("Crashlytics collection will be disabled after restarting.");
+ BaseApplication.getInstance().setFirebaseCrashlyticsEnabled(false);
displayRestartAppToTakeEffectToast();
}
} else if (key.equals(getString(R.string.pref_privacy_analytics_enable_key))) {
enabled = sharedPreferences.getBoolean(key, false);
- BaseApplication.getInstance().setFirebaseAnalyticsCollection(enabled);
+ BaseApplication.getInstance().setFirebaseAnalyticsEnabled(enabled);
if(enabled)
Timber.i("Analytics collection enabled.");
else
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
index 37f88876..5adfd788 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
@@ -807,8 +807,8 @@ public abstract class BaseActivity extends AppCompatActivity {
builder.setPositiveButton("Yes, I want to help", (dialogInterface, i) -> {
addUserConsent();
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
- BaseApplication.getInstance().startFirebaseCrashlyticsCollection();
- BaseApplication.getInstance().setFirebaseAnalyticsCollection(true);
+ BaseApplication.getInstance().setFirebaseCrashlyticsEnabled(true);
+ BaseApplication.getInstance().setFirebaseAnalyticsEnabled(true);
setUserDataShareEnabled(true);
});
builder.setNegativeButton("Nope, leave me alone", (dialogInterface, i) -> {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
index 755b539a..51d01bba 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
@@ -14,13 +14,12 @@ import androidx.multidex.MultiDexApplication;
import androidx.preference.PreferenceManager;
import com.bumptech.glide.Glide;
-import com.crashlytics.android.Crashlytics;
-import com.crashlytics.android.core.CrashlyticsCore;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.google.firebase.FirebaseApp;
import com.google.firebase.analytics.FirebaseAnalytics;
+import com.google.firebase.crashlytics.FirebaseCrashlytics;
import com.itkacher.okhttpprofiler.OkHttpProfilerInterceptor;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.iconics.IconicsDrawable;
@@ -40,7 +39,6 @@ import gr.thmmy.mthmmy.BuildConfig;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.crashreporting.CrashReportingTree;
-import io.fabric.sdk.android.Fabric;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.HttpUrl;
@@ -53,6 +51,8 @@ import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DISPLAY_RELAT
public class BaseApplication extends MultiDexApplication {
private static BaseApplication baseApplication; //BaseApplication singleton
+ private CrashReportingTree crashReportingTree;
+
//Firebase
private static String firebaseProjectId;
private FirebaseAnalytics firebaseAnalytics;
@@ -88,19 +88,23 @@ public class BaseApplication extends MultiDexApplication {
SharedPreferences settingsSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences draftsPrefs = getSharedPreferences(getString(R.string.pref_topic_drafts_key), MODE_PRIVATE);
- if (settingsSharedPrefs.getBoolean(getString(R.string.pref_privacy_crashlytics_enable_key), false))
- startFirebaseCrashlyticsCollection();
- else
- Timber.i("Starting app with Crashlytics disabled.");
+ if (settingsSharedPrefs.getBoolean(getString(R.string.pref_privacy_crashlytics_enable_key), false)){
+ Timber.i("Starting app with Firebase Crashlytics enabled.");
+ setFirebaseCrashlyticsEnabled(true);
+ }
+ else {
+ Timber.i("Starting app with Firebase Crashlytics disabled.");
+ setFirebaseCrashlyticsEnabled(false);
+ }
firebaseProjectId = FirebaseApp.getInstance().getOptions().getProjectId();
firebaseAnalytics = FirebaseAnalytics.getInstance(this);
boolean enableAnalytics = settingsSharedPrefs.getBoolean(getString(R.string.pref_privacy_analytics_enable_key), false);
firebaseAnalytics.setAnalyticsCollectionEnabled(enableAnalytics);
if (enableAnalytics)
- Timber.i("Starting app with Analytics enabled.");
+ Timber.i("Starting app with Firebase Analytics enabled.");
else
- Timber.i("Starting app with Analytics disabled.");
+ Timber.i("Starting app with Firebase Analytics disabled.");
SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext());
PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor);
@@ -215,24 +219,32 @@ public class BaseApplication extends MultiDexApplication {
firebaseAnalytics.logEvent(event, params);
}
- public void setFirebaseAnalyticsCollection(boolean enabled) {
+ public void setFirebaseAnalyticsEnabled(boolean enabled) {
firebaseAnalytics.setAnalyticsCollectionEnabled(enabled);
if (!enabled)
firebaseAnalytics.resetAnalyticsData();
+
+ if(enabled)
+ Timber.i("Firebase Analytics enabled.");
+ else
+ Timber.i("Firebase Analytics disabled.");
}
- // Set up Crashlytics, disabled for debug builds
- public void startFirebaseCrashlyticsCollection() {
- if (!Fabric.isInitialized()) {
- Crashlytics crashlyticsKit = new Crashlytics.Builder()
- .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
- .build();
- // Initialize Fabric with the debug-disabled Crashlytics.
- Fabric.with(this, crashlyticsKit);
- Timber.plant(new CrashReportingTree());
- Timber.i("Crashlytics enabled.");
- } else
- Timber.i("Crashlytics were already initialized for this app session.");
+ public void setFirebaseCrashlyticsEnabled(boolean enable) {
+ FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(enable);
+ if(enable){
+ crashReportingTree = new CrashReportingTree();
+ Timber.plant(crashReportingTree);
+ Timber.i("CrashReporting tree planted.");
+ Timber.i("Firebase Crashlytics enabled.");
+ }
+ else{
+ if(crashReportingTree!=null) {
+ Timber.uproot(crashReportingTree);
+ Timber.i("CrashReporting tree uprooted.");
+ }
+ Timber.i("Firebase Crashlytics disabled.");
+ }
}
public static String getFirebaseProjectId(){
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReporter.java b/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReporter.java
index 65011440..4842013c 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReporter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReporter.java
@@ -1,6 +1,7 @@
package gr.thmmy.mthmmy.utils.crashreporting;
-import com.crashlytics.android.Crashlytics;
+
+import com.google.firebase.crashlytics.FirebaseCrashlytics;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -43,12 +44,14 @@ public class CrashReporter {
else
languageValue = "Unknown";
- Crashlytics.setString(themeKey, themeValue);
- Crashlytics.setString(languageKey, languageValue);
- Crashlytics.setBool("isLoggedIn", BaseApplication.getInstance().getSessionManager().isLoggedIn());
+ FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
+ crashlytics.setCustomKey(themeKey, themeValue);
+ crashlytics.setCustomKey(languageKey, languageValue);
+ crashlytics.setCustomKey("isLoggedIn", BaseApplication.getInstance().getSessionManager().isLoggedIn());
}
public static void reportDocument(Document document, String key) {
+ FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
String documentString = document.toString();
ParseHelpers.Language language = ParseHelpers.Language.getLanguage(document);
@@ -71,7 +74,7 @@ public class CrashReporter {
batch = documentString.substring(i * STRING_BATCH_LENGTH, (i + 1) * STRING_BATCH_LENGTH);
else
batch = documentString.substring(i * STRING_BATCH_LENGTH);
- Crashlytics.setString(key + "_" + i + 1, batch);
+ crashlytics.setCustomKey(key + "_" + i + 1, batch);
}
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java b/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
index f378000e..83e55a37 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
@@ -2,12 +2,17 @@ package gr.thmmy.mthmmy.utils.crashreporting;
import android.util.Log;
-import com.crashlytics.android.Crashlytics;
+import com.google.firebase.crashlytics.FirebaseCrashlytics;
import timber.log.Timber.DebugTree;
public class CrashReportingTree extends DebugTree {
-
+ private FirebaseCrashlytics firebaseCrashlytics;
+ public CrashReportingTree() {
+ super();
+ firebaseCrashlytics = FirebaseCrashlytics.getInstance();
+ }
+
@Override
protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
@@ -25,14 +30,13 @@ public class CrashReportingTree extends DebugTree {
else
level = 'A';
- Crashlytics.log(level + "/" + tag + ": " + message);
+ firebaseCrashlytics.log(level + "/" + tag + ": " + message);
if(priority == Log.ERROR) {
if (t!=null)
- Crashlytics.logException(t);
+ firebaseCrashlytics.recordException(t);
else
- Crashlytics.logException(new Exception(message));
+ firebaseCrashlytics.recordException(new Exception(message));
}
-
}
}
diff --git a/build.gradle b/build.gradle
index 0400e33c..d966ef2f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,7 +3,6 @@ apply plugin: "com.github.ben-manes.versions"
buildscript {
repositories {
- maven { url "https://maven.fabric.io/public" }
google()
jcenter()
maven { url "https://jitpack.io" }
@@ -11,7 +10,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.google.gms:google-services:4.3.3'
- classpath 'io.fabric.tools:gradle:1.31.2'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath 'org.ajoberstar.grgit:grgit-core:3.1.1' // Also change in app/gradle/grgit.gradle
classpath "com.github.ben-manes:gradle-versions-plugin:0.21.0"
}
@@ -20,6 +19,7 @@ buildscript {
allprojects {
repositories {
maven { url "https://maven.google.com" }
+ google()
jcenter()
maven { url "https://jitpack.io" }
}
From c5326e781c7285b3f653153f571961a9320d7256 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Mon, 8 Jun 2020 20:16:23 +0300
Subject: [PATCH 02/21] Glide crash fix
---
.../activities/profile/ProfileActivity.java | 19 +++++++++++++------
.../mthmmy/activities/topic/TopicAdapter.java | 15 +++++++++------
.../gr/thmmy/mthmmy/utils/ui/GlideUtils.java | 17 +++++++++++++++++
3 files changed, 39 insertions(+), 12 deletions(-)
create mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/ui/GlideUtils.java
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 81f70fae..e88a22de 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
@@ -1,5 +1,7 @@
package gr.thmmy.mthmmy.activities.profile;
+import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
@@ -57,6 +59,7 @@ import timber.log.Timber;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
import static gr.thmmy.mthmmy.utils.parsing.ParseHelpers.emojiTagToHtml;
+import static gr.thmmy.mthmmy.utils.ui.GlideUtils.isValidContextForGlide;
import static gr.thmmy.mthmmy.utils.ui.PhotoViewUtils.displayPhotoViewImage;
/**
@@ -222,12 +225,16 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
avatarView.setOnClickListener(v -> displayPhotoViewImage(ProfileActivity.this, avatarUrl));
}
- Glide.with(this)
- .load(avatarUri)
- .circleCrop()
- .error(R.drawable.ic_default_user_avatar)
- .placeholder(R.drawable.ic_default_user_avatar)
- .into(avatarView);
+ if(isValidContextForGlide(this)){
+ Glide.with(this)
+ .load(avatarUri)
+ .circleCrop()
+ .error(R.drawable.ic_default_user_avatar)
+ .placeholder(R.drawable.ic_default_user_avatar)
+ .into(avatarView);
+ }
+ else
+ Timber.d("Will not load Glide image (invalid context)");
}
/**
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 213de341..e0f41e8f 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
@@ -88,6 +88,7 @@ import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_WHITE;
import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_YELLOW;
import static gr.thmmy.mthmmy.base.BaseActivity.getSessionManager;
import static gr.thmmy.mthmmy.utils.FileUtils.faIconFromFilename;
+import static gr.thmmy.mthmmy.utils.ui.GlideUtils.isValidContextForGlide;
/**
* Custom {@link RecyclerView.Adapter} used for topics.
@@ -810,12 +811,14 @@ class TopicAdapter extends RecyclerView.Adapter {
if(imageUrl!=null)
imageUrl = imageUrl.trim();
- Glide.with(context)
- .load(imageUrl)
- .circleCrop()
- .error(R.drawable.ic_default_user_avatar_darker)
- .placeholder(R.drawable.ic_default_user_avatar_darker)
- .into(imageView);
+ if(isValidContextForGlide(context)) {
+ Glide.with(context)
+ .load(imageUrl)
+ .circleCrop()
+ .error(R.drawable.ic_default_user_avatar_darker)
+ .placeholder(R.drawable.ic_default_user_avatar_darker)
+ .into(imageView);
+ }
}
@Override
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ui/GlideUtils.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ui/GlideUtils.java
new file mode 100644
index 00000000..1f3f57c7
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ui/GlideUtils.java
@@ -0,0 +1,17 @@
+package gr.thmmy.mthmmy.utils.ui;
+
+import android.app.Activity;
+import android.content.Context;
+
+public class GlideUtils {
+ public static boolean isValidContextForGlide(final Context context) {
+ if (context == null)
+ return false;
+
+ if (context instanceof Activity) {
+ final Activity activity = (Activity) context;
+ return !activity.isDestroyed() && !activity.isFinishing();
+ }
+ return true;
+ }
+}
From 05776162c2679550677a77228ebd44db76aca9cb Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Mon, 8 Jun 2020 20:27:55 +0300
Subject: [PATCH 03/21] Up appcompat version to fix WebView crash (Android 5.1)
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index e2eb5c50..da29d78f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -77,7 +77,7 @@ tasks.whenTaskAdded { task ->
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":emojis")
- implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.appcompat:appcompat:1.2.0-rc01'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
From ca7cb4ce1b8ed663559630510eee007c1a992789 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sat, 13 Jun 2020 23:39:23 +0300
Subject: [PATCH 04/21] Improved clickability of library links
---
app/src/main/assets/libraries_style.css | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/app/src/main/assets/libraries_style.css b/app/src/main/assets/libraries_style.css
index 39372a93..cbe97749 100644
--- a/app/src/main/assets/libraries_style.css
+++ b/app/src/main/assets/libraries_style.css
@@ -15,7 +15,6 @@ pre {
h4, h5 {
display: inline;
- padding: 1em;
}
a, h4, h5 {
@@ -23,6 +22,14 @@ a, h4, h5 {
word-wrap: break-word;
}
+h4 {
+ padding: 1em;
+}
+
li {
color: #26A69A;
+}
+
+ul a {
+ margin-left: 1em;
}
\ No newline at end of file
From a12bc8d7be473cbaecf7ddbd323a6740fbb802e3 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Mon, 15 Jun 2020 00:42:38 +0300
Subject: [PATCH 05/21] Enable cleartext traffic for sciweavers.org (for Tex
images)
---
app/src/main/res/xml/network_security_config.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
index e87d713f..13da65b7 100644
--- a/app/src/main/res/xml/network_security_config.xml
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -3,5 +3,6 @@
www.thmmy.gr
+ www.sciweavers.org
From 74b4d727c306169114658c7904fed856d927449b Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Tue, 16 Jun 2020 19:56:32 +0300
Subject: [PATCH 06/21] Add release badge to README
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index fc28062a..96b10849 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# mTHMMY
+[![GitHub release](https://img.shields.io/github/release/ThmmyNoLife/mTHMMY.svg)](https://github.com/ThmmyNoLife/mTHMMY/releases)
[![API](https://img.shields.io/badge/API-19%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=19)
[![Discord Channel](https://img.shields.io/badge/discord-public@mTHMMY-738bd7.svg?style=flat)][discord-server]
![Last Commit](https://img.shields.io/github/last-commit/ThmmyNoLife/mTHMMY/develop.svg?style=flat)
From 6bd29c9dc7719653360ed27e39ade11fea424e97 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Wed, 17 Jun 2020 21:28:36 +0300
Subject: [PATCH 07/21] TopicTask crash fix
---
.../activities/profile/ProfileActivity.java | 2 --
.../activities/topic/tasks/TopicTask.java | 17 ++++++++---------
2 files changed, 8 insertions(+), 11 deletions(-)
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 e88a22de..016009ca 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
@@ -1,7 +1,5 @@
package gr.thmmy.mthmmy.activities.profile;
-import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
index 14899fa0..c3e78d8d 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
@@ -11,6 +11,9 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import gr.thmmy.mthmmy.activities.topic.TopicParser;
import gr.thmmy.mthmmy.base.BaseApplication;
@@ -29,6 +32,8 @@ import timber.log.Timber;
* parameter.
*/
public class TopicTask extends AsyncTask {
+ private static final Pattern msgPattern = Pattern.compile("msg(\\d+)");
+
private TopicTaskObserver topicTaskObserver;
private OnTopicTaskCompleted finishListener;
@@ -58,15 +63,9 @@ public class TopicTask extends AsyncTask {
//Finds the index of message focus if present
int postFocus = 0;
-
- //TODO: Better parseInt handling - may rarely fail
- if (newPageUrl.contains("msg")) {
- String tmp = newPageUrl.substring(newPageUrl.indexOf("msg") + 3);
- if (tmp.contains(";"))
- postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf(';')));
- else if (tmp.contains("#"))
- postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf('#')));
- }
+ Matcher matcher = msgPattern.matcher(newPageUrl);
+ if (matcher.find())
+ postFocus = Integer.parseInt(Objects.requireNonNull(matcher.group(1)));
Request request = new Request.Builder()
.url(newPageUrl)
From d767d27072d6689e50d70af2d4a249a36aca3c17 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Thu, 18 Jun 2020 18:55:45 +0300
Subject: [PATCH 08/21] BoardActivity improvements
---
.../activities/board/BoardActivity.java | 56 ++++++++++---------
.../mthmmy/activities/board/BoardAdapter.java | 22 +++++++-
.../mthmmy/activities/topic/TopicAdapter.java | 1 -
.../layout/activity_board_sub_board_row.xml | 9 ++-
4 files changed, 55 insertions(+), 33 deletions(-)
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 87e7d27b..aedda58b 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
@@ -80,12 +80,11 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
Toast.makeText(this, "An error has occurred\nAborting.", Toast.LENGTH_SHORT).show();
finish();
}
+
//Fixes url
- {
- String tmpUrlSbstr = boardUrl.replaceAll("(.+)(board=)([0-9]*)(\\.*[0-9]*).*", "$1$2$3");
- if (!tmpUrlSbstr.substring(tmpUrlSbstr.indexOf("board=")).contains("."))
- boardUrl = tmpUrlSbstr + ".0";
- }
+ String tmpUrlSbstr = boardUrl.replaceAll("(.+)(board=)([0-9]*)(\\.*[0-9]*).*", "$1$2$3");
+ if (!tmpUrlSbstr.substring(tmpUrlSbstr.indexOf("board=")).contains("."))
+ boardUrl = tmpUrlSbstr + ".0";
//Initializes graphics
toolbar = findViewById(R.id.toolbar);
@@ -239,8 +238,12 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
pLastPost = "No posts yet", pLastPostUrl = "";
Elements subBoardColumns = subBoardRow.select(">td");
for (Element subBoardCol : subBoardColumns) {
- if (Objects.equals(subBoardCol.className(), "windowbg"))
+ if (Objects.equals(subBoardCol.className(), "windowbg")){
pStats = subBoardCol.text();
+ if(pStats.equals("--"))
+ pStats = "";
+ }
+
else if (Objects.equals(subBoardCol.className(), "smalltext")) {
pLastPost = subBoardCol.text();
if (pLastPost.contains(" in ")) {
@@ -257,16 +260,15 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
"\n" +
pLastPost.substring(pLastPost.lastIndexOf(" από ") + 1);
pLastPostUrl = subBoardCol.select("a").first().attr("href");
- } else {
- pLastPost = "No posts yet.";
- pLastPostUrl = "";
- }
+ } else if (pLastPost.contains("redirected clicks")||pLastPost.contains("N/A"))
+ pLastPost = "";
+ else
+ pLastPost = "No posts yet";
} else {
pUrl = subBoardCol.select("a").first().attr("href");
pTitle = subBoardCol.select("a").first().text();
- if (subBoardCol.select("div.smalltext").first() != null) {
+ if (subBoardCol.select("div.smalltext").first() != null)
pMods = subBoardCol.select("div.smalltext").first().text();
- }
}
}
tempSubboards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl));
@@ -282,18 +284,18 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
String pTopicUrl, pSubject, pStarter, pLastUser="", pLastPostDateTime="00:00:00", 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;
- }
+
+ 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;
+
pStarter = topicColumns.get(3).text();
pStats = "Replies: " + topicColumns.get(4).text() + ", Views: " + topicColumns.get(5).text();
@@ -304,8 +306,10 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
pLastPostDateTime = matcher.group(1);
pLastUser = matcher.group(3);
}
- else
- throw new ParseException("Parsing failed (pLastPost came with: \"" + pLastPost + "\")");
+ else{
+ Timber.e("Parsing failed (pLastPost came with: \"%s\", html was \"%s\")", pLastPost, topicColumns);
+ continue;
+ }
pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href");
tempTopics.add(new Topic(pTopicUrl, pSubject, pStarter, pLastUser, pLastPostDateTime, pLastPostUrl,
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 c508fdc2..0a697706 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
@@ -161,9 +161,25 @@ class BoardAdapter extends RecyclerView.Adapter {
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());
+ String mods = subBoard.getMods();
+ String stats = subBoard.getStats();
+ String lastPost = subBoard.getLastPost();
+
+ if(!mods.isEmpty()){
+ subBoardViewHolder.boardMods.setText(mods);
+ subBoardViewHolder.boardMods.setVisibility(View.VISIBLE);
+ }
+
+ if(!stats.isEmpty()){
+ subBoardViewHolder.boardStats.setText(stats);
+ subBoardViewHolder.boardStats.setVisibility(View.VISIBLE);
+ }
+
+ if(!lastPost.isEmpty()){
+ subBoardViewHolder.boardLastPost.setText(lastPost);
+ subBoardViewHolder.boardLastPost.setVisibility(View.VISIBLE);
+ }
+
if (!Objects.equals(subBoard.getLastPostUrl(), "")) {
subBoardViewHolder.boardLastPost.setOnClickListener(view -> {
Intent intent = new Intent(context, TopicActivity.class);
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 e0f41e8f..def64530 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
@@ -982,7 +982,6 @@ class TopicAdapter extends RecyclerView.Adapter {
for (int i = 0; i < topicItems.size(); i++) {
if (topicItems.get(i) instanceof Post && ((Post) topicItems.get(i)).getPostIndex() == testAgainst) {
//same page
- Timber.d(Integer.toString(i));
postFocusListener.onPostFocusChange(i);
return true;
}
diff --git a/app/src/main/res/layout/activity_board_sub_board_row.xml b/app/src/main/res/layout/activity_board_sub_board_row.xml
index 97335218..ac8eb60a 100644
--- a/app/src/main/res/layout/activity_board_sub_board_row.xml
+++ b/app/src/main/res/layout/activity_board_sub_board_row.xml
@@ -62,7 +62,8 @@
android:text="@string/child_board_mods"
android:textColor="@color/secondary_text"
android:textSize="12sp"
- android:textStyle="italic" />
+ android:textStyle="italic"
+ android:visibility="gone" />
+ android:textSize="12sp"
+ android:visibility="gone" />
+ android:textSize="12sp"
+ android:visibility="gone" />
\ No newline at end of file
From daccf9df6a70b1b3fd106465bcc9a063c8db804b Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Thu, 18 Jun 2020 19:27:29 +0300
Subject: [PATCH 09/21] Bookmarks small fix
---
.../java/gr/thmmy/mthmmy/activities/board/BoardActivity.java | 2 +-
.../thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java | 2 --
.../thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java | 1 +
.../java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java | 5 ++++-
4 files changed, 6 insertions(+), 4 deletions(-)
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 aedda58b..e9111365 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
@@ -327,7 +327,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
|| !Objects.equals(boardTitle, parsedTitle)) {
boardTitle = parsedTitle;
toolbar.setTitle(boardTitle);
- thisPageBookmark = new Bookmark(boardTitle, ThmmyPage.getBoardId(boardUrl), true);
+ thisPageBookmark = new Bookmark(boardTitle, thisPageBookmark.getId(), thisPageBookmark.isNotificationsEnabled());
setBoardBookmark(findViewById(R.id.bookmark));
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
index ef2b79b6..7054db43 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
@@ -26,8 +26,6 @@ import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE;
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 BookmarksActivity extends BaseActivity {
private static final String TOPIC_URL = "https://www.thmmy.gr/smf/index.php?topic=";
private static final String BOARD_URL = "https://www.thmmy.gr/smf/index.php?board=";
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java
index 23562e0d..cdd6f714 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.model.Bookmark;
+//TODO refactor using RecyclerView
public class BookmarksFragment extends Fragment {
enum Type {TOPIC, BOARD}
private static final String ARG_SECTION_NUMBER = "SECTION_NUMBER";
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 f9145be5..907b1fb6 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
@@ -155,6 +155,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
}
topicPageUrl = ThmmyPage.sanitizeTopicUrl(topicPageUrl);
+ //TODO if topicTitle provided is null make bookmark button unclickable until title is fetched (also for BoardActivity)
thisPageBookmark = new Bookmark(topicTitle, ThmmyPage.getTopicId(topicPageUrl), true);
//Initializes graphics
@@ -671,8 +672,10 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
});
viewModel.getTopicTitle().observe(this, newTopicTitle -> {
if (newTopicTitle == null) return;
- if (!TextUtils.equals(toolbarTitle.getText(), newTopicTitle))
+ if (!TextUtils.equals(toolbarTitle.getText(), newTopicTitle)) {
+ thisPageBookmark = new Bookmark(newTopicTitle, thisPageBookmark.getId(), thisPageBookmark.isNotificationsEnabled());
toolbarTitle.setText(newTopicTitle);
+ }
});
viewModel.getPageTopicId().observe(this, pageTopicId -> {
if (pageTopicId == null) return;
From c242b009e0626071bf5a4290583852ae2da8dc9f Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Thu, 18 Jun 2020 19:30:55 +0300
Subject: [PATCH 10/21] UnreadFragment tiny tweak
---
.../mthmmy/activities/main/unread/UnreadFragment.java | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
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 c3088094..f8097a81 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
@@ -119,16 +119,7 @@ public class UnreadFragment extends BaseFragment {
progressBar = rootView.findViewById(R.id.progressBar);
noUnreadTopicsTextView = rootView.findViewById(R.id.no_unread_topics);
markAsReadFAB = rootView.findViewById(R.id.unread_fab);
-
- if(topicSummaries.isEmpty()){
- hideMarkAsReadFAB();
- noUnreadTopicsTextView.setVisibility(View.VISIBLE);
- }
- else{
- noUnreadTopicsTextView.setVisibility(View.INVISIBLE);
- showMarkAsReadFAB();
- }
-
+
unreadAdapter = new UnreadAdapter(topicSummaries, fragmentInteractionListener);
CustomRecyclerView recyclerView = rootView.findViewById(R.id.list);
From 423573cbc102702d3ce7b61859b3946d23eafc7c Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Fri, 19 Jun 2020 00:10:48 +0300
Subject: [PATCH 11/21] BoardActivity fixes
---
.../activities/board/BoardActivity.java | 42 +++++++++++--------
.../mthmmy/activities/topic/TopicParser.java | 11 -----
2 files changed, 24 insertions(+), 29 deletions(-)
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 e9111365..c941269e 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
@@ -236,6 +236,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (!Objects.equals(subBoardRow.className(), "titlebg")) {
String pUrl = "", pTitle = "", pMods = "", pStats = "",
pLastPost = "No posts yet", pLastPostUrl = "";
+ boolean parsingFailed = false;
Elements subBoardColumns = subBoardRow.select(">td");
for (Element subBoardCol : subBoardColumns) {
if (Objects.equals(subBoardCol.className(), "windowbg")){
@@ -246,20 +247,22 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
else if (Objects.equals(subBoardCol.className(), "smalltext")) {
pLastPost = subBoardCol.text();
- if (pLastPost.contains(" in ")) {
- pLastPost = pLastPost.substring(0, pLastPost.indexOf(" in ")) +
- "\n" +
- pLastPost.substring(pLastPost.indexOf(" in ") + 1, pLastPost.indexOf(" by ")) +
- "\n" +
- pLastPost.substring(pLastPost.lastIndexOf(" by ") + 1);
- pLastPostUrl = subBoardCol.select("a").first().attr("href");
- } else if (pLastPost.contains(" σε ")) {
- pLastPost = pLastPost.substring(0, pLastPost.indexOf(" σε ")) +
- "\n" +
- pLastPost.substring(pLastPost.indexOf(" σε ") + 1, pLastPost.indexOf(" από ")) +
- "\n" +
- pLastPost.substring(pLastPost.lastIndexOf(" από ") + 1);
- pLastPostUrl = subBoardCol.select("a").first().attr("href");
+ if (pLastPost.contains(" in ") || pLastPost.contains(" σε ")) {
+ Pattern pattern = Pattern.compile("(?:Last post on |Τελευταίο μήνυμα στις )((?:(?!(?:in|σε)).)*)\\s(?:in|σε)\\s.*");
+ Matcher matcher = pattern.matcher(pLastPost);
+ if (matcher.find()){
+ String pLastPostDateTime = matcher.group(1);
+ String pSubject = subBoardCol.select("a").first().attr("title");
+ String pLastUser = subBoardCol.select("a").last().text();
+ pLastPost = "Last post on: " + pLastPostDateTime + "\nin: " + pSubject + "\nby " +pLastUser;
+
+ pLastPostUrl = subBoardCol.select("a").first().attr("href");
+ }
+ else{
+ parsingFailed = true;
+ break;
+ }
+
} else if (pLastPost.contains("redirected clicks")||pLastPost.contains("N/A"))
pLastPost = "";
else
@@ -271,7 +274,10 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
pMods = subBoardCol.select("div.smalltext").first().text();
}
}
- tempSubboards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl));
+ if(!parsingFailed)
+ tempSubboards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl));
+ else
+ Timber.e("Parsing failed (pLastPost came with: \"%s\", subBoardColumns html was \"%s\")", pLastPost, subBoardColumns);
}
}
}
@@ -300,14 +306,14 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
pStats = "Replies: " + topicColumns.get(4).text() + ", Views: " + topicColumns.get(5).text();
pLastPost = topicColumns.last().text();
- Pattern pattern = Pattern.compile("(.+)\\s(by|από)\\s(.+)$");
+ Pattern pattern = Pattern.compile("((?:(?!(?:by|από)).)*)\\s(?:by|από)\\s(.*)");
Matcher matcher = pattern.matcher(pLastPost);
if (matcher.find()){
pLastPostDateTime = matcher.group(1);
- pLastUser = matcher.group(3);
+ pLastUser = matcher.group(2);
}
else{
- Timber.e("Parsing failed (pLastPost came with: \"%s\", html was \"%s\")", pLastPost, topicColumns);
+ Timber.e("Parsing failed (pLastPost came with: \"%s\", topicColumns html was \"%s\")", pLastPost, topicColumns);
continue;
}
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 901ce553..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
@@ -18,7 +18,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import gr.thmmy.mthmmy.base.BaseActivity;
-import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.model.Poll;
import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.ThmmyFile;
@@ -26,8 +25,6 @@ import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import timber.log.Timber;
-import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp;
-
/**
* Singleton used for parsing a topic.
@@ -178,7 +175,6 @@ public class TopicParser {
p_specialRank, p_gender, p_personalText, p_numberOfPosts, p_postLastEditDate,
p_postURL, p_deletePostURL, p_editPostURL;
int p_postNum, p_postIndex, p_numberOfStars, p_userColor;
- long p_timestamp;
boolean p_isDeleted = false, p_isUserMentionedInPost = false;
ArrayList p_attachedFiles;
@@ -195,7 +191,6 @@ public class TopicParser {
p_postLastEditDate = null;
p_deletePostURL = null;
p_editPostURL = null;
- p_timestamp = 0;
//Language independent parsing
//Finds thumbnail url
@@ -272,12 +267,6 @@ public class TopicParser {
p_postDate = p_postDate.substring(p_postDate.indexOf("στις:") + 6
, p_postDate.indexOf(" »"));
- if (BaseApplication.getInstance().isDisplayRelativeTimeEnabled()) {
- String timestamp = convertToTimestamp(p_postDate);
- if(timestamp!=null)
- p_timestamp = Long.valueOf(timestamp);
- }
-
//Finds post's reply index number
Element postNum = thisRow.select("div.smalltext:matches(Απάντηση #)").first();
if (postNum == null) { //Topic starter
From 43567e03b58b34f07bfafe5de7f2e71267fbc047 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Fri, 19 Jun 2020 12:07:19 +0300
Subject: [PATCH 12/21] Include edge cases in BoardActivity parsing
---
.../activities/board/BoardActivity.java | 23 +++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
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 c941269e..9e297dcf 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
@@ -229,6 +229,9 @@ 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");
+
+ final Pattern pLastPostPattern = Pattern.compile("((?:(?!(?:by|από)).)*)\\s(?:by|από)\\s(.*)");
+
if(pagesLoaded == 0) { //Finds sub boards
Elements subBoardRows = boardPage.select("div.tborder>table>tbody>tr");
if (subBoardRows != null && !subBoardRows.isEmpty()) {
@@ -253,12 +256,25 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (matcher.find()){
String pLastPostDateTime = matcher.group(1);
String pSubject = subBoardCol.select("a").first().attr("title");
- String pLastUser = subBoardCol.select("a").last().text();
+
+ // Purification for extreme edge cases
+ String pSubjectConcat = subBoardCol.select("a").first().text();
+ pLastPost = pLastPost.replaceAll(pSubjectConcat, "");
+
+ String pLastUser;
+ matcher = pLastPostPattern.matcher(pLastPost); //Don't even try simply grabbing , user might be guest
+ if (matcher.find())
+ pLastUser = matcher.group(2);
+ else {
+ parsingFailed = true;
+ break;
+ }
+
pLastPost = "Last post on: " + pLastPostDateTime + "\nin: " + pSubject + "\nby " +pLastUser;
pLastPostUrl = subBoardCol.select("a").first().attr("href");
}
- else{
+ else {
parsingFailed = true;
break;
}
@@ -306,8 +322,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
pStats = "Replies: " + topicColumns.get(4).text() + ", Views: " + topicColumns.get(5).text();
pLastPost = topicColumns.last().text();
- Pattern pattern = Pattern.compile("((?:(?!(?:by|από)).)*)\\s(?:by|από)\\s(.*)");
- Matcher matcher = pattern.matcher(pLastPost);
+ Matcher matcher = pLastPostPattern.matcher(pLastPost);
if (matcher.find()){
pLastPostDateTime = matcher.group(1);
pLastUser = matcher.group(2);
From 2af55e1acaaaefdf3d62041369a49d0b966da90a Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Fri, 26 Jun 2020 23:48:37 +0300
Subject: [PATCH 13/21] Add InvalidSessionException, refactoring
---
.../activities/main/forum/ForumFragment.java | 2 +-
.../main/recent/RecentFragment.java | 2 +-
.../main/unread/UnreadFragment.java | 36 +++++++------
.../activities/profile/ProfileActivity.java | 2 +-
.../activities/shoutbox/SendShoutTask.java | 4 +-
.../activities/shoutbox/ShoutboxFragment.java | 2 +-
.../activities/shoutbox/ShoutboxTask.java | 2 +-
.../activities/topic/TopicActivity.java | 2 +-
.../activities/topic/tasks/DeleteTask.java | 4 +-
.../topic/tasks/RemoveVoteTask.java | 4 +-
.../topic/tasks/SubmitVoteTask.java | 4 +-
.../gr/thmmy/mthmmy/base/BaseActivity.java | 4 +-
.../session/InvalidSessionException.java | 13 +++++
.../thmmy/mthmmy/session/SessionManager.java | 50 +++++++++----------
.../java/gr/thmmy/mthmmy/utils/Parcel.java | 1 -
.../{ => networking}/NetworkResultCodes.java | 2 +-
.../utils/{ => networking}/NetworkTask.java | 13 ++++-
.../mthmmy/utils/parsing/NewParseTask.java | 7 ++-
.../mthmmy/viewmodel/TopicViewModel.java | 2 +-
app/src/main/res/layout/fragment_unread.xml | 1 +
20 files changed, 92 insertions(+), 65 deletions(-)
create mode 100644 app/src/main/java/gr/thmmy/mthmmy/session/InvalidSessionException.java
rename app/src/main/java/gr/thmmy/mthmmy/utils/{ => networking}/NetworkResultCodes.java (94%)
rename app/src/main/java/gr/thmmy/mthmmy/utils/{ => networking}/NetworkTask.java (86%)
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 061db9d2..3344d089 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
@@ -30,7 +30,7 @@ import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.Board;
import gr.thmmy.mthmmy.model.Category;
import gr.thmmy.mthmmy.session.SessionManager;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.views.CustomRecyclerView;
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 5b27c570..625f7440 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
@@ -26,7 +26,7 @@ import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.session.SessionManager;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.views.CustomRecyclerView;
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 f8097a81..a8ba7f10 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
@@ -29,9 +29,10 @@ 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.InvalidSessionException;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.session.ValidateSessionTask;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.views.CustomRecyclerView;
@@ -266,6 +267,8 @@ public class UnreadFragment extends BaseFragment {
hideProgressUI();
if (resultCode == NetworkResultCodes.NETWORK_ERROR)
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
+ else if (resultCode == SessionManager.INVALID_SESSION)
+ Toast.makeText(getContext(), "Session verification failed. Please try logging in again.", Toast.LENGTH_LONG).show();
else
Toast.makeText(getContext(), "Unexpected error," +
" please contact the developers with the details", Toast.LENGTH_LONG).show();
@@ -278,7 +281,10 @@ public class UnreadFragment extends BaseFragment {
}
@Override
- protected ArrayList parse(Document document, Response response) throws ParseException {
+ protected ArrayList parse(Document document, Response response) throws ParseException, InvalidSessionException {
+ if(!document.select("td:containsOwn(Only registered members are allowed to access this section.)").isEmpty())
+ throw new InvalidSessionException();
+
Elements unread = document.select("table.bordercolor[cellspacing=1] tr:not(.titlebg)");
ArrayList fetchedTopicSummaries = new ArrayList<>();
if (!unread.isEmpty()) {
@@ -338,42 +344,42 @@ public class UnreadFragment extends BaseFragment {
progressBar.setVisibility(ProgressBar.VISIBLE);
}
- private void onMarkReadTaskFinished(int resultCode, Boolean isSessionVerified) {
+ private void onMarkReadTaskFinished(int resultCode, Void isSessionVerified) {
hideProgressUI();
- if (resultCode == NetworkResultCodes.SUCCESSFUL) {
- if (!isSessionVerified){
- Toast.makeText(getContext(), "Session verification failed", Toast.LENGTH_SHORT).show();
- startValidateSessionTask();
- }
- else
+ if (resultCode == NetworkResultCodes.SUCCESSFUL)
startUnreadTask();
- }
else{
hideProgressUI();
if (resultCode == NetworkResultCodes.NETWORK_ERROR)
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
+ else if (resultCode == SessionManager.INVALID_SESSION){
+ Toast.makeText(getContext(), "Session verification failed. Please try logging out and back in again", Toast.LENGTH_LONG).show();
+ startValidateSessionTask();
+ }
else
Toast.makeText(getContext(), "Unexpected error," +
" please contact the developers with the details", Toast.LENGTH_LONG).show();
}
}
- private class MarkReadTask extends NewParseTask {
- MarkReadTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
+ private class MarkReadTask extends NewParseTask {
+ MarkReadTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
super(onTaskStartedListener, onParseTaskFinishedListener);
}
@Override
- protected Boolean parse(Document document, Response response) throws ParseException {
+ protected Void parse(Document document, Response response) throws ParseException {
Elements sessionVerificationFailed = document.select("td:containsOwn(Session " +
"verification failed. Please try logging out and back in again, and then try " +
"again.), td:containsOwn(Η επαλήθευση συνόδου απέτυχε. Παρακαλούμε κάντε " +
"αποσύνδεση, επανασύνδεση και ξαναδοκιμάστε.)");
- return sessionVerificationFailed.isEmpty();
+ if(!sessionVerificationFailed.isEmpty())
+ throw new InvalidSessionException();
+ return null;
}
@Override
- protected int getResultCode(Response response, Boolean isSessionVerified) {
+ protected int getResultCode(Response response, Void v) {
return NetworkResultCodes.SUCCESSFUL;
}
}
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 016009ca..223f36e9 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
@@ -45,8 +45,8 @@ import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.model.ThmmyPage;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.Parcel;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.utils.ui.CenterVerticalSpan;
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
index 3b2af22f..171be1e3 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/SendShoutTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/SendShoutTask.java
@@ -4,8 +4,8 @@ import org.jsoup.nodes.Document;
import java.io.IOException;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
-import gr.thmmy.mthmmy.utils.NetworkTask;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
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
index 0049fa6b..e776423f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
@@ -21,7 +21,7 @@ import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.model.Shout;
import gr.thmmy.mthmmy.model.Shoutbox;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.viewmodel.ShoutboxViewModel;
import gr.thmmy.mthmmy.views.CustomRecyclerView;
import gr.thmmy.mthmmy.views.editorview.EditorView;
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
index 8a1d3768..5fbb1415 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxTask.java
@@ -7,7 +7,7 @@ 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.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
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 907b1fb6..3621057f 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
@@ -54,7 +54,7 @@ import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.utils.HTMLUtils;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
import gr.thmmy.mthmmy.views.CustomLinearLayoutManager;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
index b277d2bd..96600b7b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
@@ -4,8 +4,8 @@ import org.jsoup.nodes.Document;
import java.io.IOException;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
-import gr.thmmy.mthmmy.utils.NetworkTask;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/RemoveVoteTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/RemoveVoteTask.java
index f94ae027..484522c1 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/RemoveVoteTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/RemoveVoteTask.java
@@ -2,8 +2,8 @@ package gr.thmmy.mthmmy.activities.topic.tasks;
import org.jsoup.nodes.Document;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
-import gr.thmmy.mthmmy.utils.NetworkTask;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
import okhttp3.Response;
public class RemoveVoteTask extends NetworkTask {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/SubmitVoteTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/SubmitVoteTask.java
index ec3773f7..75dc37e3 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/SubmitVoteTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/SubmitVoteTask.java
@@ -4,8 +4,8 @@ import org.jsoup.nodes.Document;
import java.io.IOException;
-import gr.thmmy.mthmmy.utils.NetworkResultCodes;
-import gr.thmmy.mthmmy.utils.NetworkTask;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
index 5adfd788..defaa6d3 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
@@ -463,8 +463,7 @@ public abstract class BaseActivity extends AppCompatActivity {
private void updateDrawer() {
if (drawer != null) {
- if (!sessionManager.isLoggedIn()) //When logged out or if user is guest
- {
+ if (!sessionManager.isLoggedIn()){ //When logged out or if user is guest
drawer.removeItem(DOWNLOADS_ID);
drawer.removeItem(UPLOAD_ID);
loginLogoutItem.withName(R.string.login).withIcon(loginIcon); //Swap logout with login
@@ -486,7 +485,6 @@ public abstract class BaseActivity extends AppCompatActivity {
}
accountHeader.updateProfile(profileDrawerItem);
drawer.updateItem(loginLogoutItem);
-
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/InvalidSessionException.java b/app/src/main/java/gr/thmmy/mthmmy/session/InvalidSessionException.java
new file mode 100644
index 00000000..37bc2ddd
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/session/InvalidSessionException.java
@@ -0,0 +1,13 @@
+package gr.thmmy.mthmmy.session;
+
+public class InvalidSessionException extends RuntimeException {
+ public InvalidSessionException() {}
+
+ public InvalidSessionException(String message) {
+ super(message);
+ }
+
+ public InvalidSessionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
index 36490d56..e87cdf05 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
@@ -43,15 +43,16 @@ public class SessionManager {
private static final String baseMarkAllAsReadLink = "https://www.thmmy.gr/smf/index.php?action=markasread;sa=all;sesc=";
private static final String guestName = "Guest";
- //Response Codes
- public static final int SUCCESS = 0;
- public static final int FAILURE = 1; //Generic Error
- public static final int WRONG_USER = 2;
- public static final int WRONG_PASSWORD = 3;
- public static final int CANCELLED = 4;
- public static final int CONNECTION_ERROR = 5;
- public static final int EXCEPTION = 6;
- public static final int BANNED_USER = 7;
+ //Response Codes - make sure they do not overlap with NetworkResultCodes, just in case
+ public static final int SUCCESS = 20;
+ public static final int FAILURE = 21; //Generic Error
+ public static final int WRONG_USER = 22;
+ public static final int WRONG_PASSWORD = 23;
+ public static final int CANCELLED = 24;
+ public static final int CONNECTION_ERROR = 25;
+ public static final int EXCEPTION = 26;
+ public static final int BANNED_USER = 27;
+ public static final int INVALID_SESSION = 28;
// Client & Cookies
private final OkHttpClient client;
@@ -63,12 +64,12 @@ public class SessionManager {
private final SharedPreferences draftsPrefs;
private static final String USERNAME = "Username";
private static final String USER_ID = "UserID";
- private static final String AVATAR_LINK = "AvatarLink";
- private static final String HAS_AVATAR = "HasAvatar";
+ public static final String AVATAR_LINK = "AvatarLink";
+ public static final String HAS_AVATAR = "HasAvatar";
private static final String SESC = "Sesc";
private static final String LOGOUT_LINK = "LogoutLink";
private static final String MARK_ALL_AS_READ_LINK = "MarkAllAsReadLink";
- private static final String LOGGED_IN = "LoggedIn";
+ public static final String LOGGED_IN = "LoggedIn";
private static final String LOGIN_SCREEN_AS_DEFAULT = "LoginScreenAsDefault";
//Constructor
@@ -224,8 +225,7 @@ public class SessionManager {
Document document = Jsoup.parse(response.body().string());
Elements loginButton = document.select("[value=Login]"); //Attempt to find login button
- if (!loginButton.isEmpty()) //If login button exists, logout was successful
- {
+ if (!loginButton.isEmpty()){ //If login button exists, logout was successful
Timber.i("Logout successful!");
return SUCCESS;
} else {
@@ -245,6 +245,16 @@ public class SessionManager {
}
}
+ public void clearSessionData() {
+ cookieJar.clear();
+ sharedPrefs.edit().clear().apply(); //Clear session data
+ sharedPrefs.edit().putString(USERNAME, guestName).apply();
+ sharedPrefs.edit().putInt(USER_ID, -1).apply();
+ sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
+ draftsPrefs.edit().clear().apply(); //Clear saved drafts
+ Timber.i("Session data cleared.");
+ }
+
public void refreshSescFromUrl(String url){
String sesc = extractSescFromLink(url);
if(sesc!=null){
@@ -356,16 +366,6 @@ public class SessionManager {
}
- private void clearSessionData() {
- cookieJar.clear();
- sharedPrefs.edit().clear().apply(); //Clear session data
- sharedPrefs.edit().putString(USERNAME, guestName).apply();
- sharedPrefs.edit().putInt(USER_ID, -1).apply();
- sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
- draftsPrefs.edit().clear().apply(); //Clear saved drafts
- Timber.i("Session data cleared.");
- }
-
private void setLoginScreenAsDefault(boolean b){
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, b).apply();
}
@@ -421,7 +421,6 @@ public class SessionManager {
return -1;
}
-
@Nullable
private String extractAvatarLink(@NonNull Document doc) {
Elements avatar = doc.getElementsByClass("avatar");
@@ -461,5 +460,4 @@ public class SessionManager {
return baseMarkAllAsReadLink + sesc;
}
//----------------------------------OTHER FUNCTIONS END-----------------------------------------
-
}
\ No newline at end of file
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/Parcel.java b/app/src/main/java/gr/thmmy/mthmmy/utils/Parcel.java
index 83e65285..8733bf8c 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/Parcel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/Parcel.java
@@ -1,7 +1,6 @@
package gr.thmmy.mthmmy.utils;
public class Parcel {
-
private int resultCode;
private T data;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/NetworkResultCodes.java b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkResultCodes.java
similarity index 94%
rename from app/src/main/java/gr/thmmy/mthmmy/utils/NetworkResultCodes.java
rename to app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkResultCodes.java
index 90cd8771..958435e1 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/NetworkResultCodes.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkResultCodes.java
@@ -1,4 +1,4 @@
-package gr.thmmy.mthmmy.utils;
+package gr.thmmy.mthmmy.utils.networking;
public class NetworkResultCodes {
/**
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/NetworkTask.java b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java
similarity index 86%
rename from app/src/main/java/gr/thmmy/mthmmy/utils/NetworkTask.java
rename to app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java
index a8c42c8b..a12d5757 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/NetworkTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java
@@ -1,4 +1,4 @@
-package gr.thmmy.mthmmy.utils;
+package gr.thmmy.mthmmy.utils.networking;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
@@ -10,6 +10,10 @@ import java.io.IOException;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseApplication;
+import gr.thmmy.mthmmy.session.InvalidSessionException;
+import gr.thmmy.mthmmy.session.SessionManager;
+import gr.thmmy.mthmmy.utils.ExternalAsyncTask;
+import gr.thmmy.mthmmy.utils.Parcel;
import gr.thmmy.mthmmy.utils.crashreporting.CrashReporter;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import okhttp3.OkHttpClient;
@@ -63,7 +67,12 @@ public abstract class NetworkTask extends ExternalAsyncTask
.getString(R.string.pref_privacy_crashlytics_enable_key), false))
CrashReporter.reportForumInfo(Jsoup.parse(responseBodyString));
return new Parcel<>(NetworkResultCodes.PARSE_ERROR, null);
- } catch (Exception e) {
+ } catch (InvalidSessionException ise) {
+ //TODO: Uncomment the lines below when UI is ready to auto-adjust to changes in session data
+ // BaseApplication.getInstance().getSessionManager().clearSessionData();
+ // BaseApplication.getInstance().getSessionManager().guestLogin();
+ return new Parcel<>(SessionManager.INVALID_SESSION, null);
+ }catch (Exception e) {
Timber.e(e);
return new Parcel<>(NetworkResultCodes.PERFORM_TASK_ERROR, null);
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/NewParseTask.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/NewParseTask.java
index def14c2f..754e7825 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/NewParseTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/NewParseTask.java
@@ -2,7 +2,8 @@ package gr.thmmy.mthmmy.utils.parsing;
import org.jsoup.nodes.Document;
-import gr.thmmy.mthmmy.utils.NetworkTask;
+import gr.thmmy.mthmmy.session.InvalidSessionException;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
import okhttp3.Response;
public abstract class NewParseTask extends NetworkTask {
@@ -22,8 +23,10 @@ public abstract class NewParseTask extends NetworkTask {
protected final T performTask(Document document, Response response) {
try {
return parse(document, response);
+ } catch (InvalidSessionException ise) {
+ throw ise;
} catch (Exception e) {
- throw new ParseException("Parse failed.", e);
+ throw new ParseException("Parsing failed", e);
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
index 8f8f4c3a..49f619c2 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
@@ -30,7 +30,7 @@ import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.ExternalAsyncTask;
-import gr.thmmy.mthmmy.utils.NetworkTask;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import timber.log.Timber;
diff --git a/app/src/main/res/layout/fragment_unread.xml b/app/src/main/res/layout/fragment_unread.xml
index 4d1d5506..3da5651c 100644
--- a/app/src/main/res/layout/fragment_unread.xml
+++ b/app/src/main/res/layout/fragment_unread.xml
@@ -61,6 +61,7 @@
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/fab_margins"
android:layout_marginBottom="@dimen/fab_margins"
+ android:visibility="gone"
app:layout_behavior="gr.thmmy.mthmmy.utils.ui.ScrollAwareFABBehavior"
app:srcCompat="@drawable/ic_mark_as_read" />
\ No newline at end of file
From 2bdb37a2dfcadc7a74aa770a2f2b08a9486d08d8 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sat, 27 Jun 2020 12:51:24 +0300
Subject: [PATCH 14/21] Refactoring
---
.../gr/thmmy/mthmmy/base/BaseApplication.java | 59 ++++++++++++-------
.../thmmy/mthmmy/session/SessionManager.java | 48 +++++++--------
app/src/main/res/values/strings.xml | 8 ++-
3 files changed, 68 insertions(+), 47 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
index 51d01bba..390faf5c 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
@@ -48,6 +48,7 @@ import timber.log.Timber;
import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DISPLAY_RELATIVE_TIME;
+// TODO: Replace MultiDexApplication with Application after KitKat support is dropped
public class BaseApplication extends MultiDexApplication {
private static BaseApplication baseApplication; //BaseApplication singleton
@@ -63,9 +64,6 @@ public class BaseApplication extends MultiDexApplication {
private boolean displayRelativeTime;
- //TODO: maybe use PreferenceManager.getDefaultSharedPreferences here as well?
- private static final String SHARED_PREFS = "ThmmySharedPrefs";
-
//Display Metrics
private static float widthDp;
private static int widthPxl, heightPxl;
@@ -84,10 +82,32 @@ public class BaseApplication extends MultiDexApplication {
Timber.plant(new Timber.DebugTree());
//Shared Preferences
- SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
+ SharedPreferences sessionSharedPrefs = getSharedPreferences(getString(R.string.session_shared_prefs), MODE_PRIVATE);
SharedPreferences settingsSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences draftsPrefs = getSharedPreferences(getString(R.string.pref_topic_drafts_key), MODE_PRIVATE);
+ initFirebase(settingsSharedPrefs);
+
+ SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext());
+ PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor);
+
+ initOkHttp(cookieJar);
+
+ sessionManager = new SessionManager(client, cookieJar, sharedPrefsCookiePersistor, sessionSharedPrefs, draftsPrefs);
+
+ //Sets up upload service
+ UploadService.NAMESPACE = BuildConfig.APPLICATION_ID;
+ UploadService.HTTP_STACK = new OkHttpStack(client);
+
+ //Initialize and create the image loader logic for the drawer
+ initDrawerImageLoader();
+
+ setDisplayMetrics();
+
+ displayRelativeTime = settingsSharedPrefs.getBoolean(DISPLAY_RELATIVE_TIME, true);
+ }
+
+ private void initFirebase(SharedPreferences settingsSharedPrefs){
if (settingsSharedPrefs.getBoolean(getString(R.string.pref_privacy_crashlytics_enable_key), false)){
Timber.i("Starting app with Firebase Crashlytics enabled.");
setFirebaseCrashlyticsEnabled(true);
@@ -105,9 +125,10 @@ public class BaseApplication extends MultiDexApplication {
Timber.i("Starting app with Firebase Analytics enabled.");
else
Timber.i("Starting app with Firebase Analytics disabled.");
+ }
+
+ private void initOkHttp(PersistentCookieJar cookieJar){
- SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext());
- PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor);
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.addInterceptor(chain -> {
@@ -115,9 +136,9 @@ public class BaseApplication extends MultiDexApplication {
HttpUrl oldUrl = chain.request().url();
if (Objects.equals(chain.request().url().host(), "www.thmmy.gr")
&& !oldUrl.toString().contains("theme=4")) {
- //Probably works but needs more testing:
- HttpUrl newUrl = oldUrl.newBuilder().addQueryParameter("theme", "4").build();
- request = request.newBuilder().url(newUrl).build();
+ //Probably works but needs more testing:
+ HttpUrl newUrl = oldUrl.newBuilder().addQueryParameter("theme", "4").build();
+ request = request.newBuilder().url(newUrl).build();
}
return chain.proceed(request);
})
@@ -143,14 +164,9 @@ public class BaseApplication extends MultiDexApplication {
builder.addInterceptor(new OkHttpProfilerInterceptor());
client = builder.build();
+ }
- sessionManager = new SessionManager(client, cookieJar, sharedPrefsCookiePersistor, sharedPrefs, draftsPrefs);
-
- //Sets up upload service
- UploadService.NAMESPACE = BuildConfig.APPLICATION_ID;
- UploadService.HTTP_STACK = new OkHttpStack(client);
-
- //Initialize and create the image loader logic
+ private void initDrawerImageLoader(){
DrawerImageLoader.init(new AbstractDrawerImageLoader() {
@Override
public void set(ImageView imageView, Uri uri, Drawable placeholder, String tag) {
@@ -167,24 +183,25 @@ public class BaseApplication extends MultiDexApplication {
if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)) {
return new IconicsDrawable(ctx).icon(FontAwesome.Icon.faw_user)
.paddingDp(10)
- .color(ContextCompat.getColor(ctx, R.color.primary_light))
+ .color(ContextCompat.getColor(ctx, R.color.iron))
.backgroundColor(ContextCompat.getColor(ctx, R.color.primary));
}
return super.placeholder(ctx, tag);
}
});
+ }
+ private void setDisplayMetrics(){
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
widthPxl = displayMetrics.widthPixels;
widthDp = widthPxl / displayMetrics.density;
heightPxl = displayMetrics.heightPixels;
-
- displayRelativeTime = settingsSharedPrefs.getBoolean(DISPLAY_RELATIVE_TIME, true);
}
- //Getters
+
+ //-------------------- Getters --------------------
public Context getContext() {
return getApplicationContext();
}
@@ -213,7 +230,7 @@ public class BaseApplication extends MultiDexApplication {
return displayRelativeTime;
}
- //--------------------Firebase--------------------
+ //-------------------- Firebase --------------------
public void logFirebaseAnalyticsEvent(String event, Bundle params) {
firebaseAnalytics.logEvent(event, params);
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
index e87cdf05..2c5cc42b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
@@ -60,25 +60,25 @@ public class SessionManager {
private final SharedPrefsCookiePersistor cookiePersistor; //Used to explicitly edit cookies in cookieJar
//Shared Preferences & its keys
- private final SharedPreferences sharedPrefs;
+ private final SharedPreferences sessionSharedPrefs;
private final SharedPreferences draftsPrefs;
private static final String USERNAME = "Username";
private static final String USER_ID = "UserID";
- public static final String AVATAR_LINK = "AvatarLink";
- public static final String HAS_AVATAR = "HasAvatar";
+ private static final String AVATAR_LINK = "AvatarLink";
+ private static final String HAS_AVATAR = "HasAvatar";
private static final String SESC = "Sesc";
private static final String LOGOUT_LINK = "LogoutLink";
private static final String MARK_ALL_AS_READ_LINK = "MarkAllAsReadLink";
- public static final String LOGGED_IN = "LoggedIn";
+ private static final String LOGGED_IN = "LoggedIn";
private static final String LOGIN_SCREEN_AS_DEFAULT = "LoginScreenAsDefault";
//Constructor
public SessionManager(OkHttpClient client, PersistentCookieJar cookieJar,
- SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sharedPrefs, SharedPreferences draftsPrefs) {
+ SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sessionSharedPrefs, SharedPreferences draftsPrefs) {
this.client = client;
this.cookiePersistor = cookiePersistor;
this.cookieJar = cookieJar;
- this.sharedPrefs = sharedPrefs;
+ this.sessionSharedPrefs = sessionSharedPrefs;
this.draftsPrefs = draftsPrefs;
}
@@ -124,7 +124,7 @@ public class SessionManager {
setPersistentCookieSession(); //Store cookies
//Edit SharedPreferences, save session's data
- SharedPreferences.Editor editor = sharedPrefs.edit();
+ SharedPreferences.Editor editor = sessionSharedPrefs.edit();
setLoginScreenAsDefault(false);
editor.putBoolean(LOGGED_IN, true);
editor.putString(USERNAME, extractUserName(document));
@@ -247,10 +247,10 @@ public class SessionManager {
public void clearSessionData() {
cookieJar.clear();
- sharedPrefs.edit().clear().apply(); //Clear session data
- sharedPrefs.edit().putString(USERNAME, guestName).apply();
- sharedPrefs.edit().putInt(USER_ID, -1).apply();
- sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
+ sessionSharedPrefs.edit().clear().apply(); //Clear session data
+ sessionSharedPrefs.edit().putString(USERNAME, guestName).apply();
+ sessionSharedPrefs.edit().putInt(USER_ID, -1).apply();
+ sessionSharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
draftsPrefs.edit().clear().apply(); //Clear saved drafts
Timber.i("Session data cleared.");
}
@@ -267,15 +267,15 @@ public class SessionManager {
//---------------------------------------GETTERS------------------------------------------------
public String getUsername() {
- return sharedPrefs.getString(USERNAME, USERNAME);
+ return sessionSharedPrefs.getString(USERNAME, USERNAME);
}
public int getUserId() {
- return sharedPrefs.getInt(USER_ID, -1);
+ return sessionSharedPrefs.getInt(USER_ID, -1);
}
public String getAvatarLink() {
- return sharedPrefs.getString(AVATAR_LINK, AVATAR_LINK);
+ return sessionSharedPrefs.getString(AVATAR_LINK, AVATAR_LINK);
}
public Cookie getThmmyCookie() {
@@ -288,7 +288,7 @@ public class SessionManager {
}
public String getMarkAllAsReadLink() {
- String markAsReadLink = sharedPrefs.getString(MARK_ALL_AS_READ_LINK, null);
+ String markAsReadLink = sessionSharedPrefs.getString(MARK_ALL_AS_READ_LINK, null);
if(markAsReadLink == null){ //For older versions, extract it from logout link (otherwise user would have to login again)
String sesc = extractSescFromLink(getLogoutLink());
if(sesc!=null) {
@@ -302,38 +302,38 @@ public class SessionManager {
}
private String getLogoutLink() {
- return sharedPrefs.getString(LOGOUT_LINK, null);
+ return sessionSharedPrefs.getString(LOGOUT_LINK, null);
}
public boolean hasAvatar() {
- return sharedPrefs.getBoolean(HAS_AVATAR, false);
+ return sessionSharedPrefs.getBoolean(HAS_AVATAR, false);
}
public boolean isLoggedIn() {
- return sharedPrefs.getBoolean(LOGGED_IN, false);
+ return sessionSharedPrefs.getBoolean(LOGGED_IN, false);
}
public boolean isLoginScreenDefault() {
- return sharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true);
+ return sessionSharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true);
}
//--------------------------------------GETTERS END---------------------------------------------
//---------------------------------------SETTERS------------------------------------------------
private void setSesc(String sesc){
- SharedPreferences.Editor editor = sharedPrefs.edit();
+ SharedPreferences.Editor editor = sessionSharedPrefs.edit();
editor.putString(SESC, sesc);
editor.apply();
}
private void setMarkAsReadLink(String markAllAsReadLink){
- SharedPreferences.Editor editor = sharedPrefs.edit();
+ SharedPreferences.Editor editor = sessionSharedPrefs.edit();
editor.putString(MARK_ALL_AS_READ_LINK, markAllAsReadLink);
editor.apply();
}
private void setLogoutLink(String logoutLink){
- SharedPreferences.Editor editor = sharedPrefs.edit();
+ SharedPreferences.Editor editor = sessionSharedPrefs.edit();
editor.putString(LOGOUT_LINK, logoutLink);
editor.apply();
}
@@ -367,7 +367,7 @@ public class SessionManager {
}
private void setLoginScreenAsDefault(boolean b){
- sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, b).apply();
+ sessionSharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, b).apply();
}
@NonNull
@@ -448,7 +448,7 @@ public class SessionManager {
if (matcher.find())
return matcher.group(1);
}
- Timber.e(new ParseException("Parsing failed(extractSescFromLogoutLink)"),"ParseException");
+ Timber.e(new ParseException("Parsing failed(extractSescFromLink)"),"ParseException");
return null;
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d1c69acb..f881b88d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -209,7 +209,7 @@
Analytics data reports
Automatically send us anonymized data for analytical purposes
-
+
Black
Red
Yellow
@@ -229,8 +229,12 @@
Link text
Required
-
+
New topic
Create topic
Link copied
+
+
+ SessionSharedPrefs
+
From 5cc2e503f0f7879359b4aabe4a77eefc9ab0df4c Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sat, 27 Jun 2020 18:54:49 +0300
Subject: [PATCH 15/21] SessionManager, mark unread & logout improvements
---
.../main/unread/UnreadFragment.java | 87 ++------
.../gr/thmmy/mthmmy/base/BaseActivity.java | 71 +++----
.../gr/thmmy/mthmmy/base/BaseApplication.java | 1 -
.../gr/thmmy/mthmmy/session/LogoutTask.java | 86 ++++++++
.../thmmy/mthmmy/session/MarkAsReadTask.java | 65 ++++++
.../thmmy/mthmmy/session/SessionManager.java | 196 ++----------------
.../mthmmy/session/ValidateSessionTask.java | 18 --
.../mthmmy/utils/networking/NetworkTask.java | 25 ++-
8 files changed, 235 insertions(+), 314 deletions(-)
create mode 100644 app/src/main/java/gr/thmmy/mthmmy/session/LogoutTask.java
create mode 100644 app/src/main/java/gr/thmmy/mthmmy/session/MarkAsReadTask.java
delete mode 100644 app/src/main/java/gr/thmmy/mthmmy/session/ValidateSessionTask.java
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 a8ba7f10..124c35c4 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
@@ -26,19 +26,17 @@ import java.util.ArrayList;
import java.util.List;
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.InvalidSessionException;
+import gr.thmmy.mthmmy.session.MarkAsReadTask;
import gr.thmmy.mthmmy.session.SessionManager;
-import gr.thmmy.mthmmy.session.ValidateSessionTask;
import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.parsing.NewParseTask;
import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.views.CustomRecyclerView;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import okhttp3.Response;
-import timber.log.Timber;
/**
* A {@link BaseFragment} subclass.
@@ -60,13 +58,11 @@ public class UnreadFragment extends BaseFragment {
private UnreadAdapter unreadAdapter;
private List topicSummaries;
- private String markAsReadUrl;
private int numberOfPages = 0;
private int loadedPages = 0;
private UnreadTask unreadTask;
- private MarkReadTask markReadTask;
- private ValidateSessionTask validateSessionTask;
+ private MarkAsReadTask markAsReadTask;
// Required empty public constructor
public UnreadFragment() {}
@@ -90,11 +86,6 @@ public class UnreadFragment extends BaseFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
topicSummaries = new ArrayList<>();
- markAsReadUrl = BaseApplication.getInstance().getSessionManager().getMarkAllAsReadLink();
- if(markAsReadUrl==null){
- Timber.i("MarkAsRead URL is null.");
- startValidateSessionTask();
- }
}
@Override
@@ -105,7 +96,7 @@ public class UnreadFragment extends BaseFragment {
assert SessionManager.unreadUrl != null;
unreadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.unreadUrl.toString());
}
- markReadTask = new MarkReadTask(this::onMarkReadTaskStarted, this::onMarkReadTaskFinished);
+ markAsReadTask = new MarkAsReadTask(UnreadFragment.this::onMarkAsReadTaskStarted, UnreadFragment.this::onMarkAsReadTaskFinished);
}
@@ -146,17 +137,10 @@ public class UnreadFragment extends BaseFragment {
public void onDestroy() {
super.onDestroy();
cancelUnreadTaskIfRunning();
- if (markReadTask!=null){
- try{
- if(markReadTask.isRunning())
- markReadTask.cancel(true);
- } // Yes, it happens even though we checked
- catch (NullPointerException ignored){ }
- }
- if (validateSessionTask!=null){
+ if (markAsReadTask !=null){
try{
- if(validateSessionTask.isRunning())
- validateSessionTask.cancel(true);
+ if(markAsReadTask.isRunning())
+ markAsReadTask.cancel(true);
} // Yes, it happens even though we checked
catch (NullPointerException ignored){ }
}
@@ -179,11 +163,6 @@ public class UnreadFragment extends BaseFragment {
}
}
- private void startValidateSessionTask(){
- validateSessionTask = new ValidateSessionTask();
- validateSessionTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
private void cancelUnreadTaskIfRunning(){
if (unreadTask!=null){
try{
@@ -215,9 +194,9 @@ public class UnreadFragment extends BaseFragment {
builder.setTitle("Mark all as read");
builder.setMessage("Are you sure that you want to mark ALL topics as read?");
builder.setPositiveButton("Yep", (dialogInterface, i) -> {
- if (!markReadTask.isRunning() && markAsReadUrl!=null){
- markReadTask = new MarkReadTask(this::onMarkReadTaskStarted, this::onMarkReadTaskFinished);
- markReadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, markAsReadUrl);
+ if (!markAsReadTask.isRunning()){
+ markAsReadTask = new MarkAsReadTask(this::onMarkAsReadTaskStarted, this::onMarkAsReadTaskFinished);
+ markAsReadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
builder.setNegativeButton("Nope", (dialogInterface, i) -> {});
@@ -304,12 +283,10 @@ public class UnreadFragment extends BaseFragment {
}
Element topBar = document.select("table:not(.bordercolor):not(#bodyarea):has(td.middletext)").first();
- Element pagesElement = null, markRead = null;
- if (topBar != null) {
+ Element pagesElement = null;
+ if (topBar != null)
pagesElement = topBar.select("td.middletext").first();
- markRead = document.select("table:not(.bordercolor):not([width])").select("a")
- .first();
- }
+
if (numberOfPages == 0 && pagesElement != null) {
Elements pages = pagesElement.select("a");
@@ -319,14 +296,6 @@ public class UnreadFragment extends BaseFragment {
numberOfPages = 1;
}
- if (markRead != null && loadedPages == numberOfPages - 1){
- String retrievedMarkAsReadUrl = markRead.attr("href");
- if(!retrievedMarkAsReadUrl.equals(markAsReadUrl)) {
- markAsReadUrl = retrievedMarkAsReadUrl;
- BaseApplication.getInstance().getSessionManager().refreshSescFromUrl(retrievedMarkAsReadUrl);
- }
- }
-
return fetchedTopicSummaries;
}
return new ArrayList<>();
@@ -338,13 +307,13 @@ public class UnreadFragment extends BaseFragment {
}
}
- //---------------------------------------MARKREAD TASK------------------------------------------
- private void onMarkReadTaskStarted() {
+ //---------------------------------------MARK AS READ TASK------------------------------------------
+ private void onMarkAsReadTaskStarted() {
cancelUnreadTaskIfRunning();
progressBar.setVisibility(ProgressBar.VISIBLE);
}
- private void onMarkReadTaskFinished(int resultCode, Void isSessionVerified) {
+ private void onMarkAsReadTaskFinished(int resultCode, Void v) {
hideProgressUI();
if (resultCode == NetworkResultCodes.SUCCESSFUL)
startUnreadTask();
@@ -352,35 +321,11 @@ public class UnreadFragment extends BaseFragment {
hideProgressUI();
if (resultCode == NetworkResultCodes.NETWORK_ERROR)
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
- else if (resultCode == SessionManager.INVALID_SESSION){
+ else if (resultCode == SessionManager.INVALID_SESSION)
Toast.makeText(getContext(), "Session verification failed. Please try logging out and back in again", Toast.LENGTH_LONG).show();
- startValidateSessionTask();
- }
else
Toast.makeText(getContext(), "Unexpected error," +
" please contact the developers with the details", Toast.LENGTH_LONG).show();
}
}
-
- private class MarkReadTask extends NewParseTask {
- MarkReadTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
- super(onTaskStartedListener, onParseTaskFinishedListener);
- }
-
- @Override
- protected Void parse(Document document, Response response) throws ParseException {
- Elements sessionVerificationFailed = document.select("td:containsOwn(Session " +
- "verification failed. Please try logging out and back in again, and then try " +
- "again.), td:containsOwn(Η επαλήθευση συνόδου απέτυχε. Παρακαλούμε κάντε " +
- "αποσύνδεση, επανασύνδεση και ξαναδοκιμάστε.)");
- if(!sessionVerificationFailed.isEmpty())
- throw new InvalidSessionException();
- return null;
- }
-
- @Override
- protected int getResultCode(Response response, Void v) {
- return NetworkResultCodes.SUCCESSFUL;
- }
- }
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
index defaa6d3..6c571129 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
@@ -62,9 +62,11 @@ import gr.thmmy.mthmmy.model.Bookmark;
import gr.thmmy.mthmmy.model.ThmmyFile;
import gr.thmmy.mthmmy.services.DownloadHelper;
import gr.thmmy.mthmmy.services.UploadsReceiver;
+import gr.thmmy.mthmmy.session.LogoutTask;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.FileUtils;
import gr.thmmy.mthmmy.utils.io.AssetUtils;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
import gr.thmmy.mthmmy.viewmodel.BaseViewModel;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import okhttp3.OkHttpClient;
@@ -82,7 +84,6 @@ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_
import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DEFAULT_HOME_TAB;
import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR;
import static gr.thmmy.mthmmy.services.UploadsReceiver.UPLOAD_ID_KEY;
-import static gr.thmmy.mthmmy.session.SessionManager.SUCCESS;
import static gr.thmmy.mthmmy.utils.FileUtils.getMimeType;
public abstract class BaseActivity extends AppCompatActivity {
@@ -497,47 +498,35 @@ public abstract class BaseActivity extends AppCompatActivity {
}
//-------------------------------------------LOGOUT-------------------------------------------------
-
- /**
- * Result toast will always display a success, because when user chooses logout all data are
- * cleared regardless of the actual outcome
- */
- private class LogoutTask extends AsyncTask { //Attempt logout
- ProgressDialog progressDialog;
-
- protected Integer doInBackground(Void... voids) {
- return sessionManager.logout();
- }
-
- protected void onPreExecute() { //Show a progress dialog until done
- progressDialog = new ProgressDialog(BaseActivity.this,
- R.style.AppTheme_Dark_Dialog);
- progressDialog.setCancelable(false);
- progressDialog.setIndeterminate(true);
- progressDialog.setMessage("Logging out...");
- progressDialog.show();
- }
-
- protected void onPostExecute(Integer result) {
- if (result == SUCCESS) {
- SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- if (sharedPrefs.getString(DEFAULT_HOME_TAB, "0").equals("2")) {
- SharedPreferences.Editor editor = sharedPrefs.edit();
- editor.putString(DEFAULT_HOME_TAB, "0").apply();
- }
+ private ProgressDialog progressDialog;
+ private void onLogoutTaskStarted() {
+ progressDialog = new ProgressDialog(BaseActivity.this,
+ R.style.AppTheme_Dark_Dialog);
+ progressDialog.setCancelable(false);
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage("Logging out...");
+ progressDialog.show();
+ }
+
+ private void onLogoutTaskFinished(int resultCode, Void v) {
+ if (resultCode == NetworkResultCodes.SUCCESSFUL) {
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ if (sharedPrefs.getString(DEFAULT_HOME_TAB, "0").equals("2")) {
+ SharedPreferences.Editor editor = sharedPrefs.edit();
+ editor.putString(DEFAULT_HOME_TAB, "0").apply();
}
-
- updateDrawer();
- if (mainActivity != null)
- mainActivity.updateTabs();
- progressDialog.dismiss();
- //TODO: Redirect to Main only for some Activities (e.g. Topic, Board, Downloads)
- //if (BaseActivity.this instanceof TopicActivity){
- Intent intent = new Intent(BaseActivity.this, MainActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- //}
}
+
+ updateDrawer();
+ if (mainActivity != null)
+ mainActivity.updateTabs();
+ progressDialog.dismiss();
+ //TODO: Redirect to Main only for some Activities (e.g. Topic, Board, Downloads)
+ //if (BaseActivity.this instanceof TopicActivity){
+ Intent intent = new Intent(BaseActivity.this, MainActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ //}
}
private void showLogoutDialog() {
@@ -545,7 +534,7 @@ public abstract class BaseActivity extends AppCompatActivity {
builder.setTitle("Logout");
builder.setMessage("Are you sure that you want to logout?");
builder.setPositiveButton("Yep", (dialogInterface, i) -> {
- new LogoutTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); //Avoid delays between onPreExecute() and doInBackground()
+ new LogoutTask(this::onLogoutTaskStarted, this::onLogoutTaskFinished).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); //Avoid delays between onPreExecute() and doInBackground()
});
builder.setNegativeButton("Nope", (dialogInterface, i) -> {});
builder.create().show();
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
index 390faf5c..dea0808b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
@@ -128,7 +128,6 @@ public class BaseApplication extends MultiDexApplication {
}
private void initOkHttp(PersistentCookieJar cookieJar){
-
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.addInterceptor(chain -> {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/LogoutTask.java b/app/src/main/java/gr/thmmy/mthmmy/session/LogoutTask.java
new file mode 100644
index 00000000..66333739
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/session/LogoutTask.java
@@ -0,0 +1,86 @@
+package gr.thmmy.mthmmy.session;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.select.Elements;
+
+import gr.thmmy.mthmmy.base.BaseApplication;
+import gr.thmmy.mthmmy.utils.Parcel;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
+import gr.thmmy.mthmmy.utils.parsing.ParseException;
+import okhttp3.Response;
+import timber.log.Timber;
+
+import static gr.thmmy.mthmmy.session.SessionManager.baseLogoutLink;
+import static gr.thmmy.mthmmy.session.SessionManager.indexUrl;
+
+
+public class LogoutTask extends NetworkTask {
+ private String logoutLink;
+
+ public LogoutTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
+ super(onTaskStartedListener, onParseTaskFinishedListener);
+ }
+
+ @Override
+ protected Parcel doInBackground(String... input) {
+ /* Firstly we will find the logout link
+ Keep in mind, server changes sesc at will over time for a given session!
+ */
+ Parcel parcel = executeInBackground(indexUrl.toString());
+ if(parcel.getResultCode() == NetworkResultCodes.SUCCESSFUL)
+ return executeInBackground(logoutLink); // Now we will attempt to logout
+ else return parcel;
+ }
+
+ @Override
+ protected Void performTask(Document document, Response response) {
+ try {
+ if(logoutLink==null)
+ logoutLink = extractLogoutLink(document);
+ else { // Just for logging purposes
+ Elements sessionVerificationFailed = document.select("td:containsOwn(Session " +
+ "verification failed. Please try logging out and back in again, and then try " +
+ "again.), td:containsOwn(Η επαλήθευση συνόδου απέτυχε. Παρακαλούμε κάντε " +
+ "αποσύνδεση, επανασύνδεση και ξαναδοκιμάστε.)");
+ if(!sessionVerificationFailed.isEmpty()){
+ Timber.i("Logout failed (invalid session)");
+ throw new InvalidSessionException();
+ }
+ Elements loginButton = document.select("[value=Login]"); //Attempt to find login button
+ if (!loginButton.isEmpty()) //If login button exists, logout was successful
+ Timber.i("Logout successful!");
+ else
+ Timber.i("Logout failed");
+ }
+ } catch (InvalidSessionException ise) {
+ throw ise;
+ } catch (Exception e) {
+ throw new ParseException("Parsing failed", e);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Parcel voidParcel) {
+ super.onPostExecute(voidParcel);
+ //All data should always be cleared from device regardless the result of logout
+ BaseApplication.getInstance().getSessionManager().logoutCleanup();
+ }
+
+ @Override
+ protected int getResultCode(Response response, Void v) {
+ return NetworkResultCodes.SUCCESSFUL;
+ }
+
+ private String extractLogoutLink(Document document){
+ Elements logoutLink = document.select("a[href^=" + baseLogoutLink + "]");
+
+ if (!logoutLink.isEmpty()) {
+ String link = logoutLink.first().attr("href");
+ if (link != null && !link.isEmpty())
+ return link;
+ }
+ throw new ParseException("Parsing failed (logoutLink extraction)");
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/MarkAsReadTask.java b/app/src/main/java/gr/thmmy/mthmmy/session/MarkAsReadTask.java
new file mode 100644
index 00000000..684f87ba
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/session/MarkAsReadTask.java
@@ -0,0 +1,65 @@
+package gr.thmmy.mthmmy.session;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.select.Elements;
+
+import gr.thmmy.mthmmy.utils.Parcel;
+import gr.thmmy.mthmmy.utils.networking.NetworkResultCodes;
+import gr.thmmy.mthmmy.utils.networking.NetworkTask;
+import gr.thmmy.mthmmy.utils.parsing.ParseException;
+import okhttp3.Response;
+
+import static gr.thmmy.mthmmy.session.SessionManager.baseMarkAllAsReadLink;
+import static gr.thmmy.mthmmy.session.SessionManager.unreadUrl;
+
+public class MarkAsReadTask extends NetworkTask {
+ private String markAsReadLink;
+
+ public MarkAsReadTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener onParseTaskFinishedListener) {
+ super(onTaskStartedListener, onParseTaskFinishedListener);
+ }
+
+ @Override
+ protected Parcel doInBackground(String... input) {
+ Parcel parcel = executeInBackground(unreadUrl.toString());
+ if(parcel.getResultCode() == NetworkResultCodes.SUCCESSFUL)
+ return executeInBackground(markAsReadLink);
+ else return parcel;
+ }
+
+ @Override
+ protected Void performTask(Document document, Response response) {
+ try {
+ Elements sessionVerificationFailed = document.select("td:containsOwn(Session " +
+ "verification failed. Please try logging out and back in again, and then try " +
+ "again.), td:containsOwn(Η επαλήθευση συνόδου απέτυχε. Παρακαλούμε κάντε " +
+ "αποσύνδεση, επανασύνδεση και ξαναδοκιμάστε.)");
+ if(!sessionVerificationFailed.isEmpty())
+ throw new InvalidSessionException();
+ if(markAsReadLink==null)
+ markAsReadLink = extractMarkAsReadLink(document);
+
+ } catch (InvalidSessionException ise) {
+ throw ise;
+ } catch (Exception e) {
+ throw new ParseException("Parsing failed", e);
+ }
+ return null;
+ }
+
+ @Override
+ protected int getResultCode(Response response, Void v) {
+ return NetworkResultCodes.SUCCESSFUL;
+ }
+
+ private String extractMarkAsReadLink(Document document){
+ Elements markAllAsReadLink = document.select("a[href^=" + baseMarkAllAsReadLink + "]");
+
+ if (!markAllAsReadLink.isEmpty()) {
+ String link = markAllAsReadLink.first().attr("href");
+ if (link != null && !link.isEmpty())
+ return link;
+ }
+ throw new ParseException("Parsing failed (markAllAsReadLink extraction)");
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
index 2c5cc42b..fff30acf 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java
@@ -39,8 +39,8 @@ public class SessionManager {
private static final HttpUrl loginUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=login2");
public static final HttpUrl unreadUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=unread;all;start=0;theme=4");
public static final HttpUrl shoutboxUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=tpmod;sa=shoutbox;theme=4");
- private static final String baseLogoutLink = "https://www.thmmy.gr/smf/index.php?action=logout;sesc=";
- private static final String baseMarkAllAsReadLink = "https://www.thmmy.gr/smf/index.php?action=markasread;sa=all;sesc=";
+ static final String baseLogoutLink = "https://www.thmmy.gr/smf/index.php?action=logout;sesc=";
+ static final String baseMarkAllAsReadLink = "https://www.thmmy.gr/smf/index.php?action=markasread;sa=all;sesc=";
private static final String guestName = "Guest";
//Response Codes - make sure they do not overlap with NetworkResultCodes, just in case
@@ -66,9 +66,6 @@ public class SessionManager {
private static final String USER_ID = "UserID";
private static final String AVATAR_LINK = "AvatarLink";
private static final String HAS_AVATAR = "HasAvatar";
- private static final String SESC = "Sesc";
- private static final String LOGOUT_LINK = "LogoutLink";
- private static final String MARK_ALL_AS_READ_LINK = "MarkAllAsReadLink";
private static final String LOGGED_IN = "LoggedIn";
private static final String LOGIN_SCREEN_AS_DEFAULT = "LoginScreenAsDefault";
@@ -82,37 +79,29 @@ public class SessionManager {
this.draftsPrefs = draftsPrefs;
}
- //------------------------------------AUTH BEGINS----------------------------------------------
+ //------------------------------------ AUTH ----------------------------------------------
/**
* Login function with two options: (username, password) or nothing (using saved cookies).
* Always call it in a separate thread.
*/
- public int login(String... strings) {
+ public int login(String username, String password) {
Timber.d("Logging in...");
//Build the login request for each case
Request request;
- if (strings.length == 2) {
- clearSessionData();
-
- String loginName = strings[0];
- String password = strings[1];
-
- RequestBody formBody = new FormBody.Builder()
- .add("user", loginName)
- .add("passwrd", password)
- .add("cookielength", "-1") //-1 is forever
- .build();
- request = new Request.Builder()
- .url(loginUrl)
- .post(formBody)
- .build();
- } else {
- request = new Request.Builder()
- .url(loginUrl)
- .build();
- }
+ clearSessionData();
+
+ RequestBody formBody = new FormBody.Builder()
+ .add("user", username)
+ .add("passwrd", password)
+ .add("cookielength", "-1") //-1 is forever
+ .build();
+ request = new Request.Builder()
+ .url(loginUrl)
+ .post(formBody)
+ .build();
+
try {
//Make request & handle response
@@ -133,10 +122,6 @@ public class SessionManager {
if (avatar != null)
editor.putString(AVATAR_LINK, avatar);
editor.putBoolean(HAS_AVATAR, avatar != null);
- String sesc = extractSesc(document);
- editor.putString(SESC, sesc);
- editor.putString(LOGOUT_LINK, generateLogoutLink(sesc));
- editor.putString(MARK_ALL_AS_READ_LINK, generateMarkAllAsReadLink(sesc));
editor.apply();
return SUCCESS;
@@ -179,29 +164,6 @@ public class SessionManager {
}
}
- /**
- * A function that checks the validity of the current saved session (if it exists).
- * If isLoggedIn() is true, it will call login() with cookies. On failure, this can only return
- * the code FAILURE. CANCELLED, CONNECTION_ERROR and EXCEPTION are simply considered a SUCCESS
- * (e.g. no internet connection), at least until a more thorough handling of different
- * exceptions is implemented (if considered mandatory).
- * Always call it in a separate thread in a way that won't hinder performance (e.g. after
- * fragments' data are retrieved).
- */
- void validateSession() {
- Timber.i("Validating session...");
- if (isLoggedIn()) {
- Timber.i("Refreshing session...");
- int loginResult = login();
- if (loginResult != FAILURE)
- return;
- } else if (isLoginScreenDefault())
- return;
-
- setLoginScreenAsDefault(true);
- clearSessionData();
- }
-
/**
* Call this function when user explicitly chooses to continue as a guest (UI thread).
*/
@@ -211,41 +173,12 @@ public class SessionManager {
setLoginScreenAsDefault(false);
}
- /**
- * Logout function. Always call it in a separate thread.
- */
- public int logout() {
- Timber.i("Logging out...");
- try {
- Request request = new Request.Builder()
- .url(getLogoutLink())
- .build();
- //Make request & handle response
- Response response = client.newCall(request).execute();
- Document document = Jsoup.parse(response.body().string());
-
- Elements loginButton = document.select("[value=Login]"); //Attempt to find login button
- if (!loginButton.isEmpty()){ //If login button exists, logout was successful
- Timber.i("Logout successful!");
- return SUCCESS;
- } else {
- Timber.i("Logout failed.");
- return FAILURE;
- }
- } catch (IOException e) {
- Timber.w(e, "Logout IOException");
- return CONNECTION_ERROR;
- } catch (Exception e) {
- Timber.e(e, "Logout Exception");
- return EXCEPTION;
- } finally {
- //All data should always be cleared from device regardless the result of logout
- clearSessionData();
- guestLogin();
- }
+ void logoutCleanup() {
+ clearSessionData();
+ guestLogin();
}
- public void clearSessionData() {
+ private void clearSessionData() {
cookieJar.clear();
sessionSharedPrefs.edit().clear().apply(); //Clear session data
sessionSharedPrefs.edit().putString(USERNAME, guestName).apply();
@@ -255,17 +188,7 @@ public class SessionManager {
Timber.i("Session data cleared.");
}
- public void refreshSescFromUrl(String url){
- String sesc = extractSescFromLink(url);
- if(sesc!=null){
- setSesc(sesc);
- setLogoutLink(generateLogoutLink(sesc));
- setMarkAsReadLink(sesc);
- }
- }
- //--------------------------------------AUTH ENDS-----------------------------------------------
-
- //---------------------------------------GETTERS------------------------------------------------
+ //--------------------------------------- GETTERS ------------------------------------------------
public String getUsername() {
return sessionSharedPrefs.getString(USERNAME, USERNAME);
}
@@ -287,24 +210,6 @@ public class SessionManager {
return null;
}
- public String getMarkAllAsReadLink() {
- String markAsReadLink = sessionSharedPrefs.getString(MARK_ALL_AS_READ_LINK, null);
- if(markAsReadLink == null){ //For older versions, extract it from logout link (otherwise user would have to login again)
- String sesc = extractSescFromLink(getLogoutLink());
- if(sesc!=null) {
- setSesc(sesc);
- markAsReadLink = generateMarkAllAsReadLink(sesc);
- setMarkAsReadLink(markAsReadLink);
- return markAsReadLink;
- }
- }
- return markAsReadLink; // Warning: it can be null
- }
-
- private String getLogoutLink() {
- return sessionSharedPrefs.getString(LOGOUT_LINK, null);
- }
-
public boolean hasAvatar() {
return sessionSharedPrefs.getBoolean(HAS_AVATAR, false);
}
@@ -317,34 +222,10 @@ public class SessionManager {
return sessionSharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true);
}
- //--------------------------------------GETTERS END---------------------------------------------
-
- //---------------------------------------SETTERS------------------------------------------------
- private void setSesc(String sesc){
- SharedPreferences.Editor editor = sessionSharedPrefs.edit();
- editor.putString(SESC, sesc);
- editor.apply();
- }
-
- private void setMarkAsReadLink(String markAllAsReadLink){
- SharedPreferences.Editor editor = sessionSharedPrefs.edit();
- editor.putString(MARK_ALL_AS_READ_LINK, markAllAsReadLink);
- editor.apply();
- }
-
- private void setLogoutLink(String logoutLink){
- SharedPreferences.Editor editor = sessionSharedPrefs.edit();
- editor.putString(LOGOUT_LINK, logoutLink);
- editor.apply();
- }
-
- //--------------------------------------SETTERS END---------------------------------------------
-
- //------------------------------------OTHER FUNCTIONS-------------------------------------------
+ //------------------------------------ OTHER -------------------------------------------
private boolean validateRetrievedCookies() {
List cookieList = cookieJar.loadForRequest(indexUrl);
- for(Cookie cookie: cookieList)
- {
+ for(Cookie cookie: cookieList) {
if(cookie.name().equals("THMMYgrC00ki3"))
return true;
}
@@ -363,7 +244,6 @@ public class SessionManager {
cookieList.add(builder.build());
cookiePersistor.clear();
cookiePersistor.saveAll(cookieList);
-
}
private void setLoginScreenAsDefault(boolean b){
@@ -430,34 +310,4 @@ public class SessionManager {
Timber.i("Extracting avatar's link failed!");
return null;
}
-
- private String extractSesc(@NonNull Document doc) {
- Elements logoutLink = doc.select("a[href^=https://www.thmmy.gr/smf/index.php?action=logout;sesc=]");
- if (!logoutLink.isEmpty()) {
- String link = logoutLink.first().attr("href");
- return extractSescFromLink(link);
- }
- Timber.e(new ParseException("Parsing failed(extractSesc)"),"ParseException");
- return null;
- }
-
- private String extractSescFromLink(String link){
- if (link != null){
- Pattern pattern = Pattern.compile(".+;sesc=(\\w+)");
- Matcher matcher = pattern.matcher(link);
- if (matcher.find())
- return matcher.group(1);
- }
- Timber.e(new ParseException("Parsing failed(extractSescFromLink)"),"ParseException");
- return null;
- }
-
- private String generateLogoutLink(String sesc){
- return baseLogoutLink + sesc;
- }
-
- private String generateMarkAllAsReadLink(String sesc){
- return baseMarkAllAsReadLink + sesc;
- }
- //----------------------------------OTHER FUNCTIONS END-----------------------------------------
}
\ No newline at end of file
diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/ValidateSessionTask.java b/app/src/main/java/gr/thmmy/mthmmy/session/ValidateSessionTask.java
deleted file mode 100644
index b5c1392f..00000000
--- a/app/src/main/java/gr/thmmy/mthmmy/session/ValidateSessionTask.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package gr.thmmy.mthmmy.session;
-
-import android.os.AsyncTask;
-
-import gr.thmmy.mthmmy.base.BaseApplication;
-
-
-public class ValidateSessionTask extends AsyncTask {
- @Override
- protected Void doInBackground(String... params) {
- BaseApplication.getInstance().getSessionManager().validateSession();
- return null;
- }
-
- public boolean isRunning(){
- return getStatus() == AsyncTask.Status.RUNNING;
- }
-}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java
index a12d5757..0ba26dd3 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java
@@ -1,7 +1,8 @@
package gr.thmmy.mthmmy.utils.networking;
import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
+
+import androidx.preference.PreferenceManager;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@@ -38,7 +39,19 @@ public abstract class NetworkTask extends ExternalAsyncTask
public NetworkTask() {}
@Override
- protected final Parcel doInBackground(String... input) {
+ protected Parcel doInBackground(String... input) {
+ return executeInBackground(input);
+ }
+
+ @Override
+ protected void onPostExecute(Parcel tParcel) {
+ if (onNetworkTaskFinishedListener != null)
+ onNetworkTaskFinishedListener.onNetworkTaskFinished(tParcel.getResultCode(), tParcel.getData());
+ else
+ super.onPostExecute(tParcel);
+ }
+
+ protected Parcel executeInBackground(String... input) {
Response response;
try {
response = sendRequest(BaseApplication.getInstance().getClient(), input);
@@ -78,14 +91,6 @@ public abstract class NetworkTask extends ExternalAsyncTask
}
}
- @Override
- protected void onPostExecute(Parcel tParcel) {
- if (onNetworkTaskFinishedListener != null)
- onNetworkTaskFinishedListener.onNetworkTaskFinished(tParcel.getResultCode(), tParcel.getData());
- else
- super.onPostExecute(tParcel);
- }
-
protected Response sendRequest(OkHttpClient client, String... input) throws IOException {
String url = input[0];
Request request = new Request.Builder()
From 573751acf4d92bf0fe0757cc0b8a3d7746ad7f58 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sat, 27 Jun 2020 19:36:25 +0300
Subject: [PATCH 16/21] UnreadFragment FAB tiny fix
---
.../thmmy/mthmmy/activities/main/unread/UnreadFragment.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
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 124c35c4..661ed1be 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
@@ -92,10 +92,13 @@ public class UnreadFragment extends BaseFragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (topicSummaries.isEmpty()){
+ hideMarkAsReadFAB();
unreadTask = new UnreadTask(this::onUnreadTaskStarted, UnreadFragment.this::onUnreadTaskCancelled, this::onUnreadTaskFinished);
assert SessionManager.unreadUrl != null;
unreadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.unreadUrl.toString());
}
+ else
+ showMarkAsReadFAB();
markAsReadTask = new MarkAsReadTask(UnreadFragment.this::onMarkAsReadTaskStarted, UnreadFragment.this::onMarkAsReadTaskFinished);
}
@@ -129,7 +132,6 @@ public class UnreadFragment extends BaseFragment {
this::startUnreadTask
);
}
-
return rootView;
}
From e96d0bd7999ff25cb4739d658b170a49a3198edf Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sat, 27 Jun 2020 20:11:52 +0300
Subject: [PATCH 17/21] Colors refactoring
---
app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java | 8 ++++----
.../main/java/gr/thmmy/mthmmy/base/BaseApplication.java | 2 +-
app/src/main/res/layout/activity_about.xml | 2 +-
app/src/main/res/layout/activity_settings.xml | 2 +-
app/src/main/res/layout/activity_upload.xml | 6 +++---
.../main/res/layout/activity_upload_fields_builder.xml | 2 +-
.../res/layout/activity_upload_filename_info_popup.xml | 2 +-
app/src/main/res/layout/download_prompt_dialog.xml | 2 +-
app/src/main/res/layout/fragment_bookmarks.xml | 2 +-
app/src/main/res/layout/fragment_forum_board_row.xml | 2 +-
app/src/main/res/layout/fragment_forum_category_row.xml | 2 +-
app/src/main/res/layout/fragment_recent_row.xml | 2 +-
app/src/main/res/layout/fragment_unread_row.xml | 2 +-
app/src/main/res/values/colors.xml | 7 ++++---
app/src/main/res/values/styles.xml | 6 +++---
15 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
index 6c571129..d31b7993 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
@@ -206,7 +206,7 @@ public abstract class BaseActivity extends AppCompatActivity {
*/
protected void createDrawer() {
final int primaryColor = ContextCompat.getColor(this, R.color.iron);
- final int selectedPrimaryColor = ContextCompat.getColor(this, R.color.primary_dark);
+ final int selectedPrimaryColor = ContextCompat.getColor(this, R.color.primary_light);
final int selectedSecondaryColor = ContextCompat.getColor(this, R.color.accent);
PrimaryDrawerItem homeItem, bookmarksItem, settingsItem, aboutItem, shoutboxItem;
@@ -361,7 +361,7 @@ public abstract class BaseActivity extends AppCompatActivity {
.withActivity(this)
.withCompactStyle(true)
.withSelectionListEnabledForSingleProfile(false)
- .withHeaderBackground(R.color.primary)
+ .withHeaderBackground(R.color.primary_dark)
.withTextColor(getResources().getColor(R.color.iron))
.addProfiles(profileDrawerItem)
.withOnAccountHeaderListener((view, profile, currentProfile) -> {
@@ -390,7 +390,7 @@ public abstract class BaseActivity extends AppCompatActivity {
.withActivity(this)
.withToolbar(toolbar)
.withDrawerWidthDp((int) BaseApplication.getInstance().getWidthInDp() / 2)
- .withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_light))
+ .withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_lighter))
.withAccountHeader(accountHeader)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
if (drawerItem.equals(HOME_ID)) {
@@ -494,7 +494,7 @@ public abstract class BaseActivity extends AppCompatActivity {
.icon(FontAwesome.Icon.faw_user)
.paddingDp(10)
.color(ContextCompat.getColor(this, R.color.iron))
- .backgroundColor(ContextCompat.getColor(this, R.color.primary_light)));
+ .backgroundColor(ContextCompat.getColor(this, R.color.primary_lighter)));
}
//-------------------------------------------LOGOUT-------------------------------------------------
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
index dea0808b..49ff1c0e 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
@@ -183,7 +183,7 @@ public class BaseApplication extends MultiDexApplication {
return new IconicsDrawable(ctx).icon(FontAwesome.Icon.faw_user)
.paddingDp(10)
.color(ContextCompat.getColor(ctx, R.color.iron))
- .backgroundColor(ContextCompat.getColor(ctx, R.color.primary));
+ .backgroundColor(ContextCompat.getColor(ctx, R.color.primary_lighter));
}
return super.placeholder(ctx, tag);
}
diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml
index 87d99723..8bd337e9 100644
--- a/app/src/main/res/layout/activity_about.xml
+++ b/app/src/main/res/layout/activity_about.xml
@@ -28,7 +28,7 @@
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/primary_light"
+ android:background="@color/primary_lighter"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload.xml b/app/src/main/res/layout/activity_upload.xml
index 2282efae..1760ff1f 100644
--- a/app/src/main/res/layout/activity_upload.xml
+++ b/app/src/main/res/layout/activity_upload.xml
@@ -28,7 +28,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|start"
- android:background="@color/primary_light"
+ android:background="@color/primary_lighter"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
@@ -37,7 +37,7 @@
@@ -46,7 +46,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- android:background="@color/primary_light"
+ android:background="@color/primary_lighter"
android:orientation="vertical">
diff --git a/app/src/main/res/layout/fragment_bookmarks.xml b/app/src/main/res/layout/fragment_bookmarks.xml
index 8d1372c0..aa1bbaab 100644
--- a/app/src/main/res/layout/fragment_bookmarks.xml
+++ b/app/src/main/res/layout/fragment_bookmarks.xml
@@ -9,7 +9,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|start"
- android:background="@color/primary_light"
+ android:background="@color/primary_lighter"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
diff --git a/app/src/main/res/layout/fragment_forum_board_row.xml b/app/src/main/res/layout/fragment_forum_board_row.xml
index 871c5450..3f6eb4e6 100644
--- a/app/src/main/res/layout/fragment_forum_board_row.xml
+++ b/app/src/main/res/layout/fragment_forum_board_row.xml
@@ -2,7 +2,7 @@
+ android:background="@color/primary_lighter">
#2B2B2B
- #333333
- #3C3C3C
- #494949
+ #333333
+ #3C3C3C
+ #494949
+ #222222
#26A69A
#E7E7E7
#757575
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 1e092378..28fe1690 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -2,7 +2,7 @@
@@ -86,6 +86,6 @@
From 96f5821c9f366f927f7de1b4be3653385e552c50 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sat, 27 Jun 2020 20:41:19 +0300
Subject: [PATCH 18/21] Use a consistent guest avatar
---
app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java | 6 +-----
.../main/java/gr/thmmy/mthmmy/base/BaseApplication.java | 8 ++------
2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
index d31b7993..733e12b8 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
@@ -490,11 +490,7 @@ public abstract class BaseActivity extends AppCompatActivity {
}
private void setDefaultAvatar() {
- profileDrawerItem.withIcon(new IconicsDrawable(this)
- .icon(FontAwesome.Icon.faw_user)
- .paddingDp(10)
- .color(ContextCompat.getColor(this, R.color.iron))
- .backgroundColor(ContextCompat.getColor(this, R.color.primary_lighter)));
+ profileDrawerItem.withIcon(R.drawable.ic_default_user_avatar);
}
//-------------------------------------------LOGOUT-------------------------------------------------
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
index 49ff1c0e..131ae24b 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
@@ -179,12 +179,8 @@ public class BaseApplication extends MultiDexApplication {
@Override
public Drawable placeholder(Context ctx, String tag) {
- if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)) {
- return new IconicsDrawable(ctx).icon(FontAwesome.Icon.faw_user)
- .paddingDp(10)
- .color(ContextCompat.getColor(ctx, R.color.iron))
- .backgroundColor(ContextCompat.getColor(ctx, R.color.primary_lighter));
- }
+ if (DrawerImageLoader.Tags.PROFILE.name().equals(tag))
+ return BaseApplication.getInstance().getResources().getDrawable(R.drawable.ic_default_user_avatar);
return super.placeholder(ctx, tag);
}
});
From 06883907e4b78595b37003069a729bca0dd3a7be Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Sun, 5 Jul 2020 11:20:28 +0300
Subject: [PATCH 19/21] Globally enable cleartext traffic, as some avatars
require it
---
app/src/main/AndroidManifest.xml | 2 +-
app/src/main/res/drawable/ic_default_user_avatar.xml | 2 +-
app/src/main/res/xml/network_security_config.xml | 8 --------
3 files changed, 2 insertions(+), 10 deletions(-)
delete mode 100644 app/src/main/res/xml/network_security_config.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e36ad051..fa42ba6b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,7 +19,7 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
- android:networkSecurityConfig="@xml/network_security_config"
+ android:usesCleartextTraffic="true"
android:theme="@style/AppTheme"
tools:ignore="UnusedAttribute">
-
+
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
deleted file mode 100644
index 13da65b7..00000000
--- a/app/src/main/res/xml/network_security_config.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- www.thmmy.gr
- www.sciweavers.org
-
-
From e94c0150a1aacc276f7aa260fd02c3fcb8c0fcd3 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Thu, 9 Jul 2020 21:44:02 +0300
Subject: [PATCH 20/21] Attachments parsing fix, up version
---
app/build.gradle | 4 ++--
.../java/gr/thmmy/mthmmy/activities/board/BoardActivity.java | 2 +-
.../java/gr/thmmy/mthmmy/activities/topic/TopicParser.java | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index da29d78f..62af4345 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
applicationId "gr.thmmy.mthmmy"
minSdkVersion 19
targetSdkVersion 29
- versionCode 24
- versionName "1.8.1"
+ versionCode 25
+ versionName "1.8.2"
archivesBaseName = "mTHMMY-v$versionName"
buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\""
buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\""
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 9e297dcf..0623111f 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
@@ -259,7 +259,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
// Purification for extreme edge cases
String pSubjectConcat = subBoardCol.select("a").first().text();
- pLastPost = pLastPost.replaceAll(pSubjectConcat, "");
+ pLastPost = pLastPost.replace(pSubjectConcat, "");
String pLastUser;
matcher = pLastPostPattern.matcher(pLastPost); //Don't even try simply grabbing , user might be guest
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 1a7922ff..7f28e8dc 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
@@ -294,7 +294,7 @@ public class TopicParser {
Timber.e(e, "Attached file malformed url");
break;
}
- String attachedFileName = tmpAttachedFileUrlAndName.text().substring(1);
+ String attachedFileName = tmpAttachedFileUrlAndName.wholeText().substring(1);
//Gets file's info (size and download count)
String postAttachmentsTextSbstr = postAttachmentsText.substring(
@@ -366,7 +366,7 @@ public class TopicParser {
Timber.e(e, "Attached file malformed url");
break;
}
- String attachedFileName = tmpAttachedFileUrlAndName.text().substring(1);
+ String attachedFileName = tmpAttachedFileUrlAndName.wholeText().substring(1);
//Gets file's info (size and download count)
String postAttachmentsTextSbstr = postAttachmentsText.substring(
From 4b14151f8b840ca4da127e87be832351bc547d85 Mon Sep 17 00:00:00 2001
From: Ezerous
Date: Mon, 20 Jul 2020 14:16:35 +0300
Subject: [PATCH 21/21] Small BaseApp & gradle fixes
---
.gitignore | 1 +
app/build.gradle | 13 +++++++------
app/src/main/AndroidManifest.xml | 1 +
.../java/gr/thmmy/mthmmy/base/BaseApplication.java | 12 ++++++++++--
build.gradle | 2 +-
emojis/build.gradle | 9 +--------
gradle/wrapper/gradle-wrapper.properties | 4 ++--
7 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/.gitignore b/.gitignore
index 3f32039e..8b2da229 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@ bin/
gen/
out/
output.json
+output-metadata.json
# Gradle files
.gradle/
diff --git a/app/build.gradle b/app/build.gradle
index 62af4345..603d2651 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,7 +11,7 @@ android {
buildToolsVersion = '29.0.3'
defaultConfig {
- vectorDrawables.useSupportLibrary = true
+ vectorDrawables.useSupportLibrary = true //TODO: Remove when minSdkVersion >= 21
applicationId "gr.thmmy.mthmmy"
minSdkVersion 19
targetSdkVersion 29
@@ -25,13 +25,14 @@ android {
buildTypes {
release {
+ multiDexEnabled true //TODO: Remove when minSdkVersion >= 21
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
multiDexKeepProguard file('proguard-rules.pro') //TODO: Remove when minSdkVersion >= 21
}
debug {
- multiDexEnabled true
+ multiDexEnabled true //TODO: Remove when minSdkVersion >= 21
def date = new Date().format('ddMMyy_HHmmss')
archivesBaseName = archivesBaseName + "-$date"
firebaseCrashlytics {
@@ -77,7 +78,7 @@ tasks.whenTaskAdded { task ->
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":emojis")
- implementation 'androidx.appcompat:appcompat:1.2.0-rc01'
+ implementation 'androidx.appcompat:appcompat:1.3.0-alpha01'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
@@ -88,9 +89,9 @@ dependencies {
implementation 'androidx.exifinterface:exifinterface:1.2.0'
implementation 'androidx.multidex:multidex:2.0.1' //TODO: Remove when minSdkVersion >= 21
implementation 'com.google.android.material:material:1.1.0'
- implementation 'com.google.firebase:firebase-analytics:17.4.3'
- implementation 'com.google.firebase:firebase-crashlytics:17.0.1'
- implementation 'com.google.firebase:firebase-messaging:20.2.0'
+ implementation 'com.google.firebase:firebase-analytics:17.4.4'
+ implementation 'com.google.firebase:firebase-crashlytics:17.1.1'
+ implementation 'com.google.firebase:firebase-messaging:20.2.3'
implementation 'com.snatik:storage:2.1.0'
implementation ('com.squareup.okhttp3:okhttp:3.12.12') { //TODO: Warning: OkHttp has dropped support for Android 19 since OkHttp 3.13!
force = true //TODO: Remove when minSdkVersion >= 21
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fa42ba6b..7c7ab811 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
index 131ae24b..feed7496 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
@@ -179,8 +179,16 @@ public class BaseApplication extends MultiDexApplication {
@Override
public Drawable placeholder(Context ctx, String tag) {
- if (DrawerImageLoader.Tags.PROFILE.name().equals(tag))
- return BaseApplication.getInstance().getResources().getDrawable(R.drawable.ic_default_user_avatar);
+ if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+ return ContextCompat.getDrawable(BaseApplication.getInstance(), R.drawable.ic_default_user_avatar);
+ else { // Just for KitKats
+ return new IconicsDrawable(ctx).icon(FontAwesome.Icon.faw_user)
+ .paddingDp(10)
+ .color(ContextCompat.getColor(ctx, R.color.iron))
+ .backgroundColor(ContextCompat.getColor(ctx, R.color.primary_lighter));
+ }
+ }
return super.placeholder(ctx, tag);
}
});
diff --git a/build.gradle b/build.gradle
index d966ef2f..72da44f0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
maven { url "https://jitpack.io" }
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.3'
+ classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath 'org.ajoberstar.grgit:grgit-core:3.1.1' // Also change in app/gradle/grgit.gradle
diff --git a/emojis/build.gradle b/emojis/build.gradle
index 6aef90cf..46608744 100644
--- a/emojis/build.gradle
+++ b/emojis/build.gradle
@@ -4,7 +4,6 @@ android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
-
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
@@ -20,10 +19,4 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
-
-}
-
-dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.1.0'
-}
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 669ee9b7..0e03b907 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat May 09 21:06:12 EEST 2020
+#Mon Jul 20 13:59:13 EEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip