diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f95392f4..8a57fcbc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + package="gr.thmmy.mthmmy" + android:installLocation="auto"> 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 82100a2d..710170fa 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,5 +1,6 @@ package gr.thmmy.mthmmy.activities.topic; +import android.content.Intent; import android.graphics.Rect; import android.net.Uri; import android.os.AsyncTask; @@ -11,7 +12,6 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Html; -import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.method.LinkMovementMethod; import android.text.method.ScrollingMovementMethod; @@ -39,6 +39,8 @@ import java.util.ArrayList; 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.Bookmark; import gr.thmmy.mthmmy.model.Post; @@ -51,6 +53,12 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; import static gr.thmmy.mthmmy.activities.topic.ReplyParser.replyStatus; /** @@ -621,14 +629,33 @@ public class TopicActivity extends BaseActivity { postsList.addAll(TopicParser.parseTopic(topic, language)); } - private void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span) - { + private void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span) { int start = strBuilder.getSpanStart(span); int end = strBuilder.getSpanEnd(span); int flags = strBuilder.getSpanFlags(span); ClickableSpan clickable = new ClickableSpan() { + @Override public void onClick(View view) { - //TODO + ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(Uri.parse(span.getURL())); + if (target.is(ThmmyPage.PageCategory.BOARD)) { + Intent intent = new Intent(getApplicationContext(), BoardActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_BOARD_URL, span.getURL()); + extras.putString(BUNDLE_BOARD_TITLE, ""); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + getApplicationContext().startActivity(intent); + } else if (target.is(ThmmyPage.PageCategory.PROFILE)) { + Intent intent = new Intent(getApplicationContext(), ProfileActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_PROFILE_URL, span.getURL()); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); + extras.putString(BUNDLE_PROFILE_USERNAME, ""); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + getApplicationContext().startActivity(intent); + } else if (target.is(ThmmyPage.PageCategory.INDEX)) + finish(); } }; strBuilder.setSpan(clickable, start, end, flags); @@ -639,7 +666,7 @@ public class TopicActivity extends BaseActivity { CharSequence sequence = Html.fromHtml(html); SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence); URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class); - for(URLSpan span : urls) { + for (URLSpan span : urls) { makeLinkClickable(strBuilder, span); } return strBuilder; 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 035933cf..59c529af 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java @@ -18,6 +18,7 @@ import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -198,34 +199,52 @@ class TopicAdapter extends RecyclerView.Adapter { holder.postNum.setText(""); holder.subject.setText(currentPost.getSubject()); holder.post.loadDataWithBaseURL("file:///android_asset/", currentPost.getContent(), "text/html", "UTF-8", null); - if (currentPost.getAttachedFiles() != null && currentPost.getAttachedFiles().size() != 0) { + if ((currentPost.getAttachedFiles() != null && currentPost.getAttachedFiles().size() != 0) + || (currentPost.getLastEdit() != null)) { holder.bodyFooterDivider.setVisibility(View.VISIBLE); - int filesTextColor; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - filesTextColor = context.getResources().getColor(R.color.accent, null); - } 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); - attached.setClickable(true); - attached.setTypeface(Typeface.createFromAsset(context.getAssets() - , "fonts/fontawesome-webfont.ttf")); - attached.setText(faIconFromFilename(attachedFile.getFilename()) + " " - + attachedFile.getFilename() + attachedFile.getFileInfo()); - attached.setTextColor(filesTextColor); - attached.setPadding(0, 3, 0, 3); - - attached.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - ((BaseActivity) context).launchDownloadService(attachedFile); - } - }); - holder.postFooter.addView(attached); + if (currentPost.getAttachedFiles() != null && currentPost.getAttachedFiles().size() != 0) { + int filesTextColor; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + filesTextColor = context.getResources().getColor(R.color.accent, null); + } else //noinspection deprecation + filesTextColor = context.getResources().getColor(R.color.accent); + + for (final ThmmyFile attachedFile : currentPost.getAttachedFiles()) { + final TextView attached = new TextView(context); + attached.setTextSize(10f); + attached.setClickable(true); + attached.setTypeface(Typeface.createFromAsset(context.getAssets() + , "fonts/fontawesome-webfont.ttf")); + attached.setText(faIconFromFilename(attachedFile.getFilename()) + " " + + attachedFile.getFilename() + attachedFile.getFileInfo()); + attached.setTextColor(filesTextColor); + attached.setPadding(0, 3, 0, 3); + + attached.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ((BaseActivity) context).launchDownloadService(attachedFile); + } + }); + + holder.postFooter.addView(attached); + } + } + if (currentPost.getLastEdit() != null && currentPost.getLastEdit().length() > 0) { + int lastEditTextColor; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + lastEditTextColor = context.getResources().getColor(R.color.white, null); + } else //noinspection deprecation + lastEditTextColor = context.getResources().getColor(R.color.white); + + final TextView lastEdit = new TextView(context); + lastEdit.setTextSize(12f); + lastEdit.setText(currentPost.getLastEdit()); + lastEdit.setTextColor(lastEditTextColor); + lastEdit.setPadding(0, 3, 0, 3); + holder.postFooter.addView(lastEdit); } } else { holder.bodyFooterDivider.setVisibility(View.GONE); @@ -312,24 +331,27 @@ class TopicAdapter extends RecyclerView.Adapter { } if (!currentPost.isDeleted()) { //Sets graphics behavior + holder.thumbnail.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + //Clicking the thumbnail opens user's profile + Intent intent = new Intent(context, ProfileActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL()); + if (currentPost.getThumbnailUrl() == null) + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); + else + 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); + } + }); holder.header.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - //Clicking an expanded header starts profile activity - if (viewProperties.get(holder.getAdapterPosition())[isUserExtraInfoVisibile]) { - Intent intent = new Intent(context, ProfileActivity.class); - Bundle extras = new Bundle(); - extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL()); - if (currentPost.getThumbnailUrl() == null) - extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); - else - 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); - } - + //Clicking the header makes it expand/collapse boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); tmp[isUserExtraInfoVisibile] = !tmp[isUserExtraInfoVisibile]; viewProperties.set(holder.getAdapterPosition(), tmp); @@ -341,7 +363,7 @@ class TopicAdapter extends RecyclerView.Adapter { @Override public void onClick(View v) { boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); - tmp[1] = false; + tmp[isUserExtraInfoVisibile] = false; viewProperties.set(holder.getAdapterPosition(), tmp); TopicAnimations.animateUserExtraInfoVisibility(v); 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 9cab0649..9229c6b9 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 @@ -160,7 +160,7 @@ class TopicParser { for (Element thisRow : postRows) { //Variables for Post constructor String p_userName, p_thumbnailUrl, p_subject, p_post, p_postDate, p_profileURL, p_rank, - p_specialRank, p_gender, p_personalText, p_numberOfPosts; + p_specialRank, p_gender, p_personalText, p_numberOfPosts, p_postLastEditDate; int p_postNum, p_postIndex, p_numberOfStars, p_userColor; boolean p_isDeleted = false; ArrayList p_attachedFiles; @@ -175,6 +175,7 @@ class TopicParser { p_numberOfStars = 0; p_userColor = USER_COLOR_YELLOW; p_attachedFiles = new ArrayList<>(); + p_postLastEditDate = null; //Language independent parsing //Finds thumbnail url @@ -190,11 +191,11 @@ class TopicParser { //Finds post's text p_post = ParseHelpers.youtubeEmbeddedFix(thisRow.select("div").select(".post").first()); - //Add stuff to make it work in WebView + //Adds stuff to make it work in WebView //style.css p_post = ("" + p_post); - //Find post's index + //Finds post's index //This is an int assigned by the forum used for post focusing and quotes, it is not //the same as reply index. Element postIndex = thisRow.select("a[name^=msg]").first(); @@ -205,6 +206,10 @@ class TopicParser { p_postIndex = Integer.parseInt(tmp.substring(tmp.indexOf("msg") + 3)); } + Element postLastEditDate = thisRow.select("td.smalltext[id^=modified_]").first(); + if (postLastEditDate != null && !Objects.equals(postLastEditDate.text(), "")) + p_postLastEditDate = postLastEditDate.text(); + //Language dependent parsing Element userName; if (language.is(ParseHelpers.Language.GREEK)) { @@ -406,12 +411,12 @@ class TopicParser { parsedPostsList.add(new Post(p_thumbnailUrl, p_userName, p_subject, p_post, p_postIndex , p_postNum, p_postDate, p_profileURL, p_rank, p_specialRank, p_gender , p_numberOfPosts, p_personalText, p_numberOfStars, p_userColor - , p_attachedFiles)); + , p_attachedFiles, p_postLastEditDate)); } else { //Deleted user //Add new post in postsList, only standard information needed parsedPostsList.add(new Post(p_thumbnailUrl, p_userName, p_subject, p_post, p_postIndex - , p_postNum, p_postDate, p_userColor, p_attachedFiles)); + , p_postNum, p_postDate, p_userColor, p_attachedFiles, p_postLastEditDate)); } } return parsedPostsList; 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 15b6afe6..baf8cc20 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Post.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Post.java @@ -27,6 +27,7 @@ public class Post { private final boolean isDeleted; private final int userColor; private final ArrayList attachedFiles; + private final String lastEdit; //Extra info private final String profileURL; @@ -57,6 +58,7 @@ public class Post { personalText = ""; numberOfStars = 0; attachedFiles = null; + lastEdit = null; } /** @@ -80,12 +82,13 @@ public class Post { * @param numberOfStars author's number of stars * @param userColor author's user color * @param attachedFiles post's attached files + * @param lastEdit post's last edit date */ public Post(@Nullable String thumbnailUrl, String author, String subject, String content , int postIndex, int postNumber, String postDate, String profileURl, @Nullable String rank , @Nullable String special_rank, @Nullable String gender, @Nullable String numberOfPosts , @Nullable String personalText, int numberOfStars, int userColor - , @Nullable ArrayList attachedFiles) { + , @Nullable ArrayList attachedFiles, @Nullable String lastEdit) { if (Objects.equals(thumbnailUrl, "")) this.thumbnailUrl = null; else this.thumbnailUrl = thumbnailUrl; this.author = author; @@ -97,6 +100,7 @@ public class Post { this.isDeleted = false; this.userColor = userColor; this.attachedFiles = attachedFiles; + this.lastEdit = lastEdit; this.profileURL = profileURl; this.rank = rank; this.specialRank = special_rank; @@ -120,10 +124,11 @@ public class Post { * @param postDate date of submission * @param userColor author's user color * @param attachedFiles post's attached files + * @param lastEdit post's last edit date */ public Post(@Nullable String thumbnailUrl, String author, String subject, String content , int postIndex, int postNumber, String postDate, int userColor - , @Nullable ArrayList attachedFiles) { + , @Nullable ArrayList attachedFiles, @Nullable String lastEdit) { if (Objects.equals(thumbnailUrl, "")) this.thumbnailUrl = null; else this.thumbnailUrl = thumbnailUrl; this.author = author; @@ -135,6 +140,7 @@ public class Post { this.isDeleted = true; this.userColor = userColor; this.attachedFiles = attachedFiles; + this.lastEdit = lastEdit; profileURL = null; rank = "Rank"; specialRank = "Special rank"; @@ -310,4 +316,14 @@ public class Post { public ArrayList getAttachedFiles() { return attachedFiles; } + + /** + * Gets this post's last edit date or null if post hasn't been edited. + * + * @return date of last edit or null + */ + @Nullable + public String getLastEdit() { + return lastEdit; + } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7af0467a..c864d4e3 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -16,7 +16,8 @@ #323232 #3C3F41 #8B8B8B - #4B0082 + + #FF9800 #FFFFFF #CCCCCC