From 402d081c0ebd716e6f1828b2aa3a08e2fdb24919 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Fri, 9 Jun 2017 23:30:35 +0300 Subject: [PATCH 01/25] Crash reporting fixes and updates (plus some library updates) --- .gitlab-ci.yml | 2 +- app/build.gradle | 20 +++++++++--------- app/src/main/assets/apache_libraries.html | 6 +++--- .../activities/board/BoardActivity.java | 2 +- .../downloads/DownloadsActivity.java | 2 +- .../activities/main/forum/ForumFragment.java | 19 ++++++++++------- .../main/recent/RecentFragment.java | 6 +++--- .../activities/profile/ProfileActivity.java | 3 ++- .../latestPosts/LatestPostsFragment.java | 3 ++- .../profile/stats/StatsFragment.java | 3 ++- .../mthmmy/activities/topic/Posting.java | 7 +++---- .../activities/topic/TopicActivity.java | 8 +++---- .../mthmmy/activities/topic/TopicParser.java | 2 +- .../java/gr/thmmy/mthmmy/model/ThmmyPage.java | 2 +- .../mthmmy/services/DownloadService.java | 6 +++--- .../thmmy/mthmmy/session/SessionManager.java | 6 +++--- .../mthmmy/utils/CrashReportingTree.java | 21 ++++++++++++------- .../utils/exceptions/UnknownException.java | 14 ------------- build.gradle | 2 +- 19 files changed, 65 insertions(+), 69 deletions(-) delete mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/exceptions/UnknownException.java diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cd22f77e..b3c840ca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ image: openjdk:8-jdk variables: ANDROID_TARGET_SDK: "25" - ANDROID_BUILD_TOOLS: "25.0.2" + ANDROID_BUILD_TOOLS: "25.0.3" ANDROID_SDK_TOOLS: "25.2.5" before_script: diff --git a/app/build.gradle b/app/build.gradle index 1517040e..83f079af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 25 - buildToolsVersion "25.0.2" + buildToolsVersion "25.0.3" defaultConfig { vectorDrawables.useSupportLibrary = true @@ -28,25 +28,25 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:25.3.0' - compile 'com.android.support:design:25.3.0' - compile 'com.android.support:support-v4:25.3.0' - compile 'com.android.support:cardview-v7:25.3.0' - compile 'com.android.support:recyclerview-v7:25.3.0' - compile 'com.google.firebase:firebase-crash:10.2.0' - compile 'com.squareup.okhttp3:okhttp:3.6.0' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:design:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + compile 'com.android.support:cardview-v7:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' + compile 'com.google.firebase:firebase-crash:11.0.0' + compile 'com.squareup.okhttp3:okhttp:3.8.0' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' compile 'org.jsoup:jsoup:1.10.2' compile 'com.github.franmontiel:PersistentCookieJar:v1.0.0' compile 'com.github.PhilJay:MPAndroidChart:v3.0.1' - compile('com.mikepenz:materialdrawer:5.8.2@aar') { + compile('com.mikepenz:materialdrawer:5.9.2@aar') { transitive = true } compile 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar' compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.5' compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' - compile 'me.zhanghai.android.materialprogressbar:library:1.3.0' + compile 'me.zhanghai.android.materialprogressbar:library:1.4.1' compile 'com.jakewharton.timber:timber:4.5.1' } diff --git a/app/src/main/assets/apache_libraries.html b/app/src/main/assets/apache_libraries.html index 2c0ceabc..2fe80f29 100644 --- a/app/src/main/assets/apache_libraries.html +++ b/app/src/main/assets/apache_libraries.html @@ -39,7 +39,7 @@ 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 00dbb69a..57a97093 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 @@ -194,7 +194,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } catch (SSLHandshakeException e) { Timber.w("Certificate problem (please switch to unsafe connection)."); } catch (Exception e) { - Timber.e("ERROR", e); + Timber.e(e, "Exception"); } return null; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java index b4339f14..724bf3c3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java @@ -189,7 +189,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. } catch (SSLHandshakeException e) { Timber.w("Certificate problem (please switch to unsafe connection)."); } catch (Exception e) { - Timber.e("ERROR", e); + Timber.e(e, "Exception"); } return null; } 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 8bcecc25..8ca74bdb 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 @@ -29,6 +29,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.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import okhttp3.HttpUrl; @@ -178,12 +179,15 @@ public class ForumFragment extends BaseFragment categories.addAll(fetchedCategories); fetchedCategories.clear(); return 0; - } catch (IOException e) { - Timber.d("Network Error", e); + } catch (ParseException e) { + Timber.e(e, "ParseException"); return 1; - } catch (Exception e) { - Timber.d("Exception", e); + } catch (IOException e) { + Timber.i(e, "Network Error"); return 2; + } catch (Exception e) { + Timber.e(e, "Exception"); + return 3; } } @@ -193,14 +197,13 @@ public class ForumFragment extends BaseFragment if (result == 0) forumAdapter.notifyParentDataSetChanged(false); - else if (result == 1) + else if (result == 2) Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(ProgressBar.INVISIBLE); } - private void parse(Document document) - { + private void parse(Document document) throws ParseException { Elements categoryBlocks = document.select(".tborder:not([style])>table[cellpadding=5]"); if (categoryBlocks.size() != 0) { for(Element categoryBlock: categoryBlocks) @@ -225,7 +228,7 @@ public class ForumFragment extends BaseFragment } } else - Timber.e("Parsing failed!"); + throw new ParseException("Parsing failed"); } public void setUrl(String string) 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 47f4678d..45b1140d 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 @@ -161,13 +161,13 @@ public class RecentFragment extends BaseFragment { parse(document); return 0; } catch (ParseException e) { - Timber.e("ParseException", e); + Timber.e(e, "ParseException"); return 1; } catch (IOException e) { - Timber.i("Network Error", e); + Timber.i(e, "Network Error"); return 2; } catch (Exception e) { - Timber.e("Exception", e); + Timber.e(e, "Exception"); return 3; } 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 08495dd9..e5a30cc8 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 @@ -276,11 +276,12 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment } catch (SSLHandshakeException e) { Timber.w("Certificate problem (please switch to unsafe connection)."); } catch (Exception e) { - Timber.e("ERROR", e); + Timber.e(e, "Exception"); } return false; } + //TODO: better parse error handling (ParseException etc.) protected void onPostExecute(Boolean result) { if (!result) { //Parse failed! //TODO report as ParseException? Timber.d("Parse failed!"); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java index 5c3f8d40..d08ad37a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java @@ -167,7 +167,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap } catch (SSLHandshakeException e) { Timber.w("Certificate problem (please switch to unsafe connection)."); } catch (Exception e) { - Timber.e("ERROR", e); + Timber.e(e, "Exception"); } return false; } @@ -185,6 +185,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap isLoadingMore = false; } + //TODO: better parse error handling (ParseException etc.) private boolean parseLatestPosts(Document latestPostsPage) { Elements latestPostsRows = latestPostsPage. select("td:has(table:Contains(Show Posts)):not([style]) > table"); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java index f573f3db..8e9ca93d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java @@ -141,11 +141,12 @@ public class StatsFragment extends Fragment { } catch (SSLHandshakeException e) { Timber.w("Certificate problem (please switch to unsafe connection)."); } catch (Exception e) { - Timber.e("ERROR", e); + Timber.e(e, "Exception"); } return false; } + //TODO: better parse error handling (ParseException etc.) @Override protected void onPostExecute(Boolean result) { if (!result) { //Parse failed! diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java index 7c42b8cd..f0220f82 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java @@ -1,7 +1,5 @@ package gr.thmmy.mthmmy.activities.topic; -import android.util.Log; - import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -11,6 +9,7 @@ import java.util.Map; import java.util.regex.Matcher; import okhttp3.Response; +import timber.log.Timber; class Posting { enum REPLY_STATUS { @@ -26,8 +25,8 @@ class Posting { String[] errors = postErrorPage.select("tr[id=errors] div[id=error_list]").first() .toString().split("
"); for (int i = 0; i < errors.length; ++i) { //TODO test - Log.d("TAG", String.valueOf(i)); - Log.d("TAG", errors[i]); + Timber.d(String.valueOf(i)); + Timber.d(errors[i]); } for (String error : errors) { if (error.contains("Your session timed out while posting") || 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 050fea14..74dcadac 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 @@ -134,7 +134,7 @@ public class TopicActivity extends BaseActivity { ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory( Uri.parse(topicPageUrl)); if (!target.is(ThmmyPage.PageCategory.TOPIC)) { - Timber.e("Bundle came with a non topic url!\nUrl:\n" + topicPageUrl); + Timber.e("Bundle came with a non topic url!\nUrl: %s" , topicPageUrl); Toast.makeText(this, "An error has occurred\n Aborting.", Toast.LENGTH_SHORT).show(); finish(); } @@ -517,10 +517,10 @@ public class TopicActivity extends BaseActivity { parse(document); return SUCCESS; } catch (IOException e) { - Timber.i("IO Exception", e); + Timber.i(e, "IO Exception"); return NETWORK_ERROR; } catch (Exception e) { - Timber.e("Exception", e); + Timber.e(e, "Exception"); return OTHER_ERROR; } } @@ -568,7 +568,7 @@ public class TopicActivity extends BaseActivity { break; default: //Parse failed - should never happen - Timber.d("Parse failed!"); //TODO report ParseException? + Timber.d("Parse failed!"); //TODO report ParseException!!! Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show(); finish(); break; 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 3ce9c24d..c3e7271c 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 @@ -259,7 +259,7 @@ class TopicParser { try { attachedUrl = new URL(tmpAttachedFileUrlAndName.attr("href")); } catch (MalformedURLException e) { - Timber.e("Attached file malformed url", e); + Timber.e(e, "Attached file malformed url"); break; } String attachedFileName = tmpAttachedFileUrlAndName.text().substring(1); diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java index 9e935f69..3ca324ed 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java @@ -162,7 +162,7 @@ public class ThmmyPage { || Objects.equals(uriString, "https://www.thmmy.gr") || Objects.equals(uriString, "https://www.thmmy.gr/smf/index.php")) return PageCategory.INDEX; - Timber.v("Unknown thmmy link found, link: " + uriString); + Timber.v("Unknown thmmy link found, link: %s" , uriString); return PageCategory.UNKNOWN_THMMY; } return PageCategory.NOT_THMMY; diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java index 52883ef4..0283cef1 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -142,7 +142,7 @@ public class DownloadService extends IntentService { fileName = file.getName(); - Timber.v("Started saving file " + fileName); + Timber.v("Started saving file %s" , fileName); sendNotification(downloadId, STARTED, fileName); sink = Okio.buffer(Okio.sink(file)); @@ -154,11 +154,11 @@ public class DownloadService extends IntentService { Timber.e("Response not a binary file!"); } catch (FileNotFoundException e) { Timber.i("Download failed..."); - Timber.e("FileNotFound", e); + Timber.e(e, "FileNotFound"); sendNotification(downloadId, FAILED, fileName); } catch (IOException e) { Timber.i("Download failed..."); - Timber.e("IOException", e); + Timber.e(e, "IOException"); sendNotification(downloadId, FAILED, fileName); } finally { if (sink != null) { 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 1455fb27..93b37b46 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -154,10 +154,10 @@ public class SessionManager { Timber.i("Login InterruptedIOException"); //users cancels LoginTask return CANCELLED; } catch (IOException e) { - Timber.w("Login IOException", e); + Timber.w(e ,"Login IOException"); return CONNECTION_ERROR; } catch (Exception e) { - Timber.w("Login Exception (other)", e); + Timber.e(e, "Login Exception (other)"); return EXCEPTION; } } @@ -223,7 +223,7 @@ public class SessionManager { Timber.w("Logout IOException", e); return CONNECTION_ERROR; } catch (Exception e) { - Timber.w("Logout Exception", e); + Timber.e(e, "Logout Exception"); return EXCEPTION; } finally { //All data should always be cleared from device regardless the result of logout diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java b/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java index 2aeca9a2..c5851d30 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java @@ -4,17 +4,17 @@ import android.util.Log; import com.google.firebase.crash.FirebaseCrash; -import gr.thmmy.mthmmy.utils.exceptions.UnknownException; -import timber.log.Timber; +import timber.log.Timber.DebugTree; -public class CrashReportingTree extends Timber.Tree { +public class CrashReportingTree extends DebugTree { + @Override protected void log(int priority, String tag, String message, Throwable t) { if (priority == Log.VERBOSE || priority == Log.DEBUG) { return; } - String level="A"; + String level; if (priority == Log.INFO) level = "I"; @@ -22,13 +22,18 @@ public class CrashReportingTree extends Timber.Tree { level = "W"; else if(priority == Log.ERROR) level = "E"; + else + level = "A"; FirebaseCrash.log(level + "/" + tag + ": " + message); - if(t==null) - t = new UnknownException("UnknownException"); + if(priority == Log.ERROR) + { + if (t!=null) + FirebaseCrash.report(t); + else + FirebaseCrash.report(new Exception(message)); + } - if ((priority == Log.ERROR)) - FirebaseCrash.report(t); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/exceptions/UnknownException.java b/app/src/main/java/gr/thmmy/mthmmy/utils/exceptions/UnknownException.java deleted file mode 100644 index 81c890ad..00000000 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/exceptions/UnknownException.java +++ /dev/null @@ -1,14 +0,0 @@ -package gr.thmmy.mthmmy.utils.exceptions; - -/** - * UnknownException is thrown upon an error (see Report.java in release), when no other specific - * exception is set, to report to FireBase. - */ -public class UnknownException extends Exception { - public UnknownException() { - } - - public UnknownException(String message) { - super(message); - } -} diff --git a/build.gradle b/build.gradle index a40a0e30..f5ee47bc 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { maven { url "https://jitpack.io" } } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.google.gms:google-services:3.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From d603c814cb39ac9f184f4942ba6957eedde60a9d Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 10 Jun 2017 00:35:25 +0300 Subject: [PATCH 02/25] More library updates --- app/build.gradle | 6 +++--- app/src/main/assets/apache_libraries.html | 4 ++-- app/src/main/assets/mit_libraries.html | 2 +- build.gradle | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 83f079af..85cf281e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,13 +38,13 @@ dependencies { compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' compile 'org.jsoup:jsoup:1.10.2' - compile 'com.github.franmontiel:PersistentCookieJar:v1.0.0' - compile 'com.github.PhilJay:MPAndroidChart:v3.0.1' + compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1' + compile 'com.github.PhilJay:MPAndroidChart:v3.0.2' compile('com.mikepenz:materialdrawer:5.9.2@aar') { transitive = true } compile 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar' - compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.5' + compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.7' compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' compile 'me.zhanghai.android.materialprogressbar:library:1.4.1' compile 'com.jakewharton.timber:timber:4.5.1' diff --git a/app/src/main/assets/apache_libraries.html b/app/src/main/assets/apache_libraries.html index 2fe80f29..45905fa2 100644 --- a/app/src/main/assets/apache_libraries.html +++ b/app/src/main/assets/apache_libraries.html @@ -45,10 +45,10 @@
Picasso v2.5.2 (Copyright ©2013 Square, Inc.)
  • -
    PersistentCookieJar v1.0.0 (Copyright ©2016 Francisco José Montiel Navarro)
    +
    PersistentCookieJar v1.0.1 (Copyright ©2016 Francisco José Montiel Navarro)
  • -
    MPAndroidChart v3.0.1 (Copyright ©2016 Philipp Jahoda)
    +
    MPAndroidChart v3.0.2 (Copyright ©2016 Philipp Jahoda)
  • MaterialDrawer v5.9.2 (Copyright ©2016 Mike Penz)
    diff --git a/app/src/main/assets/mit_libraries.html b/app/src/main/assets/mit_libraries.html index 2c6cf3bb..42b46e78 100644 --- a/app/src/main/assets/mit_libraries.html +++ b/app/src/main/assets/mit_libraries.html @@ -42,7 +42,7 @@
    jsoup v1.10.2 (Copyright ©2009-2017, Jonathan Hedley <jonathan@hedley.net>)
  • -
    android-gif-drawable v1.2.5 (Copyright ©2016 Karol Wrótniak, Droids on Roids)
    +
    android-gif-drawable v1.2.7 (Copyright ©2016 Karol Wrótniak, Droids on Roids)
  • Expandable RecyclerView v3.0.0-RC1 (Copyright ©2015, Big Nerd Ranch)
    diff --git a/build.gradle b/build.gradle index f5ee47bc..d786c62a 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.google.gms:google-services:3.0.0' + classpath 'com.google.gms:google-services:3.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From fe107b82c1eaa9874a87d6a819670fb41b77abab Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 10 Jun 2017 14:21:25 +0300 Subject: [PATCH 03/25] Generic ParseTask init Testing in RecentFragment only at the moment --- app/build.gradle | 2 +- .../main/recent/RecentFragment.java | 71 +++++++------------ .../mthmmy/activities/topic/TopicParser.java | 1 - .../mthmmy/utils/CrashReportingTree.java | 10 +-- .../java/gr/thmmy/mthmmy/utils/ParseTask.java | 48 +++++++++++++ 5 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java diff --git a/app/build.gradle b/app/build.gradle index 85cf281e..5dd89bee 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,7 +33,7 @@ dependencies { compile 'com.android.support:support-v4:25.3.1' compile 'com.android.support:cardview-v7:25.3.1' compile 'com.android.support:recyclerview-v7:25.3.1' - compile 'com.google.firebase:firebase-crash:11.0.0' + compile 'com.google.firebase:firebase-crash:10.2.6' compile 'com.squareup.okhttp3:okhttp:3.8.0' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' 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 45b1140d..8f4a9663 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 @@ -12,11 +12,9 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Toast; -import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -27,14 +25,13 @@ import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.utils.CustomRecyclerView; +import gr.thmmy.mthmmy.utils.ParseTask; import gr.thmmy.mthmmy.utils.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - -import okhttp3.HttpUrl; import okhttp3.Request; -import okhttp3.Response; import timber.log.Timber; + /** * A {@link BaseFragment} subclass. * Activities that contain this fragment must implement the @@ -84,7 +81,7 @@ public class RecentFragment extends BaseFragment { if (topicSummaries.isEmpty()) { recentTask =new RecentTask(); - recentTask.execute(); + recentTask.execute(SessionManager.indexUrl.toString()); } Timber.d("onActivityCreated"); @@ -117,7 +114,7 @@ public class RecentFragment extends BaseFragment { public void onRefresh() { if (recentTask != null && recentTask.getStatus() != AsyncTask.Status.RUNNING) { recentTask = new RecentTask(); - recentTask.execute(); + recentTask.execute(SessionManager.indexUrl.toString()); } } @@ -141,51 +138,21 @@ public class RecentFragment extends BaseFragment { } //---------------------------------------ASYNC TASK----------------------------------- - - private class RecentTask extends AsyncTask { - private final HttpUrl thmmyUrl = SessionManager.indexUrl; - private Document document; - + private class RecentTask extends ParseTask { protected void onPreExecute() { - progressBar.setVisibility(ProgressBar.VISIBLE); } - protected Integer doInBackground(Void... voids) { - Request request = new Request.Builder() - .url(thmmyUrl) + @Override + protected Request prepareRequest(String... strings) { + return new Request.Builder() + .url(strings[0]) .build(); - try { - Response response = client.newCall(request).execute(); - document = Jsoup.parse(response.body().string()); - parse(document); - return 0; - } catch (ParseException e) { - Timber.e(e, "ParseException"); - return 1; - } catch (IOException e) { - Timber.i(e, "Network Error"); - return 2; - } catch (Exception e) { - Timber.e(e, "Exception"); - return 3; - } - } - - protected void onPostExecute(Integer result) { - - if (result == 0) - recentAdapter.notifyDataSetChanged(); - else if (result == 2) - Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show(); //Fixme, sometimes activity isn't ready - - progressBar.setVisibility(ProgressBar.INVISIBLE); - swipeRefreshLayout.setRefreshing(false); - } - - private void parse(Document document) throws ParseException { + @Override + public void parse(Document document) throws ParseException + { Elements recent = document.select("#block8 :first-child div"); if (!recent.isEmpty()) { topicSummaries.clear(); @@ -217,6 +184,20 @@ public class RecentFragment extends BaseFragment { } throw new ParseException("Parsing failed"); } + + + @Override + protected void onPostExecute(ParseTask.ResultCode result) { + + if (result == ResultCode.SUCCESS) + recentAdapter.notifyDataSetChanged(); + else if (result == ResultCode.NETWORK_ERROR) + Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show(); //Fixme, sometimes activity isn't ready + + progressBar.setVisibility(ProgressBar.INVISIBLE); + swipeRefreshLayout.setRefreshing(false); + } + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java index c3e7271c..81b1e47f 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 @@ -1,7 +1,6 @@ package gr.thmmy.mthmmy.activities.topic; import android.graphics.Color; -import android.util.Log; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java b/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java index c5851d30..a3407254 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java @@ -14,16 +14,16 @@ public class CrashReportingTree extends DebugTree { return; } - String level; + char level; if (priority == Log.INFO) - level = "I"; + level = 'I'; else if (priority == Log.WARN) - level = "W"; + level = 'W'; else if(priority == Log.ERROR) - level = "E"; + level = 'E'; else - level = "A"; + level = 'A'; FirebaseCrash.log(level + "/" + tag + ": " + message); diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java new file mode 100644 index 00000000..cd85ce20 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java @@ -0,0 +1,48 @@ +package gr.thmmy.mthmmy.utils; + +import android.os.AsyncTask; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import java.io.IOException; + +import gr.thmmy.mthmmy.base.BaseApplication; +import gr.thmmy.mthmmy.utils.exceptions.ParseException; + +import okhttp3.Request; +import okhttp3.Response; +import timber.log.Timber; + +public abstract class ParseTask extends AsyncTask { + protected enum ResultCode { + SUCCESS, PARSING_ERROR, NETWORK_ERROR, OTHER_ERROR + } + + @Override + protected ResultCode doInBackground(String... params) { + Request request = prepareRequest(params); + try { + Response response = BaseApplication.getInstance().getClient().newCall(request).execute(); + Document document = Jsoup.parse(response.body().string()); + parse(document); + return ResultCode.SUCCESS; + } catch (ParseException e) { + Timber.tag(this.getClass().getSimpleName()); + Timber.e(e, "Parsing Error"); + return ResultCode.PARSING_ERROR; + } catch (IOException e) { + Timber.tag(this.getClass().getSimpleName()); + Timber.i(e, "Network Error"); + return ResultCode.NETWORK_ERROR; + } catch (Exception e) { + Timber.tag(this.getClass().getSimpleName()); + Timber.e(e, "Other Error"); + return ResultCode.OTHER_ERROR; + } + } + + protected abstract Request prepareRequest(String... params); + protected abstract void parse (Document document) throws ParseException; +} + From dc0506a5acc3dc45630c0dd8434169852d6b7c78 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 29 Jun 2017 16:14:31 +0300 Subject: [PATCH 04/25] More ParseTask stuff --- .../activities/board/BoardActivity.java | 66 ++++++++----------- .../activities/main/forum/ForumFragment.java | 60 ++++++----------- .../main/recent/RecentFragment.java | 14 +--- .../activities/topic/TopicActivity.java | 7 +- .../thmmy/mthmmy/session/SessionManager.java | 4 +- .../java/gr/thmmy/mthmmy/utils/ParseTask.java | 25 ++++++- 6 files changed, 74 insertions(+), 102 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 57a97093..d25a2340 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 @@ -13,7 +13,6 @@ import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.Toast; -import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; @@ -21,17 +20,15 @@ import org.jsoup.select.Elements; import java.util.ArrayList; import java.util.Objects; -import javax.net.ssl.SSLHandshakeException; - import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Board; import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.model.Topic; +import gr.thmmy.mthmmy.utils.ParseTask; +import gr.thmmy.mthmmy.utils.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; -import okhttp3.Request; -import okhttp3.Response; import timber.log.Timber; public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMoreListener { @@ -176,47 +173,15 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo *

    BoardTask's {@link AsyncTask#execute execute} method needs a boards's url as String * parameter!

    */ - private class BoardTask extends AsyncTask { + private class BoardTask extends ParseTask { @Override protected void onPreExecute() { if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE); if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(false); } - @Override - protected Void doInBackground(String... boardUrl) { - Request request = new Request.Builder() - .url(boardUrl[0]) - .build(); - try { - Response response = client.newCall(request).execute(); - parseBoard(Jsoup.parse(response.body().string())); - } catch (SSLHandshakeException e) { - Timber.w("Certificate problem (please switch to unsafe connection)."); - } catch (Exception e) { - Timber.e(e, "Exception"); - } - return null; - } - - @Override - protected void onPostExecute(Void voids) { - if (boardTitle == null || Objects.equals(boardTitle, "") - || !Objects.equals(boardTitle, parsedTitle)) { - boardTitle = parsedTitle; - toolbar.setTitle(boardTitle); - thisPageBookmark = new Bookmark(boardTitle, ThmmyPage.getBoardId(boardUrl)); - } - - //Parse was successful - ++pagesLoaded; - if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(true); - progressBar.setVisibility(ProgressBar.INVISIBLE); - boardAdapter.notifyDataSetChanged(); - isLoadingMore = false; - } - - private void parseBoard(Document boardPage) { + @Override //TODO should throw ParseException + public void parse(Document boardPage) throws ParseException { parsedTitle = boardPage.select("div.nav a.nav").last().text(); //Removes loading item @@ -320,5 +285,26 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } } } + + @Override + protected void postParsing(ResultCode result) { + //TODO if (result == ResultCode.SUCCESS)... + if (boardTitle == null || Objects.equals(boardTitle, "") + || !Objects.equals(boardTitle, parsedTitle)) { + boardTitle = parsedTitle; + toolbar.setTitle(boardTitle); + thisPageBookmark = new Bookmark(boardTitle, ThmmyPage.getBoardId(boardUrl)); + } + + //Parse was successful + ++pagesLoaded; + if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(true); + progressBar.setVisibility(ProgressBar.INVISIBLE); + boardAdapter.notifyDataSetChanged(); + isLoadingMore = false; + } + + } + } 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 8ca74bdb..b8e3c140 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 @@ -10,16 +10,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.RelativeLayout; -import android.widget.Toast; import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter; -import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -29,12 +26,11 @@ 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.ParseTask; import gr.thmmy.mthmmy.utils.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - import okhttp3.HttpUrl; import okhttp3.Request; -import okhttp3.Response; import timber.log.Timber; /** @@ -153,9 +149,8 @@ public class ForumFragment extends BaseFragment //---------------------------------------ASYNC TASK----------------------------------- - private class ForumTask extends AsyncTask { + private class ForumTask extends ParseTask { private HttpUrl forumUrl = SessionManager.forumUrl; //may change upon collapse/expand - private Document document; private final List fetchedCategories; @@ -167,43 +162,16 @@ public class ForumFragment extends BaseFragment progressBar.setVisibility(ProgressBar.VISIBLE); } - protected Integer doInBackground(Void... voids) { - Request request = new Request.Builder() + @Override + protected Request prepareRequest(String... params) { + return new Request.Builder() .url(forumUrl) .build(); - try { - Response response = client.newCall(request).execute(); - document = Jsoup.parse(response.body().string()); - parse(document); - categories.clear(); - categories.addAll(fetchedCategories); - fetchedCategories.clear(); - return 0; - } catch (ParseException e) { - Timber.e(e, "ParseException"); - return 1; - } catch (IOException e) { - Timber.i(e, "Network Error"); - return 2; - } catch (Exception e) { - Timber.e(e, "Exception"); - return 3; - } - } - protected void onPostExecute(Integer result) { - - if (result == 0) - forumAdapter.notifyParentDataSetChanged(false); - else if (result == 2) - Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show(); - - progressBar.setVisibility(ProgressBar.INVISIBLE); - } - - private void parse(Document document) throws ParseException { + @Override + public void parse(Document document) throws ParseException { Elements categoryBlocks = document.select(".tborder:not([style])>table[cellpadding=5]"); if (categoryBlocks.size() != 0) { for(Element categoryBlock: categoryBlocks) @@ -229,9 +197,21 @@ public class ForumFragment extends BaseFragment } else throw new ParseException("Parsing failed"); + + categories.clear(); + categories.addAll(fetchedCategories); + fetchedCategories.clear(); + } + + @Override + protected void postParsing(ParseTask.ResultCode result) { + if (result == ResultCode.SUCCESS) + forumAdapter.notifyParentDataSetChanged(false); + + progressBar.setVisibility(ProgressBar.INVISIBLE); } - public void setUrl(String string) + public void setUrl(String string) //TODO delete and simplify e.g. in prepareRequest possible? { forumUrl = HttpUrl.parse(string); } 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 8f4a9663..293338d2 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 @@ -10,7 +10,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.RelativeLayout; -import android.widget.Toast; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; @@ -28,7 +27,6 @@ import gr.thmmy.mthmmy.utils.CustomRecyclerView; import gr.thmmy.mthmmy.utils.ParseTask; import gr.thmmy.mthmmy.utils.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; -import okhttp3.Request; import timber.log.Timber; @@ -143,13 +141,6 @@ public class RecentFragment extends BaseFragment { progressBar.setVisibility(ProgressBar.VISIBLE); } - @Override - protected Request prepareRequest(String... strings) { - return new Request.Builder() - .url(strings[0]) - .build(); - } - @Override public void parse(Document document) throws ParseException { @@ -187,12 +178,9 @@ public class RecentFragment extends BaseFragment { @Override - protected void onPostExecute(ParseTask.ResultCode result) { - + protected void postParsing(ParseTask.ResultCode result) { if (result == ResultCode.SUCCESS) recentAdapter.notifyDataSetChanged(); - else if (result == ResultCode.NETWORK_ERROR) - Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show(); //Fixme, sometimes activity isn't ready progressBar.setVisibility(ProgressBar.INVISIBLE); swipeRefreshLayout.setRefreshing(false); 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 74dcadac..c959d091 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 @@ -49,7 +49,6 @@ import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.ParseHelpers; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - import okhttp3.MultipartBody; import okhttp3.Request; import okhttp3.RequestBody; @@ -698,10 +697,10 @@ public class TopicActivity extends BaseActivity { //subject = document.select("input[name=subject]").first().attr("value"); topic = document.select("input[name=topic]").first().attr("value"); } catch (IOException e) { - Timber.e("Post failed.", e); + Timber.e(e,"Post failed."); return false; } catch (Selector.SelectorParseException e) { - Timber.e("Post failed.", e); + Timber.e(e,"Post failed."); return false; } @@ -735,7 +734,7 @@ public class TopicActivity extends BaseActivity { return true; } } catch (IOException e) { - Timber.e("Post failed.", e); + Timber.e(e,"Post failed."); return false; } } 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 93b37b46..b5b56bfe 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -317,7 +317,7 @@ public class SessionManager { if (userName != null && !userName.isEmpty()) return userName; - Timber.e("ParseException", new ParseException("Parsing failed(username extraction)")); + Timber.e(new ParseException("Parsing failed(username extraction)"),"ParseException"); return "User"; //return a default username } @@ -341,7 +341,7 @@ public class SessionManager { if (link != null && !link.isEmpty()) return link; } - Timber.e("ParseException", new ParseException("Parsing failed(logoutLink extraction)")); + Timber.e(new ParseException("Parsing failed(logoutLink extraction)"),"ParseException"); return "https://www.thmmy.gr/smf/index.php?action=logout"; //return a default link } //----------------------------------OTHER FUNCTIONS END----------------------------------------- diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java index cd85ce20..9ce5a882 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseTask.java @@ -1,6 +1,7 @@ package gr.thmmy.mthmmy.utils; import android.os.AsyncTask; +import android.widget.Toast; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -9,16 +10,30 @@ import java.io.IOException; import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.utils.exceptions.ParseException; - import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; +/** + * An {@link AsyncTask} class to be inherited for asynchronous parsing. + * Do NOT override doInBackground() and onPostExecute directly. + * Default usage while executing is ParseTask.execute(urlToParse), however feel free to override + * and modify prepareRequest() as needed. + */ public abstract class ParseTask extends AsyncTask { protected enum ResultCode { SUCCESS, PARSING_ERROR, NETWORK_ERROR, OTHER_ERROR } + protected abstract void parse (Document document) throws ParseException; + protected abstract void postParsing (ParseTask.ResultCode result); //ResultCode.NETWORK_ERROR is handled automatically + + protected Request prepareRequest(String... params) { + return new Request.Builder() + .url(params[0]) + .build(); + } + @Override protected ResultCode doInBackground(String... params) { Request request = prepareRequest(params); @@ -42,7 +57,11 @@ public abstract class ParseTask extends AsyncTask Date: Tue, 11 Jul 2017 14:36:32 +0300 Subject: [PATCH 05/25] ForumFragment can be refreshed manually --- .../activities/main/forum/ForumFragment.java | 21 ++++++++++++++-- app/src/main/res/layout/fragment_forum.xml | 25 +++++++++++-------- 2 files changed, 34 insertions(+), 12 deletions(-) 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 b8e3c140..83f7d748 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java @@ -2,9 +2,9 @@ package gr.thmmy.mthmmy.activities.main.forum; import android.os.AsyncTask; import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -26,6 +26,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.CustomRecyclerView; import gr.thmmy.mthmmy.utils.ParseTask; import gr.thmmy.mthmmy.utils.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; @@ -47,6 +48,7 @@ public class ForumFragment extends BaseFragment // Fragment initialization parameters, e.g. ARG_SECTION_NUMBER private MaterialProgressBar progressBar; + private SwipeRefreshLayout swipeRefreshLayout; private ForumAdapter forumAdapter; private List categories; @@ -124,7 +126,7 @@ public class ForumFragment extends BaseFragment } }); - RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.list); + CustomRecyclerView recyclerView = (CustomRecyclerView) rootView.findViewById(R.id.list); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext()); recyclerView.setLayoutManager(linearLayoutManager); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), @@ -132,6 +134,20 @@ public class ForumFragment extends BaseFragment recyclerView.addItemDecoration(dividerItemDecoration); recyclerView.setAdapter(forumAdapter); + swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swiperefresh); + swipeRefreshLayout.setOnRefreshListener( + new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (forumTask != null && forumTask.getStatus() != AsyncTask.Status.RUNNING) { + forumTask = new ForumTask(); + forumTask.execute(SessionManager.indexUrl.toString()); + } + } + + } + ); + } return rootView; } @@ -209,6 +225,7 @@ public class ForumFragment extends BaseFragment forumAdapter.notifyParentDataSetChanged(false); progressBar.setVisibility(ProgressBar.INVISIBLE); + swipeRefreshLayout.setRefreshing(false); } public void setUrl(String string) //TODO delete and simplify e.g. in prepareRequest possible? diff --git a/app/src/main/res/layout/fragment_forum.xml b/app/src/main/res/layout/fragment_forum.xml index 49bf6061..04c4ec4e 100644 --- a/app/src/main/res/layout/fragment_forum.xml +++ b/app/src/main/res/layout/fragment_forum.xml @@ -6,17 +6,22 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent"> + + + Date: Tue, 11 Jul 2017 15:01:43 +0300 Subject: [PATCH 06/25] Proguard init --- app/build.gradle | 4 ++-- app/proguard-rules.pro | 17 +++++++++++++++++ .../activities/main/forum/ForumAdapter.java | 2 -- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5dd89bee..06bf2efb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /*debug { @@ -45,7 +45,7 @@ dependencies { } compile 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar' compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.7' - compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' + compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' //Deprecated! compile 'me.zhanghai.android.materialprogressbar:library:1.4.1' compile 'com.jakewharton.timber:timber:4.5.1' } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index ff7615bd..3b0e65f5 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -15,3 +15,20 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} + +# OkHttp +-dontwarn okio.** +-dontwarn javax.annotation.Nullable +-dontwarn javax.annotation.ParametersAreNonnullByDefault + +# Picasso +-dontwarn com.squareup.okhttp.** + +# Android-Iconics (fontawesome-typeface) +-keep class .R +-keep class **.R$* { + ; +} + +# android-gif-drawable +-keep public class pl.droidsonroids.gif.GifIOException{(int, java.lang.String);} \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java index 9f896b29..821c83a5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java @@ -26,7 +26,6 @@ import gr.thmmy.mthmmy.model.TopicSummary; * specified {@link ForumFragment.ForumFragmentInteractionListener}. */ class ForumAdapter extends ExpandableRecyclerAdapter { - private final Context context; private final LayoutInflater layoutInflater; private final List categories; @@ -34,7 +33,6 @@ class ForumAdapter extends ExpandableRecyclerAdapter categories, BaseFragment.FragmentInteractionListener listener) { super(categories); - this.context = context; this.categories = categories; mListener = (ForumFragment.ForumFragmentInteractionListener) listener; layoutInflater = LayoutInflater.from(context); From 5c6a7d03d8ec196645f917bfcb13cf831a05a561 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Tue, 11 Jul 2017 15:48:02 +0300 Subject: [PATCH 07/25] Bookmarks work for guests too, minor tweaks. --- .../mthmmy/activities/BookmarkActivity.java | 181 ++++++++++-------- .../mthmmy/activities/LoginActivity.java | 1 - .../downloads/DownloadsActivity.java | 1 - .../activities/main/forum/ForumFragment.java | 7 +- .../main/recent/RecentFragment.java | 2 - .../activities/profile/ProfileActivity.java | 2 - .../latestPosts/LatestPostsFragment.java | 1 - .../profile/stats/StatsFragment.java | 1 - .../profile/summary/SummaryFragment.java | 2 - .../mthmmy/activities/topic/TopicAdapter.java | 2 - .../gr/thmmy/mthmmy/base/BaseActivity.java | 56 +++--- .../gr/thmmy/mthmmy/receiver/Receiver.java | 1 - .../mthmmy/services/DownloadService.java | 1 - app/src/main/res/values/strings.xml | 4 +- 14 files changed, 130 insertions(+), 132 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java index ec0c2b25..28a0fb80 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java @@ -22,6 +22,8 @@ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; public class BookmarkActivity extends BaseActivity { + private TextView boardsTitle; + private TextView topicsTitle; @Override protected void onCreate(Bundle savedInstanceState) { @@ -43,93 +45,100 @@ public class BookmarkActivity extends BaseActivity { LinearLayout bookmarksLinearView = (LinearLayout) findViewById(R.id.bookmarks_container); LayoutInflater layoutInflater = getLayoutInflater(); - TextView tmp = new TextView(this); - tmp.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT - , LinearLayout.LayoutParams.WRAP_CONTENT)); - tmp.setText(getString(R.string.board_bookmarks_title)); - tmp.setTypeface(tmp.getTypeface(), Typeface.BOLD); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - tmp.setTextColor(getColor(R.color.primary_text)); - } else { - //noinspection deprecation - tmp.setTextColor(getResources().getColor(R.color.primary_text)); - } - tmp.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - tmp.setTextSize(20f); - bookmarksLinearView.addView(tmp); + if(!getBoardsBookmarked().isEmpty()) { + boardsTitle = new TextView(this); + boardsTitle.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT + , LinearLayout.LayoutParams.WRAP_CONTENT)); + boardsTitle.setText(getString(R.string.board_bookmarks_title)); + boardsTitle.setTypeface(boardsTitle.getTypeface(), Typeface.BOLD); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + boardsTitle.setTextColor(getColor(R.color.primary_text)); + } else { + //noinspection deprecation + boardsTitle.setTextColor(getResources().getColor(R.color.primary_text)); + } + boardsTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + boardsTitle.setTextSize(20f); + bookmarksLinearView.addView(boardsTitle); - for (final Bookmark bookmarkedBoard : getBoardsBookmarked()) { - if (bookmarkedBoard != null && bookmarkedBoard.getTitle() != null) { - final LinearLayout row = (LinearLayout) layoutInflater.inflate( - R.layout.activity_bookmark_row, bookmarksLinearView, false); - row.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(BookmarkActivity.this, BoardActivity.class); - Bundle extras = new Bundle(); - extras.putString(BUNDLE_BOARD_URL, "https://www.thmmy.gr/smf/index.php?board=" - + bookmarkedBoard.getId() + ".0"); - extras.putString(BUNDLE_BOARD_TITLE, bookmarkedBoard.getTitle()); - intent.putExtras(extras); - startActivity(intent); - finish(); - } - }); - ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedBoard.getTitle()); - (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - removeBookmark(bookmarkedBoard); - row.setVisibility(View.GONE); - } - }); - bookmarksLinearView.addView(row); + for (final Bookmark bookmarkedBoard : getBoardsBookmarked()) { + if (bookmarkedBoard != null && bookmarkedBoard.getTitle() != null) { + final LinearLayout row = (LinearLayout) layoutInflater.inflate( + R.layout.activity_bookmark_row, bookmarksLinearView, false); + row.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(BookmarkActivity.this, BoardActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_BOARD_URL, "https://www.thmmy.gr/smf/index.php?board=" + + bookmarkedBoard.getId() + ".0"); + extras.putString(BUNDLE_BOARD_TITLE, bookmarkedBoard.getTitle()); + intent.putExtras(extras); + startActivity(intent); + finish(); + } + }); + ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedBoard.getTitle()); + (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + removeBookmark(bookmarkedBoard); + row.setVisibility(View.GONE); + updateTitles(); + } + }); + bookmarksLinearView.addView(row); + } } } - tmp = new TextView(this); - tmp.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT - , LinearLayout.LayoutParams.WRAP_CONTENT)); - tmp.setText(getString(R.string.topic_bookmarks_title)); - tmp.setTypeface(tmp.getTypeface(), Typeface.BOLD); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - tmp.setTextColor(getColor(R.color.primary_text)); - } else { - //noinspection deprecation - tmp.setTextColor(getResources().getColor(R.color.primary_text)); - } - tmp.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - tmp.setTextSize(20f); - bookmarksLinearView.addView(tmp); - for (final Bookmark bookmarkedTopic : getTopicsBookmarked()) { - if (bookmarkedTopic != null && bookmarkedTopic.getTitle() != null) { - final LinearLayout row = (LinearLayout) layoutInflater.inflate( - R.layout.activity_bookmark_row, bookmarksLinearView, false); - row.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(BookmarkActivity.this, TopicActivity.class); - Bundle extras = new Bundle(); - extras.putString(BUNDLE_TOPIC_URL, "https://www.thmmy.gr/smf/index.php?topic=" - + bookmarkedTopic.getId() + "." + 2147483647); - extras.putString(BUNDLE_TOPIC_TITLE, bookmarkedTopic.getTitle()); - intent.putExtras(extras); - startActivity(intent); - finish(); - } - }); - ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedTopic.getTitle()); - (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - removeBookmark(bookmarkedTopic); - row.setVisibility(View.GONE); - } - }); - bookmarksLinearView.addView(row); + if(!getTopicsBookmarked().isEmpty()) { + topicsTitle = new TextView(this); + topicsTitle.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT + , LinearLayout.LayoutParams.WRAP_CONTENT)); + topicsTitle.setText(getString(R.string.topic_bookmarks_title)); + topicsTitle.setTypeface(topicsTitle.getTypeface(), Typeface.BOLD); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + topicsTitle.setTextColor(getColor(R.color.primary_text)); + } else { + //noinspection deprecation + topicsTitle.setTextColor(getResources().getColor(R.color.primary_text)); + } + topicsTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + topicsTitle.setTextSize(20f); + bookmarksLinearView.addView(topicsTitle); + + for (final Bookmark bookmarkedTopic : getTopicsBookmarked()) { + if (bookmarkedTopic != null && bookmarkedTopic.getTitle() != null) { + final LinearLayout row = (LinearLayout) layoutInflater.inflate( + R.layout.activity_bookmark_row, bookmarksLinearView, false); + row.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(BookmarkActivity.this, TopicActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_TOPIC_URL, "https://www.thmmy.gr/smf/index.php?topic=" + + bookmarkedTopic.getId() + "." + 2147483647); + extras.putString(BUNDLE_TOPIC_TITLE, bookmarkedTopic.getTitle()); + intent.putExtras(extras); + startActivity(intent); + finish(); + } + }); + ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedTopic.getTitle()); + (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + removeBookmark(bookmarkedTopic); + row.setVisibility(View.GONE); + updateTitles(); + } + }); + bookmarksLinearView.addView(row); + } } } } @@ -139,4 +148,12 @@ public class BookmarkActivity extends BaseActivity { drawer.setSelection(BOOKMARKS_ID); super.onResume(); } + + private void updateTitles() + { + if(getBoardsBookmarked().isEmpty()) + boardsTitle.setVisibility(View.GONE); + if(getTopicsBookmarked().isEmpty()) + topicsTitle.setVisibility(View.GONE); + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java index 39a770c2..460b0b0d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java @@ -14,7 +14,6 @@ import android.widget.Toast; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.base.BaseActivity; - import timber.log.Timber; import static gr.thmmy.mthmmy.session.SessionManager.CONNECTION_ERROR; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java index 724bf3c3..8c944f7f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java @@ -27,7 +27,6 @@ import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Download; import gr.thmmy.mthmmy.model.ThmmyPage; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; 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 83f7d748..3f9fab04 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 @@ -210,13 +210,12 @@ public class ForumFragment extends BaseFragment fetchedCategories.add(category); } + categories.clear(); + categories.addAll(fetchedCategories); + fetchedCategories.clear(); } else throw new ParseException("Parsing failed"); - - categories.clear(); - categories.addAll(fetchedCategories); - fetchedCategories.clear(); } @Override 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 293338d2..24c5132a 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 @@ -147,7 +147,6 @@ public class RecentFragment extends BaseFragment { Elements recent = document.select("#block8 :first-child div"); if (!recent.isEmpty()) { topicSummaries.clear(); - for (int i = 0; i < recent.size(); i += 3) { String link = recent.get(i).child(0).attr("href"); String title = recent.get(i).child(0).attr("title"); @@ -170,7 +169,6 @@ public class RecentFragment extends BaseFragment { topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); } - return; } throw new ParseException("Parsing failed"); 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 e5a30cc8..f21a21eb 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 @@ -19,7 +19,6 @@ import android.text.SpannableString; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; - import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; @@ -50,7 +49,6 @@ import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CenterVerticalSpan; import gr.thmmy.mthmmy.utils.CircleTransform; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java index d08ad37a..8f39f6c9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java @@ -26,7 +26,6 @@ import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.utils.ParseHelpers; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java index 8e9ca93d..50c8c521 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java @@ -41,7 +41,6 @@ import javax.net.ssl.SSLHandshakeException; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; - import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java index 70644bf4..fc3d4dd7 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java @@ -7,7 +7,6 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.text.Html; import android.text.method.LinkMovementMethod; - import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -25,7 +24,6 @@ import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.utils.ParseHelpers; - import timber.log.Timber; 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 f1a0cca2..42c29531 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 @@ -18,7 +18,6 @@ import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; - import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -54,7 +53,6 @@ import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CircleTransform; - import timber.log.Timber; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 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 3be339d3..10516b05 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -65,7 +65,6 @@ public abstract class BaseActivity extends AppCompatActivity { private static final String BOOKMARKED_BOARDS_KEY = "bookmarkedBoardsKey"; protected Bookmark thisPageBookmark; private MenuItem thisPageBookmarkMenuButton; - private ImageButton thisPageBookmarkImageButton; private SharedPreferences bookmarksFile; private ArrayList topicsBookmarked; private ArrayList boardsBookmarked; @@ -86,25 +85,23 @@ public abstract class BaseActivity extends AppCompatActivity { if (sessionManager == null) sessionManager = BaseApplication.getInstance().getSessionManager(); - - if (sessionManager.isLoggedIn()) { - if (bookmarked == null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - bookmarked = getResources().getDrawable(R.drawable.ic_bookmark_true, null); - } else //noinspection deprecation - bookmarked = getResources().getDrawable(R.drawable.ic_bookmark_true); - } - if (notBookmarked == null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - notBookmarked = getResources().getDrawable(R.drawable.ic_bookmark_false, null); - } else //noinspection deprecation - notBookmarked = getResources().getDrawable(R.drawable.ic_bookmark_false); - } - if (topicsBookmarked == null || boardsBookmarked == null) { - bookmarksFile = getSharedPreferences(BOOKMARKS_SHARED_PREFS, Context.MODE_PRIVATE); - loadSavedBookmarks(); - } + if (bookmarked == null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + bookmarked = getResources().getDrawable(R.drawable.ic_bookmark_true, null); + } else //noinspection deprecation + bookmarked = getResources().getDrawable(R.drawable.ic_bookmark_true); } + if (notBookmarked == null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + notBookmarked = getResources().getDrawable(R.drawable.ic_bookmark_false, null); + } else //noinspection deprecation + notBookmarked = getResources().getDrawable(R.drawable.ic_bookmark_false); + } + if (topicsBookmarked == null || boardsBookmarked == null) { + bookmarksFile = getSharedPreferences(BOOKMARKS_SHARED_PREFS, Context.MODE_PRIVATE); + loadSavedBookmarks(); + } + } @Override @@ -221,14 +218,6 @@ public abstract class BaseActivity extends AppCompatActivity { .withName(R.string.downloads) .withIcon(downloadsIcon) .withSelectedIcon(downloadsIconSelected); - bookmarksItem = new PrimaryDrawerItem() - .withTextColor(primaryColor) - .withSelectedColor(selectedPrimaryColor) - .withSelectedTextColor(selectedSecondaryColor) - .withIdentifier(BOOKMARKS_ID) - .withName(R.string.bookmark) - .withIcon(bookmarksIcon) - .withSelectedIcon(bookmarksIconSelected); } else loginLogoutItem = new PrimaryDrawerItem() .withTextColor(primaryColor) @@ -237,6 +226,15 @@ public abstract class BaseActivity extends AppCompatActivity { .withIcon(loginIcon) .withSelectable(false); + bookmarksItem = new PrimaryDrawerItem() + .withTextColor(primaryColor) + .withSelectedColor(selectedPrimaryColor) + .withSelectedTextColor(selectedSecondaryColor) + .withIdentifier(BOOKMARKS_ID) + .withName(R.string.bookmark) + .withIcon(bookmarksIcon) + .withSelectedIcon(bookmarksIconSelected); + aboutItem = new PrimaryDrawerItem() .withTextColor(primaryColor) .withSelectedColor(selectedPrimaryColor) @@ -333,7 +331,7 @@ public abstract class BaseActivity extends AppCompatActivity { if (sessionManager.isLoggedIn()) drawerBuilder.addDrawerItems(homeItem, bookmarksItem, downloadsItem, loginLogoutItem, aboutItem); else - drawerBuilder.addDrawerItems(homeItem, loginLogoutItem, aboutItem); + drawerBuilder.addDrawerItems(homeItem, bookmarksItem, loginLogoutItem, aboutItem); drawer = drawerBuilder.build(); @@ -352,7 +350,6 @@ public abstract class BaseActivity extends AppCompatActivity { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest { drawer.removeItem(DOWNLOADS_ID); - drawer.removeItem(BOOKMARKS_ID); loginLogoutItem.withName(R.string.login).withIcon(loginIcon); //Swap logout with login profileDrawerItem.withName(sessionManager.getUsername()).withIcon(new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_user) @@ -432,7 +429,6 @@ public abstract class BaseActivity extends AppCompatActivity { } protected void setBoardBookmark(final ImageButton thisPageBookmarkImageButton) { - this.thisPageBookmarkImageButton = thisPageBookmarkImageButton; if (thisPageBookmark.matchExists(boardsBookmarked)) { thisPageBookmarkImageButton.setImageDrawable(bookmarked); } else { diff --git a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java index d93f4272..6b7f0c60 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -14,7 +14,6 @@ import android.webkit.MimeTypeMap; import java.io.File; import gr.thmmy.mthmmy.R; - import timber.log.Timber; import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java index 0283cef1..4e22c7b1 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -13,7 +13,6 @@ import java.io.IOException; import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.receiver.Receiver; - import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d95e5e63..6faf81e1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,8 +63,8 @@ Remove - Your bookmarked boards: - Your bookmarked topics: + Boards + Topics Libraries From dea72c44adc09435426cb5be752ff58b56943209 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Tue, 11 Jul 2017 18:33:23 +0300 Subject: [PATCH 08/25] Bookmarks hotfix --- .../java/gr/thmmy/mthmmy/activities/BookmarkActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java index 28a0fb80..1ff2c001 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java @@ -151,9 +151,9 @@ public class BookmarkActivity extends BaseActivity { private void updateTitles() { - if(getBoardsBookmarked().isEmpty()) + if(getBoardsBookmarked().isEmpty()&&boardsTitle!=null) boardsTitle.setVisibility(View.GONE); - if(getTopicsBookmarked().isEmpty()) + if(getTopicsBookmarked().isEmpty()&&topicsTitle!=null) topicsTitle.setVisibility(View.GONE); } } From ab0b82e04fe2df27ee3300a687cfa6aad2f9ac2b Mon Sep 17 00:00:00 2001 From: Ezerous Date: Tue, 11 Jul 2017 19:02:29 +0300 Subject: [PATCH 09/25] Fixed TopicTitle ellipsizing, removed toolbar from MainActivity, minor tweaks --- .../gr/thmmy/mthmmy/activities/BookmarkActivity.java | 3 +++ .../gr/thmmy/mthmmy/activities/main/MainActivity.java | 7 ------- .../gr/thmmy/mthmmy/activities/topic/TopicActivity.java | 5 +++++ app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java | 4 +++- app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java | 2 +- app/src/main/res/drawable/ic_file_download.xml | 9 +++++++++ app/src/main/res/layout/activity_main.xml | 9 --------- app/src/main/res/layout/activity_topic.xml | 7 ------- 8 files changed, 21 insertions(+), 25 deletions(-) create mode 100644 app/src/main/res/drawable/ic_file_download.xml diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java index 1ff2c001..d010eb8f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java @@ -21,6 +21,9 @@ 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 better UI +//TODO after clicking bookmark and then back button should return to this activity public class BookmarkActivity extends BaseActivity { private TextView boardsTitle; private TextView topicsTitle; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java index ddc604b4..dd57cba4 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java @@ -8,7 +8,6 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; -import android.support.v7.widget.Toolbar; import android.widget.Toast; import gr.thmmy.mthmmy.R; @@ -57,12 +56,6 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out); } - //Initialize toolbar - toolbar = (Toolbar) - - findViewById(R.id.toolbar); - - setSupportActionBar(toolbar); //Initialize drawer createDrawer(); 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 c959d091..e097f937 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 @@ -14,6 +14,7 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Html; import android.text.SpannableStringBuilder; +import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.text.method.ScrollingMovementMethod; import android.text.style.ClickableSpan; @@ -143,7 +144,11 @@ public class TopicActivity extends BaseActivity { //Initializes graphics toolbar = (Toolbar) findViewById(R.id.toolbar); toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title); + toolbarTitle.setSingleLine(true); + toolbarTitle.setEllipsize(TextUtils.TruncateAt.MARQUEE); + toolbarTitle.setMarqueeRepeatLimit(-1); toolbarTitle.setText(topicTitle); + toolbarTitle.setSelected(true); setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); 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 10516b05..a2c8877e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -335,7 +335,9 @@ public abstract class BaseActivity extends AppCompatActivity { drawer = drawerBuilder.build(); - drawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false); + if(!(BaseActivity.this instanceof MainActivity)) + drawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false); + drawer.setOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() { @Override public boolean onNavigationClickListener(View clickedView) { diff --git a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java index 6b7f0c60..2ef4fdd4 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -49,7 +49,7 @@ public class Receiver extends BroadcastReceiver { .setContentText(text) .setTicker(ticker) .setAutoCancel(true) - .setSmallIcon(R.mipmap.ic_launcher); + .setSmallIcon(R.drawable.ic_file_download); if (state.equals(STARTED)) builder.setOngoing(true); diff --git a/app/src/main/res/drawable/ic_file_download.xml b/app/src/main/res/drawable/ic_file_download.xml new file mode 100644 index 00000000..80734766 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_download.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b032b9b9..d3c0fe27 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -13,17 +13,8 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="@dimen/appbar_padding_top" android:theme="@style/ToolbarTheme"> - - - From 1c57f25e30b2f01a3d6f5ac982b730136d38fb34 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Fri, 14 Jul 2017 14:16:13 +0300 Subject: [PATCH 10/25] Proguard update --- app/proguard-rules.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 3b0e65f5..b00af7bc 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -31,4 +31,7 @@ } # android-gif-drawable --keep public class pl.droidsonroids.gif.GifIOException{(int, java.lang.String);} \ No newline at end of file +-keep public class pl.droidsonroids.gif.GifIOException{(int, java.lang.String);} + +#JSoup +-keep class org.jsoup.** \ No newline at end of file From 1d5214136fa84fe9d65feae7db55d10c3ae8188b Mon Sep 17 00:00:00 2001 From: Apostolof Date: Fri, 14 Jul 2017 22:19:13 +0300 Subject: [PATCH 11/25] Unread posts init --- .../mthmmy/activities/main/MainActivity.java | 21 +- .../activities/main/forum/ForumFragment.java | 44 ++--- .../main/recent/RecentFragment.java | 17 +- .../activities/main/unread/UnreadAdapter.java | 109 +++++++++++ .../main/unread/UnreadFragment.java | 184 ++++++++++++++++++ .../thmmy/mthmmy/session/SessionManager.java | 1 + app/src/main/res/layout/fragment_unread.xml | 38 ++++ .../res/layout/fragment_unread_empty_row.xml | 19 ++ .../main/res/layout/fragment_unread_row.xml | 54 +++++ app/src/main/res/values-w820dp/dimens.xml | 1 + app/src/main/res/values/dimens.xml | 1 + 11 files changed, 450 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java create mode 100644 app/src/main/res/layout/fragment_unread.xml create mode 100644 app/src/main/res/layout/fragment_unread_empty_row.xml create mode 100644 app/src/main/res/layout/fragment_unread_row.xml diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java index dd57cba4..c730b9df 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java @@ -16,6 +16,7 @@ import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.main.forum.ForumFragment; import gr.thmmy.mthmmy.activities.main.recent.RecentFragment; +import gr.thmmy.mthmmy.activities.main.unread.UnreadFragment; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.base.BaseActivity; @@ -33,7 +34,7 @@ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; -public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener { +public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener, UnreadFragment.UnreadFragmentInteractionListener { //----------------------------------------CLASS VARIABLES----------------------------------------- private static final int TIME_INTERVAL = 2000; @@ -115,6 +116,14 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF startActivity(i); } + @Override + public void onUnreadFragmentInteraction(TopicSummary topicSummary){ + Intent i = new Intent(MainActivity.this, TopicActivity.class); + i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl()); + i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getSubject()); + startActivity(i); + } + //---------------------------------FragmentPagerAdapter--------------------------------------------- /** @@ -123,7 +132,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF * it may be best to switch to a * {@link android.support.v4.app.FragmentStatePagerAdapter}. */ - public class SectionsPagerAdapter extends FragmentPagerAdapter { + private class SectionsPagerAdapter extends FragmentPagerAdapter { SectionsPagerAdapter(FragmentManager fm) { super(fm); @@ -136,6 +145,8 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF return RecentFragment.newInstance(position + 1); case 1: return ForumFragment.newInstance(position + 1); + case 2: + return UnreadFragment.newInstance(position + 1); default: return RecentFragment.newInstance(position + 1); //temp (?) } @@ -143,8 +154,8 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF @Override public int getCount() { - // Show 2 total pages. - return 2; + // Show 3 total pages. + return 3; } @Override @@ -154,6 +165,8 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF return "RECENT POSTS"; case 1: return "FORUM"; + case 2: + return "UNREAD"; } return null; 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 3f9fab04..75919925 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 @@ -42,8 +42,7 @@ import timber.log.Timber; * Use the {@link ForumFragment#newInstance} factory method to * create an instance of this fragment. */ -public class ForumFragment extends BaseFragment -{ +public class ForumFragment extends BaseFragment { private static final String TAG = "ForumFragment"; // Fragment initialization parameters, e.g. ARG_SECTION_NUMBER @@ -56,11 +55,13 @@ public class ForumFragment extends BaseFragment private ForumTask forumTask; // Required empty public constructor - public ForumFragment() {} + public ForumFragment() { + } /** * Use ONLY this factory method to create a new instance of * this fragment using the provided parameters. + * * @return A new instance of fragment Forum. */ public static ForumFragment newInstance(int sectionNumber) { @@ -81,9 +82,8 @@ public class ForumFragment extends BaseFragment @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (categories.isEmpty()) - { - forumTask =new ForumTask(); + if (categories.isEmpty()) { + forumTask = new ForumTask(); forumTask.execute(); } @@ -103,11 +103,10 @@ public class ForumFragment extends BaseFragment forumAdapter.setExpandCollapseListener(new ExpandableRecyclerAdapter.ExpandCollapseListener() { @Override public void onParentExpanded(int parentPosition) { - if(BaseActivity.getSessionManager().isLoggedIn()) - { - if(forumTask.getStatus()== AsyncTask.Status.RUNNING) + if (BaseActivity.getSessionManager().isLoggedIn()) { + if (forumTask.getStatus() == AsyncTask.Status.RUNNING) forumTask.cancel(true); - forumTask =new ForumTask(); + forumTask = new ForumTask(); forumTask.setUrl(categories.get(parentPosition).getCategoryURL()); forumTask.execute(); } @@ -115,11 +114,10 @@ public class ForumFragment extends BaseFragment @Override public void onParentCollapsed(int parentPosition) { - if(BaseActivity.getSessionManager().isLoggedIn()) - { - if(forumTask.getStatus()== AsyncTask.Status.RUNNING) + if (BaseActivity.getSessionManager().isLoggedIn()) { + if (forumTask.getStatus() == AsyncTask.Status.RUNNING) forumTask.cancel(true); - forumTask =new ForumTask(); + forumTask = new ForumTask(); forumTask.setUrl(categories.get(parentPosition).getCategoryURL()); forumTask.execute(); } @@ -155,11 +153,11 @@ public class ForumFragment extends BaseFragment @Override public void onDestroy() { super.onDestroy(); - if(forumTask!=null&&forumTask.getStatus()!= AsyncTask.Status.RUNNING) + if (forumTask != null && forumTask.getStatus() != AsyncTask.Status.RUNNING) forumTask.cancel(true); } - public interface ForumFragmentInteractionListener extends FragmentInteractionListener{ + public interface ForumFragmentInteractionListener extends FragmentInteractionListener { void onForumFragmentInteraction(Board board); } @@ -190,22 +188,19 @@ public class ForumFragment extends BaseFragment public void parse(Document document) throws ParseException { Elements categoryBlocks = document.select(".tborder:not([style])>table[cellpadding=5]"); if (categoryBlocks.size() != 0) { - for(Element categoryBlock: categoryBlocks) - { + for (Element categoryBlock : categoryBlocks) { Element categoryElement = categoryBlock.select("td[colspan=2]>[name]").first(); String categoryUrl = categoryElement.attr("href"); Category category = new Category(categoryElement.text(), categoryUrl); - if(categoryUrl.contains("sa=collapse")|| !BaseActivity.getSessionManager().isLoggedIn()) - { + if (categoryUrl.contains("sa=collapse") || !BaseActivity.getSessionManager().isLoggedIn()) { category.setExpanded(true); Elements boardsElements = categoryBlock.select("b [name]"); - for(Element boardElement: boardsElements) { + for (Element boardElement : boardsElements) { Board board = new Board(boardElement.attr("href"), boardElement.text(), null, null, null, null); category.getBoards().add(board); } - } - else + } else category.setExpanded(false); fetchedCategories.add(category); @@ -213,8 +208,7 @@ public class ForumFragment extends BaseFragment categories.clear(); categories.addAll(fetchedCategories); fetchedCategories.clear(); - } - else + } else throw new ParseException("Parsing failed"); } 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 24c5132a..86e3a2d2 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 @@ -51,11 +51,13 @@ public class RecentFragment extends BaseFragment { private RecentTask recentTask; // Required empty public constructor - public RecentFragment() {} + public RecentFragment() { + } /** * Use ONLY this factory method to create a new instance of * this fragment using the provided parameters. + * * @return A new instance of fragment Recent. */ public static RecentFragment newInstance(int sectionNumber) { @@ -76,9 +78,8 @@ public class RecentFragment extends BaseFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (topicSummaries.isEmpty()) - { - recentTask =new RecentTask(); + if (topicSummaries.isEmpty()) { + recentTask = new RecentTask(); recentTask.execute(SessionManager.indexUrl.toString()); } @@ -126,7 +127,7 @@ public class RecentFragment extends BaseFragment { @Override public void onDestroy() { super.onDestroy(); - if(recentTask!=null&&recentTask.getStatus()!= AsyncTask.Status.RUNNING) + if (recentTask != null && recentTask.getStatus() != AsyncTask.Status.RUNNING) recentTask.cancel(true); } @@ -142,8 +143,7 @@ public class RecentFragment extends BaseFragment { } @Override - public void parse(Document document) throws ParseException - { + public void parse(Document document) throws ParseException { Elements recent = document.select("#block8 :first-child div"); if (!recent.isEmpty()) { topicSummaries.clear(); @@ -174,7 +174,6 @@ public class RecentFragment extends BaseFragment { throw new ParseException("Parsing failed"); } - @Override protected void postParsing(ParseTask.ResultCode result) { if (result == ResultCode.SUCCESS) @@ -183,7 +182,5 @@ public class RecentFragment extends BaseFragment { progressBar.setVisibility(ProgressBar.INVISIBLE); swipeRefreshLayout.setRefreshing(false); } - } - } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java new file mode 100644 index 00000000..c6ae194d --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java @@ -0,0 +1,109 @@ +package gr.thmmy.mthmmy.activities.main.unread; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.List; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseFragment; +import gr.thmmy.mthmmy.model.TopicSummary; + +class UnreadAdapter extends RecyclerView.Adapter { + private final Context context; + private final List unreadList; + private final UnreadFragment.UnreadFragmentInteractionListener mListener; + + private final int VIEW_TYPE_ITEM = 0; + private final int VIEW_TYPE_NADA = 1; + + UnreadAdapter(Context context, @NonNull List topicSummaryList, BaseFragment.FragmentInteractionListener listener) { + this.context = context; + this.unreadList = topicSummaryList; + mListener = (UnreadFragment.UnreadFragmentInteractionListener) listener; + } + + @Override + public int getItemViewType(int position) { + return unreadList.get(position).getTopicUrl() == null ? VIEW_TYPE_NADA : VIEW_TYPE_ITEM; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_ITEM) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.fragment_unread_row, parent, false); + return new ViewHolder(view); + } else if (viewType == VIEW_TYPE_NADA) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.fragment_unread_empty_row, parent, false); + return new EmptyViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (holder instanceof UnreadAdapter.EmptyViewHolder) { + final UnreadAdapter.EmptyViewHolder emptyViewHolder = (UnreadAdapter.EmptyViewHolder) holder; + emptyViewHolder.text.setText(unreadList.get(position).getDateTimeModified()); + } else if (holder instanceof UnreadAdapter.ViewHolder) { + final UnreadAdapter.ViewHolder viewHolder = (UnreadAdapter.ViewHolder) holder; + + viewHolder.mTitleView.setText(unreadList.get(position).getSubject()); + viewHolder.mDateTimeView.setText(unreadList.get(position).getDateTimeModified()); + viewHolder.mUserView.setText(context.getString(R.string.byUser, unreadList.get(position).getLastUser())); + + viewHolder.topic = unreadList.get(position); + + viewHolder.mView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (null != mListener) { + // Notify the active callbacks interface (the activity, if the + // fragment is attached to one) that an item has been selected. + mListener.onUnreadFragmentInteraction(viewHolder.topic); //? + + } + + } + }); + } + } + + @Override + public int getItemCount() { + return unreadList.size(); + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + final View mView; + final TextView mTitleView; + final TextView mUserView; + final TextView mDateTimeView; + public TopicSummary topic; + + ViewHolder(View view) { + super(view); + mView = view; + mTitleView = (TextView) view.findViewById(R.id.title); + mUserView = (TextView) view.findViewById(R.id.lastUser); + mDateTimeView = (TextView) view.findViewById(R.id.dateTime); + } + } + + private static class EmptyViewHolder extends RecyclerView.ViewHolder { + final TextView text; + + EmptyViewHolder(View view) { + super(view); + text = (TextView) view.findViewById(R.id.text); + } + } +} 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 new file mode 100644 index 00000000..726d502f --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java @@ -0,0 +1,184 @@ +package gr.thmmy.mthmmy.activities.main.unread; + +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; + +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; +import java.util.List; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseFragment; +import gr.thmmy.mthmmy.model.TopicSummary; +import gr.thmmy.mthmmy.session.SessionManager; +import gr.thmmy.mthmmy.utils.CustomRecyclerView; +import gr.thmmy.mthmmy.utils.ParseTask; +import gr.thmmy.mthmmy.utils.exceptions.ParseException; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import timber.log.Timber; + +/** + * A {@link BaseFragment} subclass. + * Activities that contain this fragment must implement the + * {@link UnreadFragment.UnreadFragmentInteractionListener} interface + * to handle interaction events. + * Use the {@link UnreadFragment#newInstance} factory method to + * create an instance of this fragment. + */ + +public class UnreadFragment extends BaseFragment { + private static final String TAG = "UnreadFragment"; + // Fragment initialization parameters, e.g. ARG_SECTION_NUMBER + + private MaterialProgressBar progressBar; + private SwipeRefreshLayout swipeRefreshLayout; + private UnreadAdapter unreadAdapter; + + private List topicSummaries; + + private UnreadTask unreadTask; + + // Required empty public constructor + public UnreadFragment() { + } + + /** + * Use ONLY this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment Unread. + */ + public static UnreadFragment newInstance(int sectionNumber) { + UnreadFragment fragment = new UnreadFragment(); + Bundle args = new Bundle(); + args.putString(ARG_TAG, TAG); + args.putInt(ARG_SECTION_NUMBER, sectionNumber); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + topicSummaries = new ArrayList<>(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + if (topicSummaries.isEmpty()) { + unreadTask = new UnreadTask(); + unreadTask.execute(SessionManager.unreadUrl.toString()); + + } + Timber.d("onActivityCreated"); + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + final View rootView = inflater.inflate(R.layout.fragment_unread, container, false); + + // Set the adapter + if (rootView instanceof RelativeLayout) { + progressBar = (MaterialProgressBar) rootView.findViewById(R.id.progressBar); + unreadAdapter = new UnreadAdapter(getActivity(), topicSummaries, fragmentInteractionListener); + + CustomRecyclerView recyclerView = (CustomRecyclerView) rootView.findViewById(R.id.list); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext()); + recyclerView.setLayoutManager(linearLayoutManager); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), + linearLayoutManager.getOrientation()); + recyclerView.addItemDecoration(dividerItemDecoration); + recyclerView.setAdapter(unreadAdapter); + + swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swiperefresh); + swipeRefreshLayout.setOnRefreshListener( + new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) { + unreadTask = new UnreadTask(); + unreadTask.execute(SessionManager.unreadUrl.toString()); + } + } + + } + ); + } + + return rootView; + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) + unreadTask.cancel(true); + } + + + public interface UnreadFragmentInteractionListener extends FragmentInteractionListener { + void onUnreadFragmentInteraction(TopicSummary topicSummary); + } + + //---------------------------------------ASYNC TASK----------------------------------- + private class UnreadTask extends ParseTask { + protected void onPreExecute() { + progressBar.setVisibility(ProgressBar.VISIBLE); + } + + @Override + public void parse(Document document) throws ParseException { + Elements unread = document.select("table.bordercolor[cellspacing=1] tr:not(.titlebg)"); + if (!unread.isEmpty()) { + topicSummaries.clear(); + for (Element row : unread) { + Elements information = row.select("td"); + String link = information.get(2).select("a").first().attr("href"); + String title = information.get(2).select("a").first().text(); + + Element lastUserAndDate = information.get(6); + String lastUser = lastUserAndDate.select("a").text(); + String dateTime = lastUserAndDate.select("span").html(); + dateTime = dateTime.substring(3, dateTime.indexOf("", ""); + + topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); + } + } else { + String message = document.select("table.bordercolor[cellspacing=1]").first().text(); + if (message.contains("No messages")){ //It's english + message = "No unread posts!"; + }else{ //It's greek + message = "Δεν υπάρχουν μη διαβασμένα μυνήματα!"; + } + topicSummaries.add(new TopicSummary(null, null, null, message)); + } + } + + + @Override + protected void postParsing(ParseTask.ResultCode result) { + if (result == ResultCode.SUCCESS) + unreadAdapter.notifyDataSetChanged(); + + progressBar.setVisibility(ProgressBar.INVISIBLE); + swipeRefreshLayout.setRefreshing(false); + } + + } +} 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 b5b56bfe..4c2c60cc 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -36,6 +36,7 @@ public class SessionManager { public static final HttpUrl indexUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?theme=4"); public static final HttpUrl forumUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=forum;theme=4"); 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"); private static final String guestName = "Guest"; //Response Codes diff --git a/app/src/main/res/layout/fragment_unread.xml b/app/src/main/res/layout/fragment_unread.xml new file mode 100644 index 00000000..846fb7cb --- /dev/null +++ b/app/src/main/res/layout/fragment_unread.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_unread_empty_row.xml b/app/src/main/res/layout/fragment_unread_empty_row.xml new file mode 100644 index 00000000..d5394258 --- /dev/null +++ b/app/src/main/res/layout/fragment_unread_empty_row.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_unread_row.xml b/app/src/main/res/layout/fragment_unread_row.xml new file mode 100644 index 00000000..8f256f2e --- /dev/null +++ b/app/src/main/res/layout/fragment_unread_row.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml index d70052bd..2efd3b5a 100644 --- a/app/src/main/res/values-w820dp/dimens.xml +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -9,4 +9,5 @@ 144dp 64dp 40dp + 24sp diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index a779507a..914c6e3d 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -7,4 +7,5 @@ 36dp 16dp 10dp + 24sp From 4f99f9b296bbd86597d16cd0744b98e581e7d5b8 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Fri, 14 Jul 2017 22:41:47 +0300 Subject: [PATCH 12/25] Unread posts tab minor 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 726d502f..4b5e6b6c 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 @@ -5,6 +5,7 @@ import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -146,6 +147,7 @@ public class UnreadFragment extends BaseFragment { Elements unread = document.select("table.bordercolor[cellspacing=1] tr:not(.titlebg)"); if (!unread.isEmpty()) { topicSummaries.clear(); + Log.d("UnreadFragment", unread.html()); for (Element row : unread) { Elements information = row.select("td"); String link = information.get(2).select("a").first().attr("href"); @@ -154,7 +156,7 @@ public class UnreadFragment extends BaseFragment { Element lastUserAndDate = information.get(6); String lastUser = lastUserAndDate.select("a").text(); String dateTime = lastUserAndDate.select("span").html(); - dateTime = dateTime.substring(3, dateTime.indexOf("")); dateTime = dateTime.replace("", ""); topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); From 8b995830004c05bcf6a09aaa43ebd6fb184c3d69 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 15 Jul 2017 00:11:01 +0300 Subject: [PATCH 13/25] Post's date and index visible by default, unread posts tab minor fix --- .../main/unread/UnreadFragment.java | 6 +- .../activities/topic/TopicActivity.java | 16 +- .../mthmmy/activities/topic/TopicAdapter.java | 152 ++++-------------- .../activities/topic/TopicAnimations.java | 86 +++------- .../layout-v21/activity_topic_post_row.xml | 112 ++++++------- .../res/layout/activity_topic_post_row.xml | 99 ++++++------ app/src/main/res/menu/topic_menu.xml | 4 +- app/src/main/res/values/strings.xml | 1 + 8 files changed, 161 insertions(+), 315 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 4b5e6b6c..f5145c43 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 @@ -150,18 +150,20 @@ public class UnreadFragment extends BaseFragment { Log.d("UnreadFragment", unread.html()); for (Element row : unread) { Elements information = row.select("td"); - String link = information.get(2).select("a").first().attr("href"); + String link = information.last().select("a").first().attr("href"); String title = information.get(2).select("a").first().text(); Element lastUserAndDate = information.get(6); String lastUser = lastUserAndDate.select("a").text(); String dateTime = lastUserAndDate.select("span").html(); - dateTime = dateTime.substring(3, dateTime.indexOf("
    ")); + //dateTime = dateTime.replace("
    ", ""); + dateTime = dateTime.substring(0, dateTime.indexOf("
    ")); dateTime = dateTime.replace("", ""); topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); } } else { + topicSummaries.clear(); String message = document.select("table.bordercolor[cellspacing=1]").first().text(); if (message.contains("No messages")){ //It's english message = "No unread posts!"; 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 e097f937..f96f30bc 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 @@ -5,6 +5,7 @@ import android.content.Intent; import android.graphics.Rect; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.design.widget.FloatingActionButton; @@ -114,12 +115,12 @@ public class TopicActivity extends BaseActivity { topicViewers = new SpannableStringBuilder("Loading..."); //Other variables private MaterialProgressBar progressBar; - TextView toolbarTitle; + private TextView toolbarTitle; private static String base_url = ""; private String topicTitle; private String parsedTitle; private RecyclerView recyclerView; - String loadedPageUrl = ""; + private String loadedPageUrl = ""; private boolean reloadingPage = false; @@ -665,7 +666,13 @@ public class TopicActivity extends BaseActivity { } private SpannableStringBuilder getSpannableFromHtml(String html) { - CharSequence sequence = Html.fromHtml(html); + CharSequence sequence; + if (Build.VERSION.SDK_INT >= 24) { + sequence = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY); + } else { + //noinspection deprecation + sequence = Html.fromHtml(html); + } SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence); URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class); for (URLSpan span : urls) { @@ -687,7 +694,7 @@ public class TopicActivity extends BaseActivity { @Override protected Boolean doInBackground(String... message) { Document document; - String numReplies, seqnum, sc, subject, topic; + String numReplies, seqnum, sc, topic; Request request = new Request.Builder() .url(replyPageUrl + ";wap2") @@ -699,7 +706,6 @@ public class TopicActivity extends BaseActivity { numReplies = replyPageUrl.substring(replyPageUrl.indexOf("num_replies=") + 12); seqnum = document.select("input[name=seqnum]").first().attr("value"); sc = document.select("input[name=sc]").first().attr("value"); - //subject = document.select("input[name=subject]").first().attr("value"); topic = document.select("input[name=topic]").first().attr("value"); } catch (IOException e) { Timber.e(e,"Post failed."); 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 42c29531..3c848c72 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 @@ -19,7 +19,6 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.webkit.WebResourceRequest; @@ -74,35 +73,30 @@ class TopicAdapter extends RecyclerView.Adapter { private static int THUMBNAIL_SIZE; private final Context context; private String topicTitle; - private ArrayList toQuoteList = new ArrayList<>(); + private final ArrayList toQuoteList = new ArrayList<>(); private final List postsList; /** * Used to hold the state of visibility and other attributes for views that are animated or - * otherwise changed. Used in combination with {@link #isPostDateAndNumberVisibile}, - * {@link #isUserExtraInfoVisibile} and {@link #isQuoteButtonChecked}. + * otherwise changed. Used in combination with {@link #isUserExtraInfoVisibile} and + * {@link #isQuoteButtonChecked}. */ private final ArrayList viewProperties = new ArrayList<>(); - /** - * Index of state indicator in the boolean array. If true post is expanded and post's date and - * number are visible. - */ - private static final int isPostDateAndNumberVisibile = 0; /** * Index of state indicator in the boolean array. If true user's extra info are expanded and * visible. */ - private static final int isUserExtraInfoVisibile = 1; + private static final int isUserExtraInfoVisibile = 0; /** * Index of state indicator in the boolean array. If true quote button for this post is checked. */ - private static final int isQuoteButtonChecked = 2; + private static final int isQuoteButtonChecked = 1; private TopicActivity.TopicTask topicTask; private TopicActivity.ReplyTask replyTask; private final int VIEW_TYPE_POST = 0; private final int VIEW_TYPE_QUICK_REPLY = 1; - private String[] replyDataHolder = new String[2]; - private int replySubject = 0, replyText = 1; + private final String[] replyDataHolder = new String[2]; + private final int replySubject = 0, replyText = 1; private String loadedPageUrl = ""; /** @@ -323,9 +317,23 @@ class TopicAdapter extends RecyclerView.Adapter { if (!currentPost.isDeleted() && viewProperties.get(position)[isUserExtraInfoVisibile]) { holder.userExtraInfo.setVisibility(View.VISIBLE); holder.userExtraInfo.setAlpha(1.0f); + + holder.username.setMaxLines(Integer.MAX_VALUE); + holder.username.setEllipsize(null); + + holder.subject.setTextColor(Color.parseColor("#FFFFFF")); + holder.subject.setMaxLines(Integer.MAX_VALUE); + holder.subject.setEllipsize(null); } else { holder.userExtraInfo.setVisibility(View.GONE); holder.userExtraInfo.setAlpha(0.0f); + + holder.username.setMaxLines(1); + holder.username.setEllipsize(TextUtils.TruncateAt.END); + + holder.subject.setTextColor(Color.parseColor("#757575")); + holder.subject.setMaxLines(1); + holder.subject.setEllipsize(TextUtils.TruncateAt.END); } if (!currentPost.isDeleted()) { //Sets graphics behavior @@ -353,7 +361,9 @@ class TopicAdapter extends RecyclerView.Adapter { boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); tmp[isUserExtraInfoVisibile] = !tmp[isUserExtraInfoVisibile]; viewProperties.set(holder.getAdapterPosition(), tmp); - TopicAnimations.animateUserExtraInfoVisibility(holder.userExtraInfo); + TopicAnimations.animateUserExtraInfoVisibility(holder.username, + holder.subject, Color.parseColor("#FFFFFF"), + Color.parseColor("#757575"), holder.userExtraInfo); } }); //Clicking the expanded part of a header (the extra info) makes it collapse @@ -364,7 +374,9 @@ class TopicAdapter extends RecyclerView.Adapter { tmp[isUserExtraInfoVisibile] = false; viewProperties.set(holder.getAdapterPosition(), tmp); - TopicAnimations.animateUserExtraInfoVisibility(v); + TopicAnimations.animateUserExtraInfoVisibility(holder.username, + holder.subject, Color.parseColor("#FFFFFF"), + Color.parseColor("#757575"), v); } }); } else { @@ -372,30 +384,6 @@ class TopicAdapter extends RecyclerView.Adapter { holder.userExtraInfo.setOnClickListener(null); } - //Avoid's view's visibility recycling - if (viewProperties.get(position)[isPostDateAndNumberVisibile]) { //Expanded - holder.postDateAndNumberExp.setVisibility(View.VISIBLE); - holder.postDateAndNumberExp.setAlpha(1.0f); - holder.postDateAndNumberExp.setTranslationY(0); - - holder.username.setMaxLines(Integer.MAX_VALUE); - holder.username.setEllipsize(null); - - holder.subject.setTextColor(Color.parseColor("#FFFFFF")); - holder.subject.setMaxLines(Integer.MAX_VALUE); - holder.subject.setEllipsize(null); - } else { //Collapsed - holder.postDateAndNumberExp.setVisibility(View.GONE); - holder.postDateAndNumberExp.setAlpha(0.0f); - holder.postDateAndNumberExp.setTranslationY(holder.postDateAndNumberExp.getHeight()); - - holder.username.setMaxLines(1); - holder.username.setEllipsize(TextUtils.TruncateAt.END); - - holder.subject.setTextColor(Color.parseColor("#757575")); - holder.subject.setMaxLines(1); - holder.subject.setEllipsize(TextUtils.TruncateAt.END); - } //noinspection PointlessBooleanExpression,ConstantConditions if (!BaseActivity.getSessionManager().isLoggedIn()) holder.quoteToggle.setVisibility(View.GONE); @@ -425,23 +413,6 @@ class TopicAdapter extends RecyclerView.Adapter { } }); } - //Card expand/collapse when card is touched - holder.cardView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - //Change post's viewProperties accordingly - boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); - tmp[isPostDateAndNumberVisibile] = !tmp[isPostDateAndNumberVisibile]; - viewProperties.set(holder.getAdapterPosition(), tmp); - - TopicAnimations.animatePostExtraInfoVisibility(holder.postDateAndNumberExp - , holder.username, holder.subject - , Color.parseColor("#FFFFFF") - , Color.parseColor("#757575")); - } - }); - //Also when post is clicked - holder.post.setOnTouchListener(new CustomTouchListener(holder.post, holder.cardView)); } else if (currentHolder instanceof QuickReplyViewHolder) { final QuickReplyViewHolder holder = (QuickReplyViewHolder) currentHolder; @@ -501,7 +472,7 @@ class TopicAdapter extends RecyclerView.Adapter { private class PostViewHolder extends RecyclerView.ViewHolder { final CardView cardView; final LinearLayout cardChildLinear; - final FrameLayout postDateAndNumberExp; + final FrameLayout postDateAndNumber; final TextView postDate, postNum, username, subject; final ImageView thumbnail; final public WebView post; @@ -519,7 +490,7 @@ class TopicAdapter extends RecyclerView.Adapter { //Standard stuff cardView = (CardView) view.findViewById(R.id.card_view); cardChildLinear = (LinearLayout) view.findViewById(R.id.card_child_linear); - postDateAndNumberExp = (FrameLayout) view.findViewById(R.id.post_date_and_number_exp); + postDateAndNumber = (FrameLayout) view.findViewById(R.id.post_date_and_number_exp); postDate = (TextView) view.findViewById(R.id.post_date); postNum = (TextView) view.findViewById(R.id.post_number); thumbnail = (ImageView) view.findViewById(R.id.thumbnail); @@ -568,71 +539,6 @@ class TopicAdapter extends RecyclerView.Adapter { } } - /** - * This class is a gesture detector for WebViews. It handles post's clicks, long clicks and - * touch and drag. - */ - private class CustomTouchListener implements View.OnTouchListener { - //Long press handling - private float downCoordinateX; - private float downCoordinateY; - private final float SCROLL_THRESHOLD = 7; - final private WebView post; - final private CardView cardView; - - //Other variables - final static int FINGER_RELEASED = 0; - final static int FINGER_TOUCHED = 1; - final static int FINGER_DRAGGING = 2; - final static int FINGER_UNDEFINED = 3; - - private int fingerState = FINGER_RELEASED; - - CustomTouchListener(WebView pPost, CardView pCard) { - post = pPost; - cardView = pCard; - } - - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - switch (motionEvent.getAction()) { - case MotionEvent.ACTION_DOWN: - //Logs XY - downCoordinateX = motionEvent.getX(); - downCoordinateY = motionEvent.getY(); - - if (fingerState == FINGER_RELEASED) - fingerState = FINGER_TOUCHED; - else - fingerState = FINGER_UNDEFINED; - break; - case MotionEvent.ACTION_UP: - if (fingerState != FINGER_DRAGGING) { - //Doesn't expand the card if this was a link - WebView.HitTestResult htResult = post.getHitTestResult(); - if (htResult.getExtra() != null - && htResult.getExtra() != null) { - fingerState = FINGER_RELEASED; - return false; - } - cardView.performClick(); - } - fingerState = FINGER_RELEASED; - break; - case MotionEvent.ACTION_MOVE: - //Cancels long click if finger moved too much - if (((Math.abs(downCoordinateX - motionEvent.getX()) > SCROLL_THRESHOLD || - Math.abs(downCoordinateY - motionEvent.getY()) > SCROLL_THRESHOLD))) { - fingerState = FINGER_DRAGGING; - } else fingerState = FINGER_UNDEFINED; - break; - default: - fingerState = FINGER_UNDEFINED; - } - return false; - } - } - /** * This class is used to handle link clicks in WebViews. When link url is one that the app can * handle internally, it does. Otherwise user is prompt to open the link in a browser. diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java index c0206a1d..ae4516ef 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java @@ -7,80 +7,16 @@ import android.view.View; import android.widget.TextView; class TopicAnimations { - //--------------------------POST'S INFO VISIBILITY CHANGE ANIMATION METHOD-------------------------- - - /** - * Method that animates view's visibility changes for post's extra info - */ - static void animatePostExtraInfoVisibility(final View dateAndPostNum, TextView username, - TextView subject, int expandedColor, int collapsedColor) { - //If the view is gone fade it in - if (dateAndPostNum.getVisibility() == View.GONE) { - //Show full username - username.setMaxLines(Integer.MAX_VALUE); //As in the android sourcecode - username.setEllipsize(null); - - //Show full subject - subject.setTextColor(expandedColor); - subject.setMaxLines(Integer.MAX_VALUE); //As in the android sourcecode - subject.setEllipsize(null); - - - dateAndPostNum.clearAnimation(); - // Prepare the View for the animation - dateAndPostNum.setVisibility(View.VISIBLE); - dateAndPostNum.setAlpha(0.0f); - - // Start the animation - dateAndPostNum.animate() - .translationY(0) - .alpha(1.0f) - .setDuration(300) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - dateAndPostNum.setVisibility(View.VISIBLE); - } - }); - } - //If the view is visible fade it out - else { - username.setMaxLines(1); //As in the android sourcecode - username.setEllipsize(TextUtils.TruncateAt.END); - - subject.setTextColor(collapsedColor); - subject.setMaxLines(1); //As in the android sourcecode - subject.setEllipsize(TextUtils.TruncateAt.END); - - dateAndPostNum.clearAnimation(); - - // Start the animation - dateAndPostNum.animate() - .translationY(dateAndPostNum.getHeight()) - .alpha(0.0f) - .setDuration(300) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - dateAndPostNum.setVisibility(View.GONE); - } - }); - } - } -//------------------------POST'S INFO VISIBILITY CHANGE ANIMATION METHOD END------------------------ - //--------------------------USER'S INFO VISIBILITY CHANGE ANIMATION METHOD-------------------------- /** * Method that animates view's visibility changes for user's extra info */ - static void animateUserExtraInfoVisibility(final View userExtra) { - + static void animateUserExtraInfoVisibility(TextView username, TextView subject, + int expandedColor, int collapsedColor, + final View userExtra) { //If the view is gone fade it in if (userExtra.getVisibility() == View.GONE) { - userExtra.clearAnimation(); userExtra.setVisibility(View.VISIBLE); userExtra.setAlpha(0.0f); @@ -96,6 +32,15 @@ class TopicAnimations { userExtra.setVisibility(View.VISIBLE); } }); + + //Show full username + username.setMaxLines(Integer.MAX_VALUE); //As in the android sourcecode + username.setEllipsize(null); + + //Show full subject + subject.setTextColor(expandedColor); + subject.setMaxLines(Integer.MAX_VALUE); //As in the android sourcecode + subject.setEllipsize(null); } //If the view is visible fade it out else { @@ -112,6 +57,13 @@ class TopicAnimations { userExtra.setVisibility(View.GONE); } }); + + username.setMaxLines(1); //As in the android sourcecode + username.setEllipsize(TextUtils.TruncateAt.END); + + subject.setTextColor(collapsedColor); + subject.setMaxLines(1); //As in the android sourcecode + subject.setEllipsize(TextUtils.TruncateAt.END); } } //------------------------POST'S INFO VISIBILITY CHANGE ANIMATION METHOD END------------------------ diff --git a/app/src/main/res/layout-v21/activity_topic_post_row.xml b/app/src/main/res/layout-v21/activity_topic_post_row.xml index 8b745727..64bd6610 100644 --- a/app/src/main/res/layout-v21/activity_topic_post_row.xml +++ b/app/src/main/res/layout-v21/activity_topic_post_row.xml @@ -1,48 +1,14 @@ - - - - - - - - - + + + android:transitionName="user_thumbnail" /> + android:textStyle="bold" /> + android:text="@string/post_subject" /> + android:src="@drawable/ic_format_quote_unchecked" /> + android:visibility="gone" /> + android:visibility="gone" /> - + android:visibility="gone" /> + android:visibility="gone" /> + android:visibility="gone" /> + android:visibility="gone" /> + + + + + + + + + android:layout_marginTop="5dp" + android:background="@color/divider" /> + android:text="@string/post" /> + android:visibility="gone" /> - + android:paddingRight="16dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_topic_post_row.xml b/app/src/main/res/layout/activity_topic_post_row.xml index 677a58db..696566e1 100644 --- a/app/src/main/res/layout/activity_topic_post_row.xml +++ b/app/src/main/res/layout/activity_topic_post_row.xml @@ -1,6 +1,5 @@ - - - - - - - - - + android:src="@drawable/ic_default_user_thumbnail" /> + android:textStyle="bold" /> + android:text="@string/post_subject" /> + android:src="@drawable/ic_format_quote_unchecked" /> + android:visibility="gone" /> + android:visibility="gone" /> - + android:visibility="gone" /> + android:visibility="gone" /> + android:visibility="gone" /> + android:visibility="gone" /> + + + + + + + + + android:layout_marginTop="5dp" + android:background="@color/divider" /> + android:text="@string/post" /> + android:visibility="gone" /> - + android:paddingRight="16dp" /> \ No newline at end of file diff --git a/app/src/main/res/menu/topic_menu.xml b/app/src/main/res/menu/topic_menu.xml index 16c60e0a..e9ca1807 100644 --- a/app/src/main/res/menu/topic_menu.xml +++ b/app/src/main/res/menu/topic_menu.xml @@ -5,12 +5,12 @@ android:id="@+id/menu_bookmark" android:icon="@drawable/ic_bookmark_false" app:showAsAction="ifRoom" - android:title="Bookmark"> + android:title="@string/bookmark"> + android:title="@string/info"> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6faf81e1..5c6dc980 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,6 +9,7 @@ About Home Bookmarks + Info thmmy.gr From dfc57108a3958b8bf94753ee5fa39fdd8c81df90 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 15 Jul 2017 01:12:17 +0300 Subject: [PATCH 14/25] Fix for scroll-to-quickreply --- .../mthmmy/activities/topic/TopicActivity.java | 1 + .../mthmmy/activities/topic/TopicAdapter.java | 18 ++++++++++++++++++ app/src/main/res/drawable/ic_reply.xml | 9 +++++++++ app/src/main/res/layout/activity_topic.xml | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable/ic_reply.xml 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 f96f30bc..a10b7daf 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 @@ -187,6 +187,7 @@ public class TopicActivity extends BaseActivity { topicAdapter.prepareForReply(new ReplyTask(), topicTitle, loadedPageUrl); replyFAB.hide(); bottomNavBar.setVisibility(View.GONE); + recyclerView.scrollToPosition(postsList.size() - 1); } } }); 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 3c848c72..88c9694b 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 @@ -21,6 +21,7 @@ import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -136,6 +137,23 @@ class TopicAdapter extends RecyclerView.Adapter { View view = LayoutInflater.from(parent.getContext()). inflate(R.layout.activity_topic_quick_reply_row, parent, false); view.findViewById(R.id.quick_reply_submit).setEnabled(true); + + final EditText quickReplyText = (EditText) view.findViewById(R.id.quick_reply_text); + quickReplyText.setFocusableInTouchMode(true); + quickReplyText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + quickReplyText.post(new Runnable() { + @Override + public void run() { + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(quickReplyText, InputMethodManager.SHOW_IMPLICIT); + } + }); + } + }); + quickReplyText.requestFocus(); + //Default post subject replyDataHolder[replySubject] = "Re: " + topicTitle; //Build quotes diff --git a/app/src/main/res/drawable/ic_reply.xml b/app/src/main/res/drawable/ic_reply.xml new file mode 100644 index 00000000..1fc7f4f1 --- /dev/null +++ b/app/src/main/res/drawable/ic_reply.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index 1e1c5416..1334fe4e 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -123,7 +123,7 @@ android:layout_marginBottom="50dp" android:layout_marginEnd="@dimen/fab_margins" app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior" - app:srcCompat="@drawable/ic_add_fab"/> + app:srcCompat="@drawable/ic_reply"/> From fbe8b0032209ce7463e5347d9c0d93ac0374a690 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 15 Jul 2017 01:26:35 +0300 Subject: [PATCH 15/25] Fixes for post's date and index, unread posts tab in MainActivity, quote buttons in topics --- .../mthmmy/activities/main/MainActivity.java | 8 +++-- .../activities/main/unread/UnreadAdapter.java | 34 +++++++++++++++++++ .../main/unread/UnreadFragment.java | 10 ++++-- .../activities/topic/TopicActivity.java | 20 +++++++---- .../mthmmy/activities/topic/TopicAdapter.java | 8 +++-- .../layout-v21/activity_topic_post_row.xml | 6 ++-- .../res/layout/activity_topic_post_row.xml | 4 +-- .../layout/fragment_unread_mark_read_row.xml | 15 ++++++++ 8 files changed, 86 insertions(+), 19 deletions(-) create mode 100644 app/src/main/res/layout/fragment_unread_mark_read_row.xml diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java index c730b9df..b85ee294 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java @@ -36,7 +36,7 @@ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener, UnreadFragment.UnreadFragmentInteractionListener { - //----------------------------------------CLASS VARIABLES----------------------------------------- +//-----------------------------------------CLASS VARIABLES------------------------------------------ private static final int TIME_INTERVAL = 2000; private long mBackPressed; @@ -57,7 +57,6 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out); } - //Initialize drawer createDrawer(); @@ -117,7 +116,10 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF } @Override - public void onUnreadFragmentInteraction(TopicSummary topicSummary){ + public void onUnreadFragmentInteraction(TopicSummary topicSummary) { + if (topicSummary.getLastUser() == null && topicSummary.getDateTimeModified() == null) { + return; //TODO! + } Intent i = new Intent(MainActivity.this, TopicActivity.class); i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl()); i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getSubject()); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java index c6ae194d..2d415dd0 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java @@ -21,6 +21,7 @@ class UnreadAdapter extends RecyclerView.Adapter { private final int VIEW_TYPE_ITEM = 0; private final int VIEW_TYPE_NADA = 1; + private final int VIEW_TYPE_MARK_READ = 2; UnreadAdapter(Context context, @NonNull List topicSummaryList, BaseFragment.FragmentInteractionListener listener) { this.context = context; @@ -30,6 +31,7 @@ class UnreadAdapter extends RecyclerView.Adapter { @Override public int getItemViewType(int position) { + if (unreadList.get(position).getDateTimeModified() == null) return VIEW_TYPE_MARK_READ; return unreadList.get(position).getTopicUrl() == null ? VIEW_TYPE_NADA : VIEW_TYPE_ITEM; } @@ -43,6 +45,10 @@ class UnreadAdapter extends RecyclerView.Adapter { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.fragment_unread_empty_row, parent, false); return new EmptyViewHolder(view); + } else if (viewType == VIEW_TYPE_MARK_READ) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.fragment_unread_mark_read_row, parent, false); + return new MarkReadViewHolder(view); } return null; } @@ -74,6 +80,22 @@ class UnreadAdapter extends RecyclerView.Adapter { } }); + } else if (holder instanceof UnreadAdapter.MarkReadViewHolder) { + final UnreadAdapter.MarkReadViewHolder markReadViewHolder = (UnreadAdapter.MarkReadViewHolder) holder; + markReadViewHolder.text.setText(unreadList.get(position).getSubject()); + markReadViewHolder.topic = unreadList.get(position); + + markReadViewHolder.mView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (null != mListener) { + // Notify the active callbacks interface (the activity, if the + // fragment is attached to one) that an item has been selected. + mListener.onUnreadFragmentInteraction(markReadViewHolder.topic); + } + } + }); } } @@ -106,4 +128,16 @@ class UnreadAdapter extends RecyclerView.Adapter { text = (TextView) view.findViewById(R.id.text); } } + + private static class MarkReadViewHolder extends RecyclerView.ViewHolder { + final View mView; + final TextView text; + public TopicSummary topic; + + MarkReadViewHolder(View view) { + super(view); + mView = view; + text = (TextView) view.findViewById(R.id.mark_read); + } + } } 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 f5145c43..99954acd 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 @@ -158,16 +158,22 @@ public class UnreadFragment extends BaseFragment { String dateTime = lastUserAndDate.select("span").html(); //dateTime = dateTime.replace("
    ", ""); dateTime = dateTime.substring(0, dateTime.indexOf("
    ")); + dateTime = dateTime.replace("", ""); dateTime = dateTime.replace("", ""); topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); } + Element markRead = document.select("table:not(.bordercolor):not([width])").select("a") + .first(); + if (markRead != null) + topicSummaries.add(new TopicSummary(markRead.attr("href"), markRead.text(), null, + null)); } else { topicSummaries.clear(); String message = document.select("table.bordercolor[cellspacing=1]").first().text(); - if (message.contains("No messages")){ //It's english + if (message.contains("No messages")) { //It's english message = "No unread posts!"; - }else{ //It's greek + } else { //It's greek message = "Δεν υπάρχουν μη διαβασμένα μυνήματα!"; } topicSummaries.add(new TopicSummary(null, null, null, message)); 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 a10b7daf..ba559876 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 @@ -135,7 +135,7 @@ public class TopicActivity extends BaseActivity { ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory( Uri.parse(topicPageUrl)); if (!target.is(ThmmyPage.PageCategory.TOPIC)) { - Timber.e("Bundle came with a non topic url!\nUrl: %s" , topicPageUrl); + Timber.e("Bundle came with a non topic url!\nUrl: %s", topicPageUrl); Toast.makeText(this, "An error has occurred\n Aborting.", Toast.LENGTH_SHORT).show(); finish(); } @@ -551,8 +551,11 @@ public class TopicActivity extends BaseActivity { } progressBar.setVisibility(ProgressBar.INVISIBLE); - topicAdapter.customNotifyDataSetChanged(new TopicTask()); - if (replyPageUrl == null) replyFAB.hide(); + if (replyPageUrl == null) { + replyFAB.hide(); + topicAdapter.customNotifyDataSetChanged(new TopicTask(), false); + } else topicAdapter.customNotifyDataSetChanged(new TopicTask(), true); + if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(true); //Set current page @@ -566,7 +569,10 @@ public class TopicActivity extends BaseActivity { break; case SAME_PAGE: progressBar.setVisibility(ProgressBar.INVISIBLE); - topicAdapter.customNotifyDataSetChanged(new TopicTask()); + if (replyPageUrl == null) { + replyFAB.hide(); + topicAdapter.customNotifyDataSetChanged(new TopicTask(), false); + } else topicAdapter.customNotifyDataSetChanged(new TopicTask(), true); if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(true); paginationEnabled(true); Toast.makeText(TopicActivity.this, "That's the same page.", Toast.LENGTH_SHORT).show(); @@ -709,10 +715,10 @@ public class TopicActivity extends BaseActivity { sc = document.select("input[name=sc]").first().attr("value"); topic = document.select("input[name=topic]").first().attr("value"); } catch (IOException e) { - Timber.e(e,"Post failed."); + Timber.e(e, "Post failed."); return false; } catch (Selector.SelectorParseException e) { - Timber.e(e,"Post failed."); + Timber.e(e, "Post failed."); return false; } @@ -746,7 +752,7 @@ public class TopicActivity extends BaseActivity { return true; } } catch (IOException e) { - Timber.e(e,"Post failed."); + Timber.e(e, "Post failed."); return false; } } 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 88c9694b..4a5f5798 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 @@ -99,6 +99,7 @@ class TopicAdapter extends RecyclerView.Adapter { private final String[] replyDataHolder = new String[2]; private final int replySubject = 0, replyText = 1; private String loadedPageUrl = ""; + private boolean canReply = false; /** * @param context the context of the {@link RecyclerView} @@ -403,9 +404,9 @@ class TopicAdapter extends RecyclerView.Adapter { } //noinspection PointlessBooleanExpression,ConstantConditions - if (!BaseActivity.getSessionManager().isLoggedIn()) + if (!BaseActivity.getSessionManager().isLoggedIn() || !canReply) { holder.quoteToggle.setVisibility(View.GONE); - else { + } else { if (viewProperties.get(position)[isQuoteButtonChecked]) holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked); else @@ -469,8 +470,9 @@ class TopicAdapter extends RecyclerView.Adapter { } } - void customNotifyDataSetChanged(TopicActivity.TopicTask topicTask) { + void customNotifyDataSetChanged(TopicActivity.TopicTask topicTask, boolean canReply) { this.topicTask = topicTask; + this.canReply = canReply; viewProperties.clear(); for (int i = 0; i < postsList.size(); ++i) { //Initializes properties, array's values will be false by default diff --git a/app/src/main/res/layout-v21/activity_topic_post_row.xml b/app/src/main/res/layout-v21/activity_topic_post_row.xml index 64bd6610..2362427d 100644 --- a/app/src/main/res/layout-v21/activity_topic_post_row.xml +++ b/app/src/main/res/layout-v21/activity_topic_post_row.xml @@ -164,6 +164,8 @@ android:id="@+id/post_date_and_number_exp" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginLeft="16dp" + android:layout_marginRight="16dp" android:layout_marginTop="16dp"> + android:textSize="10sp" /> + android:textSize="10sp" /> diff --git a/app/src/main/res/layout/activity_topic_post_row.xml b/app/src/main/res/layout/activity_topic_post_row.xml index 696566e1..99eeefd6 100644 --- a/app/src/main/res/layout/activity_topic_post_row.xml +++ b/app/src/main/res/layout/activity_topic_post_row.xml @@ -174,7 +174,7 @@ android:gravity="start" android:text="" android:textColor="@color/card_expand_text_color" - android:textSize="8sp" /> + android:textSize="10sp" /> + android:textSize="10sp" /> diff --git a/app/src/main/res/layout/fragment_unread_mark_read_row.xml b/app/src/main/res/layout/fragment_unread_mark_read_row.xml new file mode 100644 index 00000000..ee3a4f49 --- /dev/null +++ b/app/src/main/res/layout/fragment_unread_mark_read_row.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file From 1284b7c64e3354a84dd5a7277b700b37f80dbb57 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 15 Jul 2017 15:43:02 +0300 Subject: [PATCH 16/25] Fixes for inconsistency detected bug --- .../activities/board/BoardActivity.java | 3 -- .../activities/topic/TopicActivity.java | 18 ++++++++- .../mthmmy/activities/topic/TopicAdapter.java | 6 ++- .../utils/CustomLinearLayoutManager.java | 38 +++++++++++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java 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 d25a2340..565b587a 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 @@ -303,8 +303,5 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo boardAdapter.notifyDataSetChanged(); isLoadingMore = false; } - - } - } 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 ba559876..8cb77d90 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 @@ -10,7 +10,6 @@ import android.os.Bundle; import android.os.Handler; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AlertDialog; -import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Html; @@ -49,6 +48,7 @@ import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.ThmmyPage; +import gr.thmmy.mthmmy.utils.CustomLinearLayoutManager; import gr.thmmy.mthmmy.utils.ParseHelpers; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import okhttp3.MultipartBody; @@ -168,7 +168,17 @@ public class TopicActivity extends BaseActivity { recyclerView = (RecyclerView) findViewById(R.id.topic_recycler_view); recyclerView.setHasFixedSize(true); - LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); + recyclerView.setOnTouchListener( + new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return topicTask != null && topicTask.getStatus() == AsyncTask.Status.RUNNING; + } + } + ); + //LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); + CustomLinearLayoutManager layoutManager = new CustomLinearLayoutManager( + getApplicationContext(), loadedPageUrl); recyclerView.setLayoutManager(layoutManager); topicAdapter = new TopicAdapter(this, postsList, topicTask); recyclerView.setAdapter(topicAdapter); @@ -551,6 +561,7 @@ public class TopicActivity extends BaseActivity { } progressBar.setVisibility(ProgressBar.INVISIBLE); + recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug if (replyPageUrl == null) { replyFAB.hide(); topicAdapter.customNotifyDataSetChanged(new TopicTask(), false); @@ -636,6 +647,9 @@ public class TopicActivity extends BaseActivity { } postsList.clear(); + int oldSize = postsList.size(); + topicAdapter.notifyItemRangeRemoved(0, oldSize); + recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug postsList.addAll(TopicParser.parseTopic(topic, language)); } 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 4a5f5798..b37ec5e4 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 @@ -172,7 +172,8 @@ class TopicAdapter extends RecyclerView.Adapter { @SuppressLint({"SetJavaScriptEnabled", "SetTextI18n"}) @Override - public void onBindViewHolder(final RecyclerView.ViewHolder currentHolder, final int position) { + public void onBindViewHolder(final RecyclerView.ViewHolder currentHolder, + final int position) { if (currentHolder instanceof PostViewHolder) { final Post currentPost = postsList.get(position); final PostViewHolder holder = (PostViewHolder) currentHolder; @@ -478,7 +479,8 @@ class TopicAdapter extends RecyclerView.Adapter { //Initializes properties, array's values will be false by default viewProperties.add(new boolean[3]); } - notifyDataSetChanged(); + notifyItemRangeInserted(0, postsList.size()); + //notifyDataSetChanged(); } @Override diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java b/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java new file mode 100644 index 00000000..cc03225c --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java @@ -0,0 +1,38 @@ +package gr.thmmy.mthmmy.utils; + +import android.content.Context; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; + +import timber.log.Timber; + +public class CustomLinearLayoutManager extends LinearLayoutManager { + private String pageUrl; + + public CustomLinearLayoutManager(Context context, String pageUrl) { + super(context); + this.pageUrl = pageUrl; + } + + @Override + public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { + try { + super.onLayoutChildren(recycler, state); + } catch (IndexOutOfBoundsException e) { + Timber.wtf(e, "Inconsistency detected: topic_requested = \"" + pageUrl + "\""); + Log.d("CustomLinearLayoutMan", "Inconsistency detected: topic_requested = \"" + + pageUrl + "\"", e); + } + } + + /** + * Disable predictive animations. There is a bug in RecyclerView which causes views that + * are being reloaded to pull invalid ViewHolders from the internal recycler stack if the + * adapter size has decreased since the ViewHolder was recycled. + */ + @Override + public boolean supportsPredictiveItemAnimations() { + return false; + } +} \ No newline at end of file From 7816c2d032ea7a1126817ad920ed7552ab643987 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 15 Jul 2017 16:34:08 +0300 Subject: [PATCH 17/25] Mark read functionality --- .../activities/main/unread/UnreadAdapter.java | 18 +++-- .../main/unread/UnreadFragment.java | 69 +++++++++++++++++-- 2 files changed, 74 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java index 2d415dd0..73adc1e4 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java @@ -18,15 +18,19 @@ class UnreadAdapter extends RecyclerView.Adapter { private final Context context; private final List unreadList; private final UnreadFragment.UnreadFragmentInteractionListener mListener; + private final MarkReadInteractionListener markReadListener; private final int VIEW_TYPE_ITEM = 0; private final int VIEW_TYPE_NADA = 1; private final int VIEW_TYPE_MARK_READ = 2; - UnreadAdapter(Context context, @NonNull List topicSummaryList, BaseFragment.FragmentInteractionListener listener) { + UnreadAdapter(Context context, @NonNull List topicSummaryList, + BaseFragment.FragmentInteractionListener listener, + MarkReadInteractionListener markReadInteractionListener) { this.context = context; this.unreadList = topicSummaryList; mListener = (UnreadFragment.UnreadFragmentInteractionListener) listener; + markReadListener = markReadInteractionListener; } @Override @@ -54,7 +58,7 @@ class UnreadAdapter extends RecyclerView.Adapter { } @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if (holder instanceof UnreadAdapter.EmptyViewHolder) { final UnreadAdapter.EmptyViewHolder emptyViewHolder = (UnreadAdapter.EmptyViewHolder) holder; emptyViewHolder.text.setText(unreadList.get(position).getDateTimeModified()); @@ -70,14 +74,11 @@ class UnreadAdapter extends RecyclerView.Adapter { viewHolder.mView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (null != mListener) { // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. mListener.onUnreadFragmentInteraction(viewHolder.topic); //? - } - } }); } else if (holder instanceof UnreadAdapter.MarkReadViewHolder) { @@ -88,11 +89,10 @@ class UnreadAdapter extends RecyclerView.Adapter { markReadViewHolder.mView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (null != mListener) { // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. - mListener.onUnreadFragmentInteraction(markReadViewHolder.topic); + markReadListener.onMarkReadInteraction(unreadList.get(position).getTopicUrl()); } } }); @@ -140,4 +140,8 @@ class UnreadAdapter extends RecyclerView.Adapter { text = (TextView) view.findViewById(R.id.mark_read); } } + + public interface MarkReadInteractionListener { + void onMarkReadInteraction(String markReadLinkUrl); + } } 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 99954acd..5427fc9e 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 @@ -5,17 +5,18 @@ import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.RelativeLayout; +import android.widget.Toast; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -27,6 +28,7 @@ import gr.thmmy.mthmmy.utils.CustomRecyclerView; import gr.thmmy.mthmmy.utils.ParseTask; import gr.thmmy.mthmmy.utils.exceptions.ParseException; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import okhttp3.Request; import timber.log.Timber; /** @@ -49,6 +51,7 @@ public class UnreadFragment extends BaseFragment { private List topicSummaries; private UnreadTask unreadTask; + private MarkReadTask markReadTask; // Required empty public constructor public UnreadFragment() { @@ -81,8 +84,8 @@ public class UnreadFragment extends BaseFragment { if (topicSummaries.isEmpty()) { unreadTask = new UnreadTask(); unreadTask.execute(SessionManager.unreadUrl.toString()); - } + markReadTask = new MarkReadTask(); Timber.d("onActivityCreated"); } @@ -96,7 +99,16 @@ public class UnreadFragment extends BaseFragment { // Set the adapter if (rootView instanceof RelativeLayout) { progressBar = (MaterialProgressBar) rootView.findViewById(R.id.progressBar); - unreadAdapter = new UnreadAdapter(getActivity(), topicSummaries, fragmentInteractionListener); + unreadAdapter = new UnreadAdapter(getActivity(), topicSummaries, + fragmentInteractionListener, new UnreadAdapter.MarkReadInteractionListener() { + @Override + public void onMarkReadInteraction(String markReadLinkUrl) { + if (markReadTask != null && markReadTask.getStatus() != AsyncTask.Status.RUNNING) { + markReadTask = new MarkReadTask(); + markReadTask.execute(markReadLinkUrl); + } + } + }); CustomRecyclerView recyclerView = (CustomRecyclerView) rootView.findViewById(R.id.list); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext()); @@ -129,9 +141,10 @@ public class UnreadFragment extends BaseFragment { super.onDestroy(); if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) unreadTask.cancel(true); + if (markReadTask != null && markReadTask.getStatus() != AsyncTask.Status.RUNNING) + markReadTask.cancel(true); } - public interface UnreadFragmentInteractionListener extends FragmentInteractionListener { void onUnreadFragmentInteraction(TopicSummary topicSummary); } @@ -147,7 +160,6 @@ public class UnreadFragment extends BaseFragment { Elements unread = document.select("table.bordercolor[cellspacing=1] tr:not(.titlebg)"); if (!unread.isEmpty()) { topicSummaries.clear(); - Log.d("UnreadFragment", unread.html()); for (Element row : unread) { Elements information = row.select("td"); String link = information.last().select("a").first().attr("href"); @@ -180,7 +192,6 @@ public class UnreadFragment extends BaseFragment { } } - @Override protected void postParsing(ParseTask.ResultCode result) { if (result == ResultCode.SUCCESS) @@ -189,6 +200,52 @@ public class UnreadFragment extends BaseFragment { progressBar.setVisibility(ProgressBar.INVISIBLE); swipeRefreshLayout.setRefreshing(false); } + } + private class MarkReadTask extends AsyncTask { + private static final int SUCCESS = 0; + private static final int NETWORK_ERROR = 1; + private static final int OTHER_ERROR = 2; + + @Override + protected void onPreExecute() { + progressBar.setVisibility(ProgressBar.VISIBLE); + } + + @Override + protected Integer doInBackground(String... strings) { + Request request = new Request.Builder() + .url(strings[0]) + .build(); + try { + client.newCall(request).execute(); + return SUCCESS; + } catch (IOException e) { + Timber.i(e, "IO Exception"); + return NETWORK_ERROR; + } catch (Exception e) { + Timber.e(e, "Exception"); + return OTHER_ERROR; + } + } + + @Override + protected void onPostExecute(Integer result) { + progressBar.setVisibility(ProgressBar.GONE); + + if (result == NETWORK_ERROR) { + Toast.makeText(getContext() + , "Task was unsuccessful!\n Please check your internet conneciton.", + Toast.LENGTH_LONG).show(); + } else if (result == OTHER_ERROR) { + Toast.makeText(getContext() + , "Fatal error!\n Task aborted...", Toast.LENGTH_LONG).show(); + } else { + if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) { + unreadTask = new UnreadTask(); + unreadTask.execute(SessionManager.unreadUrl.toString()); + } + } + } } } From 5d8e6aa65216d1229371a2740b529e57aa2e3992 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sun, 16 Jul 2017 11:18:12 +0300 Subject: [PATCH 18/25] Webview fix attempt and other tweaks --- .../main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java | 2 +- .../gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java | 2 +- .../java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java index b85ee294..bc6603a8 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java @@ -164,7 +164,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF public CharSequence getPageTitle(int position) { switch (position) { case 0: - return "RECENT POSTS"; + return "RECENT"; case 1: return "FORUM"; case 2: 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 5427fc9e..d1febe97 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 @@ -186,7 +186,7 @@ public class UnreadFragment extends BaseFragment { if (message.contains("No messages")) { //It's english message = "No unread posts!"; } else { //It's greek - message = "Δεν υπάρχουν μη διαβασμένα μυνήματα!"; + message = "Δεν υπάρχουν μη διαβασμένα μηνύματα!"; } topicSummaries.add(new TopicSummary(null, null, null, message)); } 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 b37ec5e4..ecc7a011 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 @@ -178,6 +178,8 @@ class TopicAdapter extends RecyclerView.Adapter { final Post currentPost = postsList.get(position); final PostViewHolder holder = (PostViewHolder) currentHolder; + holder.setIsRecyclable(false); + //Post's WebView parameters holder.post.setClickable(true); holder.post.setWebViewClient(new LinkLauncher()); From 8eaaf1c054e0072d62d6fc054d7a5b93b1b4bced Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sun, 16 Jul 2017 12:57:03 +0300 Subject: [PATCH 19/25] Make unread invisible for guests --- .../mthmmy/activities/main/MainActivity.java | 75 ++++++++++++------- .../gr/thmmy/mthmmy/base/BaseActivity.java | 10 +++ .../gr/thmmy/mthmmy/base/BaseApplication.java | 2 - .../gr/thmmy/mthmmy/base/BaseFragment.java | 29 +------ 4 files changed, 60 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java index bc6603a8..9e665182 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java @@ -10,6 +10,9 @@ import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.widget.Toast; +import java.util.ArrayList; +import java.util.List; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.board.BoardActivity; @@ -39,6 +42,8 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF //-----------------------------------------CLASS VARIABLES------------------------------------------ private static final int TIME_INTERVAL = 2000; private long mBackPressed; + private SectionsPagerAdapter sectionsPagerAdapter; + private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { @@ -48,7 +53,6 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF setContentView(R.layout.activity_main); if (sessionManager.isLoginScreenDefault()) - { //Go to login Intent intent = new Intent(MainActivity.this, LoginActivity.class); @@ -61,14 +65,21 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF createDrawer(); //Create the adapter that will return a fragment for each section of the activity - SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + sectionsPagerAdapter.addFragment(RecentFragment.newInstance(1), "RECENT"); + sectionsPagerAdapter.addFragment(ForumFragment.newInstance(2), "FORUM"); + if(sessionManager.isLoggedIn()) + sectionsPagerAdapter.addFragment(UnreadFragment.newInstance(3), "UNREAD"); + //Set up the ViewPager with the sections adapter. - ViewPager mViewPager = (ViewPager) findViewById(R.id.container); - mViewPager.setAdapter(mSectionsPagerAdapter); + viewPager = (ViewPager) findViewById(R.id.container); + viewPager.setAdapter(sectionsPagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); - tabLayout.setupWithViewPager(mViewPager); + tabLayout.setupWithViewPager(viewPager); + + setMainActivity(this); } @Override @@ -81,6 +92,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF @Override protected void onResume() { drawer.setSelection(HOME_ID); + updateTabs(); super.onResume(); } @@ -135,45 +147,56 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF * {@link android.support.v4.app.FragmentStatePagerAdapter}. */ private class SectionsPagerAdapter extends FragmentPagerAdapter { + private final List fragmentList = new ArrayList<>(); + private final List fragmentTitleList = new ArrayList<>(); SectionsPagerAdapter(FragmentManager fm) { super(fm); } + void addFragment(Fragment fragment, String title) { + fragmentList.add(fragment); + fragmentTitleList.add(title); + notifyDataSetChanged(); + } + + void removeFragment(int position) { + fragmentList.remove(position); + fragmentTitleList.remove(position); + notifyDataSetChanged(); + if(viewPager.getCurrentItem()==position) + viewPager.setCurrentItem(position-1); + } + @Override public Fragment getItem(int position) { - switch (position) { - case 0: - return RecentFragment.newInstance(position + 1); - case 1: - return ForumFragment.newInstance(position + 1); - case 2: - return UnreadFragment.newInstance(position + 1); - default: - return RecentFragment.newInstance(position + 1); //temp (?) - } + return fragmentList.get(position); } @Override public int getCount() { - // Show 3 total pages. - return 3; + return fragmentList.size(); } @Override public CharSequence getPageTitle(int position) { - switch (position) { - case 0: - return "RECENT"; - case 1: - return "FORUM"; - case 2: - return "UNREAD"; - } + return fragmentTitleList.get(position); + } - return null; + @Override + public int getItemPosition(Object object) { + int position = fragmentList.indexOf(object); + return position == -1 ? POSITION_NONE : position; } } + + public void updateTabs() + { + if(!sessionManager.isLoggedIn()&§ionsPagerAdapter.getCount()==3) + sectionsPagerAdapter.removeFragment(2); + else if(sessionManager.isLoggedIn()&§ionsPagerAdapter.getCount()==2) + sectionsPagerAdapter.addFragment(UnreadFragment.newInstance(3), "UNREAD"); + } //-------------------------------FragmentPagerAdapter END------------------------------------------- private void redirectToActivityFromIntent(Intent intent) { 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 a2c8877e..f43d603f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -75,6 +75,8 @@ public abstract class BaseActivity extends AppCompatActivity { protected Toolbar toolbar; protected Drawer drawer; + private MainActivity mainActivity; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -394,6 +396,8 @@ public abstract class BaseActivity extends AppCompatActivity { protected void onPostExecute(Integer result) { Toast.makeText(getBaseContext(), "Logged out successfully!", Toast.LENGTH_LONG).show(); updateDrawer(); + if(mainActivity!=null) + mainActivity.updateTabs(); progressDialog.dismiss(); } } @@ -563,4 +567,10 @@ public abstract class BaseActivity extends AppCompatActivity { } + //----------------------------------MISC---------------------- + protected void setMainActivity(MainActivity mainActivity) + { + this.mainActivity = mainActivity; + } + } 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 3030cce0..24c84558 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java @@ -35,8 +35,6 @@ import okhttp3.Response; import timber.log.Timber; public class BaseApplication extends Application { - - private static BaseApplication baseApplication; //BaseApplication singleton // Client & SessionManager diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java index 20bd8da2..0f3487d9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java @@ -6,7 +6,6 @@ import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import okhttp3.OkHttpClient; -import timber.log.Timber; public abstract class BaseFragment extends Fragment { protected static final String ARG_SECTION_NUMBER = "SectionNumber"; @@ -26,31 +25,6 @@ public abstract class BaseFragment extends Fragment { if (client == null) client = BaseApplication.getInstance().getClient(); //must check every time - e.g. // becomes null when app restarts after crash - Timber.d("onCreate"); - } - - @Override - public void onStart() { - super.onStart(); - Timber.d("onStart"); - } - - @Override - public void onResume() { - super.onResume(); - Timber.d("onResume"); - } - - @Override - public void onPause() { - super.onPause(); - Timber.d("onPause"); - } - - @Override - public void onStop() { - super.onStop(); - Timber.d("onStop"); } @Override @@ -76,6 +50,5 @@ public abstract class BaseFragment extends Fragment { * the activity that contains it, to allow communication upon interaction, * between the fragment and the activity/ other fragments */ - public interface FragmentInteractionListener { - } + public interface FragmentInteractionListener {} } From cb0b6e1540f3eb9e4c76e3122de1603f2ee6fb90 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 20 Jul 2017 22:18:32 +0300 Subject: [PATCH 20/25] Layout fixes (mostly for tablets), rolled back recyclable --- .../mthmmy/activities/topic/TopicAdapter.java | 2 -- .../main/res/layout-sw600dp/activity_main.xml | 34 +++++++++++++++++++ app/src/main/res/layout/activity_about.xml | 2 +- app/src/main/res/layout/activity_bookmark.xml | 4 +-- .../main/res/layout/activity_downloads.xml | 2 +- app/src/main/res/layout/activity_topic.xml | 5 +-- app/src/main/res/menu/topic_menu.xml | 2 +- 7 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 app/src/main/res/layout-sw600dp/activity_main.xml 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 ecc7a011..b37ec5e4 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 @@ -178,8 +178,6 @@ class TopicAdapter extends RecyclerView.Adapter { final Post currentPost = postsList.get(position); final PostViewHolder holder = (PostViewHolder) currentHolder; - holder.setIsRecyclable(false); - //Post's WebView parameters holder.post.setClickable(true); holder.post.setWebViewClient(new LinkLauncher()); diff --git a/app/src/main/res/layout-sw600dp/activity_main.xml b/app/src/main/res/layout-sw600dp/activity_main.xml new file mode 100644 index 00000000..62b3d010 --- /dev/null +++ b/app/src/main/res/layout-sw600dp/activity_main.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 2e724601..797665a2 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -30,7 +30,7 @@ android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="64dp" + app:layout_behavior="@string/appbar_scrolling_view_behavior" android:background="@color/background"> + android:scrollbars="none" + app:layout_behavior="@string/appbar_scrolling_view_behavior">
    diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index 1334fe4e..27f9b6b1 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -37,12 +37,13 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top|start" - android:layout_marginTop="64dp" android:background="@color/background" + android:paddingTop="4dp" android:paddingBottom="54dp" android:clipToPadding="false" android:scrollbars="none" - tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity"> + tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> \ No newline at end of file From e3d7eaa6b0ffcc3be5ef8fc713dc66424749e415 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 20 Jul 2017 22:37:40 +0300 Subject: [PATCH 21/25] Doc updates --- CONTRIBUTING.md | 16 +++++++--------- README.md | 8 ++++++++ doc/forum_post.txt | 35 ----------------------------------- 3 files changed, 15 insertions(+), 44 deletions(-) delete mode 100644 doc/forum_post.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 44be1c74..6f5733a4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,35 +13,33 @@ vulnerabilities, please report them in private to There are many ways of contributing to mTHMMY: -- Simply using the latest release version (anonymous reports are sent automatically) -- Becoming an alpha or beta tester +- Simply using the [latest release version][google-play] from Google Play (anonymous reports are sent automatically) - Joining our [Discord server][discord-server] -- Submiting bugs and ideas on our [Trello board][trello-board] -- Getting code access to fork mTHMMY and submit [merge requests](#merge-requests) +- Submitting bugs and ideas on our [Trello board][trello-board] +- Forking mTHMMY and submitting [merge requests](#merge-requests) - Joining our core team - Contacting us by email at `thmmynolife@gmail.com` ## Issue tracker The [mTHMMY Board on trello.com][trello-board] is used as an Issue Tracker, for bugs and improvements concerning the available mTHMMY releases. -Before creating a card to submit an issue please **[search the board][trello-board]** for similar entries. +Before creating a card to submit an issue please **search the board** for similar entries. ## Merge requests Merge requests with fixes and improvements to mTHMMY are most welcome. Any developer that wants to work independently from the core team can simply follow the workflow below to make a merge request: -1. Request and get access to the repository 1. Fork the project into your personal space on GitLab.com -1. Create a feature branch, branch away from `develop` +1. Create a feature branch, away from `develop` 1. Push the commit(s) to your fork 1. Create a merge request (MR) targeting `develop` [at mTHMMY](https://gitlab.com/ThmmyNoLife/mTHMMY/tree/develop) 1. Fill the MR title describing the change you want to make -1. Fill the MR description with a brief motive for your change and the method you used to achieve it. +1. Fill the MR description with a brief motive for your change and the method you used to achieve it 1. Submit the MR. - +[google-play]: https://play.google.com/store/apps/details?id=gr.thmmy.mthmmy [trello-board]: https://trello.com/invite/b/4MVlkrkg/44a931707bd0b84a5e0bdfc42b9ae4f1/mthmmy [discord-server]: https://discord.gg/CVt3yrn diff --git a/README.md b/README.md index 89f8a134..f27cc28a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ mTHMMY is a mobile app for the [thmmy.gr](https://www.thmmy.gr) community. mTHMMY can be installed on any smartphone with Android 4.4 KitKat or newer. +## Download + +The latest release version is available on Google Play: + +Get it on Google Play + ## Contributing Please refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for details. @@ -20,5 +26,7 @@ Please refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for details. Do not hesitate to contact us for any matter, either by sending an email to `thmmynolife@gmail.com`, or by joining our [Discord server][discord-server]. +**Legal attribution: Google Play and the Google Play logo are trademarks of Google Inc.* + [discord-server]: https://discord.gg/CVt3yrn [trello-board]: https://trello.com/invite/b/4MVlkrkg/44a931707bd0b84a5e0bdfc42b9ae4f1/mthmmy diff --git a/doc/forum_post.txt b/doc/forum_post.txt deleted file mode 100644 index 1957af12..00000000 --- a/doc/forum_post.txt +++ /dev/null @@ -1,35 +0,0 @@ -[center][size=25pt][b]Introduction[/b][/size][/center] - -Από τη συζήτηση [url=https://www.thmmy.gr/smf/index.php?topic=67629.0]εδώ[/url], ξεκίνησε ένα project με στόχο τη δημιουργία εφαρμογής για Android κινητά που θα συγκεντρώνει και θα κάνει πιο εύκολη τη πρόσβαση σε μερικές από τις βασικές σελίδες και υπηρεσίες που αφορούν τη σχολή και χρησιμοποιούμε καθημερινά. - -Μετά από 2+ μήνες δουλειάς και πάνω από 9000 γραμμές κώδικα (.java, .xml και άλλα), σήμερα (16/1/2017) ανεβάσαμε για πρώτη φορά την εφαρμογή (σε closed alpha phase) στο Google Play Store! - -Προς το παρόν η εφαρμογή υποστηρίζει κάποιες από τις βασικές λειτουργίες του forum. Σταδιακά θα ενσωματώνονται όλο και περισσότερες λειτουργίες, για παράδειγμα ενός συστήματος ειδοποιήσεων για νέες ανακοινώσεις του ethmmy και της σελίδας της γραμματείας, instant chat κ.ά., ανάλογα πάντα με τις ιδέες, τη διάθεση και την ενέργεια όσων θα συμμετέχουν. - -Αυτή τη στιγμή με το project ασχολούμαστε εγώ και ο L, ενώ έχουν βοηθήσει ο iason1907 και ο [url=https://www.thmmy.gr/smf/index.php?topic=67565.msg1163192#msg1163192]nohponex[/url]. - -[hr] -[center][size=25pt][b]Κάλεσμα για contributors[/b][/size] - -[img height=200]https://tctechcrunch2011.files.wordpress.com/2015/04/uncle-sam-we-want-you1-kopie_1.png[/img][/center] - -Αν ενδιαφέρεσαι κι [b]ΕΣΥ[/b] να ασχοληθείς με το project μπορείς να το κάνεις με πολλούς τρόπους: -[list] - -[li] -Να αναφέρεις bugs, να προτείνεις βελτιώσεις και να συμμετέχεις σε συζητήσεις στον [url=https://discord.gg/PVRVjth]Discord server[/url] μας και στον Issue Tracker στο [url=trello.com]Trello[/url] (το link του είναι pinned στο #feedback στο Discord). -[/li] -[li] -Να κατεβάσεις και να δοκιμάσεις την alpha έκδοση της εφαρμογής από [url=https://play.google.com/apps/testing/gr.thmmy.mthmmy]εδώ[/url], [b]αφού [/b]πρώτα μας στείλεις το Gmail που έχεις στο Google Play για να αποκτήσεις πρόσβαση. -[/li] -[li] -Να έρθεις σε άμεση επικοινωνία με την ομάδα μέσω του [url=https://discord.gg/PVRVjth]Discord[/url] ή στέλνοντας email στο thmmynolife@gmail.com. -[/li] -[li]Αν ξέρεις προγραμματισμό μπορείς αρχικά να ζητήσεις πρόσβαση στο repository και να συνεισφέρεις κώδικα με fork και merge requests στους ρυθμούς σου. Χρειάζονται [i]άμεσα[/i] νέοι developers για υλοποιήση καινούργιων χαρακτηριστικών, διόρθωση εντόμων, σύνταξη των javadocs και του documentation γενικότερα, white-box testing, υλοποίηση του backend στο server που στήθηκε πρόσφατα και πολλών άλλων. -[/li][/list] -[hr] -[center][size=25pt][b]Η εφαρμογή[/b][/size][/center] - -[center][url=https://s6.postimg.org/v9mseb7n5/image.png][img width=200]https://s6.postimg.org/v9mseb7n5/image.png[/img][/url] [url=https://s6.postimg.org/3nk0tmoa9/image2.png][img width=200]https://s6.postimg.org/3nk0tmoa9/image2.png[/img][/url] [url=https://s6.postimg.org/i813ogj8x/image3.png][img width=200]https://s6.postimg.org/i813ogj8x/image3.png[/img][/url] [url=https://s6.postimg.org/4to0sfckx/image4.png][img width=200]https://s6.postimg.org/4to0sfckx/image4.png[/img][/url] [url=https://s6.postimg.org/69zjakfht/image5.png][img width=200]https://s6.postimg.org/69zjakfht/image5.png[/img][/url] [url=https://s6.postimg.org/rkx3etxm9/image6.png][img width=200]https://s6.postimg.org/rkx3etxm9/image6.png[/img][/url][/center] - -Αυτή τη στιγμή στην εφαρμογή μπορείς να κάνεις login και logout, να δεις τα "Πρόσφατα", να περιηγηθείς στα boards, topics και user profiles, να κατεβάσεις αρχεία από τα downloads και από συνημμένα σε post. \ No newline at end of file From c79b1204f43d8ae914bb4ef59305d4e9c388f060 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 22 Jul 2017 15:19:20 +0300 Subject: [PATCH 22/25] Bookmarks refresh on activity resume, fixed quote, embedded video overlay image and recyclerView bugs. Made activities SingeInstance. --- app/src/main/AndroidManifest.xml | 57 +++++---- .../main/assets/YouTube_light_color_icon.png | Bin 0 -> 13195 bytes .../activities/board/BoardActivity.java | 8 ++ .../mthmmy/activities/topic/Posting.java | 121 +++++++++++++----- .../activities/topic/TopicActivity.java | 4 +- .../mthmmy/activities/topic/TopicAdapter.java | 1 + .../gr/thmmy/mthmmy/base/BaseActivity.java | 30 ++++- .../gr/thmmy/mthmmy/utils/ParseHelpers.java | 2 +- 8 files changed, 156 insertions(+), 67 deletions(-) create mode 100644 app/src/main/assets/YouTube_light_color_icon.png diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8a57fcbc..8e78f4e6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,12 +1,12 @@ + package="gr.thmmy.mthmmy" + android:installLocation="auto"> - - - - + + + + - + - + - + - - + + + android:scheme="http" /> + android:scheme="http" /> + android:scheme="https" /> + android:scheme="https" /> - + + android:windowSoftInputMode="adjustPan" /> + android:value=".activities.main.MainActivity" /> + android:value=".activities.main.MainActivity" /> + android:theme="@style/AppTheme.NoActionBar" /> + android:value=".activities.main.MainActivity" /> + android:value=".activities.main.MainActivity" /> + android:value=".activities.main.MainActivity" /> + android:resource="@xml/provider_paths" /> + android:exported="false" /> - - + + diff --git a/app/src/main/assets/YouTube_light_color_icon.png b/app/src/main/assets/YouTube_light_color_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bfd6db39af520e36914c67a9bb9d0b151f3178cd GIT binary patch literal 13195 zcmaKTc_7r?7x$fE2uTYm6i*9E;t`Q`S|lxKkwWMxDJpB(%{P)K6+&8U(}Fg%35A)c zY!xMG5o60z*<~>1`<^?g-}C%_@B8+Tx%ZxX?pZ$P+;i{!cGAkiOj2A<93doWzHZGH zgoNQI_4OnX`136L^)mP~+sAZ=&sO(+KEAuXoYBg??teKenIGEi;=ILq_g;U`a%V$? zmZ_VsS-H*cF6y

    l2P! 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 literal 0 HcmV?d00001 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 565b587a..633ab6ec 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 @@ -8,6 +8,7 @@ import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.ProgressBar; @@ -161,6 +162,13 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } } + @Override + public void onResume() { + super.onResume(); + Log.d("Boardaa", "onResume called!"); + refreshBoardBookmark((ImageButton) findViewById(R.id.bookmark)); + } + @Override public void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java index f0220f82..3fe99911 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java @@ -1,5 +1,7 @@ package gr.thmmy.mthmmy.activities.topic; +import android.util.Log; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -11,11 +13,52 @@ import java.util.regex.Matcher; import okhttp3.Response; import timber.log.Timber; +/** + * This is a utility class containing a collection of static methods to help with topic replying. + */ class Posting { + /** + * {@link REPLY_STATUS} enum defines the different possible outcomes of a topic reply request. + */ enum REPLY_STATUS { - SUCCESSFUL, NO_SUBJECT, EMPTY_BODY, NEW_REPLY_WHILE_POSTING, NOT_FOUND, SESSION_ENDED, OTHER_ERROR + /** + * The request was successful + */ + SUCCESSFUL, + /** + * Request was lacking a subject + */ + NO_SUBJECT, + /** + * Request had empty body + */ + EMPTY_BODY, + /** + * There were new topic replies while making the request + */ + NEW_REPLY_WHILE_POSTING, + /** + * Error 404, page was not found + */ + NOT_FOUND, + /** + * User session ended while posting the reply + */ + SESSION_ENDED, + /** + * Other undefined of unidentified error + */ + OTHER_ERROR } + /** + * This method can be used to check whether a topic post request was successful or not and if + * not maybe get the reason why. + * + * @param response {@link okhttp3.Response} of the request + * @return a {@link REPLY_STATUS} that describes the response status + * @throws IOException method relies to {@link org.jsoup.Jsoup#parse(String)} + */ static REPLY_STATUS replyStatus(Response response) throws IOException { if (response.code() == 404) return REPLY_STATUS.NOT_FOUND; if (response.code() < 200 || response.code() >= 400) return REPLY_STATUS.OTHER_ERROR; @@ -44,10 +87,19 @@ class Posting { return REPLY_STATUS.SUCCESSFUL; } + /** + * This is a fucked up method.. Just don't waste your time here unless you have suicidal + * tendencies. + * + * @param html the html string to be transformed to BBcode + * @return the BBcode string + */ static String htmlToBBcode(String html) { + Log.d("Cancer", html); Map bbMap = new HashMap<>(); Map smileysMap1 = new HashMap<>(); Map smileysMap2 = new HashMap<>(); + smileysMap1.put("Smiley", ":)"); smileysMap1.put("Wink", ";)"); smileysMap1.put("Cheesy", ":D"); @@ -170,64 +222,66 @@ class Posting { //html stuff on the beginning bbMap.put("\n ", ""); //quotes and code headers - bbMap.put("\n\\s+?

    \n (.+?)\n
    ", ""); - bbMap.put("\n\\s+?
    \n (.+?)\n
    ", ""); - bbMap.put("\n\\s+?
    \n (.+?)\n
    ", ""); - bbMap.put("
    ", "\n"); + bbMap.put("\\s*?
    (.*?(\\n))*?.*?<\\/div>", ""); + bbMap.put("\\s*?
    (.*?(\\n))+?.*?<\\/div>", ""); + bbMap.put("\\s*?
    (.*?(\\n))+?.*?<\\/div>", ""); + bbMap.put("
    ", "\\\n"); + //Non-breaking space + bbMap.put(" ", " "); //bold - bbMap.put("\n\\s+?(.+?)", "\\[b\\]$1\\[/b\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/b>", "\\[b\\]$1\\[/b\\]"); //italics - bbMap.put("\n\\s+?(.+?)", "\\[i\\]$1\\[/i\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/i>", "\\[i\\]$1\\[/i\\]"); //underline - bbMap.put("\n\\s+?(.+?)", "\\[u\\]$1\\[/u\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[u\\]$1\\[/u\\]"); //deleted - bbMap.put("\n\\s+?(.+?)", "\\[s\\]$1\\[/s\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/del>", "\\[s\\]$1\\[/s\\]"); //text color - bbMap.put("\n\\s+?(.+?)", "\\[color=$1\\]$2\\[/color\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[color=$1\\]$2\\[/color\\]"); //glow - bbMap.put("\n\\s+?(.+?)", "\\[glow=$1,2,300\\]$2\\[/glow\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[glow=$1,2,300\\]$2\\[/glow\\]"); //shadow - bbMap.put("\n\\s+?(.+?)", "\\[shadow=$1,$2\\]$3\\[/shadow\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[shadow=$1,$2\\]$3\\[/shadow\\]"); //running text - bbMap.put("\\s+?\n (.+?)\n ", "\\[move\\]$1\\[/move\\]"); + bbMap.put("\\s*?\n ([\\S\\s]+?)\n <\\/marquee>", "\\[move\\]$1\\[/move\\]"); //alignment - bbMap.put("\n\\s+?
    \n (.+?)\n
    ", "\\[center\\]$1\\[/center\\]"); - bbMap.put("\n\\s+?
    \n (.+?)\n
    ", "\\[$1\\]$2\\[/$1\\]"); + bbMap.put("\\s*?
    \n ([\\S\\s]+?)\n <\\/div>", "\\[center\\]$1\\[/center\\]"); + bbMap.put("\\s*?
    \n ([\\S\\s]+?)\n <\\/div>", "\\[$1\\]$2\\[/$1\\]"); //preformated - bbMap.put("\n\\s+?
    (.+?)
    ", "\\[pre\\]$1\\[/pre\\]"); + bbMap.put("\\s*?
    ([\\S\\s]+?)<\\/pre>", "\\[pre\\]$1\\[/pre\\]");
             //horizontal rule
    -        bbMap.put("\n\\s+?
    ", "\\[hr\\]"); + bbMap.put("\\s*?
    ", "\\[hr\\]"); //resize - bbMap.put("\n\\s+?(.+?)", "\\[size=$1\\]$3\\[/size\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[size=$1\\]$3\\[/size\\]"); //font - bbMap.put("\n\\s+?(.+?)", "\\[font=$1\\]$2\\[/font\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[font=$1\\]$2\\[/font\\]"); //lists - bbMap.put("\\s+
  • (.+?)
  • ", "\\[li\\]$1\\[/li\\]"); - bbMap.put("\n\\s+
      ([\\S\\s]+?)\n\\s+
    ", + bbMap.put("\\s+
  • (.+?)<\\/li>", "\\[li\\]$1\\[/li\\]"); + bbMap.put("\n\\s+
      ([\\S\\s]+?)\n\\s+<\\/ul>", "\\[list\\]\n$1\n\\[/list\\]"); //latex code - bbMap.put("\n\\s+?", "\\[tex\\]$1\\[/tex\\]"); + bbMap.put("\\s*?", "\\[tex\\]$1\\[/tex\\]"); //code - bbMap.put("\n\\s+?
      \n (.+?)\n
      ", "\\[code\\]$1\\[/code\\]"); + bbMap.put("\\s*?
      ((.*?(\\n))+?.*?)<\\/div>", "\\[code\\]$1\\[/code\\]"); //teletype - bbMap.put("\n\\s+?(.+?)", "\\[tt\\]$1\\[/tt\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/tt>", "\\[tt\\]$1\\[/tt\\]"); //superscript/subscript - bbMap.put("\n\\s+?(.+?)", "\\[sub\\]$1\\[/sub\\]"); - bbMap.put("\n\\s+?(.+?)", "\\[sup\\]$1\\[/sup\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/sub>", "\\[sub\\]$1\\[/sub\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/sup>", "\\[sup\\]$1\\[/sup\\]"); //tables - bbMap.put("\\s+?([\\S\\s]+?)", "\\[td\\]$1\\[/td\\]"); - bbMap.put("([\\S\\s]+?)\n ", "\\[tr\\]$1\\[/tr\\]"); - bbMap.put("\n\\s+?\n \n ([\\S\\s]+?)\n \n
      " + bbMap.put("\\s*?([\\S\\s]+?)<\\/td>", "\\[td\\]$1\\[/td\\]"); + bbMap.put("([\\S\\s]+?)\n <\\/tr>", "\\[tr\\]$1\\[/tr\\]"); + bbMap.put("\\s*?\n \n ([\\S\\s]+?)\n <\\/tbody>\n <\\/table>" , "\\[table\\]$2\\[/table\\]"); //videos - bbMap.put("\n\\s+?
      \n", + bbMap.put("\\s*?
      .+?watch\\?v=(.+?)\"((.|\\n)*?)/div>\n", "[youtube]https://www.youtube.com/watch?v=$1[/youtube]"); //ftp - bbMap.put("([\\S\\s]+?)", "\\[fpt=ftp:$1\\]$2\\[/ftp\\]"); + bbMap.put("([\\S\\s]+?)<\\/a>", "\\[fpt=ftp:$1\\]$2\\[/ftp\\]"); //mailto - bbMap.put("\n\\s+?([\\S\\s]+?)", "\\[email\\]$2\\[/email\\]"); + bbMap.put("\\s*?([\\S\\s]+?)<\\/a>", "\\[email\\]$2\\[/email\\]"); //links - bbMap.put("\n\\s+?([\\S\\s]+?)", "\\[url=$1\\]$2\\[/url\\]"); + bbMap.put("\\s*?([\\S\\s]+?)", "\\[url=$1\\]$2\\[/url\\]"); //smileys for (Map.Entry entry : smileysMap1.entrySet()) { bbMap.put("\n \""", "\\[img height=$2\\]$1\\[/img\\]"); html = html.replaceAll("\\s+", "\\[img\\]$1\\[/img\\]"); + Log.d("Cancer", html); return html; } } 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 8cb77d90..5c170204 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 @@ -226,6 +226,7 @@ public class TopicActivity extends BaseActivity { // Inflates the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.topic_menu, menu); setTopicBookmark(menu.getItem(0)); + super.onCreateOptionsMenu(menu); return true; } @@ -269,8 +270,9 @@ public class TopicActivity extends BaseActivity { @Override protected void onResume() { - drawer.setSelection(-1); super.onResume(); + refreshTopicBookmark(); + drawer.setSelection(-1); } @Override 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 b37ec5e4..aa17b311 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 @@ -181,6 +181,7 @@ class TopicAdapter extends RecyclerView.Adapter { //Post's WebView parameters holder.post.setClickable(true); holder.post.setWebViewClient(new LinkLauncher()); + holder.post.setLayerType(View.LAYER_TYPE_SOFTWARE, null); //Avoids errors about layout having 0 width/height holder.thumbnail.setMinimumWidth(1); 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 f43d603f..f844573d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -337,7 +337,7 @@ public abstract class BaseActivity extends AppCompatActivity { drawer = drawerBuilder.build(); - if(!(BaseActivity.this instanceof MainActivity)) + if (!(BaseActivity.this instanceof MainActivity)) drawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false); drawer.setOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() { @@ -396,7 +396,7 @@ public abstract class BaseActivity extends AppCompatActivity { protected void onPostExecute(Integer result) { Toast.makeText(getBaseContext(), "Logged out successfully!", Toast.LENGTH_LONG).show(); updateDrawer(); - if(mainActivity!=null) + if (mainActivity != null) mainActivity.updateTabs(); progressDialog.dismiss(); } @@ -422,6 +422,18 @@ public abstract class BaseActivity extends AppCompatActivity { } } + protected void refreshTopicBookmark() { + if (thisPageBookmarkMenuButton == null) { + return; + } + loadSavedBookmarks(); + if (thisPageBookmark.matchExists(topicsBookmarked)) { + thisPageBookmarkMenuButton.setIcon(bookmarked); + } else { + thisPageBookmarkMenuButton.setIcon(notBookmarked); + } + } + protected void topicMenuBookmarkClick() { if (thisPageBookmark.matchExists(topicsBookmarked)) { thisPageBookmarkMenuButton.setIcon(notBookmarked); @@ -455,6 +467,17 @@ public abstract class BaseActivity extends AppCompatActivity { }); } + protected void refreshBoardBookmark(final ImageButton thisPageBookmarkImageButton) { + if (thisPageBookmarkImageButton == null) + return; + loadSavedBookmarks(); + if (thisPageBookmark.matchExists(boardsBookmarked)) { + thisPageBookmarkImageButton.setImageDrawable(bookmarked); + } else { + thisPageBookmarkImageButton.setImageDrawable(notBookmarked); + } + } + private void loadSavedBookmarks() { String tmpString = bookmarksFile.getString(BOOKMARKED_TOPICS_KEY, null); if (tmpString != null) @@ -568,8 +591,7 @@ public abstract class BaseActivity extends AppCompatActivity { } //----------------------------------MISC---------------------- - protected void setMainActivity(MainActivity mainActivity) - { + protected void setMainActivity(MainActivity mainActivity) { this.mainActivity = mainActivity; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java index 75a9fa72..a2e80cca 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java @@ -156,7 +156,7 @@ public class ParseHelpers { + "" + "" + + "src=\"YouTube_light_color_icon.png\">" + "" + " Date: Sat, 22 Jul 2017 17:47:21 +0300 Subject: [PATCH 23/25] Changed page NavBar and ReplyFab behaviors, removed topic's bottom padding. --- .../java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java | 3 +-- .../java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java | 3 +-- app/src/main/res/layout/activity_topic.xml | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java index 58ba1a62..f49fe28d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java @@ -41,8 +41,7 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior 40)) && child.getVisibility() != View.VISIBLE) { + } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { child.show(); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java index 0f3564c6..834cbe34 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java @@ -35,8 +35,7 @@ public class ScrollAwareLinearBehavior extends CoordinatorLayout.Behavior if ((dyConsumed > 0 || (!target.canScrollVertically(-1) && dyConsumed == 0 && dyUnconsumed < 40)) && bottomNavBar.getVisibility() == View.VISIBLE) { hide(bottomNavBar); - } else if ((dyConsumed < 0 || (!target.canScrollVertically(1) && dyConsumed == 0 - && dyUnconsumed > 40)) && bottomNavBar.getVisibility() != View.VISIBLE) { + } else if (dyConsumed < 0 && bottomNavBar.getVisibility() != View.VISIBLE) { show(bottomNavBar); } } diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index 27f9b6b1..e726d372 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -39,7 +39,6 @@ android:layout_gravity="top|start" android:background="@color/background" android:paddingTop="4dp" - android:paddingBottom="54dp" android:clipToPadding="false" android:scrollbars="none" tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity" From 417b53a396cf773a78a1f95e90056ba7e7d5f155 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Mon, 24 Jul 2017 18:02:07 +0300 Subject: [PATCH 24/25] Unread tab minor fix --- app/src/main/res/layout/fragment_unread_mark_read_row.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_unread_mark_read_row.xml b/app/src/main/res/layout/fragment_unread_mark_read_row.xml index ee3a4f49..ffc6e8e8 100644 --- a/app/src/main/res/layout/fragment_unread_mark_read_row.xml +++ b/app/src/main/res/layout/fragment_unread_mark_read_row.xml @@ -1,7 +1,7 @@ @@ -9,7 +9,7 @@ \ No newline at end of file From c47eaaf8d5e2cea69ef0005c089c6a51ea187ebc Mon Sep 17 00:00:00 2001 From: Ezerous Date: Mon, 24 Jul 2017 18:21:41 +0300 Subject: [PATCH 25/25] Up version --- VERSION | 2 +- app/build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 6085e946..f0bb29e7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.1 +1.3.0 diff --git a/app/build.gradle b/app/build.gradle index 06bf2efb..cc50d899 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "gr.thmmy.mthmmy" minSdkVersion 19 targetSdkVersion 25 - versionCode 7 - versionName "1.2.1" + versionCode 8 + versionName "1.3.0" archivesBaseName = "mTHMMY-v$versionName" }