Revert "Revert "feat(web): move emails notifications to one pane and enable opening settings via url (#1614)" (#1617)" (#1619)

This reverts commit 6824dd2d5f.
This commit is contained in:
Karol Sójko
2022-09-22 20:18:19 +02:00
committed by GitHub
parent 4f8e75f36a
commit e50f4eb92e
6 changed files with 171 additions and 41 deletions

View File

@@ -11,6 +11,7 @@ import {
ListedAuthorSecretsData,
LogSessionUserAgentOption,
SettingName,
MuteMarketingEmailsOption,
} from '@standardnotes/settings'
type SettingType =
@@ -23,6 +24,7 @@ type SettingType =
| MuteFailedBackupsEmailsOption
| MuteFailedCloudBackupsEmailsOption
| MuteSignInEmailsOption
| MuteMarketingEmailsOption
| OneDriveBackupFrequency
export class SettingsList {

View File

@@ -0,0 +1,134 @@
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/Application/Application'
import { MuteMarketingEmailsOption, MuteSignInEmailsOption, SettingName } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Constants/Strings'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import Spinner from '@/Components/Spinner/Spinner'
type Props = {
application: WebApplication
}
const Email: FunctionComponent<Props> = ({ application }: Props) => {
const [signInEmailsMutedValue, setSignInEmailsMutedValue] = useState(MuteSignInEmailsOption.NotMuted)
const [marketingEmailsMutedValue, setMarketingEmailsMutedValue] = useState(MuteMarketingEmailsOption.NotMuted)
const [isLoading, setIsLoading] = useState(true)
const updateSetting = async (settingName: SettingName, payload: string): Promise<boolean> => {
try {
await application.settings.updateSetting(settingName, payload, false)
return true
} catch (e) {
application.alertService.alert(STRING_FAILED_TO_UPDATE_USER_SETTING).catch(console.error)
return false
}
}
const loadSettings = useCallback(async () => {
if (!application.getUser()) {
return
}
setIsLoading(true)
try {
const userSettings = await application.settings.listSettings()
setSignInEmailsMutedValue(
userSettings.getSettingValue<MuteSignInEmailsOption>(
SettingName.MuteSignInEmails,
MuteSignInEmailsOption.NotMuted,
),
),
setMarketingEmailsMutedValue(
userSettings.getSettingValue<MuteMarketingEmailsOption>(
SettingName.MuteMarketingEmails,
MuteMarketingEmailsOption.NotMuted,
),
)
} catch (error) {
console.error(error)
} finally {
setIsLoading(false)
}
}, [application])
useEffect(() => {
loadSettings().catch(console.error)
}, [loadSettings])
const toggleMuteSignInEmails = async () => {
const previousValue = signInEmailsMutedValue
const newValue =
previousValue === MuteSignInEmailsOption.Muted ? MuteSignInEmailsOption.NotMuted : MuteSignInEmailsOption.Muted
setSignInEmailsMutedValue(newValue)
const updateResult = await updateSetting(SettingName.MuteSignInEmails, newValue)
if (!updateResult) {
setSignInEmailsMutedValue(previousValue)
}
}
const toggleMuteMarketingEmails = async () => {
const previousValue = marketingEmailsMutedValue
const newValue =
previousValue === MuteMarketingEmailsOption.Muted
? MuteMarketingEmailsOption.NotMuted
: MuteMarketingEmailsOption.Muted
setMarketingEmailsMutedValue(newValue)
const updateResult = await updateSetting(SettingName.MuteMarketingEmails, newValue)
if (!updateResult) {
setMarketingEmailsMutedValue(previousValue)
}
}
return (
<PreferencesGroup>
<PreferencesSegment>
<Title>Email</Title>
<div>
<div className="flex items-center justify-between">
<div className="flex flex-col">
<Subtitle>Disable sign-in notification emails</Subtitle>
<Text>
Disables email notifications when a new sign-in occurs on your account. (Email notifications are
available to paid subscribers).
</Text>
</div>
{isLoading ? (
<Spinner className="ml-2 flex-shrink-0" />
) : (
<Switch
onChange={toggleMuteSignInEmails}
checked={signInEmailsMutedValue === MuteSignInEmailsOption.Muted}
/>
)}
</div>
<HorizontalSeparator classes="my-4" />
<div className="flex items-center justify-between">
<div className="flex flex-col">
<Subtitle>Disable marketing notification emails</Subtitle>
<Text>Disables email notifications with special deals and promotions.</Text>
</div>
{isLoading ? (
<Spinner className="ml-2 flex-shrink-0" />
) : (
<Switch
onChange={toggleMuteMarketingEmails}
checked={marketingEmailsMutedValue === MuteMarketingEmailsOption.Muted}
/>
)}
</div>
</div>
</PreferencesSegment>
</PreferencesGroup>
)
}
export default observer(Email)

View File

@@ -8,6 +8,7 @@ import Defaults from './Defaults'
import LabsPane from './Labs/Labs'
import Advanced from '@/Components/Preferences/Panes/General/Advanced/AdvancedSection'
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
import Email from './Email'
type Props = {
viewControllerManager: ViewControllerManager
@@ -19,6 +20,7 @@ const General: FunctionComponent<Props> = ({ viewControllerManager, application,
<PreferencesPane>
<Tools application={application} />
<Defaults application={application} />
<Email application={application} />
<LabsPane application={application} />
<Advanced
application={application}

View File

@@ -2,7 +2,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/Application/Application'
import { MuteSignInEmailsOption, LogSessionUserAgentOption, SettingName } from '@standardnotes/snjs'
import { LogSessionUserAgentOption, SettingName } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Constants/Strings'
@@ -15,9 +15,6 @@ type Props = {
}
const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
const [signInEmailsMutedValue, setSignInEmailsMutedValue] = useState<MuteSignInEmailsOption>(
MuteSignInEmailsOption.NotMuted,
)
const [sessionUaLoggingValue, setSessionUaLoggingValue] = useState<LogSessionUserAgentOption>(
LogSessionUserAgentOption.Enabled,
)
@@ -41,12 +38,6 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
try {
const userSettings = await application.settings.listSettings()
setSignInEmailsMutedValue(
userSettings.getSettingValue<MuteSignInEmailsOption>(
SettingName.MuteSignInEmails,
MuteSignInEmailsOption.NotMuted,
),
)
setSessionUaLoggingValue(
userSettings.getSettingValue<LogSessionUserAgentOption>(
SettingName.LogSessionUserAgent,
@@ -64,19 +55,6 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
loadSettings().catch(console.error)
}, [loadSettings])
const toggleMuteSignInEmails = async () => {
const previousValue = signInEmailsMutedValue
const newValue =
previousValue === MuteSignInEmailsOption.Muted ? MuteSignInEmailsOption.NotMuted : MuteSignInEmailsOption.Muted
setSignInEmailsMutedValue(newValue)
const updateResult = await updateSetting(SettingName.MuteSignInEmails, newValue)
if (!updateResult) {
setSignInEmailsMutedValue(previousValue)
}
}
const toggleSessionLogging = async () => {
const previousValue = sessionUaLoggingValue
const newValue =
@@ -97,23 +75,6 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
<PreferencesSegment>
<Title>Privacy</Title>
<div>
<div className="flex items-center justify-between">
<div className="flex flex-col">
<Subtitle>Disable sign-in notification emails</Subtitle>
<Text>
Disables email notifications when a new sign-in occurs on your account. (Email notifications are
available to paid subscribers).
</Text>
</div>
{isLoading ? (
<Spinner className="ml-2 flex-shrink-0" />
) : (
<Switch
onChange={toggleMuteSignInEmails}
checked={signInEmailsMutedValue === MuteSignInEmailsOption.Muted}
/>
)}
</div>
<HorizontalSeparator classes="my-4" />
<div className="flex items-center justify-between">
<div className="flex flex-col">

View File

@@ -29,9 +29,18 @@ export class PreferencesController {
closePreferences = (): void => {
this._open = false
this.currentPane = DEFAULT_PANE
this.removePreferencesToggleFromURLQueryParameters()
}
get isOpen(): boolean {
return this._open
}
private removePreferencesToggleFromURLQueryParameters() {
const urlSearchParams = new URLSearchParams(window.location.search)
urlSearchParams.delete('settings')
const newUrl = `${window.location.origin}${window.location.pathname}${urlSearchParams.toString()}`
window.history.replaceState(null, document.title, newUrl)
}
}

View File

@@ -29,6 +29,8 @@ import { NavigationController } from './Navigation/NavigationController'
import { FilePreviewModalController } from './FilePreviewModalController'
import { SelectedItemsController } from './SelectedItemsController'
import { HistoryModalController } from './NoteHistory/HistoryModalController'
import { PreferenceId } from '@/Components/Preferences/PreferencesMenu'
import { AccountMenuPane } from '@/Components/AccountMenu/AccountMenuPane'
export class ViewControllerManager {
readonly enableUnfinishedFeatures: boolean = window?.enabledUnfinishedFeatures
@@ -209,11 +211,31 @@ export class ViewControllerManager {
addAppEventObserver() {
this.unsubAppEventObserver = this.application.addEventObserver(async (eventName) => {
const urlSearchParams = new URLSearchParams(window.location.search)
switch (eventName) {
case ApplicationEvent.Launched:
if (window.location.search.includes('purchase=true')) {
if (urlSearchParams.get('purchase')) {
this.purchaseFlowController.openPurchaseFlow()
}
if (urlSearchParams.get('settings')) {
const user = this.application.getUser()
if (user === undefined) {
this.accountMenuController.setShow(true)
this.accountMenuController.setCurrentPane(AccountMenuPane.SignIn)
break
}
this.preferencesController.openPreferences()
this.preferencesController.setCurrentPane(urlSearchParams.get('settings') as PreferenceId)
}
break
case ApplicationEvent.SignedIn:
if (urlSearchParams.get('settings')) {
this.preferencesController.openPreferences()
this.preferencesController.setCurrentPane(urlSearchParams.get('settings') as PreferenceId)
}
break
case ApplicationEvent.SyncStatusChanged:
this.syncStatusController.update(this.application.sync.getSyncStatus())