diff --git a/app/build.gradle b/app/build.gradle
index ac5a28c4..aab5c5d6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
applicationId "gr.thmmy.mthmmy"
minSdkVersion 19
targetSdkVersion 25
- versionCode 1
- versionName "1.0.0"
+ versionCode 2
+ versionName "1.0.1"
archivesBaseName = "mTHMMY-v$versionName"
}
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 bedc7ed1..9b7071f5 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
@@ -2,6 +2,7 @@ package gr.thmmy.mthmmy.activities.board;
import android.content.DialogInterface;
import android.content.Intent;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
@@ -28,6 +29,7 @@ import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.base.BaseActivity;
import gr.thmmy.mthmmy.model.Board;
+import gr.thmmy.mthmmy.model.LinkTarget;
import gr.thmmy.mthmmy.model.Topic;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mthmmy.utils.Report;
@@ -74,6 +76,12 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
Bundle extras = getIntent().getExtras();
boardTitle = extras.getString(BUNDLE_BOARD_TITLE);
boardUrl = extras.getString(BUNDLE_BOARD_URL);
+ LinkTarget.Target target = LinkTarget.resolveLinkTarget(Uri.parse(boardUrl));
+ if (!target.is(LinkTarget.Target.BOARD)) {
+ Report.e(TAG, "Bundle came with a non board url!\nUrl:\n" + boardUrl);
+ Toast.makeText(this, "An error has occurred\nAborting.", Toast.LENGTH_SHORT).show();
+ finish();
+ }
//Initializes graphics
toolbar = (Toolbar) findViewById(R.id.toolbar);
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 8b5d14b1..307f1b33 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
@@ -183,7 +183,7 @@ public class RecentFragment extends BaseFragment {
private void parse(Document document) {
Elements recent = document.select("#block8 :first-child div");
- if (recent.size() == 30) {
+ if (!recent.isEmpty()) {
topicSummaries.clear();
for (int i = 0; i < recent.size(); i += 3) {
@@ -210,7 +210,6 @@ public class RecentFragment extends BaseFragment {
return;
}
-
topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime));
}
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 5899efae..66e85146 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
@@ -2,6 +2,7 @@ package gr.thmmy.mthmmy.activities.profile;
import android.content.DialogInterface;
import android.content.Intent;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
@@ -38,6 +39,7 @@ 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.model.LinkTarget;
import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.utils.CircleTransform;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
@@ -86,6 +88,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
private String personalText;
private String profileUrl;
private String username;
+ private int tabSelect;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -162,6 +165,20 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
});
}
+ LinkTarget.Target target = LinkTarget.resolveLinkTarget(Uri.parse(profileUrl));
+ if (!target.is(LinkTarget.Target.PROFILE)) {
+ Report.e(TAG, "Bundle came with a non profile url!\nUrl:\n" + profileUrl);
+ Toast.makeText(this, "An error has occurred\n Aborting.", Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ if (target.is(LinkTarget.Target.PROFILE_STATS)) {
+ profileUrl = profileUrl.substring(0, profileUrl.indexOf(";sa=statPanel"));
+ tabSelect = 2;
+ } else if (target.is(LinkTarget.Target.PROFILE_LATEST_POSTS)) {
+ profileUrl = profileUrl.substring(0, profileUrl.indexOf(";sa=showPosts"));
+ tabSelect = 1;
+ }
+
profileTask = new ProfileTask();
profileTask.execute(profileUrl); //Attempts data parsing
}
@@ -258,6 +275,10 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
setupViewPager(viewPager, profilePage);
TabLayout tabLayout = (TabLayout) findViewById(R.id.profile_tabs);
tabLayout.setupWithViewPager(viewPager);
+ if (tabSelect != 0) {
+ TabLayout.Tab tab = tabLayout.getTabAt(tabSelect);
+ if (tab != null) tab.select();
+ }
}
}
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 c7ca6b73..3943bf0d 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
@@ -2,6 +2,7 @@ package gr.thmmy.mthmmy.activities.topic;
import android.content.DialogInterface;
import android.content.Intent;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@@ -28,6 +29,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.model.LinkTarget;
import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.utils.ParseHelpers;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
@@ -99,7 +101,14 @@ public class TopicActivity extends BaseActivity {
setContentView(R.layout.activity_topic);
Bundle extras = getIntent().getExtras();
- topicTitle = extras.getString("TOPIC_TITLE");
+ 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));
+ Toast.makeText(this, "An error has occurred\n Aborting.", Toast.LENGTH_SHORT).show();
+ finish();
+ }
//Initializes graphics
toolbar = (Toolbar) findViewById(R.id.toolbar);
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 7c69d9ef..f44e3a65 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,6 +16,7 @@ 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;
@@ -632,7 +633,7 @@ class TopicAdapter extends RecyclerView.Adapter Class has one constructor:
- * and the methods:
Class has one constructor, {@link #ThmmyFile(URL, String, String)}.
*/
public class ThmmyFile {
/**
@@ -33,9 +32,22 @@ public class ThmmyFile {
private String extension, filePath;
private File file;
+ /**
+ * 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 constructor only creates a ThmmyFile object and does not download the file. To download
- * the file use {@link #download()} or {@link #download()}!
+ * the file use {@link #download(Context)}!
*
* @param fileUrl {@link URL} object with file's url
* @param filename {@link String} with desired file name
@@ -63,7 +75,7 @@ public class ThmmyFile {
}
/**
- * This is null until {@link #download()} or {@link #download()} is called and has succeeded.
+ * This is null until {@link #download(Context)} is called and has succeeded.
*
* @return String with file's extension or null
*/
@@ -73,7 +85,7 @@ public class ThmmyFile {
}
/**
- * This is null until {@link #download()} or {@link #download()} is called and has succeeded.
+ * This is null until {@link #download(Context)} is called and has succeeded.
*
* @return String with file's path or null
*/
@@ -83,7 +95,7 @@ public class ThmmyFile {
}
/**
- * This is null until {@link #download()} or {@link #download()} is called and has succeeded.
+ * This is null until {@link #download(Context)} is called and has succeeded.
*
* @return {@link File} or null
*/
@@ -112,7 +124,10 @@ public class ThmmyFile {
* @throws SecurityException if the requested file is not hosted by the forum.
*/
@Nullable
- public File download() throws IOException, SecurityException {
+ public File download(Context context) throws IOException, SecurityException, OutOfMemoryError {
+ if (fileUrl == null) {
+ return null;
+ }
if (!Objects.equals(fileUrl.getHost(), "www.thmmy.gr"))
throw new SecurityException("Downloading files from other sources is not supported");
@@ -122,7 +137,7 @@ public class ThmmyFile {
if (!response.isSuccessful()) {
throw new IOException("Failed to download file: " + response);
}
- file = getOutputMediaFile(filename);
+ file = getOutputMediaFile(context, filename, fileInfo);
if (file == null) {
Report.d(TAG, "Error creating media file, check storage permissions!");
} else {
@@ -138,24 +153,40 @@ public class ThmmyFile {
}
@Nullable
- private static File getOutputMediaFile(String fileName) {
- // To be safe, you should check that the SDCard is mounted
- // using Environment.getExternalStorageState() before doing this.
- File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
- + "/Android/data/gr.thmmy.mthmmy/"
- + "Downloads/");
-
- // This location works best if you want the created files to be shared
- // between applications and persist after your app has been uninstalled.
+ 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.getExternalStorageDirectory()
+ + "/Android/data/gr.thmmy.mthmmy/"
+ + "Downloads/");
+ } else {
+ mediaStorageDir = new File(context.getFilesDir(), "Downloads");
+ }
- // Create the storage directory if it does not exist
+ //Creates the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Report.d(TAG, "problem!");
- return null;
+ 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!");
}
}
- // Create a media file name
+
+ //Creates a media file name
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + fileName);
return mediaFile;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java
index cb0b772c..2520cc89 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ParseHelpers.java
@@ -119,6 +119,9 @@ public class ParseHelpers {
if (warning.text().contains("The topic or board you are looking for appears " +
"to be either missing or off limits to you."))
return UNAUTHORIZED_OR_MISSING;
+ else if (warning.text().contains("Το θέμα ή πίνακας που ψάχνετε ή δεν υπάρχει ή " +
+ "δεν είναι προσβάσιμο από εσάς. "))
+ return UNAUTHORIZED_OR_MISSING;
}
}
return READY;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java
index 8c818bc9..58ba1a62 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java
@@ -12,7 +12,9 @@ import android.view.View;
* otherwise.
*/
@SuppressWarnings("WeakerAccess")
-public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior