Skip to content
Snippets Groups Projects
Commit 5a9967db authored by xaralis's avatar xaralis
Browse files

feat: favicons, page desc, support removing likes/dislikes

parent 8762f823
No related branches found
No related tags found
No related merge requests found
Pipeline #1792 passed
......@@ -2,14 +2,21 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<!-- Favicons -->
<link rel="apple-touch-icon" href="%REACT_APP_STYLEGUIDE_URL%images/favicons/favicon-196x196.png">
<link rel="icon" type="image/png" href="%REACT_APP_STYLEGUIDE_URL%images/favicons/favicon-196x196.png" sizes="196x196">
<meta name="application-name" content="CF2021">
<meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-TileImage" content="%REACT_APP_STYLEGUIDE_URL%images/favicons/mstile-144x144.png">
<meta name="msapplication-square70x70logo" content="%REACT_APP_STYLEGUIDE_URL%images/favicons/mstile-70x70.png">
<meta name="msapplication-square150x150logo" content="%REACT_APP_STYLEGUIDE_URL%images/favicons/mstile-150x150.png">
<meta name="msapplication-wide310x150logo" content="%REACT_APP_STYLEGUIDE_URL%images/favicons/mstile-310x150.png">
<meta name="msapplication-square310x310logo" content="%REACT_APP_STYLEGUIDE_URL%images/favicons/mstile-310x310.png">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<meta property="og:url" content="https://cf2021.pirati.cz/" />
<meta property="og:type" content="website" />
<meta property="og:title" content="CF 2021" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
......@@ -24,8 +31,8 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link rel="stylesheet" href="%REACT_APP_STYLEGUIDE_URL%/css/styles.css" />
<title>React App</title>
<link rel="stylesheet" href="%REACT_APP_STYLEGUIDE_URL%css/styles.css" />
<title>CF 2021 | Pirátská strana</title>
</head>
<body class="h-screen">
<noscript>You need to enable JavaScript to run this app.</noscript>
......
......@@ -41,7 +41,7 @@ const LoadingComponent = (
<div className="h-screen w-screen flex justify-center items-center">
<div className="text-center">
<img
src={`${process.env.REACT_APP_STYLEGUIDE_URL}/images/logo-round-black.svg`}
src={`${process.env.REACT_APP_STYLEGUIDE_URL}images/logo-round-black.svg`}
className="w-20 mb-2 inline-block"
alt="Pirátská strana"
/>
......
......@@ -34,6 +34,37 @@ export const like = createAsyncAction(
}
);
export const removeLike = createAsyncAction(
/**
* @param {CF2021.Post} post
*/
async (post) => {
return successResult(post);
},
{
shortCircuitHook: ({ args }) => {
if (args.ranking.myVote !== "like") {
return errorResult();
}
return false;
},
postActionHook: ({ result }) => {
if (!result.error) {
PostStore.update((state) => {
state.items[result.payload.id].ranking.likes -= 1;
state.items[result.payload.id].ranking.score -= 1;
state.items[result.payload.id].ranking.myVote = "none";
if (state.filters.sort === "byScore") {
updateWindowPosts(state);
}
});
}
},
}
);
export const dislike = createAsyncAction(
/**
* @param {CF2021.Post} post
......@@ -65,6 +96,37 @@ export const dislike = createAsyncAction(
}
);
export const removeDislike = createAsyncAction(
/**
* @param {CF2021.Post} post
*/
async (post) => {
return successResult(post);
},
{
shortCircuitHook: ({ args }) => {
if (args.ranking.myVote !== "dislike") {
return errorResult();
}
return false;
},
postActionHook: ({ result }) => {
if (!result.error) {
PostStore.update((state) => {
state.items[result.payload.id].ranking.dislikes -= 1;
state.items[result.payload.id].ranking.score += 1;
state.items[result.payload.id].ranking.myVote = "none";
if (state.filters.sort === "byScore") {
updateWindowPosts(state);
}
});
}
},
}
);
/**
* Add new discussion post.
*/
......
......@@ -6,7 +6,7 @@ const Footer = () => {
<div className="footer__main py-4 lg:py-16 container container--default">
<section className="footer__brand">
<img
src="https://www.va-fighters.com/pirati/krajska-sablona/dist/assets/img/logo.svg"
src={`${process.env.REACT_APP_STYLEGUIDE_URL}images/logo-full-white.svg`}
alt=""
className="w-32 md:w-40 pb-6"
/>
......
......@@ -24,7 +24,7 @@ const Navbar = () => {
<div className="navbar__brand my-4 flex items-center lg:pr-8 lg:my-0">
<NavLink to="/">
<img
src={`${process.env.REACT_APP_STYLEGUIDE_URL}/images/logo-round-white.svg`}
src={`${process.env.REACT_APP_STYLEGUIDE_URL}images/logo-round-white.svg`}
className="w-8"
alt="Pirátská strana"
/>
......
import React from "react";
import classNames from "classnames";
const Thumbs = ({ likes, dislikes, onLike, onDislike, canThumb }) => {
const Thumbs = ({ likes, dislikes, onLike, onDislike, myVote }) => {
return (
<div>
<div className="space-x-2 text-sm flex items-center">
<button
className={classNames("text-blue-300 flex items-center space-x-1", {
"cursor-not-allowed": !canThumb,
"cursor-pointer": myVote === "none" || myVote === "like",
"cursor-default": myVote === "dislike",
})}
disabled={!canThumb}
disabled={myVote === "dislike"}
onClick={onLike}
>
<span className="font-bold">{likes}</span>
......@@ -17,9 +18,10 @@ const Thumbs = ({ likes, dislikes, onLike, onDislike, canThumb }) => {
</button>
<button
className={classNames("text-red-600 flex items-center space-x-1", {
"cursor-not-allowed": !canThumb,
"cursor-pointer": myVote === "none" || myVote === "dislike",
"cursor-default": myVote === "like",
})}
disabled={!canThumb}
disabled={myVote === "like"}
onClick={onDislike}
>
<i className="ico--thumbs-down transform -scale-x-1"></i>
......
......@@ -153,7 +153,7 @@ const Post = ({
dislikes={ranking.dislikes}
onLike={onLike}
onDislike={onDislike}
canThumb={ranking.myVote === "none"}
myVote={ranking.myVote}
/>
{displayActions && (
<DropdownMenu right>
......
import React from "react";
import pick from "lodash/pick";
import { dislike, like } from "actions/posts";
import { dislike, like, removeDislike, removeLike } from "actions/posts";
import PostList from "components/posts/PostList";
import { PostStore } from "stores";
......@@ -16,6 +16,32 @@ const PostsContainer = ({ className }) => {
// const onLike = (post) => like.run();
// const onDislike = (post) => console.log("dislike", post);
/**
*
* @param {CF2021.Post} post
*/
const onLike = (post) => {
if (post.ranking.myVote === "none") {
return like.run(post);
}
if (post.ranking.myVote === "like") {
return removeLike.run(post);
}
};
/**
*
* @param {CF2021.Post} post
*/
const onDislike = (post) => {
if (post.ranking.myVote === "none") {
return dislike.run(post);
}
if (post.ranking.myVote === "dislike") {
return removeDislike.run(post);
}
};
const sliceStart = (window.page - 1) * window.perPage;
const sliceEnd = window.page * window.perPage;
......@@ -40,8 +66,8 @@ const PostsContainer = ({ className }) => {
items={window.items
.slice(sliceStart, sliceEnd)
.map((postId) => items[postId])}
onLike={like.run}
onDislike={dislike.run}
onLike={onLike}
onDislike={onDislike}
className={className}
dimArchived={!showingArchivedOnly}
displayActions={true}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment