diff --git a/src/Flows.css b/src/Flows.css
index d16322e..f76e885 100644
--- a/src/Flows.css
+++ b/src/Flows.css
@@ -393,3 +393,38 @@
.op-btn {
margin: 0 0.25em;
}
+
+.box-content-wrapper {
+ display: flex;
+}
+
+.box-content-wrapper .box-content {
+ flex: 1 1;
+}
+
+.box-content-wrapper .box-content-vote {
+ flex: 0 0;
+}
+
+.vote-num {
+ text-align: center;
+}
+
+.vote-icon-inactive {
+ fill: None;
+ stroke: #333;
+ stroke-width: 2px;
+}
+
+.root-dark-mode .vote-icon-inactive {
+ stroke: #777;
+}
+
+
+.vote-icon-active {
+ fill: #333;
+}
+
+.root-dark-mode .vote-icon-active {
+ fill: #777;
+}
diff --git a/src/Flows.js b/src/Flows.js
index 6e668be..e2b55eb 100644
--- a/src/Flows.js
+++ b/src/Flows.js
@@ -228,6 +228,7 @@ class FlowItem extends PureComponent {
show_pid,
do_vote,
do_block,
+ do_react,
search_param,
} = this.props;
const { cw } = this.state;
@@ -340,13 +341,62 @@ class FlowItem extends PureComponent {
{!!info.hot_score && (
hot score: {info.hot_score}
)}
-
-
+
+
+
+
+
+
do_react && do_react(1)}
+ >
+
+
+ {do_react ? (
+ <>
+
{info.up_votes}
+
+
{info.down_votes}
+ >
+ ) : (
+
+ {info.up_votes - info.down_votes}
+
+ )}
+
do_react && do_react(-1)}
+ >
+
+
+
{info.poll && (
@@ -469,6 +519,21 @@ class FlowSidebar extends PureComponent {
});
}
+ set_reaction(reaction_status) {
+ console.log(reaction_status);
+ const prev_info = this.state.info;
+ const pid = prev_info.pid;
+ API.set_reaction(pid, reaction_status, this.props.token).then((json) => {
+ this.setState({
+ info: Object.assign({}, prev_info, json.data),
+ });
+ // TODO: save to localStore
+ this.syncState({
+ info: Object.assign({}, prev_info, json.data),
+ });
+ });
+ }
+
toggle_attention() {
const prev_info = this.state.info;
const pid = prev_info.pid;
@@ -710,6 +775,7 @@ class FlowSidebar extends PureComponent {
window.location.reload();
});
}}
+ do_react={this.set_reaction.bind(this)}
/>
);
diff --git a/src/flows_api.js b/src/flows_api.js
index 05943bb..940588d 100644
--- a/src/flows_api.js
+++ b/src/flows_api.js
@@ -100,6 +100,21 @@ export const API = {
return handle_response(response, true);
},
+ set_reaction: async (pid, reaction_status, token) => {
+ let data = new URLSearchParams([['status', reaction_status]]);
+
+ let response = await fetch(`${get_api_base_2()}/post/${pid}/reaction`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'User-Token': token,
+ },
+ body: data,
+ });
+
+ return handle_response(response, true);
+ },
+
report: async (pid, reason, should_hide, token) => {
let data = new URLSearchParams([
['pid', pid],