Remove loading indicator where load times are fast

If the load time is too fast (on a mid-tier device),
then for most people they will see a flicker of a
loading spinner (which looks like a bug). These indicators
would only marginally improve the experience of people with
the slowest devices, but for most people this will just look
like a bug.

I left the indicators in the InsightsPage since those queries
actually do take >=300ms on a mid-tier device.
This commit is contained in:
Brandon Presley 2023-11-15 15:53:32 +13:00
parent b44cbae131
commit 1b164aaaf1
5 changed files with 38 additions and 42 deletions

View File

@ -6,12 +6,7 @@ import {
} from "@react-navigation/native";
import { useCallback, useEffect, useState } from "react";
import { Pressable, StyleSheet, View } from "react-native";
import {
ActivityIndicator,
IconButton,
Switch as PaperSwitch,
Text,
} from "react-native-paper";
import { IconButton, Switch as PaperSwitch, Text } from "react-native-paper";
import ReorderableList, {
ReorderableListRenderItemInfo,
} from "react-native-reorderable-list";
@ -171,9 +166,7 @@ export default function EditPlan() {
{DAYS.map((day) => renderDay(day))}
<Text style={[styles.title, { marginTop: MARGIN }]}>Exercises</Text>
{names === undefined ? (
<ActivityIndicator />
) : (
{names !== undefined && (
<ReorderableList
data={names}
ListEmptyComponent={<Text>No exercises yet</Text>}

View File

@ -25,6 +25,8 @@ interface HourCount {
export default function InsightsPage() {
const [weekCounts, setWeekCounts] = useState<WeekCount[]>();
const [hourCounts, setHourCounts] = useState<HourCount[]>();
const [loadingWeeks, setLoadingWeeks] = useState(true);
const [loadingHours, setLoadingHours] = useState(true);
const [period, setPeriod] = useState(Periods.Monthly);
const [showWeek, setShowWeek] = useState(false);
const [showHour, setShowHour] = useState(false);
@ -53,14 +55,22 @@ export default function InsightsPage() {
ORDER BY hour
`;
setLoadingWeeks(true);
setLoadingHours(true);
setTimeout(
() =>
AppDataSource.manager
.query(selectWeeks)
.then(setWeekCounts)
.then(() => setLoadingWeeks(false))
.then(() =>
AppDataSource.manager.query(selectHours).then(setHourCounts)
),
)
.then(() => setLoadingHours(false))
.finally(() => {
setLoadingWeeks(false);
setLoadingHours(false);
}),
400
);
}, [period])
@ -126,9 +136,9 @@ export default function InsightsPage() {
/>
</View>
{weekCounts === undefined && <ActivityIndicator />}
{weekCounts?.length > 0 && (
{loadingWeeks ? (
<ActivityIndicator />
) : (
<AppPieChart
options={weekCounts.map((weekCount) => ({
label: DAYS[weekCount.week],
@ -136,6 +146,7 @@ export default function InsightsPage() {
}))}
/>
)}
{weekCounts?.length === 0 && (
<Text style={{ marginBottom: MARGIN }}>
No entries yet! Start recording sets to see your most active days of
@ -166,14 +177,15 @@ export default function InsightsPage() {
/>
</View>
{hourCounts === undefined && <ActivityIndicator />}
{hourCounts?.length > 0 && (
{loadingHours ? (
<ActivityIndicator />
) : (
<Chart
data={hourCounts.map((hc) => hc.count)}
labels={hourCounts.map((hc) => hourLabel(hc.hour))}
/>
)}
{hourCounts?.length === 0 && (
<Text>
No entries yet! Start recording sets to see your most active hours

View File

@ -5,16 +5,16 @@ import {
} from "@react-navigation/native";
import { useCallback, useState } from "react";
import { FlatList } from "react-native";
import { ActivityIndicator, List } from "react-native-paper";
import { List } from "react-native-paper";
import { Like } from "typeorm";
import { StackParams } from "./AppStack";
import { LIMIT } from "./constants";
import { getNow, setRepo, settingsRepo } from "./db";
import DrawerHeader from "./DrawerHeader";
import GymSet, { defaultSet } from "./gym-set";
import ListMenu from "./ListMenu";
import Page from "./Page";
import SetItem from "./SetItem";
import { LIMIT } from "./constants";
import { getNow, setRepo, settingsRepo } from "./db";
import GymSet, { defaultSet } from "./gym-set";
import Settings from "./settings";
export default function SetList() {
@ -134,7 +134,7 @@ export default function SetList() {
}, [sets, ids]);
const getContent = () => {
if (!settings || sets === undefined) return <ActivityIndicator />;
if (!settings || sets === undefined) return null;
if (sets.length === 0)
return (
<List.Item

View File

@ -7,16 +7,14 @@ import {
} from "@react-navigation/native";
import { useCallback, useMemo, useRef, useState } from "react";
import { FlatList, NativeModules, TextInput, View } from "react-native";
import {
ActivityIndicator,
Button,
IconButton,
ProgressBar,
useTheme,
} from "react-native-paper";
import { check, PERMISSIONS, request, RESULTS } from "react-native-permissions";
import { IconButton, ProgressBar } from "react-native-paper";
import { PERMISSIONS, RESULTS, check, request } from "react-native-permissions";
import AppInput from "./AppInput";
import { StackParams } from "./AppStack";
import PrimaryButton from "./PrimaryButton";
import Select from "./Select";
import StackHeader from "./StackHeader";
import StartPlanItem from "./StartPlanItem";
import { getBestSet } from "./best.service";
import { PADDING } from "./constants";
import { convert } from "./conversions";
@ -25,12 +23,8 @@ import { AppDataSource } from "./data-source";
import { getNow, setRepo, settingsRepo } from "./db";
import { fixNumeric } from "./fix-numeric";
import GymSet from "./gym-set";
import Select from "./Select";
import Settings from "./settings";
import StackHeader from "./StackHeader";
import StartPlanItem from "./StartPlanItem";
import { toast } from "./toast";
import PrimaryButton from "./PrimaryButton";
export default function StartPlan() {
const { params } = useRoute<RouteProp<StackParams, "StartPlan">>();
@ -40,7 +34,6 @@ export default function StartPlan() {
const [selected, setSelected] = useState(0);
const [settings, setSettings] = useState<Settings>();
const [counts, setCounts] = useState<CountMany[]>();
const { colors } = useTheme();
const weightRef = useRef<TextInput>(null);
const repsRef = useRef<TextInput>(null);
const exercises = useMemo(() => params.plan.exercises.split(","), [params]);
@ -222,9 +215,7 @@ export default function StartPlan() {
label="Unit"
/>
)}
{counts === undefined ? (
<ActivityIndicator />
) : (
{counts !== undefined && (
<FlatList
data={counts}
keyExtractor={(count) => count.name}

View File

@ -3,18 +3,18 @@ import { format } from "date-fns";
import { useEffect, useMemo, useState } from "react";
import { View } from "react-native";
import { FileSystem } from "react-native-file-access";
import { ActivityIndicator, IconButton, List } from "react-native-paper";
import { IconButton, List } from "react-native-paper";
import Share from "react-native-share";
import { captureScreen } from "react-native-view-shot";
import { StackParams } from "./AppStack";
import Chart from "./Chart";
import Select from "./Select";
import StackHeader from "./StackHeader";
import { PADDING } from "./constants";
import { setRepo } from "./db";
import GymSet from "./gym-set";
import { Metrics } from "./metrics";
import { Periods } from "./periods";
import Select from "./Select";
import StackHeader from "./StackHeader";
import Volume from "./volume";
export default function ViewGraph() {
@ -76,7 +76,7 @@ export default function ViewGraph() {
}, [params.name, metric, period]);
const weightChart = useMemo(() => {
if (weights === undefined) return <ActivityIndicator />;
if (weights === undefined) return null;
let periodFormat = "do";
if (period === Periods.Weekly) periodFormat = "iii";
@ -95,7 +95,7 @@ export default function ViewGraph() {
}, [weights, period]);
const volumeChart = useMemo(() => {
if (volumes === undefined) return <ActivityIndicator />;
if (volumes === undefined) return null;
let periodFormat = "do";
if (period === Periods.Weekly) periodFormat = "iii";