@expo/vector-icons#Entypo JavaScript Examples

The following examples show how to use @expo/vector-icons#Entypo. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From discovery-mobile-ui with MIT License 6 votes vote down vote up
CatalogScreenHeader = ({ collection, navigation }) => {
  const savedRecords = useSelector(savedRecordsSelector).length;
  return (
    <Header style={styles.header}>
      <Left>
        {/* }<TouchableOpacity onPress={() => navigation.goBack()}> */}
        <TouchableOpacity onPress={() => navigation.navigate('CollectionsList')}>
          <Entypo name="chevron-thin-left" size={20} color={Colors.headerIcon} />
        </TouchableOpacity>
      </Left>
      <View style={styles.headerTitleContainer}>
        <HeaderCountIcon count={savedRecords} outline />
        <Title style={styles.collectionLabel}>{collection?.label}</Title>
      </View>
      <Right>

        <CatalogModal collectionId={collection.id} />
      </Right>
    </Header>
  );
}
Example #2
Source File: CatalogScreenActionIcon.js    From discovery-mobile-ui with MIT License 6 votes vote down vote up
CatalogScreenActionIcon = () => {
  const handlePress = () => {
    ActionSheetIOS.showActionSheetWithOptions(
      {
        options: ['Cancel', 'Placeholder Action', 'Placeholder Action', 'Placeholder Action'],
        destructiveButtonIndex: 3,
        cancelButtonIndex: 0,
        userInterfaceStyle: 'dark',
      },
      (buttonIndex) => {
        if (buttonIndex === 0) {
          // cancel action
        } else if (buttonIndex === 1) {
          // renameAlert();
        } else if (buttonIndex === 2) {
          // duplicateAlert();
        } else if (buttonIndex === 3) {
          // if (collectionsCount <= 1) {
          //   deleteErrorAlert();
          // } else {
          //   deleteCollectionAlert();
          // }
        }
      },
    );
  };

  return (
    <TouchableOpacity onPress={handlePress}>
      <Entypo name="dots-three-vertical" size={24} color={Colors.darkgrey} />
    </TouchableOpacity>
  );
}
Example #3
Source File: ResourceCardNoteActions.js    From discovery-mobile-ui with MIT License 6 votes vote down vote up
ResourceCardNoteActions = ({
  hasNotes, showNotes, setShowNotes, resourceId,
}) => {
  const navigation = useNavigation();

  if (!hasNotes) {
    return (
      <TouchableOpacity style={styles.addNoteButton} onPress={() => navigation.navigate('Notes', { resourceId })}>
        <Entypo name="squared-plus" size={24} color={Colors.darkgrey2} />
        <BaseText variant="title" style={styles.buttonText}>Add Notes</BaseText>
      </TouchableOpacity>
    );
  }

  const showNotesText = showNotes ? 'Hide Notes' : 'Show Notes';
  const showNotesIcon = showNotes ? 'sticky-note' : 'sticky-note-o';
  return (
    <View style={styles.actionsContainer}>
      <TouchableOpacity style={styles.addNoteButton} onPress={() => navigation.navigate('Notes', { resourceId })}>
        <Entypo name="squared-plus" size={24} color={Colors.darkgrey2} />
        <BaseText variant="title" style={styles.buttonText}>Add Notes</BaseText>
      </TouchableOpacity>
      <View style={styles.verticalDivider} />
      <TouchableOpacity style={styles.addNoteButton} onPress={() => setShowNotes(!showNotes)}>
        <FontAwesome name={showNotesIcon} size={20} color={Colors.darkgrey2} />
        <BaseText variant="title" style={styles.buttonText}>{showNotesText}</BaseText>
      </TouchableOpacity>
    </View>
  );
}
Example #4
Source File: Routes.js    From timetable with MIT License 5 votes vote down vote up
BottomTab = () => {
  const Tab = createBottomTabNavigator()
  const { t } = useTranslation()
  const { theme } = useContext(ThemeContext)

  return (
    <Tab.Navigator
      initialRouteName='Stations'
      tabBarOptions={{
        activeTintColor: theme.bottomTabNavActive,
        inactiveTintColor: theme.bottomTabNavInactive,
        style: { backgroundColor: theme.bottomTabNavBackground }
      }}
    >
      <Tab.Screen
        name='Favorites'
        component={Favorites}
        options={{
          title: t('routes.favorites'),
          tabBarIcon: ({ color, size }) => (
            <AntDesign name='staro' color={color} size={size} />
          )
        }}
      />
      <Tab.Screen
        name='Stations'
        component={Stations}
        options={{
          title: t('routes.stations'),
          tabBarIcon: ({ color, size }) => (
            <Entypo name='location' color={color} size={size} />
          )
        }}
      />
      <Tab.Screen
        name='Lines'
        component={Lines}
        options={{
          title: t('routes.lines'),
          tabBarIcon: ({ color, size }) => (
            <Entypo name='dots-three-horizontal' color={color} size={size} />
          )
        }}
      />
      <Tab.Screen
        name='About'
        component={About}
        options={{
          title: t('routes.about'),
          tabBarIcon: ({ color, size }) => (
            <Entypo name='info' color={color} size={size} />
          )
        }}
      />
    </Tab.Navigator>
  )
}
Example #5
Source File: index.js    From discovery-mobile-ui with MIT License 5 votes vote down vote up
DetailsPanel = ({
  navigation, collection, savedRecordsGroupedByType, savedRecords,
}) => {
  const { detailsPanelSortingState: sortingState } = collection;
  const { RECORD_TYPE, RECORD_DATE, TIME_SAVED } = sortFields;
  const hasSavedRecords = Object.entries(savedRecords).length > 0;
  const hasMultipleSavedRecords = Object.entries(savedRecords).length > 1;
  const savedItemsCount = useSelector(savedRecordsSelector).length;

  const handlePressNoteIcon = () => {
    navigation.navigate('Notes');
  };

  const displayAccordion = () => {
    switch (sortingState.activeSortField) {
      case RECORD_TYPE:
        return (
          <SubTypeAccordionsContainer
            data={savedRecordsGroupedByType}
            fromDetailsPanel
          />
        );
      case RECORD_DATE:
        return (
          <DateAccordionsContainer
            fromDetailsPanel
          />
        );
      case TIME_SAVED:
        return (
          <TimeSavedAccordionsContainer
            fromDetailsPanel
          />
        );
      default:
        console.warn('No activeSortField in DetailsPanel'); // eslint-disable-line no-console
        return null;
    }
  };

  return (
    <SafeAreaView style={styles.root}>
      <Header style={styles.header}>
        <Left>
          <TouchableOpacity onPress={() => navigation.goBack()}>
            <Entypo name="chevron-thin-left" size={20} color={Colors.headerIcon} />
          </TouchableOpacity>
        </Left>
        <View style={styles.headerTitleContainer}>
          {savedItemsCount > 0 && <HeaderCountIcon count={savedItemsCount} outline />}
          <Title style={styles.headerText}>{collection?.label}</Title>
        </View>
        <Right>
          <TouchableOpacity onPress={handlePressNoteIcon}>
            <FontAwesome name="sticky-note-o" size={20} color={Colors.headerIcon} />
          </TouchableOpacity>
        </Right>
      </Header>
      {!hasSavedRecords && (
        <View style={styles.zeroStateContainer}>
          <Text style={styles.zeroStateText}>No Records in Collection.</Text>
        </View>
      )}
      {hasSavedRecords && (
        <>
          <SortingHeader
            sortingState={sortingState}
            hasMultipleSavedRecords={hasMultipleSavedRecords}
          />
          <ScrollView>
            {displayAccordion()}
          </ScrollView>
        </>
      )}
    </SafeAreaView>
  );
}
Example #6
Source File: Lines.js    From timetable with MIT License 4 votes vote down vote up
Lines = () => {
  const { i18n, t } = useTranslation()
  const navigation = useNavigation()
  const { theme } = useTheme()

  const [busArray, setBusArray] = useState([])

  useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      setBusArray(i18n.language == 'en' ? EnBus.Bus : GeBus.Bus)
    })

    // Cleanup
    return unsubscribe
  }, [navigation])

  // FlatList Item
  const Item = ({ busNumber, stopA, stopB }) => {
    const [boolean, setBoolean] = useState(true)

    // Change direction
    const changeDirectionHandler = () => setBoolean(!boolean)

    // Bus Line start-end direction
    const direction = boolean ? (
      <TouchableOpacity
        onPress={() =>
          navigation.navigate('LinesMap', { busNumber, forward: 0 })
        }
      >
        <View style={styles.listItem}>
          <Text style={{ color: theme.text }}>{stopA}</Text>
          <Entypo name='arrow-long-right' color='#1f5c87' size={25} />
          <Text style={{ color: theme.text }}>{stopB}</Text>
        </View>
      </TouchableOpacity>
    ) : (
      <TouchableOpacity
        onPress={() =>
          navigation.navigate('LinesMap', { busNumber, forward: 1 })
        }
      >
        <View style={styles.listItem}>
          <Text style={{ color: theme.text }}>{stopB}</Text>
          <Entypo name='arrow-long-right' color='#1f5c87' size={25} />
          <Text style={{ color: theme.text }}>{stopA}</Text>
        </View>
      </TouchableOpacity>
    )

    return (
      <View>
        <View style={[styles.separator, { borderBottomColor: theme.border }]} />

        <View
          style={[
            styles.wrapBusIcon,
            {
              backgroundColor: theme.backgroundColor,
              borderColor: theme.border
            }
          ]}
        >
          <MaterialCommunityIcons
            name='bus'
            color='#1f5c87'
            size={15}
            style={styles.busIcon}
          />

          <Text style={[styles.busNumber, { color: theme.text }]}>
            {busNumber}
          </Text>
        </View>

        <Text style={[styles.from, { color: theme.text }]}>
          {t('lines.from')}
        </Text>

        {direction}

        <View style={styles.changeDirection}>
          <Button
            onPress={changeDirectionHandler}
            text={t('lines.change')}
            buttonColor={theme.buttonColor}
            textColor={theme.buttonText}
            margin={0}
            paddingVertical={4}
            fontSize={12}
          />
        </View>
      </View>
    )
  }

  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={busArray}
        renderItem={({ item }) => (
          <Item
            busNumber={item.RouteNumber}
            stopA={item.StopA}
            stopB={item.StopB}
          />
        )}
        keyExtractor={item => item.RouteNumber}
      />
    </SafeAreaView>
  )
}
Example #7
Source File: Post.js    From InstagramClone with Apache License 2.0 4 votes vote down vote up
function Post(props) {
    const [item, setItem] = useState(props.route.params.item)
    const [user, setUser] = useState(props.route.params.user)
    const [currentUserLike, setCurrentUserLike] = useState(false)
    const [unmutted, setUnmutted] = useState(true)
    const [videoref, setvideoref] = useState(null)
    const [sheetRef, setSheetRef] = useState(useRef(null))
    const [modalShow, setModalShow] = useState({ visible: false, item: null })
    const [isValid, setIsValid] = useState(true);
    const [exists, setExists] = useState(false);
    const [loaded, setLoaded] = useState(false);

    const isFocused = useIsFocused();
    useEffect(() => {

        if (props.route.params.notification != undefined) {

            firebase.firestore()
                .collection("users")
                .doc(props.route.params.user)
                .get()
                .then((snapshot) => {
                    if (snapshot.exists) {
                        let user = snapshot.data();
                        user.uid = snapshot.id;

                        setUser(user)
                    }
                })

            firebase.firestore()
                .collection("posts")
                .doc(props.route.params.user)
                .collection("userPosts")
                .doc(props.route.params.item)
                .get()
                .then((snapshot) => {
                    if (snapshot.exists) {
                        let post = snapshot.data();
                        post.id = snapshot.id;

                        setItem(post)
                        setLoaded(true)
                        setExists(true)
                    }
                })
            firebase.firestore()
                .collection("posts")
                .doc(props.route.params.user)
                .collection("userPosts")
                .doc(props.route.params.item)
                .collection("likes")
                .doc(firebase.auth().currentUser.uid)
                .onSnapshot((snapshot) => {
                    let currentUserLike = false;
                    if (snapshot.exists) {
                        currentUserLike = true;
                    }
                    setCurrentUserLike(currentUserLike)

                })

        }
        else {
            firebase.firestore()
                .collection("posts")
                .doc(props.route.params.user.uid)
                .collection("userPosts")
                .doc(props.route.params.item.id)
                .collection("likes")
                .doc(firebase.auth().currentUser.uid)
                .onSnapshot((snapshot) => {
                    let currentUserLike = false;
                    if (snapshot.exists) {
                        currentUserLike = true;
                    }
                    setCurrentUserLike(currentUserLike)

                })

            setItem(props.route.params.item)
            setUser(props.route.params.user)
            setLoaded(true)
            setExists(true)
        }

    }, [props.route.params.notification, props.route.params.item])

    useEffect(() => {
        if (videoref !== null) {
            videoref.setIsMutedAsync(props.route.params.unmutted)
        }
        setUnmutted(props.route.params.unmutted)
    }, [props.route.params.unmutted])

    useEffect(() => {
        if (videoref !== null) {
            if (isFocused) {
                videoref.playAsync()
            } else {
                videoref.stopAsync()

            }
        }

    }, [props.route.params.index, props.route.params.inViewPort])

    const onUsernamePress = (username, matchIndex) => {
        props.navigation.navigate("ProfileOther", { username, uid: undefined })
    }

    const onLikePress = (userId, postId, item) => {
        item.likesCount += 1;
        setCurrentUserLike(true)
        firebase.firestore()
            .collection("posts")
            .doc(userId)
            .collection("userPosts")
            .doc(postId)
            .collection("likes")
            .doc(firebase.auth().currentUser.uid)
            .set({})
            .then()
        props.sendNotification(user.notificationToken, "New Like", `${props.currentUser.name} liked your post`, { type: 0, postId, user: firebase.auth().currentUser.uid })

    }
    const onDislikePress = (userId, postId, item) => {
        item.likesCount -= 1;

        setCurrentUserLike(false)
        firebase.firestore()
            .collection("posts")
            .doc(userId)
            .collection("userPosts")
            .doc(postId)
            .collection("likes")
            .doc(firebase.auth().currentUser.uid)
            .delete()
    }
    if (!exists && loaded) {
        return (
            <View style={{ height: '100%', justifyContent: 'center', margin: 'auto' }}>
                <FontAwesome5 style={{ alignSelf: 'center', marginBottom: 20 }} name="dizzy" size={40} color="black" />
                <Text style={[text.notAvailable]}>Post does not exist</Text>
            </View>
        )
    }
    if (!loaded) {
        return (<View></View>)

    }
    if (user == undefined) {
        return (<View></View>)
    }
    if (item == null) {
        return (<View />)
    }

    const _handleVideoRef = (component) => {
        setvideoref(component);

        if (component !== null) {
            component.setIsMutedAsync(props.route.params.unmutted)
        }
    }

    if (videoref !== null) {
        videoref.setIsMutedAsync(unmutted)
        if (isFocused && props.route.params.index == props.route.params.inViewPort) {
            videoref.playAsync()
        } else {
            videoref.stopAsync()

        }
    }


    if (sheetRef.current !== null && !props.route.params.feed) {
        if (modalShow.visible) {
            sheetRef.snapTo(0)
        } else {
            sheetRef.snapTo(1)
        }
    }

    return (
        <View style={[container.container, utils.backgroundWhite]}>

            <View>
                <View style={[container.horizontal, { alignItems: 'center', padding: 10 }]}>
                    <TouchableOpacity
                        style={[container.horizontal, { alignItems: 'center' }]}
                        onPress={() => props.navigation.navigate("ProfileOther", { uid: user.uid, username: undefined })}>

                        {user.image == 'default' ?
                            (
                                <FontAwesome5
                                    style={[utils.profileImageSmall]}
                                    name="user-circle" size={35} color="black" />

                            )
                            :
                            (
                                <Image
                                    style={[utils.profileImageSmall]}
                                    source={{
                                        uri: user.image
                                    }}
                                />
                            )
                        }
                        <View style={{ alignSelf: 'center' }}>
                            <Text style={[text.bold, text.medium, { marginBottom: 0 }]} >{user.name}</Text>
                        </View>

                    </TouchableOpacity>

                    <TouchableOpacity
                        style={[{ marginLeft: 'auto' }]}

                        onPress={() => {
                            if (props.route.params.feed) {
                                props.route.params.setModalShow({ visible: true, item })
                            } else {
                                setModalShow({ visible: true, item })
                            }
                        }}>
                        <Feather
                            name="more-vertical" size={20} color="black" />
                    </TouchableOpacity>
                </View>
                {item.type == 0 ?
                    <View>
                        {props.route.params.index == props.route.params.inViewPort && isFocused ?
                            <View>
                                <VideoPlayer
                                    videoProps={{
                                        isLooping: true,
                                        shouldPlay: true,
                                        resizeMode: Video.RESIZE_MODE_COVER,
                                        source: {
                                            uri: item.downloadURL,
                                        },
                                        videoRef: _handleVideoRef,
                                    }}
                                    inFullscreen={false}
                                    showControlsOnLoad={true}
                                    showFullscreenButton={false}
                                    height={WINDOW_WIDTH}
                                    width={WINDOW_WIDTH}
                                    shouldPlay={true}
                                    isLooping={true}
                                    style={{
                                        aspectRatio: 1 / 1, height: WINDOW_WIDTH,
                                        width: WINDOW_WIDTH, backgroundColor: 'black'
                                    }}
                                />

                                <TouchableOpacity
                                    style={{ position: 'absolute', borderRadius: 500, backgroundColor: 'black', width: 40, height: 40, alignItems: 'center', justifyContent: 'center', margin: 10, right: 0 }}
                                    activeOpacity={1}
                                    onPress={() => {
                                        if (videoref == null) {
                                            return;
                                        }
                                        if (unmutted) {
                                            if (props.route.params.setUnmuttedMain == undefined) {
                                                setUnmutted(false)
                                            } else {
                                                props.route.params.setUnmuttedMain(false)

                                            }

                                        } else {
                                            if (props.route.params.setUnmuttedMain == undefined) {
                                                setUnmutted(true)
                                            } else {
                                                props.route.params.setUnmuttedMain(true)

                                            }

                                        }

                                    }}>
                                    {!unmutted ?

                                        <Feather name="volume-2" size={20} color="white" />
                                        :
                                        <Feather name="volume-x" size={20} color="white" />
                                    }
                                </TouchableOpacity>

                            </View>

                            :
                            <View style={{ marginTop: 4 }}>

                                <CachedImage
                                    cacheKey={item.id}
                                    style={[container.image]}
                                    source={{ uri: item.downloadURLStill }}
                                />
                            </View>
                        }

                    </View>

                    :

                    <CachedImage
                        cacheKey={item.id}
                        style={container.image}
                        source={{ uri: item.downloadURL }}
                    />
                }

                <View style={[utils.padding10, container.horizontal]}>
                    {currentUserLike ?
                        (
                            <Entypo name="heart" size={30} color="red" onPress={() => onDislikePress(user.uid, item.id, item)} />
                        )
                        :
                        (
                            <Feather name="heart" size={30} color="black" onPress={() => onLikePress(user.uid, item.id, item)} />

                        )
                    }
                    <Feather style={utils.margin15Left} name="message-square" size={30} color="black" onPress={() => props.navigation.navigate('Comment', { postId: item.id, uid: user.uid, user })} />
                    <Feather style={utils.margin15Left} name="share" size={26} color="black" onPress={() => props.navigation.navigate('ChatList', { postId: item.id, post: { ...item, user: user }, share: true })} />


                </View>
                <View style={[container.container, utils.padding10Sides]}>
                    <Text style={[text.bold, text.medium]}>
                        {item.likesCount} likes
                    </Text>
                    <Text style={[utils.margin15Right, utils.margin5Bottom]}>
                        <Text style={[text.bold]}
                            onPress={() => props.navigation.navigate("ProfileOther", { uid: user.uid, username: undefined })}>
                            {user.name}
                        </Text>

                        <Text>    </Text>
                        <ParsedText
                            parse={
                                [
                                    { pattern: /@(\w+)/, style: { color: 'green', fontWeight: 'bold' }, onPress: onUsernamePress },
                                ]
                            }
                        >{item.caption}</ParsedText>

                    </Text>
                    <Text
                        style={[text.grey, utils.margin5Bottom]} onPress={() => props.navigation.navigate('Comment', { postId: item.id, uid: user.uid, user })}>
                        View all {item.commentsCount} Comments
                    </Text>
                    <Text
                        style={[text.grey, text.small, utils.margin5Bottom]}>
                        {timeDifference(new Date(), item.creation.toDate())}
                    </Text>
                </View>
            </View>

            <BottomSheet
                bottomSheerColor="#FFFFFF"
                ref={setSheetRef}
                initialPosition={0} //200, 300
                snapPoints={[300, 0]}
                isBackDrop={true}
                isBackDropDismissByPress={true}
                isRoundBorderWithTipHeader={true}
                backDropColor="black"
                isModal
                containerStyle={{ backgroundColor: "white" }}
                tipStyle={{ backgroundColor: "white" }}
                headerStyle={{ backgroundColor: "white", flex: 1 }}
                bodyStyle={{ backgroundColor: "white", flex: 1, borderRadius: 20 }}
                body={

                    <View>

                        {modalShow.item != null ?
                            <View>
                                <TouchableOpacity style={{ padding: 20 }}
                                    onPress={() => {
                                        props.navigation.navigate("ProfileOther", { uid: modalShow.item.user.uid, username: undefined });
                                        setModalShow({ visible: false, item: null });
                                    }}>
                                    <Text >Profile</Text>
                                </TouchableOpacity>
                                <Divider />
                                {props.route.params.user.uid == firebase.auth().currentUser.uid ?
                                    <TouchableOpacity style={{ padding: 20 }}
                                        onPress={() => {
                                            props.deletePost(modalShow.item).then(() => {
                                                props.fetchUserPosts()
                                                props.navigation.popToTop()
                                            })
                                            setModalShow({ visible: false, item: null });
                                        }}>
                                        <Text >Delete</Text>
                                    </TouchableOpacity>
                                    : null}

                                <Divider />
                                <TouchableOpacity style={{ padding: 20 }} onPress={() => setModalShow({ visible: false, item: null })}>
                                    <Text >Cancel</Text>
                                </TouchableOpacity>
                            </View>
                            : null}

                    </View>
                }
            />
            <Snackbar
                visible={isValid.boolSnack}
                duration={2000}
                onDismiss={() => { setIsValid({ boolSnack: false }) }}>
                {isValid.message}
            </Snackbar>
        </View>
    )
}
Example #8
Source File: ReviewTopBar.js    From juken with MIT License 4 votes vote down vote up
ReviewTopBar = ({
  submissionQueue,
  submissionErrors,
  ignoreSubmissionErrors,
  retrySubmission,
  isQueueClear,
  setMenuOpen,
}) => {
  
  const isInternetReachable = useNetworkListener();
  const { showActionSheetWithOptions } = useActionSheet();

  const uploadSuccess = submissionQueue.length === 0;
  const uploadFail = submissionErrors.length > 0;
  const uploadQueue = submissionQueue.length;
  const uploadErrors = submissionErrors.length;

  let badgeColor = uploadFail
    ? theme.palette.red
    : 'rgba(0, 0, 0, .1)';
  
  let badgeIcon = null;
  if (uploadSuccess) badgeIcon = <AntDesign name="check" size={10} color="white" />;
  if (uploadQueue > 0) badgeIcon = <AntDesign name="arrowup" size={10} color="white" />;

  let badgeText = null;
  if (uploadQueue > 0) badgeText = uploadQueue;
  if (uploadFail) badgeText = uploadErrors;

  return (
    <>

      {/** top bar */}
      <TopBar
        style={styles.wrapper}
        centerText={isQueueClear ? '' : 'Reviews'}
        left={<Entypo name="menu" size={20} color="white" />}
        leftOnPress={() => setMenuOpen(true)}
        right={
          <>
            {!isInternetReachable && (
              <Badge
                style={{ marginRight: 6, backgroundColor: theme.palette.red }}
                icon={<Feather name="wifi-off" size={10} color="white" />}
              />
            )}
            <Badge
              style={{ backgroundColor: badgeColor }}
              text={badgeText}
              icon={badgeIcon}
            />
          </>
        }
        rightOnPress={!uploadFail ? null : () => {
          showActionSheetWithOptions({
              options: [
                'Cancel',
                'Retry',
                'Ignore',
              ],
              destructiveButtonIndex: 2,
              title: `Failed to submit ${uploadErrors} review${uploadErrors === 1 ? '' : 's'}`,
              message: (
                'You can retry submission after making sure your device ' +
                'has an active internet connection. If you submitted the reviews ' +
                'from another application, please use the Ignore button to dismiss ' +
                'the errors.'
              ),
            }, buttonIndex => {
              if (buttonIndex === 1) {
                retrySubmission();
              } else if (buttonIndex === 2) {
                dialog({
                  webTitle: 'Unless you submitted your reviews elsewhere, your unsubmitted reviews will be lost. Are you sure ?',
                  mobileTitle: 'Are you sure ?',
                  mobileMessage: 'Unless you submitted your reviews elsewhere, your unsubmitted reviews will be lost.',
                  onConfirm: ignoreSubmissionErrors
                });
              }
            })
        }}
      />
    </>
  )
}
Example #9
Source File: CollectionRowActionIcon.js    From discovery-mobile-ui with MIT License 4 votes vote down vote up
CollectionRowActionIcon = ({
  collections,
  collectionId,
  collectionLabel,
  collectionsCount,
  updateIsAddingNewCollectionAction,
  selectCollectionAction,

}) => {
  const [collectionsDialogText, setCollectionsDialogText] = useState(null);
  const navigation = useNavigation();

  const handlePress = () => {
    if (collections[collectionId].preBuilt) {
      ActionSheetIOS.showActionSheetWithOptions(
        {
          options: [
            'Cancel',
            CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DUPLICATE].title,
          ],
          cancelButtonIndex: 0,
          userInterfaceStyle: 'dark',
        },
        (buttonIndex) => {
          if (buttonIndex === 0) {
          // cancel action
          } else if (buttonIndex === 1) {
            setCollectionsDialogText(CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DUPLICATE]);
          }
        },
      );
    } else {
      ActionSheetIOS.showActionSheetWithOptions(
        {
          options: [
            'Cancel',
            'Edit Collection',

            CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.RENAME].title,
            CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DUPLICATE].title,
            CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DELETE].title,
          ],
          destructiveButtonIndex: 4,
          cancelButtonIndex: 0,
          userInterfaceStyle: 'dark',
        },
        (buttonIndex) => {
          if (buttonIndex === 0) {
          // cancel action
          } else if (buttonIndex === 1) {
            selectCollectionAction(collectionId);
            updateIsAddingNewCollectionAction(false);
            navigation.navigate('CollectionInput');
          } else if (buttonIndex === 2) {
            setCollectionsDialogText(CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.RENAME]);
          } else if (buttonIndex === 3) {
            setCollectionsDialogText(CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DUPLICATE]);
          } else if (buttonIndex === 4) {
            if (collectionsCount <= 1) {
              setCollectionsDialogText(
                CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DELETE_ERROR],
              );
            } else {
              setCollectionsDialogText(CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DELETE]);
            }
          }
        },
      );
    }
  };

  return (
    <View>
      <TouchableOpacity onPress={handlePress}>
        <Entypo name="dots-three-vertical" size={20} color={Colors.headerIcon} />
      </TouchableOpacity>
      {collectionsDialogText && (
        <CollectionsDialog
          collectionId={collectionId}
          collectionLabel={collectionLabel}
          collectionsDialogText={collectionsDialogText}
          setCollectionsDialogText={setCollectionsDialogText}
        />
      )}
    </View>
  );
}
Example #10
Source File: CatalogModal.js    From discovery-mobile-ui with MIT License 4 votes vote down vote up
CatalogModal = ({
  collectionId,
  clearCollectionAction,
  clearMarkedResourcesAction,
  collection,
  clearHighlightedEnabled,
  hasCollectionRecordsInScope,
}) => {
  const [modalVisible, setModalVisible] = useState(false);
  const { showCollectionOnly, showMarkedOnly } = collection;
  const clearCollectionEnabled = hasCollectionRecordsInScope && !collection.preBuilt;

  const handleClearCollection = () => {
    const clearAndCloseModal = () => {
      clearCollectionAction(collectionId);
      setModalVisible(false);
    };

    Alert.alert(
      'Clear Collection',
      'Are you sure you want to clear the records saved to this collection?',
      [
        {
          text: 'Cancel',
          onPress: () => {},
          style: 'cancel',
        },
        {
          text: 'Clear',
          onPress: clearAndCloseModal,
          style: 'destructive',
        },
      ],
    );
  };

  const handleClearMarked = () => {
    const clearAndCloseModal = () => {
      clearMarkedResourcesAction(collectionId);
      setModalVisible(false);
    };

    Alert.alert(
      'Clear Highlighted Events',
      'Are you sure you want to clear the highlighted records?',
      [
        {
          text: 'Cancel',
          onPress: () => {},
          style: 'cancel',
        },
        {
          text: 'Clear',
          onPress: clearAndCloseModal,
          style: 'destructive',
        },
      ],
    );
  };

  return (
    <View style={styles.root}>
      <Modal
        animationType="slide"
        transparent
        visible={modalVisible}
        onRequestClose={() => {
          setModalVisible(false);
        }}
      >
        <View style={styles.centeredView}>
          <View style={styles.modalView}>
            <View style={styles.modalHeaderContainer}>
              <BaseText variant="sectionTitle">Workspaces</BaseText>
              <TouchableOpacity onPress={() => setModalVisible(false)}>
                <Ionicons name="close" size={30} color="black" />
              </TouchableOpacity>
            </View>
            <View style={styles.controlsContainer}>
              <SegmentControlDescription
                showCollectionOnly={showCollectionOnly}
                showMarkedOnly={showMarkedOnly}
              />
              <View style={styles.segmentControlContainer}>
                <CollectionSegmentControl
                  readOnly={collection.preBuilt}
                />
                <MarkedSegmentControl />
              </View>
              <TouchableOpacity
                disabled={!clearCollectionEnabled}
                style={[
                  styles.clearButtonBase,
                  clearCollectionEnabled ? null : styles.clearButtonDisabled,
                ]}
                onPress={handleClearCollection}
              >
                <BaseText variant={clearCollectionEnabled ? 'buttonDestructive' : 'buttonDisabled'}>Clear Collection</BaseText>
              </TouchableOpacity>
              <TouchableOpacity
                disabled={!clearHighlightedEnabled}
                style={[
                  styles.clearButtonBase,
                  clearHighlightedEnabled ? null : styles.clearButtonDisabled,
                ]}
                onPress={handleClearMarked}
              >
                <BaseText variant={clearHighlightedEnabled ? 'buttonDestructive' : 'buttonDisabled'}>Clear Highlights</BaseText>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </Modal>
      <TouchableOpacity
        onPress={() => {
          setModalVisible(true);
        }}
      >
        <Entypo name="dots-three-vertical" size={20} color={Colors.headerIcon} />
      </TouchableOpacity>
    </View>
  );
}
Example #11
Source File: CollectionInputScreen.js    From discovery-mobile-ui with MIT License 4 votes vote down vote up
CollectionInputScreen = ({
  collection,
  createCollectionAction,
  selectCollectionAction,
  editCollectionDetailsAction,
  creatingCollection,
  collectionsLabels,
  collections,
  renameCollectionAction,
}) => {
  const navigation = useNavigation();
  const [title, onChangeTitle] = useState(creatingCollection ? DEFAULT_COLLECTION_NAME : collection.label); // eslint-disable-line max-len
  const [purpose, onChangePurpose] = useState(creatingCollection ? '' : collection?.purpose);
  const [current, currentSelection] = useState(creatingCollection ? false : collection?.current);
  const [urgent, urgentSelection] = useState(creatingCollection ? false : collection?.urgent);
  const [newCollectionID, setCollectionID] = useState('');
  const [isAddingCollection, setIsAddingCollection] = useState(false);
  const [collectionsDialogText, setCollectionsDialogText] = useState(null);
  const [open, setOpen] = useState(false);
  const [hasTextValue, setHasTextValue] = useState(false);
  const [sameName, setSameName] = useState(false);
  const [moveToCatalog, setMoveToCatalog] = useState(false);

  const itemsList = [

  ];
  const itemNames = [];
  const collectionNames = [];
  if (Object.keys(collections).length > 0) {
    Object.keys(collections).forEach((key) => {
      if (collections[key] != null) {
        collectionNames.push(collections[key].label);
        for (let j = 0; j < collections[key].tags.length; j += 1) {
          if (!itemNames.includes(collections[key].tags[j])) {
            itemNames.push(collections[key].tags[j]);
          }
        }
      }
    });
  }
  for (let i = 0; i < itemNames.length; i += 1) {
    itemsList.push({ label: itemNames[i], value: itemNames[i] });
  }
  const [items, setItems] = useState(itemsList);
  const [value, setValue] = useState(creatingCollection ? [] : collection.tags);

  const discardInputAlert = () => {
    Alert.alert(
      'Discard Edits',
      'Are you sure you want to discard edits to this collection?',
      [
        {
          text: 'Cancel',
          onPress: () => {},
          style: 'cancel',
        },
        {
          text: 'Discard',
          onPress: () => handleCloseInput(),
          style: 'destructive',
        },
      ],
    );
  };

  const handleCloseInput = ({ alert }) => {
    if (alert) {
      discardInputAlert();
    }
  };

  const handleSave = () => {
    if (creatingCollection) {
      if (!collectionNames.includes(title)) {
        if (hasTextValue) {
          if (hasInputErrors({ text: title, isRename: false, label: title })) {
            return;
          }
          createCollectionAction(title);
          setIsAddingCollection(true);
        }
      }
    } else {
      if (hasInputErrors({ text: title, isRename: true, label: title })) {
        return;
      }
      renameCollectionAction(newCollectionID, title);

      editCollectionDetailsAction(purpose, value, (current || urgent), urgent);
    }
  };
  const saveCollection = () => {
    handleSave();
    navigation.navigate('CollectionsList');
  };
  const saveAndContinue = () => {
    if (creatingCollection) {
      if (!collectionNames.includes(title)) {
        if (hasTextValue) {
          if (hasInputErrors({ text: title, isRename: false, label: title })) {
            return;
          }
          createCollectionAction(title);
          setIsAddingCollection(true);
        }
      }
    } else {
      if (hasInputErrors({ text: title, isRename: true, label: title })) {
        return;
      }
      renameCollectionAction(newCollectionID, title);

      editCollectionDetailsAction(purpose, value, (current || urgent), urgent);
    }
    setMoveToCatalog(true);
    //
  };
  const discardChanges = () => {
    setCollectionsDialogText(CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DISCARD]);
  };

  const discardChangesCreate = () => {
    setCollectionsDialogText(CollectionsDialogText[COLLECTIONS_DIALOG_ACTIONS.DISCARD_CREATE]);
  };
    // selectCollectionAction(title);

  // console.log(collection)
  // collection.label = title
  // collection.tags = tags

  useEffect(() => {
    if (Object.keys(collections).length > 0) {
      setCollectionID(Object.keys(collections)[Object.keys(collections).length - 1]);

      if (isAddingCollection) {
        selectCollectionAction(Object.keys(collections)[Object.keys(collections).length - 1]);
        editCollectionDetailsAction(purpose, value, (current || urgent), urgent);
        setIsAddingCollection(false);
      }
    }
    if (moveToCatalog) {
      navigation.navigate('Catalog');
    }

    // if (useState(collections )!== collections) {
    // }
  }, [collections, isAddingCollection, moveToCatalog]);

  useEffect(() => {
    setSameName(false);
    if (title.length > 0) {
      setHasTextValue(true);
    }
    if (creatingCollection) {
      for (let i = 0; i < collectionNames.length; i += 1) {
        if (collectionNames[i].toLowerCase() === title.toLowerCase()) {
          setHasTextValue(false);
          setSameName(true);
        }
      }
    }
  }, [title]);

  const saveButtonTextStyle = hasTextValue ? styles.saveButtonText : styles.disabledSaveButtonText;

  // PLACEHOLDERS
  const placeholderTitle = creatingCollection ? '' : collection.label;

  const isUniqueName = ({ text, isRename, label }) => {
    // if action is rename, new label can be same as old label
    if (isRename && (text.toLowerCase() === label.toLowerCase())) {
      return true;
    }
    return !((collectionsLabels).includes(text.toLowerCase()));
  };
  const hasMinLength = (text) => text.length > 0;

  const hasInputErrors = ({ text, isRename, label }) => {
    if (!hasMinLength(text)) {
      return true;
    }
    if (!isUniqueName({ text, isRename, label })) {
      return true;
    }
    return false;
  };
  const reduceInputs = () => {
    Keyboard.dismiss();
    setOpen(false);
  };

  return (

    <SafeAreaView style={styles.root}>

      <Header style={styles.header}>
        <Left>
          <TouchableOpacity onPress={() => navigation.goBack()}>
            <Entypo name="chevron-thin-left" size={20} color="black" />
          </TouchableOpacity>
        </Left>
        <TouchableWithoutFeedback onPress={reduceInputs}>
          <View style={styles.headerTitleContainer}>
            <Title style={styles.headerText}><Text>{title}</Text></Title>
          </View>
        </TouchableWithoutFeedback>
        <Right>
          <TouchableWithoutFeedback style={styles.empty_toucable} onPress={reduceInputs}>
            <View style={styles.headerTitleContainer}>

              <Text style={styles.header_empty_text}> </Text>

            </View>

          </TouchableWithoutFeedback>
        </Right>
      </Header>

      <View style={styles.inputField}>

        <KeyboardAvoidingView behavior="padding">
          <TouchableWithoutFeedback onPress={reduceInputs}>

            <View style={styles.textInputDiv}>
              <Text variant="title" style={styles.formHeader}>Title</Text>
            </View>
          </TouchableWithoutFeedback>

          <View style={styles.titleTextInputContainer}>
            <TextInput
              style={styles.textInput}
              onChangeText={onChangeTitle}
              placeholder={placeholderTitle}
              value={title}
              onTouchStart={() => setOpen(false)}
              multiline={false}
              autoFocus
            />
          </View>

          <View style={styles.titleFooter}>
            {sameName
            && (
            <View style={styles.sameNameAlertContainer}>
              <Text style={{ color: Colors.destructive }}>Collection name must be unique</Text>
            </View>
            )}
          </View>

        </KeyboardAvoidingView>

        <KeyboardAvoidingView behavior="padding">

          <TouchableWithoutFeedback onPress={reduceInputs}>

            <View style={styles.textInputDiv}>

              <TouchableOpacity style={styles.textInputHeader} disabled>
                <Text variant="title" style={styles.formHeader}>Purpose</Text>
              </TouchableOpacity>
            </View>
          </TouchableWithoutFeedback>

          <View style={styles.purposeTextInputContainer}>
            <TextInput
              style={styles.textInput}
              onChangeText={onChangePurpose}
              placeholder="add purpose"
              onSubmitEditing={Keyboard.dismiss}
              value={purpose}
              onTouchStart={() => setOpen(false)}
              multiline={false}
              autoFocus
            />
          </View>
        </KeyboardAvoidingView>

        <View style={styles.tagTextHeader}>
          <TouchableWithoutFeedback disabled onPress={reduceInputs}>
            <Text variant="title" style={styles.formHeader}>Collection Tags</Text>
          </TouchableWithoutFeedback>
        </View>

        <View style={{ zIndex: 100, backgroundColor: '#fff' }}>
          <Picker
            multiple
            min={0}
            max={5}
            open={open}
            value={value}
            setOpen={setOpen}
            setValue={setValue}
            items={items}
            setItems={setItems}
            searchable
            placeholder="add new or existing tags "
          />
        </View>
        <View style={styles.switchTextHeader}>
          <TouchableWithoutFeedback disabled onPress={reduceInputs}>

            <Text variant="title" style={styles.formHeader}>Priority</Text>
          </TouchableWithoutFeedback>

        </View>

        <View style={styles.switchRow}>
          <View style={styles.currentTextField}>

            <Feather name="watch" size={18} color={Colors.currentCollectionColor} />

            <Text style={styles.switchText}>Current</Text>
          </View>

          <Switch
            trackColor={{
              false: Colors.mediumgrey,
              true: Platform.OS === 'ios' ? Colors.primary : Colors.primaryLight,
            }}
            thumbColor={(Platform.OS === 'ios') ? 'white' : Colors[(current ? 'primary' : 'primaryLight')]}
            onValueChange={() => currentSelection(!current)}
            value={current || urgent}
            disabled={urgent}
          />
          <View style={styles.leftRightPadding}>
            <Feather name="alert-triangle" size={18} color={Colors.destructive} />

            <Text variant="title" style={styles.switchText}>Urgent</Text>
          </View>

          <Switch
            trackColor={{
              false: Colors.mediumgrey,
              true: Platform.OS === 'ios' ? Colors.primary : Colors.primaryLight,
            }}
            thumbColor={(Platform.OS === 'ios') ? 'white' : Colors[(urgent ? 'primary' : 'primaryLight')]}
            onValueChange={() => urgentSelection(!urgent)}
            value={urgent}
          />
        </View>
      </View>

      <KeyboardAvoidingView style={styles.textRow}>
        <TouchableOpacity
          style={styles.saveButton}
          onPress={() => {
            if (creatingCollection) {
              discardChangesCreate();
            } else {
              discardChanges();
            }
          }}
        >
          <BaseText variant="title" style={styles.discardButtonText}>Discard</BaseText>
        </TouchableOpacity>

        {collectionsDialogText && (
        <CollectionsDialog
          collectionsDialogText={collectionsDialogText}
          setCollectionsDialogText={setCollectionsDialogText}
        />
        )}
        <View style={styles.saveCol}>
          <TouchableOpacity
            style={styles.saveButton}
            onPress={saveCollection}
            disabled={!hasTextValue}
          >
            <BaseText variant="title" style={saveButtonTextStyle}>Save</BaseText>
          </TouchableOpacity>

          <TouchableOpacity
            style={styles.saveButton}
            onPress={saveAndContinue}
            disabled={!hasTextValue}
          >
            <BaseText variant="title" style={saveButtonTextStyle}>Save and Continue</BaseText>
          </TouchableOpacity>
        </View>
      </KeyboardAvoidingView>

    </SafeAreaView>
  );
}
Example #12
Source File: NotesScreen.js    From discovery-mobile-ui with MIT License 4 votes vote down vote up
NotesScreen = ({
  resource,
  createRecordNoteAction,
  editRecordNoteAction,
  collection,
  createCollectionNoteAction,
  editCollectionNoteAction,
}) => {
  const navigation = useNavigation();
  const route = useRoute();
  const editingNote = route?.params?.editingNote;
  const [text, onChangeText] = useState('');
  const [editNoteId, setEditNoteId] = useState(null);
  const [showNoteInput, setShowNoteInput] = useState(false);
  const isResourceNotes = !!resource;

  const closeInput = () => {
    onChangeText('');
    setEditNoteId(null);
    setShowNoteInput(false);
  };

  const discardInputAlert = () => {
    Alert.alert(
      'Discard Edits',
      'Are you sure you want to discard edits to this note?',
      [
        {
          text: 'Cancel',
          onPress: () => {},
          style: 'cancel',
        },
        {
          text: 'Discard',
          onPress: () => closeInput(),
          style: 'destructive',
        },
      ],
    );
  };

  const handleCloseInput = ({ alert }) => {
    if (alert) {
      discardInputAlert();
    } else {
      closeInput();
    }
  };

  const handleSave = () => {
    if (isResourceNotes) {
      if (editNoteId) {
        editRecordNoteAction(resource.id, text, editNoteId);
      } else {
        createRecordNoteAction(resource.id, text);
      }
    } else if (editNoteId) {
      editCollectionNoteAction(editNoteId, text);
    } else {
      createCollectionNoteAction(text);
    }
    closeInput();
  };

  const handleCreateNote = () => {
    setShowNoteInput(true);
  };

  const handleEditNote = (noteId, noteText) => {
    setEditNoteId(noteId);
    onChangeText(noteText);
    setShowNoteInput(true);
  };

  useEffect(() => {
    if (editingNote) {
      handleEditNote(editingNote.id, editingNote.text);
    } else {
      handleCreateNote();
    }
  }, []);

  const hasTextValue = text.length > 0;
  const saveButtonTextStyle = hasTextValue ? styles.saveButtonText : styles.disabledSaveButtonText;
  const noteCount = isResourceNotes
    ? collection.records[resource.id]?.notes && Object.keys(collection.records[resource?.id]?.notes).length // eslint-disable-line max-len
    : Object.keys(collection.notes).length;

  return (
    <SafeAreaView style={styles.root}>
      <Header style={styles.header}>
        <Left>
          <TouchableOpacity onPress={() => navigation.goBack()}>
            <Entypo name="chevron-thin-left" size={20} color="black" />
          </TouchableOpacity>
        </Left>
        <View style={styles.headerTitleContainer}>
          {noteCount > 0 && <HeaderCountIcon count={noteCount} outline />}
          <Title style={styles.headerText}><Text>Notes</Text></Title>
        </View>
        <Right>
          {!showNoteInput && (
            <TouchableOpacity onPress={handleCreateNote} disabled={showNoteInput}>
              <Feather name="plus-square" size={24} color="black" />
            </TouchableOpacity>
          )}
        </Right>
      </Header>
      <ScrollView>
        {isResourceNotes && (
          <View style={styles.resourceCardContainer}>
            <ResourceCard
              resourceId={resource.id}
              resource={resource}
              handleEditNote={handleEditNote}
              editNoteId={editNoteId}
              fromNotesScreen
            />
          </View>
        )}
        {!isResourceNotes && (
          <>
            <View style={styles.collectionHeaderContainer}>
              <View style={styles.collectionLabelContainer}>
                <Text>{collection.label}</Text>
              </View>
            </View>
            <CollectionNotes
              editNoteId={editNoteId}
              handleEditNote={handleEditNote}
              fromNotesScreen
            />
          </>
        )}
      </ScrollView>
      {showNoteInput && (
      <KeyboardAvoidingView behavior="padding">
        <View style={styles.noteEditingActions}>
          <TouchableOpacity onPress={() => handleCloseInput({ alert: true })}>
            <Ionicons name="ios-close-outline" size={24} color="black" />
          </TouchableOpacity>
          <TouchableOpacity style={styles.saveButton} onPress={handleSave} disabled={!hasTextValue}>
            <BaseText variant="title" style={saveButtonTextStyle}>Save</BaseText>
          </TouchableOpacity>
        </View>
        <View style={styles.textInputContainer}>
          <TextInput
            style={styles.textInput}
            onChangeText={onChangeText}
            multiline
            value={text}
            autoFocus
          />
        </View>
      </KeyboardAvoidingView>
      )}
    </SafeAreaView>
  );
}