diff options
author | Hailey <me@haileyok.com> | 2024-07-11 18:43:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-11 18:43:10 -0700 |
commit | 8b121af2e438ca77cc5f5b1715516107c18aff6f (patch) | |
tree | c7f1a28b63226c79e07aef4d2e88898358a62ec6 /modules | |
parent | 83e8522e0a89be28b1733f4c50dbd4379d98d03b (diff) | |
download | voidsky-8b121af2e438ca77cc5f5b1715516107c18aff6f.tar.zst |
referrers for all platforms (#4514)
Diffstat (limited to 'modules')
6 files changed, 138 insertions, 11 deletions
diff --git a/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/referrer/ExpoBlueskyReferrerModule.kt b/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/referrer/ExpoBlueskyReferrerModule.kt index ac6ed90b8..bac555233 100644 --- a/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/referrer/ExpoBlueskyReferrerModule.kt +++ b/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/referrer/ExpoBlueskyReferrerModule.kt @@ -1,5 +1,8 @@ package expo.modules.blueskyswissarmy.referrer +import android.content.Intent +import android.net.Uri +import android.os.Build import android.util.Log import com.android.installreferrer.api.InstallReferrerClient import com.android.installreferrer.api.InstallReferrerStateListener @@ -8,10 +11,53 @@ import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition class ExpoBlueskyReferrerModule : Module() { + private var intent: Intent? = null + private var activityReferrer: Uri? = null + override fun definition() = ModuleDefinition { Name("ExpoBlueskyReferrer") + OnNewIntent { + intent = it + activityReferrer = appContext.currentActivity?.referrer + } + + AsyncFunction("getReferrerInfoAsync") { + val intentReferrer = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + intent?.getParcelableExtra(Intent.EXTRA_REFERRER, Uri::class.java) + } else { + intent?.getParcelableExtra(Intent.EXTRA_REFERRER) + } + + // Some apps explicitly set a referrer, like Chrome. In these cases, we prefer this since + // it's the actual website that the user came from rather than the app. + if (intentReferrer is Uri) { + val res = + mapOf( + "referrer" to intentReferrer.toString(), + "hostname" to intentReferrer.host, + ) + intent = null + return@AsyncFunction res + } + + // In all other cases, we'll just record the app that sent the intent. + if (activityReferrer != null) { + // referrer could become null here. `.toString()` though can be called on null + val res = + mapOf( + "referrer" to activityReferrer.toString(), + "hostname" to (activityReferrer?.host ?: ""), + ) + activityReferrer = null + return@AsyncFunction res + } + + return@AsyncFunction null + } + AsyncFunction("getGooglePlayReferrerInfoAsync") { promise: Promise -> val referrerClient = InstallReferrerClient.newBuilder(appContext.reactContext).build() referrerClient.startConnection( diff --git a/modules/expo-bluesky-swiss-army/src/Referrer/index.android.ts b/modules/expo-bluesky-swiss-army/src/Referrer/index.android.ts index 06dfd2d09..ec2bcb57d 100644 --- a/modules/expo-bluesky-swiss-army/src/Referrer/index.android.ts +++ b/modules/expo-bluesky-swiss-army/src/Referrer/index.android.ts @@ -1,9 +1,13 @@ import {requireNativeModule} from 'expo' -import {GooglePlayReferrerInfo} from './types' +import {GooglePlayReferrerInfo, ReferrerInfo} from './types' export const NativeModule = requireNativeModule('ExpoBlueskyReferrer') -export function getGooglePlayReferrerInfoAsync(): Promise<GooglePlayReferrerInfo> { +export function getGooglePlayReferrerInfoAsync(): Promise<GooglePlayReferrerInfo | null> { return NativeModule.getGooglePlayReferrerInfoAsync() } + +export function getReferrerInfoAsync(): Promise<ReferrerInfo | null> { + return NativeModule.getReferrerInfoAsync() +} diff --git a/modules/expo-bluesky-swiss-army/src/Referrer/index.ios.ts b/modules/expo-bluesky-swiss-army/src/Referrer/index.ios.ts new file mode 100644 index 000000000..2bf1497a0 --- /dev/null +++ b/modules/expo-bluesky-swiss-army/src/Referrer/index.ios.ts @@ -0,0 +1,37 @@ +import {SharedPrefs} from '../../index' +import {NotImplementedError} from '../NotImplemented' +import {GooglePlayReferrerInfo, ReferrerInfo} from './types' + +export function getGooglePlayReferrerInfoAsync(): Promise<GooglePlayReferrerInfo> { + throw new NotImplementedError() +} + +export function getReferrerInfoAsync(): Promise<ReferrerInfo | null> { + const referrer = SharedPrefs.getString('referrer') + if (referrer) { + SharedPrefs.removeValue('referrer') + try { + const url = new URL(referrer) + return { + referrer, + hostname: url.hostname, + } + } catch (e) { + return { + referrer, + hostname: undefined, + } + } + } + + const referrerApp = SharedPrefs.getString('referrerApp') + if (referrerApp) { + SharedPrefs.removeValue('referrerApp') + return { + referrer: referrerApp, + hostname: referrerApp, + } + } + + return null +} diff --git a/modules/expo-bluesky-swiss-army/src/Referrer/index.ts b/modules/expo-bluesky-swiss-army/src/Referrer/index.ts index 255398552..a60f7b6db 100644 --- a/modules/expo-bluesky-swiss-army/src/Referrer/index.ts +++ b/modules/expo-bluesky-swiss-army/src/Referrer/index.ts @@ -1,7 +1,10 @@ import {NotImplementedError} from '../NotImplemented' -import {GooglePlayReferrerInfo} from './types' +import {GooglePlayReferrerInfo, ReferrerInfo} from './types' -// @ts-ignore throws export function getGooglePlayReferrerInfoAsync(): Promise<GooglePlayReferrerInfo> { throw new NotImplementedError() } + +export function getReferrerInfoAsync(): Promise<ReferrerInfo | null> { + throw new NotImplementedError() +} diff --git a/modules/expo-bluesky-swiss-army/src/Referrer/index.web.ts b/modules/expo-bluesky-swiss-army/src/Referrer/index.web.ts new file mode 100644 index 000000000..76f03e7c8 --- /dev/null +++ b/modules/expo-bluesky-swiss-army/src/Referrer/index.web.ts @@ -0,0 +1,34 @@ +import {Platform} from 'react-native' + +import {NotImplementedError} from '../NotImplemented' +import {GooglePlayReferrerInfo, ReferrerInfo} from './types' + +export function getGooglePlayReferrerInfoAsync(): Promise<GooglePlayReferrerInfo> { + throw new NotImplementedError() +} + +export function getReferrerInfoAsync(): Promise<ReferrerInfo | null> { + if ( + Platform.OS === 'web' && + // for ssr + typeof document !== 'undefined' && + document != null && + document.referrer + ) { + try { + const url = new URL(document.referrer) + if (url.hostname !== 'bsky.app') { + return { + referrer: url.href, + hostname: url.hostname, + } + } + } catch { + // If something happens to the URL parsing, we don't want to actually cause any problems for the user. Just + // log the error so we might catch it + console.error('Failed to parse referrer URL') + } + } + + return null +} diff --git a/modules/expo-bluesky-swiss-army/src/Referrer/types.ts b/modules/expo-bluesky-swiss-army/src/Referrer/types.ts index 55faaff4d..921e3a692 100644 --- a/modules/expo-bluesky-swiss-army/src/Referrer/types.ts +++ b/modules/expo-bluesky-swiss-army/src/Referrer/types.ts @@ -1,7 +1,10 @@ -export type GooglePlayReferrerInfo = - | { - installReferrer?: string - clickTimestamp?: number - installTimestamp?: number - } - | undefined +export type GooglePlayReferrerInfo = { + installReferrer?: string + clickTimestamp?: number + installTimestamp?: number +} + +export type ReferrerInfo = { + referrer: string + hostname: string +} |