Browse Source

Optimizations & Cleanup

pull/68/head
Ezerous 5 years ago
parent
commit
d5ed7f81c7
No known key found for this signature in database GPG Key ID: 262B2954BBA319E3
  1. 14
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
  2. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java
  3. 21
      app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java
  4. 18
      app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
  5. 22
      app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java
  6. 13
      app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
  7. 11
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
  8. 2
      app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
  9. 39
      app/src/main/java/gr/thmmy/mthmmy/model/Topic.java
  10. 55
      app/src/main/java/gr/thmmy/mthmmy/model/TopicSummary.java
  11. 22
      app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParser.java
  12. 2
      app/src/main/res/values/strings.xml
  13. 2
      app/src/main/res/xml-v26/app_preferences_guest.xml
  14. 2
      app/src/main/res/xml-v26/app_preferences_user.xml
  15. 2
      app/src/main/res/xml/app_preferences_guest.xml
  16. 2
      app/src/main/res/xml/app_preferences_user.xml
  17. 46
      app/src/test/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParserTest.java

14
app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java

@ -277,7 +277,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (topicRows != null && !topicRows.isEmpty()) { if (topicRows != null && !topicRows.isEmpty()) {
for (Element topicRow : topicRows) { for (Element topicRow : topicRows) {
if (!Objects.equals(topicRow.className(), "titlebg")) { if (!Objects.equals(topicRow.className(), "titlebg")) {
String pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl, pStats; String pTopicUrl, pSubject, pStarter, pLastUser="", pLastPostDateTime="00:00:00", pLastPost, pLastPostUrl, pStats;
boolean pLocked = false, pSticky = false, pUnread = false; boolean pLocked = false, pSticky = false, pUnread = false;
Elements topicColumns = topicRow.select(">td"); Elements topicColumns = topicRow.select(">td");
{ {
@ -292,21 +292,21 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (column.select("a[id^=newicon]").first() != null) if (column.select("a[id^=newicon]").first() != null)
pUnread = true; pUnread = true;
} }
pStartedBy = topicColumns.get(3).text(); pStarter = topicColumns.get(3).text();
pStats = "Replies: " + topicColumns.get(4).text() + ", Views: " + topicColumns.get(5).text(); pStats = "Replies: " + topicColumns.get(4).text() + ", Views: " + topicColumns.get(5).text();
pLastPost = topicColumns.last().text(); pLastPost = topicColumns.last().text();
if (pLastPost.contains("by")) { if (pLastPost.contains("by")) {
pLastPost = pLastPost.substring(0, pLastPost.indexOf("by")) + pLastPostDateTime = pLastPost.substring(0, pLastPost.indexOf("by") -1);
"\n" + pLastPost.substring(pLastPost.indexOf("by")); pLastUser = pLastPost.substring(pLastPost.indexOf("by") + 3);
} else if (pLastPost.contains("από")) { } else if (pLastPost.contains("από")) {
pLastPost = pLastPost.substring(0, pLastPost.indexOf("από")) + pLastPostDateTime = pLastPost.substring(0, pLastPost.indexOf("από") - 1);
"\n" + pLastPost.substring(pLastPost.indexOf("από")); pLastUser = pLastPost.substring(pLastPost.indexOf("από") + 4);
} else { } else {
Timber.wtf("Board parsing about to fail. pLastPost came with: %s", pLastPost); Timber.wtf("Board parsing about to fail. pLastPost came with: %s", pLastPost);
} }
pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href"); pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href");
tempTopics.add(new Topic(pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl, tempTopics.add(new Topic(pTopicUrl, pSubject, pStarter, pLastUser, pLastPostDateTime, pLastPostUrl,
pStats, pLocked, pSticky, pUnread)); pStats, pLocked, pSticky, pUnread));
} }
} }

4
app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java

@ -187,7 +187,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
topicViewHolder.topicRow.setOnClickListener(view -> { topicViewHolder.topicRow.setOnClickListener(view -> {
Intent intent = new Intent(context, TopicActivity.class); Intent intent = new Intent(context, TopicActivity.class);
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putString(BUNDLE_TOPIC_URL, topic.getUrl()); extras.putString(BUNDLE_TOPIC_URL, topic.getTopicUrl());
extras.putString(BUNDLE_TOPIC_TITLE, topic.getSubject()); extras.putString(BUNDLE_TOPIC_TITLE, topic.getSubject());
intent.putExtras(extras); intent.putExtras(extras);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
@ -232,7 +232,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
topicViewHolder.topicSubject.setText(lockedSticky); topicViewHolder.topicSubject.setText(lockedSticky);
topicViewHolder.topicStartedBy.setText(context.getString(R.string.topic_started_by, topic.getStarter())); topicViewHolder.topicStartedBy.setText(context.getString(R.string.topic_started_by, topic.getStarter()));
topicViewHolder.topicStats.setText(topic.getStats()); topicViewHolder.topicStats.setText(topic.getStats());
topicViewHolder.topicLastPost.setText(context.getString(R.string.topic_last_post, topic.getLastPostDateAndTime())); topicViewHolder.topicLastPost.setText(context.getString(R.string.topic_last_post, topic.getLastPostDateTime(), topic.getLastUser()));
topicViewHolder.topicLastPost.setOnClickListener(view -> { topicViewHolder.topicLastPost.setOnClickListener(view -> {
Intent intent = new Intent(context, TopicActivity.class); Intent intent = new Intent(context, TopicActivity.class);
Bundle extras = new Bundle(); Bundle extras = new Bundle();

21
app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java

@ -42,22 +42,23 @@ class RecentAdapter extends RecyclerView.Adapter<RecentAdapter.ViewHolder> {
@Override @Override
public void onBindViewHolder(final ViewHolder holder, final int position) { public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mTitleView.setText(recentList.get(position).getSubject()); TopicSummary topicSummary = recentList.get(position);
holder.mTitleView.setText(topicSummary.getSubject());
String dateTimeString = recentList.get(position).getDateTimeModified(); if(BaseApplication.getInstance().isDisplayRelativeTimeEnabled()){
if(BaseApplication.getInstance().isDisplayRelativeTimeEnabled()) String timestamp = topicSummary.getLastPostTimestamp();
try{ try{
holder.mDateTimeView.setReferenceTime(Long.valueOf(dateTimeString)); holder.mDateTimeView.setReferenceTime(Long.valueOf(timestamp));
} }
catch(NumberFormatException e){ catch(NumberFormatException e){
Timber.e(e, "Invalid number format: %s", dateTimeString); Timber.e(e, "Invalid number format: %s", timestamp);
holder.mDateTimeView.setText(dateTimeString); holder.mDateTimeView.setText(topicSummary.getLastPostSimplifiedDateTime());
}
} }
else else
holder.mDateTimeView.setText(dateTimeString); holder.mDateTimeView.setText(topicSummary.getLastPostSimplifiedDateTime());
holder.mUserView.setText(recentList.get(position).getLastUser()); holder.mUserView.setText(topicSummary.getLastUser());
holder.topic = recentList.get(position); holder.topic = topicSummary;
holder.mView.setOnClickListener(v -> { holder.mView.setOnClickListener(v -> {
if (null != mListener) { if (null != mListener) {

18
app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java

@ -34,9 +34,6 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertDateTime;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp;
/** /**
* A {@link BaseFragment} subclass. * A {@link BaseFragment} subclass.
@ -189,21 +186,12 @@ public class RecentFragment extends BaseFragment {
String dateTime = recent.get(i + 2).text(); String dateTime = recent.get(i + 2).text();
pattern = Pattern.compile("\\[(.*)]"); pattern = Pattern.compile("\\[(.*)]");
matcher = pattern.matcher(dateTime); matcher = pattern.matcher(dateTime);
if (matcher.find()){ if (matcher.find())
dateTime = matcher.group(1); fetchedRecent.add(new TopicSummary(link, title, lastUser, matcher.group(1)));
if (BaseApplication.getInstance().isDisplayRelativeTimeEnabled()) {
dateTime=convertDateTime(dateTime, false);
String timestamp = convertToTimestamp(dateTime);
if(timestamp!=null)
dateTime=timestamp;
}
else
dateTime=convertDateTime(dateTime, true);
}
else else
throw new ParseException("Parsing failed (dateTime)"); throw new ParseException("Parsing failed (dateTime)");
fetchedRecent.add(new TopicSummary(link, title, lastUser, dateTime));
} }
return fetchedRecent; return fetchedRecent;
} }

22
app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java

@ -36,7 +36,7 @@ class UnreadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (unreadList.get(position).getDateTimeModified() == null) return VIEW_TYPE_MARK_READ; if (unreadList.get(position).getLastPostDateTime() == null) return VIEW_TYPE_MARK_READ;
return unreadList.get(position).getTopicUrl() == null ? VIEW_TYPE_NADA : VIEW_TYPE_ITEM; return unreadList.get(position).getTopicUrl() == null ? VIEW_TYPE_NADA : VIEW_TYPE_ITEM;
} }
@ -61,29 +61,29 @@ class UnreadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
TopicSummary topicSummary = unreadList.get(holder.getAdapterPosition());
if (holder instanceof UnreadAdapter.EmptyViewHolder) { if (holder instanceof UnreadAdapter.EmptyViewHolder) {
final UnreadAdapter.EmptyViewHolder emptyViewHolder = (UnreadAdapter.EmptyViewHolder) holder; final UnreadAdapter.EmptyViewHolder emptyViewHolder = (UnreadAdapter.EmptyViewHolder) holder;
emptyViewHolder.text.setText(unreadList.get(holder.getAdapterPosition()).getDateTimeModified()); emptyViewHolder.text.setText(topicSummary.getLastPostDateTime());
} else if (holder instanceof UnreadAdapter.ViewHolder) { } else if (holder instanceof UnreadAdapter.ViewHolder) {
final UnreadAdapter.ViewHolder viewHolder = (UnreadAdapter.ViewHolder) holder; final UnreadAdapter.ViewHolder viewHolder = (UnreadAdapter.ViewHolder) holder;
viewHolder.mTitleView.setText(unreadList.get(holder.getAdapterPosition()).getSubject()); viewHolder.mTitleView.setText(topicSummary.getSubject());
String dateTimeString=unreadList.get(holder.getAdapterPosition()).getDateTimeModified();
if(BaseApplication.getInstance().isDisplayRelativeTimeEnabled()){ if(BaseApplication.getInstance().isDisplayRelativeTimeEnabled()){
String timestamp = topicSummary.getLastPostTimestamp();
try{ try{
viewHolder.mDateTimeView.setReferenceTime(Long.valueOf(dateTimeString)); viewHolder.mDateTimeView.setReferenceTime(Long.valueOf(timestamp));
} }
catch(NumberFormatException e){ catch(NumberFormatException e){
Timber.e(e, "Invalid number format."); Timber.e(e, "Invalid number format: %s", timestamp);
viewHolder.mDateTimeView.setText(dateTimeString); viewHolder.mDateTimeView.setText(topicSummary.getLastPostSimplifiedDateTime());
} }
} }
else else
viewHolder.mDateTimeView.setText(dateTimeString); viewHolder.mDateTimeView.setText(topicSummary.getLastPostSimplifiedDateTime());
viewHolder.mUserView.setText(unreadList.get(position).getLastUser()); viewHolder.mUserView.setText(topicSummary.getLastUser());
viewHolder.topic = unreadList.get(holder.getAdapterPosition()); viewHolder.topic = topicSummary;
viewHolder.mView.setOnClickListener(v -> { viewHolder.mView.setOnClickListener(v -> {
if (null != mListener) { if (null != mListener) {

13
app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java

@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary; import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.session.SessionManager;
@ -37,9 +36,6 @@ import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertDateTime;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp;
/** /**
* A {@link BaseFragment} subclass. * A {@link BaseFragment} subclass.
* Activities that contain this fragment must implement the * Activities that contain this fragment must implement the
@ -219,15 +215,6 @@ public class UnreadFragment extends BaseFragment {
dateTime = dateTime.replace("<b>", ""); dateTime = dateTime.replace("<b>", "");
dateTime = dateTime.replace("</b>", ""); dateTime = dateTime.replace("</b>", "");
if (BaseApplication.getInstance().isDisplayRelativeTimeEnabled()) {
dateTime=convertDateTime(dateTime, false);
String timestamp = convertToTimestamp(dateTime);
if(timestamp!=null)
dateTime=timestamp;
}
else
dateTime=convertDateTime(dateTime, true);
fetchedTopicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); fetchedTopicSummaries.add(new TopicSummary(link, title, lastUser, dateTime));
} }
Element topBar = document.select("table:not(.bordercolor):not(#bodyarea):has(td.middletext)").first(); Element topBar = document.select("table:not(.bordercolor):not(#bodyarea):has(td.middletext)").first();

11
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java

@ -18,6 +18,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.model.Poll; import gr.thmmy.mthmmy.model.Poll;
import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.model.ThmmyFile;
@ -25,6 +26,8 @@ import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import timber.log.Timber; import timber.log.Timber;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp;
/** /**
* Singleton used for parsing a topic. * Singleton used for parsing a topic.
@ -175,6 +178,7 @@ public class TopicParser {
p_specialRank, p_gender, p_personalText, p_numberOfPosts, p_postLastEditDate, p_specialRank, p_gender, p_personalText, p_numberOfPosts, p_postLastEditDate,
p_postURL, p_deletePostURL, p_editPostURL; p_postURL, p_deletePostURL, p_editPostURL;
int p_postNum, p_postIndex, p_numberOfStars, p_userColor; int p_postNum, p_postIndex, p_numberOfStars, p_userColor;
long p_timestamp;
boolean p_isDeleted = false, p_isUserMentionedInPost = false; boolean p_isDeleted = false, p_isUserMentionedInPost = false;
ArrayList<ThmmyFile> p_attachedFiles; ArrayList<ThmmyFile> p_attachedFiles;
@ -191,6 +195,7 @@ public class TopicParser {
p_postLastEditDate = null; p_postLastEditDate = null;
p_deletePostURL = null; p_deletePostURL = null;
p_editPostURL = null; p_editPostURL = null;
p_timestamp = 0;
//Language independent parsing //Language independent parsing
//Finds thumbnail url //Finds thumbnail url
@ -267,6 +272,12 @@ public class TopicParser {
p_postDate = p_postDate.substring(p_postDate.indexOf("στις:") + 6 p_postDate = p_postDate.substring(p_postDate.indexOf("στις:") + 6
, p_postDate.indexOf(" »")); , p_postDate.indexOf(" »"));
if (BaseApplication.getInstance().isDisplayRelativeTimeEnabled()) {
String timestamp = convertToTimestamp(p_postDate);
if(timestamp!=null)
p_timestamp = Long.valueOf(timestamp);
}
//Finds post's reply index number //Finds post's reply index number
Element postNum = thisRow.select("div.smalltext:matches(Απάντηση #)").first(); Element postNum = thisRow.select("div.smalltext:matches(Απάντηση #)").first();
if (postNum == null) { //Topic starter if (postNum == null) { //Topic starter

2
app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java

@ -183,7 +183,7 @@ public class BaseApplication extends Application {
heightPxl = displayMetrics.heightPixels; heightPxl = displayMetrics.heightPixels;
displayRelativeTime = settingsSharedPrefs.getBoolean(DISPLAY_RELATIVE_TIME, false); displayRelativeTime = settingsSharedPrefs.getBoolean(DISPLAY_RELATIVE_TIME, true);
} }
//Getters //Getters

39
app/src/main/java/gr/thmmy/mthmmy/model/Topic.java

@ -8,7 +8,7 @@ package gr.thmmy.mthmmy.model;
* not, whether it's sticky or not and whether it contains an unread post or not.</b>. * not, whether it's sticky or not and whether it contains an unread post or not.</b>.
*/ */
public class Topic extends TopicSummary { public class Topic extends TopicSummary {
private final String lastPostUrl, stats; private final String lastPostUrl, starter, stats;
private final boolean locked, sticky, unread; private final boolean locked, sticky, unread;
// Suppresses default constructor // Suppresses default constructor
@ -16,6 +16,7 @@ public class Topic extends TopicSummary {
private Topic() { private Topic() {
super(); super();
this.lastPostUrl = null; this.lastPostUrl = null;
this.starter = null;
this.stats = null; this.stats = null;
this.locked = false; this.locked = false;
this.sticky = false; this.sticky = false;
@ -29,57 +30,31 @@ public class Topic extends TopicSummary {
* @param topicUrl this topic's url * @param topicUrl this topic's url
* @param subject this topic's subject * @param subject this topic's subject
* @param starter this topic starter's username * @param starter this topic starter's username
* @param lastPost username of topic's last post's author * @param lastUser username of topic's last post's author
* @param lastPostUrl url of topic's last post * @param lastPostUrl url of topic's last post
* @param stats this topic's view and reply stats * @param stats this topic's view and reply stats
* @param locked whether this topic is locked or not * @param locked whether this topic is locked or not
* @param sticky whether this topic is sticky or not * @param sticky whether this topic is sticky or not
* @param unread whether this topic contains an unread post or not * @param unread whether this topic contains an unread post or not
*/ */
public Topic(String topicUrl, String subject, String starter, String lastPost, String lastPostUrl, public Topic(String topicUrl, String subject, String starter, String lastUser, String LastPostDateTime, String lastPostUrl,
String stats, boolean locked, boolean sticky, boolean unread) { String stats, boolean locked, boolean sticky, boolean unread) {
super(topicUrl, subject, starter, lastPost); super(topicUrl, subject, lastUser, LastPostDateTime);
this.lastPostUrl = lastPostUrl; this.lastPostUrl = lastPostUrl;
this.starter = starter;
this.stats = stats; this.stats = stats;
this.locked = locked; this.locked = locked;
this.sticky = sticky; this.sticky = sticky;
this.unread = unread; this.unread = unread;
} }
/**
* Gets this topic's url.
*
* @return this topic's url
*/
public String getUrl() {
return topicUrl;
}
/**
* Gets this topic's subject.
*
* @return this topic's subject
*/
public String getSubject() {
return subject;
}
/** /**
* Gets this topic's starter username. * Gets this topic's starter username.
* *
* @return this topic's starter username * @return this topic's starter username
*/ */
public String getStarter() { public String getStarter() {
return lastUser; return starter;
}
/**
* Gets this topic's last post's date and time.
*
* @return last post's date and time
*/
public String getLastPostDateAndTime() {
return dateTimeModified;
} }
/** /**

55
app/src/main/java/gr/thmmy/mthmmy/model/TopicSummary.java

@ -1,5 +1,8 @@
package gr.thmmy.mthmmy.model; package gr.thmmy.mthmmy.model;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.simplifyDateTime;
/** /**
* Class that defines the summary of a topic. All member variables are declared final (thus no * Class that defines the summary of a topic. All member variables are declared final (thus no
* setters are supplied). Class has one constructor and getter methods for all variables. * setters are supplied). Class has one constructor and getter methods for all variables.
@ -7,10 +10,12 @@ package gr.thmmy.mthmmy.model;
* time of this topic's last post.</b>. * time of this topic's last post.</b>.
*/ */
public class TopicSummary { public class TopicSummary {
final String topicUrl; private final String topicUrl;
final String subject; private final String subject;
final String lastUser; private final String lastUser;
final String dateTimeModified; private final String lastPostDateTime;
private final String lastPostSimplifiedDateTime;
private final String lastPostTimestamp;
// Suppresses default constructor // Suppresses default constructor
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -18,23 +23,27 @@ public class TopicSummary {
this.topicUrl = null; this.topicUrl = null;
this.subject = null; this.subject = null;
this.lastUser = null; this.lastUser = null;
this.dateTimeModified = null; this.lastPostDateTime = null;
this.lastPostSimplifiedDateTime = null;
this.lastPostTimestamp = null;
} }
/** /**
* Constructor specifying all class variables necessary to summarise this topic. All variables * Constructor specifying all class variables necessary to summarize this topic. All variables
* are declared final, once assigned they can not change. * are declared final, once assigned they can not change.
* *
* @param topicUrl this topic's url * @param topicUrl this topic's url
* @param subject this topic's subject * @param subject this topic's subject
* @param lastUser username of this topic's last author * @param lastUser username of this topic's last post's author
* @param dateTimeModified this topic's date and time of last post * @param lastPostDateTime this topic's date and time of last post
*/ */
public TopicSummary(String topicUrl, String subject, String lastUser, String dateTimeModified) { public TopicSummary(String topicUrl, String subject, String lastUser, String lastPostDateTime) {
this.topicUrl = topicUrl; this.topicUrl = topicUrl;
this.subject = subject; this.subject = subject;
this.lastUser = lastUser; this.lastUser = lastUser;
this.dateTimeModified = dateTimeModified; this.lastPostDateTime = lastPostDateTime;
this.lastPostTimestamp = convertToTimestamp(lastPostDateTime);
this.lastPostSimplifiedDateTime = simplifyDateTime(lastPostDateTime);
} }
/** /**
@ -56,9 +65,9 @@ public class TopicSummary {
} }
/** /**
* Gets username of this topic's last author. * Gets username of this topic's last post's author.
* *
* @return username of last author * @return username of last post's author
*/ */
public String getLastUser() { public String getLastUser() {
return lastUser; return lastUser;
@ -69,7 +78,25 @@ public class TopicSummary {
* *
* @return this topic's date and time of last post * @return this topic's date and time of last post
*/ */
public String getDateTimeModified() { public String getLastPostDateTime() {
return dateTimeModified; return lastPostDateTime;
}
/**
* Gets this topic's simplified date and time of last post.
*
* @return this topic's simplified date and time of last post
*/
public String getLastPostSimplifiedDateTime() {
return lastPostSimplifiedDateTime;
}
/**
* Gets the timestamp of this topic's last post.
*
* @return the timestamp of this topic's last post
*/
public String getLastPostTimestamp() {
return lastPostTimestamp;
} }
} }

22
app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParser.java

@ -46,6 +46,9 @@ public class ThmmyDateTimeParser {
String originalDateTime = thmmyDateTime; String originalDateTime = thmmyDateTime;
DateTimeZone dtz = getDtz(); DateTimeZone dtz = getDtz();
// Remove any unnecessary "Today at" strings
thmmyDateTime = purifyTodayDateTime(thmmyDateTime);
// Add today's date for the first two cases // Add today's date for the first two cases
if(thmmyDateTime.charAt(2)==':') if(thmmyDateTime.charAt(2)==':')
thmmyDateTime = (new DateTime()).toString("MMMM d, Y, ") + thmmyDateTime; thmmyDateTime = (new DateTime()).toString("MMMM d, Y, ") + thmmyDateTime;
@ -84,16 +87,19 @@ public class ThmmyDateTimeParser {
return timestamp; return timestamp;
} }
public static String convertDateTime(String dateTime, boolean removeSeconds){ public static String simplifyDateTime(String dateTime){
//Convert e.g. Today at 12:16:48 -> 12:16:48, but October 03, 2019, 16:40:18 remains as is return removeSeconds(purifyTodayDateTime(dateTime));
if (!dateTime.contains(",")) }
dateTime = dateTime.replaceAll(".+? ([0-9])", "$1");
//Remove seconds // Converts e.g. Today at 12:16:48 -> 12:16:48, but October 03, 2019, 16:40:18 remains as is
if(removeSeconds) @VisibleForTesting
dateTime = dateTime.replaceAll("(.+?)(:[0-5][0-9])($|\\s)", "$1$3"); static String purifyTodayDateTime(String dateTime){
return dateTime.replaceAll("(Today at |Σήμερα στις )(.+)", "$2");
}
return dateTime; // Converts e.g. 12:16:48 -> 12:16, October 03, 2019, 16:40:18 -> 12:16 October 03, 2019, 16:40
private static String removeSeconds(String dateTime){
return dateTime.replaceAll("(.*):\\d+(.*)", "$1$2");
} }
@VisibleForTesting @VisibleForTesting

2
app/src/main/res/values/strings.xml

@ -41,7 +41,7 @@
<string name="topic_subject">Subject</string> <string name="topic_subject">Subject</string>
<string name="topic_started_by">Started by: %1$s</string> <string name="topic_started_by">Started by: %1$s</string>
<string name="topic_stats">Stats</string> <string name="topic_stats">Stats</string>
<string name="topic_last_post">Last post on: %1$s</string> <string name="topic_last_post">Last post on: %1$s\nby %2$s</string>
<!--Topic Activity--> <!--Topic Activity-->
<string name="share">Share</string> <string name="share">Share</string>

2
app/src/main/res/xml-v26/app_preferences_guest.xml

@ -15,7 +15,7 @@
android:summary="@string/pref_summary_app_main_default_tab" android:summary="@string/pref_summary_app_main_default_tab"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<androidx.preference.SwitchPreferenceCompat <androidx.preference.SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="true"
android:key="@string/pref_app_display_relative_time_key" android:key="@string/pref_app_display_relative_time_key"
android:title="@string/pref_title_display_relative_time" android:title="@string/pref_title_display_relative_time"
android:summary="@string/pref_summary_display_relative_time" android:summary="@string/pref_summary_display_relative_time"

2
app/src/main/res/xml-v26/app_preferences_user.xml

@ -15,7 +15,7 @@
android:summary="@string/pref_summary_app_main_default_tab" android:summary="@string/pref_summary_app_main_default_tab"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<androidx.preference.SwitchPreferenceCompat <androidx.preference.SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="true"
android:key="@string/pref_app_display_relative_time_key" android:key="@string/pref_app_display_relative_time_key"
android:title="@string/pref_title_display_relative_time" android:title="@string/pref_title_display_relative_time"
android:summary="@string/pref_summary_display_relative_time" android:summary="@string/pref_summary_display_relative_time"

2
app/src/main/res/xml/app_preferences_guest.xml

@ -15,7 +15,7 @@
android:summary="@string/pref_summary_app_main_default_tab" android:summary="@string/pref_summary_app_main_default_tab"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<androidx.preference.SwitchPreferenceCompat <androidx.preference.SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="true"
android:key="@string/pref_app_display_relative_time_key" android:key="@string/pref_app_display_relative_time_key"
android:title="@string/pref_title_display_relative_time" android:title="@string/pref_title_display_relative_time"
android:summary="@string/pref_summary_display_relative_time" android:summary="@string/pref_summary_display_relative_time"

2
app/src/main/res/xml/app_preferences_user.xml

@ -15,7 +15,7 @@
android:summary="@string/pref_summary_app_main_default_tab" android:summary="@string/pref_summary_app_main_default_tab"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<androidx.preference.SwitchPreferenceCompat <androidx.preference.SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="true"
android:key="@string/pref_app_display_relative_time_key" android:key="@string/pref_app_display_relative_time_key"
android:title="@string/pref_title_display_relative_time" android:title="@string/pref_title_display_relative_time"
android:summary="@string/pref_summary_display_relative_time" android:summary="@string/pref_summary_display_relative_time"

46
app/src/test/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParserTest.java

@ -10,6 +10,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunner;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp; import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.convertToTimestamp;
import static gr.thmmy.mthmmy.utils.parsing.ThmmyDateTimeParser.purifyTodayDateTime;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.powermock.api.support.membermodification.MemberMatcher.method; import static org.powermock.api.support.membermodification.MemberMatcher.method;
@ -47,7 +48,6 @@ public class ThmmyDateTimeParserTest {
} }
}; };
@Test @Test
public void dateTimesAreConvertedCorrectly() { public void dateTimesAreConvertedCorrectly() {
stub(method(ThmmyDateTimeParser.class, GET_DTZ)).toReturn(DateTimeZone.forID(TIME_ZONE)); stub(method(ThmmyDateTimeParser.class, GET_DTZ)).toReturn(DateTimeZone.forID(TIME_ZONE));
@ -72,14 +72,54 @@ public class ThmmyDateTimeParserTest {
"00:58:07", "00:58:07",
"23:23:23", "23:23:23",
"09:09:09 am", "09:09:09 am",
"09:09:09 pm" "09:09:09 pm",
"Today at 12:16:48",
"Σήμερα στις 12:16:48",
"Today at 12:16:48 am"
}; };
@Test @Test
public void todayDateTimeConvertToNonNull() { public void todayDateTimesConvertToNonNull() {
stub(method(ThmmyDateTimeParser.class, GET_DTZ)).toReturn(DateTimeZone.forID(TIME_ZONE)); stub(method(ThmmyDateTimeParser.class, GET_DTZ)).toReturn(DateTimeZone.forID(TIME_ZONE));
for (String todayDateTime : todayDateTimes) for (String todayDateTime : todayDateTimes)
assertNotNull(convertToTimestamp(todayDateTime)); assertNotNull(convertToTimestamp(todayDateTime));
} }
private final String [] dateTimesToBePurified = {
"12:16:48",
"12:16:48 am",
"Today at 12:16:48",
"Σήμερα στις 12:16:48",
"Today at 12:16:48 am"
};
private final String [] expectedPurifiedDateTimes = {
"12:16:48",
"12:16:48 am",
"12:16:48",
"12:16:48",
"12:16:48 am"
};
@Test
public void todayDateTimesArePurifiedCorrectly(){
String[] purifiedTodayDateTimes = new String[dateTimesToBePurified.length];
for(int i = 0; i< dateTimesToBePurified.length; i++)
purifiedTodayDateTimes[i] = purifyTodayDateTime(dateTimesToBePurified[i]);
assertArrayEquals(purifiedTodayDateTimes, expectedPurifiedDateTimes);
// Those below should remain unaltered
String[][] purifiedDateTimes = new String[dateTimes.length][];
for(int i=0; i<dateTimes.length; i++){
purifiedDateTimes[i] = new String[dateTimes[i].length];
for(int j=0; j<dateTimes[i].length; j++)
purifiedDateTimes[i][j]=purifyTodayDateTime(dateTimes[i][j]);
}
assertArrayEquals(dateTimes, purifiedDateTimes);
}
} }

Loading…
Cancel
Save