{user.username}
57 |58 | Change profile photo 59 |
60 |{error}
} 146 |No page found
13 |Suggestions
14 |20 | Suggestions 21 | 22 | See all 23 | 24 |
25 |No Posts Yet
41 |setShowAllComments(!showAllComments)} 23 | className="text-sm text-gray-400 mb-1 select-none cursor-pointer" 24 | > 25 | View all {allComments.length} Comments 26 |
27 | )} 28 | {allComments 29 | .slice(0, showAllComments ? allComments.length : 3) 30 | .map((comment, index) => ( 31 |
32 |
33 |
34 | {" "}
35 | {comment.createdBy.fullname}
36 |
37 |
38 |
46 | posted {formatDistanceToNow(postedAt)} ago 47 |
48 |55 | {likes} 56 | {likes > 1 ? `likes` : `like`} 57 |
58 |{user.fullname}
45 | 46 |{post.createdBy.username}
36 |{post.location}
37 |No Posts Yet
34 |63 | {post.likes.length} 64 |
65 |72 | {post.likes.length} 73 |
74 |
|
|
22 | |
|
|
23 | |
|
|
24 |
25 |
26 |
27 | ## Tablet Screenshot
28 | | | |
29 | | ------------- |:-------------:|
30 | |
|
|
31 | |
|
|
32 |
33 |
34 |
35 | ## Mobile Screenshot
36 | | | | | |
37 | | ------------- |:-------------|:------------- |:-------------|
38 | |
|
|
|
|
39 |
40 |
41 |
42 |
43 |
44 | ## Created & Maintained By
45 |
46 | [Sonu Sharma](https://github.com/TheAlphamerc) ([Twitter](https://www.twitter.com/TheAlphamerc)) ([Youtube](https://www.youtube.com/user/sonusharma045sonu/)) ([Insta](https://www.instagram.com/_sonu_sharma__)) ([Dev.to](https://dev.to/thealphamerc))
47 | 
48 |
49 | > If you found this project helpful or you learned something from the source code and want to thank me, consider buying me a cup of :coffee:
50 | >
51 |
52 | > *
53 | > * [PayPal](https://www.paypal.me/TheAlphamerc/)
54 |
55 | > You can also nominate me for Github Star developer program
56 | > https://stars.github.com/nominate
57 |
58 |
--------------------------------------------------------------------------------
/src/models/post.tsx:
--------------------------------------------------------------------------------
1 | // import { CommentModel, CommentConverter } from ".";
2 | import { ProfileConverter } from ".";
3 | import { identity } from "./identity";
4 | import { PostProfileConverter, Profile } from "./profile";
5 |
6 | interface Prop {
7 | id: string;
8 | caption?: string;
9 | attachments?: string[];
10 | location?: string;
11 | likes?: string[];
12 | comments?: PostModel[];
13 | createdAt: any;
14 | createdBy: Profile;
15 | reportedBy?: Profile[];
16 | }
17 | class PostModel {
18 | id: string;
19 | caption: string;
20 | attachments: string[] | undefined;
21 | location: string | undefined;
22 | likes: string[] | undefined;
23 | comments: PostModel[] | undefined;
24 | createdAt: any;
25 | createdBy: Profile;
26 | reportedBy: Profile[] | undefined;
27 | constructor({
28 | id,
29 | caption = "",
30 | attachments,
31 | location,
32 | createdBy,
33 | createdAt,
34 | likes,
35 | comments,
36 | reportedBy,
37 | }: Prop) {
38 | this.id = id;
39 | this.caption = caption;
40 | this.attachments = attachments;
41 | this.location = location;
42 | this.comments = comments;
43 | this.likes = likes;
44 | this.createdAt = createdAt;
45 | this.createdBy = createdBy;
46 | this.reportedBy = reportedBy;
47 | }
48 | }
49 |
50 | // Firestore data converter
51 | const PostConverter = {
52 | toFirestore: (post: any) => {
53 | return {
54 | id: identity(post.id),
55 | caption: identity(post.caption),
56 | attachments: identity(post.attachments),
57 | likes: identity(post.likes),
58 | location: identity(post.location),
59 | comments: Array.isArray(post.comments)
60 | ? post.comments.map((com: any) => PostConverter.toFirestore(com))
61 | : [],
62 | createdBy: PostProfileConverter.toFirestore(post.createdBy),
63 | createdAt: post.createdAt,
64 | reportedBy: Array.isArray(post.reportedBy)
65 | ? post.reportedBy.map((user: any) => ProfileConverter.toFirestore(user))
66 | : [],
67 | };
68 | },
69 | fromFirestore: (snapshot: any, options: any) => {
70 | const data = snapshot.data(options);
71 | return new PostModel({
72 | id: snapshot.id,
73 | caption: data.caption,
74 | attachments: data.attachments,
75 | location: data.location,
76 | likes: data.likes,
77 | comments: Array.isArray(data.comments)
78 | ? data.comments.map((com: any) => CommentConverter.fromFirestore(com))
79 | : [],
80 | createdBy: PostProfileConverter.fromFirestore(data.createdBy),
81 | createdAt: data.createdAt,
82 | reportedBy: Array.isArray(data.comments)
83 | ? data.comments.map((com: any) =>
84 | PostProfileConverter.fromFirestore(com)
85 | )
86 | : [],
87 | });
88 | },
89 | };
90 |
91 | const CommentConverter = {
92 | toFirestore: (post: any) => {
93 | return {
94 | id: identity(post.id),
95 | caption: identity(post.caption),
96 | likes: identity(post.likes),
97 | createdBy: PostProfileConverter.toFirestore(post.createdBy),
98 | createdAt: post.createdAt,
99 | };
100 | },
101 | fromFirestore: (comment: any) => {
102 | return new PostModel({
103 | id: comment.id,
104 | caption: comment.caption,
105 | likes: comment.likes,
106 | createdBy: PostProfileConverter.fromFirestore(comment.createdBy),
107 | createdAt: comment.createdAt,
108 | });
109 | },
110 | };
111 |
112 | export { PostModel, PostConverter };
113 |
--------------------------------------------------------------------------------
/src/hook/use-feed.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, useEffect, useState } from "react";
2 | import { SessionContext } from "../context/session";
3 | import { PostModel } from "../models/post";
4 | import FeedService from "../services/feed";
5 | import UsePost from "./use-post";
6 | import useScroll from "./use-scroll";
7 |
8 | function UserFeeds(): {
9 | feed: PostModel[] | undefined;
10 | isLoading: boolean;
11 | } {
12 | const [feed, setFeeds] = useState
46 |
55 | {error}
58 | )} 59 | 60 | 91 |94 | Don't have an account?{" "} 95 | 99 | Sign up 100 | 101 |
102 |
38 |
39 |
58 |
67 | {error}
70 | )} 71 | 72 | 123 |126 | Have an account?{" "} 127 | 131 | Sign in 132 | 133 |
134 |{profile.fullname}
122 |{profile.bio}
123 | {profile.website && ( 124 |125 | {profile.website} 126 |
127 | )} 128 |135 | {photoCount ?? 0}{" "} 136 | {photoCount === 1 ? " photo" : " photos"} 137 |
138 |139 | {followerCount} 140 | 141 | {followerCount === 1 ? " follower" : " followers"} 142 | 143 |
144 |145 | {profile.following?.length ?? 0} 146 | 147 | {profile.following?.length === 1 ? " following" : " following"} 148 | 149 |
150 |58 | Change profile photo 59 |
60 |{error}
} 146 |Create Post
98 | {IsSubmittable && !loading ? ( 99 | 108 | ) : loading ? ( 109 |Drag photos and videos here
178 | 187 |{user.username}
236 |