Skip to content

Commit

Permalink
Merge pull request #27 from dpakach/follow
Browse files Browse the repository at this point in the history
[Feat] Add follow users
  • Loading branch information
dpakach authored Jan 30, 2021
2 parents 5b33e5c + ae7142b commit 9c949f0
Show file tree
Hide file tree
Showing 21 changed files with 1,410 additions and 227 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ service: ## build the binary and docker image of $SERVICE service
cd $(SERVICE) && \
make && make docker-build

restart: stop run

restart-service: ## Restart a service $SERVICE
make -C $(SERVICE) api
make -C $(SERVICE)
Expand Down
4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"scripts": {
"start": "webpack-dev-server --open",
"build": "webpack",
"lint": "eslint '*/**/*.{js,ts,tsx}' --quiet",
"lint-fix": "eslint '*/**/*.{js,ts,tsx}' --quiet --fix"
"lint": "eslint 'src/**/*.{js,ts,tsx}' --quiet",
"lint-fix": "eslint 'src/**/*.{js,ts,tsx}' --quiet --fix"
},
"keywords": [],
"author": "",
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ export default function App() {
<Route exact path="/profile/:user">
<ProfilePage loggedIn={loggedIn} tokens={tokens} />
</Route>
<Route exact path="/" render={(props) => <Posts {...props} loggedIn={loggedIn} tokens={tokens} />} />
<Route
exact
path="/"
render={(props) => <Posts {...props} loggedIn={loggedIn} tokens={tokens} showInput={true} />}
/>
</Switch>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ function Post({ post: p, tokens, level, loggedIn, clickable }: PostProps) {

return (
<>
{Object.keys(post.rezweet).length === 0 ? (
{post.rezweet.id === '0' ? (
<></>
) : (
<>
Expand All @@ -141,7 +141,7 @@ function Post({ post: p, tokens, level, loggedIn, clickable }: PostProps) {
>
<Link onClick={() => updatePage(updateKey + 1)} to={`/post/${post.id}`}>
<p>{post.text}</p>
{!post.rezweet ? <></> : getRezweet(post.rezweet)}
{post.rezweet.id === '0' ? <></> : getRezweet(post.rezweet)}
<Link className="username" to={`/profile/${post.author.username}`}>
<b>@{post.author.username}</b>
</Link>
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/Posts.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { useState, useEffect } from 'react';
import { Redirect, useHistory } from 'react-router';
import { tokenToString } from 'typescript';
import { get, post, sendFileUploadRequest } from './helpers/request';
import Post from './Post';
Expand All @@ -8,15 +9,18 @@ import { CreatePostRequest, Tokens } from './types/types';
type PostsProps = {
tokens: Tokens;
loggedIn: boolean;
showInput: boolean;
};
function Posts(props: PostsProps) {
const { loggedIn, tokens } = props;
const { loggedIn, tokens, showInput } = props;
const [postText, setPostText]: [string, (prop: string) => void] = useState('');
const [posts, setPosts] = useState([]);
const [message, setMessage]: [string, (prop: string) => void] = useState('');
const history = useHistory();

useEffect(() => {
get('/posts', { headers: loggedIn ? { token: tokens.token } : {} })
const url = loggedIn ? '/posts/feed/postfeed' : '/posts';
get(url, { headers: loggedIn ? { token: tokens.token } : {} })
.then((res) => res.json())
.then(
(json) => {
Expand Down Expand Up @@ -60,6 +64,7 @@ function Posts(props: PostsProps) {
setPosts([json.post, ...posts]);
setPostText('');
setMessage('Successfully created a post');
history.push(`/post/${json.post.id}`);
},
(error) => {
setMessage('Error: ' + error.message);
Expand All @@ -71,7 +76,7 @@ function Posts(props: PostsProps) {
<>
<h2>Posts</h2>
{!message || <p>{message}</p>}
{!props.loggedIn || (
{showInput && loggedIn && (
<form onSubmit={handleSubmit}>
<textarea
placeholder="Create a new post"
Expand Down
42 changes: 38 additions & 4 deletions frontend/src/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Redirect, useParams } from 'react-router-dom';
import { get, post } from './helpers/request';
import { getDate } from './helpers/date';
import { User, Tokens, Genders } from './types/types';
import Posts from './Posts';

type ProfileProps = {
tokens: Tokens;
Expand Down Expand Up @@ -32,23 +33,31 @@ function ProfilePage(props: ProfileProps) {
const [gender, setGender] = useState(Genders.NOT_SPECIFIED);
const [birthday, setBirthday]: [string, (prop: string) => void] = useState('');
const [user, setUser] = useState({} as User);
const [following, setFollowing] = useState(false);

useEffect(() => {
let url = '/users/profile';
let url;
if (profileUser) {
url += `/${profileUser}`;
url = `/users/profile/${profileUser}`;
} else {
url = '/users/self/profile';
}
get(url, { headers: { token: tokens.token } })
const headers = loggedIn ? { token: tokens.token } : {};
get(url, { headers })
.then((res) => res.json())
.then((data) => {
setDisplayName(data.Profile['displayName'] || '');
setBirthday(data.Profile['dateOfBirth'] || '');
setGender(data.Profile['gender'] || Genders.NOT_SPECIFIED);
setUser(data.user);
setFollowing(data.following);
});
}, []);

function handleSubmit(e) {
if (!loggedIn) {
return;
}
e.preventDefault();
return post('/users/profile', {
body: { profile: { userId: user.id, displayName, gender: gender, dateOfBirth: birthday } },
Expand All @@ -65,12 +74,35 @@ function ProfilePage(props: ProfileProps) {
);
}

function toggleFollow(e) {
if (!loggedIn) {
return;
}
e.preventDefault();
const urlPrefix = following ? 'unfollow' : 'follow';
return post(`/users/${urlPrefix}/${user.username}`, {
headers: { token: tokens.token },
body: { username: user.username },
})
.then((res) => res.json())
.then(
() => {
setMessage(`Success: ${urlPrefix}ed the user`);
setFollowing(!following);
},
(error) => {
setMessage('Error: ' + error.message);
},
);
}

return (
<>
{self && !loggedIn && <Redirect to="/" />}
<div>
{displayName || 'Name not set'} ({getGenderName(gender) || 'Gender not specified'})
<br />@{user.username}
<br />@{user.username}{' '}
{loggedIn && profileUser && <a onClick={toggleFollow}>{following ? 'Unfollow' : 'follow'}</a>}
<br />
joined {getDate(user.created)}
<br />
Expand Down Expand Up @@ -121,6 +153,8 @@ function ProfilePage(props: ProfileProps) {
</form>
</>
)}
<h3>Posts by @{user.username}</h3>
<Posts loggedIn={loggedIn} tokens={tokens} showInput={false} />
</>
);
}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export default function Signup(props: signupProps) {
() => {
setMessage('Success: Created User');
setTimeout(() => {
props.setLoggedIn(true);
setCompleted(true);
}, 2000);
},
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/SinglePost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ function SinglePost(props: SinglePostParams) {
useEffect(() => {
if (postId) {
get(`/posts/${postId}`, {})
.then((res) => res.json())
.then((res) => {
return res.json();
})
.then(
(json) => {
setPost(json.post);
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
Expand Down Expand Up @@ -362,6 +363,7 @@ google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0 h1:lQ+dE99pFsb8osbJB3oRfE5eW4Hx6a/lZQr8Jh+eoT4=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
Expand Down
93 changes: 93 additions & 0 deletions pkg/data/follow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package data

import (
"errors"
)

var FollowStore = new(Follows)

// follows type for Users List
type Follows struct {
Follows []Follow `json:"follow"`
}

// AddDbList adds a new follow to follows.follows
func (f *Follows) AddDbList(follow *Follow) {
f.Follows = append(f.Follows, *follow)
}

// ReadFromDb updates follows.follows from the file
func (f *Follows) ReadFromDb() *Follows {
return f
}

// CommitDb writes follows.follows to the file
func (f *Follows) CommitDb() {
return
}

// followers of id
func (f *Follows) GetFollowers(id int64) []Follow {
follows := []Follow{}
for _, item := range f.Follows {
if item.Follows == id {
follows = append(follows, item)
}
}
return follows
}

// id is following
func (f *Follows) GetfollowByUser(id int64) []Follow {
follows := []Follow{}
for _, item := range f.Follows {
if item.User == id {
follows = append(follows, item)
}
}
return follows
}

// get follow relation between 2 users
func (f *Follows) GetByUserAndFollows(userId, follows int64) *Follow {
for _, item := range f.Follows {
if item.User == userId && item.Follows == follows {
return &item
}
}
return nil
}

func (f *Follows) DeleteFollow(userId, follows int64) error {
found := false
for idx, item := range f.Follows {
if item.User == userId && item.Follows == follows {
f.Follows = append(f.Follows[:idx], f.Follows[idx+1:]...)
found = true
break
}
}
if !found {
return errors.New("Could not find the item")
}
return nil
}

func (f *Follows) GetFollowsCount(userId int64) int64 {
return int64(len(f.GetFollowers(userId)))
}

func (f *Follows) GetFollowingCount(userId int64) int64 {
return int64(len(f.GetfollowByUser(userId)))
}

// follow type for a follow Instance
type Follow struct {
User int64 `json:"user"`
Follows int64 `json:"follows"`
}

// SaveToStore saves the follow to the given dB store
func (f *Follow) SaveToStore() {
FollowStore.AddDbList(f)
}
34 changes: 34 additions & 0 deletions pkg/data/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ func (p *Posts) GetPosts() []Post {
return posts
}

func (p *Posts) GetPostsByUser(userid int64) []Post {
posts := []Post{}
for _, item := range p.Posts {
if item.Author == userid {
childs := p.GetPostChilds(item.ID)
item.Children = childs
posts = append(posts, item)
}
}
return posts
}

func (p *Posts) GetPostChilds(id int64) []Post {
posts := []Post{}
for _, item := range p.Posts {
Expand All @@ -66,6 +78,28 @@ func (p *Posts) GetPostWithChilds(id int64) *Post {
return post
}

func (p *Posts) GetUserFeed(userId int64, following []int64) []Post {
posts := []Post{}
for _, item := range p.Posts {
found := false
for _, id := range following {
if id == item.Author {
found = true
break
}
}
if !found {
continue
}
if item.ParentId == 0 {
childs := p.GetPostChilds(item.ID)
item.Children = childs
posts = append(posts, item)
}
}
return posts
}

// NewID returns new ID for the new Post
func (p *Posts) NewID() int64 {
id := int64(0)
Expand Down
Loading

0 comments on commit 9c949f0

Please sign in to comment.