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(" embededVideosUrls.size()) + if (counter > embededVideosUrls.size()) break; + final String videoId = embededVideosUrls.get(counter); fixed = fixed.replace( fixed.substring(fixed.indexOf("") + 9) , ""); - ++tmp_counter; + + "src=\"YouTube_light_color_icon.png?" + + VIDEO_ID_PARAMETER + + "=" + + videoId // To grab it in ReactiveWebView + + "\" style=\"background-image: url('" + + "https://img.youtube.com/vi/" + + videoId + + "/default.jpg');\">" + ); + ++counter; } return fixed; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java b/app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java index 7c9efdb8..eddd6781 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java +++ b/app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java @@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.views; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.net.Uri; import android.util.AttributeSet; import android.view.MotionEvent; import android.webkit.WebView; @@ -13,6 +14,7 @@ import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.utils.ui.ImageDownloadDialogBuilder; import static android.content.Context.CLIPBOARD_SERVICE; +import static gr.thmmy.mthmmy.utils.parsing.ParseHelpers.VIDEO_ID_PARAMETER; import static gr.thmmy.mthmmy.utils.ui.PhotoViewUtils.displayPhotoViewImage; public class ReactiveWebView extends WebView { @@ -77,8 +79,16 @@ public class ReactiveWebView extends WebView { copyUrlToClipboard(result.getExtra()); else if(result.getType() == WebView.HitTestResult.IMAGE_TYPE) { String imageURL = result.getExtra(); - ImageDownloadDialogBuilder builder = new ImageDownloadDialogBuilder(context,imageURL); - builder.show(); + showImageDownloadDialog(imageURL); + } + else if(result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) { + final String imageURL = result.getExtra(); + Uri uri = Uri.parse(imageURL); + String videoId = uri.getQueryParameter(VIDEO_ID_PARAMETER); + if (videoId!=null) + copyUrlToClipboard("https://www.youtube.com/watch?v=" + videoId); + else + showImageDownloadDialog(imageURL); } return false; }); @@ -90,4 +100,9 @@ public class ReactiveWebView extends WebView { clipboard.setPrimaryClip(clip); Toast.makeText(BaseApplication.getInstance().getApplicationContext(),context.getString(R.string.link_copied_msg),Toast.LENGTH_SHORT).show(); } + + private void showImageDownloadDialog(String imageURL){ + ImageDownloadDialogBuilder builder = new ImageDownloadDialogBuilder(context, imageURL); + builder.show(); + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/views/editorview/EditorView.java b/app/src/main/java/gr/thmmy/mthmmy/views/editorview/EditorView.java index 051bfdfb..df39daa3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/views/editorview/EditorView.java +++ b/app/src/main/java/gr/thmmy/mthmmy/views/editorview/EditorView.java @@ -375,11 +375,13 @@ public class EditorView extends LinearLayout implements EmojiInputField { if (emojiKeyboard.onEmojiButtonToggle()) { //prevent system keyboard from appearing when clicking the edittext editText.setTextIsSelectable(true); - imm.hideSoftInputFromWindow(getWindowToken(), 0); + if (imm != null) + imm.hideSoftInputFromWindow(getWindowToken(), 0); } else { editText.requestFocus(); - imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); + if (imm != null) + imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); } editText.setSelection(selectionStart, selectionEnd); }); @@ -398,10 +400,12 @@ public class EditorView extends LinearLayout implements EmojiInputField { editText.setOnClickListener(view -> { if (!emojiKeyboard.isVisible()) { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE); - imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); + if (imm != null) + imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); } else { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(getWindowToken(), 0); + if (imm != null) + imm.hideSoftInputFromWindow(getWindowToken(), 0); requestEditTextFocus(); } showMarkdown(); diff --git a/app/src/main/res/layout/activity_create_content.xml b/app/src/main/res/layout/activity_create_content.xml index 5c42f68b..279eb871 100644 --- a/app/src/main/res/layout/activity_create_content.xml +++ b/app/src/main/res/layout/activity_create_content.xml @@ -53,7 +53,7 @@ android:layout_below="@id/subject_input" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" - app:hint="topic message"/> + app:hint="@string/message"/> Page
next last - Quick reply… - Subject… + Subject + Message Submit - Message… Could not connect to thmmy.gr\n\nTap to retry Network error retry