Browse Source

Version 2.1.0

master v2.1.0
Ezerous 2 years ago
parent
commit
51343cc918
  1. 10
      app/build.gradle
  2. 3
      app/src/main/AndroidManifest.xml
  3. 14
      app/src/main/assets/style.css
  4. 13
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
  5. 85
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java
  6. 13
      app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java
  7. 18
      app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java
  8. 7
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  9. 2
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
  10. 52
      app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java
  11. 63
      app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java
  12. 10
      app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
  13. 2
      app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
  14. 9
      app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java
  15. 6
      app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java
  16. 6
      app/src/main/res/layout/activity_upload_file_list_row.xml
  17. 8
      app/src/main/res/layout/fragment_bookmarks.xml
  18. 23
      app/src/main/res/layout/fragment_bookmarks_row.xml
  19. 5
      app/src/main/res/values/strings.xml

10
app/build.gradle

@ -7,15 +7,15 @@ apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics' apply plugin: 'com.google.firebase.crashlytics'
android { android {
compileSdkVersion 30 compileSdkVersion 31
buildToolsVersion = '30.0.2' buildToolsVersion = '30.0.2'
defaultConfig { defaultConfig {
applicationId "gr.thmmy.mthmmy" applicationId "gr.thmmy.mthmmy"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode 30 versionCode 31
versionName "2.0.0" versionName "2.1.0"
archivesBaseName = "mTHMMY-v$versionName" archivesBaseName = "mTHMMY-v$versionName"
buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\"" buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\""
buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\"" buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\""
@ -76,14 +76,14 @@ tasks.whenTaskAdded { task ->
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":emojis") implementation project(":emojis")
implementation 'androidx.appcompat:appcompat:1.4.0-alpha03' implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.exifinterface:exifinterface:1.3.3' implementation 'androidx.exifinterface:exifinterface:1.3.3'
implementation 'com.google.android.material:material:1.4.0' implementation 'com.google.android.material:material:1.4.0'
implementation platform('com.google.firebase:firebase-bom:28.4.0') implementation platform('com.google.firebase:firebase-bom:28.4.0')

3
app/src/main/AndroidManifest.xml

@ -7,8 +7,8 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@ -41,6 +41,7 @@
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleTask" android:launchMode="singleTask"
android:exported="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

14
app/src/main/assets/style.css

@ -188,7 +188,7 @@ a img {
margin: 1px; margin: 1px;
padding: 1px; padding: 1px;
font-size: x-small; font-size: x-small;
line-height: 1.4em; line-height: 1.4;
} }
@ -199,7 +199,7 @@ a img {
background-color: #626566; background-color: #626566;
font-family: "Comic Sans MS", "times new roman", monospace; font-family: "Comic Sans MS", "times new roman", monospace;
font-size: x-small; font-size: x-small;
line-height: 1.3em; line-height: 1.3;
/* Put a nice border around it. */ /* Put a nice border around it. */
border: 1px solid #FFFFFF; border: 1px solid #FFFFFF;
margin: 1px auto 1px auto; margin: 1px auto 1px auto;
@ -223,7 +223,7 @@ a img {
font-style: normal; font-style: normal;
font-weight: bold; font-weight: bold;
font-size: x-small; font-size: x-small;
line-height: 1.2em; line-height: 1.2;
} }
@ -361,7 +361,7 @@ tr.titlebg2 td,
.personalmessage { .personalmessage {
width: 100%; width: 100%;
overflow: auto; overflow: auto;
line-height: 1.3em; line-height: 1.3;
color: white; color: white;
background: #3C3F41 !important; background: #3C3F41 !important;
} }
@ -373,7 +373,7 @@ tr.titlebg2 td,
width: 100%; width: 100%;
overflow: auto; overflow: auto;
padding-bottom: 3px; padding-bottom: 3px;
line-height: 1.3em; line-height: 1.3;
} }
#left { #left {
@ -597,3 +597,7 @@ span[style="background-color: yellow;"] {
[style="color: white;"]>span[style="background-color: yellow;"] { [style="color: white;"]>span[style="background-color: yellow;"] {
color: white !important; color: white !important;
} }
span[style*="line-height: 1.3em;"] {
line-height: 1.3 !important;
}

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

@ -250,7 +250,6 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (pStats.equals("--")) if (pStats.equals("--"))
pStats = ""; pStats = "";
} }
else if (Objects.equals(subBoardCol.className(), "smalltext")) { else if (Objects.equals(subBoardCol.className(), "smalltext")) {
pLastPost = subBoardCol.text(); pLastPost = subBoardCol.text();
if (pLastPost.contains(" in ") || pLastPost.contains(" σε ")) { if (pLastPost.contains(" in ") || pLastPost.contains(" σε ")) {
@ -281,7 +280,6 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
parsingFailed = true; parsingFailed = true;
break; break;
} }
} }
else if (pLastPost.contains("redirected clicks") || pLastPost.contains("N/A")) else if (pLastPost.contains("redirected clicks") || pLastPost.contains("N/A"))
pLastPost = ""; pLastPost = "";
@ -289,11 +287,18 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
pLastPost = "No posts yet"; pLastPost = "No posts yet";
} }
else { else {
pUrl = subBoardCol.select("a").first().attr("href"); Element subBoardTitleElement = subBoardCol.select("a").first();
pTitle = subBoardCol.select("a").first().text(); if (subBoardTitleElement != null) {
pUrl = subBoardTitleElement.attr("href");
pTitle = subBoardTitleElement.text();
if (subBoardCol.select("div.smalltext").first() != null) if (subBoardCol.select("div.smalltext").first() != null)
pMods = subBoardCol.select("div.smalltext").first().text(); pMods = subBoardCol.select("div.smalltext").first().text();
} }
else {
parsingFailed = true;
break;
}
}
} }
if (!parsingFailed) if (!parsingFailed)
tempSubBoards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl)); tempSubBoards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost, pLastPostUrl));

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

@ -32,11 +32,9 @@ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
* {@link RecyclerView.Adapter} that can display a {@link gr.thmmy.mthmmy.model.Board}. * {@link RecyclerView.Adapter} that can display a {@link gr.thmmy.mthmmy.model.Board}.
*/ */
class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_SUB_BOARD_TITLE = 0; private final int VIEW_TYPE_SUB_BOARD = 0;
private final int VIEW_TYPE_SUB_BOARD = 1; private final int VIEW_TYPE_TOPIC = 1;
private final int VIEW_TYPE_TOPIC_TITLE = 2; private final int VIEW_TYPE_LOADING = 2;
private final int VIEW_TYPE_TOPIC = 3;
private final int VIEW_TYPE_LOADING = 4;
private final Context context; private final Context context;
private ArrayList<Board> parsedSubBoards; private ArrayList<Board> parsedSubBoards;
@ -56,13 +54,11 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (position <= parsedSubBoards.size()) { if (position < parsedSubBoards.size()) {
if (position == 0) return VIEW_TYPE_SUB_BOARD_TITLE;
return VIEW_TYPE_SUB_BOARD; return VIEW_TYPE_SUB_BOARD;
} }
else if (position <= parsedSubBoards.size() + parsedTopics.size() + 1) { else if (position < parsedSubBoards.size() + parsedTopics.size()) {
if (position == parsedSubBoards.size() + 1) return VIEW_TYPE_TOPIC_TITLE; if (parsedTopics.get(position - parsedSubBoards.size()) != null) //??
if (parsedTopics.get(position - parsedSubBoards.size() - 1 - 1) != null)
return VIEW_TYPE_TOPIC; return VIEW_TYPE_TOPIC;
} }
return VIEW_TYPE_LOADING; return VIEW_TYPE_LOADING;
@ -70,52 +66,11 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_SUB_BOARD_TITLE) { if (viewType == VIEW_TYPE_SUB_BOARD) {
TextView subBoardTitle = new TextView(context);
subBoardTitle.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.WRAP_CONTENT));
subBoardTitle.setText(context.getString(R.string.child_board_title));
subBoardTitle.setTypeface(subBoardTitle.getTypeface(), Typeface.BOLD);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
subBoardTitle.setBackgroundColor(context.getColor(R.color.background_light));
subBoardTitle.setTextColor(context.getColor(R.color.accent));
}
else {
//noinspection deprecation
subBoardTitle.setBackgroundColor(context.getResources().getColor(R.color.background_light));
//noinspection deprecation
subBoardTitle.setTextColor(context.getResources().getColor(R.color.accent));
}
subBoardTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
subBoardTitle.setTextSize(20f);
return new TitlesViewHolder(subBoardTitle);
}
else if (viewType == VIEW_TYPE_SUB_BOARD) {
View subBoard = LayoutInflater.from(parent.getContext()). View subBoard = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_board_sub_board_row, parent, false); inflate(R.layout.activity_board_sub_board_row, parent, false);
return new SubBoardViewHolder(subBoard); return new SubBoardViewHolder(subBoard);
} }
else if (viewType == VIEW_TYPE_TOPIC_TITLE) {
TextView topicTitle = new TextView(context);
topicTitle.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.WRAP_CONTENT));
topicTitle.setText(context.getString(R.string.topic_title));
topicTitle.setTypeface(topicTitle.getTypeface(), Typeface.BOLD);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
topicTitle.setTextColor(context.getColor(R.color.primary_text));
}
else {
//noinspection deprecation
topicTitle.setTextColor(context.getResources().getColor(R.color.primary_text));
}
topicTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
topicTitle.setTextSize(20f);
return new TitlesViewHolder(topicTitle);
}
else if (viewType == VIEW_TYPE_TOPIC) { else if (viewType == VIEW_TYPE_TOPIC) {
View topic = LayoutInflater.from(parent.getContext()). View topic = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_board_topic_row, parent, false); inflate(R.layout.activity_board_topic_row, parent, false);
@ -132,7 +87,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof SubBoardViewHolder) { if (holder instanceof SubBoardViewHolder) {
final Board subBoard = parsedSubBoards.get(position - 1); final Board subBoard = parsedSubBoards.get(position);
final SubBoardViewHolder subBoardViewHolder = (SubBoardViewHolder) holder; final SubBoardViewHolder subBoardViewHolder = (SubBoardViewHolder) holder;
if (boardExpandableVisibility.size() != parsedSubBoards.size()) { if (boardExpandableVisibility.size() != parsedSubBoards.size()) {
@ -149,7 +104,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent); context.startActivity(intent);
}); });
if (boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition() - 1)) { if (boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition())) {
subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE); subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE);
subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
} }
@ -158,7 +113,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
} }
subBoardViewHolder.showHideExpandable.setOnClickListener(view -> { subBoardViewHolder.showHideExpandable.setOnClickListener(view -> {
final boolean visible = boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition() - 1); final boolean visible = boardExpandableVisibility.get(subBoardViewHolder.getAdapterPosition());
if (visible) { if (visible) {
subBoardViewHolder.boardExpandable.setVisibility(View.GONE); subBoardViewHolder.boardExpandable.setVisibility(View.GONE);
subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
@ -167,7 +122,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE); subBoardViewHolder.boardExpandable.setVisibility(View.VISIBLE);
subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); subBoardViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
} }
boardExpandableVisibility.set(subBoardViewHolder.getAdapterPosition() - 1, !visible); boardExpandableVisibility.set(subBoardViewHolder.getAdapterPosition(), !visible);
}); });
subBoardViewHolder.boardTitle.setText(subBoard.getTitle()); subBoardViewHolder.boardTitle.setText(subBoard.getTitle());
String mods = subBoard.getMods(); String mods = subBoard.getMods();
@ -202,7 +157,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
} }
} }
else if (holder instanceof TopicViewHolder) { else if (holder instanceof TopicViewHolder) {
final Topic topic = parsedTopics.get(position - parsedSubBoards.size() - 1 - 1); final Topic topic = parsedTopics.get(position - parsedSubBoards.size());
final TopicViewHolder topicViewHolder = (TopicViewHolder) holder; final TopicViewHolder topicViewHolder = (TopicViewHolder) holder;
if (topicExpandableVisibility.size() != parsedTopics.size()) { if (topicExpandableVisibility.size() != parsedTopics.size()) {
@ -220,7 +175,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
context.startActivity(intent); context.startActivity(intent);
}); });
if (topicExpandableVisibility.get(topicViewHolder.getAdapterPosition() - parsedSubBoards if (topicExpandableVisibility.get(topicViewHolder.getAdapterPosition() - parsedSubBoards
.size() - 2)) { .size())) {
topicViewHolder.topicExpandable.setVisibility(View.VISIBLE); topicViewHolder.topicExpandable.setVisibility(View.VISIBLE);
topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
} }
@ -230,7 +185,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
} }
topicViewHolder.showHideExpandable.setOnClickListener(view -> { topicViewHolder.showHideExpandable.setOnClickListener(view -> {
final boolean visible = topicExpandableVisibility.get(topicViewHolder. final boolean visible = topicExpandableVisibility.get(topicViewHolder.
getAdapterPosition() - parsedSubBoards.size() - 2); getAdapterPosition() - parsedSubBoards.size());
if (visible) { if (visible) {
topicViewHolder.topicExpandable.setVisibility(View.GONE); topicViewHolder.topicExpandable.setVisibility(View.GONE);
topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
@ -240,7 +195,7 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp); topicViewHolder.showHideExpandable.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
} }
topicExpandableVisibility.set(topicViewHolder.getAdapterPosition() - topicExpandableVisibility.set(topicViewHolder.getAdapterPosition() -
parsedSubBoards.size() - 2, !visible); parsedSubBoards.size(), !visible);
}); });
topicViewHolder.topicSubject.setTypeface(Typeface.createFromAsset(context.getAssets() topicViewHolder.topicSubject.setTypeface(Typeface.createFromAsset(context.getAssets()
, "fonts/fontawesome-webfont.ttf")); , "fonts/fontawesome-webfont.ttf"));
@ -280,8 +235,8 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public int getItemCount() { public int getItemCount() {
int items = 0; int items = 0;
if (parsedSubBoards != null) items += parsedSubBoards.size() + 1; if (parsedSubBoards != null) items += parsedSubBoards.size();
if (parsedTopics != null) items += parsedTopics.size() + 1; if (parsedTopics != null) items += parsedTopics.size();
return items; return items;
} }
@ -320,12 +275,6 @@ class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
} }
} }
private static class TitlesViewHolder extends RecyclerView.ViewHolder {
TitlesViewHolder(View title) {
super(title);
}
}
private static class LoadingViewHolder extends RecyclerView.ViewHolder { private static class LoadingViewHolder extends RecyclerView.ViewHolder {
final MaterialProgressBar progressBar; final MaterialProgressBar progressBar;

13
app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java

@ -89,7 +89,9 @@ public class BookmarksActivity extends BaseActivity {
startActivity(intent); startActivity(intent);
break; break;
case BookmarksFragment.INTERACTION_TOGGLE_TOPIC_NOTIFICATION: case BookmarksFragment.INTERACTION_TOGGLE_TOPIC_NOTIFICATION:
return toggleNotification(bookmarkedTopic); boolean notificationsEnabled = toggleNotification(bookmarkedTopic);
displayNotificationsToggleToast(notificationsEnabled);
return notificationsEnabled;
case BookmarksFragment.INTERACTION_REMOVE_TOPIC_BOOKMARK: case BookmarksFragment.INTERACTION_REMOVE_TOPIC_BOOKMARK:
removeBookmark(bookmarkedTopic); removeBookmark(bookmarkedTopic);
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Bookmark removed", Toast.LENGTH_SHORT).show(); Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Bookmark removed", Toast.LENGTH_SHORT).show();
@ -112,7 +114,9 @@ public class BookmarksActivity extends BaseActivity {
startActivity(intent); startActivity(intent);
break; break;
case BookmarksFragment.INTERACTION_TOGGLE_BOARD_NOTIFICATION: case BookmarksFragment.INTERACTION_TOGGLE_BOARD_NOTIFICATION:
return toggleNotification(bookmarkedBoard); boolean notificationsEnabled = toggleNotification(bookmarkedBoard);
displayNotificationsToggleToast(notificationsEnabled);
return notificationsEnabled;
case BookmarksFragment.INTERACTION_REMOVE_BOARD_BOOKMARK: case BookmarksFragment.INTERACTION_REMOVE_BOARD_BOOKMARK:
removeBookmark(bookmarkedBoard); removeBookmark(bookmarkedBoard);
Toast.makeText(getApplicationContext(), "Bookmark removed", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), "Bookmark removed", Toast.LENGTH_SHORT).show();
@ -123,6 +127,11 @@ public class BookmarksActivity extends BaseActivity {
return true; return true;
} }
private void displayNotificationsToggleToast (boolean notificationsEnabled){
String toastText = notificationsEnabled ? "Notifications enabled" : "Notifications disabled";
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), toastText, Toast.LENGTH_SHORT).show();
}
/** /**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages. If it becomes too memory intensive, * one of the sections/tabs/pages. If it becomes too memory intensive,

18
app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java

@ -1,6 +1,7 @@
package gr.thmmy.mthmmy.activities.bookmarks; package gr.thmmy.mthmmy.activities.bookmarks;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -11,11 +12,14 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import java.util.ArrayList; import java.util.ArrayList;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.board.BoardActivity;
import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.Bookmark;
//TODO refactor using RecyclerView //TODO refactor using RecyclerView
@ -83,10 +87,8 @@ public class BookmarksFragment extends Fragment {
} }
} }
notificationsEnabledButtonImage = getResources().getDrawable(R.drawable.ic_notification_on, null); notificationsEnabledButtonImage = getResources().getDrawable(R.drawable.ic_notification_on, null);
notificationsDisabledButtonImage = getResources().getDrawable(R.drawable.ic_notification_off, null); notificationsDisabledButtonImage = getResources().getDrawable(R.drawable.ic_notification_off, null);
} }
@Override @Override
@ -104,7 +106,7 @@ public class BookmarksFragment extends Fragment {
if (bookmark != null && bookmark.getTitle() != null) { if (bookmark != null && bookmark.getTitle() != null) {
final LinearLayout row = (LinearLayout) layoutInflater.inflate( final LinearLayout row = (LinearLayout) layoutInflater.inflate(
R.layout.fragment_bookmarks_row, bookmarksLinearView, false); R.layout.fragment_bookmarks_row, bookmarksLinearView, false);
row.setOnClickListener(view -> { row.findViewById(R.id.bookmark_card).setOnClickListener(view -> {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity instanceof BookmarksActivity) if (activity instanceof BookmarksActivity)
((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionClick, bookmark); ((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionClick, bookmark);
@ -129,14 +131,20 @@ public class BookmarksFragment extends Fragment {
(row.findViewById(R.id.remove_bookmark)).setOnClickListener(view -> { (row.findViewById(R.id.remove_bookmark)).setOnClickListener(view -> {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity instanceof BookmarksActivity) { if (activity instanceof BookmarksActivity) {
new AlertDialog.Builder(activity)
.setMessage("Are you sure that you want to remove this bookmark?")
.setPositiveButton("Yes", (dialogInterface, i) -> {
((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionRemove, bookmark); ((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionRemove, bookmark);
bookmarks.remove(bookmark); bookmarks.remove(bookmark);
}
row.setVisibility(View.GONE); row.setVisibility(View.GONE);
if (bookmarks.isEmpty()) { if (bookmarks.isEmpty()) {
showNothingBookmarked(); showNothingBookmarked();
} }
})
.setNegativeButton("No", (dialogInterface, i) -> {
})
.show();
}
}); });
bookmarksLinearView.addView(row); bookmarksLinearView.addView(row);
} }

7
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -633,8 +633,11 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
else { else {
Timber.i("Post edit unsuccessful"); Timber.i("Post edit unsuccessful");
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Edit failed!", Toast.LENGTH_SHORT).show(); Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Edit failed!", Toast.LENGTH_SHORT).show();
recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setAlpha(1); View postBeingEditedView = recyclerView.getChildAt(viewModel.getPostBeingEditedPosition());
recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setEnabled(true); if (postBeingEditedView != null) {
postBeingEditedView.setAlpha(1);
postBeingEditedView.setEnabled(true);
}
} }
} }
}); });

2
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java

@ -125,7 +125,7 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
0, 0, 0, 0, null, null); 0, 0, 0, 0, null, null);
} }
else { else {
Timber.e(e, "Topic parse failed"); Timber.e(e, "Topic parsing failed (%s)!", newPageUrl);
return new TopicTaskResult(ResultCode.PARSING_ERROR, null, null, null, return new TopicTaskResult(ResultCode.PARSING_ERROR, null, null, null,
0, 0, 0, 0, null, null); 0, 0, 0, 0, null, null);
} }

52
app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java

@ -10,6 +10,7 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.Spannable; import android.text.Spannable;
@ -327,31 +328,21 @@ public class UploadActivity extends BaseActivity {
//File should be uploaded with a different name //File should be uploaded with a different name
if (checkPerms()) { if (checkPerms()) {
if (!uploadFile.isCameraPhoto()) { String newFileName = FileUtils.getFilenameWithoutExtension(editTextFilename);
//Temporarily copies the file to a another location and renames it
if(uploadFile.isCameraPhoto())
newFileName = newFileName + ".jpg";
//Temporarily copies the file to another location (external cache) and renames it
tempFileUri = UploadsHelper.createTempFile(this, storage, tempFileUri = UploadsHelper.createTempFile(this, storage,
uploadFile.getFileUri(), uploadFile.getFileUri(),
FileUtils.getFilenameWithoutExtension(editTextFilename)); newFileName);
}
else { //Something went wrong while creating temporary file, abort
//Renames the photo taken if(tempFileUri == null){
String photoPath = uploadFile.getPhotoFile().getPath();
photoPath = photoPath.substring(0, photoPath.lastIndexOf(File.separator));
String destinationFilename = photoPath + File.separator +
FileUtils.getFilenameWithoutExtension(editTextFilename) + ".jpg";
if (!storage.rename(uploadFile.getPhotoFile().getAbsolutePath(), destinationFilename)) {
//Something went wrong, abort
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Could not create temporary file for renaming", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
return; return;
} }
//Points photoFile and fileUri to the new copied and renamed file
uploadFile.setPhotoFile(storage.getFile(destinationFilename));
uploadFile.setFileUri(FileProvider.getUriForFile(this, getPackageName() +
".provider", uploadFile.getPhotoFile()));
}
} }
else { else {
requestPerms(UPLOAD_REQUEST_STORAGE_CODE); requestPerms(UPLOAD_REQUEST_STORAGE_CODE);
@ -561,7 +552,7 @@ public class UploadActivity extends BaseActivity {
UploadFile newFile = new UploadFile(true, TakePhoto.processResult(this, UploadFile newFile = new UploadFile(true, TakePhoto.processResult(this,
photoFileCreated), photoFileCreated); photoFileCreated), photoFileCreated);
addFileViewToList(FileUtils.getFilenameWithoutExtension(FileUtils. addFileViewToList(FileUtils.getFilenameWithoutExtension(FileUtils.
filenameFromUri(this, newFile.getFileUri()))); filenameFromUri(this, newFile.getFileUri())) + ".jpg");
filesList.add(newFile); filesList.add(newFile);
} }
else if (requestCode == AFR_REQUEST_CODE_FIELDS_BUILDER) { else if (requestCode == AFR_REQUEST_CODE_FIELDS_BUILDER) {
@ -596,6 +587,10 @@ public class UploadActivity extends BaseActivity {
case UPLOAD_REQUEST_CAMERA_CODE: case UPLOAD_REQUEST_CAMERA_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
takePhoto(); takePhoto();
else {
Timber.w("Take photo failed (permission denied).");
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Take photo failed (storage permission denied)", Toast.LENGTH_SHORT).show();
}
break; break;
case UPLOAD_REQUEST_STORAGE_CODE: case UPLOAD_REQUEST_STORAGE_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
@ -609,6 +604,7 @@ public class UploadActivity extends BaseActivity {
finish(); finish();
} }
else { else {
Timber.w("Zip task failed (permission denied).");
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Please retry uploading.", Toast.LENGTH_SHORT).show(); Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Please retry uploading.", Toast.LENGTH_SHORT).show();
} }
break; break;
@ -720,17 +716,23 @@ public class UploadActivity extends BaseActivity {
cancelIntent.setAction(UploadsReceiver.ACTION_CANCEL_UPLOAD); cancelIntent.setAction(UploadsReceiver.ACTION_CANCEL_UPLOAD);
cancelIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); cancelIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID);
int pendingIntentFlags;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
pendingIntentFlags = PendingIntent.FLAG_MUTABLE |PendingIntent.FLAG_UPDATE_CURRENT;
else
pendingIntentFlags = PendingIntent.FLAG_UPDATE_CURRENT;
uploadNotificationConfig.getProgress().actions.add(new UploadNotificationAction( uploadNotificationConfig.getProgress().actions.add(new UploadNotificationAction(
R.drawable.ic_cancel_accent_24dp, R.drawable.ic_cancel_accent_24dp,
context.getString(R.string.cancel), context.getString(R.string.cancel),
PendingIntent.getBroadcast(context, 0, cancelIntent, PendingIntent.getBroadcast(context, 0, cancelIntent,
PendingIntent.FLAG_UPDATE_CURRENT) pendingIntentFlags)
)); ));
uploadNotificationConfig.getError().actions.add(new UploadNotificationAction( uploadNotificationConfig.getError().actions.add(new UploadNotificationAction(
R.drawable.ic_notification, R.drawable.ic_notification,
context.getString(R.string.upload_retry), context.getString(R.string.upload_retry),
PendingIntent.getBroadcast(context, 0, retryIntent, PendingIntent.getBroadcast(context, 0, retryIntent,
PendingIntent.FLAG_UPDATE_CURRENT) pendingIntentFlags)
)); ));
return uploadNotificationConfig; return uploadNotificationConfig;
@ -1069,7 +1071,7 @@ public class UploadActivity extends BaseActivity {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
assert weakActivity != null; assert weakActivity != null;
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Zipping files", Toast.LENGTH_SHORT).show(); Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Zipping files...", Toast.LENGTH_SHORT).show();
} }
@Override @Override
@ -1077,7 +1079,7 @@ public class UploadActivity extends BaseActivity {
if (weakActivity == null || zipFilename == null) if (weakActivity == null || zipFilename == null)
return false; return false;
File zipFile = UploadsHelper.createZipFile(zipFilename); File zipFile = UploadsHelper.createZipFile(weakActivity.get(), zipFilename);
if (zipFile == null) if (zipFile == null)
return false; return false;

63
app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java

@ -2,7 +2,6 @@ package gr.thmmy.mthmmy.activities.upload;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Environment;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -27,24 +26,19 @@ import timber.log.Timber;
public class UploadsHelper { public class UploadsHelper {
private static final int BUFFER = 4096; private static final int BUFFER = 4096;
private static final String TEMP_FILES_DIRECTORY = "~tmp_mTHMMY_uploads";
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")
@Nullable @Nullable
static Uri createTempFile(Context context, Storage storage, Uri fileUri, String newFilename) { static Uri createTempFile(Context context, Storage storage, Uri fileUri, String newFilename) {
Timber.i("Creating new temporary file (%s)", newFilename);
String oldFilename = FileUtils.filenameFromUri(context, fileUri); String oldFilename = FileUtils.filenameFromUri(context, fileUri);
String fileExtension = oldFilename.substring(oldFilename.indexOf('.')); String fileExtension = oldFilename.substring(oldFilename.indexOf('.'));
String destinationFilename = Environment.getExternalStorageDirectory().getPath() +
File.separatorChar + TEMP_FILES_DIRECTORY + File.separatorChar + newFilename + fileExtension;
File tempDirectory = new File(android.os.Environment.getExternalStorageDirectory().getPath() + File tempFilesDirectory = createTempFilesDir(context);
File.separatorChar + TEMP_FILES_DIRECTORY); if (tempFilesDirectory==null)
if (!tempDirectory.exists() && !tempDirectory.mkdirs()) {
Timber.w("Temporary directory build returned false in %s", UploadActivity.class.getSimpleName());
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Couldn't create temporary directory", Toast.LENGTH_SHORT).show();
return null; return null;
}
String destinationFilename = tempFilesDirectory.getAbsolutePath() + File.separatorChar + newFilename + fileExtension;
InputStream inputStream; InputStream inputStream;
BufferedInputStream bufferedInputStream = null; BufferedInputStream bufferedInputStream = null;
@ -53,7 +47,7 @@ public class UploadsHelper {
try { try {
inputStream = context.getContentResolver().openInputStream(fileUri); inputStream = context.getContentResolver().openInputStream(fileUri);
if (inputStream == null) { if (inputStream == null) {
Timber.w("Input stream was null, %s", UploadActivity.class.getSimpleName()); Timber.e("Input stream was null, %s", UploadActivity.class.getSimpleName());
return null; return null;
} }
@ -81,20 +75,19 @@ public class UploadsHelper {
} }
@Nullable @Nullable
static File createZipFile(@NonNull String zipFilename) { static File createZipFile(Context context, @NonNull String zipFilename) {
// Create a zip file name // Create a zip file in temp directory
File zipFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + Timber.i("Creating temporary zip file %s", zipFilename);
File.separator + "mTHMMY");
if (!zipFolder.exists() && !zipFolder.mkdirs()) { File tempFilesDirectory = createTempFilesDir(context);
Timber.w("Zip folder build returned false in %s", UploadsHelper.class.getSimpleName()); if (tempFilesDirectory==null)
return null; return null;
}
return new File(zipFolder, zipFilename); return new File(tempFilesDirectory, zipFilename);
} }
static void zip(Context context, Uri[] files, Uri zipFile) { static void zip(Context context, Uri[] files, Uri zipFile) {
Timber.i("Adding files to %s...", zipFile.getPath());
try { try {
BufferedInputStream origin; BufferedInputStream origin;
OutputStream dest = context.getContentResolver().openOutputStream(zipFile); OutputStream dest = context.getContentResolver().openOutputStream(zipFile);
@ -117,21 +110,45 @@ public class UploadsHelper {
origin.close(); origin.close();
} }
Timber.i("Files added successfully to %s.", zipFile.getPath());
out.close(); out.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void deleteTempFiles(Storage storage) { private static File createTempFilesDir(Context context){
File tempFilesDirectory = new File(Environment.getExternalStorageDirectory().getPath() + File tempFilesDirectory = context.getExternalCacheDir();
File.separatorChar + TEMP_FILES_DIRECTORY);
if (tempFilesDirectory == null){
Timber.e("Temporary files directory error (%s)!", UploadActivity.class.getSimpleName());
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Temporary files directory error (%s)!", Toast.LENGTH_SHORT).show();
return null;
}
if (!tempFilesDirectory.exists() && !tempFilesDirectory.mkdirs()) {
Timber.e("Temporary directory %s creation returned false (%s)", tempFilesDirectory.getAbsolutePath(), UploadActivity.class.getSimpleName());
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Couldn't create temporary directory for file renaming!", Toast.LENGTH_SHORT).show();
return null;
}
return tempFilesDirectory;
}
public static void deleteTempFiles(Context context, Storage storage) {
File tempFilesDirectory = context.getExternalCacheDir();
if (tempFilesDirectory != null){
if (storage.isDirectoryExists(tempFilesDirectory.getAbsolutePath())) { if (storage.isDirectoryExists(tempFilesDirectory.getAbsolutePath())) {
for (File tempFile : storage.getFiles(tempFilesDirectory.getAbsolutePath())) { for (File tempFile : storage.getFiles(tempFilesDirectory.getAbsolutePath())) {
storage.deleteFile(tempFile.getAbsolutePath()); storage.deleteFile(tempFile.getAbsolutePath());
} }
storage.deleteDirectory(tempFilesDirectory.getAbsolutePath()); storage.deleteDirectory(tempFilesDirectory.getAbsolutePath());
Timber.i("Deleted temp files from cache.");
}
} }
else
Timber.e("Couldn't delete temp files!");
} }
} }

10
app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java

@ -694,6 +694,7 @@ public abstract class BaseActivity extends AppCompatActivity {
//True if permissions are OK //True if permissions are OK
protected boolean checkPerms() { protected boolean checkPerms() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
Timber.i("Checking storage permissions.");
String[] PERMISSIONS_STORAGE = { String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}; Manifest.permission.WRITE_EXTERNAL_STORAGE};
@ -705,12 +706,14 @@ public abstract class BaseActivity extends AppCompatActivity {
} }
//Display popup for user to grant permission //Display popup for user to grant permission
protected void requestPerms(int code) { //Runtime permissions request for devices with API >= 23 protected void requestPerms(int code) {
//Runtime permissions request for devices with API >= 23
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
String[] PERMISSIONS_STORAGE = { String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}; Manifest.permission.WRITE_EXTERNAL_STORAGE};
Timber.i("Requesting storage permissions (code %d).", code);
requestPermissions(PERMISSIONS_STORAGE, code); requestPermissions(PERMISSIONS_STORAGE, code);
} }
} }
@ -722,9 +725,12 @@ public abstract class BaseActivity extends AppCompatActivity {
if (permsRequestCode == DOWNLOAD_REQUEST_CODE) { if (permsRequestCode == DOWNLOAD_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
prepareDownload(tempThmmyFile); prepareDownload(tempThmmyFile);
else {
Timber.w("Download failed (permission denied).");
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Download failed (storage permission denied)", Toast.LENGTH_SHORT).show();
}
} }
} }
//----------------------------------DOWNLOAD---------------------- //----------------------------------DOWNLOAD----------------------
private ThmmyFile tempThmmyFile; private ThmmyFile tempThmmyFile;

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

@ -147,7 +147,7 @@ public class BaseApplication extends Application implements Executor{
boolean updated = task.getResult(); boolean updated = task.getResult();
Timber.i("Firebase remote config params updated: %s", updated); Timber.i("Firebase remote config params updated: %s", updated);
} else } else
Timber.e("Fetching Firebase remote config params failed!"); Timber.w("Fetching Firebase remote config params failed!");
}); });
} }

9
app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java

@ -178,8 +178,15 @@ public class NotificationService extends FirebaseMessagingService {
extras.putString(BUNDLE_TOPIC_TITLE, postNotification.getTopicTitle()); extras.putString(BUNDLE_TOPIC_TITLE, postNotification.getTopicTitle());
intent.putExtras(extras); intent.putExtras(extras);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int pendingIntentFlags;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S)
pendingIntentFlags = PendingIntent.FLAG_IMMUTABLE |PendingIntent.FLAG_ONE_SHOT;
else
pendingIntentFlags = PendingIntent.FLAG_ONE_SHOT;
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode++, intent, PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode++, intent,
PendingIntent.FLAG_ONE_SHOT); pendingIntentFlags);
int notificationId; int notificationId;
String contentText; String contentText;

6
app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java

@ -105,7 +105,7 @@ public class UploadsReceiver extends UploadServiceBroadcastReceiver {
String response = serverResponse.getBodyAsString(); String response = serverResponse.getBodyAsString();
if (response.contains("Η προσθήκη του αρχείου ήταν επιτυχημένη.") || response.contains("The upload was successful.")) { if (response.contains("Η προσθήκη του αρχείου ήταν επιτυχημένη.") || response.contains("The upload was successful.")) {
Timber.i("Upload completed successfully (id: %s)", uploadInfo.getUploadId()); Timber.i("Upload completed successfully (id: %s)", uploadInfo.getUploadId());
Toast.makeText(context.getApplicationContext(), "Upload completed successfully", Toast.LENGTH_SHORT).show(); Toast.makeText(context.getApplicationContext(), "Upload completed successfully!", Toast.LENGTH_SHORT).show();
BaseApplication.getInstance().logFirebaseAnalyticsEvent("file_upload", null); BaseApplication.getInstance().logFirebaseAnalyticsEvent("file_upload", null);
} }
else { else {
@ -118,7 +118,7 @@ public class UploadsReceiver extends UploadServiceBroadcastReceiver {
storage = new Storage(context.getApplicationContext()); storage = new Storage(context.getApplicationContext());
} }
UploadsHelper.deleteTempFiles(storage); UploadsHelper.deleteTempFiles(context, storage);
} }
@Override @Override
@ -130,7 +130,7 @@ public class UploadsReceiver extends UploadServiceBroadcastReceiver {
storage = new Storage(context.getApplicationContext()); storage = new Storage(context.getApplicationContext());
//cancelNotification(context, uploadInfo.getNotificationID()); //cancelNotification(context, uploadInfo.getNotificationID());
UploadsHelper.deleteTempFiles(storage); UploadsHelper.deleteTempFiles(context, storage);
} }
public static void setDialogDisplay(AlertDialog uploadProgressDialog, String dialogUploadID, public static void setDialogDisplay(AlertDialog uploadProgressDialog, String dialogUploadID,

6
app/src/main/res/layout/activity_upload_file_list_row.xml

@ -3,7 +3,9 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingEnd="0dp">
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/upload_file_item_text" android:id="@+id/upload_file_item_text"
@ -11,6 +13,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_weight="1" android:layout_weight="1"
android:paddingTop="0dp"
android:paddingBottom="1dp"
android:ellipsize="marquee" android:ellipsize="marquee"
android:singleLine="true" android:singleLine="true"
android:textColor="@color/primary_text" /> android:textColor="@color/primary_text" />

8
app/src/main/res/layout/fragment_bookmarks.xml

@ -9,7 +9,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="top|start" android:layout_gravity="top|start"
android:background="@color/primary_lighter" android:background="@color/primary_lighter_2"
android:scrollbars="none" android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
@ -17,10 +17,8 @@
android:id="@+id/bookmarks_container" android:id="@+id/bookmarks_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:layout_margin="2dp"
android:showDividers="middle" android:orientation="vertical" />
android:divider="?android:listDivider"
android:dividerPadding="16dp" />
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<TextView <TextView

23
app/src/main/res/layout/fragment_bookmarks_row.xml

@ -1,12 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bookmark_row" android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/bookmark_card"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground" android:foreground="?android:attr/selectableItemBackground"
card_view:cardBackgroundColor="@color/background"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="2dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@ -41,9 +53,10 @@
android:paddingBottom="3dp" android:paddingBottom="3dp"
android:paddingTop="3dp" android:paddingTop="3dp"
android:paddingStart="6dp" android:paddingStart="6dp"
android:paddingEnd="6dp" android:paddingEnd="12dp"
android:layout_marginEnd="12dp"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:contentDescription="@string/remove_bookmark" android:contentDescription="@string/remove_bookmark"
app:srcCompat="@drawable/ic_delete_accent_24dp" /> app:srcCompat="@drawable/ic_delete_accent_24dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>

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

@ -95,9 +95,10 @@
<string name="epl_libraries"><u>Eclipse Public License v1.0 libraries</u></string> <string name="epl_libraries"><u>Eclipse Public License v1.0 libraries</u></string>
<string name="other_libraries"><u>Other libraries</u></string> <string name="other_libraries"><u>Other libraries</u></string>
<string name="contact">Contact</string> <string name="contact">Contact</string>
<string name="contact_text">Do not hesitate to contact us for any matter either by email at thmmynolife@gmail.com, or by joining our discord server at https://discord.gg/CVt3yrn.</string> <string name="contact_text">Do not hesitate to contact us for any technical matter, either by email at thmmynolife@gmail.com, or by joining our Discord server using https://discord.gg/CVt3yrn&#8203;.
For account-related issues, please contact the administration team of thmmy.gr by email at contact@thmmy.gr.</string>
<string name="open_source">Open Source</string> <string name="open_source">Open Source</string>
<string name="open_source_text">The source code of mTHMMY can be found on Github (https://github.com/ThmmyNoLife/mTHMMY) along with further details of how one can contribute.</string> <string name="open_source_text">The source code of mTHMMY can be found on Github at https://github.com/ThmmyNoLife/mTHMMY, along with further details of how one can contribute.</string>
<string name="trollPic">You should see a funny pic!</string> <string name="trollPic">You should see a funny pic!</string>
<string name="privacy_policy">Privacy policy</string> <string name="privacy_policy">Privacy policy</string>

Loading…
Cancel
Save