Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dpakach committed Jan 30, 2021
1 parent 9c949f0 commit 54f4b38
Show file tree
Hide file tree
Showing 13 changed files with 651 additions and 105 deletions.
3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@babel/preset-react": "^7.10.4",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.14",
"@types/jest": "^26.0.20",
"@types/node": "^14.14.20",
"@types/react": "^17.0.0",
Expand Down
67 changes: 48 additions & 19 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import Docs from './Docs';
import './styles/main.scss';
import { Tokens } from './types/types';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSignOutAlt, faHome, faUser, faUserPlus } from '@fortawesome/free-solid-svg-icons'

export default function App() {
const tokensString = window.localStorage.getItem('tokens');

Expand Down Expand Up @@ -44,30 +47,56 @@ export default function App() {
<Router>
<div className="main">
<div className="container">
<h1 className="header">Zwitter</h1>
{message && <p> {message} </p>}
<div className="navigation">
<h1 className="navigation__title">ZWITTER</h1>
<ul className="navigation__list">
<Link to="/">
<li className="navigation__item navigation__item--active">
<FontAwesomeIcon className="navigation__icon" icon={faHome} />
<p className="navigation__label">Home</p>
</li>
</Link>
{loggedIn ? (
<>
<Link to="/profile">
<li className="navigation__item navigation__item--active">
<FontAwesomeIcon className="navigation__icon" icon={faUser} />
<p className="navigation__label">Profile</p>
</li>
</Link>

<Link to="#" onClick={handleLogout}>
<li className="navigation__item navigation__item--active">
<FontAwesomeIcon className="navigation__icon" icon={faSignOutAlt} />
<p className="navigation__label">Logout</p>
</li>
</Link>
</>
) : (
<>
<Link to="/login">
<li className="navigation__item navigation__item--active">
<FontAwesomeIcon className="navigation__icon" icon={faUser} />
<p className="navigation__label">Login</p>
</li>
</Link>
<Link to="/signup">
<li className="navigation__item navigation__item--active">
<FontAwesomeIcon className="navigation__icon" icon={faUserPlus} />
<p className="navigation__label">Signup</p>
</li>
</Link>
</>
)}
</ul>
</div>

{loggedIn && (
<p>
Logged in as <b>@{tokens.user.username}</b>
</p>
)}
<div>
<Link to="/">Home </Link>
{loggedIn ? (
<>
<Link to="/profile">Profile </Link>
<Link to="#" onClick={handleLogout}>
{' '}
Logout{' '}
</Link>
</>
) : (
<>
<Link to="/login">Login </Link>
<Link to="/signup">Signup </Link>
</>
)}

<div className="main-content">
<Switch>
<Route
exact
Expand Down
105 changes: 67 additions & 38 deletions frontend/src/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { post as httpPost } from './helpers/request';
import { Link, useHistory } from 'react-router-dom';
import { baseUrl } from './const';
import { Tokens, PostType, CreatePostRequest, PostReactTypes } from './types/types';
import { timeSince } from "./helpers/date";

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHeart, faCommentDots, faRetweet, faReplyAll, faRepublican, faReply } from '@fortawesome/free-solid-svg-icons';

type PostProps = {
loggedIn: boolean;
Expand All @@ -19,22 +23,40 @@ function Post({ post: p, tokens, level, loggedIn, clickable }: PostProps) {
const [post, setPost]: [PostType, (post: PostType) => void] = React.useState<PostType>(p);
const [message, setMessage]: [string, (message: string) => void] = React.useState('');
const history = useHistory();

const [timeString, setTimeString]: [string, (timeString: string) => void] = React.useState('');
const [updateKey, updatePage]: [number, (updateKey: number) => void] = React.useState<number>(0);

React.useEffect(() => {
setPost(p);
let formattedDate: string = timeSince(parseInt(post.created)) + " ago";
setTimeString(formattedDate);
}, []);

React.useEffect(() => {
console.log('rerender')
const timer=setTimeout(() => {
let formattedDate = timeSince(parseInt(post.created)) + " ago";

setTimeString(formattedDate);
}, 1000);

// Clear timeout if the component is unmounted
return () => clearTimeout(timer);
})

const updateTimeAgo = function() {
const created: Date = new Date(parseInt(post.created) * 1000);
const formattedDate: string = timeSince(parseInt(post.created)) + " ago"
setTimeString(formattedDate)
}

const dateOptions: Intl.DateTimeFormatOptions = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
};
const created: Date = new Date(parseInt(post.created) * 1000);
const formattedDate: string = created.toLocaleTimeString('en-US', dateOptions);


function getRezweet(rezweet) {
if (Object.keys(rezweet).length === 0) {
return;
Expand Down Expand Up @@ -89,6 +111,10 @@ function Post({ post: p, tokens, level, loggedIn, clickable }: PostProps) {
}

function likePost(): Promise<void> {
if (!loggedIn) {
history.push("/login")
return
}
return httpPost(`/posts/${post.id}/like`, { headers: { token: tokens.token } })
.then((res) => res.json())
.then(
Expand All @@ -106,7 +132,10 @@ function Post({ post: p, tokens, level, loggedIn, clickable }: PostProps) {
);
}

function toggleReplyRezweet(type: PostReactTypes) {
function toggleReplyRezweet(type: PostReactTypes): void {
if (!loggedIn) {
return history.push("/login")
}
if (type == PostReactTypes.REZWEET) {
setReplyShown(false);
setRezweetShown(!rezweetShown);
Expand Down Expand Up @@ -139,40 +168,40 @@ function Post({ post: p, tokens, level, loggedIn, clickable }: PostProps) {
}}
className={clickable && 'post-section'}
>
<Link onClick={() => updatePage(updateKey + 1)} to={`/post/${post.id}`}>
<p>{post.text}</p>
{post.rezweet.id === '0' ? <></> : getRezweet(post.rezweet)}
<Link className="username" to={`/profile/${post.author.username}`}>
<b>@{post.author.username}</b>
<div className="list-item">
<Link onClick={() => updatePage(updateKey + 1)} to={`/post/${post.id}`}>
<div className="list-item__content">{post.text}</div>

{post.rezweet.id === '0' ? <></> : getRezweet(post.rezweet)}
<Link className="username" to={`/profile/${post.author.username}`}>
<b>@{post.author.username}</b>
</Link>
<p>{timeString}</p>
{post.media && (
<>
<img src={`${baseUrl}/media/${post.media}`} alt={post.text} style={{ width: '400px' }} />
<br />
</>
)}
</Link>
<p>{formattedDate}</p>
{post.media && (
<>
<img src={`${baseUrl}/media/${post.media}`} alt={post.text} style={{ width: '400px' }} />
<br />
</>
)}
</Link>
{!loggedIn || (
<>
<button onClick={() => toggleReplyRezweet(PostReactTypes.REPLY)}>reply</button>
<button onClick={() => toggleReplyRezweet(PostReactTypes.REZWEET)}>rezweet</button>
<button
onClick={likePost}
style={
post.liked
? {
color: '#ccc',
backgroundColor: '#3f6ea1',
}
: {}
}
>
Like
</button>
</>
)}
<p>Likes: {post.likes || 0}</p>
<div className="facts">
<div className={"fact__icon " + (replyShown ? "fact__icon--1" : "")} onClick={() => toggleReplyRezweet(PostReactTypes.REPLY)}>
<FontAwesomeIcon className="fact__icon" icon={faCommentDots} />
<div className="fact__value">13k</div>
</div>

<div className={"fact__icon " + (rezweetShown ? "fact__icon--1" : "")} onClick={() => toggleReplyRezweet(PostReactTypes.REZWEET)}>
<FontAwesomeIcon className="fact__icon" icon={faRetweet} />
<div className="fact__value">20k</div>
</div>

<div className="fact" onClick={likePost}>
<FontAwesomeIcon className={"fact__icon " + (post.liked ? "fact__icon--1" : "")} icon={faHeart} />
<div className="fact__value">{post.likes || 0}</div>
</div>
</div>
</div>

{!(replyShown || rezweetShown) || (
<>
<p>{message}</p>
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/Posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ function Posts(props: PostsProps) {
<input type="file" id="create-post-media-input" />
</form>
)}
{posts.map((post) => (
<Post post={post} key={post.id} tokens={props.tokens} level={0} clickable={true} {...props} />
))}
<div className="list">
{posts.map((post) => (
<Post post={post} key={post.id} tokens={props.tokens} level={0} clickable={true} {...props} />
))}
</div>
</>
);
}
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/helpers/date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,31 @@ export function getDate(timeStamp: number): string {
const currentDate = date.toISOString().slice(0, 10);
return currentDate;
}

export function timeSince(date: number): string {

var seconds = Math.floor((new Date()).getTime() / 1000) - date;

var interval = seconds / 31536000;

if (interval > 1) {
return Math.floor(interval) + " years";
}
interval = seconds / 2592000;
if (interval > 1) {
return Math.floor(interval) + " months";
}
interval = seconds / 86400;
if (interval > 1) {
return Math.floor(interval) + " days";
}
interval = seconds / 3600;
if (interval > 1) {
return Math.floor(interval) + " hours";
}
interval = seconds / 60;
if (interval > 1) {
return Math.floor(interval) + " minutes";
}
return Math.floor(seconds) + " seconds";
}
77 changes: 77 additions & 0 deletions frontend/src/styles/_base.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: inherit;
}

html {
}

a {
text-decoration: none;
}

body {
box-sizing: border-box;
background-color: $color-grey-light-1;
grid-area: body;

font-family: sans-serif;
margin: 0;
padding: 0;
}

.main {
height: 92vh;
overflow: scroll;
background-color: #fefefe !important;
min-height: 100%;

@include respond(tab-land) {
width: 100rem;
}
}

.navigation {
grid-area: navigation;
z-index: 100;
}

.container {
max-width: 50rem;
overflow: hidden;
display: grid;

padding: 2rem;
margin: 0 auto;

grid-template-areas:
'body'
'navigation';

@include respond(tab-land) {
grid-template-areas:
'navigation'
'body';
}

@include respond(tab-port) {
padding: .5rem
}
}

.main-content {
margin-bottom: $nav-height;
margin-top: 0;
@include respond(tab-port) {
margin-top: $nav-height;
margin-bottom: 0;
}
}

.username {
color: #008ce9;
}
Loading

0 comments on commit 54f4b38

Please sign in to comment.