Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error popups #115

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
87 changes: 67 additions & 20 deletions app/src/components/common/ConfirmModal.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,50 @@
import React from "react";

import { TouchableOpacity } from "react-native";
import { Button, Layout, ModalService, Text } from "@ui-kitten/components";
import { Button, Layout, Modal, ModalService, Spinner, Text } from "@ui-kitten/components";
import tailwind from "tailwind-rn";

interface ConfirmModalProps {
message: string;
buttonText: string;
isLoading?: boolean;
loadingMessage?: string;
onPressConfirm: () => void;
onPressCancel?: () => void;
status?: "basic" | "primary" | "success" | "info" | "warning" | "danger" | "control";
}
export const showConfirmModal = ({ message, buttonText, onPressConfirm, onPressCancel, status }: ConfirmModalProps): void => {
const ConfirmModalComponent = ({ message, buttonText, isLoading, loadingMessage, onPressConfirm, onPressCancel, status = "primary" }: ConfirmModalProps) => {
return (
<TouchableOpacity
style={tailwind("w-full h-full flex flex-col items-center justify-center bg-black bg-opacity-50")}
onPress={onPressCancel}
>
<Layout style={tailwind("flex flex-col items-center bg-white py-4 rounded-2xl w-3/4")}>
<Text style={tailwind("my-1")}>
{isLoading ? (loadingMessage ?? message) : message}
</Text>
<Layout style={tailwind("flex flex-col justify-around my-1")}>
{isLoading
? (
<Spinner size="giant" />
) : (
<>
<Button onPress={onPressConfirm} status={status} appearance="ghost" size="large">
{buttonText}
</Button>
<Button onPress={onPressCancel} status="basic" appearance="ghost">
Cancel
</Button>
</>
)}
</Layout>
</Layout>
</TouchableOpacity>
)
}

type ConfirmModalMethodProps = Omit<ConfirmModalProps, "isLoading" | "loadingMessage">;
export const showConfirmModal = ({ message, buttonText, onPressConfirm, onPressCancel, status }: ConfirmModalMethodProps): void => {
let modalId = ''

const hideModal = () => ModalService.hide(modalId)
Expand All @@ -27,26 +60,40 @@ export const showConfirmModal = ({ message, buttonText, onPressConfirm, onPressC
};

modalId = ModalService.show(
<TouchableOpacity
style={tailwind("w-full h-full flex flex-col items-center justify-center bg-black bg-opacity-50")}
onPress={pressCancel}
>
<Layout style={tailwind("flex flex-col items-center bg-white py-4 rounded-2xl w-3/4")}>
<Text style={tailwind("my-1")}>
{message}
</Text>
<Layout style={tailwind("flex flex-col justify-around mt-1")}>
<Button onPress={pressConfirm} status={status} appearance="ghost" size="large">
{buttonText}
</Button>
<Button onPress={pressCancel} status="basic" appearance="ghost">
Cancel
</Button>
</Layout>
</Layout>
</TouchableOpacity>,
<ConfirmModalComponent
message={message}
buttonText={buttonText}
onPressConfirm={pressConfirm}
onPressCancel={pressCancel}
status={status}
/>,
{
onBackdropPress: pressCancel,
}
);
}

interface ConfirmModalComponentProps extends ConfirmModalProps {
visible: boolean;
hideModal: () => void;
}
export const ConfirmModal = ({ visible, hideModal, message, buttonText, isLoading, loadingMessage, onPressCancel, onPressConfirm, status }: ConfirmModalComponentProps): JSX.Element => {
const pressCancel = () => {
onPressCancel && onPressCancel();
hideModal();
};

return (
<Modal visible={visible} style={tailwind("flex-1 w-full h-full")}>
<ConfirmModalComponent
message={message}
buttonText={buttonText}
isLoading={isLoading}
loadingMessage={loadingMessage}
onPressConfirm={onPressConfirm}
onPressCancel={pressCancel}
status={status}
/>
</Modal>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { StackScreenProps } from "@react-navigation/stack";
import { Button, CheckBox, Icon, IconProps, Input, Layout, Spinner, Text } from "@ui-kitten/components";
import React, { useState } from "react";
import { Keyboard, SafeAreaView } from "react-native";
import { Keyboard, SafeAreaView, ToastAndroid } from "react-native";
import { useQueryClient } from "react-query";
import tailwind from "tailwind-rn";
import validate from "validate.js";
Expand Down Expand Up @@ -51,6 +51,9 @@ export const CreateStickerPackScreen = ({ navigation }: Props): React.ReactEleme
stickerPack: data,
});
},
onError: () => {
ToastAndroid.show("Failed to create stickerpack, please try again.", 10000);
}
});
};

Expand Down
20 changes: 17 additions & 3 deletions app/src/screens/app/home/stickerpack/StickerPackScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import { Alert, Platform, SafeAreaView, TouchableOpacity } from "react-native";
import { Alert, Platform, SafeAreaView, ToastAndroid } from "react-native";

import { Button, Icon, Layout, ModalService, Spinner, Text } from "@ui-kitten/components";
import { Button, Icon, Layout, Spinner } from "@ui-kitten/components";
import { StackScreenProps } from "@react-navigation/stack";
import { HomeStackParamList } from "../../../../navigation/app/AppStackNavigator";
import tailwind from "tailwind-rn";
Expand Down Expand Up @@ -115,11 +115,25 @@ export const StickerPackScreen = ({ navigation, route }: Props): React.ReactElem

const dto = { stickerPackId, stickerName, file };

uploadSticker(dto);
uploadSticker(dto, {
onError: () => {
// TODO: Add alert for iOS as well
ToastAndroid.show(
"Something went wrong while uploading the sticker, please try again.",
10000
);
}
});
})
.catch((error) => {
if (error.code !== "E_PICKER_CANCELLED") {
console.log(error);
} else {
// TODO: Add alert for iOS as well
ToastAndroid.show(
"Something went wrong while selecting an image, please try again.",
10000
);
}
});
};
Expand Down
56 changes: 34 additions & 22 deletions app/src/screens/app/home/stickerpack/StickerScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,50 @@
import React, { useEffect } from "react";
import React, { useEffect, useState } from "react";

import { StackScreenProps } from "@react-navigation/stack";
import { Button, Icon } from "@ui-kitten/components";
import { Image, SafeAreaView } from "react-native";
import { Image, SafeAreaView, ToastAndroid } from "react-native";
import { HomeStackParamList } from "../../../../navigation/app/AppStackNavigator";
import tw from "tailwind-react-native-classnames";
import tailwind from "tailwind-rn";
import { useDeleteStickerMutation } from "../../../../api/hooks/mutations/stickerPack";
import { useQueryClient } from "react-query";
import { showConfirmModal } from "../../../../components/common/ConfirmModal";
import { ConfirmModal } from "../../../../components/common/ConfirmModal";


type Props = StackScreenProps<HomeStackParamList, "StickerScreen">;
const StickerScreen = ({ route, navigation }: Props): JSX.Element => {
const { stickerPack, sticker, allowDeleteSticker } = route.params;

const [confirmModalVisible, setConfirmModalVisible] = useState(false)

const queryClient = useQueryClient();
const { mutate: deleteSticker } = useDeleteStickerMutation(queryClient);
const { mutate: deleteSticker, isLoading } = useDeleteStickerMutation(queryClient);

const onPressDeleteSticker = async () => {
const onPressConfirm = async () => {
await deleteSticker({
stickerPackId: stickerPack.id,
stickerId: sticker.id,
})
navigation.pop();
}
const onPressConfirmDelete = async () => {
deleteSticker({
stickerPackId: stickerPack.id,
stickerId: sticker.id,
}, {
onSuccess: () => {
setConfirmModalVisible(false);
navigation.pop();
},
onError: () => {
ToastAndroid.show("Something went wrong while deleting the sticker, please try again.", 10000);
}
})
}

showConfirmModal({
message: "Are you sure?",
buttonText: "Delete Sticker",
onPressConfirm,
status: "danger"
});
const onPressDeleteButton = async () => {
setConfirmModalVisible(true);
}

const DeleteIcon = () => (
<Button
appearance="ghost"
status="danger"
style={tailwind("mx-3 px-1")}
onPress={onPressDeleteSticker}
onPress={onPressDeleteButton}
accessoryLeft={(props) => (<Icon style={tw.style("w-8 h-8")} name="trash" {...props} />)}
/>
);
Expand All @@ -54,11 +58,19 @@ const StickerScreen = ({ route, navigation }: Props): JSX.Element => {
return (
<SafeAreaView style={tw`flex justify-center h-full bg-white`}>
<Image
style={tw.style("rounded-lg w-full", {
paddingBottom: "100%",
})}
style={tw.style("rounded-lg w-full", { paddingBottom: "100%" })}
source={{ uri: sticker.fileUrl }}
/>
<ConfirmModal
visible={confirmModalVisible}
isLoading={isLoading}
loadingMessage="Deleting sticker..."
hideModal={() => setConfirmModalVisible(false)}
message="Are you sure?"
buttonText="Delete Sticker"
onPressConfirm={onPressConfirmDelete}
status="danger"
/>
</SafeAreaView>
);
}
Expand Down