From a8328c076c0766608aa8ff72336ea26ee7064fe4 Mon Sep 17 00:00:00 2001
From: Renard
Date: Fri, 27 Sep 2019 14:41:35 -0300
Subject: Implementación de eliminación de posts

---
 src/Board.js  |   2 +
 src/Post.js   | 542 +++++++++++++++++++++++++++++++++-------------------------
 src/Thread.js |   1 +
 3 files changed, 310 insertions(+), 235 deletions(-)

(limited to 'src')

diff --git a/src/Board.js b/src/Board.js
index 2a6155f..f425954 100644
--- a/src/Board.js
+++ b/src/Board.js
@@ -167,6 +167,7 @@ class Board extends Component {
                   threadId={thread.id}
                   currentBoard={currentBoard}
                   nightMode={nightMode}
+                  totalReplies={thread.total_replies}
                 />
                 <Divider />
                 {thread.replies.map((reply, index, replies) => (
@@ -178,6 +179,7 @@ class Board extends Component {
                     key={"reply_" + reply.id}
                     currentBoard={currentBoard}
                     nightMode={nightMode}
+                    totalReplies={thread.total_replies}
                   />
                 ))}
               </Comment.Group>
diff --git a/src/Post.js b/src/Post.js
index a950f7c..a4c8a4a 100644
--- a/src/Post.js
+++ b/src/Post.js
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { Component } from "react";
 import {
   Image,
   Icon,
@@ -7,7 +7,8 @@ import {
   Flag,
   Embed,
   Form,
-  Button
+  Button,
+  Confirm
 } from "semantic-ui-react";
 import Moment from "react-moment";
 import "moment/locale/es";
@@ -68,263 +69,334 @@ const QuickReplyModal = ({ trigger, currentBoard, id, locked, replyIndex }) => (
   </Modal>
 );
 
-const Post = ({ index, post, locked, threadId, currentBoard, nightMode }) => {
-  const filesize = require("filesize");
+class Post extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      deleteDialog: false
+    };
+    this.showDialog = this.showDialog.bind(this);
+    this.handleCancel = this.handleCancel.bind(this);
+    this.handleConfirm = this.handleConfirm.bind(this);
+  }
 
-  // Manejo de posts eliminados
-  if (post.IS_DELETED > 0) {
-    return (
-      <Comment inverted={nightMode}>
-        <Comment.Avatar
-          src={`https://bienvenidoainternet.org/static/css/img/picnicbdy.gif`}
-        />
-        <Comment.Content>
-          <Comment.Author as="a">
-            #{currentBoard.board_type === 0 ? post.id : index + 1}
-          </Comment.Author>
-          <Comment.Metadata>
-            <div>
-              <Moment fromNow unix locale="es" date={post.timestamp} />
-            </div>
-          </Comment.Metadata>
-          <Comment.Text>
-            <span className="deleted">
-              Eliminado por el {post.IS_DELETED === 1 ? "usuario." : "Staff."}
-            </span>
-          </Comment.Text>
-        </Comment.Content>
-      </Comment>
-    );
+  showDialog() {
+    this.setState({ deleteDialog: true });
   }
 
-  // Obtener un avatar aleatorio basado en ID
-  let user_id = post.timestamp_formatted.split(" ID:")[1];
-  const seedrandom = require("seedrandom");
-  const rng = seedrandom(threadId + index);
-  const idRng = seedrandom(user_id);
-  const idColor =
-    "rgb(" +
-    Math.round(idRng() * 255) +
-    ", " +
-    Math.round(idRng() * 200) +
-    ", " +
-    Math.round(idRng() * 200) +
-    ")";
+  handleCancel() {
+    this.setState({ deleteDialog: false });
+  }
 
-  let rndAvatar, hue;
-  if (user_id !== "") {
-    let i = Math.round(idRng() * (avatars.length - 1));
-    rndAvatar = avatars[i];
-    hue = Math.round(idRng() * 360);
-  } else {
-    let i = Math.round(rng() * (avatars.length - 1));
-    rndAvatar = avatars[i];
-    hue = Math.round(rng() * 360);
+  handleConfirm() {
+    this.setState({ deleteDialog: false });
+    const { post, currentBoard } = this.props;
+    let password = localStorage.getItem("password");
+    fetch(
+      `https://bienvenidoainternet.org/cgi/api/delete?dir=${currentBoard.dir}&id=${post.id}&password=${password}`
+    )
+      .then(response => {
+        return response.json();
+      })
+      .then(resource => {
+        console.log(resource);
+      });
   }
 
-  // Obetener bandera del pais (para /world)
-  let flag;
-  if (currentBoard.dir === "world") {
-    flag = post.name.match("[A-Z][A-Z]");
-    if (flag !== null) {
-      flag = flag[0].toLowerCase();
+  render() {
+    const {
+      index,
+      post,
+      locked,
+      threadId,
+      currentBoard,
+      nightMode,
+      totalReplies
+    } = this.props;
+    const filesize = require("filesize");
+
+    // Manejo de posts eliminados
+    if (post.IS_DELETED > 0) {
+      return (
+        <Comment inverted={nightMode}>
+          <Comment.Avatar
+            src={`https://bienvenidoainternet.org/static/css/img/picnicbdy.gif`}
+          />
+          <Comment.Content>
+            <Comment.Author as="a">
+              #{currentBoard.board_type === 0 ? post.id : index + 1}
+            </Comment.Author>
+            <Comment.Metadata>
+              <div>
+                <Moment fromNow unix locale="es" date={post.timestamp} />
+              </div>
+            </Comment.Metadata>
+            <Comment.Text>
+              <span className="deleted">
+                Eliminado por el {post.IS_DELETED === 1 ? "usuario." : "Staff."}
+              </span>
+            </Comment.Text>
+          </Comment.Content>
+        </Comment>
+      );
+    }
+
+    // Obtener un avatar aleatorio basado en ID
+    let user_id = post.timestamp_formatted.split(" ID:")[1];
+    const seedrandom = require("seedrandom");
+    const rng = seedrandom(threadId + index);
+    const idRng = seedrandom(user_id);
+    const idColor =
+      "rgb(" +
+      Math.round(idRng() * 255) +
+      ", " +
+      Math.round(idRng() * 200) +
+      ", " +
+      Math.round(idRng() * 200) +
+      ")";
+
+    let rndAvatar, hue;
+    if (user_id !== "") {
+      let i = Math.round(idRng() * (avatars.length - 1));
+      rndAvatar = avatars[i];
+      hue = Math.round(idRng() * 360);
     } else {
-      flag = "kp"; // heh
+      let i = Math.round(rng() * (avatars.length - 1));
+      rndAvatar = avatars[i];
+      hue = Math.round(rng() * 360);
     }
-  }
 
-  // Fix: imagenes en dominio incorrecto
-  post.message = post.message.replace(
-    '<img src="/',
-    '<img src="https://bienvenidoainternet.org/'
-  );
+    // Obetener bandera del pais (para /world)
+    let flag;
+    if (currentBoard.dir === "world") {
+      flag = post.name.match("[A-Z][A-Z]");
+      if (flag !== null) {
+        flag = flag[0].toLowerCase();
+      } else {
+        flag = "kp"; // heh
+      }
+    }
 
-  // Fix para reach-router
-  if (currentBoard.board_type === 0) {
-    post.message = post.message.replace("/res/", "/read/");
-    post.message = post.message.replace(".html#", "/");
-  }
+    // Fix: imagenes en dominio incorrecto
+    post.message = post.message.replace(
+      '<img src="/',
+      '<img src="https://bienvenidoainternet.org/'
+    );
 
-  if (post.tripcode === " (★ ****-****)") {
-    post.tripcode = "";
-  }
+    // Fix para reach-router
+    if (currentBoard.board_type === 0) {
+      post.message = post.message.replace("/res/", "/read/");
+      post.message = post.message.replace(".html#", "/");
+    }
 
-  // Obtener lista de videos de youtube incrustados
-  const youtubeRe = RegExp(
-    /(?:https?:\/\/)?(?:www\.)?youtu(.be\/|be\.com\/watch\?v=)(\w{11})/g
-  );
-  const youtubeVideos = post.message.match(youtubeRe);
+    if (post.tripcode === " (★ ****-****)") {
+      post.tripcode = "";
+    }
 
-  // El post es nuestro?
-  const ownPosts = JSON.parse(localStorage.getItem("ownPosts"));
-  let isMine = false;
-  if (ownPosts !== null) {
-    if (Object.prototype.hasOwnProperty.call(ownPosts, currentBoard.dir)) {
-      ownPosts[currentBoard.dir].forEach(reply => {
-        if (reply.thread_id === post.parentid) {
-          if (reply.reply_id === post.id) {
-            isMine = true;
+    // Obtener lista de videos de youtube incrustados
+    const youtubeRe = RegExp(
+      /(?:https?:\/\/)?(?:www\.)?youtu(.be\/|be\.com\/watch\?v=)(\w{11})/g
+    );
+    const youtubeVideos = post.message.match(youtubeRe);
+
+    // El post es nuestro?
+    const ownPosts = JSON.parse(localStorage.getItem("ownPosts"));
+    let isMine = false;
+    if (ownPosts !== null) {
+      if (Object.prototype.hasOwnProperty.call(ownPosts, currentBoard.dir)) {
+        ownPosts[currentBoard.dir].forEach(reply => {
+          if (reply.thread_id === post.parentid) {
+            if (reply.reply_id === post.id) {
+              isMine = true;
+            }
           }
-        }
-      });
+        });
+      }
     }
-  }
 
-  let starColor;
-  if (user_id === "CAP_USER*") {
-    starColor = "yellow";
-  } else if (isMine) {
-    starColor = "blue";
-  } else {
-    starColor = "grey";
-  }
+    let starColor;
+    if (user_id === "CAP_USER*") {
+      starColor = "yellow";
+    } else if (isMine) {
+      starColor = "blue";
+    } else {
+      starColor = "grey";
+    }
 
-  let hasVideo = post.file.endsWith(".webm");
-  let hasAudio =
-    post.file.endsWith(".mp3") ||
-    post.file.endsWith(".opus") ||
-    post.file.endsWith(".ogg");
-  let isMime =
-    post.file.endsWith(".epub") ||
-    post.file.endsWith(".mod") ||
-    post.file.endsWith(".pdf") ||
-    post.file.endsWith(".s3m") ||
-    post.file.endsWith(".swf") ||
-    post.file.endsWith(".torrent") ||
-    post.file.endsWith(".xm");
+    let hasVideo = post.file.endsWith(".webm");
+    let hasAudio =
+      post.file.endsWith(".mp3") ||
+      post.file.endsWith(".opus") ||
+      post.file.endsWith(".ogg");
+    let isMime =
+      post.file.endsWith(".epub") ||
+      post.file.endsWith(".mod") ||
+      post.file.endsWith(".pdf") ||
+      post.file.endsWith(".s3m") ||
+      post.file.endsWith(".swf") ||
+      post.file.endsWith(".torrent") ||
+      post.file.endsWith(".xm");
 
-  return (
-    <Comment inverted={nightMode}>
-      <Comment.Avatar
-        src={`https://bienvenidoainternet.org/static/ico/${rndAvatar}.gif`}
-        style={{ filter: `hue-rotate(${hue}deg)` }}
-      />
-      <Comment.Content>
-        <Comment.Author
-          as="a"
-          href={post.mail !== "" ? `mailto:${post.email}` : null}
-        >
-          #{currentBoard.board_type === 0 ? post.id : index + 1}{" "}
-          <span
-            className={post.email === "sage" ? "username sage" : "username"}
+    let isDeleteable = true;
+    // No se pueden eliminar hilos con más de 5 respuestas
+    if (index === 0 && totalReplies > 5) {
+      isDeleteable = false;
+    }
+    // No se pueden eliminar hilos/post de /cero/
+    if (currentBoard.dir === "0") {
+      isDeleteable = false;
+    }
+    // No se pueden eliminar post con una antiguedad superior a 24 horas
+    if (Date.now() / 1000 - post.timestamp > 86400) {
+      isDeleteable = false;
+    }
+
+    return (
+      <Comment inverted={nightMode}>
+        <Comment.Avatar
+          src={`https://bienvenidoainternet.org/static/ico/${rndAvatar}.gif`}
+          style={{ filter: `hue-rotate(${hue}deg)` }}
+        />
+        <Comment.Content>
+          <Comment.Author
+            as="a"
+            href={post.mail !== "" ? `mailto:${post.email}` : null}
           >
-            {currentBoard.dir === "world"
-              ? post.name.split("<em>")[0]
-              : post.name}{" "}
-            {currentBoard.dir === "world" ? <Flag name={flag} /> : null}
-          </span>
-          <span className="tripcode">{post.tripcode}</span>
-        </Comment.Author>
-        <Comment.Metadata>
-          <div>
-            <Moment fromNow unix locale="es" date={post.timestamp} />
-          </div>
-          <div>
-            <Icon name="star" color={starColor} />
-            {user_id === "CAP_USER*" ? (
-              "Usuario verificado"
-            ) : (
-              <span style={{ color: idColor }}>{user_id}</span>
-            )}
-            {isMine ? " (Tú)" : null}
-          </div>
-        </Comment.Metadata>
-        <Comment.Text>
-          {post.file !== "" ? (
-            <div className="imageContainer">
-              {hasVideo && (
-                // eslint-disable-next-line jsx-a11y/media-has-caption
-                <video
-                  src={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
-                  controls
-                  poster={`https://bienvenidoainternet.org/${currentBoard.dir}/thumb/${post.thumb}`}
-                  width="400"
-                />
-              )}
-              {hasAudio && (
-                // eslint-disable-next-line jsx-a11y/media-has-caption
-                <audio
-                  src={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
-                  controls
-                />
-              )}
-              {!hasVideo && !hasAudio && !isMime && (
-                <ImageModal
-                  href={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
-                  trigger={
-                    <Image
-                      centered
-                      className="postImage"
-                      src={`https://bienvenidoainternet.org/${currentBoard.dir}/thumb/${post.thumb}`}
-                    />
-                  }
-                />
-              )}
-              {isMime && (
-                <Image
-                  size="mini"
-                  ui={false}
-                  src={`https://bienvenidoainternet.org/static/${post.thumb}`}
-                />
+            #{currentBoard.board_type === 0 ? post.id : index + 1}{" "}
+            <span
+              className={post.email === "sage" ? "username sage" : "username"}
+            >
+              {currentBoard.dir === "world"
+                ? post.name.split("<em>")[0]
+                : post.name}{" "}
+              {currentBoard.dir === "world" ? <Flag name={flag} /> : null}
+            </span>
+            <span className="tripcode">{post.tripcode}</span>
+          </Comment.Author>
+          <Comment.Metadata>
+            <div>
+              <Moment fromNow unix locale="es" date={post.timestamp} />
+            </div>
+            <div>
+              <Icon name="star" color={starColor} />
+              {user_id === "CAP_USER*" ? (
+                "Usuario verificado"
+              ) : (
+                <span style={{ color: idColor }}>{user_id}</span>
               )}
+              {isMine ? " (Tú)" : null}
+            </div>
+          </Comment.Metadata>
+          <Comment.Text>
+            {post.file !== "" ? (
+              <div className="imageContainer">
+                {hasVideo && (
+                  // eslint-disable-next-line jsx-a11y/media-has-caption
+                  <video
+                    src={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
+                    controls
+                    poster={`https://bienvenidoainternet.org/${currentBoard.dir}/thumb/${post.thumb}`}
+                    width="400"
+                  />
+                )}
+                {hasAudio && (
+                  // eslint-disable-next-line jsx-a11y/media-has-caption
+                  <audio
+                    src={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
+                    controls
+                  />
+                )}
+                {!hasVideo && !hasAudio && !isMime && (
+                  <ImageModal
+                    href={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
+                    trigger={
+                      <Image
+                        centered
+                        className="postImage"
+                        src={`https://bienvenidoainternet.org/${currentBoard.dir}/thumb/${post.thumb}`}
+                      />
+                    }
+                  />
+                )}
+                {isMime && (
+                  <Image
+                    size="mini"
+                    ui={false}
+                    src={`https://bienvenidoainternet.org/static/${post.thumb}`}
+                  />
+                )}
 
-              <div>
-                <a
-                  target="_blank"
-                  rel="noopener noreferrer"
-                  href={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
-                >
-                  {post.file}
-                </a>{" "}
-                {!hasAudio &&
-                  !isMime &&
-                  `${post.image_width}x${post.image_height}`}{" "}
-                {filesize(post.file_size)}
+                <div>
+                  <a
+                    target="_blank"
+                    rel="noopener noreferrer"
+                    href={`https://bienvenidoainternet.org/${currentBoard.dir}/src/${post.file}`}
+                  >
+                    {post.file}
+                  </a>{" "}
+                  {!hasAudio &&
+                    !isMime &&
+                    `${post.image_width}x${post.image_height}`}{" "}
+                  {filesize(post.file_size)}
+                </div>
               </div>
-            </div>
-          ) : null}
+            ) : null}
 
-          {youtubeVideos !== null
-            ? youtubeVideos.map((url, i) => {
-                let id = url.split("?v=")[1];
-                return (
-                  <div className="playerContainer" key={i}>
-                    <Embed
-                      id={id}
-                      source="youtube"
-                      key={i}
-                      placeholder={`https://img.youtube.com/vi/${id}/hqdefault.jpg`}
-                    />
-                  </div>
-                );
-              })
-            : null}
+            {youtubeVideos !== null
+              ? youtubeVideos.map((url, i) => {
+                  let id = url.split("?v=")[1];
+                  return (
+                    <div className="playerContainer" key={i}>
+                      <Embed
+                        id={id}
+                        source="youtube"
+                        key={i}
+                        placeholder={`https://img.youtube.com/vi/${id}/hqdefault.jpg`}
+                      />
+                    </div>
+                  );
+                })
+              : null}
 
-          <div
-            className={`postMessage ${
-              currentBoard.dir === "zonavip" ? "vipFont" : null
-            }`}
-            dangerouslySetInnerHTML={{ __html: post.message }}
-          />
-        </Comment.Text>
-        <Comment.Actions>
-          {locked ? null : (
-            <QuickReplyModal
-              trigger={<Comment.Action>Responder</Comment.Action>}
-              currentBoard={currentBoard}
-              id={threadId}
-              locked={locked}
-              replyIndex={currentBoard.board_type === 0 ? post.id : index + 1}
+            <div
+              className={`postMessage ${
+                currentBoard.dir === "zonavip" ? "vipFont" : null
+              }`}
+              dangerouslySetInnerHTML={{ __html: post.message }}
             />
-          )}
-          <ReportModal
-            trigger={<Comment.Action>Reportar</Comment.Action>}
-            postId={post.id}
-          />
-        </Comment.Actions>
-      </Comment.Content>
-    </Comment>
-  );
-};
+          </Comment.Text>
+          <Comment.Actions>
+            {locked ? null : (
+              <QuickReplyModal
+                trigger={<Comment.Action>Responder</Comment.Action>}
+                currentBoard={currentBoard}
+                id={threadId}
+                locked={locked}
+                replyIndex={currentBoard.board_type === 0 ? post.id : index + 1}
+              />
+            )}
+            <ReportModal
+              trigger={<Comment.Action>Reportar</Comment.Action>}
+              postId={post.id}
+            />
+            {isDeleteable && (
+              <Comment.Action onClick={this.showDialog}>
+                Eliminar
+              </Comment.Action>
+            )}
+          </Comment.Actions>
+        </Comment.Content>
+        <Confirm
+          open={this.state.deleteDialog}
+          content="¿Estás seguro de querer eliminar este post?"
+          onCancel={this.handleCancel}
+          onConfirm={this.handleConfirm}
+          confirmButton="Eliminar"
+          size="small"
+        />
+      </Comment>
+    );
+  }
+}
 
 export default Post;
diff --git a/src/Thread.js b/src/Thread.js
index cb2e2e9..39d8382 100644
--- a/src/Thread.js
+++ b/src/Thread.js
@@ -173,6 +173,7 @@ class Thread extends Component {
               locked={locked}
               currentBoard={currentBoard}
               threadId={id}
+              totalReplies={total_replies}
             />
           ))}
         </Comment.Group>
-- 
cgit v1.2.1-18-gbd029