about summary refs log tree commit diff
path: root/src/view/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com')
-rw-r--r--src/view/com/auth/LoggedOut.tsx3
-rw-r--r--src/view/com/auth/SplashScreen.tsx32
-rw-r--r--src/view/com/auth/SplashScreen.web.tsx110
-rw-r--r--src/view/com/auth/withAuthRequired.tsx17
-rw-r--r--src/view/com/util/post-ctrls/PostCtrls.tsx10
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.tsx6
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.web.tsx58
7 files changed, 168 insertions, 68 deletions
diff --git a/src/view/com/auth/LoggedOut.tsx b/src/view/com/auth/LoggedOut.tsx
index 3505e86af..daafa60a3 100644
--- a/src/view/com/auth/LoggedOut.tsx
+++ b/src/view/com/auth/LoggedOut.tsx
@@ -15,7 +15,7 @@ enum ScreenState {
   S_CreateAccount,
 }
 
-export function LoggedOut() {
+export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
   const pal = usePalette('default')
   const setMinimalShellMode = useSetMinimalShellMode()
   const {screen} = useAnalytics()
@@ -31,6 +31,7 @@ export function LoggedOut() {
   if (screenState === ScreenState.S_LoginOrCreateAccount) {
     return (
       <SplashScreen
+        onDismiss={onDismiss}
         onPressSignin={() => setScreenState(ScreenState.S_Login)}
         onPressCreateAccount={() => setScreenState(ScreenState.S_CreateAccount)}
       />
diff --git a/src/view/com/auth/SplashScreen.tsx b/src/view/com/auth/SplashScreen.tsx
index 05e72a2e6..2c968aef4 100644
--- a/src/view/com/auth/SplashScreen.tsx
+++ b/src/view/com/auth/SplashScreen.tsx
@@ -1,5 +1,12 @@
 import React from 'react'
-import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native'
+import {
+  SafeAreaView,
+  StyleSheet,
+  TouchableOpacity,
+  Pressable,
+  View,
+} from 'react-native'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {Text} from 'view/com/util/text/Text'
 import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
 import {s, colors} from 'lib/styles'
@@ -9,9 +16,11 @@ import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
 export const SplashScreen = ({
+  onDismiss,
   onPressSignin,
   onPressCreateAccount,
 }: {
+  onDismiss?: () => void
   onPressSignin: () => void
   onPressCreateAccount: () => void
 }) => {
@@ -20,6 +29,27 @@ export const SplashScreen = ({
 
   return (
     <CenteredView style={[styles.container, pal.view]}>
+      {onDismiss && (
+        <Pressable
+          accessibilityRole="button"
+          style={{
+            position: 'absolute',
+            top: 20,
+            right: 20,
+            padding: 20,
+            zIndex: 100,
+          }}
+          onPress={onDismiss}>
+          <FontAwesomeIcon
+            icon="x"
+            size={24}
+            style={{
+              color: String(pal.text.color),
+            }}
+          />
+        </Pressable>
+      )}
+
       <SafeAreaView testID="noSessionView" style={styles.container}>
         <ErrorBoundary>
           <View style={styles.hero}>
diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx
index f10dc4f98..08cf701da 100644
--- a/src/view/com/auth/SplashScreen.web.tsx
+++ b/src/view/com/auth/SplashScreen.web.tsx
@@ -1,5 +1,6 @@
 import React from 'react'
-import {StyleSheet, TouchableOpacity, View} from 'react-native'
+import {StyleSheet, TouchableOpacity, View, Pressable} from 'react-native'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {Text} from 'view/com/util/text/Text'
 import {TextLink} from '../util/Link'
 import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
@@ -11,9 +12,11 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {Trans} from '@lingui/macro'
 
 export const SplashScreen = ({
+  onDismiss,
   onPressSignin,
   onPressCreateAccount,
 }: {
+  onDismiss?: () => void
   onPressSignin: () => void
   onPressCreateAccount: () => void
 }) => {
@@ -23,47 +26,70 @@ export const SplashScreen = ({
   const isMobileWeb = isWeb && isTabletOrMobile
 
   return (
-    <CenteredView style={[styles.container, pal.view]}>
-      <View
-        testID="noSessionView"
-        style={[
-          styles.containerInner,
-          isMobileWeb && styles.containerInnerMobile,
-          pal.border,
-        ]}>
-        <ErrorBoundary>
-          <Text style={isMobileWeb ? styles.titleMobile : styles.title}>
-            Bluesky
-          </Text>
-          <Text style={isMobileWeb ? styles.subtitleMobile : styles.subtitle}>
-            See what's next
-          </Text>
-          <View testID="signinOrCreateAccount" style={styles.btns}>
-            <TouchableOpacity
-              testID="createAccountButton"
-              style={[styles.btn, {backgroundColor: colors.blue3}]}
-              onPress={onPressCreateAccount}
-              // TODO: web accessibility
-              accessibilityRole="button">
-              <Text style={[s.white, styles.btnLabel]}>
-                Create a new account
-              </Text>
-            </TouchableOpacity>
-            <TouchableOpacity
-              testID="signInButton"
-              style={[styles.btn, pal.btn]}
-              onPress={onPressSignin}
-              // TODO: web accessibility
-              accessibilityRole="button">
-              <Text style={[pal.text, styles.btnLabel]}>
-                <Trans>Sign In</Trans>
-              </Text>
-            </TouchableOpacity>
-          </View>
-        </ErrorBoundary>
-      </View>
-      <Footer styles={styles} />
-    </CenteredView>
+    <>
+      {onDismiss && (
+        <Pressable
+          accessibilityRole="button"
+          style={{
+            position: 'absolute',
+            top: 20,
+            right: 20,
+            padding: 20,
+            zIndex: 100,
+          }}
+          onPress={onDismiss}>
+          <FontAwesomeIcon
+            icon="x"
+            size={24}
+            style={{
+              color: String(pal.text.color),
+            }}
+          />
+        </Pressable>
+      )}
+
+      <CenteredView style={[styles.container, pal.view]}>
+        <View
+          testID="noSessionView"
+          style={[
+            styles.containerInner,
+            isMobileWeb && styles.containerInnerMobile,
+            pal.border,
+          ]}>
+          <ErrorBoundary>
+            <Text style={isMobileWeb ? styles.titleMobile : styles.title}>
+              Bluesky
+            </Text>
+            <Text style={isMobileWeb ? styles.subtitleMobile : styles.subtitle}>
+              See what's next
+            </Text>
+            <View testID="signinOrCreateAccount" style={styles.btns}>
+              <TouchableOpacity
+                testID="createAccountButton"
+                style={[styles.btn, {backgroundColor: colors.blue3}]}
+                onPress={onPressCreateAccount}
+                // TODO: web accessibility
+                accessibilityRole="button">
+                <Text style={[s.white, styles.btnLabel]}>
+                  Create a new account
+                </Text>
+              </TouchableOpacity>
+              <TouchableOpacity
+                testID="signInButton"
+                style={[styles.btn, pal.btn]}
+                onPress={onPressSignin}
+                // TODO: web accessibility
+                accessibilityRole="button">
+                <Text style={[pal.text, styles.btnLabel]}>
+                  <Trans>Sign In</Trans>
+                </Text>
+              </TouchableOpacity>
+            </View>
+          </ErrorBoundary>
+        </View>
+        <Footer styles={styles} />
+      </CenteredView>
+    </>
   )
 }
 
diff --git a/src/view/com/auth/withAuthRequired.tsx b/src/view/com/auth/withAuthRequired.tsx
index 5fd89a8bd..7a9138545 100644
--- a/src/view/com/auth/withAuthRequired.tsx
+++ b/src/view/com/auth/withAuthRequired.tsx
@@ -13,18 +13,33 @@ import {usePalette} from 'lib/hooks/usePalette'
 import {STATUS_PAGE_URL} from 'lib/constants'
 import {useOnboardingState} from '#/state/shell'
 import {useSession} from '#/state/session'
+import {
+  useLoggedOutView,
+  useLoggedOutViewControls,
+} from '#/state/shell/logged-out'
+import {IS_PROD} from '#/env'
 
 export const withAuthRequired = <P extends object>(
   Component: React.ComponentType<P>,
+  options: {
+    isPublic?: boolean // TODO(pwi) need to enable in TF somehow
+  } = {},
 ): React.FC<P> =>
   function AuthRequired(props: P) {
     const {isInitialLoad, hasSession} = useSession()
     const onboardingState = useOnboardingState()
+    const {showLoggedOut} = useLoggedOutView()
+    const {setShowLoggedOut} = useLoggedOutViewControls()
+
     if (isInitialLoad) {
       return <Loading />
     }
     if (!hasSession) {
-      return <LoggedOut />
+      if (showLoggedOut) {
+        return <LoggedOut onDismiss={() => setShowLoggedOut(false)} />
+      } else if (!options?.isPublic || IS_PROD) {
+        return <LoggedOut />
+      }
     }
     if (onboardingState.isActive) {
       return <Onboarding />
diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index 120aecf45..e548c45f7 100644
--- a/src/view/com/util/post-ctrls/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -25,6 +25,7 @@ import {
 } from '#/state/queries/post'
 import {useComposerControls} from '#/state/shell/composer'
 import {Shadow} from '#/state/cache/types'
+import {useRequireAuth} from '#/state/session'
 
 export function PostCtrls({
   big,
@@ -46,6 +47,7 @@ export function PostCtrls({
   const postUnlikeMutation = usePostUnlikeMutation()
   const postRepostMutation = usePostRepostMutation()
   const postUnrepostMutation = usePostUnrepostMutation()
+  const requireAuth = useRequireAuth()
 
   const defaultCtrlColor = React.useMemo(
     () => ({
@@ -107,7 +109,9 @@ export function PostCtrls({
       <TouchableOpacity
         testID="replyBtn"
         style={[styles.ctrl, !big && styles.ctrlPad, {paddingLeft: 0}]}
-        onPress={onPressReply}
+        onPress={() => {
+          requireAuth(() => onPressReply())
+        }}
         accessibilityRole="button"
         accessibilityLabel={`Reply (${post.replyCount} ${
           post.replyCount === 1 ? 'reply' : 'replies'
@@ -135,7 +139,9 @@ export function PostCtrls({
       <TouchableOpacity
         testID="likeBtn"
         style={[styles.ctrl, !big && styles.ctrlPad]}
-        onPress={onPressToggleLike}
+        onPress={() => {
+          requireAuth(() => onPressToggleLike())
+        }}
         accessibilityRole="button"
         accessibilityLabel={`${post.viewer?.like ? 'Unlike' : 'Like'} (${
           post.likeCount
diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx
index 0a7637252..1d34a88ab 100644
--- a/src/view/com/util/post-ctrls/RepostButton.tsx
+++ b/src/view/com/util/post-ctrls/RepostButton.tsx
@@ -7,6 +7,7 @@ import {Text} from '../text/Text'
 import {pluralize} from 'lib/strings/helpers'
 import {HITSLOP_10, HITSLOP_20} from 'lib/constants'
 import {useModalControls} from '#/state/modals'
+import {useRequireAuth} from '#/state/session'
 
 interface Props {
   isReposted: boolean
@@ -25,6 +26,7 @@ export const RepostButton = ({
 }: Props) => {
   const theme = useTheme()
   const {openModal} = useModalControls()
+  const requireAuth = useRequireAuth()
 
   const defaultControlColor = React.useMemo(
     () => ({
@@ -45,7 +47,9 @@ export const RepostButton = ({
   return (
     <TouchableOpacity
       testID="repostBtn"
-      onPress={onPressToggleRepostWrapper}
+      onPress={() => {
+        requireAuth(() => onPressToggleRepostWrapper())
+      }}
       style={[styles.control, !big && styles.controlPad]}
       accessibilityRole="button"
       accessibilityLabel={`${
diff --git a/src/view/com/util/post-ctrls/RepostButton.web.tsx b/src/view/com/util/post-ctrls/RepostButton.web.tsx
index 6c5f816aa..329382132 100644
--- a/src/view/com/util/post-ctrls/RepostButton.web.tsx
+++ b/src/view/com/util/post-ctrls/RepostButton.web.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
+import {StyleProp, StyleSheet, View, ViewStyle, Pressable} from 'react-native'
 import {RepostIcon} from 'lib/icons'
 import {colors} from 'lib/styles'
 import {useTheme} from 'lib/ThemeContext'
@@ -12,6 +12,8 @@ import {
 import {EventStopper} from '../EventStopper'
 import {useLingui} from '@lingui/react'
 import {msg} from '@lingui/macro'
+import {useRequireAuth} from '#/state/session'
+import {useSession} from '#/state/session'
 
 interface Props {
   isReposted: boolean
@@ -31,6 +33,8 @@ export const RepostButton = ({
 }: Props) => {
   const theme = useTheme()
   const {_} = useLingui()
+  const {hasSession} = useSession()
+  const requireAuth = useRequireAuth()
 
   const defaultControlColor = React.useMemo(
     () => ({
@@ -62,32 +66,46 @@ export const RepostButton = ({
     },
   ]
 
-  return (
+  const inner = (
+    <View
+      style={[
+        styles.control,
+        !big && styles.controlPad,
+        (isReposted
+          ? styles.reposted
+          : defaultControlColor) as StyleProp<ViewStyle>,
+      ]}>
+      <RepostIcon strokeWidth={2.2} size={big ? 24 : 20} />
+      {typeof repostCount !== 'undefined' ? (
+        <Text
+          testID="repostCount"
+          type={isReposted ? 'md-bold' : 'md'}
+          style={styles.repostCount}>
+          {repostCount ?? 0}
+        </Text>
+      ) : undefined}
+    </View>
+  )
+
+  return hasSession ? (
     <EventStopper>
       <NativeDropdown
         items={dropdownItems}
         accessibilityLabel={_(msg`Repost or quote post`)}
         accessibilityHint="">
-        <View
-          style={[
-            styles.control,
-            !big && styles.controlPad,
-            (isReposted
-              ? styles.reposted
-              : defaultControlColor) as StyleProp<ViewStyle>,
-          ]}>
-          <RepostIcon strokeWidth={2.2} size={big ? 24 : 20} />
-          {typeof repostCount !== 'undefined' ? (
-            <Text
-              testID="repostCount"
-              type={isReposted ? 'md-bold' : 'md'}
-              style={styles.repostCount}>
-              {repostCount ?? 0}
-            </Text>
-          ) : undefined}
-        </View>
+        {inner}
       </NativeDropdown>
     </EventStopper>
+  ) : (
+    <Pressable
+      accessibilityRole="button"
+      onPress={() => {
+        requireAuth(() => {})
+      }}
+      accessibilityLabel={_(msg`Repost or quote post`)}
+      accessibilityHint="">
+      {inner}
+    </Pressable>
   )
 }