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 |
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 |
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 |
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 |
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>
);
}