Skip to content

Commit

Permalink
Merge pull request #8830 from brave/news-optin
Browse files Browse the repository at this point in the history
Brave News: require opt-in
  • Loading branch information
bsclifton authored May 18, 2021
2 parents c3564c9 + eef0de6 commit c4ce1be
Show file tree
Hide file tree
Showing 30 changed files with 319 additions and 217 deletions.
4 changes: 4 additions & 0 deletions .storybook/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ let locale: Record<string, string> = {
rewardsWidgetEnableBrandedWallpaperTitle: 'Get paid to view this sponsored background image.',
tosAndPp: 'By turning on {{title}}, you agree to the $1Terms of Service$2 and $3Privacy Policy$4.',
braveTodayDisableSourceCommand: 'Disable content from $1',
braveTodayIntroTitle: `Today's top stories in a completely private feed, just for you.`,
braveTodayIntroDescription: `Brave News is ad-supported with completely private and anonymized ads matched on your device. Your personal information always stays private, per our $1privacy policy$2.`,
braveTodayOptInActionLabel: 'Show Brave News',
braveTodayOptOutActionLabel: 'No thanks'
}

export function provideStrings (strings: Record<string, string>) {
Expand Down
4 changes: 3 additions & 1 deletion browser/brave_profile_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ void RegisterProfilePrefsForMigration(
registry->RegisterIntegerPref(
kAlternativeSearchEngineProviderInTor,
TemplateURLPrepopulateData::PREPOPULATED_ENGINE_ID_INVALID);
// Added 05/2021
registry->RegisterBooleanPref(kBraveTodayIntroDismissed, false);
}

void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
Expand Down Expand Up @@ -304,7 +306,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {

// Brave Today
registry->RegisterDictionaryPref(kBraveTodaySources);
registry->RegisterBooleanPref(kBraveTodayIntroDismissed, false);
registry->RegisterBooleanPref(kBraveTodayOptedIn, false);
registry->RegisterListPref(kBraveTodayWeeklySessionCount);
registry->RegisterListPref(kBraveTodayWeeklyCardViewsCount);
registry->RegisterListPref(kBraveTodayWeeklyCardVisitsCount);
Expand Down
2 changes: 2 additions & 0 deletions browser/extensions/api/settings_private/brave_prefs_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() {
settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif
// Brave today prefs
(*s_brave_allowlist)[kBraveTodayOptedIn] =
settings_api::PrefType::PREF_TYPE_BOOLEAN;
(*s_brave_allowlist)[kBraveTodaySources] =
settings_api::PrefType::PREF_TYPE_DICTIONARY;
// Clear browsing data on exit prefs.
Expand Down
2 changes: 2 additions & 0 deletions browser/ui/webui/brave_webui_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ void CustomizeWebUIHTMLSource(const std::string &name,
{ "braveTodayTitle", IDS_BRAVE_TODAY_TITLE },
{ "braveTodayIntroTitle", IDS_BRAVE_TODAY_INTRO_TITLE },
{ "braveTodayIntroDescription", IDS_BRAVE_TODAY_INTRO_DESCRIPTION },
{ "braveTodayOptInActionLabel", IDS_BRAVE_TODAY_OPT_IN_ACTION_LABEL },
{ "braveTodayOptOutActionLabel", IDS_BRAVE_TODAY_OPT_OUT_ACTION_LABEL },
{ "braveTodayStatusFetching", IDS_BRAVE_TODAY_STATUS_FETCHING},
{ "braveTodayActionRefresh", IDS_BRAVE_TODAY_ACTION_REFRESH},
{ "braveTodayScrollHint", IDS_BRAVE_TODAY_SCROLL_HINT},
Expand Down
14 changes: 9 additions & 5 deletions browser/ui/webui/new_tab_page/brave_new_tab_message_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,8 @@ base::DictionaryValue GetPreferencesDictionary(PrefService* prefs) {
pref_data.SetBoolean(
"isBrandedWallpaperNotificationDismissed",
prefs->GetBoolean(kBrandedWallpaperNotificationDismissed));
pref_data.SetBoolean(
"isBraveTodayIntroDismissed",
prefs->GetBoolean(kBraveTodayIntroDismissed));
pref_data.SetBoolean("isBraveTodayOptedIn",
prefs->GetBoolean(kBraveTodayOptedIn));
pref_data.SetBoolean(
"showBinance",
prefs->GetBoolean(kNewTabPageShowBinance));
Expand Down Expand Up @@ -323,6 +322,11 @@ void BraveNewTabMessageHandler::OnJavascriptAllowed() {
base::Bind(&BraveNewTabMessageHandler::OnPrivatePropertiesChanged,
base::Unretained(this)));
}
// News
pref_change_registrar_.Add(
kBraveTodayOptedIn,
base::Bind(&BraveNewTabMessageHandler::OnPreferencesChanged,
base::Unretained(this)));
// New Tab Page preferences
pref_change_registrar_.Add(kNewTabPageShowBackgroundImage,
base::Bind(&BraveNewTabMessageHandler::OnPreferencesChanged,
Expand Down Expand Up @@ -470,8 +474,8 @@ void BraveNewTabMessageHandler::HandleSaveNewTabPagePref(
settingsKey = kNewTabPageShowStats;
} else if (settingsKeyInput == "showToday") {
settingsKey = kNewTabPageShowToday;
} else if (settingsKeyInput == "isBraveTodayIntroDismissed") {
settingsKey = kBraveTodayIntroDismissed;
} else if (settingsKeyInput == "isBraveTodayOptedIn") {
settingsKey = kBraveTodayOptedIn;
} else if (settingsKeyInput == "showRewards") {
settingsKey = kNewTabPageShowRewards;
} else if (settingsKeyInput == "isBrandedWallpaperNotificationDismissed") {
Expand Down
2 changes: 2 additions & 0 deletions chromium_src/chrome/browser/prefs/browser_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ void MigrateObsoleteProfilePrefs(Profile* profile) {

// Added 04/2021
profile->GetPrefs()->ClearPref(kAlternativeSearchEngineProviderInTor);
// Added 05/2021
profile->GetPrefs()->ClearPref(kBraveTodayIntroDismissed);
}

// This method should be periodically pruned of year+ old migrations.
Expand Down
1 change: 1 addition & 0 deletions common/pref_names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const char kNewTabPageShowTogether[] = "brave.new_tab_page.show_together";
const char kNewTabPageShowsOptions[] = "brave.new_tab_page.shows_options";
const char kBraveTodaySources[] = "brave.today.sources";
const char kBraveTodayIntroDismissed[] = "brave.today.intro_dismissed";
const char kBraveTodayOptedIn[] = "brave.today.opted_in";
const char kBraveTodayWeeklySessionCount[] =
"brave.today.p3a_weekly_session_count";
const char kBraveTodayWeeklyCardViewsCount[] =
Expand Down
1 change: 1 addition & 0 deletions common/pref_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern const char kNewTabPageShowTogether[];
extern const char kNewTabPageShowsOptions[];
extern const char kBraveTodaySources[];
extern const char kBraveTodayIntroDismissed[];
extern const char kBraveTodayOptedIn[];
extern const char kBraveTodayWeeklySessionCount[];
extern const char kBraveTodayWeeklyCardViewsCount[];
extern const char kBraveTodayWeeklyCardVisitsCount[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
// you can obtain one at http://mozilla.org/MPL/2.0/.

import * as Background from '../../../../../common/Background'
import { getPreference } from '../../../../../common/settingsPrivate'
import * as Feed from './feed'
import * as Publishers from './publishers'
import * as PublisherUserPrefs from './publisher-user-prefs'
import { fetchResource, getUnpaddedAsDataUrl } from './privateCDN'

const SETTINGS_KEY_SHOW_TODAY = 'brave.new_tab_page.show_brave_today'
const SETTINGS_KEY_OPTED_IN = 'brave.today.opted_in'
const ALARM_KEY_FEED_UPDATE = 'brave-today-update-feed'
const ALARM_KEY_PUBLISHERS_UPDATE = 'brave-today-update-publishers'

// Only do certain things when Brave Today is enabled
let isStartedUp = false

//
// This module is the orchestrator for the Brave Today backend.
// It handles command communication from front-ends, as well
Expand Down Expand Up @@ -66,11 +71,6 @@ function stopUpdateFrequency () {
chrome.alarms.clear(ALARM_KEY_PUBLISHERS_UPDATE)
}

async function getHasBraveTodayBeenUsed () {
// We'll only have local data if data has been fetched or cached.
return !!(await Feed.getLocalData())
}

// Setup listeners for messages from WebUI
import MessageTypes = Background.MessageTypes.Today
import Messages = BraveToday.Messages
Expand Down Expand Up @@ -98,7 +98,7 @@ Background.setListener<void>(
// most NTP opens won't result in reading Brave Today
// content (or changing publisher settings).
// Only do this if we've previously interacted with brave today
if (await getHasBraveTodayBeenUsed()) {
if (isStartedUp) {
await Promise.all([
Feed.getOrFetchData(),
Publishers.getOrFetchData()
Expand All @@ -110,6 +110,10 @@ Background.setListener<void>(
Background.setListener<Messages.GetFeedResponse>(
MessageTypes.getFeed,
async function (req, sender, sendResponse) {
if (!isStartedUp) {
sendResponse({ })
return
}
try {
const feed = await Feed.getOrFetchData()
// Only wait once. If there was an error or no data then return nothing.
Expand All @@ -125,9 +129,12 @@ Background.setListener<Messages.GetFeedResponse>(
Background.setListener<Messages.GetPublishersResponse>(
MessageTypes.getPublishers,
async function (req, sender, sendResponse) {
// TODO: handle error
const publishers = await Publishers.getOrFetchData()
if (!isStartedUp) {
sendResponse({ publishers: {} })
return
}
// TODO(petemill): handle error
const publishers = await Publishers.getOrFetchData()
sendResponse({ publishers })
}
)
Expand Down Expand Up @@ -158,6 +165,10 @@ Background.setListener<{}, Messages.SetPublisherPrefPayload>(
Background.setListener<Messages.IsFeedUpdateAvailableResponse, Messages.IsFeedUpdateAvailablePayload>(
MessageTypes.isFeedUpdateAvailable,
async function (req, sender, sendResponse) {
if (!isStartedUp) {
sendResponse({ isUpdateAvailable: false })
return
}
const requestHash = req.hash
// Check for update from local
const feed = await Feed.getOrFetchData(true)
Expand All @@ -171,24 +182,29 @@ Background.setListener<Messages.IsFeedUpdateAvailableResponse, Messages.IsFeedUp
}
)

Background.setListener<Messages.ClearPrefsResponse, Messages.ClearPrefsPayload>(
MessageTypes.resetPrefsToDefault,
async function (req, sender, sendResponse) {
await PublisherUserPrefs.clearPrefs()
const publishers = await Publishers.update(true)
sendResponse({ publishers })
})

// Only do certain things when Brave Today is enabled
let isStartedUp = false
Background.setListener<
Messages.ClearPrefsResponse, Messages.ClearPrefsPayload
>(MessageTypes.resetPrefsToDefault, async function (req, sender, sendResponse) {
await PublisherUserPrefs.clearPrefs()
const publishers = await Publishers.update(true)
sendResponse({ publishers })
})

async function conditionallyStartupOrShutdown (pref: chrome.settingsPrivate.PrefObject) {
if (pref.type !== chrome.settingsPrivate.PrefType.BOOLEAN) {
throw new Error(`Unknown pref type for '${SETTINGS_KEY_SHOW_TODAY}'. Expected BOOLEAN but saw ${pref.type}.`)
async function conditionallyStartupOrShutdown () {
const prefs = await Promise.all([
getPreference(SETTINGS_KEY_SHOW_TODAY),
getPreference(SETTINGS_KEY_OPTED_IN)
])
let isBraveTodayEnabled = true
for (const pref of prefs) {
if (pref.type !== chrome.settingsPrivate.PrefType.BOOLEAN) {
throw new Error(`Unknown pref type for '${pref.key}'. Expected BOOLEAN but saw ${pref.type}.`)
}
if (!pref.value) {
isBraveTodayEnabled = false
}
}
const isBraveTodayEnabled = pref.value
const hasBraveTodayBeenUsed = await getHasBraveTodayBeenUsed()
if (isBraveTodayEnabled && hasBraveTodayBeenUsed && !isStartedUp) {
if (isBraveTodayEnabled && !isStartedUp) {
isStartedUp = true
ensureUpdateFrequency()
} else if (!isBraveTodayEnabled && isStartedUp) {
Expand All @@ -197,11 +213,11 @@ async function conditionallyStartupOrShutdown (pref: chrome.settingsPrivate.Pref
}
}

chrome.settingsPrivate.getPref(SETTINGS_KEY_SHOW_TODAY, conditionallyStartupOrShutdown)

chrome.settingsPrivate.onPrefsChanged.addListener(async prefs => {
const pref = prefs.find(pref => pref.key === SETTINGS_KEY_SHOW_TODAY)
if (pref) {
await conditionallyStartupOrShutdown(pref)
}
await conditionallyStartupOrShutdown()
})

conditionallyStartupOrShutdown()
.catch((err) => {
console.error('Could not startup Brave News', err)
})
2 changes: 2 additions & 0 deletions components/brave_new_tab_ui/actions/today_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type DataReceivedPayload = {
}
export const dataReceived = createAction<DataReceivedPayload>('dataReceived')

export const optIn = createAction('optedIn')

/**
* Scroll has reached a position so that another page of content is needed
*/
Expand Down
4 changes: 2 additions & 2 deletions components/brave_new_tab_ui/api/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ export function saveShowFTX (value: boolean): void {
sendSavePref('showFTX', value)
}

export function saveIsBraveTodayIntroDismissed (value: boolean): void {
sendSavePref('isBraveTodayIntroDismissed', value)
export function saveIsBraveTodayOptedIn (value: boolean): void {
sendSavePref('isBraveTodayOptedIn', value)
}

export function saveSetAllStackWidgets (value: boolean): void {
Expand Down
5 changes: 5 additions & 0 deletions components/brave_new_tab_ui/async/today.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import AsyncActionHandler from '../../common/AsyncActionHandler'
import * as Background from '../../common/Background'
import * as Actions from '../actions/today_actions'
import { ApplicationState } from '../reducers'
import { saveIsBraveTodayOptedIn } from '../api/preferences'

function storeInHistoryState (data: Object) {
const oldHistoryState = (typeof history.state === 'object') ? history.state : {}
Expand Down Expand Up @@ -45,6 +46,10 @@ handler.on(
}
)

handler.on(Actions.optIn.getType(), async () => {
saveIsBraveTodayOptedIn(true)
})

handler.on(Actions.ensureSettingsData.getType(), async (store) => {
const state = store.getState() as ApplicationState
if (state.today.publishers && Object.keys(state.today.publishers).length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,40 @@
import styled from 'styled-components'
import {
Block as StandardBlock,
Heading as StandardHeading,
Image as StandardImage,
Text as StandardText
Image as StandardImage
} from './default'

export const Intro = styled(StandardBlock)`
font-family: Poppins;
color: white;
text-align: center;
padding: 44px 90px 36px;
display: flex;
flex-direction: column;
gap: 18px;
align-items: center;
`

export const Image = styled(StandardImage)`
margin: auto;
height: 60px;
export const Title = styled('h2')`
margin: 0;
font-weight: 600;
font-size: 28px;
line-height: 38px;
`

export const Heading = styled(StandardHeading)`
margin: 36px 0 24px;
export const Paragraph = styled('p')`
margin: 0;
font-weight: 500;
font-size: 14px;
line-height: 17px;
letter-spacing: 0.16px;
a {
color: inherit;
text-decoration: underline;
}
`

export const Text = styled(StandardText)`
${Intro} & {
font-weight: 500;
line-height: 20px;
}
export const Image = styled(StandardImage)`
margin: auto;
height: 60px;
`
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ export default function CardError () {
<Heading>
Oops…
</Heading>
<Card.Text>
<Card.Paragraph>
Brave Today is experiencing some issues. Try again.
</Card.Text>
</Card.Paragraph>
</Content>
</Card.Intro>
)
Expand Down

This file was deleted.

Loading

0 comments on commit c4ce1be

Please sign in to comment.