Skip to content

Commit

Permalink
Display prompt after a number of visits
Browse files Browse the repository at this point in the history
  • Loading branch information
rwngallego committed Jun 29, 2021
1 parent d9af6ae commit 96b5973
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 8 deletions.
24 changes: 23 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ const PerfectyPush = (() => {

await ServiceInstaller.removeConflicts()

if (!hasMinimumVisits()) {
Logger.info('Do not show yet. Required visits to display the prompt: ' + Options.visitsToDisplayPrompt)
return true
}

if (Options.askPermissionsDirectly) {
await askPermissionsDirectly()
} else {
Expand All @@ -54,6 +59,23 @@ const PerfectyPush = (() => {
return (Features.isSupported() && Options.enabled)
}

/**
* Returns if the minimum number of visits has been reached.
* In case the permissions have already been asked, it will always be true,
* otherwise it will track the number of visits in the Local Storage
* @returns {boolean} true if the visitsToDisplayPrompt is reached
*/
const hasMinimumVisits = () => {
if (Permission.askedAlready()) {
return true
}

const visits = Storage.totalVisits() + 1
Storage.setTotalVisits(visits)

return visits >= Options.visitsToDisplayPrompt
}

const drawHtmlControls = () => {
Logger.info('Drawing controls')

Expand All @@ -62,7 +84,7 @@ const PerfectyPush = (() => {
}

const askPermissionsDirectly = async () => {
if (!Permission.hasNeverAsked()) {
if (Permission.askedAlready()) {
// if we already have asked for permissions, we don't ask again
return true
}
Expand Down
21 changes: 18 additions & 3 deletions src/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jest.mock('./lib/push_api/permission', () => ({
__esModule: true,
default: {
isGranted: jest.fn(() => true),
hasNeverAsked: jest.fn(() => true),
askedAlready: jest.fn(() => false),
askIfNotDenied: jest.fn(() => true)
}
}))
Expand All @@ -29,10 +29,11 @@ jest.mock('./controls/dialog')
jest.mock('./controls/settings')

let askPermissionsDirectlySpy
let visitsToDisplayPromptSpy
describe('when the app is started', () => {
beforeEach(() => {
Permission.isGranted.mockClear()
Permission.hasNeverAsked.mockClear()
Permission.askedAlready.mockClear()
Permission.askIfNotDenied.mockClear()
Features.isSupported.mockClear()
Registration.check.mockClear()
Expand All @@ -46,6 +47,8 @@ describe('when the app is started', () => {
Options.enabled = true
askPermissionsDirectlySpy = jest.spyOn(Options, 'askPermissionsDirectly', 'get')
askPermissionsDirectlySpy.mockImplementation(() => false)
visitsToDisplayPromptSpy = jest.spyOn(Options, 'visitsToDisplayPrompt', 'get')
visitsToDisplayPromptSpy.mockImplementation(() => 0)
})

it('works with supported features and enabled', async () => {
Expand All @@ -66,6 +69,16 @@ describe('when the app is started', () => {
expect(Features.isSupported).toHaveBeenCalledTimes(1)
})

it('skips if visitsToDisplayPrompt not reached', async () => {
visitsToDisplayPromptSpy.mockImplementationOnce(() => 100)
const result = await PerfectyPush.start()

expect(result).toEqual(true)
expect(Permission.askIfNotDenied).toHaveBeenCalledTimes(0)
expect(DialogControl.draw).toHaveBeenCalledTimes(0)
expect(SettingsControl.draw).toHaveBeenCalledTimes(0)
})

it('draws the controls', async () => {
const result = await PerfectyPush.start()

Expand All @@ -85,7 +98,9 @@ describe('when the app is started', () => {

it('skips asking if permissions already granted', async () => {
askPermissionsDirectlySpy.mockImplementationOnce(() => true)
Permission.hasNeverAsked.mockImplementationOnce(() => false)
// the first one is for the shouldDisplayPrompt check, the second for the permission granted
Permission.askedAlready.mockImplementationOnce(() => true)
Permission.askedAlready.mockImplementationOnce(() => true)
const result = await PerfectyPush.start()

expect(result).toEqual(true)
Expand Down
6 changes: 5 additions & 1 deletion src/lib/push_api/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const Options = (() => {
let hideBellAfterSubscribe = false
let askPermissionsDirectly = false
let promptIconUrl = ''
let visitsToDisplayPrompt = 0

const init = (custom) => {
custom = typeof custom === 'undefined' ? {} : custom
Expand All @@ -45,6 +46,7 @@ const Options = (() => {
Options.hideBellAfterSubscribe = custom.hideBellAfterSubscribe
Options.askPermissionsDirectly = custom.askPermissionsDirectly
Options.promptIconUrl = custom.promptIconUrl
Options.visitsToDisplayPrompt = custom.visitsToDisplayPrompt
}

function getValue (customValue, defaultValue) {
Expand Down Expand Up @@ -101,7 +103,9 @@ const Options = (() => {
get askPermissionsDirectly () { return askPermissionsDirectly },
set askPermissionsDirectly (v) { askPermissionsDirectly = getValue(v, askPermissionsDirectly) },
get promptIconUrl () { return promptIconUrl },
set promptIconUrl (v) { promptIconUrl = getValue(v, promptIconUrl) }
set promptIconUrl (v) { promptIconUrl = getValue(v, promptIconUrl) },
get visitsToDisplayPrompt () { return visitsToDisplayPrompt },
set visitsToDisplayPrompt (v) { visitsToDisplayPrompt = getValue(v, visitsToDisplayPrompt) }
}
})()

Expand Down
4 changes: 3 additions & 1 deletion src/lib/push_api/options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const defaultOptions = {
loggerVerbose: false,
hideBellAfterSubscribe: false,
askPermissionsDirectly: false,
unregisterConflictsExpression: ''
unregisterConflictsExpression: '',
visitsToDisplayPrompt: 0
}

describe('options', () => {
Expand Down Expand Up @@ -75,6 +76,7 @@ describe('options', () => {
expect(value.hideBellAfterSubscribe).toEqual(expected.hideBellAfterSubscribe)
expect(value.askPermissionsDirectly).toEqual(expected.askPermissionsDirectly)
expect(value.unregisterConflictsExpression).toEqual(expected.unregisterConflictsExpression)
expect(value.visitsToDisplayPrompt).toEqual(expected.visitsToDisplayPrompt)
return true
}
})
5 changes: 4 additions & 1 deletion src/lib/push_api/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ const Permission = (() => {
return Notification.permission === 'default'
}

const askedAlready = () => !hasNeverAsked()

return {
askIfNotDenied,
isGranted,
isDenied,
hasNeverAsked
hasNeverAsked,
askedAlready
}
})()

Expand Down
17 changes: 16 additions & 1 deletion src/lib/push_api/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const Storage = (() => {
const hasAskedNotificationsKey = 'perfecty_asked_notifications'
const shouldRegisterUserKey = 'perfecty_register_again'
const optedOuKey = 'perfecty_opted_out'
const totalVisitsKey = 'perfecty_total_visits'

const setUserId = (id) => {
setItem(userIdKey, id)
Expand Down Expand Up @@ -42,6 +43,18 @@ const Storage = (() => {
return value === 'yes'
}

const setTotalVisits = (visits) => {
setItem(totalVisitsKey, visits.toString())
}

const totalVisits = () => {
const value = getItem(totalVisitsKey)
if (value === null) {
return 0
} else {
return parseInt(value)
}
}
const getItem = (key) => {
return localStorage.getItem(key)
}
Expand All @@ -62,7 +75,9 @@ const Storage = (() => {
setShouldRegisterUser,
shouldRegisterUser,
setOptedOut,
optedOut
optedOut,
setTotalVisits,
totalVisits
}
})()

Expand Down

0 comments on commit 96b5973

Please sign in to comment.