A mobile app for thmmy.gr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

844 lines
37 KiB

package gr.thmmy.mthmmy.base;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.firebase.messaging.FirebaseMessaging;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.lifecycle.ViewModelProviders;
import androidx.preference.PreferenceManager;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.AboutActivity;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.bookmarks.BookmarkActivity;
import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity;
import gr.thmmy.mthmmy.activities.main.MainActivity;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import gr.thmmy.mthmmy.activities.settings.SettingsActivity;
import gr.thmmy.mthmmy.activities.shoutbox.ShoutboxActivity;
import gr.thmmy.mthmmy.model.Bookmark;
import gr.thmmy.mthmmy.model.ThmmyFile;
import gr.thmmy.mthmmy.services.DownloadHelper;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.FileUtils;
import gr.thmmy.mthmmy.viewmodel.BaseViewModel;
import okhttp3.OkHttpClient;
import ru.noties.markwon.LinkResolverDef;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.SpannableConfiguration;
import timber.log.Timber;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_TITLE;
import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWNLOADS_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME;
import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DEFAULT_HOME_TAB;
import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR;
import static gr.thmmy.mthmmy.session.SessionManager.SUCCESS;
import static gr.thmmy.mthmmy.utils.FileUtils.getMimeType;
public abstract class BaseActivity extends AppCompatActivity {
// Client & Cookies
protected static OkHttpClient client;
//SessionManager
protected static SessionManager sessionManager;
//Bookmarks
public static final String BOOKMARKS_SHARED_PREFS = "bookmarksSharedPrefs";
public static final String BOOKMARKED_TOPICS_KEY = "bookmarkedTopicsKey";
private static final String BOOKMARKED_BOARDS_KEY = "bookmarkedBoardsKey";
protected Bookmark thisPageBookmark;
private MenuItem thisPageBookmarkMenuButton;
private SharedPreferences sharedPreferences;
private SharedPreferences bookmarksFile;
private ArrayList<Bookmark> topicsBookmarked;
private ArrayList<Bookmark> boardsBookmarked;
//Common UI elements
protected Toolbar toolbar;
protected Drawer drawer;
private MainActivity mainActivity;
private boolean isMainActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isMainActivity = this instanceof MainActivity;
if (client == null)
client = BaseApplication.getInstance().getClient(); //must check every time - e.g.
// they become null when app restarts after crash
if (sessionManager == null)
sessionManager = BaseApplication.getInstance().getSessionManager();
if (topicsBookmarked == null || boardsBookmarked == null) {
bookmarksFile = getSharedPreferences(BOOKMARKS_SHARED_PREFS, Context.MODE_PRIVATE);
loadSavedBookmarks();
}
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
BaseViewModel baseViewModel = ViewModelProviders.of(this).get(BaseViewModel.class);
baseViewModel.getCurrentPageBookmark().observe(this, thisPageBookmark -> setTopicBookmark(thisPageBookmarkMenuButton));
}
@Override
protected void onResume() {
super.onResume();
updateDrawer();
if(!sharedPreferences.getBoolean(getString(R.string.user_consent_shared_preference_key),false))
showUserConsentDialog();
}
@Override
protected void onPause() {
super.onPause();
if (drawer != null) //close drawer animation after returning to activity
drawer.closeDrawer();
}
public static OkHttpClient getClient() {
return client;
}
public static SessionManager getSessionManager() {
return sessionManager;
}
//TODO: move stuff below (?)
//------------------------------------------DRAWER STUFF----------------------------------------
protected static final int HOME_ID = 0;
protected static final int DOWNLOADS_ID = 1;
protected static final int UPLOAD_ID = 2;
protected static final int BOOKMARKS_ID = 3;
protected static final int LOG_ID = 4;
protected static final int ABOUT_ID = 5;
protected static final int SETTINGS_ID = 6;
protected static final int SHOUTBOX_ID = 7;
private AccountHeader accountHeader;
private ProfileDrawerItem profileDrawerItem;
private PrimaryDrawerItem downloadsItem, uploadItem, loginLogoutItem;
private IconicsDrawable loginIcon, logoutIcon;
/**
* Call only after initializing Toolbar
*/
protected void createDrawer() {
final int primaryColor = ContextCompat.getColor(this, R.color.iron);
final int selectedPrimaryColor = ContextCompat.getColor(this, R.color.primary_dark);
final int selectedSecondaryColor = ContextCompat.getColor(this, R.color.accent);
PrimaryDrawerItem homeItem, bookmarksItem, settingsItem, aboutItem, shoutboxItem;
IconicsDrawable homeIcon, homeIconSelected, downloadsIcon, downloadsIconSelected, uploadIcon, uploadIconSelected, settingsIcon,
settingsIconSelected, bookmarksIcon, bookmarksIconSelected, aboutIcon, aboutIconSelected;
//Drawer Icons
homeIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_home)
.color(primaryColor);
homeIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_home)
.color(selectedSecondaryColor);
bookmarksIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_bookmark)
.color(primaryColor);
bookmarksIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_bookmark)
.color(selectedSecondaryColor);
downloadsIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_file_download)
.color(primaryColor);
downloadsIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_file_download)
.color(selectedSecondaryColor);
uploadIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_file_upload)
.color(primaryColor);
uploadIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_file_upload)
.color(selectedSecondaryColor);
settingsIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_settings)
.color(primaryColor);
settingsIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_settings)
.color(selectedSecondaryColor);
loginIcon = new IconicsDrawable(this)
.icon(FontAwesome.Icon.faw_sign_in)
.color(primaryColor);
logoutIcon = new IconicsDrawable(this)
.icon(FontAwesome.Icon.faw_sign_out)
.color(primaryColor);
aboutIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_info)
.color(primaryColor);
aboutIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_info)
.color(selectedSecondaryColor);
//Drawer Items
homeItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(HOME_ID)
.withName(R.string.home)
.withIcon(homeIcon)
.withSelectedIcon(homeIconSelected);
downloadsItem = new PrimaryDrawerItem() // Don't put it in the if below
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(DOWNLOADS_ID)
.withName(R.string.downloads)
.withIcon(downloadsIcon)
.withSelectedIcon(downloadsIconSelected);
// uploadItem = new PrimaryDrawerItem()
// .withTextColor(primaryColor)
// .withSelectedColor(selectedPrimaryColor)
// .withSelectedTextColor(selectedSecondaryColor)
// .withIdentifier(UPLOAD_ID)
// .withName(R.string.upload)
// .withIcon(uploadIcon)
// .withSelectedIcon(uploadIconSelected);
shoutboxItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(SHOUTBOX_ID)
.withName(R.string.shoutbox)
.withIcon(R.drawable.ic_announcement)
.withIconColor(primaryColor)
.withSelectedIconColor(selectedSecondaryColor)
.withIconTintingEnabled(true);
if (sessionManager.isLoggedIn()) //When logged in
{
loginLogoutItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedSecondaryColor)
.withIdentifier(LOG_ID)
.withName(R.string.logout)
.withIcon(logoutIcon)
.withSelectable(false);
} else
loginLogoutItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedSecondaryColor)
.withIdentifier(LOG_ID).withName(R.string.login)
.withIcon(loginIcon)
.withSelectable(false);
settingsItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(SETTINGS_ID)
.withName(R.string.settings)
.withIcon(settingsIcon)
.withSelectedIcon(settingsIconSelected);
bookmarksItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(BOOKMARKS_ID)
.withName(R.string.bookmark)
.withIcon(bookmarksIcon)
.withSelectedIcon(bookmarksIconSelected);
aboutItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(ABOUT_ID)
.withName(R.string.about)
.withIcon(aboutIcon)
.withSelectedIcon(aboutIconSelected);
//Profile
profileDrawerItem = new ProfileDrawerItem().withName(sessionManager.getUsername()).withIdentifier(0);
//AccountHeader
accountHeader = new AccountHeaderBuilder()
.withActivity(this)
.withCompactStyle(true)
.withSelectionListEnabledForSingleProfile(false)
.withHeaderBackground(R.color.primary)
.withTextColor(getResources().getColor(R.color.iron))
.addProfiles(profileDrawerItem)
.withOnAccountHeaderListener((view, profile, currentProfile) -> {
if (sessionManager.isLoggedIn()) {
Intent intent = new Intent(BaseActivity.this, ProfileActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_PROFILE_URL, "https://www.thmmy.gr/smf/index.php?action=profile");
if (!sessionManager.hasAvatar())
extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, "");
else
extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, sessionManager.getAvatarLink());
extras.putString(BUNDLE_PROFILE_USERNAME, sessionManager.getUsername());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return false;
} else
startLoginActivity();
return true;
})
.build();
//Drawer
DrawerBuilder drawerBuilder = new DrawerBuilder()
.withActivity(this)
.withToolbar(toolbar)
.withDrawerWidthDp((int) BaseApplication.getInstance().getDpWidth() / 2)
.withSliderBackgroundColor(ContextCompat.getColor(this, R.color.primary_light))
.withAccountHeader(accountHeader)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
if (drawerItem.equals(HOME_ID)) {
if (!isMainActivity) {
Intent intent = new Intent(BaseActivity.this, MainActivity.class);
startActivity(intent);
}
} else if (drawerItem.equals(SHOUTBOX_ID)) {
if (!(BaseActivity.this instanceof ShoutboxActivity)) {
Intent intent = new Intent(BaseActivity.this, ShoutboxActivity.class);
startActivity(intent);
}
} else if (drawerItem.equals(DOWNLOADS_ID)) {
if (!(BaseActivity.this instanceof DownloadsActivity)) {
Intent intent = new Intent(BaseActivity.this, DownloadsActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_DOWNLOADS_URL, "");
extras.putString(BUNDLE_DOWNLOADS_TITLE, null);
intent.putExtras(extras);
startActivity(intent);
}
// } else if (drawerItem.equals(UPLOAD_ID)) {
// if (!(BaseActivity.this instanceof UploadActivity)) {
// Intent intent = new Intent(BaseActivity.this, UploadActivity.class);
// startActivity(intent);
// }
} else if (drawerItem.equals(BOOKMARKS_ID)) {
if (!(BaseActivity.this instanceof BookmarkActivity)) {
Intent intent = new Intent(BaseActivity.this, BookmarkActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
} else if (drawerItem.equals(LOG_ID)) {
if (!sessionManager.isLoggedIn()) //When logged out or if user is guest
startLoginActivity();
else
new LogoutTask().execute();
} else if (drawerItem.equals(ABOUT_ID)) {
if (!(BaseActivity.this instanceof AboutActivity)) {
Intent intent = new Intent(BaseActivity.this, AboutActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
} else if (drawerItem.equals(SETTINGS_ID)) {
if (!(BaseActivity.this instanceof SettingsActivity)) {
Intent intent = new Intent(BaseActivity.this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
}
drawer.closeDrawer();
return true;
});
if (sessionManager.isLoggedIn())
drawerBuilder.addDrawerItems(homeItem, bookmarksItem, shoutboxItem, downloadsItem, settingsItem, loginLogoutItem, aboutItem);
else
drawerBuilder.addDrawerItems(homeItem, bookmarksItem, shoutboxItem, settingsItem, loginLogoutItem, aboutItem);
drawer = drawerBuilder.build();
if (!isMainActivity)
drawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false);
drawer.setOnDrawerNavigationListener(clickedView -> {
onBackPressed();
return true;
});
}
private void updateDrawer() {
if (drawer != null) {
if (!sessionManager.isLoggedIn()) //When logged out or if user is guest
{
drawer.removeItem(DOWNLOADS_ID);
// drawer.removeItem(UPLOAD_ID);
loginLogoutItem.withName(R.string.login).withIcon(loginIcon); //Swap logout with login
profileDrawerItem.withName(sessionManager.getUsername());
setDefaultAvatar();
} else {
if (!drawer.getDrawerItems().contains(downloadsItem)) {
drawer.addItemAtPosition(downloadsItem, 4);
}
// if (!drawer.getDrawerItems().contains(uploadItem)) {
// drawer.addItemAtPosition(uploadItem, 5);
// }
loginLogoutItem.withName(R.string.logout).withIcon(logoutIcon); //Swap login with logout
profileDrawerItem.withName(sessionManager.getUsername());
if (sessionManager.hasAvatar())
profileDrawerItem.withIcon(sessionManager.getAvatarLink());
else
setDefaultAvatar();
}
accountHeader.updateProfile(profileDrawerItem);
drawer.updateItem(loginLogoutItem);
}
}
private void setDefaultAvatar() {
profileDrawerItem.withIcon(new IconicsDrawable(this)
.icon(FontAwesome.Icon.faw_user)
.paddingDp(10)
.color(ContextCompat.getColor(this, R.color.iron))
.backgroundColor(ContextCompat.getColor(this, R.color.primary_light)));
}
//-------------------------------------------LOGOUT-------------------------------------------------
/**
* Result toast will always display a success, because when user chooses logout all data are
* cleared regardless of the actual outcome
*/
private class LogoutTask extends AsyncTask<Void, Void, Integer> { //Attempt logout
ProgressDialog progressDialog;
protected Integer doInBackground(Void... voids) {
return sessionManager.logout();
}
protected void onPreExecute() { //Show a progress dialog until done
progressDialog = new ProgressDialog(BaseActivity.this,
R.style.AppTheme_Dark_Dialog);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Logging out...");
progressDialog.show();
}
protected void onPostExecute(Integer result) {
if (result == SUCCESS) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if (sharedPrefs.getString(DEFAULT_HOME_TAB, "0").equals("2")) {
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(DEFAULT_HOME_TAB, "0").apply();
}
}
updateDrawer();
if (mainActivity != null)
mainActivity.updateTabs();
progressDialog.dismiss();
//if (BaseActivity.this instanceof TopicActivity){
Intent intent = new Intent(BaseActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
//}
}
}
//-----------------------------------------LOGOUT END-----------------------------------------------
//---------------------------------------------BOOKMARKS--------------------------------------------
protected ArrayList<Bookmark> getBoardsBookmarked() {
return boardsBookmarked;
}
protected ArrayList<Bookmark> getTopicsBookmarked() {
return topicsBookmarked;
}
protected void setTopicBookmark(MenuItem thisPageBookmarkMenuButton) {
this.thisPageBookmarkMenuButton = thisPageBookmarkMenuButton;
if (thisPageBookmark.matchExists(topicsBookmarked)) {
thisPageBookmarkMenuButton.setIcon(R.drawable.ic_bookmark_true_accent_24dp);
} else {
thisPageBookmarkMenuButton.setIcon(R.drawable.ic_bookmark_false_accent_24dp);
}
}
protected void refreshTopicBookmark() {
if (thisPageBookmarkMenuButton == null) {
return;
}
loadSavedBookmarks();
if (thisPageBookmark.matchExists(topicsBookmarked)) {
thisPageBookmarkMenuButton.setIcon(R.drawable.ic_bookmark_true_accent_24dp);
} else {
thisPageBookmarkMenuButton.setIcon(R.drawable.ic_bookmark_false_accent_24dp);
}
}
protected void topicMenuBookmarkClick() {
if (thisPageBookmark.matchExists(topicsBookmarked)) {
thisPageBookmarkMenuButton.setIcon(R.drawable.ic_bookmark_false_accent_24dp);
toggleTopicToBookmarks(thisPageBookmark);
Toast.makeText(getBaseContext(), "Bookmark removed", Toast.LENGTH_SHORT).show();
} else {
thisPageBookmarkMenuButton.setIcon(R.drawable.ic_bookmark_true_accent_24dp);
toggleTopicToBookmarks(thisPageBookmark);
Toast.makeText(getBaseContext(), "Bookmark added", Toast.LENGTH_SHORT).show();
}
}
protected void setBoardBookmark(final ImageButton thisPageBookmarkImageButton) {
if (thisPageBookmark.matchExists(boardsBookmarked)) {
thisPageBookmarkImageButton.setImageResource(R.drawable.ic_bookmark_true_accent_24dp);
} else {
thisPageBookmarkImageButton.setImageResource(R.drawable.ic_bookmark_false_accent_24dp);
}
thisPageBookmarkImageButton.setOnClickListener(view -> {
if (thisPageBookmark.matchExists(boardsBookmarked)) {
thisPageBookmarkImageButton.setImageResource(R.drawable.ic_bookmark_false_accent_24dp);
Toast.makeText(getBaseContext(), "Bookmark removed", Toast.LENGTH_SHORT).show();
} else {
thisPageBookmarkImageButton.setImageResource(R.drawable.ic_bookmark_true_accent_24dp);
Toast.makeText(getBaseContext(), "Bookmark added", Toast.LENGTH_SHORT).show();
}
toggleBoardToBookmarks(thisPageBookmark);
});
}
protected void refreshBoardBookmark(final ImageButton thisPageBookmarkImageButton) {
if (thisPageBookmarkImageButton == null)
return;
loadSavedBookmarks();
if (thisPageBookmark.matchExists(boardsBookmarked)) {
thisPageBookmarkImageButton.setImageResource(R.drawable.ic_bookmark_true_accent_24dp);
} else {
thisPageBookmarkImageButton.setImageResource(R.drawable.ic_bookmark_false_accent_24dp);
}
}
private void loadSavedBookmarks() {
String tmpString = bookmarksFile.getString(BOOKMARKED_TOPICS_KEY, null);
if (tmpString != null)
topicsBookmarked = Bookmark.arrayFromString(tmpString);
else
topicsBookmarked = new ArrayList<>();
tmpString = bookmarksFile.getString(BOOKMARKED_BOARDS_KEY, null);
if (tmpString != null)
boardsBookmarked = Bookmark.arrayFromString(tmpString);
else {
boardsBookmarked = new ArrayList<>();
}
}
private void toggleBoardToBookmarks(Bookmark bookmark) {
if (boardsBookmarked == null) return;
if (bookmark.matchExists(boardsBookmarked)) {
boardsBookmarked.remove(bookmark.findIndex(boardsBookmarked));
FirebaseMessaging.getInstance().unsubscribeFromTopic("b" + bookmark.getId());
} else {
boardsBookmarked.add(new Bookmark(bookmark.getTitle(), bookmark.getId(), true));
FirebaseMessaging.getInstance().subscribeToTopic("b" + bookmark.getId());
}
updateBoardBookmarks();
}
private void toggleTopicToBookmarks(Bookmark bookmark) {
if (topicsBookmarked == null) return;
if (bookmark.matchExists(topicsBookmarked)) {
topicsBookmarked.remove(bookmark.findIndex(topicsBookmarked));
FirebaseMessaging.getInstance().unsubscribeFromTopic(bookmark.getId());
} else {
topicsBookmarked.add(new Bookmark(bookmark.getTitle(), bookmark.getId(), true));
FirebaseMessaging.getInstance().subscribeToTopic(bookmark.getId());
}
updateTopicBookmarks();
}
private void updateBoardBookmarks() {
String tmpString;
tmpString = Bookmark.arrayToString(boardsBookmarked);
SharedPreferences.Editor editor = bookmarksFile.edit();
editor.putString(BOOKMARKED_BOARDS_KEY, tmpString).apply();
}
private void updateTopicBookmarks() {
String tmpString;
tmpString = Bookmark.arrayToString(topicsBookmarked);
SharedPreferences.Editor editor = bookmarksFile.edit();
editor.putString(BOOKMARKED_TOPICS_KEY, tmpString).apply();
}
protected void removeBookmark(Bookmark bookmark) {
if (bookmark.matchExists(boardsBookmarked)) toggleBoardToBookmarks(bookmark);
else if (bookmark.matchExists(topicsBookmarked)) toggleTopicToBookmarks(bookmark);
}
protected boolean toggleNotification(Bookmark bookmark) {
if (bookmark.matchExists(topicsBookmarked)) {
topicsBookmarked.get(bookmark.findIndex(topicsBookmarked)).toggleNotificationsEnabled();
updateTopicBookmarks();
if (topicsBookmarked.get(bookmark.findIndex(topicsBookmarked)).isNotificationsEnabled())
FirebaseMessaging.getInstance().subscribeToTopic(bookmark.getId());
else
FirebaseMessaging.getInstance().unsubscribeFromTopic(bookmark.getId());
return topicsBookmarked.get(bookmark.findIndex(topicsBookmarked)).isNotificationsEnabled();
} else if (bookmark.matchExists(boardsBookmarked)) {
boardsBookmarked.get(bookmark.findIndex(boardsBookmarked)).toggleNotificationsEnabled();
updateBoardBookmarks();
if (boardsBookmarked.get(bookmark.findIndex(boardsBookmarked)).isNotificationsEnabled())
FirebaseMessaging.getInstance().subscribeToTopic("b" + bookmark.getId());
else
FirebaseMessaging.getInstance().unsubscribeFromTopic("b" + bookmark.getId());
return boardsBookmarked.get(bookmark.findIndex(boardsBookmarked)).isNotificationsEnabled();
} else
Timber.w("No bookmark match exists!");
return false;
}
//-------------------------------------------BOOKMARKS END------------------------------------------
//-------PERMS---------
private static final int PERMISSIONS_REQUEST_CODE = 69;
//True if permissions are OK
private boolean checkPerms() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
return !(checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED);
}
return true;
}
//Display popup for user to grant permission
private void requestPerms() { //Runtime permissions request for devices with API >= 23
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions
, @NonNull int[] grantResults) {
switch (permsRequestCode) {
case PERMISSIONS_REQUEST_CODE:
downloadFile();
break;
}
}
//----------------------------------DOWNLOAD----------------------
private ThmmyFile tempThmmyFile;
public void downloadFile(ThmmyFile thmmyFile) {
if (checkPerms())
prepareDownload(thmmyFile);
else {
tempThmmyFile = thmmyFile;
requestPerms();
}
}
//Uses temp file - called after permission grant
private void downloadFile() {
if (checkPerms())
prepareDownload(tempThmmyFile);
}
private void prepareDownload(ThmmyFile thmmyFile) {
String fileName = thmmyFile.getFilename();
if (FileUtils.fileNameExists(fileName))
openDownloadPrompt(thmmyFile);
else
DownloadHelper.enqueueDownload(thmmyFile);
}
private void openDownloadPrompt(final ThmmyFile thmmyFile) {
View view = getLayoutInflater().inflate(R.layout.download_prompt_dialog, null);
final BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(view);
TextView downloadPromptTextView = view.findViewById(R.id.downloadPromptTextView);
downloadPromptTextView.setText(getString(R.string.downloadPromptText, thmmyFile.getFilename()));
Button cancelButton = view.findViewById(R.id.cancel);
Button openButton = view.findViewById(R.id.open);
Button downloadButton = view.findViewById(R.id.download);
cancelButton.setOnClickListener(v -> dialog.dismiss());
openButton.setOnClickListener(v -> {
dialog.dismiss();
try {
String fileName = thmmyFile.getFilename();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri fileUri = FileProvider.getUriForFile(getApplicationContext(), getPackageName() + ".provider", new File(SAVE_DIR, fileName));
intent.setDataAndType(fileUri, getMimeType(fileName));
BaseActivity.this.startActivity(intent);
} catch (Exception e) {
Timber.e(e, "Couldn't open downloaded file...");
Toast.makeText(getBaseContext(), "Couldn't open file...", Toast.LENGTH_SHORT).show();
}
});
downloadButton.setOnClickListener(v -> {
dialog.dismiss();
DownloadHelper.enqueueDownload(thmmyFile);
});
dialog.show();
}
//----------------------------PRIVACY POLICY------------------
private void showUserConsentDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
builder.setTitle("User Agreement");
builder.setMessage(R.string.user_agreement_dialog_text);
builder.setPositiveButton("Yes, I want to help", (dialogInterface, i) -> {
addUserConsent();
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
BaseApplication.getInstance().startFirebaseCrashlyticsCollection();
BaseApplication.getInstance().setFirebaseAnalyticsCollection(true);
setUserDataShareEnabled(true);
});
builder.setNegativeButton("Nope, leave me alone", (dialogInterface, i) -> {
addUserConsent();
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
setUserDataShareEnabled(false);
});
builder.setNeutralButton("Privacy Policy", (dialog, which) -> {/*Will be overridden below*/});
builder.setCancelable(false);
AlertDialog alertDialog = builder.create();
alertDialog.setOnShowListener(dialogInterface -> {
Button button = alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL);
button.setOnClickListener(view -> showPrivacyPolicyDialog());
}); // Overridden like this so it won't be dismissed when user touches this button
alertDialog.show();
}
protected void showPrivacyPolicyDialog() {
TextView privacyPolicyTextView = new TextView(this);
privacyPolicyTextView.setPadding(30,20,30,20);
privacyPolicyTextView.setTextColor(ContextCompat.getColor(this, R.color.primary_text));
SpannableConfiguration configuration = SpannableConfiguration.builder(this).linkResolver(new LinkResolverDef()).build();
StringBuilder stringBuilder = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(getAssets().open("PRIVACY.md")));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
}
Markwon.setMarkdown(privacyPolicyTextView, configuration, stringBuilder.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
builder.setView(privacyPolicyTextView);
builder.setPositiveButton("Close", (dialogInterface, i) -> dialogInterface.dismiss());
builder.show();
} catch (IOException e) {
Timber.e(e, "Error reading Privacy Policy from assets.");
} catch (Exception e) {
Timber.e(e, "Error in Privacy Policy dialog.");
} finally {
try {
if(reader!=null)
reader.close();
} catch (IOException e) {
Timber.e(e, "Error in Privacy Policy dialog (closing reader).");
}
}
}
private void addUserConsent(){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(getString(R.string.user_consent_shared_preference_key), true).apply();
}
private void setUserDataShareEnabled(boolean enabled){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(getString(R.string.pref_privacy_crashlytics_enable_key), enabled).apply();
editor.putBoolean(getString(R.string.pref_privacy_analytics_enable_key), enabled).apply();
}
//----------------------------------MISC----------------------
protected void setMainActivity(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
private void startLoginActivity(){
Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
}
}