Browse Source

Version 1.8.4

master v1.8.4
Ezerous 4 years ago
parent
commit
e628c1f6db
No known key found for this signature in database GPG Key ID: 262B2954BBA319E3
  1. 6
      app/build.gradle
  2. 29
      app/src/main/AndroidManifest.xml
  3. BIN
      app/src/main/assets/YouTube_light_color_icon.png
  4. 416
      app/src/main/assets/style.css
  5. 1
      app/src/main/assets/style_light.css
  6. 13
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
  7. 7
      app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
  8. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
  9. 129
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
  10. 8
      app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java
  11. 134
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  12. 4
      app/src/main/java/gr/thmmy/mthmmy/utils/crashreporting/CrashReportingTree.java
  13. 27
      app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java
  14. 19
      app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java
  15. 12
      app/src/main/java/gr/thmmy/mthmmy/views/editorview/EditorView.java
  16. 2
      app/src/main/res/layout/activity_create_content.xml
  17. 3
      app/src/main/res/layout/fragment_profile_summary.xml
  18. 5
      app/src/main/res/values/strings.xml

6
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'

29
app/src/main/AndroidManifest.xml

@ -150,6 +150,20 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity" />
</activity>
<activity
android:name=".activities.shoutbox.ShoutboxActivity"
android:configChanges="orientation|screenSize"
android:parentActivityName=".activities.main.MainActivity"
android:theme="@style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity" />
</activity>
<activity
android:name=".activities.create_content.CreateContentActivity"
android:configChanges="orientation|screenSize"
android:parentActivityName=".activities.main.MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
<provider
android:name="androidx.core.content.FileProvider"
@ -176,20 +190,5 @@
<action android:name="gr.thmmy.mthmmy.uploadservice.broadcast.status" />
</intent-filter>
</receiver>
<activity
android:name=".activities.create_content.CreateContentActivity"
android:configChanges="orientation|screenSize"
android:parentActivityName=".activities.main.MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activities.shoutbox.ShoutboxActivity"
android:parentActivityName=".activities.main.MainActivity"
android:theme="@style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity" />
</activity>
</application>
</manifest>

BIN
app/src/main/assets/YouTube_light_color_icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

416
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;
}

1
app/src/main/assets/style_light.css

@ -8,4 +8,5 @@ body {
.customSignature {
background: #434649 !important;
margin-top: 0.5em;
}

13
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!</p>
*/
private class BoardTask extends ParseTask {
ArrayList<Board> tempSubboards = new ArrayList<>();
ArrayList<Board> tempSubBoards = new ArrayList<>();
ArrayList<Topic> 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

7
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<Fragment> fragmentList = new ArrayList<>();
private final List<String> 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;
}

4
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) {

129
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<String> parsedProfileSummaryData;
private LinkedHashMap<String, String> 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<String> parseProfileSummary(Document profile) {
//Method's variables
ArrayList<String> parsedInformation = new ArrayList<>();
LinkedHashMap<String, String> parseProfileSummary(Document profile) {
LinkedHashMap<String, String> 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 = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n" +
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style_light.css\" />\n" +
"<div class=\"customSignature\">\n" + pHtml + "\n</div>");
} 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 = "<b>" + summaryRow.select("td").first().text() + "</b> "
+ 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 = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n" +
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style_light.css\" />\n" +
"<div class=\"customSignature\">\n" + value + "\n</div>");
}
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}</p>
*/
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<String, String> 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(":</b> ") + 6);
profileSummaryRow = profileSummaryRow.replace(email,
"<a href=\"mailto:" + email + "\">" + email + "</a>");
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 = "<b>" + key + "</b> " + 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 = "<b>" + key + "</b>";
}
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()));
}
}

8
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());

134
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
}
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
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<RecyclerView.ViewHolder> {
}
}
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<RecyclerView.ViewHolder> {
* 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);

4
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;
}

27
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("<embed")) {
if (tmp_counter > embededVideosUrls.size())
if (counter > embededVideosUrls.size())
break;
final String videoId = embededVideosUrls.get(counter);
fixed = fixed.replace(
fixed.substring(fixed.indexOf("<embed"), fixed.indexOf("/noembed>") + 9)
, "<div class=\"yt\">"
+ "<a href=\"https://www.youtube.com/watch?v="
+ embededVideosUrls.get(tmp_counter) + "\" target=\"_blank\">"
+ videoId
+ "\" target=\"_blank\">"
+ "<img class=\"embedded-video-play\" "
+ "src=\"YouTube_light_color_icon.png\">"
+ "</a>"
+ "<img src=\"https://img.youtube.com/vi/"
+ embededVideosUrls.get(tmp_counter)
+ "/default.jpg\" alt=\"\" border=\"0\" width=\"40%\">"
+ "</div>");
++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');\"></a></div>"
);
++counter;
}
return fixed;
}

19
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();
}
}

12
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();

2
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"/>
<gr.thmmy.mthmmy.views.editorview.EmojiKeyboard
android:id="@+id/emoji_keyboard"

3
app/src/main/res/layout/fragment_profile_summary.xml

@ -5,8 +5,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_lighter"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="16dp"
android:scrollbars="none">
<LinearLayout

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

@ -61,10 +61,9 @@
<string name="button_page">Page</string>
<string name="button_next">next</string>
<string name="button_last">last</string>
<string name="quick_reply">Quick reply&#8230;</string>
<string name="subject">Subject&#8230;</string>
<string name="subject">Subject</string>
<string name="message">Message</string>
<string name="submit">Submit</string>
<string name="post_message">Message&#8230;</string>
<string name="network_error_retry_prompt">Could not connect to thmmy.gr\n\nTap to retry</string>
<string name="generic_network_error">Network error</string>
<string name="retry">retry</string>

Loading…
Cancel
Save