-
Sébastien Blin authored
If a settings is set when mIsRefreshingViewFromPresenter is true, the modified settings can blink, causing an infinite loop which cause a crash. Change-Id: I4f64f6c36ec626a81a9b1f3d341e6e2c792282ce Gitlab: #624
Sébastien Blin authoredIf a settings is set when mIsRefreshingViewFromPresenter is true, the modified settings can blink, causing an infinite loop which cause a crash. Change-Id: I4f64f6c36ec626a81a9b1f3d341e6e2c792282ce Gitlab: #624
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SettingsFragment.java 6.77 KiB
/*
* Copyright (C) 2004-2019 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cx.ring.settings;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.content.ContextCompat;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import cx.ring.R;
import cx.ring.application.RingApplication;
import cx.ring.client.HomeActivity;
import cx.ring.dependencyinjection.RingInjectionComponent;
import cx.ring.model.Settings;
import cx.ring.mvp.BaseSupportFragment;
import cx.ring.mvp.GenericView;
import cx.ring.services.SharedPreferencesServiceImpl;
/**
* TODO: improvements : handle multiples permissions for feature.
*/
public class SettingsFragment extends BaseSupportFragment<SettingsPresenter> implements GenericView<Settings> {
@BindView(R.id.settings_push_notifications_layout)
ViewGroup mGroupPushNotifications;
@BindView(R.id.settings_push_notifications)
Switch mViewPushNotifications;
@BindView(R.id.settings_startup)
Switch mViewStartup;
@BindView(R.id.settings_persistNotification)
Switch mViewPersistNotif;
@BindView(R.id.settings_video_layout)
View settings_video_layout;
@BindView(R.id.settings_dark_theme)
Switch mDarkTheme;
private boolean mIsRefreshingViewFromPresenter;
@Override
public int getLayout() {
return R.layout.frag_settings;
}
@Override
public void injectFragment(RingInjectionComponent component) {
component.inject(this);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onViewCreated(view, savedInstanceState);
mDarkTheme.setChecked(presenter.getDarkMode());
if (TextUtils.isEmpty(RingApplication.getInstance().getPushToken())) {
mGroupPushNotifications.setVisibility(View.GONE);
}
// loading preferences
presenter.loadSettings();
((HomeActivity) getActivity()).setToolbarState(false, R.string.menu_item_settings);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
}
@OnCheckedChanged(R.id.settings_dark_theme)
public void onDarkThemeChanged(CompoundButton button, boolean isChecked) {
presenter.setDarkMode(isChecked);
}
@OnCheckedChanged({
R.id.settings_push_notifications,
R.id.settings_startup,
R.id.settings_persistNotification
})
public void onSettingsCheckedChanged(CompoundButton button, boolean isChecked) {
if (!mIsRefreshingViewFromPresenter)
saveSettings();
}
private void saveSettings() {
Settings newSettings = new Settings();
newSettings.setAllowRingOnStartup(mViewStartup.isChecked());
newSettings.setAllowPushNotifications(mViewPushNotifications.isChecked());
newSettings.setAllowPersistentNotification(mViewPersistNotif.isChecked());
// save settings according to UI inputs
presenter.saveSettings(newSettings);
}
@OnClick(R.id.settings_video_layout)
void onVideoClick() {
HomeActivity activity = (HomeActivity) getActivity();
if (activity != null) {
activity.goToVideoSettings();
}
}
@OnClick(R.id.settings_clear_history)
public void onClearHistoryClick() {
new MaterialAlertDialogBuilder(getActivity())
.setTitle(getString(R.string.clear_history_dialog_title))
.setMessage(getString(R.string.clear_history_dialog_message))
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
// ask the presenter to clear history
presenter.clearHistory();
Snackbar.make(getView(),
getString(R.string.clear_history_completed),
Snackbar.LENGTH_SHORT).show();
})
.setNegativeButton(android.R.string.cancel, (dialog, id) -> {
//~ Empty
})
.show();
}
/**
* Presents a Toast explaining why the Read Contacts permission is required to display the devi-
* ces contacts in Ring.
*/
private void presentReadContactPermissionExplanationToast() {
Activity activity = getActivity();
if (null != activity) {
String toastMessage = getString(R.string.permission_dialog_read_contacts_message);
Toast.makeText(activity, toastMessage, Toast.LENGTH_LONG).show();
}
}
/**
* Presents a Toast explaining why the Write Call Log permission is required to enable the cor-
* responding feature.
*/
private void presentWriteCallLogPermissionExplanationToast() {
Activity activity = getActivity();
if (null != activity) {
String toastMessage = getString(R.string.permission_dialog_write_call_log_message);
Toast.makeText(activity, toastMessage, Toast.LENGTH_LONG).show();
}
}
@Override
public void showViewModel(Settings viewModel) {
mIsRefreshingViewFromPresenter = true;
mViewPushNotifications.setChecked(viewModel.isAllowPushNotifications());
mViewPersistNotif.setChecked(viewModel.isAllowPersistentNotification());
mViewStartup.setChecked(viewModel.isAllowRingOnStartup());
mIsRefreshingViewFromPresenter = false;
}
}