@expo/vector-icons#Ionicons JavaScript Examples

The following examples show how to use @expo/vector-icons#Ionicons. 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: app.js    From Baku with GNU General Public License v3.0 6 votes vote down vote up
export default function App(props) {
  // Uncomment this when we figure out what to do about device based state
  // const [loggedIn] = React.useState(false);
  const [isLoadingComplete, setLoadingComplete] = React.useState(false);
  // const [initialNavigationState] = React.useState();
  // const containerRef = React.useRef();

  React.useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        SplashScreen.preventAutoHide();
        await Font.loadAsync({
          ...Ionicons.font,
          'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf')
        });
      } catch (e) {
        {/* console.warn(e);*/}
      } finally {
        setLoadingComplete(true);
        SplashScreen.hide();
      }
    }

    loadResourcesAndDataAsync();
  }, []);

  if (!isLoadingComplete && !props.skipLoadingScreen) {
    return null;
  } else {
    return <AppNavigator loggedIn={false} />;
  }
}
Example #2
Source File: Menu.js    From 4noobs-mobile with MIT License 6 votes vote down vote up
render() {
    return (
      <AnimatedContainer style={{ top: this.state.top }}>
        <Cover>
          <Image source={require("../assets/background2.jpg")} />
          <Title>Rychillie</Title>
          <Subtitle>Frontend Developer</Subtitle>
        </Cover>
        <TouchableOpacity
          onPress={this.props.closeMenu}
          style={{
            position: "absolute",
            top: 120,
            left: "50%",
            marginLeft: -22,
            zIndex: 1,
          }}
        >
          <CloseView>
            <Ionicons name="ios-close" size={44} color="#546bfb" />
          </CloseView>
        </TouchableOpacity>
        <Content>
          {items.map((item, index) => (
            <MenuItem
              key={index}
              icon={item.icon}
              title={item.title}
              text={item.text}
            />
          ))}
        </Content>
      </AnimatedContainer>
    );
  }
Example #3
Source File: index.js    From atendimento-e-agilidade-medica-AAMed with MIT License 6 votes vote down vote up
Header = ({ flag, navigation, label }) => {
  return (
    <Container>
      {flag ? (
        <>
          <ButtonLeft onPress={() => navigation.toggleDrawer()}>
            <Ionicons name="md-menu" size={35} color="#fff" />
          </ButtonLeft>
          <ImgCenter source={require('../../assets/icon_.png')} />
          <ButtonRight onPress={() => navigation.navigate('Help')}>
            <Feather name="help-circle" size={35} color="#fff" />
          </ButtonRight>
        </>
      ) : (
        <>
          <ButtonLeft
            onPress={() => navigation.dispatch(CommonActions.goBack())}
          >
            <Ionicons name="md-arrow-back" size={30} color="#fff" />
          </ButtonLeft>
          <Label>{label}</Label>
          <ImgLeft source={require('../../assets/icon_.png')} />
        </>
      )}
    </Container>
  );
}
Example #4
Source File: TabBarIcon.js    From adyen-react-native-online-payments with MIT License 6 votes vote down vote up
export default function TabBarIcon(props) {
  return (
    <Ionicons
      name={props.name}
      size={30}
      style={{ marginBottom: -3 }}
      color={props.focused ? Colors.tabIconSelected : Colors.tabIconDefault}
    />
  );
}
Example #5
Source File: Header.js    From salyd with GNU General Public License v3.0 6 votes vote down vote up
Header = ({ children, myStyle, navigation, isBack, isUser }) => {
    return (
        <View style={{ ...styles.container, ...myStyle }}>
            {
                (navigation.canGoBack() && isBack) ?
                    <TouchableOpacity style={{
                        paddingRight: 40
                    }}
                        onPress={() => navigation.goBack()}>
                        <Ionicons name="ios-arrow-back" size={28} />
                    </TouchableOpacity>
                    : <View />
            }

            <Text style={{ ...styles.heading, paddingLeft: !(isBack && navigation.canGoBack()) ? 50 : 0, paddingRight: !isUser ? 50 : 0 }}>{children}</Text>

            {
                isUser ?

                    <TouchableOpacity style={{
                        paddingLeft: 40
                    }}
                        onPress={() => navigation.push("Profile")}
                    >
                        <FontAwesome5 name="user-circle" size={28} color="black" />
                    </TouchableOpacity>
                    : <View />
            }
        </View>
    )
}
Example #6
Source File: App.js    From aws-appsync-refarch-offline with MIT No Attribution 6 votes vote down vote up
App = () => (
  <Root>
    <Provider store={store}>
      <NavigationContainer>
        <Tab.Navigator
          screenOptions={({ route }) => ({
            tabBarIcon: ({ color, size }) => {
              if (route.name === 'Checkout') {
                return <Ionicons name="ios-cart" size={size} color={color} />;
              } else if (route.name === 'Orders') {
                return <Ionicons name="ios-archive" size={size} color={color} />;
              } else if (route.name === 'Settings') {
                return <Ionicons name="ios-settings" size={size} color={color} />;
              }
            },
          })}
          tabBarOptions={{
            activeTintColor: 'tomato',
            inactiveTintColor: 'gray',
          }}
        >
          <Tab.Screen name="Checkout" component={CheckoutScreen} />
          <Tab.Screen name="Orders" component={OrdersScreen} />
          <Tab.Screen name="Settings" component={SettingsScreen} />
        </Tab.Navigator>
      </NavigationContainer>
    </Provider>
  </Root>
)
Example #7
Source File: App.js    From expo-soundcloud-clone with MIT License 6 votes vote down vote up
async function loadResourcesAsync() {
  await Promise.all([
    /* Asset.loadAsync([
      require("./assets/images/robot-dev.png"),
      require("./assets/images/robot-prod.png")
    ]), */
    Font.loadAsync({
      // This is the font that we are using for our tab bar
      ...Ionicons.font,
      // We include SpaceMono because we use it in HomeScreen.js. Feel free to
      // remove this if you are not using it in your app
      "space-mono": require("./src/assets/fonts/SpaceMono-Regular.ttf")
    })
  ]);
}
Example #8
Source File: SecondScreen.js    From react-native-expo-template with MIT License 6 votes vote down vote up
export default function ({ navigation }) {
  const { isDarkmode } = useTheme();
  return (
    <Layout>
      <TopNav
        middleContent="Second Screen"
        leftContent={
          <Ionicons
            name="chevron-back"
            size={20}
            color={isDarkmode ? themeColor.white100 : "#191921"}
          />
        }
        leftAction={() => navigation.goBack()}
      />
      <View
        style={{
          flex: 1,
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        {/* This text using ubuntu font */}
        <Text fontWeight="bold">This is the second screen</Text>
      </View>
    </Layout>
  );
}
Example #9
Source File: index.js    From designcode-app with MIT License 6 votes vote down vote up
export default function MenuItem(props) {
  return (
    <Container>
      <IconView>
        <Ionicons name={props.icon} size={24} color="#546bfb" />
      </IconView>
      <Content>
        <Title>{props.title}</Title>
        <Text>{props.text}</Text>
      </Content>
    </Container>
  );
}
Example #10
Source File: App.js    From geometry_3d with MIT License 6 votes vote down vote up
AppBottomNavigator = createBottomTabNavigator(
  {
    Home: {
      screen: HomeScreen,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-home" size={24} color={tintColor} />
        ),
      },
    },
    Items: {
      screen: SavedItemScreen,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-albums" size={24} color={tintColor} />
        ),
      },
    },
    Account: {
      screen: AccountScreen,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-contact" size={24} color={tintColor} />
        ),
      },
    },
  },
  {
    headerMode: "none",
    initialRouteName: "Home",
    backBehavior: "order",
    //tabBarComponent: (props) => <CustomTabBar {...props} />,
  }
)
Example #11
Source File: SharePlay.js    From UltimateApp with MIT License 6 votes vote down vote up
SharePlay = ({ currentPlay }) => {
  const share = async () => {
    try {
      const shareUuid = await upload('customPlays', currentPlay);
      const url = await createLink('custom/plays/' + shareUuid, currentPlay.title);
      await Share.share({
        title: I18n.t('editor.sharePlay.shareTitle', { title: currentPlay.title }),
        message: I18n.t('editor.sharePlay.shareMessage', { url }),
        url,
      });
    } catch (error) {
      showError(I18n.t('editor.sharePlay.shareError'));
    }
  };

  return (
    <TouchableOpacity onPress={share} testID="shareButton">
      <Ionicons
        name={Platform.select({
          ios: 'ios-share-outline',
          default: 'share-social-outline',
        })}
        color={theme.COLOR_PRIMARY_LIGHT}
        size={30}
      />
    </TouchableOpacity>
  );
}
Example #12
Source File: index.js    From puente-reactnative-collect with MIT License 6 votes vote down vote up
export default function TabBarIcon(props) {
  const { name, focused } = props;
  return (
    <Ionicons
      name={name}
      size={30}
      style={{
        marginBottom: -3
      }}
      color={focused ? Colors.tabIconSelected : Colors.tabIconDefault}
    />
  );
}
Example #13
Source File: App.js    From pineapple-reactNative with MIT License 6 votes vote down vote up
async function loadResourcesAsync() {
  await Promise.all([
    Asset.loadAsync([robotDevImage, robotProdImage]),
    Font.loadAsync({
      // This is the font that we are using for our tab bar
      ...Ionicons.font,
      // We include SpaceMono because we use it in HomeScreen.js. Feel free to
      // remove this if you are not using it in your app
      'space-mono': monoFont,
    }),
  ]);
}
Example #14
Source File: AllPostsScreen.js    From SocialApp-React-Native with MIT License 6 votes vote down vote up
screenOptions = (navData) => {
    return{
        headerTitle: 'SocialApp',
        headerRight: () => (
            <Ionicons
                name={Platform.OS === 'android' ? 'md-chatboxes' : 'ios-chatboxes'}
                size = {24}
                color={Platform.OS === 'android' ? '#fff' : Colors.brightBlue}
                style={{  padding: 15, marginRight: 5 }}
                onPress={() => navData.navigation.navigate('ChatList')}
            />
        )
    };
}
Example #15
Source File: SortingHeader.js    From discovery-mobile-ui with MIT License 6 votes vote down vote up
SortingHeader = ({ sortingState, toggleSortingStateAction, hasMultipleSavedRecords }) => {
  const { activeSortField, sortDirections } = sortingState;

  const sortConfig = orderedSortFields.map((sortField) => ({
    sortField,
    sortDir: sortDirections[sortField],
    isPicked: activeSortField === sortField,
  }));

  return (
    <View style={styles.root}>
      <View style={styles.buttonContainer}>
        { sortConfig.map(({ sortField, sortDir, isPicked }) => (
          <TouchableOpacity
            key={sortField}
            style={styles.button}
            onPress={() => toggleSortingStateAction(sortField)}
            disabled={!hasMultipleSavedRecords && (sortField === activeSortField)}
          >
            <BaseText variant={isPicked ? 'title' : ''}>{SORTING_TEXT[sortField].label}</BaseText>
            {isPicked && hasMultipleSavedRecords && (
              <Ionicons
                name={sortDir === SORT_DESC ? 'arrow-down' : 'arrow-up'}
                size={20}
                color="black"
              />
            )}
          </TouchableOpacity>
        ))}
      </View>
      <View style={styles.descriptionContainer}>
        <BaseText style={styles.descriptionText}>
          {SORTING_TEXT[activeSortField][sortDirections[activeSortField]]}
        </BaseText>
      </View>
    </View>

  );
}
Example #16
Source File: index.js    From pandoa with GNU General Public License v3.0 6 votes vote down vote up
render() {
    return (
      <>
        <MapView
          ref={map => {
            this.ref = map;
          }}
          onLayout={this.fitToMarkers}
          {...this.props}
        />
        <View style={styles.view}>
          <TouchableOpacity style={styles.button} onPress={this.fitToCenter}>
            <Ionicons name="md-locate" size={30} color="#000" />
          </TouchableOpacity>
        </View>
      </>
    );
  }
Example #17
Source File: Home.js    From react-native-expo-template with MIT License 5 votes vote down vote up
export default function ({ navigation }) {
  const { isDarkmode, setTheme } = useTheme();
  const auth = getAuth();
  return (
    <Layout>
      <TopNav
        middleContent="Home"
        rightContent={
          <Ionicons
            name={isDarkmode ? "sunny" : "moon"}
            size={20}
            color={isDarkmode ? themeColor.white100 : themeColor.dark}
          />
        }
        rightAction={() => {
          if (isDarkmode) {
            setTheme("light");
          } else {
            setTheme("dark");
          }
        }}
      />
      <View
        style={{
          flex: 1,
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <Section style={{ marginTop: 20 }}>
          <SectionContent>
            <Text fontWeight="bold" style={{ textAlign: "center" }}>
              These UI components provided by Rapi UI
            </Text>
            <Button
              style={{ marginTop: 10 }}
              text="Rapi UI Documentation"
              status="info"
              onPress={() => Linking.openURL("https://rapi-ui.kikiding.space/")}
            />
            <Button
              text="Go to second screen"
              onPress={() => {
                navigation.navigate("SecondScreen");
              }}
              style={{
                marginTop: 10,
              }}
            />
            <Button
              status="danger"
              text="Logout"
              onPress={() => {
                signOut(auth);
              }}
              style={{
                marginTop: 10,
              }}
            />
          </SectionContent>
        </Section>
      </View>
    </Layout>
  );
}
Example #18
Source File: index.js    From designcode-app with MIT License 5 votes vote down vote up
export default function Menu() {
  const [top, setTop] = useState(new Animated.Value(height));

  const action = useSelector((state) => state.app.action);

  useEffect(() => {
    if (action == "openMenu") {
      Animated.spring(top, {
        toValue: 54,
        useNativeDriver: false,
      }).start();
    }

    if (action == "closeMenu") {
      Animated.spring(top, {
        toValue: height,
        useNativeDriver: false,
      }).start();
    }
  }, [action]);

  function handleCloseMenu() {
    store.dispatch({
      type: "CLOSE_MENU",
    });
  }

  function handleMenu(index) {
    if (index == 3) {
      store.dispatch({ type: "CLOSE_MENU" });
      store.dispatch({ type: "SET_NAME", name: "" });
      firebase.auth().signOut();
    }
  }

  return (
    <Animated.View style={[{ top: top }, styles.container]}>
      <Cover>
        <Image source={require("../../../assets/background2.jpg")} />
        <Title>Daniel Sousa</Title>
        <Subtitle>Designer at LearnCode</Subtitle>
      </Cover>
      <Touchable onPress={handleCloseMenu}>
        <CloseView>
          <Ionicons name="ios-close" size={44} color="#546bfb" />
        </CloseView>
      </Touchable>

      <Content>
        {items.map((item, index) => (
          <ButtonMenu key={index} onPress={() => handleMenu(index)}>
            <MenuItem title={item.title} text={item.text} icon={item.icon} />
          </ButtonMenu>
        ))}
      </Content>
    </Animated.View>
  );
}
Example #19
Source File: CustomTabBar.js    From geometry_3d with MIT License 5 votes vote down vote up
CustomTabBar = ({ navigation }) => {
  const { state } = navigation;
  const totalWidth = Dimensions.get("window").width;
  const tabWidth = totalWidth / state.routes.length;
  return (
    <View style={[style.tabContainer, { width: totalWidth }]}>
      <View style={{ flexDirection: "row" }}>
        <View style={style.slider} />
          {state.routes.map((route, index) => {
            const label = route.name;
            const isFocused = state.index === index;
            const onPress = () => {
              const event = navigation.emit({
                type: "tabPress",
                target: route.key,
                canPreventDefault: true,
              });
              if (!isFocused && !event.defaultPrevented) {
                navigation.navigate(route.name);
              }
              const onLongPress = () => {
                navigation.emit({
                  type: "tabLongPress",
                  target: route.key,
                });
              };
              return (
                <TouchableOpacity
                  onPress={onPress}
                  onLongPress={onLongPress}
                  style={{ flex: 1 }}
                  key={index}
                >
                  <Ionicons
                    name="ios-globe"
                    size={32}
                    style={{ color: "grey" }}
                  />
                </TouchableOpacity>
              );
            };
          })}
        </View>
      </View>
  );
}
Example #20
Source File: ShareDrill.js    From UltimateApp with MIT License 5 votes vote down vote up
ShareDrill = ({ drill, light }) => {
  const share = async () => {
    const url = await createLink(
      'drills/' + drill.id,
      drill.title,
      I18n.t('drills.shareDrill.description', { description: drill.description.slice(0, 70) }),
    );

    const youtubeVideos = drill.steps.reduce((total, step) => {
      const stepvideo = step.youtube ? `${step.title} - ${step.youtube}\n` : '';
      return total + stepvideo;
    }, '');

    Share.share({
      title: I18n.t('drills.shareDrill.title', { drillTitle: drill.title }),
      message: I18n.t('drills.shareDrill.content', { url, youtubeVideos, count: youtubeVideos.length }),
      url,
    }).catch((error) => showError(I18n.t('drills.shareDrill.error')));
  };

  const shareCustom = async () => {
    try {
      const shareUuid = await upload('customDrills', drill);
      const url = await createLink('custom/drills/' + shareUuid, drill.title);
      await Share.share({
        title: I18n.t('drills.shareDrill.title', { title: drill.title }),
        message: I18n.t('drills.shareDrill.content', { url, count: 0 }),
        url,
      });
    } catch (error) {
      showError(I18n.t('drills.shareDrill.error'));
    }
  };

  const lightColor = light ? styles.lightColor : undefined;
  return (
    <TouchableOpacity onPress={drill.custom ? shareCustom : share} testID="shareButton">
      <Ionicons
        name={Platform.select({
          ios: 'ios-share-outline',
          default: 'share-social',
        })}
        style={[styles.icon, lightColor]}
      />
    </TouchableOpacity>
  );
}
Example #21
Source File: SocialAppNavigator.js    From SocialApp-React-Native with MIT License 5 votes vote down vote up
BottomNavigator = () => {
    return (
        <BottomTabNavigator.Navigator
            tabBarOptions={{
                activeTintColor: Colors.brightBlue
            }}
        >
            <BottomTabNavigator.Screen
                name="Home"
                component={PostNavigator}
                options={ ({route}) => ({
                    tabBarVisible: getTabBarVisibility(route),
                    tabBarLabel: 'Home',
                    tabBarIcon: (props) => (
                        <Ionicons
                            name={Platform.OS === 'android' ? 'md-home' : 'ios-home'}
                            size={24}
                            color={props.color}
                        />
                    )
                })}
            />
            <BottomTabNavigator.Screen
                name="FindPeople"
                component={FindPeopleNavigator}
                options={{
                    tabBarLabel: 'Find People',
                    tabBarIcon: (props) => (
                        <Ionicons
                            name={Platform.OS === 'android' ? 'md-people' : 'ios-people'}
                            size={24}
                            color={props.color}
                        />
                    )
                }}
            />

            <BottomTabNavigator.Screen
                name="AddPost"
                component={CreatePostNavigator}
                options={{
                    tabBarLabel: 'Add Post',
                    tabBarIcon: (props) => (
                        <Ionicons
                            name={Platform.OS === 'android' ? 'md-add-circle-outline' : 'ios-add-circle-outline'}
                            size={24}
                            color={props.color}
                        />
                    )
                }}
            />

            <BottomTabNavigator.Screen
                name="YourProfile"
                component={UserNavigator}
                options={{
                    tabBarLabel: 'Profile',
                    tabBarIcon: (props) => (
                        <Ionicons
                            name={Platform.OS === 'android' ? 'md-person' : 'ios-person'}
                            size={24}
                            color={props.color}
                        />
                    )
                }}
            />

        </BottomTabNavigator.Navigator>
    );
}
Example #22
Source File: DateAccordionsContainer.js    From discovery-mobile-ui with MIT License 5 votes vote down vote up
DateAccordion = ({
  date, types, fromDetailsPanel, expanded, maxRecordCount,
}) => {
  const dataArray = [{ title: date, content: types }];

  const renderHeader = (item, isExpanded) => {
    const recordCountOnDate = item.content.reduce((acc, { subTypes }) => {
      subTypes.forEach(({ recordIds }) => acc.push(...recordIds));
      return acc;
    }, []).length;

    const chevronIcon = isExpanded
      ? <Ionicons name="chevron-up" size={16} color={Colors.accordionChevronIcon} />
      : <Ionicons name="chevron-down" size={16} color={Colors.accordionChevronIcon} />;
    return (
      <View style={styles.header}>
        <View style={styles.leftSideHeader}>
          {chevronIcon}
          <BaseText style={styles.headerText}>
            {item.title}
          </BaseText>
        </View>
        <View style={styles.rightSideHeader}>
          <RecordNumberBar count={recordCountOnDate} maxCount={maxRecordCount} />
        </View>
      </View>
    );
  };

  return (
    <Accordion
      style={styles.accordion}
      dataArray={dataArray}
      expanded={expanded}
      renderHeader={renderHeader}
      renderContent={(item) => (
        <SubTypeAccordionsContainer
          data={item.content}
          fromDetailsPanel={fromDetailsPanel}
          fromDateAccordion
        />
      )}
    />
  );
}
Example #23
Source File: App.js    From pandoa with GNU General Public License v3.0 5 votes vote down vote up
//import getTheme from "native-base/dist/src/theme/components";
//import material from "native-base/dist/src/theme/variables/material";

export default function App(props) {
  const [isLoadingComplete, setLoadingComplete] = React.useState(false);
  const [initialNavigationState, setInitialNavigationState] = React.useState();
  const containerRef = React.useRef();
  const { getInitialState } = useLinking(containerRef);

  // Load any resources or data that we need prior to rendering the app
  React.useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        SplashScreen.preventAutoHide();
        // Load our initial navigation state
        setInitialNavigationState(await getInitialState());

        // Load fonts
        await Font.loadAsync({
          ...Ionicons.font,
          ...MaterialCommunityIcons.font,
          "space-mono": require("./assets/fonts/SpaceMono-Regular.ttf"),
          Roboto: require("native-base/Fonts/Roboto.ttf"),
          Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf")
        });
      } catch (e) {
        // We might want to provide this error information to an error reporting service
        console.warn(e);
      } finally {
        setLoadingComplete(true);
        SplashScreen.hide();
      }
    }

    loadResourcesAndDataAsync();
  }, []);

  useEffect(() => {
    const config = async () => {
      let res = await Permissions.askAsync(Permissions.LOCATION);
      if (res.status !== "granted") {
        console.log("Permission to access location was denied");
      } else {
        console.log("Permission to access location granted");
      }
    };

    config();
  }, []);

  if (!isLoadingComplete && !props.skipLoadingScreen) {
    return null;
  } else {
    return (
      <Provider store={Store().store}>
        <PersistGate loading={null} persistor={Store().persistor}>
          <StyleProvider style={getTheme(material)}>
            <View style={styles.container}>
              {/* Platform.OS === "ios" && <StatusBar barStyle="default" /> */}

              <NavigationContainer
                ref={containerRef}
                initialState={initialNavigationState}
              >
                <Stack.Navigator headerMode="none">
                  <Stack.Screen name="Root" component={BottomTabNavigator} />
                </Stack.Navigator>
              </NavigationContainer>
            </View>
          </StyleProvider>
        </PersistGate>
      </Provider>
    );
  }
}
Example #24
Source File: SectionScreen.js    From 4noobs-mobile with MIT License 4 votes vote down vote up
render() {
    const { navigation } = this.props;
    const section = navigation.getParam("section");

    const converter = new showdown.Converter();
    const ContentHTML = converter.makeHtml(section.content);

    return (
      <ScrollView>
        <Container>
          <StatusBar hidden />

          <Cover>
            <Image source={section.image} />

            <Wrapper>
              <Logo source={section.logo} />
              <Subtitle>{section.subtitle}</Subtitle>
            </Wrapper>

            <Title>{section.title}</Title>

            <Caption>{section.caption}</Caption>
          </Cover>

          <TouchableOpacity
            onPress={() => {
              this.props.navigation.goBack();
            }}
            style={{ position: "absolute", top: 20, right: 20 }}
          >
            <CloseView>
              <Ionicons name="ios-close" size={26} color="#4775f2" />
            </CloseView>
          </TouchableOpacity>
          <Content>
            {/* <WebView
              source={{ html: ContentHTML }}
              scalesPageToFit={false}
              scrollEnabled={false}
              ref="webview"
              onNavigationStateChange={(event) => {
                if (event.url != "about:blank") {
                  this.refs.webview.stopLoading();
                  Linking.openURL(event.url);
                }
              }}
            /> */}

            <AutoHeightWebView
              customStyle={htmlStyles}
              source={{ html: ContentHTML }}
              viewportContent={"width=device-width, initial-scale=1"}
              scalesPageToFit={false}
              scrollEnabled={false}
              style={{
                width: "100%",
                backgroundColor: "transparent",
              }}
              ref="webview"
              onNavigationStateChange={(event) => {
                if (event.url != "about:blank") {
                  this.refs.webview.stopLoading();
                  Linking.openURL(event.url);
                }
              }}
              onSizeUpdated={(size) => console.log(size.height)}
            />
            {/*
            <MyWebView
              startInLoadingState={true}
              source={{ html: ContentHTML + metaTag + htmlStyles }}
              scalesPageToFit={false}
              scrollEnabled={false}
              ref="webview"
              onNavigationStateChange={(event) => {
                if (event.url != "about:blank") {
                  this.refs.webview.stopLoading();
                  Linking.openURL(event.url);
                }
              }}
            /> */}
            {/*
            <Markdown
              style={{ backgroundColor: "transparent" }}
              body={section.content}
              pureCSS={htmlStyles}
              scalesPageToFit={false}
              scrollEnabled={false}
            /> */}
          </Content>
        </Container>
      </ScrollView>
    );
  }
Example #25
Source File: ViewProfile.js    From salyd with GNU General Public License v3.0 4 votes vote down vote up
ViewProfile = ({ navigation }) => {

    const { user, token } = useContext(GlobalContext);
    const { _id, name, email, phone, image } = user;

    const logout = async () => {
        const token = await AsyncStorage.removeItem("token")
        const user = await AsyncStorage.removeItem("user")
        if (!token) {
            navigation.replace("Login");
        }
    }
    console.log(image)

    return (
        <React.Fragment>
            <Header navigation={navigation} isBack> View Profile </Header>
            <View style={styles.root}>
                <View style={{ alignItems: "center" }}>
                    <Image
                        style={{ width: 140, height: 140, borderRadius: 140 / 2, marginTop: 50 }}
                        source={{ uri: (image ? image : "https://sanjaymotels.com/wp-content/uploads/2019/01/testimony.png") }}
                    />

                </View>
                <View style={{ alignItems: "center", margin: 15 }}>
                    <Text style={styles.name}> {name} </Text>
                </View>

                <TouchableOpacity onPress={() => {
                    navigation.navigate('EditProfile', {
                        name, email, phone
                    })
                }}>
                    <View style={styles.cardContainer}>
                        <View style={styles.mycard}>
                            <View style={styles.cardContent}>
                                <FontAwesome name="user-circle" style={styles.icon} />
                                <Text style={styles.mytext}>Account Details</Text>
                                <Ionicons name="ios-arrow-forward" style={styles.arrow} />
                            </View>
                        </View>
                    </View>
                </TouchableOpacity>

                <TouchableOpacity onPress={() => {
                    navigation.navigate('RecentOrders')
                }}>
                    <View style={styles.mycard}>
                        <View style={styles.cardContent}>
                            <MaterialCommunityIcons name="food-variant" style={styles.icon} />
                            <Text style={styles.mytext}>Order History</Text>
                            <Ionicons name="ios-arrow-forward" style={styles.arrow} />
                        </View>
                    </View>
                </TouchableOpacity>


                <TouchableOpacity onPress={() => {
                    navigation.navigate('Contact')
                }}>

                    <View style={styles.mycard} onPress={() => {
                        navigation.navigate('Contact')
                    }}>
                        <View style={styles.cardContent}>
                            <Feather name="phone-call" style={styles.icon} />
                            <Text style={styles.mytext}>Contact Us</Text>
                            <Ionicons name="ios-arrow-forward" style={styles.arrow} />
                        </View>
                    </View>
                </TouchableOpacity>

                <View style={{
                    justifyContent: "center",
                    alignItems: "center"
                }}>
                    <Button onPressFunction={() => logout()}>Logout</Button>
                </View>

            </View>
        </React.Fragment>
    )
}
Example #26
Source File: StreamCard.js    From expo-soundcloud-clone with MIT License 4 votes vote down vote up
StreamCard = ({
  name,
  title,
  avatar,
  artwork,
  isLiked,
  repost,
  likes,
  listens,
  hastag,
  durantion
}) => {
  return (
    <View style={styles.container}>
      <View
        style={{ flexDirection: "row", marginBottom: 5, paddingHorizontal: 13 }}
      >
        <Image
          resizeMode="cover"
          source={{ uri: avatar }}
          style={styles.avatar}
        />
        <View style={{ flex: 1, marginLeft: 10 }}>
          <View style={{ flexDirection: "row" }}>
            <Text
              style={{ fontSize: 14, fontWeight: "bold" }}
            >{`${name} `}</Text>
            <Text style={{ fontSize: 14, color: Colors.grey }}>
              posted a track
            </Text>
          </View>

          <Text style={styles.subTitle}>22 hours ago</Text>
        </View>
      </View>

      <View style={{ height: 150, overflow: "hidden", paddingHorizontal: 13 }}>
        <ImageBackground
          resizeMode="cover"
          source={{ uri: artwork }}
          style={styles.image}
        >
          <View
            style={{
              flex: 1,
              paddingHorizontal: 20,
              top: 60
            }}
          >
            <TouchableOpacity style={styles.overlayBtn}>
              <Text style={{ color: Colors.grey, fontSize: 15 }}>{name}</Text>
            </TouchableOpacity>
            <View style={styles.overlayBtn}>
              <Text
                style={{ color: Colors.white, fontSize: 15 }}
                numberOfLines={2}
              >
                {title}
              </Text>
            </View>
          </View>
        </ImageBackground>
      </View>

      <View style={styles.timeTagContainer}>
        <Text style={styles.subTitle}>{hastag}</Text>
        <Text style={styles.subTitle}>{durantion}</Text>
      </View>

      <View
        style={{
          flexDirection: "row",
          justifyContent: "space-between",
          paddingHorizontal: 13
        }}
      >
        <TouchableOpacity
          style={{ flexDirection: "row", alignItems: "center" }}
        >
          <Ionicons name="ios-play" size={20} color={Colors.grey} />
          <Text style={{ color: Colors.grey, marginLeft: 4 }}>{listens}</Text>
        </TouchableOpacity>

        <View style={{ flexDirection: "row" }}>
          <TouchableOpacity style={styles.actionButtons}>
            <EvilIcons name="retweet" size={30} color={Colors.grey} />
            <Text style={{ color: Colors.grey, marginLeft: 4 }}>{repost}</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.actionButtons}>
            <Ionicons
              name="ios-heart"
              size={20}
              color={isLiked ? Colors.brandOrange : Colors.grey}
            />
            <Text style={{ color: Colors.grey, marginLeft: 4 }}>
              {numeral(likes).format("0.0a")}
            </Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.actionButtons}>
            <Ionicons name="ios-more" size={20} color={Colors.grey} />
          </TouchableOpacity>
        </View>
      </View>
    </View>
  );
}
Example #27
Source File: index.js    From designcode-app with MIT License 4 votes vote down vote up
export default function Notifications() {
  const [translateY, setTranslateY] = useState(new Animated.Value(30));
  const [opacity, setOpacity] = useState(new Animated.Value(0));
  const [top, setTop] = useState(new Animated.Value(3000));

  const store = useStore();

  useEffect(() => {
    if (store.getState().app.action == "openNotif") {
      Animated.parallel([
        Animated.spring(translateY, {
          toValue: 0,
          useNativeDriver: false,
        }),
        Animated.timing(opacity, {
          toValue: 1,
          duration: 500,
          useNativeDriver: false,
        }),
        Animated.timing(top, {
          toValue: 0,
          duration: 0,
          useNativeDriver: false,
        }),
      ]).start();
    }

    if (store.getState().app.action == "closeNotif") {
      Animated.parallel([
        Animated.spring(translateY, {
          toValue: 30,
          useNativeDriver: false,
        }),
        Animated.timing(opacity, {
          toValue: 0,
          duration: 500,
          useNativeDriver: false,
        }),
        Animated.timing(top, {
          toValue: 3000,
          duration: 0,
          useNativeDriver: false,
        }),
      ]).start();
    }
  }, [store.getState().app.action]);

  function closeNotif() {
    store.dispatch({ type: "CLOSE_NOTIF" });
  }

  return (
    <AnimatedContainer style={{ top: top }}>
      <TouchableOpacity
        onPress={closeNotif}
        style={{
          position: "absolute",
          top: 40,
          left: "50%",
          marginLeft: -22,
          zIndex: 100,
        }}
      >
        <CloseButton style={{ elevation: 20 }}>
          <Ionicons name="ios-close" size={44} color="#546bfb" />
        </CloseButton>
      </TouchableOpacity>
      <SafeAreaView>
        <ScrollView style={{ padding: 20 }}>
          <Wrapper>
            <Subtitle>New</Subtitle>
            {items.map((item, index) => (
              <AnimatedItem
                key={index}
                style={{
                  opacity: opacity,
                  transform: [{ translateY: translateY }],
                }}
              >
                <Header>
                  <Logo source={{ uri: item.logo }} resizeMode="contain" />
                  <Title>{item.title}</Title>
                  <DateContainer>
                    <Date>{item.date}</Date>
                  </DateContainer>
                </Header>
                <Text>{item.text}</Text>
              </AnimatedItem>
            ))}
          </Wrapper>
        </ScrollView>
      </SafeAreaView>
    </AnimatedContainer>
  );
}
Example #28
Source File: BaseLayoutScreen.js    From geometry_3d with MIT License 4 votes vote down vote up
export default function BaseLayoutScreen(props) {
  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", () => true);
    return () =>
      BackHandler.removeEventListener("hardwareBackPress", () => true);
  }, []);
  const initShape = props.initShape;
  const params = props.params;
  THREE.suppressExpoWarnings(true);
  let savedState = null;
  if (params) {
    let currSavedState = {
      shapes: params.shapes,
      lines: params.lines,
      points: params.points,
      fileName: params.fileName,
    };
    savedState = currSavedState;
  }
  const [currPoints, setCurrPoints] = useState(null);
  const [currLines, setCurrLines] = useState(null);
  const [visible, setVisible] = useState(false);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [popUpComp, setPopUpComp] = useState(null);
  const [pointsConnect, setPointsConnect] = useState([]);

  const [signalPoints, setSignalPoints] = useState(false);
  const [signalShapes, setSignalShapes] = useState(false);
  const [signalEditPoints, setSignalEditPoints] = useState(false);

  const [action, setAction] = useState("");
  const [currShapes, setCurrShapes] = useState(null);
  const [shapesConnect, setShapesConnect] = useState([]);
  const [isFromShape, setIsFromShape] = useState(false);
  const [pointsEdit, setPointsEdit] = useState(null);

  const [showSettings, setShowSettings] = useState(false);

  const [camera, setCamera] = useState(null);

  const navigate = useNavigation();
  const getCam = (cam) => {
    setCamera(() => cam);
  };
  const getPoints = (listOfPoints) => {
    setCurrPoints(() => listOfPoints);
  };
  const getLines = (listOfLines) => {
    setCurrLines(() => listOfLines);
  };
  const getShapes = (listOfShapes) => {
    setCurrShapes(() => listOfShapes);
  };
  const connectPoints = (pointsToConnect) => {
    //setIsFromShape(() => false);
    setPointsConnect(() => pointsToConnect);
  };
  const connectShapes = (shapesToConnect) => {
    //setIsFromShape(() => true);
    setShapesConnect(() => shapesToConnect);
  };
  const editPoints = (pointsToEdit) => {
    //console.log(pointsToEdit.length);
    setPointsEdit(() => pointsToEdit);
  };
  const actions = [
    {
      text: "Add points",
      icon: require("../assets/cube.png"),
      name: "add_points",
      position: 1,
    },
    {
      text: "Remove points",
      icon: require("../assets/sphere.png"),
      name: "remove_points",
      position: 2,
    },
    {
      text: "Connect points",
      icon: require("../assets/cone.png"),
      name: "connect_points",
      position: 3,
    },
    {
      text: "Disconnect points",
      icon: require("../assets/octahedron.png"),
      name: "disconnect_points",
      position: 4,
    },
    {
      text: "Add shapes",
      icon: require("../assets/add_shape.png"),
      name: "add_shapes",
      position: 5,
    },
    {
      text: "Remove shapes",
      icon: require("../assets/more.png"),
      name: "remove_shapes",
      position: 6,
    },
    {
      text: "Settings",
      icon: require("../assets/misc_shapes.png"),
      name: "settings",
      position: 7,
    },
    {
      text: "Advanced settings",
      icon: require("../assets/connect_points.png"),
      name: "advanced_settings",
      position: 8,
    },
  ];
  const cards = {
    add_points: {
      component: (
        <EditPoints
          isAdd={true}
          currentPoints={currPoints ? currPoints : []}
          returnPoints={editPoints}
        />
      ),
      action: "add_points",
    },
    remove_points: {
      component: (
        <EditPoints
          isAdd={false}
          currentPoints={currPoints ? currPoints : []}
          returnPoints={editPoints}
        />
      ),
      action: "remove_points",
    },
    connect_points: {
      component: (
        <ControlPoints
          connect={true}
          currentPoints={currPoints ? currPoints : []}
          returnPoints={connectPoints}
        />
      ),
      action: "connect_points",
    },
    disconnect_points: {
      component: (
        <ControlPoints
          connect={false}
          currentPoints={currLines ? currLines : []}
          returnPoints={connectPoints}
        />
      ),
      action: "disconnect_points",
    },
    add_shapes: {
      component: (
        <ControlShapes
          add={true}
          currShapes={currShapes ? currShapes : []}
          returnShapes={connectShapes}
          currPoints={currPoints ? currPoints : []}
        />
      ),
      action: "add_shapes",
    },
    remove_shapes: {
      component: (
        <ControlShapes
          add={false}
          currShapes={currShapes ? currShapes : []}
          returnShapes={connectShapes}
          currPoints={[]}
        />
      ),
      action: "remove_shapes",
    },
    settings: {
      component: (
        <CameraSettings
          existingShapes={currShapes ? currShapes : []}
          camera={camera}
        />
      ),
      action: "settings",
    },
    advanced_settings: {
      component: null,
      action: "advanced_settings",
    },
  };
  const onPointsEditPopUpDone = () => {
    if (pointsEdit.length > 0) {
      setSignalEditPoints(() => !signalEditPoints);
      if (action === "add_points") {
        Toast.show({
          type: "success",
          position: "top",
          text1: `${pointsEdit.length} point(s) added`,
          text2: "Success",
          visibilityTime: 3000,
          autoHide: true,
        });
      } else if (action === "remove_points") {
        Toast.show({
          type: "success",
          position: "top",
          text1: `${pointsEdit.length} point(s) removed`,
          text2: "Success",
          visibilityTime: 3000,
          autoHide: true,
        });
      }
    } else {
      Toast.show({
        type: "error",
        position: "top",
        text1: "Not enough data",
        text2: "Please try again",
        visibilityTime: 3000,
        autoHide: true,
      });
    }
  };
  const onPointsPopUpDone = () => {
    if (pointsConnect.length >= 1 && action === "disconnect_points") {
      setSignalPoints(() => !signalPoints);
      Toast.show({
        type: "success",
        position: "top",
        text1: `${pointsConnect.length} line(s) disconnected`,
        text2: "Success",
        visibilityTime: 3000,
        autoHide: true,
      });
    } else if (pointsConnect.length <= 1) {
      Toast.show({
        type: "error",
        position: "top",
        text1: "Not enough data",
        text2: "Please try again",
        visibilityTime: 3000,
        autoHide: true,
      });
    } else {
      setSignalPoints(() => !signalPoints);
      Toast.show({
        type: "success",
        position: "top",
        text1: `${pointsConnect.length} points connected`,
        text2: "Success",
        visibilityTime: 3000,
        autoHide: true,
      });
    }
    //setPointsConnect(() => []);
  };
  const onShapesPopUpDone = () => {
    if (shapesConnect.length === 0) {
      Toast.show({
        type: "error",
        position: "top",
        text1: "Not enough data",
        text2: "Please try again",
        visibilityTime: 3000,
        autoHide: true,
      });
    } else {
      setSignalShapes(() => !signalShapes);
      Toast.show({
        type: "success",
        position: "top",
        text1: `${shapesConnect.length} shape(s) ${
          action === "add_shapes" ? "added" : "removed"
        }`,
        text2: "Success",
        visibilityTime: 3000,
        autoHide: true,
      });
    }
    //setShapesConnect(() => []);
  };
  const drawerContent = () => {
    return (
      <View style={{ flex: 1 }}>
        <View
          style={{
            width: SCREEN_WIDTH * 0.8 - 40,
            height: "100%",
            backgroundColor: "white",
          }}
        >
          <FlatList
            style={{
              marginHorizontal: 10,
              marginVertical: 5,
            }}
            keyboardShouldPersistTaps="handled"
            keyExtractor={(item, index) => `${index} side drawer`}
            showsVerticalScrollIndicator={false}
            data={actions}
            renderItem={({ index, item }) => (
              <TouchableOpacity
                key={index}
                style={{
                  alignContent: "center",
                  justifyContent: "center",
                  paddingHorizontal: 10,
                  paddingVertical: 20,
                  borderColor: "black",
                  borderWidth: 1,
                  borderRadius: 10,
                  margin: 5,
                  marginBottom: index === actions.length - 1 ? 50 : 5,
                }}
                onPress={() => {
                  const card = cards[item.name];
                  if (item.name === "settings") {
                  } else if (
                    item.name === "add_shapes" ||
                    item.name === "remove_shapes"
                  ) {
                    setIsFromShape(() => true);
                  } else {
                    setIsFromShape(() => false);
                  }
                  if (item.name === "advanced_settings") {
                    setShowSettings(() => true);
                    return;
                  }
                  setVisible(true);
                  setPointsConnect(() => []);
                  setAction(() => item.name);
                  setPopUpComp(card.component);
                }}
              >
                <Text
                  style={{
                    color: "black",
                  }}
                >
                  {item.text}
                </Text>
              </TouchableOpacity>
            )}
          />
        </View>
        <TouchableOpacity
          onPress={() => setIsMenuOpen(false)}
          style={{
            borderTopRightRadius: 20,
            borderBottomRightRadius: 20,
            justifyContent: "center",
            alignItems: "center",
            height: 40,
            width: 40,
            position: "absolute",
            right: 0,
            top: SCREEN_HEIGHT / 2 - 50,
            backgroundColor: "white",
          }}
        >
          <Ionicons name="ios-arrow-back" size={25} color="black" />
        </TouchableOpacity>
      </View>
    );
  };
  return (
    <SafeAreaView
      style={{
        flex: 1,
        backgroundColor: "black",
      }}
    >
      <MenuDrawer
        open={isMenuOpen}
        drawerContent={drawerContent()}
        drawerPercentage={80}
        animationTime={100}
        overlay={true}
      >
        <TouchableOpacity
          style={{
            zIndex: 2,
            borderTopRightRadius: 20,
            borderBottomRightRadius: 20,
            justifyContent: "center",
            alignItems: "center",
            height: 40,
            width: 40,
            position: "absolute",
            left: 0,
            top: SCREEN_HEIGHT / 2 - 50,
            backgroundColor: "white",
          }}
          onPress={() => {
            setIsMenuOpen(true);
          }}
        >
          <Ionicons name="ios-arrow-forward" size={25} color="black" />
        </TouchableOpacity>
        <LayoutSetup
          getPointsCallback={getPoints}
          getLinesCallback={getLines}
          getShapesCallback={getShapes}
          getCam={getCam}
          pointsConnect={pointsConnect}
          shapesConnect={shapesConnect}
          pointsEdit={pointsEdit}
          signalPoints={signalPoints}
          signalShapes={signalShapes}
          signalEditPoints={signalEditPoints}
          action={action}
          savedState={savedState}
          initShape={initShape}
        />

        <Dialog
          visible={visible}
          dialogAnimation={
            new SlideAnimation({
              slideFrom: "bottom",
            })
          }
          width={SCREEN_WIDTH * 0.8}
          onHardwareBackPress={() => true}
          footer={
            <DialogFooter>
              <DialogButton
                text="CANCEL"
                onPress={() => {
                  setVisible(false);
                  setPopUpComp(null);
                }}
                textStyle={{
                  fontSize: 15,
                  color: "red",
                }}
              />
              <DialogButton
                text="DONE"
                onPress={() => {
                  setVisible(false);
                  if (!isFromShape) {
                    if (action === "settings") {
                    } else if (
                      (action === "remove_points" || action === "add_points") &&
                      pointsEdit
                    )
                      onPointsEditPopUpDone();
                    else if (pointsConnect) onPointsPopUpDone();
                  } else {
                    if (shapesConnect) onShapesPopUpDone();
                  }
                  setPopUpComp(null);
                }}
                textStyle={{
                  fontSize: 15,
                  color: "green",
                }}
              />
            </DialogFooter>
          }
        >
          {popUpComp}
        </Dialog>
        <TouchableOpacity
          style={styles.back}
          onPress={() =>
            navigate.navigate(
              "App",
              {},
              NavigationActions.navigate({
                routeName: params ? "Items" : "Home",
              })
            )
          }
        >
          <Ionicons name="ios-arrow-round-back" color="white" size={42} />
        </TouchableOpacity>

        <Modal visible={showSettings} animationType="slide">
          <View
            style={{
              flex: 1,
              paddingHorizontal: 10,
              paddingVertical: 10,
              backgroundColor: "white",
            }}
          >
            <TouchableOpacity
              style={styles.backModal}
              onPress={() => {
                setShowSettings(() => false);
              }}
            >
              <Ionicons name="ios-arrow-round-back" color="black" size={42} />
            </TouchableOpacity>
            <SettingModal currShapes={currShapes} currPoints={currPoints} />
          </View>
        </Modal>
      </MenuDrawer>
    </SafeAreaView>
  );
}
Example #29
Source File: DrillPage.js    From UltimateApp with MIT License 4 votes vote down vote up
DrillPage = (props) => {
  const { route, navigation } = props;

  // Create Component refs
  const drillScrollView = useRef(null);
  const descriptionRef = useRef(null);

  // Get Header Height
  const headerHeight = useHeaderHeight();
  const screenDimension = Dimensions.get('window');
  const sizeBackground = screenDimension.height - headerHeight;
  const imageStyles = { ...styles.image, height: sizeBackground };

  const drillId = route.params.id;
  const drill = props.drills.find((drill) => drill.id == drillId);

  const startFitness = () => {
    navigation.navigate('FitnessPage', { drill });
  };

  const onPressStartButton = () => {
    if (drill.type === DrillTypes.FITNESS) {
      startFitness();
    } else {
      descriptionRef.current.measureLayout(findNodeHandle(drillScrollView.current), (x, y) => {
        drillScrollView.current.scrollTo({ x: 0, y, animated: true });
      });
    }
  };

  useLayoutEffect(() => {
    navigation.setOptions({
      title: drill.title,
      headerRight: () => <ShareDrill drill={drill} />,
      headerTitleContainerStyle: {
        ...Platform.select({
          ios: {
            marginRight: 50,
          },
        }),
      },
    });
  });

  let favoriteIcon = 'heart-outline';
  if (props.favoriteDrills.findIndex((item) => item.id === props.route.params.id) !== -1) {
    favoriteIcon = 'heart';
  }
  const imageSource = drill.custom && drill.image === undefined ? customDrillsImage : { uri: drill.image };

  return (
    <ScrollView ref={drillScrollView} style={styles.drillPage}>
      <ImageBackground source={imageSource} style={imageStyles} imageStyle={styles.imageOpacity}>
        <View style={styles.titleContainer}>
          <Text style={styles.title}>{drill.title}</Text>
          <Text style={styles.author}>{drill.author}</Text>
        </View>
        <View style={styles.infoWrapper}>
          <View style={styles.infoSubWrapper}>
            <Text style={styles.info}>{drill.durationInMinutes}</Text>
            <Text style={styles.info}>{I18n.t('drillPage.minutes')}</Text>
          </View>
          <View style={styles.separator} />
          <View style={styles.infoSubWrapper}>
            <Text style={styles.info}>{drill.minimalPlayersNumber}+</Text>
            <Text style={styles.info}>{I18n.t('drillPage.players')}</Text>
          </View>
          <View style={styles.separator} />
          <View style={styles.infoSubWrapper}>
            <Text style={styles.info}>{I18n.t(`data.levels.${drill.level}`)}</Text>
            <Text style={styles.info}>{I18n.t('drillPage.level')}</Text>
          </View>
        </View>
        <View style={styles.startButton}>
          <StartButton onPress={onPressStartButton} text={I18n.t('drillPage.start')} />
          <View style={styles.favoriteButton}>
            <TouchableOpacity onPress={() => props.toggleFavorite(drill)} testID="favoriteButton">
              <Ionicons name={favoriteIcon} color={theme.COLOR_PRIMARY_LIGHT} size={30} />
            </TouchableOpacity>
          </View>
        </View>
      </ImageBackground>
      <View ref={descriptionRef}>
        <Description drill={drill} />
      </View>
      <View style={styles.animation}>
        {drill.type === DrillTypes.FRISBEE && <FrisbeeDrillIllustration drill={drill} />}
        {drill.type === DrillTypes.FITNESS && <FitnessDrillIllustration drill={drill} startFitness={startFitness} />}
      </View>
    </ScrollView>
  );
}