Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Weekly Roundup toggle to Notification settings #15325

Merged
merged 8 commits into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.CoroutineDispatcher
import org.wordpress.android.R
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.modules.UI_THREAD
import org.wordpress.android.ui.debug.DebugSettingsViewModel.NavigationAction.DebugCookies
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Button
Expand All @@ -18,23 +19,31 @@ import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Type.BUTTON
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Type.FEATURE
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Type.HEADER
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Type.ROW
import org.wordpress.android.ui.notifications.NotificationManagerWrapper
import org.wordpress.android.ui.utils.ListItemInteraction
import org.wordpress.android.ui.utils.ListItemInteraction.Companion.create
import org.wordpress.android.util.DebugUtils
import org.wordpress.android.util.config.FeaturesInDevelopment
import org.wordpress.android.util.config.ManualFeatureConfig
import org.wordpress.android.util.config.RemoteConfig
import org.wordpress.android.util.config.RemoteConfigDefaults
import org.wordpress.android.viewmodel.ContextProvider
import org.wordpress.android.viewmodel.Event
import org.wordpress.android.viewmodel.ScopedViewModel
import org.wordpress.android.workers.weeklyroundup.WeeklyRoundupNotifier
import javax.inject.Inject
import javax.inject.Named

class DebugSettingsViewModel
@Inject constructor(
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
@Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher,
private val manualFeatureConfig: ManualFeatureConfig,
private val remoteConfig: RemoteConfig,
private val debugUtils: DebugUtils
private val debugUtils: DebugUtils,
private val weeklyRoundupNotifier: WeeklyRoundupNotifier,
private val notificationManager: NotificationManagerWrapper,
private val contextProvider: ContextProvider
) : ScopedViewModel(mainDispatcher) {
private val _uiState = MutableLiveData<UiState>()
val uiState: LiveData<UiState> = _uiState
Expand Down Expand Up @@ -65,14 +74,21 @@ class DebugSettingsViewModel
uiItems.add(Button(R.string.debug_settings_restart_app, debugUtils::restartApp))
}
uiItems.add(Header(R.string.debug_settings_tools))
uiItems.add(Row(R.string.debug_cookies_title, ListItemInteraction.create(this::onDebugCookiesClick)))
uiItems.add(Row(R.string.debug_cookies_title, create(this::onDebugCookiesClick)))
uiItems.add(Row(R.string.debug_settings_force_show_weekly_roundup, create(this::onForceShowWeeklyRoundupClick)))
_uiState.value = UiState(uiItems)
}

private fun onDebugCookiesClick() {
_onNavigation.value = Event(DebugCookies)
}

private fun onForceShowWeeklyRoundupClick() = launch(bgDispatcher) {
weeklyRoundupNotifier.buildNotifications().forEach {
notificationManager.notify(it.id, it.asNotificationCompatBuilder(contextProvider.getContext()).build())
}
}

private fun buildDevelopedFeatures(): List<Feature> {
return FeaturesInDevelopment.featuresInDevelopment.map { name ->
val value = if (manualFeatureConfig.hasManualSetup(name)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.wordpress.android.ui.notifications

import android.app.Notification
import android.content.Context
import androidx.core.app.NotificationManagerCompat
import javax.inject.Inject

class NotificationManagerWrapper
@Inject constructor(private val context: Context) {
fun areNotificationsEnabled() = NotificationManagerCompat.from(context).areNotificationsEnabled()
fun notify(id: Int, notification: Notification) = NotificationManagerCompat.from(context).notify(id, notification)
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ public enum DeletablePrefKey implements PrefKey {
REMOVED_QUICK_START_CARD_TYPE,
PINNED_DYNAMIC_CARD,
BLOGGING_REMINDERS_SHOWN,
SHOULD_SCHEDULE_CREATE_SITE_NOTIFICATION
SHOULD_SCHEDULE_CREATE_SITE_NOTIFICATION,
SHOULD_SHOW_WEEKLY_ROUNDUP_NOTIFICATION
}

/**
Expand Down Expand Up @@ -1300,6 +1301,18 @@ public static boolean shouldScheduleCreateSiteNotification() {
return getBoolean(DeletablePrefKey.SHOULD_SCHEDULE_CREATE_SITE_NOTIFICATION, true);
}

public static void setShouldShowWeeklyRoundupNotification(long remoteSiteId, boolean shouldShow) {
prefs().edit().putBoolean(getShouldShowWeeklyRoundupNotification(remoteSiteId), shouldShow).apply();
}

public static boolean shouldShowWeeklyRoundupNotification(long remoteSiteId) {
return prefs().getBoolean(getShouldShowWeeklyRoundupNotification(remoteSiteId), true);
}

@NonNull private static String getShouldShowWeeklyRoundupNotification(long siteId) {
return DeletablePrefKey.SHOULD_SHOW_WEEKLY_ROUNDUP_NOTIFICATION.name() + siteId;
}

/*
* adds a local site ID to the top of list of recently chosen sites
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ class AppPrefsWrapper @Inject constructor() {
return AppPrefs.isBloggingRemindersShown(siteId)
}

fun setShouldShowWeeklyRoundupNotification(siteId: Long, shouldShow: Boolean) {
AppPrefs.setShouldShowWeeklyRoundupNotification(siteId, shouldShow)
}

fun shouldShowWeeklyRoundupNotification(siteId: Long): Boolean {
return AppPrefs.shouldShowWeeklyRoundupNotification(siteId)
}

fun setSiteJetpackCapabilities(remoteSiteId: Long, capabilities: List<JetpackCapability>) =
AppPrefs.setSiteJetpackCapabilities(remoteSiteId, capabilities)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.preference.DialogPreference;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
Expand All @@ -16,6 +17,7 @@
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;

Expand All @@ -25,6 +27,7 @@
import org.wordpress.android.models.NotificationsSettings;
import org.wordpress.android.models.NotificationsSettings.Channel;
import org.wordpress.android.models.NotificationsSettings.Type;
import org.wordpress.android.ui.prefs.AppPrefs;
import org.wordpress.android.ui.prefs.notifications.PrefMainSwitchToolbarView.MainSwitchToolbarListener;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
Expand Down Expand Up @@ -182,48 +185,68 @@ private View configureLayoutForView(LinearLayout view) {
continue;
}

View commentsSetting = View.inflate(getContext(), R.layout.notifications_settings_switch, null);
TextView title = commentsSetting.findViewById(R.id.notifications_switch_title);
title.setText(settingName);

// Add special summary text for the WPCOM section
String settingSummary = null;
if (mChannel == Channel.WPCOM && i < summaryArray.length) {
String summaryText = summaryArray[i];
TextView summary = commentsSetting.findViewById(R.id.notifications_switch_summary);
summary.setVisibility(View.VISIBLE);
summary.setText(summaryText);
settingSummary = summaryArray[i];
}

final SwitchCompat toggleSwitch = commentsSetting.findViewById(R.id.notifications_switch);
toggleSwitch.setChecked(JSONUtils.queryJSON(settingsJson, settingValue, true));
toggleSwitch.setTag(settingValue);
toggleSwitch.setOnCheckedChangeListener(mOnCheckedChangedListener);
boolean isSettingChecked = JSONUtils.queryJSON(settingsJson, settingValue, true);

View rowContainer = commentsSetting.findViewById(R.id.row_container);
rowContainer.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
toggleSwitch.setChecked(!toggleSwitch.isChecked());
}
});

if (mShouldDisplayMainSwitch && i == mSettingsArray.length - 1) {
View divider = commentsSetting.findViewById(R.id.notifications_list_divider);
if (divider != null) {
MarginLayoutParams mlp = (MarginLayoutParams) divider.getLayoutParams();
mlp.leftMargin = 0;
mlp.rightMargin = 0;
divider.setLayoutParams(mlp);
}
}
boolean isSettingLast = i == mSettingsArray.length - 1;

view.addView(commentsSetting);
view.addView(setupSettingView(settingName, settingValue, settingSummary, isSettingChecked,
isSettingLast, mOnCheckedChangedListener));
}
}

// Add Weekly Roundup setting
if (mChannel == Channel.BLOGS && mType == Type.DEVICE) {
String settingName = getContext().getString(R.string.weekly_roundup);
boolean isSettingChecked = AppPrefs.shouldShowWeeklyRoundupNotification(mBlogId);
View settingView = setupSettingView(settingName, null, null, isSettingChecked, true,
(compoundButton, isChecked) -> AppPrefs.setShouldShowWeeklyRoundupNotification(mBlogId, isChecked));
view.addView(settingView);
}

return view;
}

private CompoundButton.OnCheckedChangeListener mOnCheckedChangedListener =
private View setupSettingView(String settingName, @Nullable String settingValue, @Nullable String settingSummary,
boolean isSettingChecked, boolean isSettingLast,
CompoundButton.OnCheckedChangeListener onCheckedChangeListener) {
View setting = View.inflate(getContext(), R.layout.notifications_settings_switch, null);
TextView title = setting.findViewById(R.id.notifications_switch_title);
title.setText(settingName);

if (!TextUtils.isEmpty(settingSummary)) {
TextView summary = setting.findViewById(R.id.notifications_switch_summary);
summary.setVisibility(View.VISIBLE);
summary.setText(settingSummary);
}

final SwitchCompat toggleSwitch = setting.findViewById(R.id.notifications_switch);
toggleSwitch.setChecked(isSettingChecked);
toggleSwitch.setTag(settingValue);
toggleSwitch.setOnCheckedChangeListener(onCheckedChangeListener);

View rowContainer = setting.findViewById(R.id.row_container);
rowContainer.setOnClickListener(v -> toggleSwitch.setChecked(!toggleSwitch.isChecked()));

if (mShouldDisplayMainSwitch && isSettingLast) {
View divider = setting.findViewById(R.id.notifications_list_divider);
if (divider != null) {
MarginLayoutParams mlp = (MarginLayoutParams) divider.getLayoutParams();
mlp.leftMargin = 0;
mlp.rightMargin = 0;
divider.setLayoutParams(mlp);
}
}

return setting;
}

private final CompoundButton.OnCheckedChangeListener mOnCheckedChangedListener =
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
Expand Down Expand Up @@ -325,7 +348,7 @@ private void hideDisabledView(boolean isMainChecked) {
* Updates Notifications current settings switches state based on the main switch state
*
* @param isMainChecked TRUE to switch on the settings switches.
* FALSE to switch off the settings switches.
* FALSE to switch off the settings switches.
*/
private void setSettingsSwitchesChecked(boolean isMainChecked) {
for (String settingValue : mSettingsValues) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.wordpress.android.push.NotificationPushIds.WEEKLY_ROUNDUP_NOTIFICATIO
import org.wordpress.android.push.NotificationType.WEEKLY_ROUNDUP
import org.wordpress.android.ui.ActivityLauncher
import org.wordpress.android.ui.notifications.SystemNotificationsTracker
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.ui.stats.StatsTimeframe.WEEK
import org.wordpress.android.util.SiteUtilsWrapper
import org.wordpress.android.viewmodel.ContextProvider
Expand All @@ -26,7 +27,8 @@ class WeeklyRoundupNotifier @Inject constructor(
private val weeklyRoundupScheduler: WeeklyRoundupScheduler,
private val notificationsTracker: SystemNotificationsTracker,
private val siteUtils: SiteUtilsWrapper,
private val weeklyRoundupRepository: WeeklyRoundupRepository
private val weeklyRoundupRepository: WeeklyRoundupRepository,
private val appPrefs: AppPrefsWrapper
) {
fun shouldShowNotifications() = accountStore.hasAccessToken() && siteStore.hasSitesAccessedViaWPComRest()

Expand All @@ -36,6 +38,7 @@ class WeeklyRoundupNotifier @Inject constructor(
.awaitAll()
.asSequence()
.filterNotNull()
.filter { appPrefs.shouldShowWeeklyRoundupNotification(it.site.siteId) }
.sortedByDescending { it.score }
.take(TOP_FIVE_SITES)
.filter { it.views >= MIN_SITE_VIEWS }
Expand Down
2 changes: 2 additions & 0 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,7 @@
<string name="debug_settings_restart_app" translatable="false">Restart the app</string>
<string name="debug_settings_missing_developed_feature" translatable="false">Don\'t see a feature you\'re working on? Check that your feature config file is annotated with the FeatureInDevelopment annotation.</string>
<string name="debug_settings_tools" translatable="false">Tools</string>
<string name="debug_settings_force_show_weekly_roundup" translatable="false">Force show Weekly Roundup notification</string>

<!-- Debug cookies -->
<string name="debug_cookies_title" translatable="false">Debug cookies</string>
Expand Down Expand Up @@ -3786,6 +3787,7 @@ translators: Block name. %s: The localized block name -->
<string name="create_site_notification_create_site_action">Create site</string>

<!-- Weekly Roundup Notification -->
<string name="weekly_roundup">Weekly Roundup</string>
<string name="weekly_roundup_notification_title">Weekly Roundup: %s</string>
<string name="weekly_roundup_notification_text">Your site got %1$d views, %2$d likes, %3$d comments.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,36 @@ import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Feature.Stat
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Header
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiItem.Row
import org.wordpress.android.ui.debug.DebugSettingsViewModel.UiState
import org.wordpress.android.ui.notifications.NotificationManagerWrapper
import org.wordpress.android.util.DebugUtils
import org.wordpress.android.util.config.ManualFeatureConfig
import org.wordpress.android.util.config.RemoteConfig
import org.wordpress.android.viewmodel.ContextProvider
import org.wordpress.android.workers.weeklyroundup.WeeklyRoundupNotifier

class DebugSettingsViewModelTest : BaseUnitTest() {
@Mock lateinit var manualFeatureConfig: ManualFeatureConfig
@Mock lateinit var remoteConfig: RemoteConfig
@Mock lateinit var debugUtils: DebugUtils
@Mock lateinit var weeklyRoundupNotifier: WeeklyRoundupNotifier
@Mock lateinit var notificationManager: NotificationManagerWrapper
@Mock lateinit var contextProvider: ContextProvider
private lateinit var viewModel: DebugSettingsViewModel
private val uiStates = mutableListOf<UiState>()

@InternalCoroutinesApi
@Before
fun setUp() {
viewModel = DebugSettingsViewModel(TEST_DISPATCHER, manualFeatureConfig, remoteConfig, debugUtils)
viewModel = DebugSettingsViewModel(
TEST_DISPATCHER,
TEST_DISPATCHER,
manualFeatureConfig,
remoteConfig,
debugUtils,
weeklyRoundupNotifier,
notificationManager,
contextProvider
)
}

@Test
Expand Down
Loading