react-native-safe-area-context#useSafeArea JavaScript Examples

The following examples show how to use react-native-safe-area-context#useSafeArea. 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: Page.js    From juken with MIT License 5 votes vote down vote up
Page = ({
  center,
  children,
  style,
}) => {
  const insets = useSafeArea();

  // general padding around container
  let pTop = theme.padding.body + insets.top;
  let pBottom = theme.padding.body + insets.bottom;
  let pLeft = theme.padding.body + insets.left;
  let pRight = theme.padding.body + insets.right;

  // responsive paddings
  const {
    desktop,
    tablet,
    mobile,
  } = media();
  
  if (desktop) {
    pTop = '4%';
    pBottom = center ? '4%' : '2.5%';
    pLeft = '32%';
    pRight = '32%';
  }
  if (tablet) {
    pTop = '6%';
    pBottom = center ? '6%' : '4%';
    pLeft = '22%';
    pRight = '22%';
  }
  if (mobile) {
    pTop = '8%';
    pBottom = center ? '8%' : '6%';
    pLeft = '8%';
    pRight = '8%';
  }

  return (
    <View
      style={[
        {
          paddingTop: pTop,
          paddingLeft: pLeft,
          paddingBottom: pBottom,
          paddingRight: pRight,
        },
        styles.wrapper,
        style,
      ]}
    >
      {children}
    </View>
  )
}
Example #2
Source File: Tabs.js    From MediBuddy with MIT License 5 votes vote down vote up
function Tabs() {
  const isFocused = useIsFocused();
  const safeArea = useSafeArea();
  let tabBarProps = {};

  if (isTablet) {
    tabBarProps = {
      tabBar: props => <TabBar {...props} />,
    };
  }

  return (
    <React.Fragment>
      <Tab.Navigator
        initialRouteName="Feed"
        shifting={true}
        labeled={false}
        sceneAnimationEnabled={false}
        activeColor="#00aea2"
        inactiveColor="#95a5a6"
        barStyle={{ backgroundColor: '#ffff' }}
        {...tabBarProps}>
        <Tab.Screen
          name="Appointments"
          component={MyAppointments}
          options={{
            tabBarIcon: 'calendar-clock',
          }}
        />

        <Tab.Screen
          name="Patients"
          component={Patients}
          options={{
            tabBarIcon: 'account-multiple',
          }}
        />
        <Tab.Screen
          name="Departments"
          component={Departments}
          options={{
            tabBarIcon: 'layers',
          }}
        />
        <Tab.Screen
          name="Reports"
          component={Reports}
          options={{
            tabBarIcon: 'book-open',
          }}
        />
      </Tab.Navigator>
      <Portal>
        <FAB
          visible={isFocused} // show FAB only when this screen is focused
          icon="plus-box"
          label={isTablet ? 'Create new' : null}
          style={[
            styles.fab,
            {
              bottom: safeArea.bottom + 65,
            },
          ]}
        />
      </Portal>
    </React.Fragment>
  );
}
Example #3
Source File: recorder.js    From intentional-walk with MIT License 4 votes vote down vote up
export default function Recorder(props) {
  const {activeWalk} = props;
  const safeAreaInsets = useSafeArea();
  const [data, setData] = useState(null);
  const [now, setNow] = useState(new Date());
  const [pause, setPause] = useState(null);
  const isPausedRef = useRef(false);
  const [end, setEnd] = useState(null);

  useEffect(() => {
    Pedometer.startUpdates(newData => {
      if (!isPausedRef.current) {
        setData(newData);
        Realm.updateCurrentWalk(newData);
      }
    });
    return () => Pedometer.stopUpdates();
  }, []);

  useEffect(() => {
    const interval = setInterval(() => setNow(new Date()), 500);
    return () => clearInterval(interval);
  }, []);

  const onPause = () => {
    setPause(new Date());
    isPausedRef.current = true;
  };

  const onResume = () => {
    Realm.open().then(realm => {
      realm.write(() => {
        activeWalk.pause =
          (activeWalk.pause || 0) + moment(now).diff(pause, 'seconds');
        isPausedRef.current = false;
        setPause(null);
        setEnd(null);
      });
    });
  };

  const onStop = () => {
    let newEnd;
    if (pause) {
      newEnd = pause;
    } else {
      newEnd = new Date();
      setPause(newEnd);
      isPausedRef.current = true;
    }
    setEnd(newEnd);
    //// get one final update
    Pedometer.getPedometerData(newEnd).then(newData => {
      setData(newData);
      Realm.updateCurrentWalk(newData);
    });
  };

  const onFinish = () => {
    if (end) {
      Pedometer.stopUpdates();
      Realm.stopWalk(end, data);
    }
  };

  let dt = 0,
    elapsedTime;
  if (activeWalk) {
    let compare = now;
    if (end) {
      compare = end;
    } else if (pause) {
      compare = pause;
    }
    dt = moment(compare).diff(activeWalk.start, 'seconds');
    if (activeWalk.pause) {
      dt -= activeWalk.pause;
    }
  }
  const sec = dt % 60;
  const min = Math.floor(dt / 60);
  elapsedTime = `${min < 10 ? '0' : ''}${min}:${sec < 10 ? '0' : ''}${sec}`;

  let headerColor = Colors.primary.lightGreen;
  let headerText = Strings.recorder.recording;
  if (end) {
    headerColor = Colors.secondary.red;
    headerText = Strings.formatString(
      Strings.recorder.save,
      activeWalk.timeOfWalk,
    );
  } else if (pause) {
    headerColor = Colors.accent.yellow;
    headerText = Strings.recorder.paused;
  }
  return (
    <View pointerEvents="box-none" style={[styles.container, props.style]}>
      <View style={[styles.header, {backgroundColor: headerColor}]}>
        <Text style={[GlobalStyles.h2, styles.headerText]}>{headerText}</Text>
      </View>
      <View style={styles.body}>
        <View>
          <Text style={styles.count}>{elapsedTime}</Text>
          <Text style={styles.label}>{Strings.common.mins}</Text>
        </View>
        <View>
          <Text style={styles.count}>
            {numeral(activeWalk.distance * 0.000621371).format('0.0')}
          </Text>
          <Text style={styles.label}>{Strings.common.miles}</Text>
        </View>
        <View>
          <Text style={styles.count}>{activeWalk.steps}</Text>
          <Text style={styles.label}>{Strings.common.steps}</Text>
        </View>
        <View style={[styles.stopButtonRow, end ? styles.show : styles.hide]}>
          <Button
            onPress={onResume}
            style={styles.resumeButton}
            textStyle={{color: Colors.primary.purple}}>
            {Strings.recorder.resume}
          </Button>
          <Button onPress={onFinish} style={styles.finishButton}>
            {Strings.recorder.finish}
          </Button>
        </View>
      </View>
      {!end && (
        <View
          style={[
            styles.buttonsContainer,
            {paddingBottom: safeAreaInsets.bottom},
          ]}>
          <View style={styles.secondaryButtonContainer} />
          {pause && (
            <View style={styles.primaryButtonContainer}>
              <TouchableOpacity onPress={onResume}>
                <Image
                  style={styles.primaryButton}
                  source={require('../assets/record.png')}
                />
              </TouchableOpacity>
              <Text style={[styles.buttonText, styles.resumeText]}>
                {Strings.recorder.resume}
              </Text>
            </View>
          )}
          {!pause && (
            <View style={styles.primaryButtonContainer}>
              <TouchableOpacity onPress={onStop}>
                <Image
                  style={styles.primaryButton}
                  source={require('../assets/stop.png')}
                />
              </TouchableOpacity>
              <Text style={[styles.buttonText, styles.recordText]}>
                {Strings.recorder.stopAndSave}
              </Text>
            </View>
          )}
          {pause && (
            <View style={styles.secondaryButtonContainer}>
              <TouchableOpacity onPress={onStop} style={styles.primaryButton}>
                <Image
                  style={styles.secondaryButton}
                  source={require('../assets/stop.png')}
                />
              </TouchableOpacity>
              <Text style={[styles.buttonText, styles.recordText]}>
                {Strings.recorder.stop}
              </Text>
            </View>
          )}
          {!pause && (
            <View style={styles.secondaryButtonContainer}>
              <TouchableOpacity onPress={onPause} style={styles.primaryButton}>
                <Image
                  style={styles.secondaryButton}
                  source={require('../assets/pause.png')}
                />
              </TouchableOpacity>
              <Text style={[styles.buttonText, styles.pauseText]}>
                {Strings.recorder.pause}
              </Text>
            </View>
          )}
        </View>
      )}
    </View>
  );
}
Example #4
Source File: home.js    From intentional-walk with MIT License 4 votes vote down vote up
export default function HomeScreen({navigation}) {
  const safeAreaInsets = useSafeArea();

  const dateRef = useRef(moment().startOf('day'));
  const [date, setDate] = useState(dateRef.current);

  const [dailyWalks, setDailyWalks] = useState(null);
  const [todaysWalk, setTodaysWalk] = useState(null);
  const [totalSteps, setTotalSteps] = useState(null);

  const [contest, setContest] = useState(null);

  const [recordedWalks, setRecordedWalks] = useState(null);
  const [activeWalk, setActiveWalk] = useState(null);

  async function saveStepsAndDistances() {
    const newContest = await Realm.getContest();
    const today = moment().endOf('day');
    if (newContest) {
      let from = null;
      let to = null;
      /// check if we're in/after the contest period
      if (!newContest.isBeforeBaselineDate) {
        from = moment(newContest.startBaseline);
        /// check if we're in the contest period
        if (newContest.isAfterEndDate) {
          to = moment(newContest.end);
        } else {
          to = today;
        }
      }
      /// only save when within contest period
      if (from && to) {
        const newDailyWalks = await Fitness.getStepsAndDistances(from, to);
        if (newDailyWalks && newDailyWalks.length > 0) {
          /// get user account, then save to server...!
          const user = await Realm.getUser();
          if (user) {
            try {
              await Api.dailyWalk.create(newDailyWalks, user.id);
            } catch (error) {
              console.log(error);
            }
          }
        }
      }
    }
  }

  async function getStepsAndDistances(queryDate, currentDailyWalks) {
    setTodaysWalk(null);
    if (currentDailyWalks == null) {
      setDailyWalks(true);
      try {
        const newDailyWalks = await Fitness.getStepsAndDistances(
          moment(dateRef.current).startOf('month'),
          moment(dateRef.current).endOf('month'),
        );
        if (
          moment(dateRef.current)
            .startOf('month')
            .isSame(moment(queryDate).startOf('month'))
        ) {
          setDailyWalks(newDailyWalks);
          getStepsAndDistances(dateRef.current, newDailyWalks);
        }
      } catch (error) {
        console.log(error);
      }
    } else if (Array.isArray(currentDailyWalks)) {
      let newTodaysWalk = {
        steps: 0,
        distance: 0,
      };
      let from = moment(queryDate).startOf('day');
      let to = moment(from).endOf('day');
      for (let dailyWalk of currentDailyWalks) {
        if (
          from.isSameOrBefore(dailyWalk.date) &&
          to.isSameOrAfter(dailyWalk.date)
        ) {
          newTodaysWalk = dailyWalk;
          break;
        }
      }
      setTodaysWalk(newTodaysWalk);
    }
  }

  async function getTotalSteps() {
    setTotalSteps(null);
    /// get current contest
    const newContest = await Realm.getContest();
    const now = moment();
    let from = null,
      to = null;
    /// check if we're in/outside the contest period
    if (newContest && newContest.isDuringContest) {
      /// get total from start of contest until now
      from = moment(newContest.start);
      to = now;
    } else {
      /// get total from start of month
      from = moment().startOf('month');
      to = now;
    }
    if (from && to) {
      let newTotalSteps = 0;
      try {
        const steps = await Fitness.getSteps(from, to);
        for (let step of steps) {
          newTotalSteps += step.quantity;
        }
      } finally {
        setTotalSteps(newTotalSteps);
      }
    } else {
      /// no range, just show 0
      setTotalSteps(0);
    }
  }

  async function getRecordedWalks(queryDate) {
    const realm = await Realm.open();
    const newRecordedWalks = realm
      .objects('IntentionalWalk')
      .filtered(
        'start>=$0 AND end<$1',
        queryDate.toDate(),
        moment(queryDate).add(1, 'd').toDate(),
      )
      .sorted([['end', true]]);
    if (dateRef.current.isSame(queryDate)) {
      setRecordedWalks(newRecordedWalks);
    }
  }

  function setDateAndGetDailySteps(newDate) {
    const oldDate = dateRef.current;
    dateRef.current = newDate;
    setDate(newDate);

    let newDailyWalks = dailyWalks;
    if (!oldDate.startOf('month').isSame(moment(newDate).startOf('month'))) {
      newDailyWalks = null;
    }
    getStepsAndDistances(newDate, newDailyWalks);
    getRecordedWalks(newDate);
  }

  function refresh() {
    const today = moment().startOf('day');
    dateRef.current = moment(dateRef.current);
    if (dateRef.current.isAfter(today)) {
      dateRef.current = today;
    }
    setDate(dateRef.current);
    getStepsAndDistances(dateRef.current, null);
    getTotalSteps();
    getRecordedWalks(dateRef.current);
    saveStepsAndDistances();
  }

  /// one time setup for some data store listeners
  useEffect(() => {
    /// listen for an active walk
    let isFirstLoad = true;
    Realm.addCurrentWalkListener(walk => {
      setActiveWalk(walk);
      if (!isFirstLoad && walk == null) {
        /// if we've just finished a walk, then refresh to update step counts
        refresh();
      }
      isFirstLoad = false;
    });
    /// listen for updates to contest info
    Realm.addContestListener(newContest =>
      newContest ? setContest(newContest.toObject()) : null,
    );
    /// on cleanup, remove listeners
    return () => Realm.removeAllListeners();
  }, []);

  /// perform a bunch of other one-time checks/setup on app launch
  useEffect(() => {
    SplashScreen.hide();
    /// load settings
    Realm.getSettings().then(settings => {
      const lang = settings.lang;
      if (lang) {
        /// set language preference, if any
        Strings.setLanguage(lang);
        /// recreate the date in the current locale
        moment.locale(lang);
        dateRef.current = moment(dateRef.current);
        setDate(dateRef.current);
      }
    });
    /// get signed in user, if any
    Realm.getUser().then(user => {
      /// if no user, go to onboarding flow
      if (!user) {
        navigation.navigate('OnboardingStack');
      } else if (!user.isSurveyCompleted) {
        navigation.navigate('OnboardingStack', {
          screen: 'LoHOrigin',
          params: {initial: true},
        });
      }
    });
    /// check for updated contest info
    Realm.updateContest();
  }, []);

  useFocusEffect(
    React.useCallback(() => {
      refresh();
    }, []),
  );

  const today = moment().startOf('day');
  const isToday = date.isSame(today);

  return (
    <View style={GlobalStyles.container}>
      {!activeWalk && (
        <>
          <ScrollView>
            <View
              style={[
                GlobalStyles.content,
                {paddingBottom: safeAreaInsets.bottom + 20 + 17 + 10 + 54},
              ]}>
              <DateNavigator
                style={styles.marginBottom}
                date={date}
                setDate={setDateAndGetDailySteps}
              />
              {contest && contest.isBeforeStartDate && (
                <View style={styles.marginBottom}>
                  <Text style={styles.alertText}>
                    {Strings.home.getReadyAlert1}
                  </Text>
                  <Text style={styles.alertText}>
                    {Strings.formatString(
                      Strings.home.getReadyAlert2,
                      moment(contest.start).format(Strings.common.date),
                    )}
                  </Text>
                </View>
              )}
              {contest && contest.isDuringContest && (
                <View style={styles.marginBottom}>
                  <Text style={styles.alertText}>
                    {Strings.formatString(
                      Strings.home.currentAlert,
                      moment(contest.start).format(Strings.common.date),
                      moment(contest.end).format(Strings.common.date),
                    )}
                  </Text>
                </View>
              )}
              {contest && contest.isWeekAfterEndDate && (
                <View style={styles.marginBottom}>
                  <Text style={styles.alertText}>
                    {Strings.formatString(Strings.home.congratsAlert)}
                  </Text>
                </View>
              )}
              {contest &&
                contest.isAfterEndDate &&
                !contest.isWeekAfterEndDate && (
                  <View style={styles.marginBottom}>
                    <Text style={styles.alertText}>
                      {Strings.formatString(Strings.home.noContestAlert)}
                    </Text>
                  </View>
                )}
              <View style={styles.row}>
                <StatBox
                  mainText={
                    todaysWalk ? numeral(todaysWalk.steps).format('0,0') : ' '
                  }
                  subText={
                    isToday ? Strings.home.stepsToday : Strings.common.steps
                  }
                  icon="directions-walk"
                  iconSize={140}
                  iconStyle={styles.walkIcon}
                  style={[
                    styles.stepsBox,
                    styles.box,
                    isToday ? null : styles.stepsBoxRounded,
                  ]}
                  boxColor={Colors.accent.teal}
                />
                <StatBox
                  mainText={
                    todaysWalk
                      ? numeral(todaysWalk.distance * 0.000621371).format(
                          '0,0.0',
                        )
                      : ' '
                  }
                  mainTextSuffix={Strings.home.milesSuffix}
                  subText={
                    isToday ? Strings.home.milesToday : Strings.common.miles
                  }
                  icon="swap-calls"
                  iconSize={200}
                  iconStyle={styles.milesIcon}
                  style={[
                    styles.milesBox,
                    styles.box,
                    isToday ? null : styles.milesBoxRounded,
                  ]}
                  boxColor={Colors.primary.lightGreen}
                />
              </View>
              <View
                style={[styles.row, isToday ? null : styles.hidden]}
                pointerEvents={isToday ? 'auto' : 'none'}>
                <StatBox
                  mainText={
                    totalSteps != null ? numeral(totalSteps).format('0,0') : ' '
                  }
                  subText={
                    contest && contest.isDuringContest
                      ? Strings.home.overallStepTotal
                      : Strings.home.stepsThisMonth
                  }
                  icon="star-border"
                  iconSize={200}
                  style={[styles.overallBox, styles.box]}
                  boxColor={Colors.accent.orange}
                />
              </View>
              <View
                style={[styles.row, isToday ? null : styles.hidden]}
                pointerEvents={isToday ? 'auto' : 'none'}>
                <TouchableOpacity
                  style={styles.box}
                  onPress={() => navigation.navigate('WhereToWalk')}>
                  <View style={styles.walkBox}>
                    <Text style={styles.walkText}>
                      {Strings.home.whereToWalk}
                    </Text>
                    <Icon
                      style={styles.walkChevron}
                      name="chevron-right"
                      size={30}
                    />
                  </View>
                </TouchableOpacity>
              </View>
              <View style={[styles.subtitle]}>
                <Text style={styles.subtitleHeader}>
                  {Strings.home.myRecordedWalks}
                </Text>
                <Text
                  style={styles.subtitleLink}
                  onPress={() => navigation.navigate('RecordedWalks')}>
                  {Strings.home.allRecordedWalks}
                </Text>
              </View>
              {recordedWalks && recordedWalks.length === 0 && (
                <RecordedWalk
                  title={
                    isToday ? Strings.common.noWalksYet : Strings.common.noWalks
                  }
                  subtitle={isToday ? Strings.home.noWalksYetText : null}
                />
              )}
              {recordedWalks &&
                recordedWalks.length > 0 &&
                recordedWalks.map(walk => (
                  <RecordedWalk key={walk.id} walk={walk} />
                ))}
            </View>
          </ScrollView>
          <View
            pointerEvents={isToday ? 'box-none' : 'none'}
            style={[
              styles.recordContainer,
              {paddingBottom: safeAreaInsets.bottom},
              isToday ? null : styles.hidden,
            ]}>
            <TouchableOpacity onPress={() => Realm.startWalk()}>
              <Image
                style={styles.recordButton}
                source={require('../../assets/record.png')}
              />
            </TouchableOpacity>
            <Text style={styles.recordText}>{Strings.home.recordAWalk}</Text>
          </View>
        </>
      )}
      {activeWalk && (
        <Recorder
          style={[styles.recorder, {paddingBottom: safeAreaInsets.bottom}]}
          activeWalk={activeWalk}
        />
      )}
    </View>
  );
}