diff --git a/app/build.gradle b/app/build.gradle index 5a3516f7..c1b6c936 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { compileSdk 33 minSdkVersion 23 targetSdkVersion 33 - versionCode 33 - versionName "2.2.1" + versionCode 34 + versionName "2.3.0" archivesBaseName = "mTHMMY-v$versionName" buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\"" buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\"" diff --git a/app/gradle/grgit.gradle b/app/gradle/grgit.gradle index 53ae4204..5badd1f7 100644 --- a/app/gradle/grgit.gradle +++ b/app/gradle/grgit.gradle @@ -10,9 +10,13 @@ buildscript { } } -static def getCurrentBranch() { +def getGrgit() { + return Grgit.open(currentDir: project.rootDir) +} + +def getCurrentBranch() { try { - def grgit = Grgit.open() + def grgit = getGrgit() def currentBranch = grgit.branch.getCurrent().name grgit.close() return currentBranch @@ -21,9 +25,9 @@ static def getCurrentBranch() { } } -static def getCommitHash() { +def getCommitHash() { try { - def grgit = Grgit.open() + def grgit = getGrgit() def commitHash = grgit.head().id grgit.close() return commitHash @@ -33,9 +37,9 @@ static def getCommitHash() { } //Will return true if there are no uncommitted changes -static def isClean() { +def isClean() { try { - def grgit = Grgit.open() + def grgit = getGrgit() def isClean = grgit.status().isClean() grgit.close() return isClean 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 b0af3c94..be0977cf 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java @@ -60,7 +60,7 @@ public class AboutActivity extends BaseActivity { String versionInfo = ""; if (gitExists) versionInfo = "-" + BuildConfig.CURRENT_BRANCH + "-" + commitHash - + (BuildConfig.IS_CLEAN ? "" : "-dirty") + + (BuildConfig.IS_CLEAN ? "" : "~") + " "; // Avoid last letter being cut in italics styled TextView //Initialize appbar 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 6a427b53..5a074973 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 @@ -219,7 +219,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo try { Elements pages = boardPage.select("table.tborder td.catbg[height=30]").first() .select("a.navPages"); - if (pages != null && !pages.isEmpty()) { + if (!pages.isEmpty()) { for (Element page : pages) { if (Integer.parseInt(page.text()) > numberOfPages) numberOfPages = Integer.parseInt(page.text()); @@ -240,7 +240,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo if (pagesLoaded == 0) { //Finds sub boards Elements subBoardRows = boardPage.select("div.tborder>table>tbody>tr"); - if (subBoardRows != null && !subBoardRows.isEmpty()) { + if (!subBoardRows.isEmpty()) { for (Element subBoardRow : subBoardRows) { if (!Objects.equals(subBoardRow.className(), "titlebg")) { String pUrl = "", pTitle = "", pMods = "", pStats = "", @@ -314,7 +314,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo } //Finds topics Elements topicRows = boardPage.select("table.bordercolor>tbody>tr"); - if (topicRows != null && !topicRows.isEmpty()) { + if (!topicRows.isEmpty()) { for (Element topicRow : topicRows) { if (!Objects.equals(topicRow.className(), "titlebg")) { String pTopicUrl, pSubject, pStarter, pLastUser = "", pLastPostDateTime = "00:00:00", pLastPost, pLastPostUrl, pStats; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java index 6f8a33ce..ff5ed7a5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java @@ -16,6 +16,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; @@ -63,6 +64,7 @@ class BoardAdapter extends RecyclerView.Adapter { return VIEW_TYPE_LOADING; } + @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_SUB_BOARD) { @@ -75,16 +77,16 @@ class BoardAdapter extends RecyclerView.Adapter { inflate(R.layout.activity_board_topic_row, parent, false); return new TopicViewHolder(topic); } - else if (viewType == VIEW_TYPE_LOADING) { + // viewType == VIEW_TYPE_LOADING + else { 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) { + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { if (holder instanceof SubBoardViewHolder) { final Board subBoard = parsedSubBoards.get(position); final SubBoardViewHolder subBoardViewHolder = (SubBoardViewHolder) holder; @@ -176,8 +178,9 @@ class BoardAdapter extends RecyclerView.Adapter { intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); context.startActivity(intent); }); - if (topicExpandableVisibility.get(topicViewHolder.getBindingAdapterPosition() - parsedSubBoards - .size())) { + + final int pos = topicViewHolder.getBindingAdapterPosition() - parsedSubBoards.size(); + if (pos >=0 && pos < topicExpandableVisibility.size() && topicExpandableVisibility.get(pos)) { topicViewHolder.topicExpandable.setVisibility(View.VISIBLE); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); } @@ -185,11 +188,11 @@ class BoardAdapter extends RecyclerView.Adapter { topicViewHolder.topicExpandable.setVisibility(View.GONE); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); } + topicViewHolder.showHideExpandable.setOnClickListener(view -> { - final int pos = topicViewHolder.getBindingAdapterPosition() - parsedSubBoards.size(); - if (pos >=0 && pos < topicExpandableVisibility.size()) { - final boolean visible = topicExpandableVisibility.get(topicViewHolder. - getBindingAdapterPosition() - parsedSubBoards.size()); + final int pos2 = topicViewHolder.getBindingAdapterPosition() - parsedSubBoards.size(); + if (pos2 >=0 && pos2 < topicExpandableVisibility.size()) { + final boolean visible = topicExpandableVisibility.get(pos2); if (visible) { topicViewHolder.topicExpandable.setVisibility(View.GONE); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); @@ -198,8 +201,7 @@ class BoardAdapter extends RecyclerView.Adapter { topicViewHolder.topicExpandable.setVisibility(View.VISIBLE); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); } - topicExpandableVisibility.set(topicViewHolder.getBindingAdapterPosition() - - parsedSubBoards.size(), !visible); + topicExpandableVisibility.set(pos2, !visible); } }); topicViewHolder.topicSubject.setTypeface(Typeface.createFromAsset(context.getAssets() diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java index 5255dc15..2b1abfc1 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java @@ -8,7 +8,9 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.IOException; +import java.util.Objects; +import gr.thmmy.mthmmy.activities.topic.Posting; import gr.thmmy.mthmmy.base.BaseApplication; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; @@ -73,14 +75,12 @@ public class NewTopicTask extends AsyncTask { try { client.newCall(post).execute(); Response response2 = client.newCall(post).execute(); - switch (replyStatus(response2)) { - case SUCCESSFUL: - BaseApplication.getInstance().logFirebaseAnalyticsEvent("new_topic_creation", null); - return true; - default: - Timber.e("Malformed post. Request string: %s", post.toString()); - return false; + if (Objects.requireNonNull(replyStatus(response2)) == Posting.REPLY_STATUS.SUCCESSFUL) { + BaseApplication.getInstance().logFirebaseAnalyticsEvent("new_topic_creation", null); + return true; } + Timber.e("Malformed post. Request string: %s", post.toString()); + return false; } catch (IOException e) { return 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 793a6bba..924c35f4 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 @@ -234,13 +234,10 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. 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; - } + 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) { 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 293fa457..3cb67fdf 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 @@ -15,6 +15,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.net.MalformedURLException; @@ -27,6 +28,7 @@ import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Download; import gr.thmmy.mthmmy.model.ThmmyFile; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import timber.log.Timber; class DownloadsAdapter extends RecyclerView.Adapter { private final int VIEW_TYPE_DOWNLOAD = 0; @@ -50,6 +52,7 @@ class DownloadsAdapter extends RecyclerView.Adapter { return (parsedDownloads.get(position) == null) ? VIEW_TYPE_LOADING : VIEW_TYPE_DOWNLOAD; } + @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_DOWNLOAD) { @@ -57,12 +60,12 @@ class DownloadsAdapter extends RecyclerView.Adapter { inflate(R.layout.activity_downloads_row, parent, false); return new DownloadViewHolder(download); } - else if (viewType == VIEW_TYPE_LOADING) { + // viewType == VIEW_TYPE_LOADING + else { View loading = LayoutInflater.from(parent.getContext()). inflate(R.layout.recycler_loading_item, parent, false); return new LoadingViewHolder(loading); } - return null; } @Override @@ -87,7 +90,9 @@ class DownloadsAdapter extends RecyclerView.Adapter { context.startActivity(intent); }); - if (downloadExpandableVisibility.get(downloadViewHolder.getAdapterPosition())) { + final int pos = downloadViewHolder.getBindingAdapterPosition(); + + if (pos >=0 && pos < downloadExpandableVisibility.size() && downloadExpandableVisibility.get(pos)) { downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); } @@ -95,18 +100,21 @@ class DownloadsAdapter extends RecyclerView.Adapter { downloadViewHolder.informationExpandable.setVisibility(View.GONE); downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); } + downloadViewHolder.informationExpandableBtn.setOnClickListener(view -> { - final boolean visible = downloadExpandableVisibility.get(downloadViewHolder. - getAdapterPosition()); - if (visible) { - downloadViewHolder.informationExpandable.setVisibility(View.GONE); - downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); - } - else { - downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); - downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); + final int pos2 = downloadViewHolder.getBindingAdapterPosition(); + if (pos2 >=0 && pos2 < downloadExpandableVisibility.size()){ + final boolean visible = downloadExpandableVisibility.get(pos2); + if (visible) { + downloadViewHolder.informationExpandable.setVisibility(View.GONE); + downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); + } + else { + downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE); + downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); + } + downloadExpandableVisibility.set(pos2, !visible); } - downloadExpandableVisibility.set(downloadViewHolder.getAdapterPosition(), !visible); }); downloadViewHolder.title.setTypeface(Typeface.createFromAsset(context.getAssets() , "fonts/fontawesome-webfont.ttf")); @@ -127,7 +135,7 @@ class DownloadsAdapter extends RecyclerView.Adapter { ((BaseActivity) context).downloadFile(new ThmmyFile( new URL(download.getUrl()), download.getFileName(), null)); } catch (MalformedURLException e) { - e.printStackTrace(); + Timber.e(e, "MalformedURLException"); } }); 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 1b6468d1..45363319 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 @@ -18,6 +18,7 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.Toast; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; @@ -228,11 +229,11 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF public void updateTabIcon(int position) { if (position >= tabLayout.getTabCount()) return; if (position == 0) - tabLayout.getTabAt(0).setIcon(getResources().getDrawable(R.drawable.ic_access_time_white_24dp)); + tabLayout.getTabAt(0).setIcon(ContextCompat.getDrawable(this, R.drawable.ic_access_time_white_24dp)); else if (position == 1) - tabLayout.getTabAt(1).setIcon(getResources().getDrawable(R.drawable.ic_forum_white_24dp)); + tabLayout.getTabAt(1).setIcon(ContextCompat.getDrawable(this, R.drawable.ic_forum_white_24dp)); else if (position == 2) - tabLayout.getTabAt(2).setIcon(getResources().getDrawable(R.drawable.ic_fiber_new_white_24dp)); + tabLayout.getTabAt(2).setIcon(ContextCompat.getDrawable(this, R.drawable.ic_fiber_new_white_24dp)); } private void updateTabIcons() { 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 f5851ac0..826a2f9d 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 @@ -209,7 +209,7 @@ public class ForumFragment extends BaseFragment { @Override protected ArrayList parse(Document document, Response response) throws ParseException { Elements categoryBlocks = document.select(".tborder:not([style])>table[cellpadding=5]"); - if (categoryBlocks.size() != 0) { + if (!categoryBlocks.isEmpty()) { ArrayList fetchedCategories = new ArrayList<>(); for (Element categoryBlock : categoryBlocks) { Element categoryElement = categoryBlock.select("td[colspan=2]>[name]").first(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java index 40fab7a7..b16a750a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java @@ -11,6 +11,7 @@ public class SettingsActivity extends BaseActivity { public static final String DEFAULT_HOME_TAB = "pref_app_main_default_tab_key"; public static final String DISPLAY_COMPACT_TABS = "pref_app_display_compact_tabs_key"; public static final String DISPLAY_RELATIVE_TIME = "pref_app_display_relative_time_key"; + public static final String USE_GREEK_TIMEZONE = "pref_app_use_greek_timezone_key"; public static final String NOTIFICATION_LED_KEY = "pref_notification_led_enable_key"; public static final String NOTIFICATION_VIBRATION_KEY = "pref_notification_vibration_enable_key"; public static final String POSTING_APP_SIGNATURE_ENABLE_KEY = "pref_posting_app_signature_enable_key"; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java index 355fa8eb..efd0dccf 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java @@ -66,7 +66,9 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared defaultHomeTabValues.add("0"); defaultHomeTabValues.add("1"); - if (isLoggedIn = BaseApplication.getInstance().getSessionManager().isLoggedIn()) { + isLoggedIn = BaseApplication.getInstance().getSessionManager().isLoggedIn(); + + if (isLoggedIn) { defaultHomeTabEntries.add(UNREAD); defaultHomeTabValues.add("2"); } @@ -228,6 +230,10 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared && BaseApplication.getInstance().isDisplayCompactTabsEnabled() != sharedPreferences.getBoolean(key, false)) { displayRestartAppToTakeEffectToast(); } + else if (key.equals(getString(R.string.pref_app_use_greek_timezone_key)) + && BaseApplication.getInstance().isUseGreekTimezoneEnabled() != sharedPreferences.getBoolean(key, false)) { + displayRestartAppToTakeEffectToast(); + } } private void displayRestartAppToTakeEffectToast() { 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 ea5ce606..cddd7cd5 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 @@ -378,6 +378,10 @@ class TopicAdapter extends RecyclerView.Adapter { //Sets username,submit date, index number, subject, post's and attached files texts holder.username.setText(currentPost.getAuthor()); + + if(currentPost.getUserOnlineStatus()) + holder.onlineStatusDot.setVisibility(View.VISIBLE); + holder.postDate.setText(currentPost.getPostDate()); if (currentPost.getPostNumber() != 0) holder.postNum.setText(context.getString( @@ -822,7 +826,7 @@ class TopicAdapter extends RecyclerView.Adapter { final View bodyFooterDivider; final LinearLayout postFooter; - final TextView specialRank, rank, gender, numberOfPosts, personalText, stars; + final TextView specialRank, rank, gender, numberOfPosts, personalText, stars, onlineStatusDot; PostViewHolder(View view) { super(view); @@ -835,6 +839,7 @@ class TopicAdapter extends RecyclerView.Adapter { username = view.findViewById(R.id.username); subject = view.findViewById(R.id.subject); post = view.findViewById(R.id.post); + onlineStatusDot = view.findViewById(R.id.online_status_dot); post.setBackgroundColor(Color.argb(1, 255, 255, 255)); quoteToggle = view.findViewById(R.id.toggle_quote_button); overflowButton = view.findViewById(R.id.post_overflow_menu); 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 609348b4..205ab40c 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 @@ -46,6 +46,7 @@ public class TopicParser { private static final int USER_COLOR_BLUE = Color.parseColor("#536DFE"); static final int USER_COLOR_PINK = Color.parseColor("#FF4081"); static final int USER_COLOR_YELLOW = Color.parseColor("#FFEB3B"); + static final int USER_COLOR_PURPLE = Color.parseColor("#8C7DF2"); static final int USER_COLOR_WHITE = Color.WHITE; /** @@ -177,7 +178,7 @@ public class TopicParser { p_specialRank, p_gender, p_personalText, p_numberOfPosts, p_postLastEditDate, p_postURL, p_deletePostURL, p_editPostURL; int p_postNum, p_postIndex, p_numberOfStars, p_userColor; - boolean p_isDeleted = false, p_isUserMentionedInPost = false; + boolean p_isDeleted = false, p_isUserMentionedInPost = false, p_isUserOnline = false; ArrayList p_attachedFiles; //Initialize variables @@ -396,51 +397,38 @@ public class TopicParser { Element usersExtraInfo = userName.parent().nextElementSibling(); //Get sibling "div" List infoList = Arrays.asList(usersExtraInfo.html().split("
")); - if (language == ParseHelpers.Language.GREEK) { - for (String line : infoList) { - if (line.contains("Μηνύματα:")) { - postsLineIndex = infoList.indexOf(line); - //Remove any line breaks and spaces on the start and end - p_numberOfPosts = line.replace("\n", "").replace("\r", "").trim(); - } - if (line.contains("Φύλο:")) { - if (line.contains("alt=\"Άντρας\"")) - p_gender = "Φύλο: Άντρας"; - else - p_gender = "Φύλο: Γυναίκα"; - } - if (line.contains("alt=\"*\"")) { - starsLineIndex = infoList.indexOf(line); - Document starsHtml = Jsoup.parse(line); - p_numberOfStars = starsHtml.select("img[alt]").size(); - p_userColor = colorPicker(starsHtml.select("img[alt]").first() - .attr("abs:src")); - } + final boolean displayedLanguageGreek = language == ParseHelpers.Language.GREEK; + final String genderStr = displayedLanguageGreek ? "Φύλο:" : "Gender:"; + final String altMaleStr = displayedLanguageGreek ? "alt=\"Άντρας\"" : "alt=\"Male\""; + final String genderMaleStr = displayedLanguageGreek ? "Φύλο: Άντρας" : "Gender: Male"; + final String genderFemaleStr = displayedLanguageGreek ? "Φύλο: Γυναίκα" : "Gender: Female"; + final String postsStr = displayedLanguageGreek ? "Μηνύματα:" : "Posts:"; + final String pmTitleWithOnlineStatusStr = displayedLanguageGreek ? "title=\"Προσωπικό μήνυμα (Σε σύνδεση)\"" : "title=\"Personal Message (Online)\""; + + Document starsHtml= Jsoup.parse(""); + + for (String line : infoList) { + if (line.contains(postsStr)) { + postsLineIndex = infoList.indexOf(line); + //Remove any line breaks and spaces on the start and end + p_numberOfPosts = line.replace("\n", "").replace("\r", "").trim(); } - } - else { - for (String line : infoList) { - if (line.contains("Posts:")) { - postsLineIndex = infoList.indexOf(line); - //Remove any line breaks and spaces on the start and end - p_numberOfPosts = line.replace("\n", "").replace("\r", "").trim(); - } - if (line.contains("Gender:")) { - if (line.contains("alt=\"Male\"")) - p_gender = "Gender: Male"; - else - p_gender = "Gender: Female"; - } - if (line.contains("alt=\"*\"")) { - starsLineIndex = infoList.indexOf(line); - Document starsHtml = Jsoup.parse(line); - p_numberOfStars = starsHtml.select("img[alt]").size(); - p_userColor = colorPicker(starsHtml.select("img[alt]").first() - .attr("abs:src")); - } + if (line.contains(genderStr)) { + if (line.contains(altMaleStr)) + p_gender = genderMaleStr; + else + p_gender = genderFemaleStr; + } + if (line.contains("alt=\"*\"")) { + starsLineIndex = infoList.indexOf(line); + starsHtml = Jsoup.parse(line); } + if (line.contains(pmTitleWithOnlineStatusStr)) + p_isUserOnline = true; } + p_numberOfStars = starsHtml.select("img[alt]").size(); + //If this member has no stars yet ==> New member, //or is just a member if (starsLineIndex == -1 || starsLineIndex == 1) { @@ -451,6 +439,12 @@ public class TopicParser { p_specialRank = infoList.get(0).trim(); //First line has the special rank p_rank = infoList.get(1).trim(); //Second line has the rank } + + Element starsHtmlEl = starsHtml.select("img[alt]").first(); + + if (p_numberOfStars>0 && starsHtmlEl!=null) + p_userColor = colorPicker(starsHtmlEl.attr("abs:src"), p_specialRank); + for (int i = postsLineIndex + 1; i < infoList.size() - 1; ++i) { //Searches under "Posts:" //and above "Personal Message", "View Profile" etc buttons @@ -475,7 +469,7 @@ public class TopicParser { , p_postNum, p_postDate, p_profileURL, p_rank, p_specialRank, p_gender , p_numberOfPosts, p_personalText, p_numberOfStars, p_userColor , p_attachedFiles, p_postLastEditDate, p_postURL, p_deletePostURL, p_editPostURL - , p_isUserMentionedInPost, Post.TYPE_POST)); + , p_isUserOnline, p_isUserMentionedInPost, Post.TYPE_POST)); } else { //Deleted user @@ -586,7 +580,9 @@ public class TopicParser { * @param starsUrl String containing the URL of a user's stars * @return an int corresponding to the right color */ - private static int colorPicker(String starsUrl) { + private static int colorPicker(String starsUrl, String specialRank) { + if(Objects.equals(specialRank, "Veteran")) + return USER_COLOR_PURPLE; if (starsUrl.contains("/star.gif")) return USER_COLOR_YELLOW; else if (starsUrl.contains("/starmod.gif")) 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 2b2d2b4e..4a40e67e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -20,7 +20,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.text.Html; +// import android.text.Html; import android.view.MenuItem; import android.view.View; import android.widget.Button; @@ -62,7 +62,7 @@ import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.settings.SettingsActivity; import gr.thmmy.mthmmy.activities.shoutbox.ShoutboxActivity; -import gr.thmmy.mthmmy.activities.upload.UploadActivity; +// import gr.thmmy.mthmmy.activities.upload.UploadActivity; import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.services.DownloadHelper; 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 228b67d3..42715f5e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java @@ -2,6 +2,7 @@ package gr.thmmy.mthmmy.base; import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DISPLAY_COMPACT_TABS; import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DISPLAY_RELATIVE_TIME; +import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.USE_GREEK_TIMEZONE; import static gr.thmmy.mthmmy.activities.upload.UploadActivity.firebaseConfigUploadsCoursesKey; import static gr.thmmy.mthmmy.utils.io.ResourceUtils.readJSONResourceToString; @@ -71,6 +72,7 @@ public class BaseApplication extends Application implements Executor{ private boolean displayRelativeTime; private boolean displayCompactTabs; + private boolean useGreekTimezone; //Display Metrics private static float widthDp; @@ -115,6 +117,7 @@ public class BaseApplication extends Application implements Executor{ displayRelativeTime = settingsSharedPrefs.getBoolean(DISPLAY_RELATIVE_TIME, true); displayCompactTabs = settingsSharedPrefs.getBoolean(DISPLAY_COMPACT_TABS, true); + useGreekTimezone = settingsSharedPrefs.getBoolean(USE_GREEK_TIMEZONE, true); } private void initFirebase(SharedPreferences settingsSharedPrefs) { @@ -263,6 +266,10 @@ public class BaseApplication extends Application implements Executor{ return displayCompactTabs; } + public boolean isUseGreekTimezoneEnabled() { + return useGreekTimezone; + } + //-------------------- Firebase -------------------- public void logFirebaseAnalyticsEvent(String event, Bundle params) { 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 8000e93f..4595172e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Post.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Post.java @@ -47,6 +47,7 @@ public class Post extends TopicItem { private final String personalText; private final int numberOfStars; private final boolean isUserMentionedInPost; + private final boolean isUserOnline; // Suppresses default constructor @SuppressWarnings("unused") @@ -73,6 +74,7 @@ public class Post extends TopicItem { postURL = null; postDeleteURL = null; postEditURL = null; + isUserOnline = false; isUserMentionedInPost = false; postType = -1; } @@ -101,13 +103,14 @@ public class Post extends TopicItem { * @param attachedFiles post's attached files * @param lastEdit post's last edit date * @param postURL post's URL + * @param isUserOnline author's online status */ public Post(@Nullable String thumbnailUrl, String author, String subject, String content , String bbContent, 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 String lastEdit, String postURL - , @Nullable String postDeleteURL, @Nullable String postEditURL, boolean isUserMentionedInPost + , @Nullable String postDeleteURL, @Nullable String postEditURL, boolean isUserOnline, boolean isUserMentionedInPost , int postType) { this.bbContent = bbContent; if (Objects.equals(thumbnailUrl, "")) this.thumbnailUrl = null; @@ -132,6 +135,7 @@ public class Post extends TopicItem { this.postURL = postURL; this.postDeleteURL = postDeleteURL; this.postEditURL = postEditURL; + this.isUserOnline = isUserOnline; this.isUserMentionedInPost = isUserMentionedInPost; this.postType = postType; } @@ -182,6 +186,7 @@ public class Post extends TopicItem { this.postURL = postURL; this.postDeleteURL = postDeleteURL; this.postEditURL = postEditURL; + this.isUserOnline = false; this.isUserMentionedInPost = isUserMentionedInPost; this.postType = postType; } @@ -362,6 +367,17 @@ public class Post extends TopicItem { return userColor; } + /** + * Gets the online status of this post's author. + * + * @return online status of this post's author + */ + + @Nullable + public boolean getUserOnlineStatus() { + return isUserOnline; + } + /** * Gets this post's attached files. * diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParser.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParser.java index cfc40ae2..66660163 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParser.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ThmmyDateTimeParser.java @@ -45,7 +45,16 @@ public class ThmmyDateTimeParser { public static String convertToTimestamp(String thmmyDateTime) { Timber.v("Will attempt to convert %s to timestamp.", thmmyDateTime); String originalDateTime = thmmyDateTime; - DateTimeZone dtz = getDtz(); + + DateTimeZone dtz; + + // This was added for people who briefly travelled abroad and didn't change the displayed time in their profile settings + final boolean useeGreekTimezone = BaseApplication.getInstance().isUseGreekTimezoneEnabled(); + + if(useeGreekTimezone) + dtz = DateTimeZone.forID("Europe/Athens"); + else + dtz = DateTimeZone.getDefault(); // Remove any unnecessary "Today at" strings thmmyDateTime = purifyTodayDateTime(thmmyDateTime); @@ -112,12 +121,4 @@ public class ThmmyDateTimeParser { private static String removeSeconds(String dateTime) { return dateTime.replaceAll("(.*):\\d+($|\\s.*)", "$1$2"); } - - @VisibleForTesting - private static DateTimeZone getDtz() { - if (!BaseApplication.getInstance().getSessionManager().isLoggedIn()) - return DateTimeZone.forID("Europe/Athens"); - else - return DateTimeZone.getDefault(); - } } diff --git a/app/src/main/res/layout/activity_topic_post_row.xml b/app/src/main/res/layout/activity_topic_post_row.xml index b795224e..5dbca1a3 100644 --- a/app/src/main/res/layout/activity_topic_post_row.xml +++ b/app/src/main/res/layout/activity_topic_post_row.xml @@ -9,17 +9,17 @@ android:paddingStart="4dp" tools:ignore="SmallSp"> - + app:cardBackgroundColor="@color/background_light" + app:cardCornerRadius="5dp" + app:cardElevation="2dp" + app:cardPreventCornerOverlap="false" + app:cardUseCompatPadding="true"> + + #FF9800 #FAA61A #890d0d + #4CAF50 #FFFFFF #CCCCCC diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38263d6c..777469dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -73,13 +73,14 @@ This topic is either missing or off limits to you Remove vote show results + hide results + preference-topic-drafts-key + Reply + You may only select %d option You may only select %d options - hide results - preference-topic-drafts-key - Reply Username @@ -179,6 +180,9 @@ pref_app_display_relative_time_key Display relative time Considering that you haven\'t set some weird custom time format + pref_app_use_greek_timezone_key + Use Greek timezone + For relative time only. Disable this if you have also set a custom displayed time in your profile. pref_app_display_compact_tabs_key Display compact tabs Home screen tabs will occupy less space diff --git a/app/src/main/res/xml-v26/app_preferences_guest.xml b/app/src/main/res/xml-v26/app_preferences_guest.xml index f366c6e0..58794266 100644 --- a/app/src/main/res/xml-v26/app_preferences_guest.xml +++ b/app/src/main/res/xml-v26/app_preferences_guest.xml @@ -20,6 +20,12 @@ android:title="@string/pref_title_display_relative_time" android:summary="@string/pref_summary_display_relative_time" app:iconSpaceReserved="false" /> + + + +