Skip to content

Commit

Permalink
create overlay comments component
Browse files Browse the repository at this point in the history
  • Loading branch information
devanshusingla committed Jul 30, 2020
1 parent 77db814 commit be0907d
Show file tree
Hide file tree
Showing 15 changed files with 585 additions and 1 deletion.
25 changes: 24 additions & 1 deletion App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import { StatusBar } from "expo-status-bar";
import React from "react";
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";

import { Button } from "react-native-elements";
import comments from "./ui/Comments/CommentExample";
import CommentBox from "./ui/Comments";

export default function App() {
const [commentsVisible, setCommentsVisible] = useState(false);

return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<Button
onPress={() => {
setCommentsVisible(true);
}}
title="Open Comments"
/>
{commentsVisible ? (
<CommentBox
comments={comments}
isVisible={true}
onBack={() => {
setCommentsVisible(false);
}}
/>
) : (
<></>
)}
<StatusBar style="auto" />
</View>
);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"dependencies": {
"expo": "~38.0.8",
"expo-status-bar": "^1.0.2",
"moment": "^2.27.0",
"react": "~16.11.0",
"react-dom": "~16.11.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ declare interface IPost {

declare interface IComment {
pk: number;
parent: number;
post: number;
content: string;
created_at: string; // for ex: 2020-05-05T23:37:49.992636+05:30
Expand Down
17 changes: 17 additions & 0 deletions ui/Comments/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";
import { TouchableOpacity } from "react-native";
import { ListItem } from "react-native-elements";

type Props = {
onBack: () => void;
};

const BackButton = (props: Props) => {
return (
<TouchableOpacity onPress={props.onBack} activeOpacity={0.5}>
<ListItem leftIcon={{ name: "arrow-back" }} title="Back" />
</TouchableOpacity>
);
};

export default BackButton;
63 changes: 63 additions & 0 deletions ui/Comments/CommentBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useRef } from "react";
import { View, FlatList, TextInput, StyleSheet } from "react-native";
import { Overlay } from "react-native-elements";

import MaximisedComment from "./MaximisedComment";
import MainComment from "./MainComment";
import ReplyBox from "./ReplyBox";
import BackButton from "./BackButton";

type Props = {
onBack: () => void;
comment: IComment;
};

const CommentBox = (props: Props) => {
let inpRef: React.MutableRefObject<TextInput | undefined> = useRef();

const focusInputBox = () => {
if (inpRef.current) inpRef.current.focus();
};

const onReplyHandler = () => {
focusInputBox();
};

return (
<Overlay
isVisible
fullScreen
overlayStyle={styles.overlay}
onRequestClose={props.onBack}
>
<View style={styles.outer}>
<BackButton onBack={props.onBack} />
<View style={styles.commentOuter}>
<MainComment comment={props.comment} onReply={onReplyHandler} />
<View style={styles.commentList}>
<FlatList
data={props.comment.replies}
keyExtractor={(comment) => comment.pk.toString()}
renderItem={({ item }) => (
<MaximisedComment comment={item} showReplies />
)}
/>
</View>
</View>
<ReplyBox
placeholder={"Reply to " + props.comment.user.name}
ref={inpRef}
/>
</View>
</Overlay>
);
};

const styles = StyleSheet.create({
overlay: { padding: 0 },
outer: { flex: 1 },
commentOuter: { paddingHorizontal: 10, flex: 1 },
commentList: { paddingLeft: "5%", flex: 1 },
});

export default CommentBox;
63 changes: 63 additions & 0 deletions ui/Comments/CommentExample.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const user_def = {
pk: 0,
name: "",
roll: 0,
username: "",
email: "",
fblink: "",
following: 0,
};

const comment = (
name: string,
pk: number,
content: string,
parent: number,
replies: Array<IComment>
): IComment => {
return {
pk: pk,
parent: parent,
post: 0,
content: content,
created_at: "2020-05-05T23:37:49.992636+05:30",
user: { ...user_def, name: name },
replies: replies,
};
};

const comments: Array<IComment> = [
comment("dosa", 1, "next sem to be online", 0, [
comment("a y19", 2, ";-( mujhe wapas jana hai", 1, [
comment("iitk", 3, "Want to buy BournVita?", 2, []),
]),
]),
comment("oli", 4, "Ayodhya is in Nepal", 0, [
comment("Umar Akmal", 5, "Nepal is Ayodhya.", 4, []),
comment(
"Anonymous",
6,
"Go Brrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.",
4,
[]
),
comment("Bhau", 7, "Pehli fursat me nikal", 4, [
comment(
"Oli",
9,
"Mai aaya hi kab jo nikal jayun. Tu hi mere desh me hai.",
7,
[]
),
]),
comment(
"Gandhi",
8,
"Ye kya chal rha hai padosi desh me. Kya isi din ke liye azad karaya tha",
4,
[]
),
]),
];

export default comments;
29 changes: 29 additions & 0 deletions ui/Comments/CommentList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from "react";
import { View, StyleSheet } from "react-native";
import MinimisedComment from "./MinimisedComment";

type Props = {
comments: Array<IComment>;
};

const CommentList = (props: Props) => {
const maxHiddenChats = 3;

if (!props.comments) return <> </>;
return (
<View style={styles.commentList}>
{props.comments.slice(0, maxHiddenChats).map((comment: IComment) => (
<MinimisedComment comment={comment} key={comment.pk} />
))}
</View>
);
};

const styles = StyleSheet.create({
commentList: {
width: "100%",
paddingLeft: "5%",
},
});

export default CommentList;
68 changes: 68 additions & 0 deletions ui/Comments/MainComment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from "react";
import { Card } from "react-native-elements";
import { StyleSheet, View, Text } from "react-native";
import Title from "./Title";

import moment from "moment";

type CommentProps = {
comment: IComment;
onReply: () => void;
};

const MainComment = (props: CommentProps) => {
return (
<>
<Card
title={
<Title
name={props.comment.user.name}
avatarSize={40}
titleStyle={styles.title}
/>
}
containerStyle={styles.container}
>
<View style={styles.content}>
<Text style={{ marginTop: 5 }}>{props.comment.content}</Text>
</View>
</Card>
<View style={styles.subtitlesBox}>
<View>
<Text style={styles.subtitles}>
{moment(props.comment.created_at).fromNow()}
</Text>
</View>
<View>
<Text style={styles.subtitles} onPress={props.onReply}>
Reply
</Text>
</View>
</View>
</>
);
};

const styles = StyleSheet.create({
container: {
padding: "1%",
margin: "0.5%",
marginTop: 10,
borderBottomLeftRadius: 15,
backgroundColor: "#f9f9f9",
},
content: {
marginBottom: 2,
marginLeft: 16,
},
title: { fontSize: 20, paddingTop: 5 },
subtitlesBox: {
marginBottom: 10,
flexDirection: "row",
justifyContent: "space-between",
marginHorizontal: 12,
},
subtitles: { color: "grey", fontWeight: "bold" },
});

export default MainComment;
49 changes: 49 additions & 0 deletions ui/Comments/MaximisedComment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useState } from "react";
import { View, StyleSheet, TouchableOpacity } from "react-native";

import CommentList from "./CommentList";
import CommentBlock from "./CommentBlock";
import SideComment from "./SideComment";

type Props = {
comment: IComment;
showReplies: boolean;
};

const MaximisedComment = (props: Props) => {
let [selfExpanded, setSelfExpanded] = useState(false);

const onSelectHandler = () => {
setSelfExpanded(true);
};

const onBackHandler = () => {
setSelfExpanded(false);
};

return (
<>
<TouchableOpacity onPress={onSelectHandler} activeOpacity={0.6}>
<View style={styles.outer}>
<SideComment comment={props.comment} />
<CommentList comments={props.comment.replies} />
</View>
</TouchableOpacity>
{selfExpanded ? (
<CommentBlock comment={props.comment} onBack={onBackHandler} />
) : (
<></>
)}
</>
);
};

const styles = StyleSheet.create({
outer: {
width: "100%",
paddingLeft: "5%",
marginTop: 10,
},
});

export default MaximisedComment;
35 changes: 35 additions & 0 deletions ui/Comments/MinimisedComment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react";
import { StyleSheet, Text } from "react-native";
import { Card } from "react-native-elements";

type Props = {
comment: IComment;
};

const MinimisedComment = (props: Props) => {
return (
<Card containerStyle={styles.container}>
<Text numberOfLines={1}>
<Text style={styles.name}>{" " + props.comment.user.name}</Text>
<Text>{" " + props.comment.content}</Text>
</Text>
</Card>
);
};

const styles = StyleSheet.create({
container: {
padding: 4,
borderBottomLeftRadius: 12,
borderTopLeftRadius: 12,
marginBottom: 4,
marginTop: 4,
},
name: {
fontWeight: "bold",
marginLeft: 7,
marginRight: 5,
},
});

export default MinimisedComment;
Loading

0 comments on commit be0907d

Please sign in to comment.