From bcdbc22607b2df3431be7bb46c4284263e896887 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Wed, 18 Jan 2017 19:13:49 +0200 Subject: [PATCH 01/26] Tiny library/version/sdk updates, added doc/forum_post --- .gitlab-ci.yml | 2 +- VERSION | 2 +- app/build.gradle | 2 +- doc/forum_post.txt | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 doc/forum_post.txt diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9a7ce1df..d02a2bf6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,7 +3,7 @@ image: openjdk:8-jdk variables: ANDROID_TARGET_SDK: "25" ANDROID_BUILD_TOOLS: "25.0.1" - ANDROID_SDK_TOOLS: "25.2.4" + ANDROID_SDK_TOOLS: "25.2.5" before_script: - apt-get --quiet update --yes diff --git a/VERSION b/VERSION index 3eefcb9d..7dea76ed 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 +1.0.1 diff --git a/app/build.gradle b/app/build.gradle index aab5c5d6..f09859fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,7 +37,7 @@ dependencies { compile 'com.squareup.okhttp3:okhttp:3.5.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.1' + 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.1@aar') { diff --git a/doc/forum_post.txt b/doc/forum_post.txt new file mode 100644 index 00000000..f51905fa --- /dev/null +++ b/doc/forum_post.txt @@ -0,0 +1,34 @@ +[center][size=25pt][b]Introduction[/b][/size][/center] + +Από τη συζήτηση [url=https://www.thmmy.gr/smf/index.php?topic=67629.0]εδώ[/url], ξεκίνησε ένα project με στόχο τη δημιουργία εφαρμογής για Android κινητά που θα συγκεντρώνει και θα κάνει πιο εύκολη τη πρόσβαση σε μερικές από τις βασικές σελίδες και υπηρεσίες που αφορούν τη σχολή και χρησιμοποιούμε καθημερινά. + +Μετά από 2+ μήνες δουλειάς και πάνω από 9000 γραμμές κώδικα [size=9pt](.java, .xml και άλλα)[/size], σήμερα ανεβάσαμε για πρώτη φορά την εφαρμογή (σε 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=400]https://tctechcrunch2011.files.wordpress.com/2015/04/uncle-sam-we-want-you1-kopie_1.png[/img][/center] + +Αν ενδιαφέρεσαι κι ΕΣΥ να ασχοληθείς με το project μπορείς να το κάνεις με πολλούς τρόπους: +[list] +[li]Αν ξέρεις προγραμματισμό μπορείς αρχικά να ζητήσεις πρόσβαση στο repository. Χρειάζονται [i]άμεσα[/i] νέοι developers για υλοποιήση καινούργιων χαρακτηριστικών, διόρθωση εντόμων, σύνταξη των javadocs και του documentation γενικότερα, white-box testing, υλοποίηση του backend στο server που στήθηκε πρόσφατα και πολλών άλλων. Αυτό, αρχικά, θα γίνεται με forks και merge requests - και πάντα στο ρυθμό που μπορείς να συνεισφέρεις. +[/li] +[li] +Να αναφέρεις bugs, να προτείνεις βελτιώσεις και να συμμετέχεις σε συζητήσεις, είτε στον [url=https://discord.gg/PVRVjth]Discord server[/url], είτε αποκτώντας πρόσβαση στον Issue Tracker μας. +[/li] +[li] +Να κατεβάσεις και να δοκιμάσεις την alpha έκδοση της εφαρμογής από [url=https://play.google.com/apps/testing/gr.thmmy.mthmmy]εδώ[/url] αφού πρώτα μας δώσεις ένα gmail για να αποκτήσεις πρόσβαση. +[/li] +[li] +Να έρθεις σε άμεση επικοινωνία με την ομάδα μέσω του Discord ή στέλνοντας email στο thmmynolife@gmail.com. +[/li][/list] +[hr] +[center][size=25pt][b]Η εφαρμογή[/b][/size][/center] + +[center][url=https://s6.postimg.org/4mupem3jl/image.png][img width=200]https://s6.postimg.org/4mupem3jl/image.png[/img][/url] [url=https://s6.postimg.org/ovdhmldgx/image.png][img width=200]https://s6.postimg.org/ovdhmldgx/image.png[/img][/url] [url=https://s6.postimg.org/a9mgycgoh/image.png][img width=200]https://s6.postimg.org/a9mgycgoh/image.png[/img][/url] [url=https://s6.postimg.org/5jwj9qpo1/image.png][img width=200]https://s6.postimg.org/5jwj9qpo1/image.png[/img][/url] [url=https://s6.postimg.org/fjrfpn0xd/image.png][img width=200]https://s6.postimg.org/fjrfpn0xd/image.png[/img][/url] [url=https://s6.postimg.org/z0c5c5w1d/image.png][img width=200]https://s6.postimg.org/z0c5c5w1d/image.png[/img][/url][/center] + +Αυτή τη στιγμή στην εφαρμογή μπορείς να κάνεις login και logout, να δεις τα "Πρόσφατα", να περιηγηθείς στα boards, topics και user profiles και να κατεβάσεις αρχεία συνημμένα σε post. \ No newline at end of file From df0e143cf69429dedd297c24c9b7ba6c7ff7b9e9 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Wed, 18 Jan 2017 20:17:58 +0200 Subject: [PATCH 02/26] BaseApplication class, fixed refresh upon app restart (e.g. after crash), optimized imports --- app/src/main/AndroidManifest.xml | 1 + app/src/main/assets/mit_libraries.html | 2 +- .../mthmmy/activities/AboutActivity.java | 2 +- .../mthmmy/activities/LoginActivity.java | 2 +- .../activities/board/BoardActivity.java | 2 +- .../mthmmy/activities/main/MainActivity.java | 2 +- .../activities/main/forum/ForumAdapter.java | 2 +- .../activities/main/forum/ForumFragment.java | 4 +- .../activities/main/recent/RecentAdapter.java | 2 +- .../main/recent/RecentFragment.java | 2 +- .../activities/profile/ProfileActivity.java | 2 +- .../latestPosts/LatestPostsAdapter.java | 2 +- .../latestPosts/LatestPostsFragment.java | 4 +- .../profile/stats/StatsFragment.java | 2 +- .../activities/topic/TopicActivity.java | 2 +- .../mthmmy/activities/topic/TopicAdapter.java | 1 - .../{activities => }/base/BaseActivity.java | 77 ++------------- .../gr/thmmy/mthmmy/base/BaseApplication.java | 97 +++++++++++++++++++ .../{activities => }/base/BaseFragment.java | 8 +- .../gr/thmmy/mthmmy/model/LinkTarget.java | 1 - .../mthmmy/utils/FileManager/ThmmyFile.java | 2 +- .../utils/ScrollAwareLinearBehavior.java | 1 - 22 files changed, 127 insertions(+), 93 deletions(-) rename app/src/main/java/gr/thmmy/mthmmy/{activities => }/base/BaseActivity.java (77%) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java rename app/src/main/java/gr/thmmy/mthmmy/{activities => }/base/BaseFragment.java (89%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f8bed348..ba225043 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@
  • -
    jsoup v1.10.1 (Copyright Β©2009-2017, Jonathan Hedley <jonathan@hedley.net>)
    +
    jsoup v1.10.2 (Copyright Β©2009-2017, Jonathan Hedley <jonathan@hedley.net>)
  • android-gif-drawable v1.2.3 (Copyright Β©2016 Karol WrΓ³tniak, Droids on Roids)
    diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java index 0b33c3e9..ffc54d8d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java @@ -16,7 +16,7 @@ import android.widget.TextView; import gr.thmmy.mthmmy.BuildConfig; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseActivity; +import gr.thmmy.mthmmy.base.BaseActivity; public class AboutActivity extends BaseActivity { private static final int TIME_INTERVAL = 1000; 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 2035653a..7dacd734 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java @@ -12,8 +12,8 @@ import android.widget.ScrollView; import android.widget.Toast; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import mthmmy.utils.Report; import static gr.thmmy.mthmmy.session.SessionManager.CONNECTION_ERROR; 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 9b7071f5..a48a3a8a 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 @@ -27,7 +27,7 @@ import javax.net.ssl.SSLHandshakeException; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; -import gr.thmmy.mthmmy.activities.base.BaseActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Board; import gr.thmmy.mthmmy.model.LinkTarget; import gr.thmmy.mthmmy.model.Topic; 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 cb9981b1..84319e3f 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 @@ -12,11 +12,11 @@ import android.widget.Toast; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; -import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.main.forum.ForumFragment; import gr.thmmy.mthmmy.activities.main.recent.RecentFragment; import gr.thmmy.mthmmy.activities.topic.TopicActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Board; import gr.thmmy.mthmmy.model.TopicSummary; 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 896078e8..40f14c93 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 @@ -15,7 +15,7 @@ import com.bignerdranch.expandablerecyclerview.ParentViewHolder; import java.util.List; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseFragment; +import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.Board; import gr.thmmy.mthmmy.model.Category; import gr.thmmy.mthmmy.model.TopicSummary; 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 9b51c3af..d9777cf7 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 @@ -24,8 +24,8 @@ import java.util.ArrayList; import java.util.List; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseActivity; -import gr.thmmy.mthmmy.activities.base.BaseFragment; +import gr.thmmy.mthmmy.base.BaseActivity; +import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.Board; import gr.thmmy.mthmmy.model.Category; import gr.thmmy.mthmmy.session.SessionManager; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java index beb22697..32e46af0 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java @@ -11,7 +11,7 @@ import android.widget.TextView; import java.util.List; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseFragment; +import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java index 307f1b33..546b2db3 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 @@ -23,7 +23,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseFragment; +import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.utils.CustomRecyclerView; 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 66e85146..383323be 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 @@ -34,11 +34,11 @@ import javax.net.ssl.SSLHandshakeException; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; -import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment; import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment; import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment; import gr.thmmy.mthmmy.activities.topic.TopicActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.LinkTarget; import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.utils.CircleTransform; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java index 7976dd13..5f0f77d2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java @@ -11,7 +11,7 @@ import android.widget.TextView; import java.util.ArrayList; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseFragment; +import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.model.TopicSummary; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; 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 01786f3b..ccdb5593 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 @@ -21,8 +21,8 @@ import java.util.ArrayList; import javax.net.ssl.SSLHandshakeException; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseActivity; -import gr.thmmy.mthmmy.activities.base.BaseFragment; +import gr.thmmy.mthmmy.base.BaseActivity; +import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.utils.ParseHelpers; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; 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 c75d16bb..789bcfe4 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 @@ -38,7 +38,7 @@ import java.util.List; import javax.net.ssl.SSLHandshakeException; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.base.BaseActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import mthmmy.utils.Report; import okhttp3.Request; 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 3943bf0d..229ec37a 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 @@ -28,7 +28,7 @@ import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; -import gr.thmmy.mthmmy.activities.base.BaseActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.LinkTarget; import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.utils.ParseHelpers; 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 f44e3a65..a9627b25 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 @@ -16,7 +16,6 @@ import android.support.v4.content.res.ResourcesCompat; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; -import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java similarity index 77% rename from app/src/main/java/gr/thmmy/mthmmy/activities/base/BaseActivity.java rename to app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index 4794cf9e..492f84a1 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -1,24 +1,15 @@ -package gr.thmmy.mthmmy.activities.base; +package gr.thmmy.mthmmy.base; import android.app.ProgressDialog; -import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; -import android.widget.ImageView; import android.widget.Toast; -import com.franmontiel.persistentcookiejar.PersistentCookieJar; -import com.franmontiel.persistentcookiejar.cache.SetCookieCache; -import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; -import com.jakewharton.picasso.OkHttp3Downloader; import com.mikepenz.fontawesome_typeface_library.FontAwesome; import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.materialdrawer.AccountHeader; @@ -29,11 +20,6 @@ import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IProfile; -import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader; -import com.mikepenz.materialdrawer.util.DrawerImageLoader; -import com.squareup.picasso.Picasso; - -import java.util.concurrent.TimeUnit; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.AboutActivity; @@ -52,23 +38,10 @@ public abstract class BaseActivity extends AppCompatActivity { // Client & Cookies protected static OkHttpClient client; - private static final long connectTimeout = 30; //TimeUnit.SECONDS for all three - private static final long writeTimeout = 30; - private static final long readTimeout = 30; - protected static Picasso picasso; - private static PersistentCookieJar cookieJar; - private static SharedPrefsCookiePersistor sharedPrefsCookiePersistor; - - //Shared Preferences - protected static final String SHARED_PREFS_NAME = "ThmmySharedPrefs"; - protected static SharedPreferences sharedPrefs; //SessionManager protected static SessionManager sessionManager; - //Other variables - private static boolean init = false; //To initialize stuff only once per app start - //Common UI elements protected Toolbar toolbar; protected Drawer drawer; @@ -76,47 +49,11 @@ public abstract class BaseActivity extends AppCompatActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - if (!init) { - sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE); - sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(BaseActivity.this); - cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor); - client = new OkHttpClient.Builder() - .cookieJar(cookieJar) - .connectTimeout(connectTimeout, TimeUnit.SECONDS) - .writeTimeout(writeTimeout, TimeUnit.SECONDS) - .readTimeout(readTimeout, TimeUnit.SECONDS) - .build(); - sessionManager = new SessionManager(client, cookieJar, sharedPrefsCookiePersistor, sharedPrefs); - picasso = new Picasso.Builder(BaseActivity.this) - .downloader(new OkHttp3Downloader(client)) - .build(); - Picasso.setSingletonInstance(picasso); // all following Picasso (with Picasso.with(Context context) requests will use this Picasso object - //initialize and create the image loader logic TODO move this to a singleton BaseApplication obj - DrawerImageLoader.init(new AbstractDrawerImageLoader() { - @Override - public void set(ImageView imageView, Uri uri, Drawable placeholder) { - Picasso.with(imageView.getContext()).load(uri).placeholder(placeholder).into(imageView); - } - @Override - public void cancel(ImageView imageView) { - Picasso.with(imageView.getContext()).cancelRequest(imageView); - } - - @Override - public Drawable placeholder(Context ctx, String tag) { - if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)) { - return new IconicsDrawable(ctx).icon(FontAwesome.Icon.faw_user) - .paddingDp(10) - .color(ContextCompat.getColor(ctx, R.color.primary_light)) - .backgroundColor(ContextCompat.getColor(ctx, R.color.primary)); - } - - return super.placeholder(ctx, tag); - } - }); - init = true; - } + if(client==null) + client = BaseApplication.getInstance().getClient(); //must check every time - e.g. + // they become null when app restarts after crash + if(sessionManager==null) + sessionManager = BaseApplication.getInstance().getSessionManager(); } @Override @@ -143,7 +80,7 @@ public abstract class BaseActivity extends AppCompatActivity return sessionManager; } - //TODO: move stuff below + //TODO: move stuff below (?) //------------------------------------------DRAWER STUFF---------------------------------------- protected static final int HOME_ID=0; protected static final int LOG_ID =1; diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java new file mode 100644 index 00000000..686086aa --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java @@ -0,0 +1,97 @@ +package gr.thmmy.mthmmy.base; + +import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.support.v4.content.ContextCompat; +import android.widget.ImageView; + +import com.franmontiel.persistentcookiejar.PersistentCookieJar; +import com.franmontiel.persistentcookiejar.cache.SetCookieCache; +import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; +import com.jakewharton.picasso.OkHttp3Downloader; +import com.mikepenz.fontawesome_typeface_library.FontAwesome; +import com.mikepenz.iconics.IconicsDrawable; +import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader; +import com.mikepenz.materialdrawer.util.DrawerImageLoader; +import com.squareup.picasso.Picasso; + +import java.util.concurrent.TimeUnit; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.session.SessionManager; +import okhttp3.OkHttpClient; + +public class BaseApplication extends Application { + + + private static BaseApplication baseApplication; //BaseApplication singleton + + // Client & SessionManager + private OkHttpClient client; + private static SessionManager sessionManager; + + //Shared Preferences + private static final String SHARED_PREFS_NAME = "ThmmySharedPrefs"; + + public static BaseApplication getInstance(){ + return baseApplication; + } + + @Override + public void onCreate() { + super.onCreate(); + baseApplication = this; //init singleton + + SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE); + SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext()); + PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor); + client = new OkHttpClient.Builder() + .cookieJar(cookieJar) + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build(); + sessionManager = new SessionManager(client, cookieJar, sharedPrefsCookiePersistor, sharedPrefs); + Picasso picasso = new Picasso.Builder(getApplicationContext()) + .downloader(new OkHttp3Downloader(client)) + .build(); + + Picasso.setSingletonInstance(picasso); //All following Picasso (with Picasso.with(Context context) requests will use this Picasso object + + //Initialize and create the image loader logic + DrawerImageLoader.init(new AbstractDrawerImageLoader() { + @Override + public void set(ImageView imageView, Uri uri, Drawable placeholder) { + Picasso.with(imageView.getContext()).load(uri).placeholder(placeholder).into(imageView); + } + @Override + public void cancel(ImageView imageView) { + Picasso.with(imageView.getContext()).cancelRequest(imageView); + } + + @Override + public Drawable placeholder(Context ctx, String tag) { + if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)) { + return new IconicsDrawable(ctx).icon(FontAwesome.Icon.faw_user) + .paddingDp(10) + .color(ContextCompat.getColor(ctx, R.color.primary_light)) + .backgroundColor(ContextCompat.getColor(ctx, R.color.primary)); + } + return super.placeholder(ctx, tag); + } + }); + } + + public OkHttpClient getClient() { + return client; + } + + public SessionManager getSessionManager() { + return sessionManager; + } + + +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/base/BaseFragment.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java similarity index 89% rename from app/src/main/java/gr/thmmy/mthmmy/activities/base/BaseFragment.java rename to app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java index 6b0b93c9..c7b3d477 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/base/BaseFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java @@ -1,4 +1,4 @@ -package gr.thmmy.mthmmy.activities.base; +package gr.thmmy.mthmmy.base; import android.content.Context; import android.os.Bundle; @@ -16,14 +16,16 @@ public abstract class BaseFragment extends Fragment { private String TAG; protected int sectionNumber; - protected OkHttpClient client; + protected static OkHttpClient client; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); TAG = getArguments().getString(ARG_TAG); sectionNumber = getArguments().getInt(ARG_SECTION_NUMBER); - client = BaseActivity.getClient(); + if(client==null) + client = BaseApplication.getInstance().getClient(); //must check every time - e.g. + // becomes null when app restarts after crash Report.d(TAG, "onCreate"); } diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java b/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java index aaf14773..4a112d2a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java @@ -1,7 +1,6 @@ package gr.thmmy.mthmmy.model; import android.net.Uri; -import android.support.annotation.NonNull; import java.util.Objects; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java index c1eb7cfb..8e8414f6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java @@ -16,7 +16,7 @@ import mthmmy.utils.Report; import okhttp3.Request; import okhttp3.Response; -import static gr.thmmy.mthmmy.activities.base.BaseActivity.getClient; +import static gr.thmmy.mthmmy.base.BaseActivity.getClient; /** * Used for downloading and storing a file from the forum using {@link okhttp3}. 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 6e791204..0f3564c6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java @@ -6,7 +6,6 @@ import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.ViewCompat; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.ViewPropertyAnimator; From 3e8365f44129a76ca3cf42dc47aa546c950a22ae Mon Sep 17 00:00:00 2001 From: Apostolof Date: Wed, 18 Jan 2017 20:49:08 +0200 Subject: [PATCH 03/26] Downloading and parsing fixes. --- app/src/main/AndroidManifest.xml | 1 - .../activities/board/BoardActivity.java | 4 +- .../activities/topic/TopicActivity.java | 55 ++++++--- .../mthmmy/activities/topic/TopicAdapter.java | 36 +++--- .../thmmy/mthmmy/session/SessionManager.java | 115 ++++++++---------- .../mthmmy/utils/FileManager/ThmmyFile.java | 82 ++++++++++--- 6 files changed, 176 insertions(+), 117 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ba225043..f8ce186c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,7 +6,6 @@ - = 23 + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + checkSelfPermission(PERMISSIONS_STORAGE[0]); + checkSelfPermission(PERMISSIONS_STORAGE[1]); + requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); + } else readWriteAccepted = true; + } + + //--------------------------------------BOTTOM NAV BAR METHODS---------------------------------- + private void paginationEnabled(boolean enabled) { + firstPage.setEnabled(enabled); + previousPage.setEnabled(enabled); + nextPage.setEnabled(enabled); + lastPage.setEnabled(enabled); + } + private void initIncrementButton(ImageButton increment, final int step) { // Increment once for a click increment.setOnClickListener(new View.OnClickListener() { @@ -335,7 +367,7 @@ public class TopicActivity extends BaseActivity { protected void onPreExecute() { progressBar.setVisibility(ProgressBar.VISIBLE); - paginationEnable(false); + paginationEnabled(false); if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(false); } @@ -403,7 +435,7 @@ public class TopicActivity extends BaseActivity { pageIndicator.setText(String.valueOf(thisPage) + "/" + String.valueOf(numberOfPages)); pageRequestValue = thisPage; - paginationEnable(true); + paginationEnabled(true); if (topicTitle == null || Objects.equals(topicTitle, "")) toolbar.setTitle(parsedTitle); @@ -488,11 +520,4 @@ public class TopicActivity extends BaseActivity { } } } - - private void paginationEnable(boolean enabled) { - firstPage.setEnabled(enabled); - previousPage.setEnabled(enabled); - nextPage.setEnabled(enabled); - lastPage.setEnabled(enabled); - } } \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index a9627b25..05a2779f 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 @@ -10,7 +10,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.os.PowerManager; import android.support.annotation.NonNull; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.widget.CardView; @@ -93,7 +92,7 @@ class TopicAdapter extends RecyclerView.Adapter { * Index of state indicator in the boolean array. If true quote button for this post is checked. */ private static final int isQuoteButtonChecked = 2; - private final MaterialProgressBar progressBar; + //private final MaterialProgressBar progressBar; private DownloadTask downloadTask; private TopicActivity.TopicTask topicTask; @@ -167,7 +166,7 @@ class TopicAdapter extends RecyclerView.Adapter { //Initializes properties, array's values will be false by default viewProperties.add(new boolean[3]); } - this.progressBar = progressBar; + //this.progressBar = progressBar; downloadTask = new DownloadTask(); this.topicTask = topicTask; } @@ -244,8 +243,12 @@ class TopicAdapter extends RecyclerView.Adapter { attached.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - downloadTask = new DownloadTask(); - downloadTask.execute(attachedFile); + if (TopicActivity.readWriteAccepted) { + downloadTask = new DownloadTask(); + downloadTask.execute(attachedFile); + } else + Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT) + .show(); } }); @@ -616,17 +619,11 @@ class TopicAdapter extends RecyclerView.Adapter { * Debug Tag for logging debug output to LogCat */ private static final String TAG = "DownloadTask"; //Separate tag for AsyncTask - private PowerManager.WakeLock mWakeLock; @Override protected void onPreExecute() { super.onPreExecute(); - //Locks CPU to prevent going off - PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - getClass().getName()); - mWakeLock.acquire(); - progressBar.setVisibility(View.VISIBLE); + Toast.makeText(context, "Downloading", Toast.LENGTH_SHORT).show(); } @Override @@ -647,7 +644,10 @@ class TopicAdapter extends RecyclerView.Adapter { Report.e(TAG, "Error while trying to download a file", e); return e.toString(); } catch (OutOfMemoryError e) { - Report.e(TAG, "Error while trying to download a file", e); + Report.e(TAG, e.toString(), e); + return e.toString(); + } catch (IllegalStateException e) { + Report.e(TAG, e.toString(), e); return e.toString(); } return null; @@ -655,12 +655,10 @@ class TopicAdapter extends RecyclerView.Adapter { @Override protected void onPostExecute(String result) { - mWakeLock.release(); - if (result != null) - Toast.makeText(context, result, Toast.LENGTH_SHORT).show(); - else - Toast.makeText(context, "Download complete", Toast.LENGTH_SHORT).show(); - progressBar.setVisibility(View.INVISIBLE); + if (result != null) { + Toast.makeText(context, "Download failed!", Toast.LENGTH_SHORT).show(); + Toast.makeText(context, result, Toast.LENGTH_LONG).show(); + } } } } \ No newline at end of file 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 16ee1d0f..15245e2f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -27,11 +27,10 @@ import okhttp3.RequestBody; import okhttp3.Response; /** - This class handles all session related operations (e.g. login, logout) - and stores data to SharedPreferences (session information and cookies). -*/ -public class SessionManager -{ + * This class handles all session related operations (e.g. login, logout) + * and stores data to SharedPreferences (session information and cookies). + */ +public class SessionManager { //Class TAG private static final String TAG = "SessionManager"; @@ -66,27 +65,25 @@ public class SessionManager //Constructor public SessionManager(OkHttpClient client, PersistentCookieJar cookieJar, - SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sharedPrefs) - { + SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sharedPrefs) { this.client = client; - this.cookiePersistor=cookiePersistor; + this.cookiePersistor = cookiePersistor; this.cookieJar = cookieJar; this.sharedPrefs = sharedPrefs; } //------------------------------------AUTH BEGINS---------------------------------------------- + /** - * Login function with two options: (username, password) or nothing (using saved cookies). - * Always call it in a separate thread. + * Login function with two options: (username, password) or nothing (using saved cookies). + * Always call it in a separate thread. */ - public int login(String... strings) - { + public int login(String... strings) { Report.i(TAG, "Logging in..."); //Build the login request for each case Request request; - if (strings.length == 2) - { + if (strings.length == 2) { clearSessionData(); String loginName = strings[0]; @@ -101,9 +98,7 @@ public class SessionManager .url(loginUrl) .post(formBody) .build(); - } - else - { + } else { request = new Request.Builder() .url(loginUrl) .build(); @@ -125,20 +120,16 @@ public class SessionManager sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, false).apply(); sharedPrefs.edit().putString(USERNAME, extractUserName(document)).apply(); String avatar = extractAvatarLink(document); - if (avatar!=null) - { - sharedPrefs.edit().putBoolean(HAS_AVATAR,true).apply(); + if (avatar != null) { + sharedPrefs.edit().putBoolean(HAS_AVATAR, true).apply(); sharedPrefs.edit().putString(AVATAR_LINK, extractAvatarLink(document)).apply(); - } - else - sharedPrefs.edit().putBoolean(HAS_AVATAR,false).apply(); + } else + sharedPrefs.edit().putBoolean(HAS_AVATAR, false).apply(); sharedPrefs.edit().putString(LOGOUT_LINK, HttpUrl.parse(logoutButton.attr("href")).toString()).apply(); return SUCCESS; - } - else - { + } else { Report.i(TAG, "Login failed."); //Investigate login failure @@ -159,41 +150,35 @@ public class SessionManager return FAILURE; } //Handle exception - } - catch (InterruptedIOException e){ + } catch (InterruptedIOException e) { Report.i(TAG, "Login InterruptedIOException"); //users cancels LoginTask return CANCELLED; - } - catch (IOException e) { + } catch (IOException e) { Report.w(TAG, "Login IOException", e); return CONNECTION_ERROR; - } - catch (Exception e) { + } catch (Exception e) { Report.w(TAG, "Login Exception (other)", e); return EXCEPTION; } } /** - * A function that checks the validity of the current saved session (if it exists). - * If isLoggedIn() is true, it will call login() with cookies. On failure, this can only return - * the code FAILURE. CANCELLED, CONNECTION_ERROR and EXCEPTION are simply considered a SUCCESS - * (e.g. no internet connection), at least until a more thorough handling of different - * exceptions is implemented (if considered mandatory). - * Always call it in a separate thread in a way that won't hinder performance (e.g. after - * fragments' data are retrieved). + * A function that checks the validity of the current saved session (if it exists). + * If isLoggedIn() is true, it will call login() with cookies. On failure, this can only return + * the code FAILURE. CANCELLED, CONNECTION_ERROR and EXCEPTION are simply considered a SUCCESS + * (e.g. no internet connection), at least until a more thorough handling of different + * exceptions is implemented (if considered mandatory). + * Always call it in a separate thread in a way that won't hinder performance (e.g. after + * fragments' data are retrieved). */ - public void validateSession() - { + public void validateSession() { Report.i(TAG, "Validating session..."); - if(isLoggedIn()) - { + if (isLoggedIn()) { int loginResult = login(); - if(loginResult != FAILURE) + if (loginResult != FAILURE) return; - } - else if(isLoginScreenDefault()) + } else if (isLoginScreenDefault()) return; sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, true).apply(); @@ -201,10 +186,9 @@ public class SessionManager } /** - * Call this function when user explicitly chooses to continue as a guest (UI thread). + * Call this function when user explicitly chooses to continue as a guest (UI thread). */ - public void guestLogin() - { + public void guestLogin() { Report.i("TAG", "Continuing as a guest, as chosen by the user."); clearSessionData(); sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, false).apply(); @@ -212,14 +196,13 @@ public class SessionManager /** - * Logout function. Always call it in a separate thread. + * Logout function. Always call it in a separate thread. */ - public int logout() - { + public int logout() { Report.i(TAG, "Logging out..."); Request request = new Request.Builder() - .url(sharedPrefs.getString(LOGOUT_LINK,"LogoutLink")) + .url(sharedPrefs.getString(LOGOUT_LINK, "LogoutLink")) .build(); try { @@ -271,15 +254,18 @@ public class SessionManager return sharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true); } + //TODO FIX METHOD, THIS MIGHT BE A SECURITY FLAW!! SEE ISSUE #2 MERGED WITH #16 + public String getCookieHeader() { + return cookiePersistor.loadAll().get(0).toString(); + } + //--------------------------------------GETTERS END--------------------------------------------- //------------------------------------OTHER FUNCTIONS------------------------------------------- - private void setPersistentCookieSession() - { + private void setPersistentCookieSession() { List cookieList = cookieJar.loadForRequest(indexUrl); - if (cookieList.size() == 2) - { + if (cookieList.size() == 2) { if ((cookieList.get(0).name().equals("THMMYgrC00ki3")) && (cookieList.get(1).name().equals("PHPSESSID"))) { Cookie.Builder builder = new Cookie.Builder(); @@ -295,18 +281,16 @@ public class SessionManager } } - private void clearSessionData() - { + private void clearSessionData() { cookieJar.clear(); sharedPrefs.edit().clear().apply(); //Clear session data sharedPrefs.edit().putString(USERNAME, guestName).apply(); sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out - Report.i(TAG,"Session data cleared."); + Report.i(TAG, "Session data cleared."); } @Nullable - private String extractUserName(Document doc) - { + private String extractUserName(Document doc) { if (doc != null) { Elements user = doc.select("div[id=myuser] > h3"); @@ -319,13 +303,12 @@ public class SessionManager return matcher.group(1); } } - Report.w(TAG,"Extracting username failed!"); + Report.w(TAG, "Extracting username failed!"); return null; } @Nullable - private String extractAvatarLink(Document doc) - { + private String extractAvatarLink(Document doc) { if (doc != null) { Elements avatar = doc.select("#ava img"); @@ -333,7 +316,7 @@ public class SessionManager return avatar.attr("src"); } } - Report.w(TAG,"Extracting avatar's link failed!"); + Report.w(TAG, "Extracting avatar's link failed!"); return null; } //----------------------------------OTHER FUNCTIONS END----------------------------------------- diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java index 8e8414f6..5de8cbc8 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java @@ -1,10 +1,18 @@ package gr.thmmy.mthmmy.utils.FileManager; +import android.app.DownloadManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.Uri; import android.os.Environment; import android.os.StatFs; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.util.Log; import android.webkit.MimeTypeMap; +import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; @@ -12,6 +20,7 @@ import java.io.IOException; import java.net.URL; import java.util.Objects; +import gr.thmmy.mthmmy.base.BaseActivity; import mthmmy.utils.Report; import okhttp3.Request; import okhttp3.Response; @@ -22,6 +31,7 @@ import static gr.thmmy.mthmmy.base.BaseActivity.getClient; * Used for downloading and storing a file from the forum using {@link okhttp3}. *

    Class has one constructor, {@link #ThmmyFile(URL, String, String)}. */ +@SuppressWarnings("unused") public class ThmmyFile { /** * Debug Tag for logging debug output to LogCat @@ -46,8 +56,8 @@ public class ThmmyFile { } /** - * This constructor only creates a ThmmyFile object and does not download the file. To download - * the file use {@link #download(Context)}! + * This constructor only creates a ThmmyFile object and does not download the file. To + * download the file use {@link #download(Context)} after you provide a url! * * @param fileUrl {@link URL} object with file's url * @param filename {@link String} with desired file name @@ -115,23 +125,64 @@ public class ThmmyFile { /** * Used to download the file. If download is successful file's extension and path will be assigned * to object's fields and can be accessed using getter methods. - *

    File is stored in sdcard1/Android/data/Downloads/packageName

    * - * @return the {@link File} if successful, null otherwise - * @throws IOException if the request could not be executed due to cancellation, a connectivity - * problem or timeout. Because networks can fail during an exchange, it is possible that the - * remote server accepted the request before the failure. - * @throws SecurityException if the requested file is not hosted by the forum. + * @return null if downloaded with the download service, otherwise the {@link File} + * @throws IOException if the request could not be executed due to cancellation, a + * connectivity problem or timeout. Because networks can fail + * during an exchange, it is possible that the remote server + * accepted the request before the failure. + * @throws SecurityException if the requested file is not hosted by the forum. + * @throws IllegalStateException if file's url or filename is not yet set */ @Nullable - public File download(Context context) throws IOException, SecurityException, OutOfMemoryError { - if (fileUrl == null) { - return null; - } - if (!Objects.equals(fileUrl.getHost(), "www.thmmy.gr")) + public File download(Context context) throws IOException, IllegalStateException, OutOfMemoryError { + if (fileUrl == null) + throw new IllegalStateException("Internal error!\nNo url was provided."); + else if (!Objects.equals(fileUrl.getHost(), "www.thmmy.gr")) throw new SecurityException("Downloading files from other sources is not supported"); + else if (filename == null || Objects.equals(filename, "")) + throw new IllegalStateException("Internal error!\nNo filename was provided."); + + try { + downloadWithManager(context, fileUrl); + } catch (IllegalStateException e) { + return downloadWithoutManager(context, fileUrl); + } + return null; + } + + private void downloadWithManager(Context context, @NonNull URL pFileUrl) throws IllegalStateException, IOException { + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(pFileUrl.toString())); + request.addRequestHeader("Cookie", BaseActivity.getSessionManager().getCookieHeader()); + request.setDescription("mThmmy"); + request.setMimeType(MimeTypeMap.getSingleton().getMimeTypeFromExtension( + MimeTypeMap.getFileExtensionFromUrl(filename))); + request.setTitle(filename); + request.allowScanningByMediaScanner(); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + try { + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); + } catch (IllegalStateException e) { + Report.d(TAG, "External directory not available!", e); + Log.d(TAG, "External directory not available!", e); + throw e; + } - Request request = new Request.Builder().url(fileUrl).build(); + DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); + manager.enqueue(request); + context.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Toast.makeText(context, "Download complete", Toast.LENGTH_SHORT).show(); + context.unregisterReceiver(this); + } + }, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + } + + @Nullable + private File downloadWithoutManager(Context context, @NonNull URL pFileUrl) throws IOException + , SecurityException, OutOfMemoryError { + Request request = new Request.Builder().url(pFileUrl).build(); Response response = getClient().newCall(request).execute(); if (!response.isSuccessful()) { @@ -153,7 +204,8 @@ public class ThmmyFile { } @Nullable - private File getOutputMediaFile(Context context, String fileName, String fileInfo) throws OutOfMemoryError, IOException { + private File getOutputMediaFile(Context context, String fileName, String fileInfo) throws + OutOfMemoryError, IOException { File mediaStorageDir; String extState = Environment.getExternalStorageState(); if (Environment.isExternalStorageRemovable() && From 1bc29aca95e6577351f0a5a54af097baebc25fbd Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 19 Jan 2017 17:04:19 +0200 Subject: [PATCH 04/26] Login works for all themes --- app/src/debug/java/mthmmy/utils/Report.java | 14 ++++ .../gr/thmmy/mthmmy/base/BaseActivity.java | 1 + .../thmmy/mthmmy/session/SessionManager.java | 74 +++++++++++++------ app/src/release/java/mthmmy.utils/Report.java | 5 ++ 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/app/src/debug/java/mthmmy/utils/Report.java b/app/src/debug/java/mthmmy/utils/Report.java index 68ab3c3b..6e6a906f 100644 --- a/app/src/debug/java/mthmmy/utils/Report.java +++ b/app/src/debug/java/mthmmy/utils/Report.java @@ -64,4 +64,18 @@ public class Report { Log.wtf(TAG,message + ": " + tr.getMessage(),tr); } + + /** + * Prints long messages in logcat (debug level). + */ + public static void longMessage(String TAG, String message) + { + int maxLogSize = 1000; + for(int i = 0; i <= message.length() / maxLogSize; i++) { + int start = i * maxLogSize; + int end = (i+1) * maxLogSize; + end = end > message.length() ? message.length() : end; + Report.d(TAG, message.substring(start, end)); + } + } } \ No newline at end of file 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 492f84a1..e832301a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -198,6 +198,7 @@ public abstract class BaseActivity extends AppCompatActivity drawer = new DrawerBuilder() .withActivity(this) .withToolbar(toolbar) + .withDrawerWidthDp(175) .withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_light)) .withAccountHeader(accountHeader) .addDrawerItems(homeItem,loginLogoutItem,aboutItem) 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 15245e2f..a6bb4df5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -1,6 +1,7 @@ package gr.thmmy.mthmmy.session; import android.content.SharedPreferences; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.franmontiel.persistentcookiejar.PersistentCookieJar; @@ -35,8 +36,8 @@ public class SessionManager { private static final String TAG = "SessionManager"; //Generic constants - public static final HttpUrl indexUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php"); - public static final HttpUrl forumUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=forum"); + 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"); private static final String guestName = "Guest"; @@ -109,8 +110,9 @@ public class SessionManager { Response response = client.newCall(request).execute(); Document document = Jsoup.parse(response.body().string()); - Element logoutButton = document.getElementById("logoutbtn"); //Attempt to find logout button - if (logoutButton != null) //If logout button exists, login was successful + Elements unreadRepliesLinks = document.select("a[href=https://www.thmmy.gr/smf/index.php?action=unreadreplies]"); + + if (unreadRepliesLinks.size()>=2) //Normally it's just == 2, but who knows what can be posted by users { Report.i(TAG, "Login successful!"); setPersistentCookieSession(); //Store cookies @@ -126,7 +128,8 @@ public class SessionManager { } else sharedPrefs.edit().putBoolean(HAS_AVATAR, false).apply(); - sharedPrefs.edit().putString(LOGOUT_LINK, HttpUrl.parse(logoutButton.attr("href")).toString()).apply(); + + sharedPrefs.edit().putString(LOGOUT_LINK, extractLogoutLink(document)).apply(); return SUCCESS; } else { @@ -254,7 +257,6 @@ public class SessionManager { return sharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true); } - //TODO FIX METHOD, THIS MIGHT BE A SECURITY FLAW!! SEE ISSUE #2 MERGED WITH #16 public String getCookieHeader() { return cookiePersistor.loadAll().get(0).toString(); } @@ -290,33 +292,57 @@ public class SessionManager { } @Nullable - private String extractUserName(Document doc) { - if (doc != null) { - Elements user = doc.select("div[id=myuser] > h3"); + private String extractUserName(@NonNull Document doc) { + //Scribbles2 Theme + Elements user = doc.select("div[id=myuser] > h3"); - if (user.size() == 1) { - String txt = user.first().ownText(); + if (user.size() == 1) { + String txt = user.first().ownText(); - Pattern pattern = Pattern.compile(", (.*?),"); - Matcher matcher = pattern.matcher(txt); - if (matcher.find()) - return matcher.group(1); + Pattern pattern = Pattern.compile(", (.*?),"); + Matcher matcher = pattern.matcher(txt); + if (matcher.find()) + return matcher.group(1); + } + else + { + //Helios_Multi and SMF_oneBlue + user = doc.select("td.smalltext[width=100%] b"); + if (user.size() == 1) + return user.first().ownText(); + else + { + //SMF Default Theme + user = doc.select("td.titlebg2[height=32] b"); + if (user.size() == 1) + return user.first().ownText(); } } - Report.w(TAG, "Extracting username failed!"); + + + Report.e(TAG, "Extracting username failed!"); return null; } + @Nullable - private String extractAvatarLink(Document doc) { - if (doc != null) { - Elements avatar = doc.select("#ava img"); + private String extractAvatarLink(@NonNull Document doc) { + Elements avatar = doc.getElementsByClass("avatar"); + if (!avatar.isEmpty()) + return avatar.first().attr("src"); - if (avatar.size() == 1) { - return avatar.attr("src"); - } - } - Report.w(TAG, "Extracting avatar's link failed!"); + Report.e(TAG, "Extracting avatar's link failed!"); + return null; + } + + @Nullable + private String extractLogoutLink(@NonNull Document doc) { + Elements logoutLink = doc.select("a[href^=https://www.thmmy.gr/smf/index.php?action=logout;sesc=]"); + + if (!logoutLink.isEmpty()) + return logoutLink.first().attr("href"); + + Report.e(TAG, "Extracting logout link failed!"); return null; } //----------------------------------OTHER FUNCTIONS END----------------------------------------- diff --git a/app/src/release/java/mthmmy.utils/Report.java b/app/src/release/java/mthmmy.utils/Report.java index 25df4841..ce2ea89d 100644 --- a/app/src/release/java/mthmmy.utils/Report.java +++ b/app/src/release/java/mthmmy.utils/Report.java @@ -77,5 +77,10 @@ public class Report FirebaseCrash.report(tr); } + /** + * Does nothing in release. + */ + public static void longMessage(String TAG, String level, String message) {return;} + } From 044d4ed7365c2c5868b826fdce127c37a9993b18 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 19 Jan 2017 18:45:40 +0200 Subject: [PATCH 05/26] Drawer size fix (now depends on screen size) --- .../gr/thmmy/mthmmy/base/BaseActivity.java | 2 +- .../gr/thmmy/mthmmy/base/BaseApplication.java | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index e832301a..ba740f68 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -198,7 +198,7 @@ public abstract class BaseActivity extends AppCompatActivity drawer = new DrawerBuilder() .withActivity(this) .withToolbar(toolbar) - .withDrawerWidthDp(175) + .withDrawerWidthDp((int)BaseApplication.getInstance().getDpWidth()/2) .withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_light)) .withAccountHeader(accountHeader) .addDrawerItems(homeItem,loginLogoutItem,aboutItem) 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 686086aa..1e5ffdd6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java @@ -6,6 +6,7 @@ import android.content.SharedPreferences; import android.graphics.drawable.Drawable; import android.net.Uri; import android.support.v4.content.ContextCompat; +import android.util.DisplayMetrics; import android.widget.ImageView; import com.franmontiel.persistentcookiejar.PersistentCookieJar; @@ -31,10 +32,13 @@ public class BaseApplication extends Application { // Client & SessionManager private OkHttpClient client; - private static SessionManager sessionManager; + private SessionManager sessionManager; //Shared Preferences - private static final String SHARED_PREFS_NAME = "ThmmySharedPrefs"; + private final String SHARED_PREFS_NAME = "ThmmySharedPrefs"; + + //Display Metrics + private static float dpHeight, dpWidth; public static BaseApplication getInstance(){ return baseApplication; @@ -83,6 +87,10 @@ public class BaseApplication extends Application { return super.placeholder(ctx, tag); } }); + + DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics(); + dpHeight = displayMetrics.heightPixels / displayMetrics.density; + dpWidth = displayMetrics.widthPixels / displayMetrics.density; } public OkHttpClient getClient() { @@ -93,5 +101,11 @@ public class BaseApplication extends Application { return sessionManager; } + public float getDpHeight() { + return dpHeight; + } + public float getDpWidth() { + return dpWidth; + } } From 86f283a78db8773cda95775f8009f9cd1d14a030 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 19 Jan 2017 19:26:10 +0200 Subject: [PATCH 06/26] Added drawer support for upcoming DownloadsActivity --- .../gr/thmmy/mthmmy/base/BaseActivity.java | 64 +++++++++++++++---- app/src/main/res/values/strings.xml | 3 + 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index ba740f68..8760198d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -83,13 +83,14 @@ public abstract class BaseActivity extends AppCompatActivity //TODO: move stuff below (?) //------------------------------------------DRAWER STUFF---------------------------------------- protected static final int HOME_ID=0; - protected static final int LOG_ID =1; - protected static final int ABOUT_ID=2; + protected static final int DOWNLOADS_ID=1; + protected static final int LOG_ID =2; + protected static final int ABOUT_ID=3; private AccountHeader accountHeader; private ProfileDrawerItem profileDrawerItem; - private PrimaryDrawerItem homeItem, loginLogoutItem, aboutItem; - private IconicsDrawable homeIcon, homeIconSelected, loginIcon, logoutIcon, + private PrimaryDrawerItem homeItem, downloadsItem, loginLogoutItem, aboutItem; + private IconicsDrawable homeIcon, homeIconSelected, downloadsIcon, downloadsIconSelected, loginIcon, logoutIcon, aboutIcon, aboutIconSelected; /** @@ -110,6 +111,14 @@ public abstract class BaseActivity extends AppCompatActivity .icon(FontAwesome.Icon.faw_home) .color(selectedSecondaryColor); + downloadsIcon =new IconicsDrawable(this) + .icon(FontAwesome.Icon.faw_download) + .color(primaryColor); + + downloadsIconSelected =new IconicsDrawable(this) + .icon(FontAwesome.Icon.faw_download) + .color(selectedSecondaryColor); + loginIcon =new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_sign_in) .color(primaryColor); @@ -136,21 +145,34 @@ public abstract class BaseActivity extends AppCompatActivity .withIcon(homeIcon) .withSelectedIcon(homeIconSelected); - if (!sessionManager.isLoggedIn()) //When logged out + + + if (sessionManager.isLoggedIn()) //When logged in + { loginLogoutItem = new PrimaryDrawerItem() .withTextColor(primaryColor) .withSelectedColor(selectedSecondaryColor) - .withIdentifier(LOG_ID).withName(R.string.login) - .withIcon(loginIcon) + .withIdentifier(LOG_ID) + .withName(R.string.logout) + .withIcon(logoutIcon) .withSelectable(false); + downloadsItem = new PrimaryDrawerItem() + .withTextColor(primaryColor) + .withSelectedColor(selectedPrimaryColor) + .withSelectedTextColor(selectedSecondaryColor) + .withIdentifier(DOWNLOADS_ID) + .withName(R.string.downloads) + .withIcon(downloadsIcon) + .withSelectedIcon(downloadsIconSelected); + } else loginLogoutItem = new PrimaryDrawerItem() .withTextColor(primaryColor) .withSelectedColor(selectedSecondaryColor) - .withIdentifier(LOG_ID) - .withName(R.string.logout) - .withIcon(logoutIcon) + .withIdentifier(LOG_ID).withName(R.string.login) + .withIcon(loginIcon) .withSelectable(false); + aboutItem = new PrimaryDrawerItem() .withTextColor(primaryColor) .withSelectedColor(selectedPrimaryColor) @@ -195,13 +217,12 @@ public abstract class BaseActivity extends AppCompatActivity .build(); //Drawer - drawer = new DrawerBuilder() + DrawerBuilder drawerBuilder = new DrawerBuilder() .withActivity(this) .withToolbar(toolbar) .withDrawerWidthDp((int)BaseApplication.getInstance().getDpWidth()/2) .withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_light)) .withAccountHeader(accountHeader) - .addDrawerItems(homeItem,loginLogoutItem,aboutItem) .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { @@ -213,6 +234,14 @@ public abstract class BaseActivity extends AppCompatActivity startActivity(i); } } +// else if(drawerItem.equals(DOWNLOADS_ID)) +// { +// if (sessionManager.isLoggedIn()) //When logged out or if user is guest +// { +// Intent i = new Intent(BaseActivity.this, DownloadsActivity.class); +// startActivity(i); +// } +// } else if(drawerItem.equals(LOG_ID)) { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest @@ -238,8 +267,14 @@ public abstract class BaseActivity extends AppCompatActivity drawer.closeDrawer(); return true; } - }) - .build(); + }); + + if(sessionManager.isLoggedIn()) + drawerBuilder.addDrawerItems(homeItem,downloadsItem,loginLogoutItem,aboutItem); + else + drawerBuilder.addDrawerItems(homeItem,loginLogoutItem,aboutItem); + + drawer = drawerBuilder.build(); drawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false); drawer.setOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() { @@ -257,6 +292,7 @@ public abstract class BaseActivity extends AppCompatActivity { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest { + drawer.removeItem(DOWNLOADS_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) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 88e15276..2b469a93 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -51,6 +51,9 @@ Most Popular Boards By Posts Most Popular Boards By Activity + + Downloads + About v%1$s From c8e68f4351401ea5eaddbfbf5fc861155155f004 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Thu, 19 Jan 2017 22:18:17 +0200 Subject: [PATCH 07/26] Downloads init, profile and download fixes. --- app/src/main/AndroidManifest.xml | 2 + .../activities/board/BoardActivity.java | 4 + .../downloads/DownloadsActivity.java | 274 ++++++++++++++++++ .../downloads/DownloadsAdapter.java | 181 ++++++++++++ .../profile/stats/StatsFragment.java | 36 ++- .../profile/summary/SummaryFragment.java | 11 +- .../activities/topic/TopicActivity.java | 19 +- .../mthmmy/activities/topic/TopicAdapter.java | 2 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 121 ++++---- .../java/gr/thmmy/mthmmy/model/Download.java | 58 ++++ .../gr/thmmy/mthmmy/model/LinkTarget.java | 34 ++- .../mthmmy/utils/FileManager/ThmmyFile.java | 1 - app/src/main/res/drawable/ic_file_upload.xml | 11 + .../main/res/layout/activity_downloads.xml | 62 ++++ .../res/layout/activity_downloads_row.xml | 65 +++++ app/src/main/res/values/strings.xml | 1 + 16 files changed, 776 insertions(+), 106 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/model/Download.java create mode 100644 app/src/main/res/drawable/ic_file_upload.xml create mode 100644 app/src/main/res/layout/activity_downloads.xml create mode 100644 app/src/main/res/layout/activity_downloads_row.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f8ce186c..b1e421d3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -63,6 +63,8 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.main.MainActivity"/> + +
    \ No newline at end of file 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 80a607a5..734eafff 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 @@ -186,6 +186,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo @SuppressWarnings("unused") private static final String TAG = "BoardTask"; //Separate tag for AsyncTask + @Override protected void onPreExecute() { if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE); if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(false); @@ -207,6 +208,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo return false; } + @Override protected void onPostExecute(Boolean result) { if (!result) { //Parse failed! Report.d(TAG, "Parse failed!"); @@ -214,6 +216,8 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo , "Fatal error!\n Aborting...", Toast.LENGTH_LONG).show(); finish(); } + if (boardTitle == null || Objects.equals(boardTitle, "")) toolbar.setTitle(boardTitle); + //Parse was successful ++pagesLoaded; if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(true); 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 new file mode 100644 index 00000000..60d83b44 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java @@ -0,0 +1,274 @@ +package gr.thmmy.mthmmy.activities.downloads; + +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +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.view.View; +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; + +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.Download; +import gr.thmmy.mthmmy.model.LinkTarget; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import mthmmy.utils.Report; +import okhttp3.Request; +import okhttp3.Response; + +public class DownloadsActivity extends BaseActivity implements DownloadsAdapter.OnLoadMoreListener { + /** + * Debug Tag for logging debug output to LogCat + */ + @SuppressWarnings("unused") + private static final String TAG = "DownloadsActivity"; + /** + * The key to use when putting download's url String to {@link DownloadsActivity}'s Bundle. + */ + public static final String BUNDLE_DOWNLOADS_URL = "DOWNLOADS_URL"; + /** + * The key to use when putting download's title String to {@link DownloadsActivity}'s Bundle. + */ + public static final String BUNDLE_DOWNLOADS_TITLE = "DOWNLOADS_TITLE"; + private static final String downloadsIndexUrl = "https://www.thmmy.gr/smf/index.php?action=tpmod;dl;"; + private String downloadsUrl; + String downloadsTitle; + private ArrayList parsedDownloads = new ArrayList<>(); + + private MaterialProgressBar progressBar; + private RecyclerView recyclerView; + private DownloadsAdapter downloadsAdapter; + private FloatingActionButton uploadFAB; + + private ParseDownloadPageTask parseDownloadPageTask; + private int numberOfPages = -1; + private int pagesLoaded = 0; + private boolean isLoadingMore; + private static final int visibleThreshold = 5; + private int lastVisibleItem, totalItemCount; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_downloads); + + Bundle extras = getIntent().getExtras(); + downloadsTitle = extras.getString(BUNDLE_DOWNLOADS_TITLE); + if (downloadsTitle == null || Objects.equals(downloadsTitle, "")) + downloadsTitle = "Downloads"; + downloadsUrl = extras.getString(BUNDLE_DOWNLOADS_URL); + if (downloadsUrl != null && !Objects.equals(downloadsUrl, "")) { + LinkTarget.Target target = LinkTarget.resolveLinkTarget(Uri.parse(downloadsUrl)); + if (!target.is(LinkTarget.Target.DOWNLOADS)) { + Report.e(TAG, "Bundle came with a non board url!\nUrl:\n" + downloadsUrl); + Toast.makeText(this, "An error has occurred\nAborting.", Toast.LENGTH_SHORT).show(); + finish(); + } + } else downloadsUrl = downloadsIndexUrl; + + toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setTitle(downloadsTitle); + /*setSupportActionBar(toolbar); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + }*/ + + createDrawer(); + + progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); + + recyclerView = (RecyclerView) findViewById(R.id.downloads_recycler_view); + recyclerView.setHasFixedSize(true); + final LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); + recyclerView.setLayoutManager(layoutManager); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), + layoutManager.getOrientation()); + recyclerView.addItemDecoration(dividerItemDecoration); + downloadsAdapter = new DownloadsAdapter(getApplicationContext(), parsedDownloads); + recyclerView.setAdapter(downloadsAdapter); + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + totalItemCount = layoutManager.getItemCount(); + lastVisibleItem = layoutManager.findLastVisibleItemPosition(); + + if (!isLoadingMore && totalItemCount <= (lastVisibleItem + visibleThreshold)) { + isLoadingMore = true; + onLoadMore(); + } + } + }); + + uploadFAB = (FloatingActionButton) findViewById(R.id.download_fab); + uploadFAB.setEnabled(false); + + parseDownloadPageTask = new ParseDownloadPageTask(); + parseDownloadPageTask.execute(downloadsUrl); + } + + @Override + public void onLoadMore() { + if (pagesLoaded < numberOfPages) { + parsedDownloads.add(null); + downloadsAdapter.notifyItemInserted(parsedDownloads.size()); + + //Load data + parseDownloadPageTask = new ParseDownloadPageTask(); + if (downloadsUrl.contains("tpstart")) + parseDownloadPageTask.execute(downloadsUrl.substring(0 + , downloadsUrl.lastIndexOf(";tpstart=")) + ";tpstart=" + pagesLoaded * 10); + else parseDownloadPageTask.execute(downloadsUrl + ";tpstart=" + pagesLoaded * 10); + } + } + + @Override + public void onBackPressed() { + if (drawer.isDrawerOpen()) { + drawer.closeDrawer(); + return; + } + super.onBackPressed(); + } + + @Override + protected void onResume() { + drawer.setSelection(-1); + super.onResume(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + recyclerView.setAdapter(null); + if (parseDownloadPageTask != null && parseDownloadPageTask.getStatus() != AsyncTask.Status.RUNNING) + parseDownloadPageTask.cancel(true); + } + + /** + * An {@link AsyncTask} that handles asynchronous fetching of a downloads page and parsing it's + * data. {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link RecyclerView#swapAdapter} + * to build graphics. + *

    + *

    Calling TopicTask's {@link AsyncTask#execute execute} method needs to have profile's url + * as String parameter!

    + */ + class ParseDownloadPageTask extends AsyncTask { + /** + * Debug Tag for logging debug output to LogCat + */ + private static final String TAG = "ParseDownloadPageTask"; //Separate tag for AsyncTask + private String thisPageUrl; + + @Override + protected void onPreExecute() { + if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE); + if (uploadFAB.getVisibility() != View.GONE) uploadFAB.setEnabled(false); + } + + @Override + protected Void doInBackground(String... downloadsUrl) { + thisPageUrl = downloadsUrl[0]; + Request request = new Request.Builder() + .url(downloadsUrl[0]) + .build(); + try { + Response response = BaseActivity.getClient().newCall(request).execute(); + parseDownloads(Jsoup.parse(response.body().string())); + } catch (SSLHandshakeException e) { + Report.w(TAG, "Certificate problem (please switch to unsafe connection)."); + } catch (Exception e) { + Report.e("TAG", "ERROR", e); + } + return null; + } + + @Override + protected void onPostExecute(Void voids) { + if (downloadsTitle == null || Objects.equals(downloadsTitle, "")) + toolbar.setTitle(downloadsTitle); + + ++pagesLoaded; + if (uploadFAB.getVisibility() != View.GONE) uploadFAB.setEnabled(true); + progressBar.setVisibility(ProgressBar.INVISIBLE); + downloadsAdapter.notifyDataSetChanged(); + isLoadingMore = false; + } + + private void parseDownloads(Document downloadPage) { + if (downloadsTitle == null || Objects.equals(downloadsTitle, "")) + downloadsTitle = downloadPage.select("div.nav>b>a.nav").last().text(); + + //Removes loading item + if (isLoadingMore) { + if (parsedDownloads.size() > 0) parsedDownloads.remove(parsedDownloads.size() - 1); + } + + Download.DownloadItemType type; + if (LinkTarget.resolveLinkTarget(Uri.parse(thisPageUrl)).is(LinkTarget. + Target.DOWNLOADS_CATEGORY)) type = Download.DownloadItemType.DOWNLOADS_CATEGORY; + else type = Download.DownloadItemType.DOWNLOADS_FILE; + + Elements pages = downloadPage.select("a.navPages"); + if (pages != null) { + for (Element page : pages) { + int pageNumber = Integer.parseInt(page.text()); + if (pageNumber > numberOfPages) numberOfPages = pageNumber; + } + } else numberOfPages = 1; + + Elements rows = downloadPage.select("table.tborder>tbody>tr"); + if (type == Download.DownloadItemType.DOWNLOADS_CATEGORY) { + Elements navigationLinks = downloadPage.select("div.nav>b"); + for (Element row : rows) { + if (row.select("td").size() == 1) continue; + + String url = row.select("b>a").first().attr("href"), + title = row.select("b>a").first().text(), + subtitle = row.select("div.smalltext:not(:has(a))").text(); + if (!row.select("td").last().hasClass("windowbg2")) { + if (navigationLinks.size() < 4) { + + parsedDownloads.add(new Download(type, url, title, subtitle, null, + true, null)); + } else { + String stats = row.text(); + stats = stats.replace(title, "").replace(subtitle, "").trim(); + parsedDownloads.add(new Download(type, url, title, subtitle, stats, + false, null)); + } + } else { + String stats = row.text(); + stats = stats.replace(title, "").replace(subtitle, "").trim(); + parsedDownloads.add(new Download(type, url, title, subtitle, stats, + false, null)); + } + } + } else { + parsedDownloads.add(new Download(type, + rows.select("b>a").first().attr("href"), + rows.select("b>a").first().text(), + rows.select("div.smalltext:not(:has(a))").text(), + rows.select("span:not(:has(a))").first().text(), + false, + rows.select("span:has(a)").first().html())); + } + } + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java new file mode 100644 index 00000000..8abfdf55 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java @@ -0,0 +1,181 @@ +package gr.thmmy.mthmmy.activities.downloads; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Typeface; +import android.os.Bundle; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Objects; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.model.Download; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; + +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_TITLE; +import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_URL; + +class DownloadsAdapter extends RecyclerView.Adapter { + /** + * Debug Tag for logging debug output to LogCat + */ + @SuppressWarnings("unused") + private static final String TAG = "DownloadsAdapter"; + private final int VIEW_TYPE_DOWNLOAD = 0; + private final int VIEW_TYPE_LOADING = 1; + + private final Context context; + private ArrayList parsedDownloads = new ArrayList<>(); + private final ArrayList downloadExpandableVisibility = new ArrayList<>(); + + DownloadsAdapter(Context context, ArrayList parsedDownloads) { + this.context = context; + this.parsedDownloads = parsedDownloads; + } + + interface OnLoadMoreListener { + void onLoadMore(); + } + + @Override + public int getItemViewType(int position) { + return (parsedDownloads.get(position) == null) ? VIEW_TYPE_LOADING : VIEW_TYPE_DOWNLOAD; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_DOWNLOAD) { + View download = LayoutInflater.from(parent.getContext()). + inflate(R.layout.activity_downloads_row, parent, false); + return new DownloadViewHolder(download); + } else if (viewType == VIEW_TYPE_LOADING) { + View loading = LayoutInflater.from(parent.getContext()). + inflate(R.layout.recycler_loading_item, parent, false); + return new LoadingViewHolder(loading); + } + return null; + } + + @Override + public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { + if (holder instanceof DownloadViewHolder) { + final Download download = parsedDownloads.get(position); + final DownloadViewHolder downloadViewHolder = (DownloadViewHolder) holder; + + if (downloadExpandableVisibility.size() != parsedDownloads.size()) { + for (int i = downloadExpandableVisibility.size(); i < parsedDownloads.size(); ++i) + downloadExpandableVisibility.add(false); + } + + if (download.getType() == Download.DownloadItemType.DOWNLOADS_CATEGORY) { + downloadViewHolder.downloadRow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(context, DownloadsActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_DOWNLOADS_URL, download.getUrl()); + extras.putString(BUNDLE_DOWNLOADS_TITLE, download.getTitle()); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + }); + + if (downloadExpandableVisibility.get(downloadViewHolder.getAdapterPosition())) { + downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); + downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up); + } else { + downloadViewHolder.informationExpandable.setVisibility(View.GONE); + downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down); + } + downloadViewHolder.informationExpandableBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + final boolean visible = downloadExpandableVisibility.get(downloadViewHolder. + getAdapterPosition()); + if (visible) { + downloadViewHolder.informationExpandable.setVisibility(View.GONE); + downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down); + } else { + downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); + downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up); + } + downloadExpandableVisibility.set(downloadViewHolder.getAdapterPosition(), !visible); + } + }); + downloadViewHolder.title.setTypeface(Typeface.createFromAsset(context.getAssets() + , "fonts/fontawesome-webfont.ttf")); + if (download.hasSubCategory()) { + String tmp = context.getResources().getString(R.string.fa_folder) + " " + + download.getTitle(); + downloadViewHolder.title.setText(tmp); + } else { + String tmp = context.getResources().getString(R.string.fa_file) + " " + + download.getTitle(); + downloadViewHolder.title.setText(tmp); + } + } else { + //TODO implement download on click + + downloadViewHolder.upperLinear.setBackgroundColor(context.getResources().getColor(R.color.background)); + downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); + downloadViewHolder.informationExpandableBtn.setVisibility(View.GONE); + downloadViewHolder.informationExpandableBtn.setEnabled(false); + downloadViewHolder.title.setText(download.getTitle()); + } + + downloadViewHolder.subTitle.setText(download.getSubTitle()); + String tmp = download.getExtraInfo(); + if (tmp != null && !Objects.equals(tmp, "")) + downloadViewHolder.extraInfo.setText(tmp); + else downloadViewHolder.extraInfo.setVisibility(View.GONE); + tmp = download.getStatNumbers(); + if (tmp != null && !Objects.equals(tmp, "")) + downloadViewHolder.uploaderDate.setText(tmp); + else downloadViewHolder.uploaderDate.setVisibility(View.GONE); + } else if (holder instanceof LoadingViewHolder) { + LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder; + loadingViewHolder.progressBar.setIndeterminate(true); + } + } + + @Override + public int getItemCount() { + return parsedDownloads.size(); + } + + private static class DownloadViewHolder extends RecyclerView.ViewHolder { + final LinearLayout upperLinear, downloadRow, informationExpandable; + final TextView title, subTitle, extraInfo, uploaderDate; + final ImageButton informationExpandableBtn; + + DownloadViewHolder(View download) { + super(download); + upperLinear = (LinearLayout) download.findViewById(R.id.upper_linear); + downloadRow = (LinearLayout) download.findViewById(R.id.download_row); + informationExpandable = (LinearLayout) download.findViewById(R.id.child_board_expandable); + title = (TextView) download.findViewById(R.id.download_title); + subTitle = (TextView) download.findViewById(R.id.download_sub_title); + extraInfo = (TextView) download.findViewById(R.id.download_extra_info); + uploaderDate = (TextView) download.findViewById(R.id.download_uploader_date); + informationExpandableBtn = (ImageButton) download.findViewById(R.id.download_information_button); + } + } + + private static class LoadingViewHolder extends RecyclerView.ViewHolder { + final MaterialProgressBar progressBar; + + LoadingViewHolder(View itemView) { + super(itemView); + progressBar = (MaterialProgressBar) itemView.findViewById(R.id.recycler_progress_bar); + } + } +} 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 789bcfe4..d99f7d65 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 @@ -248,11 +248,13 @@ public class StatsFragment extends Fragment { postingActivityByTimeChartXAxis.setGranularity(1f); LineDataSet postingActivityByTimeDataSet = new LineDataSet(postingActivityByTime, null); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - postingActivityByTimeDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_chart_gradient, null)); - } else - //noinspection deprecation - postingActivityByTimeDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_chart_gradient)); + if (isAdded()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + postingActivityByTimeDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_chart_gradient, null)); + } else + //noinspection deprecation + postingActivityByTimeDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_chart_gradient)); + } postingActivityByTimeDataSet.setDrawFilled(true); postingActivityByTimeDataSet.setDrawCircles(false); postingActivityByTimeDataSet.setDrawValues(false); @@ -285,11 +287,13 @@ public class StatsFragment extends Fragment { mostPopularBoardsByPostsChartYAxis.setGranularity(1f); BarDataSet mostPopularBoardsByPostsDataSet = new BarDataSet(mostPopularBoardsByPosts, null); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mostPopularBoardsByPostsDataSet.setColors(getResources().getColor(R.color.accent, null)); - } else - //noinspection deprecation - mostPopularBoardsByPostsDataSet.setColors(getResources().getColor(R.color.accent)); + if (isAdded()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mostPopularBoardsByPostsDataSet.setColors(getResources().getColor(R.color.accent, null)); + } else + //noinspection deprecation + mostPopularBoardsByPostsDataSet.setColors(getResources().getColor(R.color.accent)); + } mostPopularBoardsByPostsDataSet.setDrawValues(false); mostPopularBoardsByPostsDataSet.setValueTextColor(Color.WHITE); @@ -324,11 +328,13 @@ public class StatsFragment extends Fragment { mostPopularBoardsByActivityChartYAxis.setLabelCount(10, false); BarDataSet mostPopularBoardsByActivityDataSet = new BarDataSet(mostPopularBoardsByActivity, null); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mostPopularBoardsByActivityDataSet.setColors(getResources().getColor(R.color.accent, null)); - } else - //noinspection deprecation - mostPopularBoardsByActivityDataSet.setColors(getResources().getColor(R.color.accent)); + if (isAdded()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mostPopularBoardsByActivityDataSet.setColors(getResources().getColor(R.color.accent, null)); + } else + //noinspection deprecation + mostPopularBoardsByActivityDataSet.setColors(getResources().getColor(R.color.accent)); + } mostPopularBoardsByActivityDataSet.setDrawValues(false); mostPopularBoardsByActivityDataSet.setValueTextColor(Color.WHITE); 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 c621f295..97d7f1e8 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 @@ -187,11 +187,12 @@ public class SummaryFragment extends Fragment { } TextView entry = new TextView(this.getContext()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - entry.setTextColor(getResources().getColor(R.color.primary_text, null)); - } else { - //noinspection deprecation - entry.setTextColor(getResources().getColor(R.color.primary_text)); + if (isAdded()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + entry.setTextColor(getResources().getColor(R.color.primary_text, null)); + else + //noinspection deprecation + entry.setTextColor(getResources().getColor(R.color.primary_text)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY)); 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 3da819cb..b940cda7 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 @@ -9,7 +9,6 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; @@ -63,7 +62,6 @@ public class TopicActivity extends BaseActivity { */ public static final String BUNDLE_TOPIC_TITLE = "TOPIC_TITLE"; private static final int PERMISSIONS_REQUEST_CODE = 69; - static boolean readWriteAccepted; private static TopicTask topicTask; //About posts private TopicAdapter topicAdapter; @@ -213,7 +211,7 @@ public class TopicActivity extends BaseActivity { topicTask.cancel(true); } - @Override + /*@Override public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions , @NonNull int[] grantResults) { switch (permsRequestCode) { @@ -221,18 +219,20 @@ public class TopicActivity extends BaseActivity { readWriteAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; break; } - } + }*/ - private void requestPerms() { //Runtime permissions for devices with API >= 23 + boolean requestPerms() { //Runtime permissions request for devices with API >= 23 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; - checkSelfPermission(PERMISSIONS_STORAGE[0]); - checkSelfPermission(PERMISSIONS_STORAGE[1]); - requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); - } else readWriteAccepted = true; + if (checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED || + checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED) { + requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); + return false; + } else return true; + } else return true; } //--------------------------------------BOTTOM NAV BAR METHODS---------------------------------- @@ -365,6 +365,7 @@ public class TopicActivity extends BaseActivity { private static final int OTHER_ERROR = 2; private static final int SAME_PAGE = 3; + @Override protected void onPreExecute() { progressBar.setVisibility(ProgressBar.VISIBLE); paginationEnabled(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 05a2779f..ad96703d 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 @@ -243,7 +243,7 @@ class TopicAdapter extends RecyclerView.Adapter { attached.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (TopicActivity.readWriteAccepted) { + if (((TopicActivity) context).requestPerms()) { downloadTask = new DownloadTask(); downloadTask.execute(attachedFile); } else diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index 8760198d..1f893856 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -24,18 +24,20 @@ import com.mikepenz.materialdrawer.model.interfaces.IProfile; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.AboutActivity; import gr.thmmy.mthmmy.activities.LoginActivity; +import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.session.SessionManager; import okhttp3.OkHttpClient; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_TITLE; +import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; -public abstract class BaseActivity extends AppCompatActivity -{ +public abstract class BaseActivity extends AppCompatActivity { // Client & Cookies protected static OkHttpClient client; @@ -49,10 +51,10 @@ public abstract class BaseActivity extends AppCompatActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if(client==null) + if (client == null) client = BaseApplication.getInstance().getClient(); //must check every time - e.g. // they become null when app restarts after crash - if(sessionManager==null) + if (sessionManager == null) sessionManager = BaseApplication.getInstance().getSessionManager(); } @@ -65,27 +67,25 @@ public abstract class BaseActivity extends AppCompatActivity @Override protected void onPause() { super.onPause(); - if(drawer!=null) //close drawer animation after returning to activity + if (drawer != null) //close drawer animation after returning to activity drawer.closeDrawer(); } - public static OkHttpClient getClient() - { + public static OkHttpClient getClient() { return client; } - public static SessionManager getSessionManager() - { + public static SessionManager getSessionManager() { return sessionManager; } //TODO: move stuff below (?) //------------------------------------------DRAWER STUFF---------------------------------------- - protected static final int HOME_ID=0; - protected static final int DOWNLOADS_ID=1; - protected static final int LOG_ID =2; - protected static final int ABOUT_ID=3; + protected static final int HOME_ID = 0; + protected static final int DOWNLOADS_ID = 1; + protected static final int LOG_ID = 2; + protected static final int ABOUT_ID = 3; private AccountHeader accountHeader; private ProfileDrawerItem profileDrawerItem; @@ -96,42 +96,41 @@ public abstract class BaseActivity extends AppCompatActivity /** * Call only after initializing Toolbar */ - protected void createDrawer() - { + protected void createDrawer() { final int primaryColor = ContextCompat.getColor(this, R.color.iron); final int selectedPrimaryColor = ContextCompat.getColor(this, R.color.primary_dark); final int selectedSecondaryColor = ContextCompat.getColor(this, R.color.accent); //Drawer Icons - homeIcon =new IconicsDrawable(this) + homeIcon = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_home) .color(primaryColor); - homeIconSelected =new IconicsDrawable(this) + homeIconSelected = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_home) .color(selectedSecondaryColor); - downloadsIcon =new IconicsDrawable(this) + downloadsIcon = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_download) .color(primaryColor); - downloadsIconSelected =new IconicsDrawable(this) + downloadsIconSelected = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_download) .color(selectedSecondaryColor); - loginIcon =new IconicsDrawable(this) + loginIcon = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_sign_in) .color(primaryColor); - logoutIcon =new IconicsDrawable(this) + logoutIcon = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_sign_out) .color(primaryColor); - aboutIcon =new IconicsDrawable(this) + aboutIcon = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_info_circle) .color(primaryColor); - aboutIconSelected =new IconicsDrawable(this) + aboutIconSelected = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_info_circle) .color(selectedSecondaryColor); @@ -146,7 +145,6 @@ public abstract class BaseActivity extends AppCompatActivity .withSelectedIcon(homeIconSelected); - if (sessionManager.isLoggedIn()) //When logged in { loginLogoutItem = new PrimaryDrawerItem() @@ -164,8 +162,7 @@ public abstract class BaseActivity extends AppCompatActivity .withName(R.string.downloads) .withIcon(downloadsIcon) .withSelectedIcon(downloadsIconSelected); - } - else + } else loginLogoutItem = new PrimaryDrawerItem() .withTextColor(primaryColor) .withSelectedColor(selectedSecondaryColor) @@ -195,12 +192,11 @@ public abstract class BaseActivity extends AppCompatActivity .withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() { @Override public boolean onProfileChanged(View view, IProfile profile, boolean currentProfile) { - if(sessionManager.isLoggedIn()) - { + if (sessionManager.isLoggedIn()) { Intent intent = new Intent(BaseActivity.this, ProfileActivity.class); Bundle extras = new Bundle(); extras.putString(BUNDLE_PROFILE_URL, "https://www.thmmy.gr/smf/index.php?action=profile"); - if(!sessionManager.hasAvatar()) + if (!sessionManager.hasAvatar()) extras.putString(BUNDLE_THUMBNAIL_URL, ""); else extras.putString(BUNDLE_THUMBNAIL_URL, sessionManager.getAvatarLink()); @@ -220,44 +216,38 @@ public abstract class BaseActivity extends AppCompatActivity DrawerBuilder drawerBuilder = new DrawerBuilder() .withActivity(this) .withToolbar(toolbar) - .withDrawerWidthDp((int)BaseApplication.getInstance().getDpWidth()/2) + .withDrawerWidthDp((int) BaseApplication.getInstance().getDpWidth() / 2) .withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_light)) .withAccountHeader(accountHeader) .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { - if(drawerItem.equals(HOME_ID)) - { - if(!(BaseActivity.this instanceof MainActivity)) - { + if (drawerItem.equals(HOME_ID)) { + if (!(BaseActivity.this instanceof MainActivity)) { Intent i = new Intent(BaseActivity.this, MainActivity.class); startActivity(i); } - } -// else if(drawerItem.equals(DOWNLOADS_ID)) -// { -// if (sessionManager.isLoggedIn()) //When logged out or if user is guest -// { -// Intent i = new Intent(BaseActivity.this, DownloadsActivity.class); -// startActivity(i); -// } -// } - else if(drawerItem.equals(LOG_ID)) - { + } else if (drawerItem.equals(DOWNLOADS_ID)) { + if (sessionManager.isLoggedIn()) //When logged out or if user is guest + { + Intent i = new Intent(BaseActivity.this, DownloadsActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_DOWNLOADS_URL, ""); + extras.putString(BUNDLE_DOWNLOADS_TITLE, null); + i.putExtras(extras); + startActivity(i); + } + } else if (drawerItem.equals(LOG_ID)) { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest { Intent intent = new Intent(BaseActivity.this, LoginActivity.class); startActivity(intent); finish(); overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out); - } - else + } else new LogoutTask().execute(); - } - else if(drawerItem.equals(ABOUT_ID)) - { - if(!(BaseActivity.this instanceof AboutActivity)) - { + } else if (drawerItem.equals(ABOUT_ID)) { + if (!(BaseActivity.this instanceof AboutActivity)) { Intent i = new Intent(BaseActivity.this, AboutActivity.class); startActivity(i); } @@ -269,10 +259,10 @@ public abstract class BaseActivity extends AppCompatActivity } }); - if(sessionManager.isLoggedIn()) - drawerBuilder.addDrawerItems(homeItem,downloadsItem,loginLogoutItem,aboutItem); + if (sessionManager.isLoggedIn()) + drawerBuilder.addDrawerItems(homeItem, downloadsItem, loginLogoutItem, aboutItem); else - drawerBuilder.addDrawerItems(homeItem,loginLogoutItem,aboutItem); + drawerBuilder.addDrawerItems(homeItem, loginLogoutItem, aboutItem); drawer = drawerBuilder.build(); @@ -286,10 +276,8 @@ public abstract class BaseActivity extends AppCompatActivity }); } - protected void updateDrawer() - { - if(drawer!=null) - { + protected void updateDrawer() { + if (drawer != null) { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest { drawer.removeItem(DOWNLOADS_ID); @@ -299,9 +287,7 @@ public abstract class BaseActivity extends AppCompatActivity .paddingDp(10) .color(ContextCompat.getColor(this, R.color.primary_light)) .backgroundColor(ContextCompat.getColor(this, R.color.primary))); - } - else - { + } else { loginLogoutItem.withName(R.string.logout).withIcon(logoutIcon); //Swap login with logout profileDrawerItem.withName(sessionManager.getUsername()).withIcon(sessionManager.getAvatarLink()); } @@ -313,9 +299,10 @@ public abstract class BaseActivity extends AppCompatActivity //-------------------------------------------LOGOUT------------------------------------------------- + /** - * Result toast will always display a success, because when user chooses logout all data are - * cleared regardless of the actual outcome + * Result toast will always display a success, because when user chooses logout all data are + * cleared regardless of the actual outcome */ protected class LogoutTask extends AsyncTask { //Attempt logout ProgressDialog progressDialog; @@ -324,8 +311,7 @@ public abstract class BaseActivity extends AppCompatActivity return sessionManager.logout(); } - protected void onPreExecute() - { //Show a progress dialog until done + protected void onPreExecute() { //Show a progress dialog until done progressDialog = new ProgressDialog(BaseActivity.this, R.style.AppTheme_Dark_Dialog); progressDialog.setCancelable(false); @@ -334,8 +320,7 @@ public abstract class BaseActivity extends AppCompatActivity progressDialog.show(); } - protected void onPostExecute(Integer result) - { + protected void onPostExecute(Integer result) { Toast.makeText(getBaseContext(), "Logged out successfully!", Toast.LENGTH_LONG).show(); updateDrawer(); progressDialog.dismiss(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Download.java b/app/src/main/java/gr/thmmy/mthmmy/model/Download.java new file mode 100644 index 00000000..5216fea4 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Download.java @@ -0,0 +1,58 @@ +package gr.thmmy.mthmmy.model; + +public class Download { + public enum DownloadItemType {DOWNLOADS_CATEGORY, DOWNLOADS_FILE} + + private final String url, title, subTitle, statNumbers, extraInfo; + private final boolean hasSubCategory; + private final DownloadItemType type; + + public Download() { + type = null; + url = null; + title = null; + subTitle = null; + statNumbers = null; + hasSubCategory = false; + extraInfo = null; + } + + public Download(DownloadItemType type, String url, String title, String subTitle, + String statNumbers, boolean hasSubCategory, String extraInfo) { + this.type = type; + this.url = url; + this.title = title; + this.subTitle = subTitle; + this.statNumbers = statNumbers; + this.hasSubCategory = hasSubCategory; + this.extraInfo = extraInfo; + } + + public DownloadItemType getType() { + return type; + } + + public String getUrl() { + return url; + } + + public String getTitle() { + return title; + } + + public String getSubTitle() { + return subTitle; + } + + public String getStatNumbers() { + return statNumbers; + } + + public String getExtraInfo() { + return extraInfo; + } + + public boolean hasSubCategory() { + return hasSubCategory; + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java b/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java index 4a112d2a..991c79bb 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java @@ -72,7 +72,19 @@ public class LinkTarget { /** * Link points to a profile. */ - PROFILE; + PROFILE, + /** + * Link points to a download. + */ + DOWNLOADS_CATEGORY, + /** + * Link points to a download category. + */ + DOWNLOADS_FILE, + /** + * Link points to downloads. + */ + DOWNLOADS; /** * This method defines a custom equality check for {@link Target} enums. It does not check @@ -81,19 +93,23 @@ public class LinkTarget { * cases described below, false otherwise.

      *
    • (Everything but {@link #NOT_THMMY}).is({@link #THMMY}) returns true
    • *
    • {@link #PROFILE_SUMMARY}.is({@link #PROFILE}) returns true
    • - *
    • {@link #PROFILE_LATEST_POSTS}.is({@link #PROFILE}) returns true
    • - *
    • {@link #PROFILE_STATS}.is({@link #PROFILE}) returns true
    • *
    • {@link #PROFILE}.is({@link #PROFILE_SUMMARY}) returns false
    • + *
    • {@link #PROFILE_LATEST_POSTS}.is({@link #PROFILE}) returns true
    • *
    • {@link #PROFILE}.is({@link #PROFILE_LATEST_POSTS}) returns false
    • - *
    • {@link #PROFILE}.is({@link #PROFILE_STATS}) returns false
    + *
  • {@link #PROFILE_STATS}.is({@link #PROFILE}) returns true
  • + *
  • {@link #PROFILE}.is({@link #PROFILE_STATS}) returns false
  • + *
  • {@link #DOWNLOADS_CATEGORY}.is({@link #DOWNLOADS}) returns true
  • + *
  • {@link #DOWNLOADS}.is({@link #DOWNLOADS_CATEGORY}) returns false
  • + *
  • {@link #DOWNLOADS_FILE}.is({@link #DOWNLOADS}) returns true
  • + *
  • {@link #DOWNLOADS}.is({@link #DOWNLOADS_FILE}) returns false
* * @param other another Target * @return true if enums are equal, false otherwise */ public boolean is(Target other) { - return (this == PROFILE_LATEST_POSTS || - this == PROFILE_STATS || - this == PROFILE_SUMMARY) && other == PROFILE + return ((this == PROFILE_LATEST_POSTS || this == PROFILE_STATS || this == PROFILE_SUMMARY) + && other == PROFILE) + || ((this == DOWNLOADS_FILE || this == DOWNLOADS_CATEGORY) && other == DOWNLOADS) || (this != NOT_THMMY && other == THMMY) || this == other; } @@ -130,6 +146,10 @@ public class LinkTarget { else return Target.PROFILE_SUMMARY; } else if (uriString.contains("action=unread")) return Target.UNREAD_POSTS; + else if (uriString.contains("action=tpmod;dl=item")) + return Target.DOWNLOADS_FILE; + else if (uriString.contains("action=tpmod;dl")) + return Target.DOWNLOADS_CATEGORY; Report.v(TAG, "Unknown thmmy link found, link: " + uriString); return Target.UNKNOWN_THMMY; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java index 5de8cbc8..eed84689 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java @@ -164,7 +164,6 @@ public class ThmmyFile { request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); } catch (IllegalStateException e) { Report.d(TAG, "External directory not available!", e); - Log.d(TAG, "External directory not available!", e); throw e; } diff --git a/app/src/main/res/drawable/ic_file_upload.xml b/app/src/main/res/drawable/ic_file_upload.xml new file mode 100644 index 00000000..74f3b4ca --- /dev/null +++ b/app/src/main/res/drawable/ic_file_upload.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/src/main/res/layout/activity_downloads.xml b/app/src/main/res/layout/activity_downloads.xml new file mode 100644 index 00000000..3547d5ea --- /dev/null +++ b/app/src/main/res/layout/activity_downloads.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_downloads_row.xml b/app/src/main/res/layout/activity_downloads_row.xml new file mode 100644 index 00000000..f4fd93b5 --- /dev/null +++ b/app/src/main/res/layout/activity_downloads_row.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + \ 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 2b469a93..dccbf7e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -81,4 +81,5 @@ + From 1aec1d6cd9dc597ef0347f7618bf377eaee0c4aa Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 19 Jan 2017 22:47:06 +0200 Subject: [PATCH 08/26] DownloadsActivity Toolbar fix --- app/src/main/AndroidManifest.xml | 8 +++++++- .../mthmmy/activities/downloads/DownloadsActivity.java | 10 +++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b1e421d3..24b701c1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -63,7 +63,13 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.main.MainActivity"/> - + +
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 60d83b44..ced0db58 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 @@ -81,15 +81,15 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. } } else downloadsUrl = downloadsIndexUrl; + //Initialize toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle(downloadsTitle); - /*setSupportActionBar(toolbar); - if (getSupportActionBar() != null) { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setDisplayShowHomeEnabled(true); - }*/ + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); createDrawer(); +// drawer.setSelection(DOWNLOADS_ID); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); From a6b6c69666a05250f59a90c694fcf33a2ef401e8 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 19 Jan 2017 22:58:16 +0200 Subject: [PATCH 09/26] DownloadsActivity drawer fix --- .../thmmy/mthmmy/activities/downloads/DownloadsActivity.java | 4 ++-- app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 ced0db58..a249627a 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 @@ -89,7 +89,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. getSupportActionBar().setDisplayShowHomeEnabled(true); createDrawer(); -// drawer.setSelection(DOWNLOADS_ID); + drawer.setSelection(DOWNLOADS_ID); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); @@ -149,7 +149,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. @Override protected void onResume() { - drawer.setSelection(-1); + drawer.setSelection(DOWNLOADS_ID); super.onResume(); } 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 1f893856..814d2224 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -228,7 +228,7 @@ public abstract class BaseActivity extends AppCompatActivity { startActivity(i); } } else if (drawerItem.equals(DOWNLOADS_ID)) { - if (sessionManager.isLoggedIn()) //When logged out or if user is guest + if (!(BaseActivity.this instanceof DownloadsActivity)) //When logged out or if user is guest { Intent i = new Intent(BaseActivity.this, DownloadsActivity.class); Bundle extras = new Bundle(); From da30d1c471152a33d52423bde7f11be4363a84fb Mon Sep 17 00:00:00 2001 From: Apostolof Date: Thu, 19 Jan 2017 23:11:59 +0200 Subject: [PATCH 10/26] Hided floating action buttons. --- .../java/gr/thmmy/mthmmy/activities/board/BoardActivity.java | 5 +++-- .../thmmy/mthmmy/activities/downloads/DownloadsActivity.java | 1 + .../gr/thmmy/mthmmy/activities/profile/ProfileActivity.java | 5 +++-- .../java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java | 5 +++-- 4 files changed, 10 insertions(+), 6 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 734eafff..8abb4498 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 @@ -97,7 +97,8 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); newTopicFAB = (FloatingActionButton) findViewById(R.id.board_fab); newTopicFAB.setEnabled(false); - if (!sessionManager.isLoggedIn()) newTopicFAB.hide(); + newTopicFAB.hide(); + /*if (!sessionManager.isLoggedIn()) newTopicFAB.hide(); else { newTopicFAB.setOnClickListener(new View.OnClickListener() { @Override @@ -125,7 +126,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } } }); - } + }*/ boardAdapter = new BoardAdapter(getApplicationContext(), parsedSubBoards, parsedTopics); RecyclerView mainContent = (RecyclerView) findViewById(R.id.board_recycler_view); 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 a249627a..356d5024 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 @@ -118,6 +118,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. uploadFAB = (FloatingActionButton) findViewById(R.id.download_fab); uploadFAB.setEnabled(false); + uploadFAB.hide(); parseDownloadPageTask = new ParseDownloadPageTask(); parseDownloadPageTask.execute(downloadsUrl); 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 383323be..2e622f1f 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 @@ -135,7 +135,8 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment pmFAB = (FloatingActionButton) findViewById(R.id.profile_fab); pmFAB.setEnabled(false); - if (!sessionManager.isLoggedIn()) pmFAB.hide(); + pmFAB.hide(); + /*if (!sessionManager.isLoggedIn()) pmFAB.hide(); else { pmFAB.setOnClickListener(new View.OnClickListener() { @Override @@ -163,7 +164,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment } } }); - } + }*/ LinkTarget.Target target = LinkTarget.resolveLinkTarget(Uri.parse(profileUrl)); if (!target.is(LinkTarget.Target.PROFILE)) { 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 b940cda7..1c13c834 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 @@ -140,7 +140,8 @@ public class TopicActivity extends BaseActivity { replyFAB = (FloatingActionButton) findViewById(R.id.topic_fab); replyFAB.setEnabled(false); - if (!sessionManager.isLoggedIn()) replyFAB.hide(); + replyFAB.hide(); + /*if (!sessionManager.isLoggedIn()) replyFAB.hide(); else { replyFAB.setOnClickListener(new View.OnClickListener() { @Override @@ -168,7 +169,7 @@ public class TopicActivity extends BaseActivity { } } }); - } + }*/ //Sets bottom navigation bar firstPage = (ImageButton) findViewById(R.id.page_first_button); From c6afc057bcbd95ab24138dd7a8cdcdcdefaff11a Mon Sep 17 00:00:00 2001 From: Apostolof Date: Thu, 19 Jan 2017 23:52:59 +0200 Subject: [PATCH 11/26] Fix for Topic's RecyclerView mixing views --- .../mthmmy/activities/topic/TopicAdapter.java | 140 ++++++++++-------- 1 file changed, 81 insertions(+), 59 deletions(-) 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 ad96703d..711f7e55 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 @@ -259,67 +259,85 @@ class TopicAdapter extends RecyclerView.Adapter { holder.postFooter.removeAllViews(); } + String mSpecialRank, mRank, mGender, mNumberOfPosts, mPersonalText; + int mNumberOfStars, mUserColor; + if (!currentPost.isDeleted()) { //Sets user's extra info - String mSpecialRank = currentPost.getSpecialRank(), mRank = currentPost.getRank(), mGender = currentPost.getGender(), mNumberOfPosts = currentPost.getNumberOfPosts(), mPersonalText = currentPost.getPersonalText(); - int mNumberOfStars = currentPost.getNumberOfStars(), mUserColor = currentPost.getUserColor(); - - if (!Objects.equals(mSpecialRank, "") && mSpecialRank != null) { - holder.specialRank.setText(mSpecialRank); - holder.specialRank.setVisibility(View.VISIBLE); - } else - holder.specialRank.setVisibility(View.GONE); - if (!Objects.equals(mRank, "") && mRank != null) { - holder.rank.setText(mRank); - holder.rank.setVisibility(View.VISIBLE); - } else - holder.rank.setVisibility(View.GONE); - if (!Objects.equals(mGender, "") && mGender != null) { - holder.gender.setText(mGender); - holder.gender.setVisibility(View.VISIBLE); - } else - holder.gender.setVisibility(View.GONE); - if (!Objects.equals(mNumberOfPosts, "") && mNumberOfPosts != null) { - holder.numberOfPosts.setText(mNumberOfPosts); - holder.numberOfPosts.setVisibility(View.VISIBLE); - } else - holder.numberOfPosts.setVisibility(View.GONE); - if (!Objects.equals(mPersonalText, "") && mPersonalText != null) { - holder.personalText.setText("\"" + mPersonalText + "\""); - holder.personalText.setVisibility(View.VISIBLE); - } else - holder.personalText.setVisibility(View.GONE); - if (mNumberOfStars > 0) { - holder.stars.setTypeface(Typeface.createFromAsset(context.getAssets() - , "fonts/fontawesome-webfont.ttf")); + mSpecialRank = currentPost.getSpecialRank(); + mRank = currentPost.getRank(); + mGender = currentPost.getGender(); + mNumberOfPosts = currentPost.getNumberOfPosts(); + mPersonalText = currentPost.getPersonalText(); + mNumberOfStars = currentPost.getNumberOfStars(); + mUserColor = currentPost.getUserColor(); + } else { + mSpecialRank = null; + mRank = null; + mGender = null; + mNumberOfPosts = null; + mPersonalText = null; + mNumberOfStars = 0; + mUserColor = 0; + } - String aStar = context.getResources().getString(R.string.fa_icon_star); - String usersStars = ""; - for (int i = 0; i < mNumberOfStars; ++i) { - usersStars += aStar; - } - holder.stars.setText(usersStars); - holder.stars.setTextColor(mUserColor); - holder.stars.setVisibility(View.VISIBLE); - } else - holder.stars.setVisibility(View.GONE); - //Special card for special member of the month! - if (mUserColor == TopicParser.USER_COLOR_PINK) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - holder.cardChildLinear.setBackground(context.getResources(). - getDrawable(R.drawable.member_of_the_month_card, null)); - } else //noinspection deprecation - holder.cardChildLinear.setBackground(context.getResources(). - getDrawable(R.drawable.member_of_the_month_card)); - } else holder.cardChildLinear.setBackground(null); - - //Avoid's view's visibility recycling - if (viewProperties.get(position)[isUserExtraInfoVisibile]) { - holder.userExtraInfo.setVisibility(View.VISIBLE); - holder.userExtraInfo.setAlpha(1.0f); - } else { - holder.userExtraInfo.setVisibility(View.GONE); - holder.userExtraInfo.setAlpha(0.0f); + if (!Objects.equals(mSpecialRank, "") && mSpecialRank != null) { + holder.specialRank.setText(mSpecialRank); + holder.specialRank.setVisibility(View.VISIBLE); + } else + holder.specialRank.setVisibility(View.GONE); + if (!Objects.equals(mRank, "") && mRank != null) { + holder.rank.setText(mRank); + holder.rank.setVisibility(View.VISIBLE); + } else + holder.rank.setVisibility(View.GONE); + if (!Objects.equals(mGender, "") && mGender != null) { + holder.gender.setText(mGender); + holder.gender.setVisibility(View.VISIBLE); + } else + holder.gender.setVisibility(View.GONE); + if (!Objects.equals(mNumberOfPosts, "") && mNumberOfPosts != null) { + holder.numberOfPosts.setText(mNumberOfPosts); + holder.numberOfPosts.setVisibility(View.VISIBLE); + } else + holder.numberOfPosts.setVisibility(View.GONE); + if (!Objects.equals(mPersonalText, "") && mPersonalText != null) { + holder.personalText.setText("\"" + mPersonalText + "\""); + holder.personalText.setVisibility(View.VISIBLE); + } else + holder.personalText.setVisibility(View.GONE); + if (mNumberOfStars > 0) { + holder.stars.setTypeface(Typeface.createFromAsset(context.getAssets() + , "fonts/fontawesome-webfont.ttf")); + + String aStar = context.getResources().getString(R.string.fa_icon_star); + String usersStars = ""; + for (int i = 0; i < mNumberOfStars; ++i) { + usersStars += aStar; } + holder.stars.setText(usersStars); + holder.stars.setTextColor(mUserColor); + holder.stars.setVisibility(View.VISIBLE); + } else + holder.stars.setVisibility(View.GONE); + //Special card for special member of the month! + if (mUserColor == TopicParser.USER_COLOR_PINK) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + holder.cardChildLinear.setBackground(context.getResources(). + getDrawable(R.drawable.member_of_the_month_card, null)); + } else //noinspection deprecation + holder.cardChildLinear.setBackground(context.getResources(). + getDrawable(R.drawable.member_of_the_month_card)); + } else holder.cardChildLinear.setBackground(null); + + //Avoid's view's visibility recycling + if (!currentPost.isDeleted() && viewProperties.get(position)[isUserExtraInfoVisibile]) { + holder.userExtraInfo.setVisibility(View.VISIBLE); + holder.userExtraInfo.setAlpha(1.0f); + } else { + holder.userExtraInfo.setVisibility(View.GONE); + holder.userExtraInfo.setAlpha(0.0f); + } + if (!currentPost.isDeleted()) { //Sets graphics behavior holder.header.setOnClickListener(new View.OnClickListener() { @Override @@ -356,7 +374,11 @@ class TopicAdapter extends RecyclerView.Adapter { TopicAnimations.animateUserExtraInfoVisibility(v); } }); - }//End of deleted profiles + } else { + holder.header.setOnClickListener(null); + holder.userExtraInfo.setOnClickListener(null); + } + //Avoid's view's visibility recycling if (viewProperties.get(position)[isPostDateAndNumberVisibile]) { //Expanded holder.postDateAndNumberExp.setVisibility(View.VISIBLE); From 846aefc46b287c4a49e676cb91b08698ecc78dc5 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Fri, 20 Jan 2017 16:50:35 +0200 Subject: [PATCH 12/26] Fixes for file downloading, profile crashes, mixed views in topics, pageNav clicking. --- app/src/main/AndroidManifest.xml | 17 +++ .../profile/summary/SummaryFragment.java | 17 ++- .../activities/topic/TopicActivity.java | 131 ++++++++++++------ .../mthmmy/activities/topic/TopicAdapter.java | 21 ++- .../mthmmy/utils/FileManager/ThmmyFile.java | 29 ++-- app/src/main/res/xml/provider_paths.xml | 11 ++ 6 files changed, 156 insertions(+), 70 deletions(-) create mode 100644 app/src/main/res/xml/provider_paths.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 24b701c1..7b1efb2d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> + + + + + + + + + + + \ No newline at end of file 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 97d7f1e8..1236b5a0 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 @@ -82,7 +82,7 @@ public class SummaryFragment extends Fragment { Bundle savedInstanceState) { final View rootView = inflater.inflate(R.layout.fragment_summary, container, false); mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content); - if (!parsedProfileSummaryData.isEmpty()) + if (!parsedProfileSummaryData.isEmpty() && isAdded()) populateLayout(); return rootView; } @@ -126,7 +126,7 @@ public class SummaryFragment extends Fragment { } protected void onPostExecute(Void result) { - populateLayout(); + if (isAdded()) populateLayout(); } /** @@ -187,13 +187,12 @@ public class SummaryFragment extends Fragment { } TextView entry = new TextView(this.getContext()); - if (isAdded()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) - entry.setTextColor(getResources().getColor(R.color.primary_text, null)); - else - //noinspection deprecation - entry.setTextColor(getResources().getColor(R.color.primary_text)); - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + entry.setTextColor(getResources().getColor(R.color.primary_text, null)); + else + //noinspection deprecation + entry.setTextColor(getResources().getColor(R.color.primary_text)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY)); } else { 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 1c13c834..7ccf2abd 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 @@ -1,16 +1,14 @@ package gr.thmmy.mthmmy.activities.topic; import android.Manifest; -import android.content.DialogInterface; -import android.content.Intent; import android.content.pm.PackageManager; +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; -import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; @@ -30,7 +28,6 @@ import java.util.ArrayList; import java.util.Objects; import gr.thmmy.mthmmy.R; -import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.LinkTarget; import gr.thmmy.mthmmy.model.Post; @@ -237,6 +234,33 @@ public class TopicActivity extends BaseActivity { } //--------------------------------------BOTTOM NAV BAR METHODS---------------------------------- + + /** + * This class is used to implement the repetitive incrementPageRequestValue/decrementPageRequestValue + * of page value when long pressing one of the page navigation buttons. + */ + class RepetitiveUpdater implements Runnable { + private final int step; + + /** + * @param step number of pages to add/subtract on each repetition + */ + RepetitiveUpdater(int step) { + this.step = step; + } + + public void run() { + long REPEAT_DELAY = 250; + if (autoIncrement) { + incrementPageRequestValue(step); + repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY); + } else if (autoDecrement) { + decrementPageRequestValue(step); + repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY); + } + } + } + private void paginationEnabled(boolean enabled) { firstPage.setEnabled(enabled); previousPage.setEnabled(enabled); @@ -244,18 +268,38 @@ public class TopicActivity extends BaseActivity { lastPage.setEnabled(enabled); } + private void paginationEnabledExcept(boolean enabled, View exception) { + if (exception == firstPage) { + previousPage.setEnabled(enabled); + nextPage.setEnabled(enabled); + lastPage.setEnabled(enabled); + } else if (exception == previousPage) { + firstPage.setEnabled(enabled); + nextPage.setEnabled(enabled); + lastPage.setEnabled(enabled); + } else if (exception == nextPage) { + firstPage.setEnabled(enabled); + previousPage.setEnabled(enabled); + lastPage.setEnabled(enabled); + } else if (exception == lastPage) { + firstPage.setEnabled(enabled); + previousPage.setEnabled(enabled); + nextPage.setEnabled(enabled); + } else { + paginationEnabled(enabled); + } + } + private void initIncrementButton(ImageButton increment, final int step) { // Increment once for a click increment.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - if (!autoIncrement && step == LARGE_STEP) { //If just clicked go to last page + if (!autoIncrement && step == LARGE_STEP) { changePage(numberOfPages - 1); - return; + } else if (!autoIncrement) { + incrementPageRequestValue(step); + changePage(pageRequestValue - 1); } - //Clicked and holden - autoIncrement = false; //Stop incrementing - incrementPageRequestValue(step); - changePage(pageRequestValue - 1); } }); @@ -263,6 +307,7 @@ public class TopicActivity extends BaseActivity { increment.setOnLongClickListener( new View.OnLongClickListener() { public boolean onLongClick(View arg0) { + paginationEnabledExcept(false, arg0); autoIncrement = true; repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), INITIAL_DELAY); return false; @@ -272,9 +317,21 @@ public class TopicActivity extends BaseActivity { // When the button is released increment.setOnTouchListener(new View.OnTouchListener() { + private Rect rect; + public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); + } else if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement) { + autoIncrement = false; + paginationEnabled(true); changePage(pageRequestValue - 1); + } else if (event.getAction() == MotionEvent.ACTION_MOVE) { + if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { + autoIncrement = false; + decrementPageRequestValue(pageRequestValue - thisPage); + paginationEnabled(true); + } } return false; } @@ -285,22 +342,20 @@ public class TopicActivity extends BaseActivity { // Decrement once for a click decrement.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - if (!autoDecrement && step == LARGE_STEP) { //If just clicked go to first page + if (!autoDecrement && step == LARGE_STEP) { changePage(0); - return; + } else if (!autoDecrement) { + decrementPageRequestValue(step); + changePage(pageRequestValue - 1); } - //Clicked and hold - autoDecrement = false; //Stop decrementing - decrementPageRequestValue(step); - changePage(pageRequestValue - 1); } }); - // Auto decrement for a long click decrement.setOnLongClickListener( new View.OnLongClickListener() { public boolean onLongClick(View arg0) { + paginationEnabledExcept(false, arg0); autoDecrement = true; repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), INITIAL_DELAY); return false; @@ -310,9 +365,21 @@ public class TopicActivity extends BaseActivity { // When the button is released decrement.setOnTouchListener(new View.OnTouchListener() { + private Rect rect; + public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); + } else if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) { + autoDecrement = false; + paginationEnabled(true); changePage(pageRequestValue - 1); + } else if (event.getAction() == MotionEvent.ACTION_MOVE) { + if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { + autoIncrement = false; + incrementPageRequestValue(thisPage - pageRequestValue); + paginationEnabled(true); + } } return false; } @@ -496,30 +563,4 @@ public class TopicActivity extends BaseActivity { //postsList = TopicParser.parseTopic(topic, language); } } - - /** - * This class is used to implement the repetitive incrementPageRequestValue/decrementPageRequestValue - * of page value when long pressing one of the page navigation buttons. - */ - class RepetitiveUpdater implements Runnable { - private final int step; - - /** - * @param step number of pages to add/subtract on each repetition - */ - RepetitiveUpdater(int step) { - this.step = step; - } - - public void run() { - long REPEAT_DELAY = 250; - if (autoIncrement) { - incrementPageRequestValue(step); - repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY); - } else if (autoDecrement) { - decrementPageRequestValue(step); - repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY); - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index 711f7e55..8b4fa82d 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 @@ -11,6 +11,7 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.v4.content.FileProvider; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; @@ -229,6 +230,7 @@ class TopicAdapter extends RecyclerView.Adapter { } else //noinspection deprecation filesTextColor = context.getResources().getColor(R.color.accent); + holder.postFooter.removeAllViews(); for (final ThmmyFile attachedFile : currentPost.getAttachedFiles()) { final TextView attached = new TextView(context); attached.setTextSize(10f); @@ -243,12 +245,12 @@ class TopicAdapter extends RecyclerView.Adapter { attached.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (((TopicActivity) context).requestPerms()) { - downloadTask = new DownloadTask(); - downloadTask.execute(attachedFile); - } else - Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT) - .show(); + //if (((BaseApplication) context).requestPerms()) { + downloadTask = new DownloadTask(); + downloadTask.execute(attachedFile); + //} else + // Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT) + // .show(); } }); @@ -658,7 +660,12 @@ class TopicAdapter extends RecyclerView.Adapter { Intent intent = new Intent(); intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(tempFile), mime); + //intent.setDataAndType(Uri.fromFile(tempFile), mime); + + intent.setDataAndType(FileProvider.getUriForFile(context, context. + getApplicationContext() + .getPackageName() + ".provider", tempFile), mime); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java index eed84689..59d2816f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java @@ -10,7 +10,6 @@ import android.os.Environment; import android.os.StatFs; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; import android.webkit.MimeTypeMap; import android.widget.Toast; @@ -25,6 +24,7 @@ import mthmmy.utils.Report; import okhttp3.Request; import okhttp3.Response; +import static android.content.Context.MODE_PRIVATE; import static gr.thmmy.mthmmy.base.BaseActivity.getClient; /** @@ -41,6 +41,7 @@ public class ThmmyFile { private final String filename, fileInfo; private String extension, filePath; private File file; + private boolean isInternal; /** * This constructor only creates a empty ThmmyFile object and does not download the file. To download @@ -53,6 +54,7 @@ public class ThmmyFile { this.extension = null; this.filePath = null; this.file = null; + this.isInternal = false; } /** @@ -70,6 +72,7 @@ public class ThmmyFile { this.extension = null; this.filePath = null; this.file = null; + this.isInternal = false; } public URL getFileUrl() { @@ -122,6 +125,10 @@ public class ThmmyFile { this.filePath = filePath; } + public boolean isInternal() { + return isInternal; + } + /** * Used to download the file. If download is successful file's extension and path will be assigned * to object's fields and can be accessed using getter methods. @@ -143,12 +150,13 @@ public class ThmmyFile { else if (filename == null || Objects.equals(filename, "")) throw new IllegalStateException("Internal error!\nNo filename was provided."); - try { + return downloadWithoutManager(context, fileUrl); + /*try { downloadWithManager(context, fileUrl); } catch (IllegalStateException e) { return downloadWithoutManager(context, fileUrl); - } - return null; + }*/ + //return null; } private void downloadWithManager(Context context, @NonNull URL pFileUrl) throws IllegalStateException, IOException { @@ -191,7 +199,11 @@ public class ThmmyFile { if (file == null) { Report.d(TAG, "Error creating media file, check storage permissions!"); } else { - FileOutputStream fos = new FileOutputStream(file); + FileOutputStream fos; + if (isInternal) + fos = context.openFileOutput(filename, MODE_PRIVATE); + else + fos = new FileOutputStream(file); fos.write(response.body().bytes()); fos.close(); @@ -209,11 +221,11 @@ public class ThmmyFile { String extState = Environment.getExternalStorageState(); if (Environment.isExternalStorageRemovable() && Objects.equals(extState, Environment.MEDIA_MOUNTED)) { - mediaStorageDir = new File(Environment.getExternalStorageDirectory() - + "/Android/data/gr.thmmy.mthmmy/" - + "Downloads/"); + mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment + .DIRECTORY_DOWNLOADS), fileName); } else { mediaStorageDir = new File(context.getFilesDir(), "Downloads"); + isInternal = true; } //Creates the storage directory if it does not exist @@ -224,7 +236,6 @@ public class ThmmyFile { } } - if (fileInfo != null) { if (fileInfo.contains("KB")) { float fileSize = Float.parseFloat(fileInfo diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml new file mode 100644 index 00000000..d056e2a0 --- /dev/null +++ b/app/src/main/res/xml/provider_paths.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file From e7e9ba9d7fbbfe9945e7a1f4622174bc95792c00 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Fri, 20 Jan 2017 22:06:11 +0200 Subject: [PATCH 13/26] Fixes for file downloading and login screen. --- app/src/main/AndroidManifest.xml | 6 ++- .../mthmmy/activities/topic/TopicAdapter.java | 40 +++++++++++----- app/src/main/res/layout/activity_login.xml | 48 ++++++++++--------- app/src/main/res/values/strings.xml | 1 - app/src/main/res/xml/provider_paths.xml | 1 - 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7b1efb2d..20248cb4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -31,9 +31,11 @@ + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar" + android:windowSoftInputMode="adjustPan"> { } @Override - protected String doInBackground(ThmmyFile... files) { + protected String doInBackground(ThmmyFile... file) { try { - File tempFile = files[0].download(context); + File tempFile = file[0].download(context); if (tempFile != null) { - String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension( - files[0].getExtension()); + if (file[0].isInternal()) { + String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension( + file[0].getExtension()); - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - //intent.setDataAndType(Uri.fromFile(tempFile), mime); + Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + //intent.setDataAndType(Uri.fromFile(tempFile), mime); - intent.setDataAndType(FileProvider.getUriForFile(context, context. - getApplicationContext() - .getPackageName() + ".provider", tempFile), mime); + intent.setDataAndType(FileProvider.getUriForFile(context, context. + getApplicationContext() + .getPackageName() + ".provider", tempFile), mime); - intent.setFlags(FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } else { + String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension( + file[0].getExtension()); + + Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + intent.setDataAndType(Uri.fromFile(tempFile), mime); + + /*intent.setDataAndType(FileProvider.getUriForFile(context, context. + getApplicationContext() + .getPackageName() + ".provider", tempFile), mime);*/ + + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } } } catch (IOException e) { Report.e(TAG, "Error while trying to download a file", e); diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index b79c2503..52bdc281 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -1,7 +1,6 @@ + android:layout_height="match_parent" + android:fillViewport="true" + android:isScrollContainer="false"> + android:layout_height="0dp" + android:layout_weight="0.4"/> + android:layout_height="0dp" + android:layout_weight="0.45"/> + android:layout_height="wrap_content"> + + + + - + android:layout_height="0dp" + android:layout_weight="0.2"/> + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dccbf7e3..86d8cf67 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,7 +12,6 @@ Username Password LOGIN - - OR - Don\'t have an account? Continue as guest! diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml index d056e2a0..a0b81b43 100644 --- a/app/src/main/res/xml/provider_paths.xml +++ b/app/src/main/res/xml/provider_paths.xml @@ -4,7 +4,6 @@ name="my_downloads" path="Downloads/"/> - From a78a4320889e6febc7e2595478034290b047e372 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 21 Jan 2017 02:44:38 +0200 Subject: [PATCH 14/26] Bookmarks init and fixes. --- app/src/main/AndroidManifest.xml | 15 +- .../mthmmy/activities/BookmarkActivity.java | 62 +++++ .../activities/board/BoardActivity.java | 15 +- .../downloads/DownloadsActivity.java | 16 +- .../activities/profile/ProfileActivity.java | 13 +- .../activities/topic/TopicActivity.java | 38 ++- .../mthmmy/activities/topic/TopicAdapter.java | 10 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 227 +++++++++++++++++- .../java/gr/thmmy/mthmmy/model/Bookmark.java | 18 ++ .../model/{LinkTarget.java => ThmmyPage.java} | 47 ++-- .../thmmy/mthmmy/utils/ObjectSerializer.java | 69 ++++++ .../res/drawable-hdpi/ic_bookmark_false.png | Bin 0 -> 293 bytes .../res/drawable-hdpi/ic_bookmark_true.png | Bin 0 -> 230 bytes .../res/drawable-mdpi/ic_bookmark_false.png | Bin 0 -> 203 bytes .../res/drawable-mdpi/ic_bookmark_true.png | Bin 0 -> 161 bytes .../res/drawable-xhdpi/ic_bookmark_false.png | Bin 0 -> 336 bytes .../res/drawable-xhdpi/ic_bookmark_true.png | Bin 0 -> 261 bytes .../res/drawable-xxhdpi/ic_bookmark_false.png | Bin 0 -> 478 bytes .../res/drawable-xxhdpi/ic_bookmark_true.png | Bin 0 -> 362 bytes .../drawable-xxxhdpi/ic_bookmark_false.png | Bin 0 -> 620 bytes .../res/drawable-xxxhdpi/ic_bookmark_true.png | Bin 0 -> 473 bytes app/src/main/res/layout/activity_board.xml | 10 + app/src/main/res/layout/activity_bookmark.xml | 57 +++++ app/src/main/res/layout/activity_topic.xml | 10 + app/src/main/res/values/strings.xml | 7 +- 25 files changed, 541 insertions(+), 73 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java rename app/src/main/java/gr/thmmy/mthmmy/model/{LinkTarget.java => ThmmyPage.java} (77%) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java create mode 100644 app/src/main/res/drawable-hdpi/ic_bookmark_false.png create mode 100644 app/src/main/res/drawable-hdpi/ic_bookmark_true.png create mode 100644 app/src/main/res/drawable-mdpi/ic_bookmark_false.png create mode 100644 app/src/main/res/drawable-mdpi/ic_bookmark_true.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_bookmark_false.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_bookmark_true.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_bookmark_false.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_bookmark_true.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_bookmark_false.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_bookmark_true.png create mode 100644 app/src/main/res/layout/activity_bookmark.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 20248cb4..a2dfc7ee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,7 +15,6 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - - - - - - - + + + toQuoteList = new ArrayList<>(); //Topic's pages private int thisPage = 1; - public static String base_url = ""; private int numberOfPages = 1; private final SparseArray pagesUrls = new SparseArray<>(); //Page select @@ -88,9 +88,10 @@ public class TopicActivity extends BaseActivity { private ImageButton nextPage; private ImageButton lastPage; //Other variables + private FloatingActionButton replyFAB; private MaterialProgressBar progressBar; + public static String base_url = ""; private String topicTitle; - private FloatingActionButton replyFAB; private String parsedTitle; private RecyclerView recyclerView; private String loadedPageUrl = ""; @@ -104,10 +105,11 @@ public class TopicActivity extends BaseActivity { Bundle extras = getIntent().getExtras(); topicTitle = extras.getString(BUNDLE_TOPIC_TITLE); - LinkTarget.Target target = LinkTarget.resolveLinkTarget( - Uri.parse(extras.getString(BUNDLE_TOPIC_URL))); - if (!target.is(LinkTarget.Target.TOPIC)) { - Report.e(TAG, "Bundle came with a non topic url!\nUrl:\n" + extras.getString(BUNDLE_TOPIC_URL)); + String topicPageUrl = extras.getString(BUNDLE_TOPIC_URL); + ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory( + Uri.parse(topicPageUrl)); + if (!target.is(ThmmyPage.PageCategory.TOPIC)) { + Report.e(TAG, "Bundle came with a non topic url!\nUrl:\n" + topicPageUrl); Toast.makeText(this, "An error has occurred\n Aborting.", Toast.LENGTH_SHORT).show(); finish(); } @@ -121,6 +123,8 @@ public class TopicActivity extends BaseActivity { getSupportActionBar().setDisplayShowHomeEnabled(true); } + setTopicBookmark((ImageButton) findViewById(R.id.bookmark), + new Bookmark(topicTitle, ThmmyPage.getTopicId(topicPageUrl))); createDrawer(); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); @@ -458,14 +462,25 @@ public class TopicActivity extends BaseActivity { } //Checks if the page to be loaded is the one already shown - if (!Objects.equals(loadedPageUrl, "") && !loadedPageUrl.contains(base_url)) { + if (!Objects.equals(loadedPageUrl, "") && loadedPageUrl.contains(base_url)) { if (newPageUrl.contains("topicseen#new")) - if (Integer.parseInt(loadedPageUrl.substring(base_url.length())) == numberOfPages) + if (thisPage == numberOfPages) return SAME_PAGE; + if (newPageUrl.contains("msg")) { + String tmpUrlSbstr = newPageUrl.substring(newPageUrl.indexOf("msg") + 3); + if (tmpUrlSbstr.contains("msg")) + tmpUrlSbstr = tmpUrlSbstr.substring(0, tmpUrlSbstr.indexOf("msg") - 1); + int testAgainst = Integer.parseInt(tmpUrlSbstr); + for (Post post : postsList) { + if (post.getPostIndex() == testAgainst) { + return SAME_PAGE; + } + } + } if (Objects.equals(loadedPageUrl.substring(base_url.length()) , newPageUrl.substring(base_url.length()))) return SAME_PAGE; - } + } else topicTitle = null; loadedPageUrl = newPageUrl; Request request = new Request.Builder() @@ -496,6 +511,9 @@ public class TopicActivity extends BaseActivity { switch (parseResult) { case SUCCESS: + setTopicBookmark((ImageButton) findViewById(R.id.bookmark), + new Bookmark(parsedTitle, ThmmyPage.getTopicId(loadedPageUrl))); + progressBar.setVisibility(ProgressBar.INVISIBLE); topicAdapter.customNotifyDataSetChanged(new TopicTask()); if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(true); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index d93d09a5..9919719e 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 @@ -43,8 +43,8 @@ import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; -import gr.thmmy.mthmmy.model.LinkTarget; import gr.thmmy.mthmmy.model.Post; +import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CircleTransform; import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; @@ -552,8 +552,8 @@ class TopicAdapter extends RecyclerView.Adapter { private boolean handleUri(final Uri uri) { final String uriString = uri.toString(); - LinkTarget.Target target = LinkTarget.resolveLinkTarget(uri); - if (target.is(LinkTarget.Target.TOPIC)) { + ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(uri); + if (target.is(ThmmyPage.PageCategory.TOPIC)) { //This url points to a topic //Checks if this is the current topic if (Objects.equals(uriString.substring(0, uriString.lastIndexOf(".")), base_url)) { @@ -574,7 +574,7 @@ class TopicAdapter extends RecyclerView.Adapter { } topicTask.execute(uri.toString()); return true; - } else if (target.is(LinkTarget.Target.BOARD)) { + } else if (target.is(ThmmyPage.PageCategory.BOARD)) { Intent intent = new Intent(context, BoardActivity.class); Bundle extras = new Bundle(); extras.putString(BUNDLE_BOARD_URL, uriString); @@ -583,7 +583,7 @@ class TopicAdapter extends RecyclerView.Adapter { intent.setFlags(FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); return true; - } else if (target.is(LinkTarget.Target.PROFILE)) { + } else if (target.is(ThmmyPage.PageCategory.PROFILE)) { Intent intent = new Intent(context, ProfileActivity.class); Bundle extras = new Bundle(); extras.putString(BUNDLE_PROFILE_URL, uriString); 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 814d2224..5086e812 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -1,13 +1,18 @@ package gr.thmmy.mthmmy.base; import android.app.ProgressDialog; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; +import android.widget.ImageButton; import android.widget.Toast; import com.mikepenz.fontawesome_typeface_library.FontAwesome; @@ -21,13 +26,20 @@ import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IProfile; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Objects; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.AboutActivity; +import gr.thmmy.mthmmy.activities.BookmarkActivity; import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; +import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.session.SessionManager; +import gr.thmmy.mthmmy.utils.ObjectSerializer; import okhttp3.OkHttpClient; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -44,6 +56,16 @@ public abstract class BaseActivity extends AppCompatActivity { //SessionManager protected static SessionManager sessionManager; + //Bookmarks + private static final String BOOKMARKS_SHARED_PREFS = "bookmarksSharedPrefs"; + private static final String BOOKMARKED_TOPICS_KEY = "bookmarkedTopicsKey"; + private static final String BOOKMARKED_BOARDS_KEY = "bookmarkedBoardsKey"; + protected static SharedPreferences bookmarksFile; + protected static ArrayList topicsBookmarked; + protected static ArrayList boardsBookmarked; + protected static Drawable bookmarked; + protected static Drawable notBookmarked; + //Common UI elements protected Toolbar toolbar; protected Drawer drawer; @@ -56,6 +78,25 @@ public abstract class BaseActivity extends AppCompatActivity { // they become null when app restarts after crash 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(); + } + } } @Override @@ -84,14 +125,16 @@ public abstract class BaseActivity extends AppCompatActivity { //------------------------------------------DRAWER STUFF---------------------------------------- protected static final int HOME_ID = 0; protected static final int DOWNLOADS_ID = 1; - protected static final int LOG_ID = 2; - protected static final int ABOUT_ID = 3; + protected static final int BOOKMARKS_ID = 2; + protected static final int LOG_ID = 3; + protected static final int ABOUT_ID = 4; private AccountHeader accountHeader; private ProfileDrawerItem profileDrawerItem; - private PrimaryDrawerItem homeItem, downloadsItem, loginLogoutItem, aboutItem; - private IconicsDrawable homeIcon, homeIconSelected, downloadsIcon, downloadsIconSelected, loginIcon, logoutIcon, - aboutIcon, aboutIconSelected; + private PrimaryDrawerItem homeItem, downloadsItem, bookmarksItem, loginLogoutItem, aboutItem; + private IconicsDrawable homeIcon, homeIconSelected, downloadsIcon, downloadsIconSelected, + bookmarksIcon, bookmarksIconSelected, loginIcon, logoutIcon, aboutIcon, + aboutIconSelected; /** * Call only after initializing Toolbar @@ -118,6 +161,14 @@ public abstract class BaseActivity extends AppCompatActivity { .icon(FontAwesome.Icon.faw_download) .color(selectedSecondaryColor); + bookmarksIcon = new IconicsDrawable(this) + .icon(FontAwesome.Icon.faw_bookmark) + .color(primaryColor); + + bookmarksIconSelected = new IconicsDrawable(this) + .icon(FontAwesome.Icon.faw_bookmark) + .color(selectedSecondaryColor); + loginIcon = new IconicsDrawable(this) .icon(FontAwesome.Icon.faw_sign_in) .color(primaryColor); @@ -162,6 +213,14 @@ 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) @@ -228,8 +287,7 @@ public abstract class BaseActivity extends AppCompatActivity { startActivity(i); } } else if (drawerItem.equals(DOWNLOADS_ID)) { - if (!(BaseActivity.this instanceof DownloadsActivity)) //When logged out or if user is guest - { + if (!(BaseActivity.this instanceof DownloadsActivity)) { Intent i = new Intent(BaseActivity.this, DownloadsActivity.class); Bundle extras = new Bundle(); extras.putString(BUNDLE_DOWNLOADS_URL, ""); @@ -237,6 +295,11 @@ public abstract class BaseActivity extends AppCompatActivity { i.putExtras(extras); startActivity(i); } + } else if (drawerItem.equals(BOOKMARKS_ID)) { + if (!(BaseActivity.this instanceof BookmarkActivity)) { + Intent i = new Intent(BaseActivity.this, BookmarkActivity.class); + startActivity(i); + } } else if (drawerItem.equals(LOG_ID)) { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest { @@ -260,7 +323,7 @@ public abstract class BaseActivity extends AppCompatActivity { }); if (sessionManager.isLoggedIn()) - drawerBuilder.addDrawerItems(homeItem, downloadsItem, loginLogoutItem, aboutItem); + drawerBuilder.addDrawerItems(homeItem, downloadsItem, bookmarksItem, loginLogoutItem, aboutItem); else drawerBuilder.addDrawerItems(homeItem, loginLogoutItem, aboutItem); @@ -298,7 +361,7 @@ public abstract class BaseActivity extends AppCompatActivity { } - //-------------------------------------------LOGOUT------------------------------------------------- +//-------------------------------------------LOGOUT------------------------------------------------- /** * Result toast will always display a success, because when user chooses logout all data are @@ -328,5 +391,151 @@ public abstract class BaseActivity extends AppCompatActivity { } //-----------------------------------------LOGOUT END----------------------------------------------- +//---------------------------------------------BOOKMARKS-------------------------------------------- + + protected ArrayList getBoardsBookmarked() { + return boardsBookmarked; + } + + protected ArrayList getTopicsBookmarked() { + return topicsBookmarked; + } + protected void setTopicBookmark(ImageButton bookmarkView, final Bookmark bookmark) { + if (matchExists(bookmark, topicsBookmarked)) { + bookmarkView.setImageDrawable(bookmarked); + } else { + bookmarkView.setImageDrawable(notBookmarked); + } + bookmarkView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (matchExists(bookmark, topicsBookmarked)) { + ((ImageButton) view).setImageDrawable(notBookmarked); + toggleTopicToBookmarks(bookmark); + Toast.makeText(BaseActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show(); + } else { + ((ImageButton) view).setImageDrawable(bookmarked); + toggleTopicToBookmarks(bookmark); + Toast.makeText(BaseActivity.this, "Bookmark added", Toast.LENGTH_SHORT).show(); + } + } + }); + } + + protected void setBoardBookmark(ImageButton bookmarkView, final Bookmark bookmark) { + if (matchExists(bookmark, boardsBookmarked)) { + bookmarkView.setImageDrawable(bookmarked); + } else { + bookmarkView.setImageDrawable(notBookmarked); + } + bookmarkView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (matchExists(bookmark, boardsBookmarked)) { + ((ImageButton) view).setImageDrawable(notBookmarked); + toggleBoardToBookmarks(bookmark); + Toast.makeText(BaseActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show(); + } else { + ((ImageButton) view).setImageDrawable(bookmarked); + toggleBoardToBookmarks(bookmark); + Toast.makeText(BaseActivity.this, "Bookmark added", Toast.LENGTH_SHORT).show(); + } + } + }); + } + + private void loadSavedBookmarks() { + String tmpString = bookmarksFile.getString(BOOKMARKED_TOPICS_KEY, null); + if (tmpString != null) + try { + topicsBookmarked = (ArrayList) ObjectSerializer.deserialize(tmpString); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + else { + topicsBookmarked = new ArrayList<>(); + topicsBookmarked.add(null); + } + + tmpString = bookmarksFile.getString(BOOKMARKED_BOARDS_KEY, null); + if (tmpString != null) + try { + boardsBookmarked = (ArrayList) ObjectSerializer.deserialize(tmpString); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + else { + boardsBookmarked = new ArrayList<>(); + boardsBookmarked.add(null); + } + } + + private void toggleBoardToBookmarks(Bookmark bookmark) { + if (boardsBookmarked == null) return; + if (matchExists(bookmark, boardsBookmarked)) { + if (boardsBookmarked.size() == 1) boardsBookmarked.set(0, null); + else boardsBookmarked.remove(findIndex(bookmark, boardsBookmarked)); + } else boardsBookmarked.add(bookmark); + updateBoardBookmarks(); + } + + private void toggleTopicToBookmarks(Bookmark bookmark) { + if (topicsBookmarked == null) return; + if (matchExists(bookmark, topicsBookmarked)) + topicsBookmarked.remove(findIndex(bookmark, topicsBookmarked)); + else topicsBookmarked.add(bookmark); + updateTopicBookmarks(); + } + + private void updateBoardBookmarks() { + String tmpString = null; + if (!(boardsBookmarked.size() == 1 && boardsBookmarked.get(0) == null)) { + try { + tmpString = ObjectSerializer.serialize(boardsBookmarked); + } catch (IOException e) { + e.printStackTrace(); + } + } + SharedPreferences.Editor editor = bookmarksFile.edit(); + editor.putString(BOOKMARKED_BOARDS_KEY, tmpString).apply(); + } + + private void updateTopicBookmarks() { + String tmpString = null; + if (!(topicsBookmarked.size() == 1 && topicsBookmarked.get(0) == null)) { + try { + tmpString = ObjectSerializer.serialize(topicsBookmarked); + } catch (IOException e) { + e.printStackTrace(); + } + } + SharedPreferences.Editor editor = bookmarksFile.edit(); + editor.putString(BOOKMARKED_TOPICS_KEY, tmpString).apply(); + } + + private boolean matchExists(Bookmark bookmark, ArrayList array) { + if (!array.isEmpty()) { + for (Bookmark b : array) { + if (b != null) { + return Objects.equals(b.getId(), bookmark.getId()) + && Objects.equals(b.getTitle(), bookmark.getTitle()); + } + } + } + return false; + } + + private int findIndex(Bookmark bookmark, ArrayList array) { + if (array.size() == 1 && array.get(0) == null) return -1; + if (!array.isEmpty()) { + for (int i = 0; i < array.size(); ++i) { + if (array.get(i) != null && Objects.equals(array.get(i).getId(), bookmark.getId()) + && Objects.equals(array.get(i).getTitle(), bookmark.getTitle())) + return i; + } + } + return -1; + } +//-------------------------------------------BOOKMARKS END------------------------------------------ } diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java new file mode 100644 index 00000000..88cc97d5 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java @@ -0,0 +1,18 @@ +package gr.thmmy.mthmmy.model; + +public class Bookmark { + private final String title, id; + + public Bookmark(String title, String id) { + this.title = title; + this.id = id; + } + + public String getTitle() { + return title; + } + + public String getId() { + return id; + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java similarity index 77% rename from app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java rename to app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java index 991c79bb..758f9765 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/LinkTarget.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java @@ -11,7 +11,7 @@ import mthmmy.utils.Report; * classes). It can be used to resolve link targets as to whether they are pointing to the forum and * where in the forum they may point. */ -public class LinkTarget { +public class ThmmyPage { /** * Debug Tag for logging debug output to LogCat */ @@ -32,7 +32,7 @@ public class LinkTarget { *
  • {@link #PROFILE}
  • * */ - public enum Target { + public enum PageCategory { /** * Link doesn't point to thmmy. */ @@ -87,7 +87,7 @@ public class LinkTarget { DOWNLOADS; /** - * This method defines a custom equality check for {@link Target} enums. It does not check + * This method defines a custom equality check for {@link PageCategory} enums. It does not check * whether a url is equal to another. *

    Method returns true if parameter's Target is the same as the object and in the specific * cases described below, false otherwise.

      @@ -106,7 +106,7 @@ public class LinkTarget { * @param other another Target * @return true if enums are equal, false otherwise */ - public boolean is(Target other) { + public boolean is(PageCategory other) { return ((this == PROFILE_LATEST_POSTS || this == PROFILE_STATS || this == PROFILE_SUMMARY) && other == PROFILE) || ((this == DOWNLOADS_FILE || this == DOWNLOADS_CATEGORY) && other == DOWNLOADS) @@ -122,7 +122,7 @@ public class LinkTarget { * @return true if url is pointing to thmmy, false otherwise */ public static boolean isThmmy(Uri uri) { - return resolveLinkTarget(uri) != Target.NOT_THMMY; + return resolvePageCategory(uri) != PageCategory.NOT_THMMY; } /** @@ -131,28 +131,43 @@ public class LinkTarget { * @param uri url to resolve * @return resolved target */ - public static Target resolveLinkTarget(Uri uri) { + public static PageCategory resolvePageCategory(Uri uri) { final String host = uri.getHost(); final String uriString = uri.toString(); if (Objects.equals(host, "www.thmmy.gr")) { - if (uriString.contains("topic=")) return Target.TOPIC; - else if (uriString.contains("board=")) return Target.BOARD; + if (uriString.contains("topic=")) return PageCategory.TOPIC; + else if (uriString.contains("board=")) return PageCategory.BOARD; else if (uriString.contains("action=profile")) { if (uriString.contains(";sa=showPosts")) - return Target.PROFILE_LATEST_POSTS; + return PageCategory.PROFILE_LATEST_POSTS; else if (uriString.contains(";sa=statPanel")) - return Target.PROFILE_STATS; - else return Target.PROFILE_SUMMARY; + return PageCategory.PROFILE_STATS; + else return PageCategory.PROFILE_SUMMARY; } else if (uriString.contains("action=unread")) - return Target.UNREAD_POSTS; + return PageCategory.UNREAD_POSTS; else if (uriString.contains("action=tpmod;dl=item")) - return Target.DOWNLOADS_FILE; + return PageCategory.DOWNLOADS_FILE; else if (uriString.contains("action=tpmod;dl")) - return Target.DOWNLOADS_CATEGORY; + return PageCategory.DOWNLOADS_CATEGORY; Report.v(TAG, "Unknown thmmy link found, link: " + uriString); - return Target.UNKNOWN_THMMY; + return PageCategory.UNKNOWN_THMMY; } - return Target.NOT_THMMY; + return PageCategory.NOT_THMMY; + } + + public static String getBoardId(String boardUrl) { + if (resolvePageCategory(Uri.parse(boardUrl)) == PageCategory.BOARD) { + return boardUrl.substring(boardUrl.indexOf("board=") + 6, boardUrl.lastIndexOf(".")); + } + return null; + } + + public static String getTopicId(String topicUrl) { + if (resolvePageCategory(Uri.parse(topicUrl)) == PageCategory.TOPIC) { + String tmp = topicUrl.substring(topicUrl.indexOf("topic=") + 6); + return tmp.substring(0, tmp.indexOf(".")); + } + return null; } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java new file mode 100644 index 00000000..ce3dbda6 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java @@ -0,0 +1,69 @@ +package gr.thmmy.mthmmy.utils; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//copied from http://github.com/apache/pig/blob/89c2e8e76c68d0d0abe6a36b4e08ddc56979796f/src/org/apache/pig/impl/util/ObjectSerializer.java +//package org.apache.pig.impl.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +public class ObjectSerializer { + + public static String serialize(Serializable obj) throws IOException { + if (obj == null) return ""; + ByteArrayOutputStream serialObj = new ByteArrayOutputStream(); + ObjectOutputStream objStream = new ObjectOutputStream(serialObj); + objStream.writeObject(obj); + objStream.close(); + return encodeBytes(serialObj.toByteArray()); + } + + public static Object deserialize(String str) throws IOException, ClassNotFoundException { + if (str == null || str.length() == 0) return null; + ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str)); + ObjectInputStream objStream = new ObjectInputStream(serialObj); + return objStream.readObject(); + } + + public static String encodeBytes(byte[] bytes) { + StringBuffer strBuf = new StringBuffer(); + + for (int i = 0; i < bytes.length; i++) { + strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a'))); + strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a'))); + } + + return strBuf.toString(); + } + + public static byte[] decodeBytes(String str) { + byte[] bytes = new byte[str.length() / 2]; + for (int i = 0; i < str.length(); i += 2) { + char c = str.charAt(i); + bytes[i / 2] = (byte) ((c - 'a') << 4); + c = str.charAt(i + 1); + bytes[i / 2] += (c - 'a'); + } + return bytes; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_bookmark_false.png b/app/src/main/res/drawable-hdpi/ic_bookmark_false.png new file mode 100644 index 0000000000000000000000000000000000000000..afb6271f66ef5b49256dcf339099b3eedb33f809 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB-gvq=hE&{oJ7Xj7Ap-$dS(S)J zABSFz8%-Qp(;66gW;QUcaOld|?4)7LQX1C4wQs3&5o71cn~V#!z+P<9gLdewW z?N$ASE-&O;l_oIoUYeGpq5OzzW`oQf+ll6$rktvBsq@ZQINjpXl2F!OBXd^JYwdz5 zg^_cMT|8Rg=uT7Hk?XC;9&qG6;NmN}wlaWU=fKW1UsLHvbF!K_-yV>PvAZ$f_ib0z zUhchzdbF5>l@@Q_HBZ4w^v1rOCk(%a#&S$e;QYnc|EnR(`@Yk+h+F&G-xO|YQ8QtR jzyHoK_0)ZSL9S!Wd>?rDZ*SuR1qg$utDnm{r-UW|L-ul^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_bookmark_true.png b/app/src/main/res/drawable-hdpi/ic_bookmark_true.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6dd7a93d93ab29cba4acf530322173258dfd0e GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB)_S@)hE&{24v04EPBcht3uNbY zXE$WpC@*lGsgQZ*4!$fl<)wT~k{jeY{s(ieSAU}6#P@0OqU3}d(}mctUOM2ob&AD` zMmD}IiP8%zn%!hgUM&b@@3qRf;<%Vk3M9mK&e6WHf>U6&<42(t5_e_4$aK7JjF9P; z<6N=t`ImwVo(g?zNnuJ>Gjam9s;_*j@FYWVdv}k_ToKC?98#=TUhVdFI4dLjSE5wl btO0}c4zY{QvlhJsI-J4N)z4*}Q$iB}VyIHP literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_bookmark_false.png b/app/src/main/res/drawable-mdpi/ic_bookmark_false.png new file mode 100644 index 0000000000000000000000000000000000000000..7915747460f3186dd0f319bc24af296c57724b74 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjlRRA}12Sl57H%^<8cq2-H zyQaIKKqq}%XtzQZ1tjYn#fSBm-T?;OXk;vd$@?2>{{i BNvQw; literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_bookmark_true.png b/app/src/main/res/drawable-mdpi/ic_bookmark_true.png new file mode 100644 index 0000000000000000000000000000000000000000..06eba446284093c1eccf813132963f9da105a6f6 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj8J;eVAr-fh1ES5k8>h`kyb&e9 zaYVoIhyBDKq5{7sCoyWa9sb}Qr1QgHO>S$#m8L*$H(iNKVt-g3sXFAa9ra$2Boh5W zrsH*EgiN;-r$S!CD#e>klO1GukF0UI5|tCMRoy*ou8%1X!=i>H~atq literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_bookmark_false.png b/app/src/main/res/drawable-xhdpi/ic_bookmark_false.png new file mode 100644 index 0000000000000000000000000000000000000000..cded6d6083ea3e83cf4913acb10142b53c6be595 GIT binary patch literal 336 zcmV-W0k8gvP)aQm0pN^d@=MX>u0r>(n&=Q@HA8{A7Mon9QIyzW*@XwAq2pzy8hKGN*vH{q~ z2sqmS+&?yn`UB~ktgo}dg8%{uAb@~e1D*sBKmY**=`do%YT)(xEnKm2zKG$gwmFlBilD45{HFb}Anfk7ej z05_PS!V7W{5IATx?AE$+ChSJ~Ty~i&PQ6+C^t;&vkp-0ZsU_z&tfp!=tb%k_BX-r>mdKI;Vst07~s- AhyVZp literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_bookmark_false.png b/app/src/main/res/drawable-xxhdpi/ic_bookmark_false.png new file mode 100644 index 0000000000000000000000000000000000000000..a837b04d311ada9e64097ac3831e7805f12b9ff6 GIT binary patch literal 478 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U|j0y;uunK>+S8mUWWr@+CDl3 zzP#oen7)_!rRWRZ9bcJbTuKVB`Q{(sJLkHGN#9YxHSoo{$=yv0I)ZX*n3qQ^>GUm{ zG`T;$Vw#D3yZql^F3YV;CqI^AWoL3=U}O;h5doW)U7fZoVEw7$EA6|2th3bg9X`K0 zrsx$=o^{Z4!vC{7&nceU5WU$g-C?%nG0AOjgbkZ3)hf~8>oS{5{~uzqU1e)({p?c>+djZ+e;H`kk;{PC3S#4(AbhIQu} zFG(oRe*BzAquX$kVOoab;k%F)(<#`njxgN@xNAx>CZ} literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_bookmark_true.png b/app/src/main/res/drawable-xxhdpi/ic_bookmark_true.png new file mode 100644 index 0000000000000000000000000000000000000000..0253be0232aad62dda91a5524c7decb52c0bea2d GIT binary patch literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U^Mh}aSW-r_4c+e-@yQpwnSl_ zMuY7vvtJ6i++cidkf-CS)UtsyxYNZWVEM`1qy?Ae-<}s;%l_Ww&r{F+4>NhDb+a91 zXL4X*WDx)n0sEpZMMQavYX-bh%U!ziN*U`4^|zvdkF30Ea~FI#dDF5(xYXc(AaBMK z1HUUS!Wp5A3wqTq>|}BX_g&!5+Q8(yKpk!t*gye?rObO7m^c&~kO(bV4F*&Zkb*3( zlIb;>8K2H(Z)LagG+z1n>F(W^?(A7!=J4?56m?T!xib~djO%&7ST0_(e|l-1AM@W? zf!8jbJMX!`#Q0S4`e`Y3=NN9z2o(Gr%&wK>X7+qJTgb7VoHPBK3*J3r1iL_~fnn2a Z>HR5DD|dIF6$FMMgQu&X%Q~loCIF3yg027n literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_bookmark_false.png b/app/src/main/res/drawable-xxxhdpi/ic_bookmark_false.png new file mode 100644 index 0000000000000000000000000000000000000000..d65bb47d00bc840daf64d5d7ae0f6ba26138201a GIT binary patch literal 620 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U^4b}aSW-r_4dw2Z>B(*1BIMj zF?W_62+iZ%r1^*WPImq~{tW)CEPV~<6`rs7U+}NEYTBMrkXLw8_3V{8cK;5Iz1Ht- z-|zh{yHBCy-rjQgAB_U~;&)7ow(P0kWMFVWMtzKLJW5}NN_kA~F%QV*y&khsG9fn0 zBbhtySAA>t{;=weTnaHC79Z9BSMI+{poB5T^2?{?S92L}Y^r&4M#^1On&F&m&Cknv zxeOI$5)Y2DHI%nA{xW0u@;pcBwSAwO+V%Cx%*;TKA;1Ca27d$($N~x|q6j>YJs^%Q zz=0z0fiHmvC?IjeA(Zg)RB3aLX{`p=tFiYX+Si zjZGygrAgsOv&(*Jz9viB6jnfngDRUIFql{}S8-_Lr@P-s43 zI^WW=gm+I?Z>vhXm)sjTC*&}@yLECEyBDgWVKe6lUeH&mYClGXj4nr~Ol zYTQ}8axYuOWWOc7_VadY&Rvzw;IVUBiNad9ihr|qZDVz)N>+OrRnnvWoH4C;=8~nB z^X9O27^h8|cC4a^OQF{=xyr_paY6E#8B+dX%rhj6cO9Qx%5Yl7*y`A1Q-(+>U|ito;uunK>+M}bKPE?swnV93 z^9#ZkA`+ga+VsR7bTYhhBs;@9JK3gjtL%cN%_lEOsCuPM|C>Jl(Oa{diSwRlPe1sf z&gjCwB2ESd4xn)i3JeS^3=Le&7T&$V`YTe8oAoIUx`^}soKiW2JioCU%e^+ zn$O7^Ap1k{!_oTp8#P;&G30UY`s4dpgJJo>^z_>@y-Ex*;uSw<=P5DRi1K`pVSKPQ zp`ntcq4FTZYYql(pzGn_3ts}zYB*@P$GC?X&SPL$P|hHa#ASFPdq5qTU&X$G35oCU zp5YpZ8(`+})wV11)t)@7ocGeAd)X>{W0&>SSG@OpwW^NI;aS?s?kfl7@6|`xTQg6{ zPb;(a7XBP!b70%dn_K664$(PKpO$vL=uB`RgJs&Xx0PB<3p!_JX3ukC-ePF%dp_8r zq4u1Q@MjUW1>VM!i|1MKUwAt6q@n-66Kj{m0A0hx-~bKG1!BLMtY$7`tSWGl0XfUl L)z4*}Q$iB}OaGl` literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_board.xml b/app/src/main/res/layout/activity_board.xml index 4c0684f7..5d3d7a3d 100644 --- a/app/src/main/res/layout/activity_board.xml +++ b/app/src/main/res/layout/activity_board.xml @@ -22,6 +22,16 @@ android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/ToolbarTheme"> + + diff --git a/app/src/main/res/layout/activity_bookmark.xml b/app/src/main/res/layout/activity_bookmark.xml new file mode 100644 index 00000000..b2fa6e33 --- /dev/null +++ b/app/src/main/res/layout/activity_bookmark.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index 8d2993ef..d7de516f 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -22,6 +22,16 @@ android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/ToolbarTheme"> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86d8cf67..06d28a45 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,7 +5,10 @@ Login Authenticating… Logout + Downloads + About Home + Bookmarks thmmy.gr @@ -50,11 +53,7 @@ Most Popular Boards By Posts Most Popular Boards By Activity - - Downloads - - About v%1$s Logo You should watch a funny pic! From 8d45d91aff52bd8dce24c7d64654da47f718f357 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 21 Jan 2017 14:03:17 +0200 Subject: [PATCH 15/26] Fixed link handling and navBar buttons crashing the ap, added ripple effect to all clickable items. --- .../activities/topic/TopicActivity.java | 16 ++- .../mthmmy/activities/topic/TopicAdapter.java | 5 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 2 +- .../res/layout/activity_board_sub_board.xml | 124 ++++++++++-------- .../main/res/layout/activity_board_topic.xml | 124 ++++++++++-------- .../res/layout/activity_downloads_row.xml | 93 +++++++------ app/src/main/res/layout/activity_topic.xml | 4 + .../res/layout/fragment_latest_posts_row.xml | 90 +++++++------ app/src/main/res/values/styles.xml | 2 - 9 files changed, 249 insertions(+), 211 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java index 24ccb3b7..6c670797 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 @@ -326,11 +326,11 @@ public class TopicActivity extends BaseActivity { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); - } else if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement) { + } else if (rect != null && event.getAction() == MotionEvent.ACTION_UP && autoIncrement) { autoIncrement = false; paginationEnabled(true); changePage(pageRequestValue - 1); - } else if (event.getAction() == MotionEvent.ACTION_MOVE) { + } else if (rect != null && event.getAction() == MotionEvent.ACTION_MOVE) { if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { autoIncrement = false; decrementPageRequestValue(pageRequestValue - thisPage); @@ -446,7 +446,7 @@ public class TopicActivity extends BaseActivity { protected Integer doInBackground(String... strings) { Document document; - base_url = strings[0].substring(0, strings[0].lastIndexOf(".")); //This topic's base url + base_url = strings[0].substring(0, strings[0].lastIndexOf(".")); //New topic's base url String newPageUrl = strings[0]; //Finds the index of message focus if present @@ -456,7 +456,7 @@ public class TopicActivity extends BaseActivity { String tmp = newPageUrl.substring(newPageUrl.indexOf("msg") + 3); if (tmp.contains(";")) postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf(";"))); - else + else if (tmp.contains("#")) postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf("#"))); } } @@ -477,8 +477,7 @@ public class TopicActivity extends BaseActivity { } } } - if (Objects.equals(loadedPageUrl.substring(base_url.length()) - , newPageUrl.substring(base_url.length()))) + if (Integer.parseInt(newPageUrl.substring(base_url.length() + 1)) / 15 + 1 == thisPage) return SAME_PAGE; } else topicTitle = null; @@ -531,6 +530,11 @@ public class TopicActivity extends BaseActivity { Toast.makeText(getBaseContext(), "Network Error", Toast.LENGTH_SHORT).show(); break; case SAME_PAGE: + progressBar.setVisibility(ProgressBar.INVISIBLE); + topicAdapter.customNotifyDataSetChanged(new TopicTask()); + if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(true); + paginationEnabled(true); + Toast.makeText(TopicActivity.this, "That's the same page.", Toast.LENGTH_SHORT).show(); //TODO change focus break; default: 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 9919719e..ceb363f5 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 @@ -556,7 +556,7 @@ class TopicAdapter extends RecyclerView.Adapter { if (target.is(ThmmyPage.PageCategory.TOPIC)) { //This url points to a topic //Checks if this is the current topic - if (Objects.equals(uriString.substring(0, uriString.lastIndexOf(".")), base_url)) { + /*if (Objects.equals(uriString.substring(0, uriString.lastIndexOf(".")), base_url)) { //Gets uri's targeted message's index number String msgIndexReq = uriString.substring(uriString.indexOf("msg") + 3); if (msgIndexReq.contains("#")) @@ -571,7 +571,8 @@ class TopicAdapter extends RecyclerView.Adapter { return true; } } - } + }*/ + topicTask.execute(uri.toString()); return true; } else if (target.is(ThmmyPage.PageCategory.BOARD)) { 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 5086e812..1d323135 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -515,7 +515,7 @@ public abstract class BaseActivity extends AppCompatActivity { } private boolean matchExists(Bookmark bookmark, ArrayList array) { - if (!array.isEmpty()) { + if (array != null && !array.isEmpty()) { for (Bookmark b : array) { if (b != null) { return Objects.equals(b.getId(), bookmark.getId()) diff --git a/app/src/main/res/layout/activity_board_sub_board.xml b/app/src/main/res/layout/activity_board_sub_board.xml index b78a9c07..3dcd5d6e 100644 --- a/app/src/main/res/layout/activity_board_sub_board.xml +++ b/app/src/main/res/layout/activity_board_sub_board.xml @@ -1,79 +1,87 @@ + android:orientation="vertical"> + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:orientation="vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp"> - + android:layout_marginBottom="5dp" + android:layout_marginTop="5dp" + android:orientation="horizontal"> - - + - + + - + android:layout_marginBottom="5dp" + android:orientation="vertical" + android:visibility="gone"> - + - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_board_topic.xml b/app/src/main/res/layout/activity_board_topic.xml index a036f151..7ce361e5 100644 --- a/app/src/main/res/layout/activity_board_topic.xml +++ b/app/src/main/res/layout/activity_board_topic.xml @@ -1,77 +1,85 @@ + android:orientation="vertical"> + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:orientation="vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp"> - + android:layout_marginBottom="5dp" + android:layout_marginTop="5dp" + android:orientation="horizontal"> - - + - + + - + android:layout_marginBottom="5dp" + android:orientation="vertical" + android:visibility="gone"> - + - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_downloads_row.xml b/app/src/main/res/layout/activity_downloads_row.xml index f4fd93b5..3206e64f 100644 --- a/app/src/main/res/layout/activity_downloads_row.xml +++ b/app/src/main/res/layout/activity_downloads_row.xml @@ -5,61 +5,70 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/card_background" - android:orientation="vertical" - android:paddingEnd="16dp" - android:paddingStart="16dp"> + android:orientation="vertical"> + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:orientation="vertical" + android:paddingEnd="16dp" + android:paddingStart="16dp"> - + android:layout_marginBottom="5dp" + android:layout_marginTop="5dp" + android:orientation="horizontal"> - - + - + + - + android:layout_marginBottom="5dp" + android:orientation="vertical" + android:visibility="gone"> - + - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index d7de516f..23b12737 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -60,6 +60,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0.8" + android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/button_first" app:srcCompat="@drawable/page_first"/> @@ -68,6 +69,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0.8" + android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/button_previous" app:srcCompat="@drawable/page_previous"/> @@ -88,6 +90,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0.8" + android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/button_next" app:srcCompat="@drawable/page_next"/> @@ -96,6 +99,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0.8" + android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/button_last" app:srcCompat="@drawable/page_last"/> diff --git a/app/src/main/res/layout/fragment_latest_posts_row.xml b/app/src/main/res/layout/fragment_latest_posts_row.xml index 82d5b60d..cad4d1cb 100644 --- a/app/src/main/res/layout/fragment_latest_posts_row.xml +++ b/app/src/main/res/layout/fragment_latest_posts_row.xml @@ -1,55 +1,61 @@ - + android:background="@color/card_background"> - + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:paddingBottom="6dp" + android:paddingLeft="10dp" + android:paddingRight="10dp" + android:paddingTop="6dp"> - + + - - + - - - \ No newline at end of file + android:layout_height="match_parent" + android:layout_alignParentStart="true" + android:layout_below="@+id/spacer_divider"> + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 98df4222..3f32d79c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -42,6 +42,4 @@ @color/primary_text @color/dialog_bg_semi_transparent - - From eb04389f95e139988f680b1b36a6199df370ba5c Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 21 Jan 2017 19:02:35 +0200 Subject: [PATCH 16/26] Download service init --- app/src/main/AndroidManifest.xml | 36 ++++--- .../activities/topic/TopicActivity.java | 31 +----- .../mthmmy/activities/topic/TopicAdapter.java | 9 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 76 +++++++++++++ .../mthmmy/services/DownloadService.java | 100 ++++++++++++++++++ 5 files changed, 198 insertions(+), 54 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a2dfc7ee..67bf2e68 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ + package="gr.thmmy.mthmmy"> - - - - + + + + - + - + - + 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" /> + + \ No newline at end of file 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 6c670797..043a5a6c 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 @@ -1,11 +1,8 @@ package gr.thmmy.mthmmy.activities.topic; -import android.Manifest; -import android.content.pm.PackageManager; 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; @@ -59,7 +56,6 @@ public class TopicActivity extends BaseActivity { * The key to use when putting topic's title String to {@link TopicActivity}'s Bundle. */ public static final String BUNDLE_TOPIC_TITLE = "TOPIC_TITLE"; - private static final int PERMISSIONS_REQUEST_CODE = 69; private static TopicTask topicTask; //About posts private TopicAdapter topicAdapter; @@ -101,7 +97,6 @@ public class TopicActivity extends BaseActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_topic); - requestPerms(); Bundle extras = getIntent().getExtras(); topicTitle = extras.getString(BUNDLE_TOPIC_TITLE); @@ -135,7 +130,7 @@ public class TopicActivity extends BaseActivity { recyclerView.setHasFixedSize(true); LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); recyclerView.setLayoutManager(layoutManager); - topicAdapter = new TopicAdapter(getApplicationContext(), progressBar, postsList, + topicAdapter = new TopicAdapter(this, progressBar, postsList, topicTask); recyclerView.setAdapter(topicAdapter); @@ -213,30 +208,6 @@ public class TopicActivity extends BaseActivity { topicTask.cancel(true); } - /*@Override - public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions - , @NonNull int[] grantResults) { - switch (permsRequestCode) { - case PERMISSIONS_REQUEST_CODE: - readWriteAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; - break; - } - }*/ - - boolean requestPerms() { //Runtime permissions request for devices with API >= 23 - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { - String[] PERMISSIONS_STORAGE = { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE}; - - if (checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED || - checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED) { - requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); - return false; - } else return true; - } else return true; - } - //--------------------------------------BOTTOM NAV BAR METHODS---------------------------------- /** 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 ceb363f5..dd9cee02 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 @@ -43,6 +43,7 @@ import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CircleTransform; @@ -56,7 +57,6 @@ import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; -import static gr.thmmy.mthmmy.activities.topic.TopicActivity.base_url; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; /** @@ -245,12 +245,7 @@ class TopicAdapter extends RecyclerView.Adapter { attached.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - //if (((BaseApplication) context).requestPerms()) { - downloadTask = new DownloadTask(); - downloadTask.execute(attachedFile); - //} else - // Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT) - // .show(); + ((BaseActivity) context).launchDownloadService(attachedFile); } }); 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 1d323135..de2b5a7e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -1,13 +1,16 @@ package gr.thmmy.mthmmy.base; +import android.Manifest; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -38,7 +41,9 @@ import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.model.Bookmark; +import gr.thmmy.mthmmy.services.DownloadService; import gr.thmmy.mthmmy.session.SessionManager; +import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; import gr.thmmy.mthmmy.utils.ObjectSerializer; import okhttp3.OkHttpClient; @@ -48,6 +53,8 @@ import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWN import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; +import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_URL; public abstract class BaseActivity extends AppCompatActivity { // Client & Cookies @@ -79,6 +86,7 @@ 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) { @@ -538,4 +546,72 @@ public abstract class BaseActivity extends AppCompatActivity { return -1; } //-------------------------------------------BOOKMARKS END------------------------------------------ + + //-------PERMS--------- + private static final int PERMISSIONS_REQUEST_CODE = 69; + + //True if permissions are OK + private boolean checkPerms() { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + return !(checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED || + checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED); + } + return true; + } + + //Display popup gor user to grant permission + public void requestPerms() { //Runtime permissions request for devices with API >= 23 + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); + } + } + + + @Override + public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions + , @NonNull int[] grantResults) { + switch (permsRequestCode) { + case PERMISSIONS_REQUEST_CODE: + launchDownloadService(); + break; + } + } + + + //----------------------------------DOWNLOAD------------------ + private ThmmyFile tempThmmyFile; + public void launchDownloadService(ThmmyFile thmmyFile) { + if(checkPerms()) + { + Intent i = new Intent(this, DownloadService.class); + i.setAction(ACTION_DOWNLOAD); + i.putExtra(EXTRA_DOWNLOAD_URL, thmmyFile.getFileUrl().toString()); + startService(i); + } + else + { + tempThmmyFile = thmmyFile; + requestPerms(); + } + } + + //Uses temp file - called after permission grant + public void launchDownloadService() { + if(checkPerms()) + { + Intent i = new Intent(this, DownloadService.class); + i.setAction(ACTION_DOWNLOAD); + i.putExtra(EXTRA_DOWNLOAD_URL, tempThmmyFile.getFileUrl().toString()); + startService(i); + } + } + } diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java new file mode 100644 index 00000000..97d05b53 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -0,0 +1,100 @@ +package gr.thmmy.mthmmy.services; + +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.os.Environment; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import gr.thmmy.mthmmy.base.BaseApplication; +import mthmmy.utils.Report; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okio.BufferedSink; +import okio.Okio; + +/** + * An {@link IntentService} subclass for handling asynchronous task requests in + * a service on a separate handler thread. + */ +public class DownloadService extends IntentService { + private static final String TAG = "DownloadService"; + + public static final String ACTION_DOWNLOAD = "gr.thmmy.mthmmy.services.action.DOWNLOAD"; + public static final String EXTRA_DOWNLOAD_URL = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_URL"; + + public DownloadService() { + super("DownloadService"); + } + + /** + * Starts this service to perform action Download with the given parameters. If + * the service is already performing a task this action will be queued. + * + * @see IntentService + */ + public static void startActionDownload(Context context, String downloadUrl) { + Intent intent = new Intent(context, DownloadService.class); + intent.setAction(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_DOWNLOAD_URL, downloadUrl); + context.startService(intent); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (intent != null) { + final String action = intent.getAction(); + if (ACTION_DOWNLOAD.equals(action)) { + final String downloadLink = intent.getStringExtra(EXTRA_DOWNLOAD_URL); + handleActionDownload(downloadLink); + } + } + } + + /** + * Handle action Foo in the provided background thread with the provided + * parameters. + */ + private void handleActionDownload(String downloadLink) { + OkHttpClient client = BaseApplication.getInstance().getClient(); + BufferedSink sink = null; + try { + Request request = new Request.Builder().url(downloadLink).build(); + Response response = client.newCall(request).execute(); + + String filename = response.headers("Content-Disposition").toString().split("\"")[1]; + + File dirPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mthmmy"); + if(!dirPath.isDirectory()) + dirPath.mkdirs(); + + File file = new File(dirPath, filename); + + sink = Okio.buffer(Okio.sink(file)); + sink.writeAll(response.body().source()); + sink.flush(); + Report.i(TAG, "Download OK!"); + } + catch (FileNotFoundException e){ + Report.e(TAG, "FileNotFound", e); + Report.i(TAG, "Download failed..."); + } + catch (IOException e){ + Report.e(TAG, "IOException", e); + Report.i(TAG, "Download failed..."); + } finally { + if (sink!= null) { + try { + sink.close(); + } catch (IOException e) { + // Ignore - Significant errors should already have been reported + } + } + } + } + +} From 0398ac249f636a61cb1e79c93571684a58bdb703 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 21 Jan 2017 19:39:04 +0200 Subject: [PATCH 17/26] Fix for bookmark functionality and letters getting chopped in TextViews. --- .../activities/board/BoardActivity.java | 5 +- .../activities/topic/TopicActivity.java | 14 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 138 ++++++------------ .../java/gr/thmmy/mthmmy/model/Bookmark.java | 57 +++++++- .../thmmy/mthmmy/utils/ObjectSerializer.java | 69 --------- .../res/layout/activity_board_sub_board.xml | 3 +- .../main/res/layout/activity_board_topic.xml | 127 ++++++++-------- .../res/layout/activity_downloads_row.xml | 2 + 8 files changed, 177 insertions(+), 238 deletions(-) delete mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.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 2289dcac..77067287 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 @@ -91,8 +91,9 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo getSupportActionBar().setDisplayShowHomeEnabled(true); } - setBoardBookmark((ImageButton) findViewById(R.id.bookmark), - new Bookmark(boardTitle, boardUrl)); + thisPageBookmark = new Bookmark(boardTitle, boardUrl); + thisPageBookmarkButton = (ImageButton) findViewById(R.id.bookmark); + setBoardBookmark(); createDrawer(); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); 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 043a5a6c..4948474e 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 @@ -9,6 +9,7 @@ import android.support.design.widget.FloatingActionButton; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; @@ -118,8 +119,9 @@ public class TopicActivity extends BaseActivity { getSupportActionBar().setDisplayShowHomeEnabled(true); } - setTopicBookmark((ImageButton) findViewById(R.id.bookmark), - new Bookmark(topicTitle, ThmmyPage.getTopicId(topicPageUrl))); + thisPageBookmark = new Bookmark(topicTitle, ThmmyPage.getTopicId(topicPageUrl)); + thisPageBookmarkButton = (ImageButton) findViewById(R.id.bookmark); + setTopicBookmark(); createDrawer(); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); @@ -450,7 +452,7 @@ public class TopicActivity extends BaseActivity { } if (Integer.parseInt(newPageUrl.substring(base_url.length() + 1)) / 15 + 1 == thisPage) return SAME_PAGE; - } else topicTitle = null; + } else if (!Objects.equals(loadedPageUrl, "")) topicTitle = null; loadedPageUrl = newPageUrl; Request request = new Request.Builder() @@ -481,8 +483,10 @@ public class TopicActivity extends BaseActivity { switch (parseResult) { case SUCCESS: - setTopicBookmark((ImageButton) findViewById(R.id.bookmark), - new Bookmark(parsedTitle, ThmmyPage.getTopicId(loadedPageUrl))); + if (topicTitle == null || Objects.equals(topicTitle, "")) { + thisPageBookmark = new Bookmark(parsedTitle, ThmmyPage.getTopicId(loadedPageUrl)); + setTopicBookmark(); + } progressBar.setVisibility(ProgressBar.INVISIBLE); topicAdapter.customNotifyDataSetChanged(new TopicTask()); 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 de2b5a7e..b3af480e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -29,9 +29,7 @@ import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IProfile; -import java.io.IOException; import java.util.ArrayList; -import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.AboutActivity; @@ -44,7 +42,6 @@ import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.services.DownloadService; import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; -import gr.thmmy.mthmmy.utils.ObjectSerializer; import okhttp3.OkHttpClient; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -67,9 +64,11 @@ public abstract class BaseActivity extends AppCompatActivity { private static final String BOOKMARKS_SHARED_PREFS = "bookmarksSharedPrefs"; private static final String BOOKMARKED_TOPICS_KEY = "bookmarkedTopicsKey"; private static final String BOOKMARKED_BOARDS_KEY = "bookmarkedBoardsKey"; - protected static SharedPreferences bookmarksFile; - protected static ArrayList topicsBookmarked; - protected static ArrayList boardsBookmarked; + protected Bookmark thisPageBookmark; + protected ImageButton thisPageBookmarkButton; + protected SharedPreferences bookmarksFile; + protected ArrayList topicsBookmarked; + protected ArrayList boardsBookmarked; protected static Drawable bookmarked; protected static Drawable notBookmarked; @@ -409,46 +408,45 @@ public abstract class BaseActivity extends AppCompatActivity { return topicsBookmarked; } - protected void setTopicBookmark(ImageButton bookmarkView, final Bookmark bookmark) { - if (matchExists(bookmark, topicsBookmarked)) { - bookmarkView.setImageDrawable(bookmarked); + protected void setTopicBookmark() { + if (thisPageBookmark.matchExists(topicsBookmarked)) { + thisPageBookmarkButton.setImageDrawable(bookmarked); } else { - bookmarkView.setImageDrawable(notBookmarked); + thisPageBookmarkButton.setImageDrawable(notBookmarked); } - bookmarkView.setOnClickListener(new View.OnClickListener() { + thisPageBookmarkButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (matchExists(bookmark, topicsBookmarked)) { - ((ImageButton) view).setImageDrawable(notBookmarked); - toggleTopicToBookmarks(bookmark); + if (thisPageBookmark.matchExists(topicsBookmarked)) { + thisPageBookmarkButton.setImageDrawable(notBookmarked); + toggleTopicToBookmarks(thisPageBookmark); Toast.makeText(BaseActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show(); } else { - ((ImageButton) view).setImageDrawable(bookmarked); - toggleTopicToBookmarks(bookmark); + thisPageBookmarkButton.setImageDrawable(bookmarked); + toggleTopicToBookmarks(thisPageBookmark); Toast.makeText(BaseActivity.this, "Bookmark added", Toast.LENGTH_SHORT).show(); } } }); } - protected void setBoardBookmark(ImageButton bookmarkView, final Bookmark bookmark) { - if (matchExists(bookmark, boardsBookmarked)) { - bookmarkView.setImageDrawable(bookmarked); + protected void setBoardBookmark() { + if (thisPageBookmark.matchExists(boardsBookmarked)) { + thisPageBookmarkButton.setImageDrawable(bookmarked); } else { - bookmarkView.setImageDrawable(notBookmarked); + thisPageBookmarkButton.setImageDrawable(notBookmarked); } - bookmarkView.setOnClickListener(new View.OnClickListener() { + thisPageBookmarkButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (matchExists(bookmark, boardsBookmarked)) { - ((ImageButton) view).setImageDrawable(notBookmarked); - toggleBoardToBookmarks(bookmark); + if (thisPageBookmark.matchExists(boardsBookmarked)) { + thisPageBookmarkButton.setImageDrawable(notBookmarked); Toast.makeText(BaseActivity.this, "Bookmark removed", Toast.LENGTH_SHORT).show(); } else { - ((ImageButton) view).setImageDrawable(bookmarked); - toggleBoardToBookmarks(bookmark); + thisPageBookmarkButton.setImageDrawable(bookmarked); Toast.makeText(BaseActivity.this, "Bookmark added", Toast.LENGTH_SHORT).show(); } + toggleBoardToBookmarks(thisPageBookmark); } }); } @@ -456,95 +454,50 @@ public abstract class BaseActivity extends AppCompatActivity { private void loadSavedBookmarks() { String tmpString = bookmarksFile.getString(BOOKMARKED_TOPICS_KEY, null); if (tmpString != null) - try { - topicsBookmarked = (ArrayList) ObjectSerializer.deserialize(tmpString); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } + topicsBookmarked = Bookmark.arrayFromString(tmpString); else { topicsBookmarked = new ArrayList<>(); - topicsBookmarked.add(null); } tmpString = bookmarksFile.getString(BOOKMARKED_BOARDS_KEY, null); if (tmpString != null) - try { - boardsBookmarked = (ArrayList) ObjectSerializer.deserialize(tmpString); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } + boardsBookmarked = Bookmark.arrayFromString(tmpString); else { boardsBookmarked = new ArrayList<>(); - boardsBookmarked.add(null); } } private void toggleBoardToBookmarks(Bookmark bookmark) { if (boardsBookmarked == null) return; - if (matchExists(bookmark, boardsBookmarked)) { - if (boardsBookmarked.size() == 1) boardsBookmarked.set(0, null); - else boardsBookmarked.remove(findIndex(bookmark, boardsBookmarked)); - } else boardsBookmarked.add(bookmark); + if (bookmark.matchExists(boardsBookmarked)) { + boardsBookmarked.remove(bookmark.findIndex(boardsBookmarked)); + } else boardsBookmarked.add(new Bookmark(bookmark.getTitle(), bookmark.getId())); updateBoardBookmarks(); } private void toggleTopicToBookmarks(Bookmark bookmark) { if (topicsBookmarked == null) return; - if (matchExists(bookmark, topicsBookmarked)) - topicsBookmarked.remove(findIndex(bookmark, topicsBookmarked)); - else topicsBookmarked.add(bookmark); + if (bookmark.matchExists(topicsBookmarked)) { + topicsBookmarked.remove(bookmark.findIndex(topicsBookmarked)); + } else { + topicsBookmarked.add(new Bookmark(bookmark.getTitle(), bookmark.getId())); + } updateTopicBookmarks(); } private void updateBoardBookmarks() { - String tmpString = null; - if (!(boardsBookmarked.size() == 1 && boardsBookmarked.get(0) == null)) { - try { - tmpString = ObjectSerializer.serialize(boardsBookmarked); - } catch (IOException e) { - e.printStackTrace(); - } - } + String tmpString; + tmpString = Bookmark.arrayToString(boardsBookmarked); SharedPreferences.Editor editor = bookmarksFile.edit(); editor.putString(BOOKMARKED_BOARDS_KEY, tmpString).apply(); } private void updateTopicBookmarks() { - String tmpString = null; - if (!(topicsBookmarked.size() == 1 && topicsBookmarked.get(0) == null)) { - try { - tmpString = ObjectSerializer.serialize(topicsBookmarked); - } catch (IOException e) { - e.printStackTrace(); - } - } + String tmpString; + tmpString = Bookmark.arrayToString(topicsBookmarked); SharedPreferences.Editor editor = bookmarksFile.edit(); editor.putString(BOOKMARKED_TOPICS_KEY, tmpString).apply(); } - - private boolean matchExists(Bookmark bookmark, ArrayList array) { - if (array != null && !array.isEmpty()) { - for (Bookmark b : array) { - if (b != null) { - return Objects.equals(b.getId(), bookmark.getId()) - && Objects.equals(b.getTitle(), bookmark.getTitle()); - } - } - } - return false; - } - - private int findIndex(Bookmark bookmark, ArrayList array) { - if (array.size() == 1 && array.get(0) == null) return -1; - if (!array.isEmpty()) { - for (int i = 0; i < array.size(); ++i) { - if (array.get(i) != null && Objects.equals(array.get(i).getId(), bookmark.getId()) - && Objects.equals(array.get(i).getTitle(), bookmark.getTitle())) - return i; - } - } - return -1; - } //-------------------------------------------BOOKMARKS END------------------------------------------ //-------PERMS--------- @@ -570,8 +523,8 @@ public abstract class BaseActivity extends AppCompatActivity { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; - requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); - } + requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); + } } @@ -588,16 +541,14 @@ public abstract class BaseActivity extends AppCompatActivity { //----------------------------------DOWNLOAD------------------ private ThmmyFile tempThmmyFile; + public void launchDownloadService(ThmmyFile thmmyFile) { - if(checkPerms()) - { + if (checkPerms()) { Intent i = new Intent(this, DownloadService.class); i.setAction(ACTION_DOWNLOAD); i.putExtra(EXTRA_DOWNLOAD_URL, thmmyFile.getFileUrl().toString()); startService(i); - } - else - { + } else { tempThmmyFile = thmmyFile; requestPerms(); } @@ -605,8 +556,7 @@ public abstract class BaseActivity extends AppCompatActivity { //Uses temp file - called after permission grant public void launchDownloadService() { - if(checkPerms()) - { + if (checkPerms()) { Intent i = new Intent(this, DownloadService.class); i.setAction(ACTION_DOWNLOAD); i.putExtra(EXTRA_DOWNLOAD_URL, tempThmmyFile.getFileUrl().toString()); diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java index 88cc97d5..e9753046 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java @@ -1,6 +1,12 @@ package gr.thmmy.mthmmy.model; -public class Bookmark { +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.util.ArrayList; +import java.util.Objects; + +public class Bookmark implements java.io.Serializable { private final String title, id; public Bookmark(String title, String id) { @@ -15,4 +21,53 @@ public class Bookmark { public String getId() { return id; } + + public boolean matchExists(ArrayList array) { + if (array != null && !array.isEmpty()) { + for (Bookmark bookmark : array) { + if (bookmark != null) { + if (Objects.equals(bookmark.getId(), this.id) + && Objects.equals(bookmark.getTitle(), this.title)) + return true; + } + } + } + return false; + } + + public int findIndex(ArrayList array) { + if (array != null && !array.isEmpty()) { + for (int i = 0; i < array.size(); ++i) { + if (array.get(i) != null && Objects.equals(array.get(i).getId(), this.id) + && Objects.equals(array.get(i).getTitle(), this.title)) + return i; + } + } + return -1; + } + + @Nullable + public static String arrayToString(@NonNull ArrayList arrayList) { + String returnString = ""; + for (Bookmark bookmark : arrayList) { + if (bookmark != null) { + returnString += (bookmark.getId() + "\t"); + returnString += (bookmark.getTitle() + "\n"); + } + } + if (!Objects.equals(returnString, "")) return returnString; + else return null; + } + + public static ArrayList arrayFromString(@NonNull String string) { + ArrayList returnArray = new ArrayList<>(); + String[] lines = string.split("\n"); + for (String line : lines) { + if (line == null || line.isEmpty() || Objects.equals(line, "")) break; + String[] parameters = line.split("\t"); + if (parameters.length != 2) break; + returnArray.add(new Bookmark(parameters[1], parameters[0])); + } + return returnArray; + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java deleted file mode 100644 index ce3dbda6..00000000 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ObjectSerializer.java +++ /dev/null @@ -1,69 +0,0 @@ -package gr.thmmy.mthmmy.utils; -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//copied from http://github.com/apache/pig/blob/89c2e8e76c68d0d0abe6a36b4e08ddc56979796f/src/org/apache/pig/impl/util/ObjectSerializer.java -//package org.apache.pig.impl.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -public class ObjectSerializer { - - public static String serialize(Serializable obj) throws IOException { - if (obj == null) return ""; - ByteArrayOutputStream serialObj = new ByteArrayOutputStream(); - ObjectOutputStream objStream = new ObjectOutputStream(serialObj); - objStream.writeObject(obj); - objStream.close(); - return encodeBytes(serialObj.toByteArray()); - } - - public static Object deserialize(String str) throws IOException, ClassNotFoundException { - if (str == null || str.length() == 0) return null; - ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str)); - ObjectInputStream objStream = new ObjectInputStream(serialObj); - return objStream.readObject(); - } - - public static String encodeBytes(byte[] bytes) { - StringBuffer strBuf = new StringBuffer(); - - for (int i = 0; i < bytes.length; i++) { - strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a'))); - strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a'))); - } - - return strBuf.toString(); - } - - public static byte[] decodeBytes(String str) { - byte[] bytes = new byte[str.length() / 2]; - for (int i = 0; i < str.length(); i += 2) { - char c = str.charAt(i); - bytes[i / 2] = (byte) ((c - 'a') << 4); - c = str.charAt(i + 1); - bytes[i / 2] += (c - 'a'); - } - return bytes; - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_board_sub_board.xml b/app/src/main/res/layout/activity_board_sub_board.xml index 3dcd5d6e..3b202022 100644 --- a/app/src/main/res/layout/activity_board_sub_board.xml +++ b/app/src/main/res/layout/activity_board_sub_board.xml @@ -28,8 +28,9 @@ android:id="@+id/child_board_title" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" - android:gravity="center_vertical" + android:paddingBottom="2dp" android:text="@string/child_board_title" android:textColor="@color/accent" android:textSize="22sp"/> diff --git a/app/src/main/res/layout/activity_board_topic.xml b/app/src/main/res/layout/activity_board_topic.xml index 7ce361e5..d041cc46 100644 --- a/app/src/main/res/layout/activity_board_topic.xml +++ b/app/src/main/res/layout/activity_board_topic.xml @@ -1,85 +1,80 @@ + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:orientation="vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp"> + android:layout_marginBottom="5dp" + android:layout_marginTop="5dp" + android:orientation="horizontal"> - + android:layout_gravity="center_vertical" + android:layout_weight="1" + android:paddingBottom="2dp" + android:text="@string/topic_subject" + android:textColor="@color/primary_text" + android:textSize="18sp"/> - + + - - + - - - + android:layout_marginBottom="1dp" + android:layout_marginTop="1dp" + android:text="@string/topic_started_by" + android:textColor="@color/secondary_text" + android:textSize="12sp"/> - + - - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_downloads_row.xml b/app/src/main/res/layout/activity_downloads_row.xml index 3206e64f..d6c664c9 100644 --- a/app/src/main/res/layout/activity_downloads_row.xml +++ b/app/src/main/res/layout/activity_downloads_row.xml @@ -29,9 +29,11 @@ android:id="@+id/download_title" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_marginBottom="2dp" android:layout_marginTop="2dp" android:layout_weight="1" + android:paddingBottom="2dp" android:textColor="@color/accent" android:textSize="18sp"/> From 4f402587eeec396d8664463bc51f3e913fb38feb Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 21 Jan 2017 20:00:58 +0200 Subject: [PATCH 18/26] Improved DownloadService --- .../mthmmy/services/DownloadService.java | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) 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 97d05b53..53bcb8c9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -4,6 +4,7 @@ import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.os.Environment; +import android.provider.MediaStore; import java.io.File; import java.io.FileNotFoundException; @@ -66,18 +67,52 @@ public class DownloadService extends IntentService { Request request = new Request.Builder().url(downloadLink).build(); Response response = client.newCall(request).execute(); - String filename = response.headers("Content-Disposition").toString().split("\"")[1]; + String contentType = response.headers("Content-Type").toString(); //check if link provides a binary file + if(contentType.equals("[application/octet-stream]")) + { + String fileName = response.headers("Content-Disposition").toString().split("\"")[1]; + + File dirPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mthmmy"); + if(!dirPath.isDirectory()) + { + if(dirPath.mkdirs()) + Report.i(TAG, "mTHMMY's directory created successfully!"); + else + Report.e(TAG, "Couldn't create mTHMMY's directory..."); + } + + + String nameFormat; + String[] tokens = fileName.split("\\.(?=[^\\.]+$)"); + + if(tokens.length!=2) + { + Report.w(TAG, "Error getting file extension"); + nameFormat = fileName + "(%d)"; + } + else + nameFormat = tokens[0] + "(%d)." + tokens[1]; - File dirPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mthmmy"); - if(!dirPath.isDirectory()) - dirPath.mkdirs(); - File file = new File(dirPath, filename); + File file = new File(dirPath, fileName); - sink = Okio.buffer(Okio.sink(file)); - sink.writeAll(response.body().source()); - sink.flush(); - Report.i(TAG, "Download OK!"); + for (int i = 1;;i++) { + if (!file.exists()) { + break; + } + + file = new File(dirPath, String.format(nameFormat, i)); + } + Report.v(TAG, "Start saving file " + file.getName()); + + + sink = Okio.buffer(Okio.sink(file)); + sink.writeAll(response.body().source()); + sink.flush(); + Report.i(TAG, "Download OK!"); + } + else + Report.e(TAG, "Response not a binary!"); } catch (FileNotFoundException e){ Report.e(TAG, "FileNotFound", e); From 45af916332b17af95364c7ef02e40047bb3062c9 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 21 Jan 2017 20:55:24 +0200 Subject: [PATCH 19/26] Bookmarks finalization. --- .../mthmmy/activities/BookmarkActivity.java | 106 ++++++++++++++++-- .../activities/board/BoardActivity.java | 2 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 5 + .../main/res/layout/activity_bookmark_row.xml | 32 ++++++ app/src/main/res/values/strings.xml | 7 +- 5 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 app/src/main/res/layout/activity_bookmark_row.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 48aa8067..db549c12 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java @@ -1,16 +1,29 @@ package gr.thmmy.mthmmy.activities; +import android.content.Intent; +import android.graphics.Typeface; +import android.os.Build; import android.os.Bundle; import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.board.BoardActivity; +import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Bookmark; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; +import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE; +import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; + public class BookmarkActivity extends BaseActivity { ProgressBar progressBar; @@ -30,32 +43,103 @@ public class BookmarkActivity extends BaseActivity { createDrawer(); drawer.setSelection(BOOKMARKS_ID); - progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); LinearLayout bookmarksLinearView = (LinearLayout) findViewById(R.id.bookmarks_container); + LayoutInflater layoutInflater = getLayoutInflater(); TextView tmp = new TextView(this); - tmp.setText("Your bookmarked boards:"); + 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); - for (Bookmark bookmarkedBoard : getBoardsBookmarked()) { + for (final Bookmark bookmarkedBoard : getBoardsBookmarked()) { if (bookmarkedBoard != null && bookmarkedBoard.getTitle() != null) { - TextView bookmarkedBoardView = new TextView(this); - bookmarkedBoardView.setText(bookmarkedBoard.getTitle()); - bookmarksLinearView.addView(bookmarkedBoardView); + Log.d("TAG", bookmarkedBoard.getTitle() + " - " + bookmarkedBoard.getId()); + final LinearLayout row = (LinearLayout) layoutInflater.inflate( + R.layout.activity_bookmark_row, bookmarksLinearView, false); + row.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Log.d("TAG", "https://www.thmmy.gr/smf/index.php?board=" + + bookmarkedBoard.getId() + ".0"); + Log.d("TAG", bookmarkedBoard.getTitle()); + 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); } } tmp = new TextView(this); - tmp.setText("Your bookmarked topics:"); + 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 (Bookmark bookmarkedTopic : getTopicsBookmarked()) { + for (final Bookmark bookmarkedTopic : getTopicsBookmarked()) { if (bookmarkedTopic != null && bookmarkedTopic.getTitle() != null) { - TextView bookmarkedTopicView = new TextView(this); - bookmarkedTopicView.setText(bookmarkedTopic.getTitle()); - bookmarksLinearView.addView(bookmarkedTopicView); + Log.d("TAG", bookmarkedTopic.getTitle() + " - " + bookmarkedTopic.getId()); + 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() + ".0"); + 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); } } } 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 77067287..ec656a78 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 @@ -91,7 +91,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo getSupportActionBar().setDisplayShowHomeEnabled(true); } - thisPageBookmark = new Bookmark(boardTitle, boardUrl); + thisPageBookmark = new Bookmark(boardTitle, ThmmyPage.getBoardId(boardUrl)); thisPageBookmarkButton = (ImageButton) findViewById(R.id.bookmark); setBoardBookmark(); createDrawer(); 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 b3af480e..ac6429dc 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -498,6 +498,11 @@ public abstract class BaseActivity extends AppCompatActivity { SharedPreferences.Editor editor = bookmarksFile.edit(); editor.putString(BOOKMARKED_TOPICS_KEY, tmpString).apply(); } + + protected void removeBookmark(Bookmark bookmark) { + if (bookmark.matchExists(boardsBookmarked)) toggleBoardToBookmarks(bookmark); + else if (bookmark.matchExists(topicsBookmarked)) toggleTopicToBookmarks(bookmark); + } //-------------------------------------------BOOKMARKS END------------------------------------------ //-------PERMS--------- diff --git a/app/src/main/res/layout/activity_bookmark_row.xml b/app/src/main/res/layout/activity_bookmark_row.xml new file mode 100644 index 00000000..6b02728b --- /dev/null +++ b/app/src/main/res/layout/activity_bookmark_row.xml @@ -0,0 +1,32 @@ + + + + + + + \ 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 06d28a45..1640a038 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -56,7 +56,12 @@ v%1$s Logo - You should watch a funny pic! + You should see a funny pic! + + + Remove + Your bookmarked boards: + Your bookmarked topics: Libraries From 0f74cef501d38d0ea68d9069e70b10e2cf6eb79a Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 21 Jan 2017 21:31:01 +0200 Subject: [PATCH 20/26] Rebase and cleanup --- app/src/main/AndroidManifest.xml | 32 +-- .../mthmmy/activities/AboutActivity.java | 20 +- .../mthmmy/activities/BookmarkActivity.java | 8 - .../activities/board/BoardActivity.java | 19 +- .../downloads/DownloadsActivity.java | 4 +- .../downloads/DownloadsAdapter.java | 8 +- .../activities/topic/TopicActivity.java | 5 +- .../mthmmy/activities/topic/TopicAdapter.java | 85 +----- .../mthmmy/activities/topic/TopicParser.java | 2 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 12 +- .../main/java/gr/thmmy/mthmmy/model/Post.java | 2 - .../java/gr/thmmy/mthmmy/model/ThmmyFile.java | 37 +++ .../mthmmy/utils/FileManager/ThmmyFile.java | 256 ------------------ app/src/main/res/drawable-hdpi/ic_pin.png | Bin 237 -> 0 bytes .../res/drawable-hdpi/ic_remove_circle.png | Bin 0 -> 584 bytes app/src/main/res/drawable-mdpi/ic_pin.png | Bin 208 -> 0 bytes .../res/drawable-mdpi/ic_remove_circle.png | Bin 0 -> 392 bytes app/src/main/res/drawable-xhdpi/ic_pin.png | Bin 266 -> 0 bytes .../res/drawable-xhdpi/ic_remove_circle.png | Bin 0 -> 746 bytes app/src/main/res/drawable-xxhdpi/ic_pin.png | Bin 344 -> 0 bytes .../res/drawable-xxhdpi/ic_remove_circle.png | Bin 0 -> 1219 bytes app/src/main/res/drawable-xxxhdpi/ic_pin.png | Bin 408 -> 0 bytes .../res/drawable-xxxhdpi/ic_remove_circle.png | Bin 0 -> 1608 bytes 23 files changed, 90 insertions(+), 400 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/model/ThmmyFile.java delete mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java delete mode 100644 app/src/main/res/drawable-hdpi/ic_pin.png create mode 100644 app/src/main/res/drawable-hdpi/ic_remove_circle.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_pin.png create mode 100644 app/src/main/res/drawable-mdpi/ic_remove_circle.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_pin.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_remove_circle.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_pin.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_remove_circle.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_pin.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_remove_circle.png diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 67bf2e68..c141b46b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ + package="gr.thmmy.mthmmy"> - - - - + + + + - + - + + 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"/> \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java index ffc54d8d..dd90a6df 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java @@ -26,7 +26,7 @@ public class AboutActivity extends BaseActivity { private AppBarLayout appBar; private CoordinatorLayout coordinatorLayout; - AlertDialog alertDialog; + private AlertDialog alertDialog; private FrameLayout trollGif; @Override @@ -42,8 +42,10 @@ public class AboutActivity extends BaseActivity { toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle(R.string.about); setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setDisplayShowHomeEnabled(true); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } createDrawer(); drawer.setSelection(ABOUT_ID); @@ -84,11 +86,11 @@ public class AboutActivity extends BaseActivity { } public void displayApacheLibraries(View v) { - LayoutInflater inflater =LayoutInflater.from(this); + LayoutInflater inflater = LayoutInflater.from(this); WebView webView = (WebView) inflater.inflate(R.layout.dialog_licenses, coordinatorLayout, false); webView.loadUrl("file:///android_asset/apache_libraries.html"); - int width = (int)(getResources().getDisplayMetrics().widthPixels*0.95); - int height = (int)(getResources().getDisplayMetrics().heightPixels*0.95); + int width = (int) (getResources().getDisplayMetrics().widthPixels * 0.95); + int height = (int) (getResources().getDisplayMetrics().heightPixels * 0.95); alertDialog = new AlertDialog.Builder(this, R.style.AppTheme_Dark_Dialog) .setTitle(getString(R.string.apache_v2_0_libraries)) .setView(webView) @@ -98,11 +100,11 @@ public class AboutActivity extends BaseActivity { } public void displayMITLibraries(View v) { - LayoutInflater inflater =LayoutInflater.from(this); + LayoutInflater inflater = LayoutInflater.from(this); WebView webView = (WebView) inflater.inflate(R.layout.dialog_licenses, coordinatorLayout, false); webView.loadUrl("file:///android_asset/mit_libraries.html"); - int width = (int)(getResources().getDisplayMetrics().widthPixels*0.95); - int height = (int)(getResources().getDisplayMetrics().heightPixels*0.95); + int width = (int) (getResources().getDisplayMetrics().widthPixels * 0.95); + int height = (int) (getResources().getDisplayMetrics().heightPixels * 0.95); alertDialog = new AlertDialog.Builder(this, R.style.AppTheme_Dark_Dialog) .setTitle(getString(R.string.the_mit_libraries)) .setView(webView) 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 db549c12..3b383267 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java @@ -5,7 +5,6 @@ import android.graphics.Typeface; import android.os.Build; import android.os.Bundle; import android.support.v7.widget.Toolbar; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; @@ -25,7 +24,6 @@ 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 { - ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { @@ -43,7 +41,6 @@ public class BookmarkActivity extends BaseActivity { createDrawer(); drawer.setSelection(BOOKMARKS_ID); - progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); LinearLayout bookmarksLinearView = (LinearLayout) findViewById(R.id.bookmarks_container); LayoutInflater layoutInflater = getLayoutInflater(); @@ -66,15 +63,11 @@ public class BookmarkActivity extends BaseActivity { for (final Bookmark bookmarkedBoard : getBoardsBookmarked()) { if (bookmarkedBoard != null && bookmarkedBoard.getTitle() != null) { - Log.d("TAG", bookmarkedBoard.getTitle() + " - " + bookmarkedBoard.getId()); final LinearLayout row = (LinearLayout) layoutInflater.inflate( R.layout.activity_bookmark_row, bookmarksLinearView, false); row.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Log.d("TAG", "https://www.thmmy.gr/smf/index.php?board=" - + bookmarkedBoard.getId() + ".0"); - Log.d("TAG", bookmarkedBoard.getTitle()); 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=" @@ -115,7 +108,6 @@ public class BookmarkActivity extends BaseActivity { for (final Bookmark bookmarkedTopic : getTopicsBookmarked()) { if (bookmarkedTopic != null && bookmarkedTopic.getTitle() != null) { - Log.d("TAG", bookmarkedTopic.getTitle() + " - " + bookmarkedTopic.getId()); final LinearLayout row = (LinearLayout) layoutInflater.inflate( R.layout.activity_bookmark_row, bookmarksLinearView, false); row.setOnClickListener(new View.OnClickListener() { 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 ec656a78..c3587b1b 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 @@ -181,7 +181,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo *

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

      */ - public class BoardTask extends AsyncTask { + public class BoardTask extends AsyncTask { //Class variables /** * Debug Tag for logging debug output to LogCat @@ -196,29 +196,23 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } @Override - protected Boolean doInBackground(String... boardUrl) { + protected Void doInBackground(String... boardUrl) { Request request = new Request.Builder() .url(boardUrl[0]) .build(); try { Response response = BaseActivity.getClient().newCall(request).execute(); - return parseBoard(Jsoup.parse(response.body().string())); + parseBoard(Jsoup.parse(response.body().string())); } catch (SSLHandshakeException e) { Report.w(TAG, "Certificate problem (please switch to unsafe connection)."); } catch (Exception e) { Report.e("TAG", "ERROR", e); } - return false; + return null; } @Override - protected void onPostExecute(Boolean result) { - if (!result) { //Parse failed! - Report.d(TAG, "Parse failed!"); - Toast.makeText(getApplicationContext() - , "Fatal error!\n Aborting...", Toast.LENGTH_LONG).show(); - finish(); - } + protected void onPostExecute(Void voids) { if (boardTitle == null || Objects.equals(boardTitle, "")) toolbar.setTitle(boardTitle); //Parse was successful @@ -229,7 +223,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo isLoadingMore = false; } - private boolean parseBoard(Document boardPage) { + private void parseBoard(Document boardPage) { if (boardTitle == null || Objects.equals(boardTitle, "")) boardTitle = boardPage.select("div.nav a.nav").last().text(); @@ -333,7 +327,6 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } } } - return true; } } } 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 1d931aa9..1f9beff4 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 @@ -47,8 +47,8 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. public static final String BUNDLE_DOWNLOADS_TITLE = "DOWNLOADS_TITLE"; private static final String downloadsIndexUrl = "https://www.thmmy.gr/smf/index.php?action=tpmod;dl;"; private String downloadsUrl; - String downloadsTitle; - private ArrayList parsedDownloads = new ArrayList<>(); + private String downloadsTitle; + private final ArrayList parsedDownloads = new ArrayList<>(); private MaterialProgressBar progressBar; private RecyclerView recyclerView; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java index 8abfdf55..02c687df 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java @@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.activities.downloads; import android.content.Context; import android.content.Intent; import android.graphics.Typeface; +import android.os.Build; import android.os.Bundle; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -125,7 +126,12 @@ class DownloadsAdapter extends RecyclerView.Adapter { } else { //TODO implement download on click - downloadViewHolder.upperLinear.setBackgroundColor(context.getResources().getColor(R.color.background)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + downloadViewHolder.upperLinear.setBackgroundColor(context.getResources().getColor(R.color.background, null)); + } else { + //noinspection deprecation + downloadViewHolder.upperLinear.setBackgroundColor(context.getResources().getColor(R.color.background)); + } downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); downloadViewHolder.informationExpandableBtn.setVisibility(View.GONE); downloadViewHolder.informationExpandableBtn.setEnabled(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 4948474e..8bf4c7ac 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 @@ -9,7 +9,6 @@ import android.support.design.widget.FloatingActionButton; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; -import android.util.Log; import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; @@ -87,7 +86,7 @@ public class TopicActivity extends BaseActivity { //Other variables private FloatingActionButton replyFAB; private MaterialProgressBar progressBar; - public static String base_url = ""; + private static String base_url = ""; private String topicTitle; private String parsedTitle; private RecyclerView recyclerView; @@ -132,7 +131,7 @@ public class TopicActivity extends BaseActivity { recyclerView.setHasFixedSize(true); LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); recyclerView.setLayoutManager(layoutManager); - topicAdapter = new TopicAdapter(this, progressBar, postsList, + topicAdapter = new TopicAdapter(this, postsList, topicTask); recyclerView.setAdapter(topicAdapter); 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 dd9cee02..c4c57cb7 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 @@ -7,11 +7,9 @@ import android.content.Intent; import android.graphics.Color; import android.graphics.Typeface; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.v4.content.FileProvider; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; @@ -20,7 +18,6 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.webkit.MimeTypeMap; import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -30,12 +27,9 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; -import android.widget.Toast; import com.squareup.picasso.Picasso; -import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -47,8 +41,7 @@ import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CircleTransform; -import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; -import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import gr.thmmy.mthmmy.model.ThmmyFile; import mthmmy.utils.Report; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -93,8 +86,6 @@ class TopicAdapter extends RecyclerView.Adapter { * Index of state indicator in the boolean array. If true quote button for this post is checked. */ private static final int isQuoteButtonChecked = 2; - //private final MaterialProgressBar progressBar; - private DownloadTask downloadTask; private TopicActivity.TopicTask topicTask; /** @@ -157,7 +148,7 @@ class TopicAdapter extends RecyclerView.Adapter { * @param context the context of the {@link RecyclerView} * @param postsList List of {@link Post} objects to use */ - TopicAdapter(Context context, MaterialProgressBar progressBar, List postsList, + TopicAdapter(Context context, List postsList, TopicActivity.TopicTask topicTask) { this.context = context; this.postsList = postsList; @@ -167,8 +158,6 @@ class TopicAdapter extends RecyclerView.Adapter { //Initializes properties, array's values will be false by default viewProperties.add(new boolean[3]); } - //this.progressBar = progressBar; - downloadTask = new DownloadTask(); this.topicTask = topicTask; } @@ -632,74 +621,4 @@ class TopicAdapter extends RecyclerView.Adapter { return context.getResources().getString(R.string.fa_file); } - - private class DownloadTask extends AsyncTask { - //Class variables - /** - * Debug Tag for logging debug output to LogCat - */ - private static final String TAG = "DownloadTask"; //Separate tag for AsyncTask - - @Override - protected void onPreExecute() { - super.onPreExecute(); - Toast.makeText(context, "Downloading", Toast.LENGTH_SHORT).show(); - } - - @Override - protected String doInBackground(ThmmyFile... file) { - try { - File tempFile = file[0].download(context); - if (tempFile != null) { - if (file[0].isInternal()) { - String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension( - file[0].getExtension()); - - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - //intent.setDataAndType(Uri.fromFile(tempFile), mime); - - intent.setDataAndType(FileProvider.getUriForFile(context, context. - getApplicationContext() - .getPackageName() + ".provider", tempFile), mime); - - intent.setFlags(FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } else { - String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension( - file[0].getExtension()); - - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(tempFile), mime); - - /*intent.setDataAndType(FileProvider.getUriForFile(context, context. - getApplicationContext() - .getPackageName() + ".provider", tempFile), mime);*/ - - intent.setFlags(FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } - } - } catch (IOException e) { - Report.e(TAG, "Error while trying to download a file", e); - return e.toString(); - } catch (OutOfMemoryError e) { - Report.e(TAG, e.toString(), e); - return e.toString(); - } catch (IllegalStateException e) { - Report.e(TAG, e.toString(), e); - return e.toString(); - } - return null; - } - - @Override - protected void onPostExecute(String result) { - if (result != null) { - Toast.makeText(context, "Download failed!", Toast.LENGTH_SHORT).show(); - Toast.makeText(context, result, Toast.LENGTH_LONG).show(); - } - } - } } \ No newline at end of file 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 538dec17..9cab0649 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 @@ -15,7 +15,7 @@ import java.util.List; import java.util.Objects; import gr.thmmy.mthmmy.model.Post; -import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; +import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.utils.ParseHelpers; import mthmmy.utils.Report; 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 ac6429dc..8b8d395d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -41,7 +41,7 @@ import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.services.DownloadService; import gr.thmmy.mthmmy.session.SessionManager; -import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; +import gr.thmmy.mthmmy.model.ThmmyFile; import okhttp3.OkHttpClient; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -66,11 +66,11 @@ public abstract class BaseActivity extends AppCompatActivity { private static final String BOOKMARKED_BOARDS_KEY = "bookmarkedBoardsKey"; protected Bookmark thisPageBookmark; protected ImageButton thisPageBookmarkButton; - protected SharedPreferences bookmarksFile; - protected ArrayList topicsBookmarked; - protected ArrayList boardsBookmarked; - protected static Drawable bookmarked; - protected static Drawable notBookmarked; + private SharedPreferences bookmarksFile; + private ArrayList topicsBookmarked; + private ArrayList boardsBookmarked; + private static Drawable bookmarked; + private static Drawable notBookmarked; //Common UI elements protected Toolbar toolbar; diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Post.java b/app/src/main/java/gr/thmmy/mthmmy/model/Post.java index 96c5a04e..15b6afe6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Post.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Post.java @@ -5,8 +5,6 @@ import android.support.annotation.Nullable; import java.util.ArrayList; import java.util.Objects; -import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; - /** * Class that defines a topic's post. All member variables are declared final (thus no setters are * supplied). Class has two constructors and getter methods for all variables. diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyFile.java b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyFile.java new file mode 100644 index 00000000..e071a6a2 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyFile.java @@ -0,0 +1,37 @@ +package gr.thmmy.mthmmy.model; + +import java.net.URL; + +public class ThmmyFile { + /** + * Debug Tag for logging debug output to LogCat + */ + private static final String TAG = "ThmmyFile"; + private final URL fileUrl; + private final String filename, fileInfo; + + /** + * This constructor only creates a ThmmyFile object and does not download the file. + * + * @param fileUrl {@link URL} object with file's url + * @param filename {@link String} with desired file name + * @param fileInfo {@link String} with any extra information (like number of downloads) + */ + public ThmmyFile(URL fileUrl, String filename, String fileInfo) { + this.fileUrl = fileUrl; + this.filename = filename; + this.fileInfo = fileInfo; + } + + public URL getFileUrl() { + return fileUrl; + } + + public String getFilename() { + return filename; + } + + public String getFileInfo() { + return fileInfo; + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java deleted file mode 100644 index 59d2816f..00000000 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java +++ /dev/null @@ -1,256 +0,0 @@ -package gr.thmmy.mthmmy.utils.FileManager; - -import android.app.DownloadManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.Uri; -import android.os.Environment; -import android.os.StatFs; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.webkit.MimeTypeMap; -import android.widget.Toast; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.util.Objects; - -import gr.thmmy.mthmmy.base.BaseActivity; -import mthmmy.utils.Report; -import okhttp3.Request; -import okhttp3.Response; - -import static android.content.Context.MODE_PRIVATE; -import static gr.thmmy.mthmmy.base.BaseActivity.getClient; - -/** - * Used for downloading and storing a file from the forum using {@link okhttp3}. - *

      Class has one constructor, {@link #ThmmyFile(URL, String, String)}. - */ -@SuppressWarnings("unused") -public class ThmmyFile { - /** - * Debug Tag for logging debug output to LogCat - */ - private static final String TAG = "ThmmyFile"; - private final URL fileUrl; - private final String filename, fileInfo; - private String extension, filePath; - private File file; - private boolean isInternal; - - /** - * This constructor only creates a empty ThmmyFile object and does not download the file. To download - * the file use {@link #download(Context)} after setting file's url! - */ - public ThmmyFile() { - this.fileUrl = null; - this.filename = null; - this.fileInfo = null; - this.extension = null; - this.filePath = null; - this.file = null; - this.isInternal = false; - } - - /** - * This constructor only creates a ThmmyFile object and does not download the file. To - * download the file use {@link #download(Context)} after you provide a url! - * - * @param fileUrl {@link URL} object with file's url - * @param filename {@link String} with desired file name - * @param fileInfo {@link String} with any extra information (like number of downloads) - */ - public ThmmyFile(URL fileUrl, String filename, String fileInfo) { - this.fileUrl = fileUrl; - this.filename = filename; - this.fileInfo = fileInfo; - this.extension = null; - this.filePath = null; - this.file = null; - this.isInternal = false; - } - - public URL getFileUrl() { - return fileUrl; - } - - public String getFilename() { - return filename; - } - - public String getFileInfo() { - return fileInfo; - } - - /** - * This is null until {@link #download(Context)} is called and has succeeded. - * - * @return String with file's extension or null - */ - @Nullable - public String getExtension() { - return extension; - } - - /** - * This is null until {@link #download(Context)} is called and has succeeded. - * - * @return String with file's path or null - */ - @Nullable - public String getFilePath() { - return filePath; - } - - /** - * This is null until {@link #download(Context)} is called and has succeeded. - * - * @return {@link File} or null - */ - @Nullable - public File getFile() { - return file; - } - - private void setExtension(String extension) { - this.extension = extension; - } - - private void setFilePath(String filePath) { - this.filePath = filePath; - } - - public boolean isInternal() { - return isInternal; - } - - /** - * Used to download the file. If download is successful file's extension and path will be assigned - * to object's fields and can be accessed using getter methods. - * - * @return null if downloaded with the download service, otherwise the {@link File} - * @throws IOException if the request could not be executed due to cancellation, a - * connectivity problem or timeout. Because networks can fail - * during an exchange, it is possible that the remote server - * accepted the request before the failure. - * @throws SecurityException if the requested file is not hosted by the forum. - * @throws IllegalStateException if file's url or filename is not yet set - */ - @Nullable - public File download(Context context) throws IOException, IllegalStateException, OutOfMemoryError { - if (fileUrl == null) - throw new IllegalStateException("Internal error!\nNo url was provided."); - else if (!Objects.equals(fileUrl.getHost(), "www.thmmy.gr")) - throw new SecurityException("Downloading files from other sources is not supported"); - else if (filename == null || Objects.equals(filename, "")) - throw new IllegalStateException("Internal error!\nNo filename was provided."); - - return downloadWithoutManager(context, fileUrl); - /*try { - downloadWithManager(context, fileUrl); - } catch (IllegalStateException e) { - return downloadWithoutManager(context, fileUrl); - }*/ - //return null; - } - - private void downloadWithManager(Context context, @NonNull URL pFileUrl) throws IllegalStateException, IOException { - DownloadManager.Request request = new DownloadManager.Request(Uri.parse(pFileUrl.toString())); - request.addRequestHeader("Cookie", BaseActivity.getSessionManager().getCookieHeader()); - request.setDescription("mThmmy"); - request.setMimeType(MimeTypeMap.getSingleton().getMimeTypeFromExtension( - MimeTypeMap.getFileExtensionFromUrl(filename))); - request.setTitle(filename); - request.allowScanningByMediaScanner(); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - try { - request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); - } catch (IllegalStateException e) { - Report.d(TAG, "External directory not available!", e); - throw e; - } - - DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - manager.enqueue(request); - context.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Toast.makeText(context, "Download complete", Toast.LENGTH_SHORT).show(); - context.unregisterReceiver(this); - } - }, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); - } - - @Nullable - private File downloadWithoutManager(Context context, @NonNull URL pFileUrl) throws IOException - , SecurityException, OutOfMemoryError { - Request request = new Request.Builder().url(pFileUrl).build(); - - Response response = getClient().newCall(request).execute(); - if (!response.isSuccessful()) { - throw new IOException("Failed to download file: " + response); - } - file = getOutputMediaFile(context, filename, fileInfo); - if (file == null) { - Report.d(TAG, "Error creating media file, check storage permissions!"); - } else { - FileOutputStream fos; - if (isInternal) - fos = context.openFileOutput(filename, MODE_PRIVATE); - else - fos = new FileOutputStream(file); - fos.write(response.body().bytes()); - fos.close(); - - filePath = file.getAbsolutePath(); - extension = MimeTypeMap.getFileExtensionFromUrl( - filePath.substring(filePath.lastIndexOf("/"))); - } - return file; - } - - @Nullable - private File getOutputMediaFile(Context context, String fileName, String fileInfo) throws - OutOfMemoryError, IOException { - File mediaStorageDir; - String extState = Environment.getExternalStorageState(); - if (Environment.isExternalStorageRemovable() && - Objects.equals(extState, Environment.MEDIA_MOUNTED)) { - mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment - .DIRECTORY_DOWNLOADS), fileName); - } else { - mediaStorageDir = new File(context.getFilesDir(), "Downloads"); - isInternal = true; - } - - //Creates the storage directory if it does not exist - if (!mediaStorageDir.exists()) { - if (!mediaStorageDir.mkdirs()) { - Report.d(TAG, "problem!"); - throw new IOException("Error.\nCouldn't create the path!"); - } - } - - if (fileInfo != null) { - if (fileInfo.contains("KB")) { - float fileSize = Float.parseFloat(fileInfo - .substring(fileInfo.indexOf("(") + 1, fileInfo.indexOf("KB") - 1)); - - StatFs stat = new StatFs(mediaStorageDir.getPath()); - long bytesAvailable = stat.getBlockSizeLong() * stat.getAvailableBlocksLong(); - if ((bytesAvailable / 1024.f) < fileSize) - throw new OutOfMemoryError("There is not enough memory!"); - } - } - - //Creates a media file name - File mediaFile; - mediaFile = new File(mediaStorageDir.getPath() + File.separator + fileName); - return mediaFile; - } -} diff --git a/app/src/main/res/drawable-hdpi/ic_pin.png b/app/src/main/res/drawable-hdpi/ic_pin.png deleted file mode 100644 index 9b2e298103632171d79cae4c168cbba505f2d2c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB*pj^6U4S$Y{B+)352QE?JR*yM zvQ&rUPlPeufHm>3$%m!qdeuB;xSfX&ZSDDDbc-{@xJ3Yl`IWjLR;Y z429HwzJ6;zp1bhMC8*uKq1ulV%YGPsF9GFmuY+?-5fRJpl67a%7Xq{)EC_^j(^aTj5(*xpu zi5&p%K1dPXfP!eTBVgg96yXD~MTt35O9@hhPZl|r;kS?|wfg1qyu=bd|ED%Fr70*h zVts|AR;%S!VkHHo2*+N6xmeoLtkYW+*Xe4&Q zA~w=UY)C5>queB_g0swv(1_(Uk|LyO#3~FAoB;zt%oyIIOe5A{c;G-_Gibo@9(5YA zmWE=@e=TP0P&Br97+db6rcTfnww-kmyD@bU+-4EWXe74By3u^lK(}6TtKSPDj(q%wSw5N+>h{y4_Qyhg3C~z<@m47e)_rkYp(h~fy zPE63AWZJc@Y`2aUlZRT`y7R>*jgypa{hh|bs&OER;X@zK6w^HAT`?W33@_z>_0AFB o`-d;Be=T$EGWDM`#1z`?V!S*%BpwQ;0#1v^GAyoABZr+ zr@oor8?DiHW3>tEFQh@J4@`gJtaj6tu@Fn5>cURfWV39(1c!WX&GK@u) zP+xGLktHi{o@JqlK^exF5{erTiYTE|142hih+17K=29I}V%{qy^dtrb5^Y65%=`E% zq1Jt}))n=t0ih)&8Lm;`jUly{!}wEM`;Ip;7o9znZH|2Dt|WE*mg#kLsv}f m2VNgB4&3sl_y0filR_`p6Q>$Fohupu0000Z;oTG{o{7;x9%7A)9gITEA7nE jWlQHi4R1i`XNWWBy{neIWA9Fos~J39{an^LB{Ts5Y8_cX diff --git a/app/src/main/res/drawable-xhdpi/ic_remove_circle.png b/app/src/main/res/drawable-xhdpi/ic_remove_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..505d8b3a308b217b162210b4cfbcffe1ceac761b GIT binary patch literal 746 zcmV1Lljg{wCF+?YFE@ED6o=3B6^b7sz5zQrG+gpNP*=$ZLWZ3Bm!ZB*k3fq)2zfCz|yeieo$p&Yae6`?ZZ zK~>Dd?-lVe^~X*?-L?Y7p#`Xb0H2&ypj&7j>azi87&?dE1yCAQgU+C|i9jRJodlFd z)&DYwOaSVKjupcE?Ep&X3N!<~28hFYfigM)bwC>$!2E3$3Iz=mh4LEWur8sVpn!Uz zCyjAfk9e#~fue@s{6vbV0_xEGW!0!Fo^uip(7J&*tQFZnGX~?Zrey*3Yw|hAkIzYQ z89+xC;IQ`m1{$#lhn4md=*~i*8^3^tEyQ7^`~W()80b_KC@yKSOP6ZRE<>6DEm(}h zniBykH~@6b3ltVyU^k^VsEY?^(g7USI1f?BQZ^YlUSyDhrZ_`gLSpb3Y7#(03bX}P2M zg4wMDKzWfB#d!ySWie8$h@I0qsiwauhqA5 zmA7Qpmq+#kynNUZx%ElqO}%NHLsog=nUe8bWN+l9aMV`DqFWW$bCNQjgQ^|RUYsVq z#(i*+1@=5Hlg3mWdl1{hT{sh%#mTOF-1>b+yb69@!k=y7zSStysrq>7AD9pj0TB=Z c5s=uJQvbkn`Bn#WAGf*4tYLb6Xq)7#s_>iMKk-*S}9(ZLd=u z5z2VLk2|yCO(Da9;JMmzR>qrCXMEmMGjF|YvrVUi;{t^M0S%p-N$Lqyyy3dt?hiZE+zY~I&b*!;`uA4ty2l?_Rqq9juej#M1VUW1PB8V1|ST= z0E7VugD?PL$;c$ii6)|p7$;_l7_mm|5PO;({jr$-oN@g%jruh*A&j4NqLSz&X0(KT zCe&+96CFf_{$3E~fpbJHF{J-P_6_lq7$j=+&j4Xb$S2x~MT3%#V}WQRE<)H*t`U7i z+yYUD*(Q34D-bp|kVo_|zb{Gghv+79!zfI>KeQ054v0F;5286t!itC~2Spubk|+$i zF!h(Y6#!WYHi?EH3dpUs`4#!P1t>6BZRUNtV>Cgkab(H$?b=nRf)@^M1k=Yvi^HdyKJkltdLZLUaH6Q zHVPYooD=WUtP<7?DM_ifMOab5mYbybP2BWbm|Asz4;iOs!f#SS7+00=Lj!?xZQ5^Rwn4=LjE)84vj8?uu3CXDva}Kh*KY1)Ld6v@(|zWAo<39#Xfs z^Ofp9S8Z|YA(r)vxF?aVuLAg>&?S9I7XdCV&h4Fo4R49z=o`Bo6uJ+bn1AE&z3ZK zwt8tr3zM*e9mdtVTsGM^vZ8z4t1QjMT44uKlO1YbcePdc6mxrBTo2Pl^~g_}?RmJi zsYyhSmX_)vZdC+~>gmvVy>_W2>}ulrWAplRM)kCQot`PqaP9YZQCO%!2oMG!3_uu! h0SE&S24TP~e*rfh>J5d_m<9j<002ovPDHLkV1foaC13ym literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_pin.png b/app/src/main/res/drawable-xxxhdpi/ic_pin.png deleted file mode 100644 index 4d6bdf41d6e708c58654a88e9bfd383de295d5f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoY)RhkE(}8pX7+2iB`GtXjQQ6bQF{I+w+dCTz4;u(DI9~j_!fpD$bD}2} zJ6KG(liP6QenK0^f#b{!3_E5ge`QWjd*!;nSmyYpnSZWu@3Ur1VmiXo!6_iDpyrVC z)AB)RtzN|6yZ=w|LB)I;W-u5cDc(uf3yvDDCk6@D|_p`hJet z{QqwW`WgMncC)zoVZG?XC5Pk19=l;gVCh<0|Y@~$!akS8)ObO$S5zo7xZt4NHN6)HACwz zMKMwPAPa*t4tKzdjwoDd!>lx8+Yh2ugS0>z_fRUt&O@j94w4DS$XL=@%LisB&HqKKBF8 z$%5jR0rqPiA8D0mjqpo>#hJ+!p&5bZ$1eYyhd9%DAbfy8v$I(E8d2utE8#^1nog52 zfE@GYccB4+rf3!JA;oiZS7<4^Kph32WmSvYDBf07f!vDnQzWRGCw>LHPy+QR-7!y< zabags1nNef+$8FH*ER_@)|R;vQFGGGoiux_y?P!m)2;8XktD*`QMkuVC^L#$Yb z5Qy!GxZ55{3$%+6qtlbBKx-mjseylY@tacdq6@rXpg0Z z$2O)Q&>6x~%eUGE+Du65*`QURQbF!*Sy*5!X%wiNaFU@@n?SWjuNzxsFsuKCvJ$9^ zP?BT2CV{RINOD}(BG5X*NR~G>2y}uVlI2)zfm~U+#{`k|>BS{61=>dl$+J7AK$i$0 zdCtcYXa(1E%v=Y0HHJWRUv}t?AL_?dUJ%m8LG_+Yh3?a}F8rm#}LI~7H zL!0Gf2!Sp}`r(T9B61Qt^OgKyg9v0+pn(tq4I_|Qfrdf|G=e~81-c(XpfLn8E6`{N zfhG{htU%)kgh1*Aq6?!7V-Sr%@dnXM77{NYkXeDwg%Iczn~rRzRwK}1 z8k*xA94Lcm2g)|m&}Mlngh0z^Xb#m^d#&dVjm@D(DUdVz2H~jZ*DS9eWqp^462Jz}J%<#i z#_#MBluo|MI`2FLYUHetN?cKlRVfJM_>{oZ@o^qm=OvJv)?XnsRf~qDlmv1#3l9iS z#c|c9ymHRF!bA@NMrTK!8HXrSa+DCG@kQSGh7f3xaGfxtEEv{V5XjLW+$GdtxU1(Y zLu4DW;#NzUr@}+vCN6735!j_Pk#;E=Gp1(>$;Mww2=nS1_tOAld zktp-KUGK-pGG-OhF1oYKx~J580@7qRUz@9l{?ExBnd@!!KP{;a#|JGAAc^__@j&J+FbJWrFxtTaD1 z;tr+lFZl7;5r2}fq&24$UafIwtiLPh0r*wg^GWIXqYVX_sr{Dq)f)twetFTYx(*r? z=Vq2SMiFRkk+ut$jSP@GG>>yE3iMxGf$U@Dv?`@N@@rnLskgtSCnA>!yM^;gclzDG z$rZG8H3?s~((YE@8-1-j^)TM)a=d5CpDq6Nduf(iZ0jOCUc0b7Rff+!CgNVC8Ol+Z z+x{~S_^x$<_4X~=OUTbyTAq3^#y#=q-U&VFyS@Q0*nK~y8uyI)uMPP>bI$*rL;icX zX?J}Q+p?$v0RjO60RjO60U!_{5FijB5C8%J0s#Vnef|LkMS~zxVD9Sx0000ft literal 0 HcmV?d00001 From fe167d73c1f53dede8e9d5ab5c083514c71e75d1 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 21 Jan 2017 22:11:53 +0200 Subject: [PATCH 21/26] Notifications init --- app/src/main/AndroidManifest.xml | 12 ++- .../gr/thmmy/mthmmy/base/BaseActivity.java | 24 ++---- .../gr/thmmy/mthmmy/receiver/Receiver.java | 49 ++++++++++++ .../mthmmy/services/DownloadService.java | 77 ++++++++++++++++++- 4 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c141b46b..19a98cf1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -92,7 +92,17 @@ + android:exported="false" /> + + + + + + + \ No newline at end of file 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 8b8d395d..0f8825dc 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -39,9 +39,9 @@ import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.model.Bookmark; +import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.services.DownloadService; import gr.thmmy.mthmmy.session.SessionManager; -import gr.thmmy.mthmmy.model.ThmmyFile; import okhttp3.OkHttpClient; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -50,8 +50,6 @@ import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWN import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; -import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; -import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_URL; public abstract class BaseActivity extends AppCompatActivity { // Client & Cookies @@ -544,16 +542,13 @@ public abstract class BaseActivity extends AppCompatActivity { } - //----------------------------------DOWNLOAD------------------ + //----------------------------------DOWNLOAD---------------------- private ThmmyFile tempThmmyFile; public void launchDownloadService(ThmmyFile thmmyFile) { - if (checkPerms()) { - Intent i = new Intent(this, DownloadService.class); - i.setAction(ACTION_DOWNLOAD); - i.putExtra(EXTRA_DOWNLOAD_URL, thmmyFile.getFileUrl().toString()); - startService(i); - } else { + if (checkPerms()) + DownloadService.startActionDownload(this, thmmyFile.getFileUrl().toString()); + else { tempThmmyFile = thmmyFile; requestPerms(); } @@ -561,12 +556,9 @@ public abstract class BaseActivity extends AppCompatActivity { //Uses temp file - called after permission grant public void launchDownloadService() { - if (checkPerms()) { - Intent i = new Intent(this, DownloadService.class); - i.setAction(ACTION_DOWNLOAD); - i.putExtra(EXTRA_DOWNLOAD_URL, tempThmmyFile.getFileUrl().toString()); - startService(i); - } + if (checkPerms()) + DownloadService.startActionDownload(this, tempThmmyFile.getFileUrl().toString()); + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java new file mode 100644 index 00000000..f6d47255 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -0,0 +1,49 @@ +package gr.thmmy.mthmmy.receiver; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.NotificationCompat; + +import gr.thmmy.mthmmy.R; + +import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_ID; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TEXT; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TICKER; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TITLE; + +public class Receiver extends BroadcastReceiver { + public Receiver() { + } + + @Override + public void onReceive(Context context, Intent intent) { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context); + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + if(intent.getAction().equals(ACTION_DOWNLOAD)) + { + Bundle extras = intent.getExtras(); + int id = extras.getInt(EXTRA_DOWNLOAD_ID); + String title = extras.getString(EXTRA_NOTIFICATION_TITLE); + String text =extras.getString(EXTRA_NOTIFICATION_TEXT); + String ticker =extras.getString(EXTRA_NOTIFICATION_TICKER); + + builder.setContentTitle(title) + .setContentText(text) + .setTicker(ticker) + .setAutoCancel(true) + .setSmallIcon(R.mipmap.ic_launcher) + ; + + Notification notification = builder.build(); + notificationManager.notify(id, notification); + } + + } + +} 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 53bcb8c9..4b561820 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -3,14 +3,16 @@ package gr.thmmy.mthmmy.services; import android.app.IntentService; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Environment; -import android.provider.MediaStore; +import android.support.annotation.NonNull; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import gr.thmmy.mthmmy.base.BaseApplication; +import gr.thmmy.mthmmy.receiver.Receiver; import mthmmy.utils.Report; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -24,14 +26,38 @@ import okio.Okio; */ public class DownloadService extends IntentService { private static final String TAG = "DownloadService"; + private static int sDownloadId =0; + + private Receiver receiver; public static final String ACTION_DOWNLOAD = "gr.thmmy.mthmmy.services.action.DOWNLOAD"; public static final String EXTRA_DOWNLOAD_URL = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_URL"; + public static final String EXTRA_DOWNLOAD_ID = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_ID"; + public static final String EXTRA_NOTIFICATION_TITLE = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TITLE"; + public static final String EXTRA_NOTIFICATION_TEXT = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TEXT"; + public static final String EXTRA_NOTIFICATION_TICKER = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TICKER"; + + public DownloadService() { super("DownloadService"); } + @Override + public void onCreate() { + super.onCreate(); + final IntentFilter filter = new IntentFilter(DownloadService.ACTION_DOWNLOAD); + receiver = new Receiver(); + registerReceiver(receiver, filter); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + this.unregisterReceiver(receiver); + } + /** * Starts this service to perform action Download with the given parameters. If * the service is already performing a task this action will be queued. @@ -63,6 +89,10 @@ public class DownloadService extends IntentService { private void handleActionDownload(String downloadLink) { OkHttpClient client = BaseApplication.getInstance().getClient(); BufferedSink sink = null; + String trueName = null; + int downloadId = sDownloadId; + sDownloadId++; + try { Request request = new Request.Builder().url(downloadLink).build(); Response response = client.newCall(request).execute(); @@ -103,13 +133,17 @@ public class DownloadService extends IntentService { file = new File(dirPath, String.format(nameFormat, i)); } - Report.v(TAG, "Start saving file " + file.getName()); + trueName = file.getName(); + + Report.v(TAG, "Started saving file " + trueName); + sendNotification("Started", trueName); sink = Okio.buffer(Okio.sink(file)); sink.writeAll(response.body().source()); sink.flush(); Report.i(TAG, "Download OK!"); + sendNotification("Completed", trueName); } else Report.e(TAG, "Response not a binary!"); @@ -117,10 +151,18 @@ public class DownloadService extends IntentService { catch (FileNotFoundException e){ Report.e(TAG, "FileNotFound", e); Report.i(TAG, "Download failed..."); + if(trueName!=null) + sendNotification("Failed", trueName); + else + sendNotification("Failed", "file"); } catch (IOException e){ Report.e(TAG, "IOException", e); Report.i(TAG, "Download failed..."); + if(trueName!=null) + sendNotification("Failed", trueName); + else + sendNotification("Failed", "file"); } finally { if (sink!= null) { try { @@ -132,4 +174,35 @@ public class DownloadService extends IntentService { } } + private void sendNotification(String type, @NonNull String fileName) + { + switch (type) { + case "Started": { + Intent intent = new Intent(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Started"); + intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" downloading..."); + intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Downloading..."); + sendBroadcast(intent); + break; + } + case "Completed": { + Intent intent = new Intent(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Completed"); + intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" finished downloading."); + intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Completed"); + sendBroadcast(intent); + break; + } + case "Failed": { + Intent intent = new Intent(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Failed"); + intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" failed."); + intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Failed"); + sendBroadcast(intent); + break; + } + } + + } + } From 86f1c6eb7ab1342682770aca0af1ad622274d41c Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 21 Jan 2017 22:18:06 +0200 Subject: [PATCH 22/26] Fixed bug bookmarks from drawer not removed when logging out --- .../java/gr/thmmy/mthmmy/activities/BookmarkActivity.java | 8 ++++++-- .../gr/thmmy/mthmmy/activities/topic/TopicAdapter.java | 2 +- app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java | 3 ++- .../main/java/gr/thmmy/mthmmy/session/SessionManager.java | 1 - 4 files changed, 9 insertions(+), 5 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 3b383267..5d854eef 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java @@ -8,7 +8,6 @@ import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; -import android.widget.ProgressBar; import android.widget.TextView; import gr.thmmy.mthmmy.R; @@ -16,7 +15,6 @@ import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Bookmark; -import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; @@ -135,4 +133,10 @@ public class BookmarkActivity extends BaseActivity { } } } + + @Override + protected void onResume() { + drawer.setSelection(BOOKMARKS_ID); + super.onResume(); + } } 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 c4c57cb7..be2e3e53 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 @@ -39,9 +39,9 @@ import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Post; +import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CircleTransform; -import gr.thmmy.mthmmy.model.ThmmyFile; import mthmmy.utils.Report; 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 0f8825dc..44d5687b 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -328,7 +328,7 @@ public abstract class BaseActivity extends AppCompatActivity { }); if (sessionManager.isLoggedIn()) - drawerBuilder.addDrawerItems(homeItem, downloadsItem, bookmarksItem, loginLogoutItem, aboutItem); + drawerBuilder.addDrawerItems(homeItem, bookmarksItem, downloadsItem, loginLogoutItem, aboutItem); else drawerBuilder.addDrawerItems(homeItem, loginLogoutItem, aboutItem); @@ -349,6 +349,7 @@ 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) 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 a6bb4df5..d47e4969 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -9,7 +9,6 @@ import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersisto import org.jsoup.Jsoup; import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; From 944fb432fb6a91c9c770f6f70b89e402c3ed9d43 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 21 Jan 2017 22:37:49 +0200 Subject: [PATCH 23/26] Downloads/notifications improvements --- .../gr/thmmy/mthmmy/receiver/Receiver.java | 11 +++++-- .../mthmmy/services/DownloadService.java | 32 +++++++++++++------ 2 files changed, 30 insertions(+), 13 deletions(-) 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 f6d47255..33c15199 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -12,9 +12,11 @@ import gr.thmmy.mthmmy.R; import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_ID; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_STATE; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TEXT; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TICKER; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TITLE; +import static gr.thmmy.mthmmy.services.DownloadService.STARTED; public class Receiver extends BroadcastReceiver { public Receiver() { @@ -29,6 +31,7 @@ public class Receiver extends BroadcastReceiver { { Bundle extras = intent.getExtras(); int id = extras.getInt(EXTRA_DOWNLOAD_ID); + String state = extras.getString(EXTRA_DOWNLOAD_STATE, "NONE"); String title = extras.getString(EXTRA_NOTIFICATION_TITLE); String text =extras.getString(EXTRA_NOTIFICATION_TEXT); String ticker =extras.getString(EXTRA_NOTIFICATION_TICKER); @@ -36,9 +39,11 @@ public class Receiver extends BroadcastReceiver { builder.setContentTitle(title) .setContentText(text) .setTicker(ticker) - .setAutoCancel(true) - .setSmallIcon(R.mipmap.ic_launcher) - ; + .setAutoCancel(true) //??? + .setSmallIcon(R.mipmap.ic_launcher); + + if(state.equals(STARTED)) + builder.setOngoing(true); Notification notification = builder.build(); notificationManager.notify(id, notification); 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 4b561820..b41a6ade 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -34,10 +34,16 @@ public class DownloadService extends IntentService { public static final String EXTRA_DOWNLOAD_URL = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_URL"; public static final String EXTRA_DOWNLOAD_ID = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_ID"; + public static final String EXTRA_DOWNLOAD_STATE = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_STATE"; public static final String EXTRA_NOTIFICATION_TITLE = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TITLE"; public static final String EXTRA_NOTIFICATION_TEXT = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TEXT"; public static final String EXTRA_NOTIFICATION_TICKER = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TICKER"; + public static final String STARTED = "Started"; + public static final String COMPLETED = "Completed"; + public static final String FAILED = "Failed"; + + public DownloadService() { super("DownloadService"); @@ -137,13 +143,13 @@ public class DownloadService extends IntentService { trueName = file.getName(); Report.v(TAG, "Started saving file " + trueName); - sendNotification("Started", trueName); + sendNotification(downloadId, STARTED, trueName); sink = Okio.buffer(Okio.sink(file)); sink.writeAll(response.body().source()); sink.flush(); Report.i(TAG, "Download OK!"); - sendNotification("Completed", trueName); + sendNotification(downloadId, COMPLETED, trueName); } else Report.e(TAG, "Response not a binary!"); @@ -152,17 +158,17 @@ public class DownloadService extends IntentService { Report.e(TAG, "FileNotFound", e); Report.i(TAG, "Download failed..."); if(trueName!=null) - sendNotification("Failed", trueName); + sendNotification(downloadId, FAILED, trueName); else - sendNotification("Failed", "file"); + sendNotification(downloadId, FAILED, "file"); } catch (IOException e){ Report.e(TAG, "IOException", e); Report.i(TAG, "Download failed..."); if(trueName!=null) - sendNotification("Failed", trueName); + sendNotification(downloadId, FAILED, trueName); else - sendNotification("Failed", "file"); + sendNotification(downloadId, FAILED, "file"); } finally { if (sink!= null) { try { @@ -174,27 +180,33 @@ public class DownloadService extends IntentService { } } - private void sendNotification(String type, @NonNull String fileName) + private void sendNotification(int downloadId, String type, @NonNull String fileName) { switch (type) { - case "Started": { + case STARTED: { Intent intent = new Intent(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); + intent.putExtra(EXTRA_DOWNLOAD_STATE, STARTED); intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Started"); intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" downloading..."); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Downloading..."); sendBroadcast(intent); break; } - case "Completed": { + case COMPLETED: { Intent intent = new Intent(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); + intent.putExtra(EXTRA_DOWNLOAD_STATE, COMPLETED); intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Completed"); intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" finished downloading."); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Completed"); sendBroadcast(intent); break; } - case "Failed": { + case FAILED: { Intent intent = new Intent(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); + intent.putExtra(EXTRA_DOWNLOAD_STATE, FAILED); intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Failed"); intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" failed."); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Failed"); From d4bb50be23bd9e8bc0f877e6de2ce0a856b8faa6 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 21 Jan 2017 23:33:52 +0200 Subject: [PATCH 24/26] MainActivity intent filters and corresponding Activity start. --- app/src/main/AndroidManifest.xml | 27 ++++++- .../downloads/DownloadsActivity.java | 10 ++- .../mthmmy/activities/main/MainActivity.java | 81 ++++++++++++++++--- .../activities/profile/ProfileActivity.java | 42 ++++++++-- .../mthmmy/activities/topic/TopicAdapter.java | 14 ++-- .../gr/thmmy/mthmmy/base/BaseActivity.java | 10 +-- .../java/gr/thmmy/mthmmy/model/ThmmyPage.java | 11 +++ 7 files changed, 159 insertions(+), 36 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 19a98cf1..1ad2d90b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,6 +26,27 @@ + + + + + + + + + + + + + + android:exported="false"/> - - + + 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 1f9beff4..c81c98ec 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 @@ -69,8 +69,6 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. Bundle extras = getIntent().getExtras(); downloadsTitle = extras.getString(BUNDLE_DOWNLOADS_TITLE); - if (downloadsTitle == null || Objects.equals(downloadsTitle, "")) - downloadsTitle = "Downloads"; downloadsUrl = extras.getString(BUNDLE_DOWNLOADS_URL); if (downloadsUrl != null && !Objects.equals(downloadsUrl, "")) { ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(Uri.parse(downloadsUrl)); @@ -83,6 +81,8 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. //Initialize toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + if (downloadsTitle == null || Objects.equals(downloadsTitle, "")) + toolbar.setTitle("Downloads"); toolbar.setTitle(downloadsTitle); setSupportActionBar(toolbar); if (getSupportActionBar() != null) { @@ -204,7 +204,8 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. @Override protected void onPostExecute(Void voids) { - if (downloadsTitle == null || Objects.equals(downloadsTitle, "")) + if (downloadsTitle != null && !Objects.equals(downloadsTitle, "") && + toolbar.getTitle() != downloadsTitle) toolbar.setTitle(downloadsTitle); ++pagesLoaded; @@ -225,7 +226,8 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. Download.DownloadItemType type; if (ThmmyPage.resolvePageCategory(Uri.parse(thisPageUrl)).is(ThmmyPage. - PageCategory.DOWNLOADS_CATEGORY)) type = Download.DownloadItemType.DOWNLOADS_CATEGORY; + PageCategory.DOWNLOADS_CATEGORY)) + type = Download.DownloadItemType.DOWNLOADS_CATEGORY; else type = Download.DownloadItemType.DOWNLOADS_FILE; Elements pages = downloadPage.select("a.navPages"); 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 84319e3f..65668324 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 @@ -1,6 +1,7 @@ package gr.thmmy.mthmmy.activities.main; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; @@ -8,20 +9,29 @@ 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.util.Log; import android.widget.Toast; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; 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.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Board; +import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.model.TopicSummary; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; +import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_TITLE; +import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; @@ -35,9 +45,13 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + final Intent intentFilter = getIntent(); + redirectToActivityFromIntent(intentFilter); setContentView(R.layout.activity_main); - if (sessionManager.isLoginScreenDefault()) { + if (sessionManager.isLoginScreenDefault()) + + { //Go to login Intent intent = new Intent(MainActivity.this, LoginActivity.class); startActivity(intent); @@ -46,7 +60,10 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF } //Initialize toolbar - toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar = (Toolbar) + + findViewById(R.id.toolbar); + setSupportActionBar(toolbar); //Initialize drawer @@ -63,6 +80,13 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF tabLayout.setupWithViewPager(mViewPager); } + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + redirectToActivityFromIntent(intent); + setIntent(intent); + } + @Override protected void onResume() { drawer.setSelection(HOME_ID); @@ -71,11 +95,10 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF @Override public void onBackPressed() { - if(drawer.isDrawerOpen()){ + if (drawer.isDrawerOpen()) { drawer.closeDrawer(); return; - } - else if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) { + } else if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) { super.onBackPressed(); return; } else { @@ -117,10 +140,13 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF @Override public Fragment getItem(int position) { - switch(position) { - case 0: return RecentFragment.newInstance(position +1); - case 1: return ForumFragment.newInstance(position +1); - default: return RecentFragment.newInstance(position +1); //temp (?) + switch (position) { + case 0: + return RecentFragment.newInstance(position + 1); + case 1: + return ForumFragment.newInstance(position + 1); + default: + return RecentFragment.newInstance(position + 1); //temp (?) } } @@ -144,4 +170,41 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF } //-------------------------------FragmentPagerAdapter END------------------------------------------- + private void redirectToActivityFromIntent(Intent intent) { + if (intent != null) { + Uri uri = intent.getData(); + if (uri != null) { + Log.d(TAG, uri.toString()); + ThmmyPage.PageCategory page = ThmmyPage.resolvePageCategory(uri); + if (!page.is(ThmmyPage.PageCategory.NOT_THMMY)) { + if (page.is(ThmmyPage.PageCategory.BOARD)) { + Intent redirectIntent = new Intent(MainActivity.this, BoardActivity.class); + redirectIntent.putExtra(BUNDLE_BOARD_URL, uri.toString()); + redirectIntent.putExtra(BUNDLE_BOARD_TITLE, ""); + startActivity(redirectIntent); + } else if (page.is(ThmmyPage.PageCategory.TOPIC)) { + Intent redirectIntent = new Intent(MainActivity.this, TopicActivity.class); + redirectIntent.putExtra(BUNDLE_TOPIC_URL, uri.toString()); + redirectIntent.putExtra(BUNDLE_TOPIC_TITLE, ""); + startActivity(redirectIntent); + } else if (page.is(ThmmyPage.PageCategory.PROFILE)) { + Intent redirectIntent = new Intent(MainActivity.this, ProfileActivity.class); + redirectIntent.putExtra(BUNDLE_PROFILE_URL, uri.toString()); + redirectIntent.putExtra(BUNDLE_PROFILE_THUMBNAIL_URL, ""); + redirectIntent.putExtra(BUNDLE_PROFILE_USERNAME, ""); + startActivity(redirectIntent); + } else if (page.is(ThmmyPage.PageCategory.DOWNLOADS)) { + Intent redirectIntent = new Intent(MainActivity.this, DownloadsActivity.class); + redirectIntent.putExtra(BUNDLE_DOWNLOADS_URL, uri.toString()); + redirectIntent.putExtra(BUNDLE_DOWNLOADS_TITLE, ""); + startActivity(redirectIntent); + } else if (!page.is(ThmmyPage.PageCategory.INDEX)) { + Toast.makeText(this, "This thmmy sector is not yet supported.", Toast.LENGTH_LONG).show(); + } + } else { + Toast.makeText(this, "This is not thmmy.", Toast.LENGTH_LONG).show(); + } + } + } + } } \ No newline at end of file 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 6d69ba86..5d604b00 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 @@ -12,6 +12,7 @@ import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.content.res.ResourcesCompat; import android.support.v4.view.ViewPager; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; @@ -50,8 +51,8 @@ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; /** * Activity for user profile. When creating an Intent of this activity you need to bundle a String * containing this user's profile url using the key {@link #BUNDLE_PROFILE_URL}, a String containing - * this user's avatar url using the key {@link #BUNDLE_THUMBNAIL_URL} and a String containing - * the username using the key {@link #BUNDLE_USERNAME}. + * this user's avatar url using the key {@link #BUNDLE_PROFILE_THUMBNAIL_URL} and a String containing + * the username using the key {@link #BUNDLE_PROFILE_USERNAME}. */ public class ProfileActivity extends BaseActivity implements LatestPostsFragment.LatestPostsFragmentInteractionListener { /** @@ -67,15 +68,16 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment * The key to use when putting user's thumbnail url String to {@link ProfileActivity}'s Bundle. * If user doesn't have a thumbnail put an empty string or leave it null. */ - public static final String BUNDLE_THUMBNAIL_URL = "THUMBNAIL_URL"; + public static final String BUNDLE_PROFILE_THUMBNAIL_URL = "THUMBNAIL_URL"; /** * The key to use when putting username String to {@link ProfileActivity}'s Bundle. * If username is not available put an empty string or leave it null. */ - public static final String BUNDLE_USERNAME = "USERNAME"; + public static final String BUNDLE_PROFILE_USERNAME = "USERNAME"; private static final int THUMBNAIL_SIZE = 200; private TextView usernameView; + private ImageView thumbnailView; private TextView personalTextView; private MaterialProgressBar progressBar; private FloatingActionButton pmFAB; @@ -84,6 +86,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment private ProfileTask profileTask; private String personalText; private String profileUrl; + private String thumbnailUrl; private String username; private int tabSelect; @@ -93,9 +96,10 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment setContentView(R.layout.activity_profile); Bundle extras = getIntent().getExtras(); - String thumbnailUrl = extras.getString(BUNDLE_THUMBNAIL_URL); + thumbnailUrl = extras.getString(BUNDLE_PROFILE_THUMBNAIL_URL); if (thumbnailUrl == null) thumbnailUrl = ""; - username = extras.getString(BUNDLE_USERNAME); + Log.d(TAG, "thumbnailUrl = " + thumbnailUrl); + username = extras.getString(BUNDLE_PROFILE_USERNAME); profileUrl = extras.getString(BUNDLE_PROFILE_URL); //Initializes graphic elements @@ -111,7 +115,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); - ImageView thumbnailView = (ImageView) findViewById(R.id.user_thumbnail); + thumbnailView = (ImageView) findViewById(R.id.user_thumbnail); if (!Objects.equals(thumbnailUrl, "")) //noinspection ConstantConditions Picasso.with(this) @@ -233,8 +237,18 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment if (username == null || Objects.equals(username, "")) { username = profilePage. select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) tr"). - first().text(); + first().select("td").last().text(); } + Log.d(TAG, "thumbnailUrl = " + thumbnailUrl); + if (thumbnailUrl == null || Objects.equals(thumbnailUrl, "")) { //Maybe there is an avatar + Log.d(TAG, "thumbnailUrl = " + thumbnailUrl); + Element profileAvatar = profilePage + .select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) img.avatar") + .first(); + if (profileAvatar != null) thumbnailUrl = profileAvatar.attr("abs:src"); + } + Log.d(TAG, "thumbnailUrl = " + thumbnailUrl); + ; { //Finds personal text Element tmpEl = profilePage.select("td.windowbg:nth-child(2)").first(); @@ -268,6 +282,18 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment progressBar.setVisibility(ProgressBar.INVISIBLE); if (usernameView.getText() != username) usernameView.setText(username); + if (thumbnailUrl != null && !Objects.equals(thumbnailUrl, "")) + //noinspection ConstantConditions + Picasso.with(getApplicationContext()) + .load(thumbnailUrl) + .resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE) + .centerCrop() + .error(ResourcesCompat.getDrawable(getResources() + , R.drawable.ic_default_user_thumbnail, null)) + .placeholder(ResourcesCompat.getDrawable(getResources() + , R.drawable.ic_default_user_thumbnail, null)) + .transform(new CircleTransform()) + .into(thumbnailView); if (personalText != null) personalTextView.setText(personalText); setupViewPager(viewPager, profilePage); 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 be2e3e53..098410b6 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 @@ -48,8 +48,8 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; -import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; -import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; /** @@ -334,10 +334,10 @@ class TopicAdapter extends RecyclerView.Adapter { Bundle extras = new Bundle(); extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL()); if (currentPost.getThumbnailUrl() == null) - extras.putString(BUNDLE_THUMBNAIL_URL, ""); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); else - extras.putString(BUNDLE_THUMBNAIL_URL, currentPost.getThumbnailUrl()); - extras.putString(BUNDLE_USERNAME, currentPost.getAuthor()); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, currentPost.getThumbnailUrl()); + extras.putString(BUNDLE_PROFILE_USERNAME, currentPost.getAuthor()); intent.putExtras(extras); intent.setFlags(FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); @@ -572,8 +572,8 @@ class TopicAdapter extends RecyclerView.Adapter { Intent intent = new Intent(context, ProfileActivity.class); Bundle extras = new Bundle(); extras.putString(BUNDLE_PROFILE_URL, uriString); - extras.putString(BUNDLE_THUMBNAIL_URL, ""); - extras.putString(BUNDLE_USERNAME, ""); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); + extras.putString(BUNDLE_PROFILE_USERNAME, ""); intent.putExtras(extras); intent.setFlags(FLAG_ACTIVITY_NEW_TASK); context.startActivity(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 44d5687b..4d54d808 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -48,8 +48,8 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_TITLE; import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; -import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; -import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; public abstract class BaseActivity extends AppCompatActivity { // Client & Cookies @@ -261,10 +261,10 @@ public abstract class BaseActivity extends AppCompatActivity { Bundle extras = new Bundle(); extras.putString(BUNDLE_PROFILE_URL, "https://www.thmmy.gr/smf/index.php?action=profile"); if (!sessionManager.hasAvatar()) - extras.putString(BUNDLE_THUMBNAIL_URL, ""); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); else - extras.putString(BUNDLE_THUMBNAIL_URL, sessionManager.getAvatarLink()); - extras.putString(BUNDLE_USERNAME, sessionManager.getUsername()); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, sessionManager.getAvatarLink()); + extras.putString(BUNDLE_PROFILE_USERNAME, sessionManager.getUsername()); intent.putExtras(extras); intent.setFlags(FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 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 758f9765..c4bc5272 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java @@ -22,6 +22,7 @@ public class ThmmyPage { * An enum describing a link's target by defining the types:

        *
      • {@link #NOT_THMMY}
      • *
      • {@link #THMMY}
      • + *
      • {@link #INDEX}
      • *
      • {@link #UNKNOWN_THMMY}
      • *
      • {@link #TOPIC}
      • *
      • {@link #BOARD}
      • @@ -41,6 +42,10 @@ public class ThmmyPage { * Link points to thmmy. */ THMMY, + /** + * Link points to thmmy index page/ + */ + INDEX, /** * Link points to a thmmy page that's not (yet) supported by the app. */ @@ -135,6 +140,7 @@ public class ThmmyPage { final String host = uri.getHost(); final String uriString = uri.toString(); + if (Objects.equals(uriString, "thmmy.gr")) return PageCategory.INDEX; if (Objects.equals(host, "www.thmmy.gr")) { if (uriString.contains("topic=")) return PageCategory.TOPIC; else if (uriString.contains("board=")) return PageCategory.BOARD; @@ -150,6 +156,11 @@ public class ThmmyPage { return PageCategory.DOWNLOADS_FILE; else if (uriString.contains("action=tpmod;dl")) return PageCategory.DOWNLOADS_CATEGORY; + else if (uriString.contains("action=forum") || Objects.equals(uriString, "www.thmmy.gr") + || Objects.equals(uriString, "http://www.thmmy.gr") + || Objects.equals(uriString, "https://www.thmmy.gr") + || Objects.equals(uriString, "https://www.thmmy.gr/smf/index.php")) + return PageCategory.INDEX; Report.v(TAG, "Unknown thmmy link found, link: " + uriString); return PageCategory.UNKNOWN_THMMY; } From c44f9d161ade1642da25ca4304d43dfd5bcef904 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sun, 22 Jan 2017 00:17:11 +0200 Subject: [PATCH 25/26] Downloads/ Notification changes --- .../mthmmy/activities/topic/TopicAdapter.java | 2 +- .../gr/thmmy/mthmmy/base/BaseActivity.java | 2 +- .../gr/thmmy/mthmmy/receiver/Receiver.java | 44 +++++++++++-- .../mthmmy/services/DownloadService.java | 61 ++++++++++--------- 4 files changed, 71 insertions(+), 38 deletions(-) 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 098410b6..b03b56e5 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 @@ -47,8 +47,8 @@ import mthmmy.utils.Report; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; -import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; 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 4d54d808..501e2452 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -47,8 +47,8 @@ import okhttp3.OkHttpClient; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_TITLE; import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_URL; -import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; public abstract class BaseActivity extends AppCompatActivity { 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 33c15199..42a867ea 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -2,23 +2,35 @@ package gr.thmmy.mthmmy.receiver; import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.v7.app.NotificationCompat; +import android.webkit.MimeTypeMap; + +import java.io.File; import gr.thmmy.mthmmy.R; +import mthmmy.utils.Report; import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; +import static gr.thmmy.mthmmy.services.DownloadService.COMPLETED; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_ID; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_STATE; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_FILE_EXTENSION; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_FILE_NAME; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TEXT; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TICKER; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_NOTIFICATION_TITLE; +import static gr.thmmy.mthmmy.services.DownloadService.SAVE_DIR; import static gr.thmmy.mthmmy.services.DownloadService.STARTED; public class Receiver extends BroadcastReceiver { + private static final String TAG = "BroadcastReceiver"; + public Receiver() { } @@ -27,14 +39,13 @@ public class Receiver extends BroadcastReceiver { NotificationCompat.Builder builder = new NotificationCompat.Builder(context); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - if(intent.getAction().equals(ACTION_DOWNLOAD)) - { + if (intent.getAction().equals(ACTION_DOWNLOAD)) { Bundle extras = intent.getExtras(); int id = extras.getInt(EXTRA_DOWNLOAD_ID); String state = extras.getString(EXTRA_DOWNLOAD_STATE, "NONE"); String title = extras.getString(EXTRA_NOTIFICATION_TITLE); - String text =extras.getString(EXTRA_NOTIFICATION_TEXT); - String ticker =extras.getString(EXTRA_NOTIFICATION_TICKER); + String text = extras.getString(EXTRA_NOTIFICATION_TEXT); + String ticker = extras.getString(EXTRA_NOTIFICATION_TICKER); builder.setContentTitle(title) .setContentText(text) @@ -42,13 +53,34 @@ public class Receiver extends BroadcastReceiver { .setAutoCancel(true) //??? .setSmallIcon(R.mipmap.ic_launcher); - if(state.equals(STARTED)) + if (state.equals(STARTED)) builder.setOngoing(true); + else if (state.equals(COMPLETED)) { + String fileName = extras.getString(EXTRA_FILE_NAME, "NONE"); + String extension = extras.getString(EXTRA_FILE_EXTENSION, "extension"); + + File file = new File(SAVE_DIR, fileName); + if (file.exists()) { +// String type = "application/" + extension; + String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); + + Uri pathUri = Uri.fromFile(file); + Intent chooserIntent = new Intent(Intent.ACTION_VIEW); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Intent chooser = Intent.createChooser(chooserIntent, "Open With..."); + intent.setDataAndType(pathUri, type); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, chooser, PendingIntent.FLAG_CANCEL_CURRENT); + builder.setContentIntent(pendingIntent); + } + else + Report.w(TAG,"File doesn't exist."); + + + } Notification notification = builder.build(); notificationManager.notify(id, notification); } - } } 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 b41a6ade..5eca8376 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -30,11 +30,15 @@ public class DownloadService extends IntentService { private Receiver receiver; + public static final String SAVE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "mthmmy"; + public static final String ACTION_DOWNLOAD = "gr.thmmy.mthmmy.services.action.DOWNLOAD"; public static final String EXTRA_DOWNLOAD_URL = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_URL"; public static final String EXTRA_DOWNLOAD_ID = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_ID"; public static final String EXTRA_DOWNLOAD_STATE = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_STATE"; + public static final String EXTRA_FILE_NAME = "gr.thmmy.mthmmy.services.extra.FILE_NAME"; + public static final String EXTRA_FILE_EXTENSION = "gr.thmmy.mthmmy.services.extra.FILE_EXTENSION"; public static final String EXTRA_NOTIFICATION_TITLE = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TITLE"; public static final String EXTRA_NOTIFICATION_TEXT = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TEXT"; public static final String EXTRA_NOTIFICATION_TICKER = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TICKER"; @@ -95,7 +99,8 @@ public class DownloadService extends IntentService { private void handleActionDownload(String downloadLink) { OkHttpClient client = BaseApplication.getInstance().getClient(); BufferedSink sink = null; - String trueName = null; + String fileName = "file"; + String extension = "extension"; int downloadId = sDownloadId; sDownloadId++; @@ -106,9 +111,9 @@ public class DownloadService extends IntentService { String contentType = response.headers("Content-Type").toString(); //check if link provides a binary file if(contentType.equals("[application/octet-stream]")) { - String fileName = response.headers("Content-Disposition").toString().split("\"")[1]; + fileName = response.headers("Content-Disposition").toString().split("\"")[1]; - File dirPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mthmmy"); + File dirPath = new File(SAVE_DIR); if(!dirPath.isDirectory()) { if(dirPath.mkdirs()) @@ -123,11 +128,15 @@ public class DownloadService extends IntentService { if(tokens.length!=2) { - Report.w(TAG, "Error getting file extension"); + Report.w(TAG, "Couldn't get file extension..."); nameFormat = fileName + "(%d)"; } else + { nameFormat = tokens[0] + "(%d)." + tokens[1]; + extension = tokens[1]; + } + File file = new File(dirPath, fileName); @@ -140,35 +149,29 @@ public class DownloadService extends IntentService { file = new File(dirPath, String.format(nameFormat, i)); } - trueName = file.getName(); + fileName = file.getName(); - Report.v(TAG, "Started saving file " + trueName); - sendNotification(downloadId, STARTED, trueName); + Report.v(TAG, "Started saving file " + fileName); + sendNotification(downloadId, STARTED, fileName, extension); sink = Okio.buffer(Okio.sink(file)); sink.writeAll(response.body().source()); sink.flush(); Report.i(TAG, "Download OK!"); - sendNotification(downloadId, COMPLETED, trueName); + sendNotification(downloadId, COMPLETED, fileName, extension); } else - Report.e(TAG, "Response not a binary!"); + Report.e(TAG, "Response not a binary file!"); } catch (FileNotFoundException e){ Report.e(TAG, "FileNotFound", e); Report.i(TAG, "Download failed..."); - if(trueName!=null) - sendNotification(downloadId, FAILED, trueName); - else - sendNotification(downloadId, FAILED, "file"); + sendNotification(downloadId, FAILED, fileName, extension); } catch (IOException e){ Report.e(TAG, "IOException", e); Report.i(TAG, "Download failed..."); - if(trueName!=null) - sendNotification(downloadId, FAILED, trueName); - else - sendNotification(downloadId, FAILED, "file"); + sendNotification(downloadId, FAILED, fileName, extension); } finally { if (sink!= null) { try { @@ -180,40 +183,38 @@ public class DownloadService extends IntentService { } } - private void sendNotification(int downloadId, String type, @NonNull String fileName) + private void sendNotification(int downloadId, String type, @NonNull String fileName, String fileExtension) { + Intent intent = new Intent(ACTION_DOWNLOAD); switch (type) { case STARTED: { - Intent intent = new Intent(ACTION_DOWNLOAD); - intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); - intent.putExtra(EXTRA_DOWNLOAD_STATE, STARTED); intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Started"); intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" downloading..."); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Downloading..."); - sendBroadcast(intent); break; } case COMPLETED: { - Intent intent = new Intent(ACTION_DOWNLOAD); - intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); - intent.putExtra(EXTRA_DOWNLOAD_STATE, COMPLETED); intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Completed"); intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" finished downloading."); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Completed"); - sendBroadcast(intent); break; } case FAILED: { - Intent intent = new Intent(ACTION_DOWNLOAD); - intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); - intent.putExtra(EXTRA_DOWNLOAD_STATE, FAILED); intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Failed"); intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" failed."); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Failed"); - sendBroadcast(intent); break; } + default:{ + Report.wtf(TAG, "Invalid notification case!"); + return; + } } + intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); + intent.putExtra(EXTRA_DOWNLOAD_STATE, type); + intent.putExtra(EXTRA_FILE_NAME, fileName); + intent.putExtra(EXTRA_FILE_EXTENSION, fileExtension); + sendBroadcast(intent); } From f6452789b62857c1e0a08a6321d0db4d4ad7bc84 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sun, 22 Jan 2017 00:57:47 +0200 Subject: [PATCH 26/26] Receiver and other fixes --- VERSION | 2 +- app/build.gradle | 4 ++-- .../downloads/DownloadsActivity.java | 2 +- .../gr/thmmy/mthmmy/receiver/Receiver.java | 22 ++++++++---------- .../res/drawable-hdpi/ic_remove_circle.png | Bin 584 -> 392 bytes .../res/drawable-mdpi/ic_remove_circle.png | Bin 392 -> 270 bytes .../res/drawable-xhdpi/ic_remove_circle.png | Bin 746 -> 509 bytes .../res/drawable-xxhdpi/ic_remove_circle.png | Bin 1219 -> 746 bytes .../res/drawable-xxxhdpi/ic_remove_circle.png | Bin 1608 -> 1060 bytes .../main/res/layout/activity_bookmark_row.xml | 7 +++--- 10 files changed, 18 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 7dea76ed..9084fa2f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 +1.1.0 diff --git a/app/build.gradle b/app/build.gradle index f09859fb..05e1d905 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "gr.thmmy.mthmmy" minSdkVersion 19 targetSdkVersion 25 - versionCode 2 - versionName "1.0.1" + versionCode 3 + versionName "1.1.0" archivesBaseName = "mTHMMY-v$versionName" } 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 c81c98ec..8d844e67 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 @@ -272,7 +272,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. rows.select("div.smalltext:not(:has(a))").text(), rows.select("span:not(:has(a))").first().text(), false, - rows.select("span:has(a)").first().html())); + rows.select("span:has(a)").first().text())); } } } 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 42a867ea..3f76766e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -16,6 +16,7 @@ import java.io.File; import gr.thmmy.mthmmy.R; import mthmmy.utils.Report; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; import static gr.thmmy.mthmmy.services.DownloadService.COMPLETED; import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_ID; @@ -61,22 +62,19 @@ public class Receiver extends BroadcastReceiver { File file = new File(SAVE_DIR, fileName); if (file.exists()) { -// String type = "application/" + extension; - String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); + String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension( + MimeTypeMap.getFileExtensionFromUrl(file.getAbsolutePath())); - Uri pathUri = Uri.fromFile(file); - Intent chooserIntent = new Intent(Intent.ACTION_VIEW); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Intent chooser = Intent.createChooser(chooserIntent, "Open With..."); - intent.setDataAndType(pathUri, type); + Intent chooser = new Intent(); + chooser.setAction(android.content.Intent.ACTION_VIEW); + chooser.setDataAndType(Uri.fromFile(file), type); + chooser.setFlags(FLAG_ACTIVITY_NEW_TASK); + chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, chooser, PendingIntent.FLAG_CANCEL_CURRENT); builder.setContentIntent(pendingIntent); - } - else - Report.w(TAG,"File doesn't exist."); - - + } else + Report.w(TAG, "File doesn't exist."); } Notification notification = builder.build(); notificationManager.notify(id, notification); diff --git a/app/src/main/res/drawable-hdpi/ic_remove_circle.png b/app/src/main/res/drawable-hdpi/ic_remove_circle.png index 10ab64f69243598d946ab6f49feeff4cc06e4603..e4cc857927bebe83c3fec9039d5d1b68d161cd6e 100644 GIT binary patch literal 392 zcmV;30eAk1P)#1v^GAyoABZr+ zr@oor8?DiHW3>tEFQh@J4@`gJtaj6tu@Fn5>cURfWV39(1c!WX&GK@u) zP+xGLktHi{o@JqlK^exF5{erTiYTE|142hih+17K=29I}V%{qy^dtrb5^Y65%=`E% zq1Jt}))n=t0ih)&8Lm;`jUly{!}wEM`;Ip;7o9znZH|2Dt|WE*mg#kLsv}f m2VNgB4&3sl_y0filR_`p6Q>$Fohupu00001bhMC8*uKq1ulV%YGPsF9GFmuY+?-5fRJpl67a%7Xq{)EC_^j(^aTj5(*xpu zi5&p%K1dPXfP!eTBVgg96yXD~MTt35O9@hhPZl|r;kS?|wfg1qyu=bd|ED%Fr70*h zVts|AR;%S!VkHHo2*+N6xmeoLtkYW+*Xe4&Q zA~w=UY)C5>queB_g0swv(1_(Uk|LyO#3~FAoB;zt%oyIIOe5A{c;G-_Gibo@9(5YA zmWE=@e=TP0P&Br97+db6rcTfnww-kmyD@bU+-4EWXe74By3u^lKpF literal 392 zcmV;30eAk1P)#1v^GAyoABZr+ zr@oor8?DiHW3>tEFQh@J4@`gJtaj6tu@Fn5>cURfWV39(1c!WX&GK@u) zP+xGLktHi{o@JqlK^exF5{erTiYTE|142hih+17K=29I}V%{qy^dtrb5^Y65%=`E% zq1Jt}))n=t0ih)&8Lm;`jUly{!}wEM`;Ip;7o9znZH|2Dt|WE*mg#kLsv}f m2VNgB4&3sl_y0filR_`p6Q>$Fohupu0000aa@BpB+5JN;;8xk5r;&TvQK!S~U+IloNo6IGI zL^Hd$f9B#9UqZM5zwd6@-I?_+p6C)ES14sZs$p%{4_}!&o5t7XqmtLaF}~r+yl3GZtu31Zs>0E~%Tj6~pka)XkjWmZ3mbrXDCW zD`>ufQ`wSo#7JPEQWKXX7B!Q+1IMaum4JajBWYvHx=*;=p=Cd9C8930{+?`nt zf2g~??pqp8L&}{`a=;N_yU)aI)39~KRK#{)q-l{F{54gYJmfpaj@eRiZ`1v4g>`Yv zTE)K21PhNfKA{L-&+%Fdca^#9pgR-D1d{Uur7kI&zW)r!00000NkvXXu0mjfe1X>o literal 746 zcmV1Lljg{wCF+?YFE@ED6o=3B6^b7sz5zQrG+gpNP*=$ZLWZ3Bm!ZB*k3fq)2zfCz|yeieo$p&Yae6`?ZZ zK~>Dd?-lVe^~X*?-L?Y7p#`Xb0H2&ypj&7j>azi87&?dE1yCAQgU+C|i9jRJodlFd z)&DYwOaSVKjupcE?Ep&X3N!<~28hFYfigM)bwC>$!2E3$3Iz=mh4LEWur8sVpn!Uz zCyjAfk9e#~fue@s{6vbV0_xEGW!0!Fo^uip(7J&*tQFZnGX~?Zrey*3Yw|hAkIzYQ z89+xC;IQ`m1{$#lhn4md=*~i*8^3^tEyQ7^`~W()80b_KC@yKSOP6ZRE<>6DEm(}h zniBykH~@6b3ltVyU^k^VsEY?^(g7USI1f?BQZ^YlUSyDhrZ_`gLSpb3Y7#(03bX}P2M zg4wMDKzWfB#d!ySWie8$h@I0qsiwauhqA5 zmA7Qpmq+#kynNUZx%ElqO}%NHLsog=nUe8bWN+l9aMV`DqFWW$bCNQjgQ^|RUYsVq z#(i*+1@=5Hlg3mWdl1{hT{sh%#mTOF-1>b+yb69@!k=y7zSStysrq>7AD9pj0TB=Z c5s1Lljg{wCF+?YFE@ED6o=3B6^b7sz5zQrG+gpNP*=$ZLWZ3Bm!ZB*k3fq)2zfCz|yeieo$p&Yae6`?ZZ zK~>Dd?-lVe^~X*?-L?Y7p#`Xb0H2&ypj&7j>azi87&?dE1yCAQgU+C|i9jRJodlFd z)&DYwOaSVKjupcE?Ep&X3N!<~28hFYfigM)bwC>$!2E3$3Iz=mh4LEWur8sVpn!Uz zCyjAfk9e#~fue@s{6vbV0_xEGW!0!Fo^uip(7J&*tQFZnGX~?Zrey*3Yw|hAkIzYQ z89+xC;IQ`m1{$#lhn4md=*~i*8^3^tEyQ7^`~W()80b_KC@yKSOP6ZRE<>6DEm(}h zniBykH~@6b3ltVyU^k^VsEY?^(g7USI1f?BQZ^YlUSyDhrZ_`gLSpb3Y7#(03bX}P2M zg4wMDKzWfB#d!ySWie8$h@I0qsiwauhqA5 zmA7Qpmq+#kynNUZx%ElqO}%NHLsog=nUe8bWN+l9aMV`DqFWW$bCNQjgQ^|RUYsVq z#(i*+1@=5Hlg3mWdl1{hT{sh%#mTOF-1>b+yb69@!k=y7zSStysrq>7AD9pj0TB=Z c5sq9juej#M1VUW1PB8V1|ST= z0E7VugD?PL$;c$ii6)|p7$;_l7_mm|5PO;({jr$-oN@g%jruh*A&j4NqLSz&X0(KT zCe&+96CFf_{$3E~fpbJHF{J-P_6_lq7$j=+&j4Xb$S2x~MT3%#V}WQRE<)H*t`U7i z+yYUD*(Q34D-bp|kVo_|zb{Gghv+79!zfI>KeQ054v0F;5286t!itC~2Spubk|+$i zF!h(Y6#!WYHi?EH3dpUs`4#!P1t>6BZRUNtV>Cgkab(H$?b=nRf)@^M1k=Yvi^HdyKJkltdLZLUaH6Q zHVPYooD=WUtP<7?DM_ifMOab5mYbybP2BWbm|Asz4;iOs!f#SS7+00=Lj!?xZQ5^Rwn4=LjE)84vj8?uu3CXDva}Kh*KY1)Ld6v@(|zWAo<39#Xfs z^Ofp9S8Z|YA(r)vxF?aVuLAg>&?S9I7XdCV&h4Fo4R49z=o`Bo6uJ+bn1AE&z3ZK zwt8tr3zM*e9mdtVTsGM^vZ8z4t1QjMT44uKlO1YbcePdc6mxrBTo2Pl^~g_}?RmJi zsYyhSmX_)vZdC+~>gmvVy>_W2>}ulrWAplRM)kCQot`PqaP9YZQCO%!2oMG!3_uu! h0SE&S24TP~e*rfh>J5d_m<9j<002ovPDHLkV1foaC13ym diff --git a/app/src/main/res/drawable-xxxhdpi/ic_remove_circle.png b/app/src/main/res/drawable-xxxhdpi/ic_remove_circle.png index 2f59367ec80dec360846e7af188671772f2009c7..5bfad8b3106e5992d774be3dc407d663a529e55c 100644 GIT binary patch literal 1060 zcmV+<1l#+GP)WD>l+0Xh}T|}FL#pAt+0jo zLM4e=`4)Sj)H65-bZv9aoadaGGv|NtyIEP(|8IBBoM)bylghm=rhqvR0t7$+fB*;p z5C8!H0#49Cv=aTq7%@wfhz+7l97xLYHSx0eLgR#4xc${9$5|7$Q1| zItVzsD(-sF`$y?&OD+0QSofw7hu_eE;u@z85yo_P+m53?vg}4b2 zH&7oO2;bv9k&cUioZ+cuScn_L8@3C$O?-1Oe2+Dv$yNb5$HPA=;ihc@t~xsG{BJl) z+ajRGu?wy$^Bl7y4goI`7{14dX#w2{4&UQ}DFKZ!y~E{Zo5-3FFpcn!)s7++(1p-X zkdI10o#iEElcnt1CvY&1X zKLT12t}@MG2$(>y%DmwgP#;m#lq>A2PDxb-bRtyWv~vm=MxeeKFO+N^U3 zC__M?{b+#&96*3J`w-xO01QEfhag;p4PS&Y4K+Lsoxu&2Ht#qDj3P*FiYUgJrGRp@ z<=qh~0x}5F?1GG75n-BJl1$0EHbV8sGfn{=2-G)ioC50PZ8d^bV@K{DWo=CyN3hDg z3Zpl)1;HwFHw*!y<$49-D(#{_6V?WeUIct955wFcBTg6GM95Xy$oV{%RHs}!fS~nj zKO6#T<(5nYewEYY7Nn9MzNM z%8k3JsmXB(Ux-_rnT63=CcX*Fjt)Cn?!3Zk@5?xLVV>g}^P>{r&5m5?svG2(?U)eY zA4c*?pY*KmzJ-q4mu8Hz4qam?3lL`_qoZ|9Dm?gf_xR1Qz=a_aYqG4zt` z)oe2{%*08+zlwa~$d^9ZAUq}aU9HPj$$iP5d~HE)3o6Pny;-G290Kq_X8-{Z03ZMY e00ck)h?2jD)2xd`kd!F^0000l;gVCh<0|Y@~$!akS8)ObO$S5zo7xZt4NHN6)HACwz zMKMwPAPa*t4tKzdjwoDd!>lx8+Yh2ugS0>z_fRUt&O@j94w4DS$XL=@%LisB&HqKKBF8 z$%5jR0rqPiA8D0mjqpo>#hJ+!p&5bZ$1eYyhd9%DAbfy8v$I(E8d2utE8#^1nog52 zfE@GYccB4+rf3!JA;oiZS7<4^Kph32WmSvYDBf07f!vDnQzWRGCw>LHPy+QR-7!y< zabags1nNef+$8FH*ER_@)|R;vQFGGGoiux_y?P!m)2;8XktD*`QMkuVC^L#$Yb z5Qy!GxZ55{3$%+6qtlbBKx-mjseylY@tacdq6@rXpg0Z z$2O)Q&>6x~%eUGE+Du65*`QURQbF!*Sy*5!X%wiNaFU@@n?SWjuNzxsFsuKCvJ$9^ zP?BT2CV{RINOD}(BG5X*NR~G>2y}uVlI2)zfm~U+#{`k|>BS{61=>dl$+J7AK$i$0 zdCtcYXa(1E%v=Y0HHJWRUv}t?AL_?dUJ%m8LG_+Yh3?a}F8rm#}LI~7H zL!0Gf2!Sp}`r(T9B61Qt^OgKyg9v0+pn(tq4I_|Qfrdf|G=e~81-c(XpfLn8E6`{N zfhG{htU%)kgh1*Aq6?!7V-Sr%@dnXM77{NYkXeDwg%Iczn~rRzRwK}1 z8k*xA94Lcm2g)|m&}Mlngh0z^Xb#m^d#&dVjm@D(DUdVz2H~jZ*DS9eWqp^462Jz}J%<#i z#_#MBluo|MI`2FLYUHetN?cKlRVfJM_>{oZ@o^qm=OvJv)?XnsRf~qDlmv1#3l9iS z#c|c9ymHRF!bA@NMrTK!8HXrSa+DCG@kQSGh7f3xaGfxtEEv{V5XjLW+$GdtxU1(Y zLu4DW;#NzUr@}+vCN6735!j_Pk#;E=Gp1(>$;Mww2=nS1_tOAld zktp-KUGK-pGG-OhF1oYKx~J580@7qRUz@9l{?ExBnd@!!KP{;a#|JGAAc^__@j&J+FbJWrFxtTaD1 z;tr+lFZl7;5r2}fq&24$UafIwtiLPh0r*wg^GWIXqYVX_sr{Dq)f)twetFTYx(*r? z=Vq2SMiFRkk+ut$jSP@GG>>yE3iMxGf$U@Dv?`@N@@rnLskgtSCnA>!yM^;gclzDG z$rZG8H3?s~((YE@8-1-j^)TM)a=d5CpDq6Nduf(iZ0jOCUc0b7Rff+!CgNVC8Ol+Z z+x{~S_^x$<_4X~=OUTbyTAq3^#y#=q-U&VFyS@Q0*nK~y8uyI)uMPP>bI$*rL;icX zX?J}Q+p?$v0RjO60RjO60U!_{5FijB5C8%J0s#Vnef|LkMS~zxVD9Sx0000ft diff --git a/app/src/main/res/layout/activity_bookmark_row.xml b/app/src/main/res/layout/activity_bookmark_row.xml index 6b02728b..a5245a79 100644 --- a/app/src/main/res/layout/activity_bookmark_row.xml +++ b/app/src/main/res/layout/activity_bookmark_row.xml @@ -4,14 +4,15 @@ android:id="@+id/bookmark_row" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="4dp" - android:layout_marginTop="4dp" android:background="?attr/selectableItemBackground" android:clickable="true" android:focusable="true" + android:gravity="center_vertical" android:orientation="horizontal" + android:paddingBottom="6dp" android:paddingEnd="16dp" - android:paddingStart="16dp"> + android:paddingStart="16dp" + android:paddingTop="6dp">