diff --git a/__tests__/lib/string.test.ts b/__tests__/lib/string.test.ts
index 78478a26d4..7e11ce6219 100644
--- a/__tests__/lib/string.test.ts
+++ b/__tests__/lib/string.test.ts
@@ -1,6 +1,11 @@
import {RichText} from '@atproto/api'
import {parseEmbedPlayerFromUrl} from 'lib/strings/embed-player'
+import {
+ createStarterPackGooglePlayUri,
+ createStarterPackLinkFromAndroidReferrer,
+ parseStarterPackHttpUri,
+} from 'lib/strings/starter-pack'
import {cleanError} from '../../src/lib/strings/errors'
import {createFullHandle, makeValidHandle} from '../../src/lib/strings/handles'
import {enforceLen} from '../../src/lib/strings/helpers'
@@ -870,3 +875,78 @@ describe('parseEmbedPlayerFromUrl', () => {
}
})
})
+
+describe('createStarterPackLinkFromAndroidReferrer', () => {
+ const inputs = [
+ 'utm_source=bluesky&utm_medium=starterpack&utm_content=starterpack-haileyok.com-rkey',
+ 'utm_source=bluesky&utm_content=starterpack-haileyok.com-rkey&utm_medium=starterpack',
+ 'utm_source=bluesky&utm_content=starterpack-haileyok.com-rkey',
+ 'utm_content=starterpack-haileyok.com-rkey',
+ 'utm_source=redsea&utm_content=starterpack-haileyok.com-rkey',
+ 'utm_source=bluesky&utm_content=starterpack-haileyok.com',
+ 'utm_source=bluesky&utm_content=starterpack',
+ 'utm_source=bluesky&utm_content=nope',
+ 'utm_source=bluesky',
+ 'utm_content=starterpack-haileyok.com-rkey',
+ ]
+ const outputs = [
+ 'https://bsky.app/start/haileyok.com/rkey',
+ 'https://bsky.app/start/haileyok.com/rkey',
+ 'https://bsky.app/start/haileyok.com/rkey',
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ]
+
+ it('returns a starter pack link when input is valid', () => {
+ for (let i = 0; i < inputs.length; i++) {
+ const result = createStarterPackLinkFromAndroidReferrer(inputs[i])
+ expect(result).toEqual(outputs[i])
+ }
+ })
+})
+
+describe('parseStarterPackHttpUri', () => {
+ const inputs = [
+ 'https://bsky.app/start/haileyok.com/rkey',
+ 'https://bsky.app/start/haileyok.com/ilovetesting',
+ 'https://bsky.app/start/testlover9000.com/rkey',
+ 'https://bsky.app/start/testlover9000.com',
+ 'https://bsky.app/start/testlover9000.com/rkey/other',
+ 'https://bsky.app/start',
+ ]
+ const outputs = [
+ {name: 'haileyok.com', rkey: 'rkey'},
+ {name: 'haileyok.com', rkey: 'ilovetesting'},
+ {name: 'testlover9000.com', rkey: 'rkey'},
+ null,
+ null,
+ null,
+ ]
+
+ it('returns the correct name and rkey when input is valid', () => {
+ for (let i = 0; i < inputs.length; i++) {
+ const result = parseStarterPackHttpUri(inputs[i])
+ expect(result).toEqual(outputs[i])
+ }
+ })
+})
+
+describe('createStarterPackGooglePlayUri', () => {
+ const base =
+ 'https://play.google.com/store/apps/details?id=xyz.blueskyweb.app&referrer=utm_source%3Dbluesky%26utm_medium%3Dstarterpack%26utm_content%3Dstarterpack-'
+
+ const inputs = [['name', 'rkey'], ['name'], []]
+ const outputs = [base + 'name-rkey', null, null]
+
+ it('returns valid google play uri when input is valid', () => {
+ for (let i = 0; i < inputs.length; i++) {
+ const result = createStarterPackGooglePlayUri(inputs[i][0], inputs[i][1])
+ expect(result).toEqual(outputs[i])
+ }
+ })
+})
diff --git a/src/components/hooks/useStarterPackEntry.native.ts b/src/components/hooks/useStarterPackEntry.native.ts
index f7a5c55b72..44299dafd2 100644
--- a/src/components/hooks/useStarterPackEntry.native.ts
+++ b/src/components/hooks/useStarterPackEntry.native.ts
@@ -1,6 +1,6 @@
import React from 'react'
-import {makeStarterPackLink} from 'lib/routes/links'
+import {createStarterPackLinkFromAndroidReferrer} from 'lib/strings/starter-pack'
import {isAndroid} from 'platform/detection'
import {useSetCurrentStarterPack} from 'state/preferences/starter-pack'
import {useUsedStarterPacks} from 'state/preferences/used-starter-packs'
@@ -24,14 +24,7 @@ export function useStarterPackEntry() {
const res = await GooglePlayReferrer.getReferrerInfoAsync()
if (res && res.installReferrer) {
- const parts = res.installReferrer.split('&')
- const starterPackSource = parts
- .find(part => part.startsWith('utm_content='))
- ?.split('=')[1]
- const sourceParts = starterPackSource?.split('-')
- if (sourceParts?.length === 3 && sourceParts[0] === 'starterpack') {
- uri = makeStarterPackLink(sourceParts[1], sourceParts[2])
- }
+ uri = createStarterPackLinkFromAndroidReferrer(res.installReferrer)
}
} else {
uri = await SwissArmyKnife.getStringValueAsync('starterPackUri', true)
diff --git a/src/lib/strings/starter-pack.ts b/src/lib/strings/starter-pack.ts
new file mode 100644
index 0000000000..36f6c7802d
--- /dev/null
+++ b/src/lib/strings/starter-pack.ts
@@ -0,0 +1,54 @@
+import {makeStarterPackLink} from 'lib/routes/links'
+
+export function createStarterPackLinkFromAndroidReferrer(
+ referrerQueryString: string,
+): string | null {
+ try {
+ // The referrer string is just some URL parameters, so lets add them to a fake URL
+ const url = new URL('http://throwaway.com/?' + referrerQueryString)
+ const utmContent = url.searchParams.get('utm_content')
+ const utmSource = url.searchParams.get('utm_source')
+
+ if (!utmContent) return null
+ if (utmSource !== 'bluesky') return null
+
+ // This should be a string like `starterpack-haileyok.com-rkey`
+ const contentParts = utmContent.split('-')
+
+ if (contentParts[0] !== 'starterpack') return null
+ if (contentParts.length !== 3) return null
+
+ return makeStarterPackLink(contentParts[1], contentParts[2])
+ } catch (e) {
+ return null
+ }
+}
+
+export function parseStarterPackHttpUri(uri: string): {
+ name?: string
+ rkey?: string
+} | null {
+ try {
+ const url = new URL(uri)
+ const parts = url.pathname.split('/')
+ const name = parts[2]
+ const rkey = parts[3]
+
+ if (parts.length !== 4) return null
+ if (!name || !rkey) return null
+ return {
+ name,
+ rkey,
+ }
+ } catch (e) {
+ return null
+ }
+}
+
+export function createStarterPackGooglePlayUri(
+ name: string,
+ rkey: string,
+): string | null {
+ if (!name || !rkey) return null
+ return `https://play.google.com/store/apps/details?id=xyz.blueskyweb.app&referrer=utm_source%3Dbluesky%26utm_medium%3Dstarterpack%26utm_content%3Dstarterpack-${name}-${rkey}`
+}
diff --git a/src/screens/StarterPack/StarterPackLandingScreen.tsx b/src/screens/StarterPack/StarterPackLandingScreen.tsx
index 373393ca3c..64508a3e30 100644
--- a/src/screens/StarterPack/StarterPackLandingScreen.tsx
+++ b/src/screens/StarterPack/StarterPackLandingScreen.tsx
@@ -7,6 +7,10 @@ import {useLingui} from '@lingui/react'
import {isAndroidWeb} from 'lib/browser'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {
+ createStarterPackGooglePlayUri,
+ parseStarterPackHttpUri,
+} from 'lib/strings/starter-pack'
import {isWeb} from 'platform/detection'
import {
useCurrentStarterPack,
@@ -41,27 +45,31 @@ function postAppClipMessage(message: AppClipMessage) {
window.webkit.messageHandlers.onMessage.postMessage(JSON.stringify(message))
}
-function parseStarterPackHttpUri(uri: string): {name?: string; rkey?: string} {
- try {
- const parsed = new URL(uri)
- const [_, _path, name, rkey] = parsed.pathname.split('/')
- return {
- name,
- rkey,
- }
- } catch (e) {
- return {}
- }
-}
-
-function createGooglePlayLink(name: string, rkey: string) {
- return `https://play.google.com/store/apps/details?id=xyz.blueskyweb.app&referrer=utm_source%3Dbluesky%26utm_medium%3Dstarterpack%26utm_content%3Dstarterpack-${name}-${rkey}`
-}
-
export function LandingScreen({
setScreenState,
}: {
setScreenState: (state: LoggedOutScreenState) => void
+}) {
+ const currentStarterPack = useCurrentStarterPack()
+ const parsed = parseStarterPackHttpUri(currentStarterPack?.uri || '')
+
+ React.useEffect(() => {
+ if (!parsed) {
+ setScreenState(LoggedOutScreenState.S_LoginOrCreateAccount)
+ }
+ }, [parsed, setScreenState])
+
+ if (parsed) {
+ return null
+ }
+
+ return
+}
+
+export function LandingScreenInner({
+ setScreenState,
+}: {
+ setScreenState: (state: LoggedOutScreenState) => void
}) {
const currentStarterPack = useCurrentStarterPack()
const {name, rkey} =
@@ -98,14 +106,14 @@ export function LandingScreen({
}
return (
-
)
}
-function LandingScreenInner({
+function LandingScreenLoaded({
starterPack,
setScreenState,
}: {
@@ -326,7 +334,13 @@ function LandingScreenInner({
const rkey = new AtUri(starterPack.uri).rkey
if (!rkey) return
- window.location.href = createGooglePlayLink(creator.handle, rkey)
+ const googlePlayUri = createStarterPackGooglePlayUri(
+ creator.handle,
+ rkey,
+ )
+ if (!googlePlayUri) return
+
+ window.location.href = googlePlayUri
}}
/>