diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 81582431..c9bd8ac9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -162,9 +162,6 @@ - diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java deleted file mode 100644 index 02f3a589..00000000 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.mian.gitnex.activities; - -import android.os.Bundle; -import android.view.View; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import org.mian.gitnex.R; -import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding; -import org.mian.gitnex.fragments.SettingsFragment; -import org.mian.gitnex.helpers.AppDatabaseSettings; -import org.mian.gitnex.helpers.AppUtil; -import org.mian.gitnex.helpers.SnackBar; -import org.mian.gitnex.notifications.Notifications; - -/** - * @author M M Arif - * @author opyale - */ -public class SettingsNotificationsActivity extends BaseActivity { - - private ActivitySettingsNotificationsBinding viewBinding; - private static String[] pollingDelayList; - private static int pollingDelayListSelectedChoice; - - @Override - public void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - viewBinding = ActivitySettingsNotificationsBinding.inflate(getLayoutInflater()); - setContentView(viewBinding.getRoot()); - - viewBinding.topAppBar.setNavigationOnClickListener(v -> finish()); - - viewBinding.enableNotificationsMode.setChecked( - Boolean.parseBoolean( - AppDatabaseSettings.getSettingsValue( - ctx, AppDatabaseSettings.APP_NOTIFICATIONS_KEY))); - - if (!viewBinding.enableNotificationsMode.isChecked()) { - AppUtil.setMultiVisibility(View.GONE, viewBinding.pollingDelayFrame); - } - - viewBinding.enableNotificationsMode.setOnCheckedChangeListener( - (buttonView, isChecked) -> { - AppDatabaseSettings.updateSettingsValue( - ctx, - String.valueOf(isChecked), - AppDatabaseSettings.APP_NOTIFICATIONS_KEY); - - if (isChecked) { - Notifications.startWorker(ctx); - AppUtil.setMultiVisibility(View.VISIBLE, viewBinding.pollingDelayFrame); - } else { - Notifications.stopWorker(ctx); - AppUtil.setMultiVisibility(View.GONE, viewBinding.pollingDelayFrame); - } - - SnackBar.success( - ctx, - findViewById(android.R.id.content), - getString(R.string.settingsSave)); - }); - viewBinding.enableNotificationsFrame.setOnClickListener( - v -> - viewBinding.enableNotificationsMode.setChecked( - !viewBinding.enableNotificationsMode.isChecked())); - - // polling delay - pollingDelayList = getResources().getStringArray(R.array.notificationsPollingDelay); - pollingDelayListSelectedChoice = - Integer.parseInt( - AppDatabaseSettings.getSettingsValue( - ctx, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY)); - viewBinding.pollingDelaySelected.setText(pollingDelayList[pollingDelayListSelectedChoice]); - - viewBinding.pollingDelayFrame.setOnClickListener( - view -> { - MaterialAlertDialogBuilder materialAlertDialogBuilder = - new MaterialAlertDialogBuilder(ctx) - .setTitle(R.string.pollingDelayDialogHeaderText) - .setSingleChoiceItems( - pollingDelayList, - pollingDelayListSelectedChoice, - (dialogInterfaceColor, i) -> { - pollingDelayListSelectedChoice = i; - viewBinding.pollingDelaySelected.setText( - pollingDelayList[ - pollingDelayListSelectedChoice]); - - AppDatabaseSettings.updateSettingsValue( - ctx, - String.valueOf(i), - AppDatabaseSettings - .APP_NOTIFICATIONS_DELAY_KEY); - - Notifications.stopWorker(ctx); - Notifications.startWorker(ctx); - - SettingsFragment.refreshParent = true; - this.recreate(); - this.overridePendingTransition(0, 0); - dialogInterfaceColor.dismiss(); - SnackBar.success( - ctx, - findViewById(android.R.id.content), - getString(R.string.settingsSave)); - }); - - materialAlertDialogBuilder.create().show(); - }); - } -} diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSettingsAboutFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSettingsAboutFragment.java new file mode 100644 index 00000000..79d6d49d --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSettingsAboutFragment.java @@ -0,0 +1,79 @@ +package org.mian.gitnex.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.mian.gitnex.R; +import org.mian.gitnex.activities.BaseActivity; +import org.mian.gitnex.databinding.BottomSheetSettingsAboutBinding; +import org.mian.gitnex.helpers.AppUtil; + +/** + * @author mmarif + */ +public class BottomSheetSettingsAboutFragment extends BottomSheetDialogFragment { + + private BottomSheetSettingsAboutBinding binding; + + @Nullable @Override + public View onCreateView( + @NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + binding = BottomSheetSettingsAboutBinding.inflate(inflater, container, false); + + // Set app version and build + binding.appVersionBuild.setText( + getString( + R.string.appVersionBuild, + AppUtil.getAppVersion(requireContext()), + AppUtil.getAppBuildNo(requireContext()))); + + // Set server version + binding.userServerVersion.setText( + ((BaseActivity) requireActivity()).getAccount().getServerVersion().toString()); + + // Set up link click listeners + binding.donationLinkPatreon.setOnClickListener( + v -> { + AppUtil.openUrlInBrowser( + requireContext(), getString(R.string.supportLinkPatreon)); + dismiss(); + }); + + binding.translateLink.setOnClickListener( + v -> { + AppUtil.openUrlInBrowser(requireContext(), getString(R.string.crowdInLink)); + dismiss(); + }); + + binding.appWebsite.setOnClickListener( + v -> { + AppUtil.openUrlInBrowser(requireContext(), getString(R.string.appWebsiteLink)); + dismiss(); + }); + + binding.feedback.setOnClickListener( + v -> { + AppUtil.openUrlInBrowser(requireContext(), getString(R.string.feedbackLink)); + dismiss(); + }); + + // Hide donation link for pro users + if (AppUtil.isPro(requireContext())) { + binding.layoutFrame1.setVisibility(View.GONE); + } + + return binding.getRoot(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; // Prevent memory leaks + } +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSettingsNotificationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSettingsNotificationsFragment.java new file mode 100644 index 00000000..43679a97 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSettingsNotificationsFragment.java @@ -0,0 +1,130 @@ +package org.mian.gitnex.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.mian.gitnex.R; +import org.mian.gitnex.databinding.BottomSheetSettingsNotificationsBinding; +import org.mian.gitnex.helpers.AppDatabaseSettings; +import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.SnackBar; +import org.mian.gitnex.notifications.Notifications; + +/** + * @author mmarif + */ +public class BottomSheetSettingsNotificationsFragment extends BottomSheetDialogFragment { + + private BottomSheetSettingsNotificationsBinding binding; + private static int pollingDelayListSelectedChoice; + + @Nullable @Override + public View onCreateView( + @NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + binding = BottomSheetSettingsNotificationsBinding.inflate(inflater, container, false); + + // Initialize polling delay + pollingDelayListSelectedChoice = + Integer.parseInt( + AppDatabaseSettings.getSettingsValue( + requireContext(), AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY)); + setChipSelection(pollingDelayListSelectedChoice); + + // Enable notifications switch + binding.enableNotificationsMode.setChecked( + Boolean.parseBoolean( + AppDatabaseSettings.getSettingsValue( + requireContext(), AppDatabaseSettings.APP_NOTIFICATIONS_KEY))); + + if (!binding.enableNotificationsMode.isChecked()) { + AppUtil.setMultiVisibility(View.GONE, binding.pollingDelayFrame); + } + + binding.enableNotificationsMode.setOnCheckedChangeListener( + (buttonView, isChecked) -> { + AppDatabaseSettings.updateSettingsValue( + requireContext(), + String.valueOf(isChecked), + AppDatabaseSettings.APP_NOTIFICATIONS_KEY); + + if (isChecked) { + Notifications.startWorker(requireContext()); + AppUtil.setMultiVisibility(View.VISIBLE, binding.pollingDelayFrame); + } else { + Notifications.stopWorker(requireContext()); + AppUtil.setMultiVisibility(View.GONE, binding.pollingDelayFrame); + } + + SnackBar.success( + requireContext(), + requireActivity().findViewById(android.R.id.content), + getString(R.string.settingsSave)); + }); + + binding.enableNotificationsFrame.setOnClickListener( + v -> + binding.enableNotificationsMode.setChecked( + !binding.enableNotificationsMode.isChecked())); + + // Polling delay selection + binding.pollingDelayChipGroup.setOnCheckedChangeListener( + (group, checkedId) -> { + int newSelection = getChipPosition(checkedId); + if (newSelection != pollingDelayListSelectedChoice) { + pollingDelayListSelectedChoice = newSelection; + AppDatabaseSettings.updateSettingsValue( + requireContext(), + String.valueOf(newSelection), + AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY); + + Notifications.stopWorker(requireContext()); + Notifications.startWorker(requireContext()); + + SettingsFragment.refreshParent = true; + SnackBar.success( + requireContext(), + requireActivity().findViewById(android.R.id.content), + getString(R.string.settingsSave)); + } + }); + + return binding.getRoot(); + } + + private void setChipSelection(int position) { + switch (position) { + case 0: + binding.chip15Minutes.setChecked(true); + break; + case 1: + binding.chip30Minutes.setChecked(true); + break; + case 2: + binding.chip45Minutes.setChecked(true); + break; + case 3: + binding.chip1Hour.setChecked(true); + break; + } + } + + private int getChipPosition(int checkedId) { + if (checkedId == R.id.chip15Minutes) return 0; + if (checkedId == R.id.chip30Minutes) return 1; + if (checkedId == R.id.chip45Minutes) return 2; + if (checkedId == R.id.chip1Hour) return 3; + return pollingDelayListSelectedChoice; // Fallback to current selection + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; // Prevent memory leaks + } +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java index 96782d75..e26772ba 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java @@ -11,18 +11,13 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.mian.gitnex.R; -import org.mian.gitnex.activities.BaseActivity; import org.mian.gitnex.activities.SettingsAppearanceActivity; import org.mian.gitnex.activities.SettingsBackupRestoreActivity; import org.mian.gitnex.activities.SettingsCodeEditorActivity; import org.mian.gitnex.activities.SettingsGeneralActivity; -import org.mian.gitnex.activities.SettingsNotificationsActivity; import org.mian.gitnex.activities.SettingsSecurityActivity; -import org.mian.gitnex.databinding.BottomSheetAboutBinding; import org.mian.gitnex.databinding.FragmentSettingsBinding; -import org.mian.gitnex.helpers.AppUtil; /** * @author mmarif @@ -59,7 +54,11 @@ public class SettingsFragment extends Fragment { v1 -> startActivity(new Intent(ctx, SettingsSecurityActivity.class))); fragmentSettingsBinding.notificationsFrame.setOnClickListener( - v1 -> startActivity(new Intent(ctx, SettingsNotificationsActivity.class))); + v1 -> + new BottomSheetSettingsNotificationsFragment() + .show( + getChildFragmentManager(), + "BottomSheetSettingsNotifications")); fragmentSettingsBinding.backupData.setText( getString( @@ -73,77 +72,12 @@ public class SettingsFragment extends Fragment { fragmentSettingsBinding.aboutAppFrame.setOnClickListener( aboutApp -> - new AboutBottomSheetFragment() + new BottomSheetSettingsAboutFragment() .show(getChildFragmentManager(), "AboutBottomSheet")); return fragmentSettingsBinding.getRoot(); } - public static class AboutBottomSheetFragment extends BottomSheetDialogFragment { - - private BottomSheetAboutBinding binding; - - @Nullable @Override - public View onCreateView( - @NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - binding = BottomSheetAboutBinding.inflate(inflater, container, false); - - // Set app version and build - binding.appVersionBuild.setText( - getString( - R.string.appVersionBuild, - AppUtil.getAppVersion(requireContext()), - AppUtil.getAppBuildNo(requireContext()))); - - // Set server version - binding.userServerVersion.setText( - ((BaseActivity) requireActivity()).getAccount().getServerVersion().toString()); - - // Set up link click listeners - binding.donationLinkPatreon.setOnClickListener( - v -> { - AppUtil.openUrlInBrowser( - requireContext(), getString(R.string.supportLinkPatreon)); - dismiss(); - }); - - binding.translateLink.setOnClickListener( - v -> { - AppUtil.openUrlInBrowser(requireContext(), getString(R.string.crowdInLink)); - dismiss(); - }); - - binding.appWebsite.setOnClickListener( - v -> { - AppUtil.openUrlInBrowser( - requireContext(), getString(R.string.appWebsiteLink)); - dismiss(); - }); - - binding.feedback.setOnClickListener( - v -> { - AppUtil.openUrlInBrowser( - requireContext(), getString(R.string.feedbackLink)); - dismiss(); - }); - - // Hide donation link for pro users - if (AppUtil.isPro(requireContext())) { - binding.layoutFrame1.setVisibility(View.GONE); - } - - return binding.getRoot(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; // Prevent memory leaks - } - } - public void rateThisApp() { try { diff --git a/app/src/main/res/layout/activity_settings_notifications.xml b/app/src/main/res/layout/activity_settings_notifications.xml deleted file mode 100644 index 80b53621..00000000 --- a/app/src/main/res/layout/activity_settings_notifications.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/bottom_sheet_about.xml b/app/src/main/res/layout/bottom_sheet_settings_about.xml similarity index 100% rename from app/src/main/res/layout/bottom_sheet_about.xml rename to app/src/main/res/layout/bottom_sheet_settings_about.xml diff --git a/app/src/main/res/layout/bottom_sheet_settings_notifications.xml b/app/src/main/res/layout/bottom_sheet_settings_notifications.xml new file mode 100644 index 00000000..0b313030 --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_settings_notifications.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +