Skip to content

Commit

Permalink
Add: Logging w/ error handling & alerting improvements on screens
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldanielecki committed Jul 11, 2022
1 parent c02daab commit 5d36840
Show file tree
Hide file tree
Showing 11 changed files with 435 additions and 95 deletions.
2 changes: 1 addition & 1 deletion common/writeItemToStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const writeItemToStorage: (eventsToAsyncStorage: Event[]) => Promise<void

try {
await AsyncStorage.setItem("EVENTS_ASYNC_STORAGE", eventsInJSONString);
} catch (error) {
} catch (error: unknown) {
if (error instanceof Error) {
console.error('useAsyncStorage getItem error:', error);
}
Expand Down
2 changes: 1 addition & 1 deletion components/SelectImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const SelectImage = (props: {
await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== "granted") {
Alert.alert(
"Insufficient permissions!",
"⚠️ Insufficient permissions! ⚠️",
"Sorry, we need camera roll permissions to make this work!",
[{ text: "Okay" }]
);
Expand Down
2 changes: 2 additions & 0 deletions ios/TamoTam.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
LastUpgradeCheck = 1130;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = 9D3QHQ7CMS;
LastSwiftMigration = 1250;
};
};
Expand Down Expand Up @@ -346,6 +347,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = TamoTam/TamoTam.entitlements;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 9D3QHQ7CMS;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
Expand Down
6 changes: 6 additions & 0 deletions ios/TamoTam.xcodeproj/xcshareddata/xcschemes/TamoTam.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
ReferencedContainer = "container:TamoTam.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-FIRDebugEnabled"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
22 changes: 21 additions & 1 deletion navigation/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import analytics from "@react-native-firebase/analytics";
import BottomTabNavigator from "./BottomTabNavigator";
import EditEventScreen from "../screens/EditEventScreen";
import EventDetailScreen from "../screens/EventDetailScreen";
import LinkingConfiguration from "./LinkingConfiguration";
import NewEventScreen from "../screens/NewEventScreen";
import NotFoundScreen from "../screens/NotFoundScreen";
import React from "react";
import React, { useRef } from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { ColorSchemeName } from "react-native";
import {
Expand All @@ -19,9 +20,28 @@ export default function Navigation({
}: {
colorScheme: ColorSchemeName;
}) {
const routeNameRef: any = useRef();
const navigationRef: any = useRef();

return (
<NavigationContainer
linking={LinkingConfiguration}
ref={navigationRef}
onReady={() => {
routeNameRef.current = navigationRef.current.getCurrentRoute().name;
}}
onStateChange={async () => {
const currentRouteName: any = navigationRef.current.getCurrentRoute().name;
const previousRouteName: any = routeNameRef.current;

if (previousRouteName !== currentRouteName) {
await analytics().logScreenView({
screen_name: currentRouteName,
screen_class: currentRouteName,
});
}
routeNameRef.current = currentRouteName;
}}
theme={colorScheme === "dark" ? DarkTheme : DefaultTheme}
>
<RootNavigator />
Expand Down
135 changes: 121 additions & 14 deletions screens/EditEventScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import * as Location from "expo-location";
import analytics from "@react-native-firebase/analytics";
import crashlytics from "@react-native-firebase/crashlytics";
import getAddressFromCoordinate from "../common/getAddressFromCoordinate";
import useColorScheme from "../hooks/useColorScheme";
import Colors from "../constants/Colors";
Expand All @@ -7,6 +10,7 @@ import MaterialHeaderButton from "../components/MaterialHeaderButton";
import MapView, { Marker, PROVIDER_GOOGLE } from "react-native-maps";
import SelectImage from "../components/SelectImage";
import React, {
useCallback,
useEffect,
useLayoutEffect,
useRef,
Expand All @@ -23,6 +27,7 @@ import {
Alert,
Dimensions,
KeyboardAvoidingView,
Platform,
ScrollView,
StyleSheet,
TextInput,
Expand All @@ -42,14 +47,14 @@ export default function EditEventScreen({ navigation, route }: any) {
const selectedEvent: Event = useSelector<any, any>((state: any) =>
state.events.savedEvents.find((event: Event) => event.id === eventId)
);
const initialRegionValue: Region = {
const [descriptionValue, setDescriptionValue] = useState<string>("");
const [error, setError] = useState<Error>(new Error());
const [initialRegionValue, setInitialRegionValue] = useState<Region>({
latitude: selectedEvent.coordinate.latitude,
longitude: selectedEvent.coordinate.longitude,
latitudeDelta: 10,
longitudeDelta: 10,
};
const [descriptionValue, setDescriptionValue] = useState<string>("");
const [error, setError] = useState<string>("");
});
const [isLoading, setIsLoading] = useState<boolean>(false);
const [selectedDate, setSelectedDate] = useState<any | Date>(
isNaN(Number(selectedEvent.date))
Expand All @@ -65,8 +70,16 @@ export default function EditEventScreen({ navigation, route }: any) {
};

useEffect(() => {
if (error) {
Alert.alert("An error occurred!", error, [{ text: "Okay" }]);
if (error.message !== "") {
Alert.alert(
"Unknown Error ❌",
"Please report this error by sending an email to us at feedback@tamotam.com. It will help us 🙏\nError details: " + error.message + "\nDate: " + new Date(),
[{ text: "Okay" }]
);
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> useEffect[error], error: " + error,
});
crashlytics().recordError(error);
}
}, [error]);

Expand All @@ -81,16 +94,82 @@ export default function EditEventScreen({ navigation, route }: any) {
iconName={
route.params && route.params.showIcon ? "arrow-back" : undefined
}
onPress={() => {
navigation.goBack();
}}
onPress={() => navigation.goBack()}
title="back"
/>
</HeaderButtons>
),
});
}, [navigation]);

const getUserLocationHandler: () => Promise<void> = useCallback(async () => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> getUserLocationHandler",
});
setError(new Error(""));
setIsLoading(true);

if (Platform.OS !== "web") {
const { status } =
await Location.requestForegroundPermissionsAsync();

analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> getUserLocationHandler, status: " + status,
});
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> getUserLocationHandler, Platform.OS: " + Platform.OS,
});
if (status !== "granted") {
Alert.alert(
"⚠️ Insufficient permissions! ⚠️",
"Sorry, we need location permissions to make this work!",
[{ text: "Okay" }]
);
return;
}
}

try {
const location = await Location.getCurrentPositionAsync({});

analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> getUserLocationHandler -> try, location: " + location,
});
setInitialRegionValue({
latitude: location.coords.latitude,
longitude: location.coords.longitude,
latitudeDelta: 10,
longitudeDelta: 10,
});
} catch (error: unknown) {
if (error instanceof Error) {
Alert.alert(
"Error ❌",
"We couldn't fetch your location.\nPlease give us the permissions, and it's essential to use TamoTam!",
[{ text: "Okay" }]
);

analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> getUserLocationHandler -> catch, error: " + error,
});
crashlytics().recordError(error);
setError(new Error(error.message));
}
} finally {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> getUserLocationHandler -> finally",
});
setIsLoading(false);
}
}, [dispatch, setError, setIsLoading]);

useEffect(() => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> useEffect[getUserLocationHandler]",
});
getUserLocationHandler();
}, [getUserLocationHandler]);

if (isLoading) {
return (
<View style={styles.centered}>
Expand All @@ -112,17 +191,26 @@ export default function EditEventScreen({ navigation, route }: any) {
const onDescriptionChange: (text: SetStateAction<string>) => void = (
text: SetStateAction<string>
) => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onDescriptionChange, text: " + text,
});
setDescriptionValue(text);
};

const onDateChange: (
_event: any,
selectedValueDate: Date | undefined
) => void = (_event: any, selectedValueDate: Date | undefined) => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onDateChange, selectedValueDate: " + selectedValueDate,
});
setSelectedDate(selectedValueDate);
};

const onImageChange: (imagePath: string) => void = (imagePath: string) => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onImageChange, imagePath: " + imagePath,
});
setSelectedImage(imagePath);
};

Expand All @@ -131,6 +219,9 @@ export default function EditEventScreen({ navigation, route }: any) {
coordinate: Coordinate;
};
}) => void = (e: { nativeEvent: { coordinate: Coordinate } }) => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onLocationChange, e.nativeEvent.coordinate: " + e.nativeEvent.coordinate,
});
setSelectedLocation({
latitude: e.nativeEvent.coordinate.latitude,
longitude: e.nativeEvent.coordinate.longitude,
Expand All @@ -140,11 +231,17 @@ export default function EditEventScreen({ navigation, route }: any) {
const onTitleChange: (text: SetStateAction<string>) => void = (
text: SetStateAction<string>
) => {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onTitleChange, text: " + text,
});
setTitleValue(text);
};

const onSaveHandler: () => void = () => {
setError("");
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onSaveHandler",
});
setError(new Error(""));
setIsLoading(true);

try {
Expand All @@ -163,18 +260,28 @@ export default function EditEventScreen({ navigation, route }: any) {
title: titleValue ? titleValue : selectedEvent.title,
};

analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onSaveHandler -> try, newEvent: " + newEvent,
});
dispatch(updateEvent(newEvent));
} catch (err) {
if (err instanceof Error) {
} catch (error: unknown) {
if (error instanceof Error) {
Alert.alert(
"An error occurred ❌",
"Error ❌",
"TamoTam couldn't save the changes.\nTry one more time!",
[{ text: "Okay" }]
);

setError(err.message);
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onSaveHandler -> catch, error: " + error,
});
crashlytics().recordError(error);
setError(new Error(error.message));
}
} finally {
analytics().logEvent("custom_log", {
description: "--- Analytics: EditEventScreen -> onSaveHandler -> finally",
});
setIsLoading(false);
}

Expand Down
3 changes: 2 additions & 1 deletion screens/EventDetailScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import analytics from "@react-native-firebase/analytics";
import getAddressFromCoordinate from "../common/getAddressFromCoordinate";
import useColorScheme from "../hooks/useColorScheme";
import Colors from "../constants/Colors";
Expand All @@ -14,7 +15,7 @@ import { HeaderButtons, Item } from "react-navigation-header-buttons";
import { Region } from "../interfaces/region";
import { View } from "../components/Themed";

export default function PlaceDetailScreen({ navigation, route }: any) {
export default function EventDetailScreen({ navigation, route }: any) {
const colorScheme: "light" | "dark" = useColorScheme();
const eventId: number = route.params.eventId;
const mapRef: MutableRefObject<null> = useRef<null>(null);
Expand Down

0 comments on commit 5d36840

Please sign in to comment.