about summary refs log tree commit diff
path: root/src/view/com/modals
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/modals')
-rw-r--r--src/view/com/modals/CreateScene.tsx243
-rw-r--r--src/view/com/modals/InviteToScene.tsx308
-rw-r--r--src/view/com/modals/Modal.tsx12
3 files changed, 0 insertions, 563 deletions
diff --git a/src/view/com/modals/CreateScene.tsx b/src/view/com/modals/CreateScene.tsx
deleted file mode 100644
index d92fe2e31..000000000
--- a/src/view/com/modals/CreateScene.tsx
+++ /dev/null
@@ -1,243 +0,0 @@
-import React, {useState} from 'react'
-import * as Toast from '../util/Toast'
-import {
-  ActivityIndicator,
-  StyleSheet,
-  TouchableOpacity,
-  View,
-} from 'react-native'
-import LinearGradient from 'react-native-linear-gradient'
-import {BottomSheetScrollView, BottomSheetTextInput} from '@gorhom/bottom-sheet'
-import {AppBskyActorCreateScene} from '@atproto/api'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {Text} from '../util/text/Text'
-import {useStores} from '../../../state'
-import {s, colors, gradients} from '../../lib/styles'
-import {
-  makeValidHandle,
-  createFullHandle,
-  enforceLen,
-  MAX_DISPLAY_NAME,
-  MAX_DESCRIPTION,
-} from '../../../lib/strings'
-
-export const snapPoints = ['60%']
-
-export function Component({}: {}) {
-  const store = useStores()
-  const [error, setError] = useState<string>('')
-  const [isProcessing, setIsProcessing] = useState<boolean>(false)
-  const [handle, setHandle] = useState<string>('')
-  const [displayName, setDisplayName] = useState<string>('')
-  const [description, setDescription] = useState<string>('')
-  const onPressSave = async () => {
-    setIsProcessing(true)
-    if (error) {
-      setError('')
-    }
-    try {
-      if (!store.me.did) {
-        return
-      }
-      const desc = await store.api.com.atproto.server.getAccountsConfig()
-      const fullHandle = createFullHandle(
-        handle,
-        desc.data.availableUserDomains[0],
-      )
-      // create scene actor
-      const createSceneRes = await store.api.app.bsky.actor.createScene({
-        handle: fullHandle,
-      })
-      // set the scene profile
-      await store.api.app.bsky.actor
-        .updateProfile({
-          did: createSceneRes.data.did,
-          displayName,
-          description,
-        })
-        .catch(e =>
-          // an error here is not critical
-          store.log.error('Failed to update scene profile during creation', e),
-        )
-      // follow the scene
-      await store.api.app.bsky.graph.follow
-        .create(
-          {
-            did: store.me.did,
-          },
-          {
-            subject: {
-              did: createSceneRes.data.did,
-              declarationCid: createSceneRes.data.declaration.cid,
-            },
-            createdAt: new Date().toISOString(),
-          },
-        )
-        .catch(e =>
-          // an error here is not critical
-          store.log.error('Failed to follow scene after creation', e),
-        )
-      Toast.show('Scene created')
-      store.shell.closeModal()
-      store.nav.navigate(`/profile/${fullHandle}`)
-    } catch (e: any) {
-      if (e instanceof AppBskyActorCreateScene.InvalidHandleError) {
-        setError(
-          'The handle can only contain letters, numbers, and dashes, and must start with a letter.',
-        )
-      } else if (e instanceof AppBskyActorCreateScene.HandleNotAvailableError) {
-        setError(`The handle "${handle}" is not available.`)
-      } else {
-        store.log.error('Failed to create scene', e)
-        setError(
-          'Failed to create the scene. Check your internet connection and try again.',
-        )
-      }
-      setIsProcessing(false)
-    }
-  }
-  const onPressCancel = () => {
-    store.shell.closeModal()
-  }
-
-  return (
-    <View style={styles.outer}>
-      <BottomSheetScrollView style={styles.inner}>
-        <Text style={[styles.title, s.black]}>Create a scene</Text>
-        <Text style={styles.description}>
-          Scenes are invite-only groups which aggregate what's popular with
-          members.
-        </Text>
-        <View style={{paddingBottom: 50}}>
-          <View style={styles.group}>
-            <Text style={[styles.label, s.black]}>Scene Handle</Text>
-            <BottomSheetTextInput
-              style={styles.textInput}
-              placeholder="e.g. alices-friends"
-              placeholderTextColor={colors.gray4}
-              autoCorrect={false}
-              value={handle}
-              onChangeText={str => setHandle(makeValidHandle(str))}
-            />
-          </View>
-          <View style={styles.group}>
-            <Text style={[styles.label, s.black]}>Scene Display Name</Text>
-            <BottomSheetTextInput
-              style={styles.textInput}
-              placeholder="e.g. Alice's Friends"
-              placeholderTextColor={colors.gray4}
-              value={displayName}
-              onChangeText={v =>
-                setDisplayName(enforceLen(v, MAX_DISPLAY_NAME))
-              }
-            />
-          </View>
-          <View style={styles.group}>
-            <Text style={[styles.label, s.black]}>Scene Description</Text>
-            <BottomSheetTextInput
-              style={[styles.textArea]}
-              placeholder="e.g. Artists, dog-lovers, and memelords."
-              placeholderTextColor={colors.gray4}
-              multiline
-              value={description}
-              onChangeText={v => setDescription(enforceLen(v, MAX_DESCRIPTION))}
-            />
-          </View>
-          {error !== '' && (
-            <View style={s.mb10}>
-              <ErrorMessage message={error} numberOfLines={3} />
-            </View>
-          )}
-          {handle.length >= 2 && !isProcessing ? (
-            <TouchableOpacity style={s.mt10} onPress={onPressSave}>
-              <LinearGradient
-                colors={[gradients.primary.start, gradients.primary.end]}
-                start={{x: 0, y: 0}}
-                end={{x: 1, y: 1}}
-                style={[styles.btn]}>
-                <Text style={[s.white, s.bold, s.f18]}>Create Scene</Text>
-              </LinearGradient>
-            </TouchableOpacity>
-          ) : (
-            <View style={s.mt10}>
-              <View style={[styles.btn]}>
-                {isProcessing ? (
-                  <ActivityIndicator />
-                ) : (
-                  <Text style={[s.gray4, s.bold, s.f18]}>Create Scene</Text>
-                )}
-              </View>
-            </View>
-          )}
-          <TouchableOpacity style={s.mt10} onPress={onPressCancel}>
-            <View style={[styles.btn, {backgroundColor: colors.white}]}>
-              <Text style={[s.black, s.bold]}>Cancel</Text>
-            </View>
-          </TouchableOpacity>
-        </View>
-      </BottomSheetScrollView>
-    </View>
-  )
-}
-
-const styles = StyleSheet.create({
-  outer: {
-    flex: 1,
-    // paddingTop: 20,
-  },
-  title: {
-    textAlign: 'center',
-    fontWeight: 'bold',
-    fontSize: 24,
-    marginBottom: 12,
-  },
-  description: {
-    textAlign: 'center',
-    fontSize: 17,
-    paddingHorizontal: 22,
-    color: colors.gray5,
-    marginBottom: 10,
-  },
-  inner: {
-    padding: 14,
-    height: 350,
-  },
-  group: {
-    marginBottom: 10,
-  },
-  label: {
-    fontSize: 16,
-    fontWeight: 'bold',
-    paddingHorizontal: 4,
-    paddingBottom: 4,
-  },
-  textInput: {
-    borderWidth: 1,
-    borderColor: colors.gray3,
-    borderRadius: 6,
-    paddingHorizontal: 14,
-    paddingVertical: 10,
-    fontSize: 16,
-    color: colors.black,
-  },
-  textArea: {
-    borderWidth: 1,
-    borderColor: colors.gray3,
-    borderRadius: 6,
-    paddingHorizontal: 12,
-    paddingTop: 10,
-    fontSize: 16,
-    color: colors.black,
-    height: 70,
-    textAlignVertical: 'top',
-  },
-  btn: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    justifyContent: 'center',
-    width: '100%',
-    borderRadius: 32,
-    padding: 14,
-    backgroundColor: colors.gray1,
-  },
-})
diff --git a/src/view/com/modals/InviteToScene.tsx b/src/view/com/modals/InviteToScene.tsx
deleted file mode 100644
index 2b4d0ac29..000000000
--- a/src/view/com/modals/InviteToScene.tsx
+++ /dev/null
@@ -1,308 +0,0 @@
-import React, {useState, useEffect, useMemo} from 'react'
-import {observer} from 'mobx-react-lite'
-import * as Toast from '../util/Toast'
-import {
-  ActivityIndicator,
-  FlatList,
-  StyleSheet,
-  useWindowDimensions,
-  View,
-} from 'react-native'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {
-  TabView,
-  SceneMap,
-  Route,
-  TabBar,
-  TabBarProps,
-} from 'react-native-tab-view'
-import _omit from 'lodash.omit'
-import {AtUri} from '../../../third-party/uri'
-import {ProfileCard} from '../profile/ProfileCard'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {Text} from '../util/text/Text'
-import {useStores} from '../../../state'
-import * as apilib from '../../../state/lib/api'
-import {ProfileViewModel} from '../../../state/models/profile-view'
-import {SuggestedInvitesView} from '../../../state/models/suggested-invites-view'
-import {Assertion} from '../../../state/models/get-assertions-view'
-import {FollowItem} from '../../../state/models/user-follows-view'
-import {s, colors} from '../../lib/styles'
-
-export const snapPoints = ['70%']
-
-export const Component = observer(function Component({
-  profileView,
-}: {
-  profileView: ProfileViewModel
-}) {
-  const store = useStores()
-  const layout = useWindowDimensions()
-  const [index, setIndex] = useState(0)
-  const tabRoutes = [
-    {key: 'suggestions', title: 'Suggestions'},
-    {key: 'pending', title: 'Pending Invites'},
-  ]
-  const [hasSetup, setHasSetup] = useState<boolean>(false)
-  const [error, setError] = useState<string>('')
-  const suggestions = useMemo(
-    () => new SuggestedInvitesView(store, {sceneDid: profileView.did}),
-    [profileView.did],
-  )
-  const [createdInvites, setCreatedInvites] = useState<Record<string, string>>(
-    {},
-  )
-  // TODO: it would be much better if we just used the suggestions view for the deleted pending invites
-  //       but mobx isnt picking up on the state change in suggestions.unconfirmed and I dont have
-  //       time to debug that right now -prf
-  const [deletedPendingInvites, setDeletedPendingInvites] = useState<
-    Record<string, boolean>
-  >({})
-
-  useEffect(() => {
-    let aborted = false
-    if (hasSetup) {
-      return
-    }
-    suggestions.setup().then(() => {
-      if (aborted) return
-      setHasSetup(true)
-    })
-    return () => {
-      aborted = true
-    }
-  }, [profileView.did])
-
-  const onPressInvite = async (follow: FollowItem) => {
-    setError('')
-    try {
-      const assertionUri = await apilib.inviteToScene(
-        store,
-        profileView.did,
-        follow.did,
-        follow.declaration.cid,
-      )
-      setCreatedInvites({[follow.did]: assertionUri, ...createdInvites})
-      Toast.show('Invite sent')
-    } catch (e: any) {
-      setError('There was an issue with the invite. Please try again.')
-      store.log.error('Failed to invite user to scene', e)
-    }
-  }
-  const onPressUndo = async (subjectDid: string, assertionUri: string) => {
-    setError('')
-    const urip = new AtUri(assertionUri)
-    try {
-      await store.api.app.bsky.graph.assertion.delete({
-        did: profileView.did,
-        rkey: urip.rkey,
-      })
-      setCreatedInvites(_omit(createdInvites, [subjectDid]))
-    } catch (e: any) {
-      setError('There was an issue with the invite. Please try again.')
-      store.log.error('Failed to delete a scene invite', e)
-    }
-  }
-
-  const onPressDeleteInvite = async (assertion: Assertion) => {
-    setError('')
-    const urip = new AtUri(assertion.uri)
-    try {
-      await store.api.app.bsky.graph.assertion.delete({
-        did: profileView.did,
-        rkey: urip.rkey,
-      })
-      setDeletedPendingInvites({
-        [assertion.uri]: true,
-        ...deletedPendingInvites,
-      })
-      Toast.show('Invite removed')
-    } catch (e: any) {
-      setError('There was an issue with the invite. Please try again.')
-      store.log.error('Failed to delete an invite', e)
-    }
-  }
-
-  const renderSuggestionItem = ({item}: {item: FollowItem}) => {
-    const createdInvite = createdInvites[item.did]
-    return (
-      <ProfileCard
-        did={item.did}
-        handle={item.handle}
-        displayName={item.displayName}
-        avatar={item.avatar}
-        renderButton={() =>
-          !createdInvite ? (
-            <>
-              <FontAwesomeIcon icon="user-plus" style={[s.mr5]} size={14} />
-              <Text style={[s.fw400, s.f14]}>Invite</Text>
-            </>
-          ) : (
-            <>
-              <FontAwesomeIcon icon="x" style={[s.mr5]} size={14} />
-              <Text style={[s.fw400, s.f14]}>Undo invite</Text>
-            </>
-          )
-        }
-        onPressButton={() =>
-          !createdInvite
-            ? onPressInvite(item)
-            : onPressUndo(item.did, createdInvite)
-        }
-      />
-    )
-  }
-
-  const renderPendingInviteItem = ({item}: {item: Assertion}) => {
-    const wasDeleted = deletedPendingInvites[item.uri]
-    if (wasDeleted) {
-      return <View />
-    }
-    return (
-      <ProfileCard
-        did={item.subject.did}
-        handle={item.subject.handle}
-        displayName={item.subject.displayName}
-        avatar={item.subject.avatar}
-        renderButton={() => (
-          <>
-            <FontAwesomeIcon icon="x" style={[s.mr5]} size={14} />
-            <Text style={[s.fw400, s.f14]}>Undo invite</Text>
-          </>
-        )}
-        onPressButton={() => onPressDeleteInvite(item)}
-      />
-    )
-  }
-
-  const Suggestions = () => (
-    <View style={s.flex1}>
-      {hasSetup ? (
-        <View style={s.flex1}>
-          <View style={styles.todoContainer}>
-            <Text style={styles.todoLabel}>
-              User search is still being implemented. For now, you can pick from
-              your follows below.
-            </Text>
-          </View>
-          {!suggestions.hasContent ? (
-            <Text
-              style={{
-                textAlign: 'center',
-                paddingTop: 10,
-                paddingHorizontal: 40,
-                fontWeight: 'bold',
-                color: colors.gray5,
-              }}>
-              {suggestions.myFollowsView.follows.length
-                ? 'Sorry! You dont follow anybody for us to suggest.'
-                : 'Sorry! All of the users you follow are members already.'}
-            </Text>
-          ) : (
-            <FlatList
-              data={suggestions.suggestions}
-              keyExtractor={item => item._reactKey}
-              renderItem={renderSuggestionItem}
-              style={s.flex1}
-            />
-          )}
-        </View>
-      ) : !error ? (
-        <ActivityIndicator />
-      ) : undefined}
-    </View>
-  )
-
-  const PendingInvites = () => (
-    <View style={s.flex1}>
-      {suggestions.sceneAssertionsView.isLoading ? (
-        <ActivityIndicator />
-      ) : undefined}
-      <View style={s.flex1}>
-        {!suggestions.unconfirmed.length ? (
-          <Text
-            style={{
-              textAlign: 'center',
-              paddingTop: 10,
-              paddingHorizontal: 40,
-              fontWeight: 'bold',
-              color: colors.gray5,
-            }}>
-            No pending invites.
-          </Text>
-        ) : (
-          <FlatList
-            data={suggestions.unconfirmed}
-            keyExtractor={item => item._reactKey}
-            renderItem={renderPendingInviteItem}
-            style={s.flex1}
-          />
-        )}
-      </View>
-    </View>
-  )
-
-  const renderScene = SceneMap({
-    suggestions: Suggestions,
-    pending: PendingInvites,
-  })
-
-  const renderTabBar = (props: TabBarProps<Route>) => (
-    <TabBar
-      {...props}
-      style={{backgroundColor: 'white'}}
-      activeColor="black"
-      inactiveColor={colors.gray5}
-      labelStyle={{textTransform: 'none'}}
-      indicatorStyle={{backgroundColor: colors.purple3}}
-    />
-  )
-
-  return (
-    <View style={s.flex1}>
-      <Text style={styles.title}>
-        Invite to {profileView.displayName || profileView.handle}
-      </Text>
-      {error !== '' ? (
-        <View style={s.p10}>
-          <ErrorMessage message={error} />
-        </View>
-      ) : undefined}
-      <TabView
-        navigationState={{index, routes: tabRoutes}}
-        renderScene={renderScene}
-        renderTabBar={renderTabBar}
-        onIndexChange={setIndex}
-        initialLayout={{width: layout.width}}
-      />
-    </View>
-  )
-})
-
-const styles = StyleSheet.create({
-  title: {
-    textAlign: 'center',
-    fontWeight: 'bold',
-    fontSize: 18,
-    marginBottom: 4,
-  },
-  todoContainer: {
-    backgroundColor: colors.pink1,
-    margin: 10,
-    padding: 10,
-    borderRadius: 6,
-  },
-  todoLabel: {
-    color: colors.pink5,
-    textAlign: 'center',
-  },
-
-  tabBar: {
-    flexDirection: 'row',
-  },
-  tabItem: {
-    alignItems: 'center',
-    padding: 16,
-    flex: 1,
-  },
-})
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index 43271c964..e0e18d54a 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -9,8 +9,6 @@ import * as models from '../../../state/models/shell-ui'
 
 import * as ConfirmModal from './Confirm'
 import * as EditProfileModal from './EditProfile'
-import * as CreateSceneModal from './CreateScene'
-import * as InviteToSceneModal from './InviteToScene'
 import * as ServerInputModal from './ServerInput'
 import * as ReportPostModal from './ReportPost'
 import * as ReportAccountModal from './ReportAccount'
@@ -55,16 +53,6 @@ export const Modal = observer(function Modal() {
         {...(store.shell.activeModal as models.EditProfileModal)}
       />
     )
-  } else if (store.shell.activeModal?.name === 'create-scene') {
-    snapPoints = CreateSceneModal.snapPoints
-    element = <CreateSceneModal.Component />
-  } else if (store.shell.activeModal?.name === 'invite-to-scene') {
-    snapPoints = InviteToSceneModal.snapPoints
-    element = (
-      <InviteToSceneModal.Component
-        {...(store.shell.activeModal as models.InviteToSceneModal)}
-      />
-    )
   } else if (store.shell.activeModal?.name === 'server-input') {
     snapPoints = ServerInputModal.snapPoints
     element = (