Skip to content

Instantly share code, notes, and snippets.

@dorianmariecom
Created October 29, 2021 21:19
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dorianmariecom/e8422538a4eefcc99aa92d91b147be12 to your computer and use it in GitHub Desktop.
Save dorianmariecom/e8422538a4eefcc99aa92d91b147be12 to your computer and use it in GitHub Desktop.
/* global __DEV__ */
import React, { useState, useEffect, useRef } from "react"
import {
facebookAppId,
facebookDisplayName,
iosOneSignalAppId,
androidOneSignalAppId,
sentryDsn,
} from "./app.json"
import { version } from "./package.json"
import { View, Linking, StatusBar, Platform } from "react-native"
import { WebView } from "react-native-webview"
import * as Facebook from "expo-facebook"
import * as GoogleSignIn from "expo-google-sign-in"
import extractHostname from "./extractHostname"
import { useBackHandler } from "@react-native-community/hooks"
import OneSignal from "react-native-onesignal"
import * as Sentry from "@sentry/react-native"
import { getStatusBarHeight } from "react-native-status-bar-height"
const ONE_SIGNAL_APP_ID =
Platform.OS === "ios" ? iosOneSignalAppId : androidOneSignalAppId
const BASE_PROTOCOL = "https"
const BASE_DEVELOPMENT_DOMAIN = "dev-socializus.dorianmarie.fr"
const BASE_PRODUCTION_DOMAIN = "socializus.app"
const BASE_DOMAIN = __DEV__ ? BASE_DEVELOPMENT_DOMAIN : BASE_PRODUCTION_DOMAIN
const BASE_URL = `${BASE_PROTOCOL}://${BASE_DOMAIN}`
const WHITELISTED_DOMAINS = [
BASE_DOMAIN,
"appleid.apple.com",
"js.stripe.com",
"m.stripe.network",
]
const STATUS_BAR_HEIGHT = Platform.OS === "ios" ? getStatusBarHeight() : 0
const INJECTED_JAVASCRIPT = `
window.socializus = window.socializus || {}
window.socializus.version = "${version}"
window.socializus.statusBarHeight = ${STATUS_BAR_HEIGHT}
true
`
Sentry.init({
dsn: sentryDsn,
release: version,
integrations: [
new Sentry.ReactNativeTracing({
tracingOrigins: [
"localhost",
BASE_DEVELOPMENT_DOMAIN,
BASE_PRODUCTION_DOMAIN,
],
}),
],
})
const App = () => {
const webView = useRef()
const [uri, setUri] = useState(BASE_URL)
const handleFacebookLogin = async () => {
try {
await Facebook.initializeAsync({
appId: facebookAppId,
appName: facebookDisplayName,
})
const { token } = await Facebook.logInWithReadPermissionsAsync({
permissions: ["public_profile", "email"],
})
if (token) {
const encodedToken = encodeURIComponent(token)
setUri(`${BASE_URL}/auth/facebook/native?token=${encodedToken}`)
} else {
}
} catch {}
}
const handleGoogleLogin = async () => {
try {
await GoogleSignIn.initAsync({ clientId: undefined })
await GoogleSignIn.askForPlayServicesAsync()
const { type, user } = await GoogleSignIn.signInAsync()
if (type === "success") {
const encodedToken = encodeURIComponent(user.auth.accessToken)
setUri(`${BASE_URL}/auth/google_oauth2/native?token=${encodedToken}`)
}
} catch {}
}
const handleOnMessage = (event) => {
try {
const payload = JSON.parse(event.nativeEvent.data)
if (payload.name === "facebook_login") {
handleFacebookLogin()
} else if (payload.name === "google_login") {
handleGoogleLogin()
} else if (payload.name === "apple_login") {
setUri(`${BASE_URL}/auth/apple?t=${Date.now()}`) // to force uri change
} else if (payload.name === "user_id") {
OneSignal.setExternalUserId(`${payload.user_id}`, payload.onesignal_id)
}
} catch {}
}
const handleOnShouldStartLoadWithRequest = (event) => {
if (!event) {
return false
}
const hostname = extractHostname(event.url)
if (event.url === "about:blank") {
return false
} else if (event.url && !WHITELISTED_DOMAINS.includes(hostname)) {
Linking.openURL(event.url)
return false
} else {
return true
}
}
const handleUrl = ({ url }) => {
if (url) {
setUri(url.replace("socializus://", `${BASE_PROTOCOL}://`))
}
}
// https://documentation.onesignal.com/docs/react-native-sdk
const setupOneSignal = () => {
OneSignal.setAppId(ONE_SIGNAL_APP_ID)
OneSignal.setLogLevel(6, 0) // logLevel VERBOSE, visualLevel NONE
OneSignal.setRequiresUserPrivacyConsent(false)
OneSignal.promptForPushNotificationsWithUserResponse(() => {})
OneSignal.setNotificationOpenedHandler((event) => {
handleUrl({ url: event.notification.launchURL })
})
}
const setupDeepLinking = async () => {
const url = await Linking.getInitialURL()
handleUrl({ url })
}
useBackHandler(() => {
webView.current.goBack()
return true
})
useEffect(() => {
const listener = Linking.addEventListener("url", handleUrl)
setupOneSignal()
setupDeepLinking()
return () => {
listener.remove()
}
}, [])
return (
<View style={{ flex: 1 }}>
<StatusBar backgroundColor="#0381FF" barStyle="dark-content" />
<WebView
ref={webView}
source={{ uri: uri }}
onMessage={handleOnMessage}
javaScriptEnabled
onShouldStartLoadWithRequest={handleOnShouldStartLoadWithRequest}
injectedJavaScriptBeforeContentLoaded={INJECTED_JAVASCRIPT}
/>
</View>
)
}
export default App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment