diff --git a/app/build.gradle b/app/build.gradle
index c73a3bd7..10c07e6e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
applicationId "gr.thmmy.mthmmy"
minSdkVersion 19
targetSdkVersion 29
- versionCode 26
- versionName "1.8.3"
+ versionCode 27
+ versionName "1.8.4"
archivesBaseName = "mTHMMY-v$versionName"
buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\""
buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\""
@@ -78,7 +78,7 @@ tasks.whenTaskAdded { task ->
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":emojis")
- implementation 'androidx.appcompat:appcompat:1.3.0-alpha01'
+ implementation 'androidx.appcompat:appcompat:1.3.0-alpha02'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8b01d869..9003cab6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -150,6 +150,20 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity" />
+
+
+
+
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/assets/YouTube_light_color_icon.png b/app/src/main/assets/YouTube_light_color_icon.png
index bfd6db39..ac136005 100644
Binary files a/app/src/main/assets/YouTube_light_color_icon.png and b/app/src/main/assets/YouTube_light_color_icon.png differ
diff --git a/app/src/main/assets/style.css b/app/src/main/assets/style.css
index 4a9fc801..501e1320 100644
--- a/app/src/main/assets/style.css
+++ b/app/src/main/assets/style.css
@@ -1,24 +1,26 @@
/* TP specific classes */
-.sitemap{
+
+.sitemap {
margin: 0;
padding: 0;
list-style: none;
}
-.sitemap_topheader{
+
+.sitemap_topheader {
background: #ECEDF3;
border-bottom: solid 1px #ffffff;
padding: 4px;
}
-.sitemap_header{
+.sitemap_header {
background: #ECEDF3;
border-bottom: solid 1px #ffffff;
padding: 4px;
display: block;
font-weight: bold;
- }
+}
-.sitemap_header_active{
+.sitemap_header_active {
background: #C8D6E1;
border-bottom: solid 1px #ffffff;
padding: 4px;
@@ -26,7 +28,8 @@
font-weight: bold;
}
-.sitemap_header:hover , .sitemap_header_active:hover{
+.sitemap_header:hover,
+.sitemap_header_active:hover {
background: #DBE4ED;
border-bottom: solid 1px #ffffff;
padding: 4px;
@@ -34,129 +37,149 @@
text-decoration: none;
}
+
/* TP other styles */
-ul#articlelist
-{
+
+ul#articlelist {
margin: 0;
padding: 0.5ex 0;
list-style: none;
}
-ul#catlist
-{
+
+ul#catlist {
margin: 0;
padding: 0;
list-style: none;
border-top: solid 1px #d0d0d0;
}
-ul#articlelist li
-{
+ul#articlelist li {
margin: 0;
display: block;
padding: 0 0 0 3ex;
background: url(images/divider.gif) no-repeat 5px 3px;
}
-ul#catlist li
-{
+
+ul#catlist li {
display: block;
padding: 0 0 0 3ex;
margin: 0;
}
+
/* Normal, standard links. */
-a:link, a:visited
-{
+
+a:link,
+a:visited {
color: #26A69A;
text-decoration: none;
}
-a:hover
-{
+
+a:hover {
text-decoration: underline;
}
+
/* Navigation links - for the link tree. */
-.nav, .nav:link, .nav:visited
-{
+
+.nav,
+.nav:link,
+.nav:visited {
color: #000000;
text-decoration: none;
}
-a.nav:hover
-{
+
+a.nav:hover {
color: #cc3333;
}
+
/* Tables should show empty cells. */
-table
-{
+
+table {
empty-cells: show;
}
+
+
/* The main body of the entire forum. */
-body
-{
+
+body {
background: #3C3F41;
margin: 0;
padding: 0;
}
+
+
/* By default (td, body..) use verdana in black. */
-body, td, th , tr
-{
+
+body,
+td,
+th,
+tr {
color: #FFFFFF;
font-size: small;
font-family: Trebuchet, sans-serif;
}
-
/* Input boxes - just a bit smaller than normal so they align well. */
-input, textarea, button
-{
+
+input,
+textarea,
+button {
color: #FFFFFF;
font-family: Trebuchet, sans-serif;
border: 1px solid #aaa;
}
-input, button
-{
+
+input,
+button {
font-size: 90%;
}
-textarea
-{
+textarea {
font-size: 100%;
color: #FFFFFF;
font-family: Trebuchet, sans-serif;
}
+
/* All input elements that are checkboxes or radio buttons. */
-input.check
-{
-}
+
+input.check {}
+
/* Selects are a bit smaller, because it makes them look even better 8). */
-select
-{
+
+select {
font-size: 90%;
font-weight: normal;
color: #FFFFFF;
font-family: Trebuchet, sans-serif;
}
+
/* Standard horizontal rule.. ([hr], etc.) */
-hr, .hrcolor
-{
+
+hr,
+.hrcolor {
height: 1px;
border: 0;
color: #666666;
background-color: #666666;
}
+
/* No image should have a border when linked */
-a img
-{
+
+a img {
border: 0;
}
+
+
/* A quote, perhaps from another post. */
-.quote
-{
+
+.quote {
font-family: tahoma, sans-serif;
color: #FFFFFF;
background-color: #404D50;
@@ -167,9 +190,10 @@ a img
line-height: 1.4em;
}
+
/* A code block - maybe even PHP ;). */
-.code
-{
+
+.code {
color: #FFFFFF;
background-color: #626566;
font-family: "Comic Sans MS", "times new roman", monospace;
@@ -187,9 +211,11 @@ a img
max-height: 24em;
}
+
/* The "Quote:" and "Code:" header parts... */
-.quoteheader, .codeheader
-{
+
+.quoteheader,
+.codeheader {
font-family: tahoma, sans-serif;
color: #26A69A;
text-decoration: none;
@@ -199,156 +225,185 @@ a img
line-height: 1.2em;
}
+
/* Generally, those [?] icons. This makes your cursor a help icon. */
-.help
-{
+
+.help {
cursor: help;
}
+
/* /me uses this a lot. (emote, try typing /me in a post.) */
-.meaction
-{
+
+.meaction {
color: red;
}
+
/* The main post box - this makes it as wide as possible. */
-.editor
-{
+
+.editor {
width: 96%;
}
+
/* Highlighted text - such as search results. */
-.highlight
-{
+
+.highlight {
background-color: yellow;
font-weight: bold;
color: black;
}
+
/* Alternating backgrounds for posts, and several other sections of the forum. */
-.windowbg
-{
+
+.windowbg {
color: #FFFFFF;
background-color: #E3E6E1;
}
-.windowbg2
-{
+
+.windowbg2 {
color: #FFFFFF;
background-color: #F2F5F0;
}
-.windowbg3
-{
+
+.windowbg3 {
color: #FFFFFF;
background-color: #E1E8E0;
}
+
+
/* the today container in calendar */
-.calendar_today
-{
+
+.calendar_today {
background-color: #FFFFFF;
}
+
/* These are used primarily for titles, but also for headers (the row that says what everything in the table is.) */
-.titlebg, tr.titlebg th, tr.titlebg td, .titlebg2, tr.titlebg2 th, tr.titlebg2 td
-{
+
+.titlebg,
+tr.titlebg th,
+tr.titlebg td,
+.titlebg2,
+tr.titlebg2 th,
+tr.titlebg2 td {
background-color: #A3A392;
padding-top: 10px;
}
-.titlebg, tr.titlebg th, tr.titlebg td, .titlebg a:link, .titlebg a:visited, .titlebg2, tr.titlebg2 th, tr.titlebg2 td, .titlebg2 a:link, .titlebg2 a:visited
-{
+
+.titlebg,
+tr.titlebg th,
+tr.titlebg td,
+.titlebg a:link,
+.titlebg a:visited,
+.titlebg2,
+tr.titlebg2 th,
+tr.titlebg2 td,
+.titlebg2 a:link,
+.titlebg2 a:visited {
color: white;
font-style: normal;
}
-.titlebg a:hover
-{
+
+.titlebg a:hover {
color: #dfdfdf;
}
-.catbg, .catbg2, .catbg3
-{
+.catbg,
+.catbg2,
+.catbg3 {
font-weight: bold;
background-color: #e4e2e0;
color: #FFFFFF;
}
+
+
/* This is used for tables that have a grid/border background color (such as the topic listing.) */
-.bordercolor
-{
+
+.bordercolor {
background-color: white;
}
+
/* This is used on tables that should just have a border around them. */
-.tborder
-{
+
+.tborder {
background-color: #FFFFFF;
}
+
/* Default font sizes: small (8pt), normal (10pt), and large (14pt). */
-.smalltext
-{
+
+.smalltext {
font-size: x-small;
font-family: tahoma, sans-serif;
}
-.middletext
-{
+
+.middletext {
font-size: 90%;
}
-.normaltext
-{
+
+.normaltext {
font-size: small;
}
-.largetext
-{
+
+.largetext {
font-size: large;
}
/* Posts and personal messages displayed throughout the forum. */
-.post, .personalmessage
-{
+
+.post,
+.personalmessage {
width: 100%;
overflow: auto;
line-height: 1.3em;
color: white;
- background: #3C3F41 !important;
+ background: #3C3F41 !important;
}
+
/* All the signatures used in the forum. If your forum users use Mozilla, Opera, or Safari, you might add max-height here ;). */
-.signature
-{
+
+.signature {
width: 100%;
overflow: auto;
padding-bottom: 3px;
line-height: 1.3em;
}
-#left
-{
+#left {
background: url(images/img2/leftbg.jpg) repeat-y white;
margin: auto;
}
-#right
-{
+
+#right {
background: url(images/img2/rightbg.gif) repeat-y top right;
}
-#top
-{
+
+#top {
background: url(images/img2/top.jpg) repeat-x;
}
-#topleft
-{
+
+#topleft {
background: url(images/img2/lefttop.jpg) no-repeat;
}
-#topright
-{
+
+#topright {
background: url(images/img2/logo.jpg) no-repeat top right;
}
-#main
-{
+
+#main {
padding: 100px 81px 20px 81px;
}
+
+
/* #################### */
-ul#menubox
-{
+ul#menubox {
padding: 0 0 44px 0;
margin: 0;
list-style: none;
@@ -358,16 +413,15 @@ ul#menubox
background: url(images/img2/leftbot.gif) no-repeat bottom left;
}
-ul#menubox li
-{
+ul#menubox li {
padding: 0 0 0 8px;
width: 65px;
height: 44px;
margin: 0;
background: url(images/img2/left.gif) repeat-y;
}
-ul#menubox li a
-{
+
+ul#menubox li a {
font-family: "Comic Sans MS", serif;
display: block;
color: black;
@@ -375,74 +429,75 @@ ul#menubox li a
height: 42px;
padding: 0 0 0 6px;
}
-ul#menubox li a span
-{
+
+ul#menubox li a span {
display: none;
}
-ul#menubox li.m1
-{
+ul#menubox li.m1 {
padding-left: 2px;
}
-ul#menubox li.m2
-{
+
+ul#menubox li.m2 {
padding-left: 6px;
}
-ul#menubox li.m3
-{
+
+ul#menubox li.m3 {
padding-left: 10px;
}
-ul#menubox li.m4
-{
+
+ul#menubox li.m4 {
padding-left: 14px;
}
-ul#menubox li.m5
-{
+
+ul#menubox li.m5 {
padding-left: 18px;
}
-
-#myuser
-{
+#myuser {
font-size: small;
padding-bottom: 1em;
}
-#ava
-{
+
+#ava {
float: right;
margin-right: 10px;
text-align: right;
font-family: "Comic Sans MS", sans-serif;
}
-#bodyarea
-{
+
+#bodyarea {
border-bottom: solid 1px #ddd;
margin-bottom: 1em;
padding-bottom: 1em;
}
-.clearfix:after
-{
- content: ".";
- display: block;
- height: 0;
- clear: both;
- visibility: hidden;
+
+.clearfix:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
}
-.clearfix
-{
+.clearfix {
display: inline-block;
}
+
/* Hides from IE-mac \*/
-* html .clearfix , * html .catbg, * html .catbg2, * html .catbg3
-{
+
+* html .clearfix,
+* html .catbg,
+* html .catbg2,
+* html .catbg3 {
height: 1%;
}
+
+
/* End hide from IE-mac */
-ul#topmenu
-{
+ul#topmenu {
position: absolute;
top: 45px;
margin: 0 195px 0 40px;
@@ -452,12 +507,12 @@ ul#topmenu
font-size: 11px;
border-bottom: groove 2px #EDF4ED;
}
-ul#topmenu li
-{
+
+ul#topmenu li {
float: left;
}
-ul#topmenu li a
-{
+
+ul#topmenu li a {
display: block;
padding: 2px 5px 2px 5px;
border-style: solid solid;
@@ -466,31 +521,31 @@ ul#topmenu li a
font-size: 11px;
color: #004080;
}
-ul#topmenu li a:hover
-{
+
+ul#topmenu li a:hover {
background: #E3E6E1;
text-decoration: none;
color: #E78E13;
}
-#pages
-{
+
+#pages {
padding-top: 1em;
}
-#uppersection
-{
+
+#uppersection {
padding: 1em;
background: url(images/img/upper.jpg) repeat-x;
}
-.errorbar
-{
+
+.errorbar {
color: white;
font-size: xx-small;
text-align: center;
padding: 3px;
border-bottom: solid 1px black;
}
-#errorpanel
-{
+
+#errorpanel {
position: absolute;
top: 0;
left: 0;
@@ -498,51 +553,46 @@ ul#topmenu li a:hover
width: 100%;
}
+
/* Additions */
-img
-{
- max-width:100% !important;
- height:auto !important;
+
+img {
+ max-width: 100% !important;
+ height: auto !important;
}
.yt {
- position: relative;
+ -webkit-tap-highlight-color: transparent;
}
.embedded-video-play {
- position: absolute;
- top: 22%;
- left: 10%;
- width: 20%;
- opacity: 0.7;
- z-index: 2;
+ width: 25%;
+ padding: 15%;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 100% auto;
}
-.customSignature{
- background: #3C3F41;
+.customSignature {
+ background: #3C3F41;
}
-[style="color: blue;"]
-{
- color: #3452fe !important;
+[style="color: blue;"] {
+ color: #3452fe !important;
}
-[style="color: purple;"]
-{
- color: #a511a5 !important;
+[style="color: purple;"] {
+ color: #a511a5 !important;
}
-[style="color: maroon;"]
-{
- color: #a51111 !important;
+[style="color: maroon;"] {
+ color: #a51111 !important;
}
-span[style="background-color: yellow;"]
-{
- color: black !important;
+span[style="background-color: yellow;"] {
+ color: black !important;
}
-[style="color: white;"] > span[style="background-color: yellow;"]
-{
- color: white !important;
+[style="color: white;"]>span[style="background-color: yellow;"] {
+ color: white !important;
}
diff --git a/app/src/main/assets/style_light.css b/app/src/main/assets/style_light.css
index a3cafed2..b70e8585 100644
--- a/app/src/main/assets/style_light.css
+++ b/app/src/main/assets/style_light.css
@@ -8,4 +8,5 @@ body {
.customSignature {
background: #434649 !important;
+ margin-top: 0.5em;
}
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 a4ede049..76d15b4f 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
@@ -8,6 +8,7 @@ import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -142,7 +143,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
mainContent.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = layoutManager.getItemCount();
lastVisibleItem = layoutManager.findLastVisibleItemPosition();
@@ -189,7 +190,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
* parameter!
*/
private class BoardTask extends ParseTask {
- ArrayList tempSubboards = new ArrayList<>();
+ ArrayList tempSubBoards = new ArrayList<>();
ArrayList tempTopics = new ArrayList<>();
@Override
@@ -200,7 +201,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
@Override //TODO should throw ParseException
public void parse(Document boardPage) throws ParseException {
- tempSubboards.addAll(parsedSubBoards);
+ tempSubBoards.addAll(parsedSubBoards);
tempTopics.addAll(parsedTopics);
//Removes loading item
if (isLoadingMore && tempTopics.size() > 0)
@@ -292,7 +293,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
}
}
if(!parsingFailed)
- tempSubboards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl));
+ tempSubBoards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl));
else
Timber.e("Parsing failed (pLastPost came with: \"%s\", subBoardColumns html was \"%s\")", pLastPost, subBoardColumns);
}
@@ -333,7 +334,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
continue;
}
- pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href");
+ pLastPostUrl = topicColumns.get(6).select("a:has(img)").first().attr("href");
tempTopics.add(new Topic(pTopicUrl, pSubject, pStarter, pLastUser, pLastPostDateTime, pLastPostUrl,
pStats, pLocked, pSticky, pUnread));
}
@@ -356,7 +357,7 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
parsedTopics.clear();
parsedSubBoards.clear();
parsedTopics.addAll(tempTopics);
- parsedSubBoards.addAll(tempSubboards);
+ parsedSubBoards.addAll(tempSubBoards);
boardAdapter.notifyDataSetChanged();
//Parse was successful
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
index 107ed6ce..dcf2ea84 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
@@ -4,6 +4,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
@@ -128,7 +129,7 @@ public class BookmarksActivity extends BaseActivity {
* it may be best to switch to a
* {@link FragmentStatePagerAdapter}.
*/
- private class SectionsPagerAdapter extends FragmentPagerAdapter {
+ private static class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List fragmentList = new ArrayList<>();
private final List fragmentTitleList = new ArrayList<>();
@@ -142,6 +143,7 @@ public class BookmarksActivity extends BaseActivity {
notifyDataSetChanged();
}
+ @NonNull
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
@@ -158,8 +160,7 @@ public class BookmarksActivity extends BaseActivity {
}
@Override
- public int getItemPosition(Object object) {
- @SuppressWarnings("RedundantCast")
+ public int getItemPosition(@NonNull Object object) {
int position = fragmentList.indexOf((Fragment) object);
return position == -1 ? POSITION_NONE : position;
}
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 625f7440..ed4431ce 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
@@ -32,8 +32,6 @@ import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.views.CustomRecyclerView;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import okhttp3.Response;
-import timber.log.Timber;
-
/**
* A {@link BaseFragment} subclass.
@@ -86,10 +84,8 @@ public class RecentFragment extends BaseFragment {
recentTask = new RecentTask(this::onRecentTaskStarted, this::onRecentTaskFinished);
recentTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, SessionManager.indexUrl.toString());
}
- Timber.d("onActivityCreated");
}
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
index d58112ea..a0cac182 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
@@ -19,7 +19,8 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
-import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Objects;
import gr.thmmy.mthmmy.R;
@@ -35,10 +36,10 @@ public class SummaryFragment extends Fragment {
*/
private static final String PROFILE_DOCUMENT = "PROFILE_DOCUMENT";
/**
- * {@link ArrayList} of Strings used to hold profile's information. Data are added in
+ * {@link HashMap} used to hold profile's information. Data are added in
* {@link SummaryTask}.
*/
- private ArrayList parsedProfileSummaryData;
+ private LinkedHashMap parsedProfileSummaryData;
/**
* A {@link Document} holding this profile's source code.
*/
@@ -68,8 +69,8 @@ public class SummaryFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- profileSummaryDocument = Jsoup.parse(requireArguments().getString(PROFILE_DOCUMENT));
- parsedProfileSummaryData = new ArrayList<>();
+ profileSummaryDocument = Jsoup.parse(Objects.requireNonNull(requireArguments().getString(PROFILE_DOCUMENT)));
+ parsedProfileSummaryData = new LinkedHashMap<>();
}
@Override
@@ -123,36 +124,42 @@ public class SummaryFragment extends Fragment {
* @return ArrayList containing this profile's parsed information
* @see org.jsoup.Jsoup Jsoup
*/
- ArrayList parseProfileSummary(Document profile) {
- //Method's variables
- ArrayList parsedInformation = new ArrayList<>();
+ LinkedHashMap parseProfileSummary(Document profile) {
+ LinkedHashMap parsedInformation = new LinkedHashMap<>();
//Contains all summary's rows
- Elements summaryRows = profile.select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) tr");
+ Elements summaryRows = profile.select("td.windowbg > table > tbody > tr");
for (Element summaryRow : summaryRows) {
- String rowText = summaryRow.text(), pHtml = "";
-
- if (summaryRow.select("td").size() == 1) //Horizontal rule rows
- pHtml = "";
- else if (summaryRow.text().contains("Current Status")
- || summaryRow.text().contains("Κατάσταση")) continue;
- else if (rowText.contains("Signature") || rowText.contains("Υπογραφή")) {
- //This needs special handling since it may have css
- pHtml = ParseHelpers.emojiTagToHtml(ParseHelpers.youtubeEmbeddedFix(summaryRow));
- //Add stuff to make it work in WebView
- //style.css
- pHtml = ("\n" +
- "\n" +
- "\n" + pHtml + "\n
");
- } else if (!rowText.contains("Name") && !rowText.contains("Όνομα")) { //Doesn't add username twice
- if (Objects.equals(summaryRow.select("td").get(1).text(), ""))
+ String key, value;
+
+ int tdSize = summaryRow.select("td").size();
+
+ if (tdSize > 1){
+ key = summaryRow.select("td").first().text().trim();
+
+ if (key.startsWith("Name") || key.startsWith("Όνομα"))
continue;
- //Style parsed information with html
- pHtml = "" + summaryRow.select("td").first().text() + " "
- + summaryRow.select("td").get(1).text();
+ else if (key.startsWith("Signature") || key.startsWith("Υπογραφή")){
+ key = summaryRow.selectFirst("td > table > tbody > tr > td").text().trim();
+ summaryRow.selectFirst("td > table > tbody > tr").remove(); //key not needed, outer html needed for CSS
+ value = ParseHelpers.emojiTagToHtml(ParseHelpers.youtubeEmbeddedFix(summaryRow)); // Is emojiTagToHtml() really needed here?
+ if(summaryRow.text().trim().isEmpty())
+ continue;
+ value = ("\n" +
+ "\n" +
+ "\n" + value + "\n
");
+ }
+ else {
+ if (summaryRow.select("td").get(1).text().isEmpty())
+ continue;
+ if (key.startsWith("Date Registered") || key.startsWith("Ημερομηνία εγγραφής") || key.startsWith("Last Active") || key.startsWith("Τελευταία σύνδεση"))
+ value = summaryRow.select("td").get(1).text().trim();
+ else
+ value = summaryRow.select("td").get(1).html().trim();
+ }
+ parsedInformation.put(key, value);
}
- parsedInformation.add(pHtml);
}
return parsedInformation;
}
@@ -165,38 +172,54 @@ public class SummaryFragment extends Fragment {
* {@link #parsedProfileSummaryData}
*/
private void populateLayout() {
- for (String profileSummaryRow : parsedProfileSummaryData) {
- if (profileSummaryRow.contains("Signature")
- || profileSummaryRow.contains("Υπογραφή")) { //This may contain css
- ReactiveWebView signatureEntry = new ReactiveWebView(this.getContext());
- signatureEntry.setBackgroundColor(Color.argb(1, 255, 255, 255));
- signatureEntry.loadDataWithBaseURL("file:///android_asset/", profileSummaryRow,
- "text/html", "UTF-8", null);
- mainContent.addView(signatureEntry);
+ for (LinkedHashMap.Entry entry : parsedProfileSummaryData.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+
+ if (key.startsWith("Current Status") || key.startsWith("Κατάσταση")){
+ addEmptyView();
continue;
}
- TextView entry = new TextView(this.getContext());
-
- if (profileSummaryRow.contains("@") &&
- (profileSummaryRow.contains("Email") || profileSummaryRow.contains("E-mail"))) {
- String email = profileSummaryRow.substring(profileSummaryRow.indexOf(": ") + 6);
- profileSummaryRow = profileSummaryRow.replace(email,
- "" + email + "");
- entry.setMovementMethod(LinkMovementMethod.getInstance());
- }
+
+ TextView textView = new TextView(this.getContext());
+
+ if (((key.startsWith("Email") || key.startsWith("E-mail"))
+ && value.contains("@")) || key.startsWith("Website") || key.startsWith("Ιστοτόπος"))
+ textView.setMovementMethod(LinkMovementMethod.getInstance());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
- entry.setTextColor(getResources().getColor(R.color.primary_text, null));
+ textView.setTextColor(getResources().getColor(R.color.primary_text, null));
else
- entry.setTextColor(getResources().getColor(R.color.primary_text));
+ textView.setTextColor(getResources().getColor(R.color.primary_text));
+
+ String textViewContent = "" + key + " " + value;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY));
- } else {
- entry.setText(Html.fromHtml(profileSummaryRow));
+ if (key.startsWith("Signature") || key.startsWith("Υπογραφή")){
+ addEmptyView();
+ textViewContent = "" + key + "";
}
- mainContent.addView(entry);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ textView.setText(Html.fromHtml(textViewContent, Html.FROM_HTML_MODE_LEGACY));
+ else
+ textView.setText(Html.fromHtml(textViewContent));
+
+ mainContent.addView(textView);
+
+ if (key.startsWith("Last Active") || key.startsWith("Τελευταία σύνδεση"))
+ addEmptyView();
+
+ if (key.startsWith("Signature") || key.startsWith("Υπογραφή")) {
+ ReactiveWebView signatureEntry = new ReactiveWebView(this.getContext());
+ signatureEntry.setBackgroundColor(Color.argb(1, 255, 255, 255));
+ signatureEntry.loadDataWithBaseURL("file:///android_asset/", value,
+ "text/html", "UTF-8", null);
+ mainContent.addView(signatureEntry);
+ }
}
}
+
+ private void addEmptyView(){
+ mainContent.addView(new TextView(this.getContext()));
+ }
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
index d6ab6cfd..0b52b9d7 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
@@ -56,10 +56,12 @@ public class ShoutboxFragment extends Fragment {
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setItemViewCacheSize(25);
recyclerView.setOnTouchListener((view, motionEvent) -> {
editorView.hideMarkdown();
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(editorView.getWindowToken(), 0);
+ if (imm != null)
+ imm.hideSoftInputFromWindow(editorView.getWindowToken(), 0);
return false;
});
@@ -82,7 +84,7 @@ public class ShoutboxFragment extends Fragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.shoutbox_menu, menu);
}
@@ -100,7 +102,7 @@ public class ShoutboxFragment extends Fragment {
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
shoutboxViewModel = ViewModelProviders.of(getActivity()).get(ShoutboxViewModel.class);
- shoutboxViewModel.getShoutboxMutableLiveData().observe(this, shoutbox -> {
+ shoutboxViewModel.getShoutboxMutableLiveData().observe(getViewLifecycleOwner(), shoutbox -> {
if (shoutbox != null) {
Timber.i("Shoutbox loaded successfully");
shoutAdapter.setShouts(shoutbox.getShouts());
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 def64530..9d0d4556 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
@@ -43,7 +43,7 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.AppCompatButton;
-import androidx.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
@@ -113,7 +113,7 @@ class TopicAdapter extends RecyclerView.Adapter {
this.postFocusListener = context;
this.emojiKeyboard = emojiKeyboard;
- viewModel = ViewModelProviders.of(context).get(TopicViewModel.class);
+ viewModel = new ViewModelProvider(context).get(TopicViewModel.class);
}
@Override
@@ -137,7 +137,8 @@ class TopicAdapter extends RecyclerView.Adapter {
quickReplyText.setFocusableInTouchMode(true);
quickReplyText.setOnFocusChangeListener((v, hasFocus) -> quickReplyText.post(() -> {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.showSoftInput(quickReplyText, InputMethodManager.SHOW_IMPLICIT);
+ if (imm != null)
+ imm.showSoftInput(quickReplyText, InputMethodManager.SHOW_IMPLICIT);
}));
quickReplyText.requestFocus();
@@ -150,7 +151,8 @@ class TopicAdapter extends RecyclerView.Adapter {
editPostEdittext.setFocusableInTouchMode(true);
editPostEdittext.setOnFocusChangeListener((v, hasFocus) -> editPostEdittext.post(() -> {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.showSoftInput(editPostEdittext, InputMethodManager.SHOW_IMPLICIT);
+ if (imm != null)
+ imm.showSoftInput(editPostEdittext, InputMethodManager.SHOW_IMPLICIT);
}));
editPostEdittext.requestFocus();
@@ -215,12 +217,10 @@ class TopicAdapter extends RecyclerView.Adapter {
for (Poll.Entry entry : entries) {
CheckBox checkBox = new CheckBox(context);
checkBox.setMovementMethod(LinkMovementMethod.getInstance());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
checkBox.setText(Html.fromHtml(entry.getEntryName(), Html.FROM_HTML_MODE_LEGACY));
- } else {
- //noinspection deprecation
+ else
checkBox.setText(Html.fromHtml(entry.getEntryName()));
- }
checkBox.setTextColor(primaryTextColor);
holder.optionsLayout.addView(checkBox);
}
@@ -236,10 +236,9 @@ class TopicAdapter extends RecyclerView.Adapter {
radioButton.setMovementMethod(LinkMovementMethod.getInstance());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
radioButton.setText(Html.fromHtml(entries[i].getEntryName(), Html.FROM_HTML_MODE_LEGACY));
- } else {
- //noinspection deprecation
+ } else
radioButton.setText(Html.fromHtml(entries[i].getEntryName()));
- }
+
radioButton.setText(ThmmyParser.html2span(context, entries[i].getEntryName()));
radioButton.setTextColor(primaryTextColor);
radioGroup.addView(radioButton);
@@ -255,12 +254,11 @@ class TopicAdapter extends RecyclerView.Adapter {
Poll.Entry entry = entries1[i];
TextView textView = new TextView(context);
textView.setMovementMethod(LinkMovementMethod.getInstance());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
textView.setText(Html.fromHtml(entry.getEntryName(), Html.FROM_HTML_MODE_LEGACY));
- } else {
- //noinspection deprecation
+ else
textView.setText(Html.fromHtml(entry.getEntryName()));
- }
+
textView.setTextColor(primaryTextColor);
if (poll.getSelectedEntryIndex() == i) {
// apply bold to the selected entry
@@ -363,7 +361,6 @@ class TopicAdapter extends RecyclerView.Adapter {
holder.post.setClickable(true);
holder.post.setWebViewClient(new LinkLauncher());
- //noinspection ConstantConditions
loadAvatar(currentPost.getThumbnailURL(), holder.thumbnail, holder.itemView.getContext());
//Sets username,submit date, index number, subject, post's and attached files texts
@@ -385,7 +382,7 @@ class TopicAdapter extends RecyclerView.Adapter {
int filesTextColor;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
filesTextColor = context.getResources().getColor(R.color.accent, null);
- } else //noinspection deprecation
+ } else
filesTextColor = context.getResources().getColor(R.color.accent);
for (final ThmmyFile attachedFile : currentPost.getAttachedFiles()) {
@@ -408,7 +405,7 @@ class TopicAdapter extends RecyclerView.Adapter {
int lastEditTextColor;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
lastEditTextColor = context.getResources().getColor(R.color.white, null);
- } else //noinspection deprecation
+ } else
lastEditTextColor = context.getResources().getColor(R.color.white);
final TextView lastEdit = new TextView(context);
@@ -492,7 +489,7 @@ class TopicAdapter extends RecyclerView.Adapter {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
holder.cardChildLinear.setBackground(context.getResources().
getDrawable(R.drawable.mention_card, null));
- } else //noinspection deprecation
+ } else
holder.cardChildLinear.setBackground(context.getResources().
getDrawable(R.drawable.mention_card));
} else if (mUserColor == TopicParser.USER_COLOR_PINK) {
@@ -500,7 +497,7 @@ class TopicAdapter extends RecyclerView.Adapter {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
holder.cardChildLinear.setBackground(context.getResources().
getDrawable(R.drawable.member_of_the_month_card, null));
- } else //noinspection deprecation
+ } else
holder.cardChildLinear.setBackground(context.getResources().
getDrawable(R.drawable.member_of_the_month_card));
} else holder.cardChildLinear.setBackground(null);
@@ -623,7 +620,6 @@ class TopicAdapter extends RecyclerView.Adapter {
popUp.showAsDropDown(holder.overflowButton);
});
- //noinspection PointlessBooleanExpression,ConstantConditions
if (!BaseActivity.getSessionManager().isLoggedIn() || !viewModel.canReply())
holder.quoteToggle.setVisibility(View.GONE);
else {
@@ -644,7 +640,6 @@ class TopicAdapter extends RecyclerView.Adapter {
final QuickReplyViewHolder holder = (QuickReplyViewHolder) currentHolder;
Post reply = (Post) topicItems.get(position);
- //noinspection ConstantConditions
loadAvatar(getSessionManager().getAvatarLink(), holder.thumbnail, holder.itemView.getContext());
holder.username.setText(getSessionManager().getUsername());
@@ -669,7 +664,9 @@ class TopicAdapter extends RecyclerView.Adapter {
return;
}
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+ if (imm != null)
+ imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+
holder.itemView.setAlpha(0.5f);
holder.itemView.setEnabled(false);
emojiKeyboard.hide();
@@ -696,47 +693,16 @@ class TopicAdapter extends RecyclerView.Adapter {
}
holder.replyEditor.setText(replyText);
holder.replyEditor.getEditText().setSelection(holder.replyEditor.getText().length());
- holder.replyEditor.getEditText().addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- ((Post) topicItems.get(holder.getAdapterPosition())).setBbContent(charSequence.toString());
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
-
- }
- });
+ holder.replyEditor.getEditText().addTextChangedListener(createTextWatcher(holder));
if (backPressHidden) {
holder.replyEditor.requestEditTextFocus();
backPressHidden = false;
}
- holder.quickReplySubject.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- ((Post) topicItems.get(holder.getAdapterPosition())).setSubject(charSequence.toString());
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
-
- }
- });
+ holder.quickReplySubject.addTextChangedListener(createTextWatcher(holder));
} else if (currentHolder instanceof EditMessageViewHolder) {
final EditMessageViewHolder holder = (EditMessageViewHolder) currentHolder;
- //noinspection ConstantConditions
loadAvatar(getSessionManager().getAvatarLink(), holder.thumbnail, holder.itemView.getContext());
holder.username.setText(getSessionManager().getUsername());
@@ -759,7 +725,9 @@ class TopicAdapter extends RecyclerView.Adapter {
return;
}
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+ if (imm != null)
+ imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+
holder.itemView.setAlpha(0.5f);
holder.itemView.setEnabled(false);
emojiKeyboard.hide();
@@ -767,38 +735,9 @@ class TopicAdapter extends RecyclerView.Adapter {
viewModel.editPost(position, holder.editSubject.getText().toString(), holder.editEditor.getText().toString());
});
- holder.editSubject.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- ((Post) topicItems.get(holder.getAdapterPosition())).setSubject(charSequence.toString());
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
-
- }
- });
- holder.editEditor.getEditText().addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ holder.editSubject.addTextChangedListener(createTextWatcher(holder));
+ holder.editEditor.getEditText().addTextChangedListener(createTextWatcher(holder));
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- ((Post) topicItems.get(holder.getAdapterPosition())).setBbContent(charSequence.toString());
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
-
- }
- });
if (backPressHidden) {
holder.editEditor.requestEditTextFocus();
backPressHidden = false;
@@ -807,6 +746,23 @@ class TopicAdapter extends RecyclerView.Adapter {
}
}
+ private TextWatcher createTextWatcher(@NonNull final RecyclerView.ViewHolder holder){
+ return new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ int position = holder.getAdapterPosition();
+ if (position >= 0 && position < topicItems.size())
+ ((Post) topicItems.get(position)).setBbContent(charSequence.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) { }
+ };
+ }
+
private void loadAvatar(String imageUrl, ImageView imageView, Context context) {
if(imageUrl!=null)
imageUrl = imageUrl.trim();
@@ -940,9 +896,7 @@ class TopicAdapter extends RecyclerView.Adapter {
* This class is used to handle link clicks in WebViews. When link url is one that the app can
* handle internally, it does. Otherwise user is prompt to open the link in a browser.
*/
- @SuppressWarnings("unchecked")
private class LinkLauncher extends WebViewClient {
- @SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
final Uri uri = Uri.parse(url);
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java b/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
index 83e55a37..77d4e352 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
@@ -2,6 +2,8 @@ package gr.thmmy.mthmmy.utils.crashreporting;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.google.firebase.crashlytics.FirebaseCrashlytics;
import timber.log.Timber.DebugTree;
@@ -14,7 +16,7 @@ public class CrashReportingTree extends DebugTree {
}
@Override
- protected void log(int priority, String tag, String message, Throwable t) {
+ protected void log(int priority, String tag, @NonNull String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
index 50ca9870..a4acb3ec 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
@@ -128,6 +128,8 @@ public class ParseHelpers {
}
}
+ public static final String VIDEO_ID_PARAMETER = "videoId";
+
/**
* This method fixes html so that embedded videos will render properly and be lightweight.
*
@@ -146,23 +148,28 @@ public class ParseHelpers {
}
String fixed = html.outerHtml();
- int tmp_counter = 0;
+ int counter = 0;
while (fixed.contains("
next
last
- Quick reply…
- Subject…
+ Subject
+ Message
Submit
- Message…
Could not connect to thmmy.gr\n\nTap to retry
Network error
retry