Skip to content

Commit

Permalink
unify special page messaging (#957)
Browse files Browse the repository at this point in the history
https://app.asana.com/0/1201614831475344/1207244302971195/f

### TL;DR

Updated messaging setup in special pages to use a shared `createSpecialPageMessaging` function.

### What changed?

- Refactored messaging setup in multiple special pages
- Created a shared createSpecialPageMessaging function
- NOTE: no functionality is changed in this PR.

### How to test?

- all changed pages have integration tests to verify

### Why make this change?

Centralized messaging setup for consistency and reusability

---
  • Loading branch information
shakyShane committed May 13, 2024
1 parent 900c93f commit d230c53
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 272 deletions.
20 changes: 12 additions & 8 deletions packages/special-pages/pages/duckplayer/src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
*/
import {
callWithRetry,
createDuckPlayerPageMessaging,
DuckPlayerPageMessages,
UserValues
} from './messages'
import { html } from '../../../../../../src/dom-utils'
import { initStorage } from './storage'
import { createYoutubeURLForError } from './utils'
import { createSpecialPageMessaging } from '../../../../shared/create-special-page-messaging'

// for docs
export { DuckPlayerPageMessages, UserValues }
Expand Down Expand Up @@ -411,12 +411,9 @@ const Comms = {
*
* `window.postMessage({ alwaysOpenSetting: false })`
*
* @param {object} opts
* @param {ImportMeta['env']} opts.env
* @param {ImportMeta['injectName']} opts.injectName
* @param {DuckPlayerPageMessages} messaging
*/
init: async (opts) => {
const messaging = createDuckPlayerPageMessaging(opts)
init: async (messaging) => {
// try to make communication with the native side.
const result = await callWithRetry(() => {
return messaging.getUserValues()
Expand Down Expand Up @@ -802,10 +799,17 @@ document.addEventListener('DOMContentLoaded', async () => {
Setting.init({
settingsUrl: settingsUrl(import.meta.injectName)
})
await Comms.init({

const messaging = createSpecialPageMessaging({
injectName: import.meta.injectName,
env: import.meta.env
env: import.meta.env,
pageName: 'duckPlayerPage'
})

const page = new DuckPlayerPageMessages(messaging, import.meta.injectName)

await Comms.init(page)

if (!Comms.messaging) {
console.warn('cannot continue as messaging was not resolved')
return
Expand Down
78 changes: 9 additions & 69 deletions packages/special-pages/pages/duckplayer/src/js/messages.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
import {
Messaging,
MessagingContext,
TestTransportConfig,
WebkitMessagingConfig,
WindowsMessagingConfig
} from '@duckduckgo/messaging'

/**
* Notifications or requests that the Duck Player Page will
* send to the native side
*/
export class DuckPlayerPageMessages {
/**
* @param {import("@duckduckgo/messaging").Messaging} messaging
* @param {ImportMeta["injectName"]} injectName
* @internal
*/
constructor (messaging) {
constructor (messaging, injectName) {
/**
* @internal
*/
this.messaging = messaging
this.injectName = injectName
}

/**
Expand All @@ -36,6 +30,12 @@ export class DuckPlayerPageMessages {
* @return {Promise<UserValues>}
*/
getUserValues () {
if (this.injectName === 'integration') {
return Promise.resolve(new UserValues({
overlayInteracted: false,
privatePlayerMode: { alwaysAsk: {} }
}))
}
return this.messaging.request('getUserValues')
}

Expand Down Expand Up @@ -100,66 +100,6 @@ export class UserValues {
}
}

/**
* @param {object} opts
* @param {ImportMeta['env']} opts.env
* @param {ImportMeta['injectName']} opts.injectName
*/
export function createDuckPlayerPageMessaging (opts) {
const messageContext = new MessagingContext({
context: 'specialPages',
featureName: 'duckPlayerPage',
env: opts.env
})
if (opts.injectName === 'windows') {
const opts = new WindowsMessagingConfig({
methods: {
// @ts-expect-error - not in @types/chrome
postMessage: window.chrome.webview.postMessage,
// @ts-expect-error - not in @types/chrome
addEventListener: window.chrome.webview.addEventListener,
// @ts-expect-error - not in @types/chrome
removeEventListener: window.chrome.webview.removeEventListener
}
})
const messaging = new Messaging(messageContext, opts)
return new DuckPlayerPageMessages(messaging)
} else if (opts.injectName === 'apple') {
const opts = new WebkitMessagingConfig({
hasModernWebkitAPI: true,
secret: '',
webkitMessageHandlerNames: ['specialPages']
})
const messaging = new Messaging(messageContext, opts)
return new DuckPlayerPageMessages(messaging)
} else if (opts.injectName === 'integration') {
const config = new TestTransportConfig({
notify (msg) {
console.log(msg)
},
request: (msg) => {
console.log(msg)
if (msg.method === 'getUserValues') {
return Promise.resolve(new UserValues({
overlayInteracted: false,
privatePlayerMode: { alwaysAsk: {} }
}))
}
return Promise.resolve(null)
},
subscribe (msg) {
console.log(msg)
return () => {
console.log('teardown')
}
}
})
const messaging = new Messaging(messageContext, config)
return new DuckPlayerPageMessages(messaging)
}
throw new Error('unreachable - platform not supported')
}

/**
* This will return either { value: awaited value },
* { error: error message }
Expand Down
30 changes: 6 additions & 24 deletions packages/special-pages/pages/example/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,17 @@
* [[include:packages/special-pages/pages/example/readme.md]]
*/

import { Messaging, MessagingContext, WindowsMessagingConfig } from '../../../../messaging/index.js'
import { ExamplePageMessages } from './messages.js'
import { Pixel, OverlayPixel, PlayPixel, PlayDoNotUse } from './pixels.js'
import { createSpecialPageMessaging } from '../../../shared/create-special-page-messaging'

/**
* An example of initialising Windows messaging
*/
const config = new WindowsMessagingConfig({
methods: {
postMessage: (...args) => {
console.log('postMessage', args)
},
addEventListener: (...args) => {
console.log('addEventListener', args)
},
removeEventListener: (...args) => {
console.log('removeEventListener', args)
}
}
})

const messagingContext = new MessagingContext({
context: 'specialPages',
featureName: 'examplePage',
env: 'development'
const messaging = createSpecialPageMessaging({
injectName: import.meta.injectName,
env: import.meta.env,
pageName: 'examplePage'
})

const messages = new Messaging(messagingContext, config)
console.log(messages)
console.log(messaging)

const h2 = document.createElement('h2')
h2.innerText = 'This is an appended element'
Expand Down
16 changes: 10 additions & 6 deletions packages/special-pages/pages/onboarding/app/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
createOnboardingMessaging
OnboardingMessages
} from './messages'
import { render, h } from 'preact'
import './styles/global.css' // global styles
Expand All @@ -9,15 +9,19 @@ import { Components } from './Components'
import { SettingsProvider, UpdateSettings } from './settings'
import { PAGE_IDS, PLATFORMS } from './types'
import { stepDefinitions } from './data'
import { createSpecialPageMessaging } from '../../../shared/create-special-page-messaging'

// share this in the app, it's an instance of `OnboardingMessages` where all your native comms should be
const messaging = createOnboardingMessaging({
const messaging = createSpecialPageMessaging({
injectName: import.meta.injectName,
env: import.meta.env
env: import.meta.env,
pageName: 'onboarding'
})

const onboarding = new OnboardingMessages(messaging, import.meta.injectName)

async function init () {
const init = await messaging.init()
const init = await onboarding.init()

for (const [key, value] of Object.entries(init?.stepDefinitions || {})) {
if (PAGE_IDS.includes(/** @type {any} */(key))) {
Expand Down Expand Up @@ -60,7 +64,7 @@ async function init () {
>
<UpdateSettings search={window.location.search} />
<GlobalProvider
messaging={messaging}
messaging={onboarding}
stepDefinitions={stepDefinitions}
firstPage={/** @type {import('./types').Step['id']} */(first)}>
<App>
Expand All @@ -82,5 +86,5 @@ async function init () {
init().catch(e => {
console.error(e)
const msg = typeof e?.message === 'string' ? e.message : 'unknown init error'
messaging.reportInitException({ message: msg })
onboarding.reportInitException({ message: msg })
})

0 comments on commit d230c53

Please sign in to comment.