diff options
12 files changed, 177 insertions, 38 deletions
diff --git a/app/build.gradle b/app/build.gradle index a5656d80..72d855a0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -95,6 +95,7 @@ dependencies { implementation 'me.zhanghai.android.fastscroll:library:1.1.2' implementation "com.thefuntasty.hauler:core:3.1.0" implementation 'com.github.Piasy:BigImageViewer:1.6.5' + implementation 'androidx.biometric:biometric:1.1.0-alpha02' def toroVersion = '3.7.0.2010003' implementation "im.ene.toro3:toro:$toroVersion" diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java index dea3aaf2..3efc949f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java @@ -75,6 +75,7 @@ import ml.docilealligator.infinityforreddit.Event.ChangeConfirmToExitEvent; import ml.docilealligator.infinityforreddit.Event.ChangeDisableSwipingBetweenTabsEvent; import ml.docilealligator.infinityforreddit.Event.ChangeLockBottomAppBarEvent; import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.Event.ChangeRequireAuthToAccountSectionEvent; import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.FetchMyInfo; @@ -468,9 +469,9 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb fab.setVisibility(View.VISIBLE); } - boolean nsfwEnabled = mSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_KEY, false); - adapter = new NavigationDrawerRecyclerViewAdapter(this, mCustomThemeWrapper, mAccountName, - mProfileImageUrl, mBannerImageUrl, mKarma, nsfwEnabled, + adapter = new NavigationDrawerRecyclerViewAdapter(this, mSharedPreferences, + mCustomThemeWrapper, mAccountName, + mProfileImageUrl, mBannerImageUrl, mKarma, new NavigationDrawerRecyclerViewAdapter.ItemClickListener() { @Override public void onMenuClick(int stringId) { @@ -972,6 +973,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); } + @Subscribe + public void onChangeRequireAuthToAccountSectionEvent(ChangeRequireAuthToAccountSectionEvent changeRequireAuthToAccountSectionEvent) { + adapter.setRequireAuthToAccountSection(changeRequireAuthToAccountSectionEvent.requireAuthToAccountSection); + } + @Override public void onLongPress() { if (sectionsPagerAdapter != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java index 4e2f5b7f..7f6938a4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java @@ -1,6 +1,6 @@ package ml.docilealligator.infinityforreddit.Adapter; -import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.Resources; import android.view.LayoutInflater; @@ -10,6 +10,10 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricManager; +import androidx.biometric.BiometricPrompt; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; @@ -18,6 +22,7 @@ import com.bumptech.glide.request.RequestOptions; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; import butterknife.BindView; import butterknife.ButterKnife; @@ -26,8 +31,12 @@ import ml.docilealligator.infinityforreddit.Account.Account; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; import pl.droidsonroids.gif.GifImageView; +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; + public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public interface ItemClickListener { @@ -44,7 +53,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re private static final int VIEW_TYPE_ACCOUNT = 5; private static final int CURRENT_MENU_ITEMS = 17; - private Context context; + private AppCompatActivity appCompatActivity; private Resources resources; private RequestManager glide; private String accountName; @@ -52,6 +61,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re private String userBannerUrl; private int karma; private boolean isNSFWEnabled; + private boolean requireAuthToAccountSection; private ItemClickListener itemClickListener; private boolean isLoggedIn; private boolean isInMainPage = true; @@ -62,18 +72,20 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re private int dividerColor; private int primaryIconColor; - public NavigationDrawerRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper, + public NavigationDrawerRecyclerViewAdapter(AppCompatActivity appCompatActivity, SharedPreferences sharedPreferences, + CustomThemeWrapper customThemeWrapper, String accountName, String userIconUrl, - String userBannerUrl, int karma, boolean isNSFWEnabled, + String userBannerUrl, int karma, ItemClickListener itemClickListener) { - this.context = context; - resources = context.getResources(); - glide = Glide.with(context); + this.appCompatActivity = appCompatActivity; + resources = appCompatActivity.getResources(); + glide = Glide.with(appCompatActivity); this.accountName = accountName; this.userIconUrl = userIconUrl; this.userBannerUrl = userBannerUrl; this.karma = karma; - this.isNSFWEnabled = isNSFWEnabled; + isNSFWEnabled = sharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_KEY, false); + requireAuthToAccountSection = sharedPreferences.getBoolean(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER, false); isLoggedIn = accountName != null; this.itemClickListener = itemClickListener; primaryTextColor = customThemeWrapper.getPrimaryTextColor(); @@ -149,7 +161,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof NavHeaderViewHolder) { if (isLoggedIn) { - ((NavHeaderViewHolder) holder).karmaTextView.setText(context.getString(R.string.karma_info, karma)); + ((NavHeaderViewHolder) holder).karmaTextView.setText(appCompatActivity.getString(R.string.karma_info, karma)); ((NavHeaderViewHolder) holder).accountNameTextView.setText(accountName); if (userIconUrl != null && !userIconUrl.equals("")) { glide.load(userIconUrl) @@ -182,18 +194,43 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re ((NavHeaderViewHolder) holder).itemView.setOnClickListener(view -> { if (isInMainPage) { - ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_up_24px)); - notifyItemRangeRemoved(1, getItemCount() - 1); - if (accounts != null) { - notifyItemRangeInserted(1, accounts.size() + 3); - } else { - if (isLoggedIn) { - notifyItemRangeInserted(1, 3); + if (requireAuthToAccountSection) { + BiometricManager biometricManager = BiometricManager.from(appCompatActivity); + if (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) { + Executor executor = ContextCompat.getMainExecutor(appCompatActivity); + BiometricPrompt biometricPrompt = new BiometricPrompt(appCompatActivity, + executor, new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationError(int errorCode, + @NonNull CharSequence errString) { + super.onAuthenticationError(errorCode, errString); + } + + @Override + public void onAuthenticationSucceeded( + @NonNull BiometricPrompt.AuthenticationResult result) { + super.onAuthenticationSucceeded(result); + openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); + } + + @Override + public void onAuthenticationFailed() { + super.onAuthenticationFailed(); + } + }); + + BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() + .setTitle(appCompatActivity.getString(R.string.unlock_account_section)) + .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) + .build(); + + biometricPrompt.authenticate(promptInfo); } else { - notifyItemInserted(1); + openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); } + } else { + openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); } - isInMainPage = false; } else { ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_down_24px)); notifyItemRangeRemoved(1, getItemCount() - 1); @@ -284,12 +321,12 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (isNSFWEnabled) { isNSFWEnabled = false; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(context.getDrawable(R.drawable.ic_nsfw_on_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); itemClickListener.onMenuClick(R.string.disable_nsfw); } else { isNSFWEnabled = true; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(context.getDrawable(R.drawable.ic_nsfw_off_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); itemClickListener.onMenuClick(R.string.enable_nsfw); } }); @@ -323,12 +360,12 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (isNSFWEnabled) { isNSFWEnabled = false; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(context.getDrawable(R.drawable.ic_nsfw_on_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); itemClickListener.onMenuClick(R.string.disable_nsfw); } else { isNSFWEnabled = true; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(context.getDrawable(R.drawable.ic_nsfw_off_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); itemClickListener.onMenuClick(R.string.enable_nsfw); } }); @@ -359,7 +396,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (stringId != 0) { ((MenuItemViewHolder) holder).menuTextView.setText(stringId); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(context.getDrawable(drawableId)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(drawableId)); if (setOnClickListener) { int finalStringId = stringId; ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> itemClickListener.onMenuClick(finalStringId)); @@ -396,6 +433,21 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } } + private void openAccountSection(ImageView dropIconImageView) { + dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_up_24px)); + notifyItemRangeRemoved(1, getItemCount() - 1); + if (accounts != null) { + notifyItemRangeInserted(1, accounts.size() + 3); + } else { + if (isLoggedIn) { + notifyItemRangeInserted(1, 3); + } else { + notifyItemInserted(1); + } + } + isInMainPage = false; + } + @Override public int getItemCount() { if (isInMainPage) { @@ -457,6 +509,10 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } } + public void setRequireAuthToAccountSection(boolean requireAuthToAccountSection) { + this.requireAuthToAccountSection = requireAuthToAccountSection; + } + class NavHeaderViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.name_text_view_nav_header_main) TextView accountNameTextView; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java new file mode 100644 index 00000000..d8455db5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.Event; + +public class ChangeRequireAuthToAccountSectionEvent { + public boolean requireAuthToAccountSection; + + public ChangeRequireAuthToAccountSectionEvent(boolean requireAuthToAccountSection) { + this.requireAuthToAccountSection = requireAuthToAccountSection; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java new file mode 100644 index 00000000..882fe17d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java @@ -0,0 +1,29 @@ +package ml.docilealligator.infinityforreddit.Settings; + +import android.os.Bundle; + +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.Event.ChangeRequireAuthToAccountSectionEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; + +public class SecurityPreferenceFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.security_preferences, rootKey); + + SwitchPreference requireAuthToAccountSectionSwitch = findPreference(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER); + + if (requireAuthToAccountSectionSwitch != null) { + requireAuthToAccountSectionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeRequireAuthToAccountSectionEvent((Boolean) newValue)); + return true; + }); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java index acf7566d..8381319b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java @@ -123,6 +123,7 @@ public class SharedPreferencesUtils { public static final String DISABLE_SWIPING_BETWEEN_TABS = "disable_swiping_between_tabs"; public static final String ENABLE_SWIPE_ACTION = "enable_swipe_action"; public static final String PULL_TO_REFRESH = "pull_to_refresh"; + public static final String REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER = "require_auth_to_account_section"; public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.main_page_tabs"; public static final String MAIN_PAGE_TAB_1_TITLE = "_main_page_tab_1_title"; diff --git a/app/src/main/res/drawable-night/ic_security_24dp.xml b/app/src/main/res/drawable-night/ic_security_24dp.xml new file mode 100644 index 00000000..3e21f473 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_security_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z" + android:fillColor="#FFFFFF"/> +</vector> diff --git a/app/src/main/res/drawable/ic_security_24dp.xml b/app/src/main/res/drawable/ic_security_24dp.xml new file mode 100644 index 00000000..be9737bd --- /dev/null +++ b/app/src/main/res/drawable/ic_security_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z" + android:fillColor="#000000"/> +</vector> diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 94df20c9..695ddfeb 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -233,14 +233,4 @@ <item>1</item> <item>2</item> </string-array> - <!-- Reply Preference --> - <string-array name="reply_entries"> - <item>Reply</item> - <item>Reply to all</item> - </string-array> - - <string-array name="reply_values"> - <item>reply</item> - <item>reply_all</item> - </string-array> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e70c54d..39a228ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -483,6 +483,8 @@ <string name="settings_disable_swiping_between_tabs_title">Disable Swiping Between Tabs</string> <string name="settings_enable_swipe_action_title">Enable Swipe Action</string> <string name="settings_pull_to_refresh_title">Pull to Refresh</string> + <string name="settings_security_title">Security</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer">Require Authentication to Go to Account Section in Navigation Drawer</string> <string name="no_link_available">Cannot get the link</string> @@ -882,7 +884,21 @@ <string name="block_user_failed">Failed to block user</string> <string name="view_full_comment_markdown">View Full Markdown</string> - <!-- TODO: Remove or change this placeholder text --> - <string name="hello_blank_fragment">Hello blank fragment</string> + + <string name="unlock_account_section">Unlock Account Section</string> + <!-- Preference Titles --> + <string name="messages_header">Messages</string> + <string name="sync_header">Sync</string> + + <!-- Messages Preferences --> + <string name="signature_title">Your signature</string> + <string name="reply_title">Default reply action</string> + + <!-- Sync Preferences --> + <string name="sync_title">Sync email periodically</string> + <string name="attachment_title">Download incoming attachments</string> + <string name="attachment_summary_on">Automatically download attachments for incoming emails + </string> + <string name="attachment_summary_off">Only download attachments when manually requested</string> </resources> diff --git a/app/src/main/res/xml/main_preferences.xml b/app/src/main/res/xml/main_preferences.xml index ce6ff184..48bf5697 100644 --- a/app/src/main/res/xml/main_preferences.xml +++ b/app/src/main/res/xml/main_preferences.xml @@ -41,6 +41,11 @@ android:icon="@drawable/ic_download_24dp" app:fragment="ml.docilealligator.infinityforreddit.Settings.DownloadLocationPreferenceFragment" /> + <Preference + app:title="@string/settings_security_title" + android:icon="@drawable/ic_security_24dp" + app:fragment="ml.docilealligator.infinityforreddit.Settings.SecurityPreferenceFragment" /> + <SwitchPreference app:defaultValue="false" app:key="save_front_page_scrolled_position" diff --git a/app/src/main/res/xml/security_preferences.xml b/app/src/main/res/xml/security_preferences.xml new file mode 100644 index 00000000..a7174faf --- /dev/null +++ b/app/src/main/res/xml/security_preferences.xml @@ -0,0 +1,8 @@ +<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> + + <SwitchPreference + app:defaultValue="false" + app:key="require_auth_to_account_section" + app:title="@string/settings_require_authentication_to_go_to_account_section_in_navigation_drawer" /> + +</PreferenceScreen>
\ No newline at end of file |