From cc5d04288981ecbe2fec851d4669fcf874ddc216 Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Fri, 26 Apr 2024 19:13:23 +0200 Subject: [PATCH] feat: add challenge modal --- .../challenge-modal.module.css | 79 +++++++++++ .../challenge-modal/challenge-modal.tsx | 125 ++++++++++++++++++ src/components/challenge-modal/index.ts | 1 + src/components/post-form/post-form.tsx | 123 ++++++++++++++--- src/components/post/post.module.css | 10 ++ src/components/post/post.tsx | 55 ++++++-- src/hooks/use-challenges.ts | 24 ++++ src/lib/utils/challenge-utils.ts | 63 +++++++++ src/modules.d.ts | 2 + src/themes.css | 10 ++ 10 files changed, 463 insertions(+), 29 deletions(-) create mode 100644 src/components/challenge-modal/challenge-modal.module.css create mode 100644 src/components/challenge-modal/challenge-modal.tsx create mode 100644 src/components/challenge-modal/index.ts create mode 100644 src/hooks/use-challenges.ts create mode 100644 src/lib/utils/challenge-utils.ts diff --git a/src/components/challenge-modal/challenge-modal.module.css b/src/components/challenge-modal/challenge-modal.module.css new file mode 100644 index 00000000..682d3036 --- /dev/null +++ b/src/components/challenge-modal/challenge-modal.module.css @@ -0,0 +1,79 @@ +.container { + position: fixed; + top: calc(50% - 150px); + left: calc(50% - 150px); + display: block; + padding: 2px; + font-size: 10pt; + border-left: none; + border-top: none; + z-index: 1000; + background-color: var(--challenge-modal-background-color); + border: var(--challenge-modal-border); +} + +.title { + font-size: var(--challenge-modal-title-font-size); + text-align: center; + margin-bottom: 1px; + padding: 0; + height: 18px; + line-height: 18px; + cursor: move; + font-weight: var(--challenge-modal-title-font-weight); + background-color: var(--challenge-modal-title-background-color); + color: var(--challenge-modal-title-text-color); + border: var(--challenge-modal-title-border); +} + +.closeIcon { + all: unset; + float: right; + cursor: pointer; + margin-bottom: -4px; + width: 18px; + height: 18px; + border: none; + image-rendering: pixelated; + background-image: var(--close-button-background-image); +} + +.container input, .container textarea { + border: 1px solid #aaa; + font-family: Arial, Helvetica, sans-serif; + font-size: 10pt; + outline: medium none; + width: 298px; + padding: 2px; + margin-bottom: 1px; +} + +.content textarea { + vertical-align: top; +} + +.challengeAnswer { + font-size: 11px !important; + padding: 0px 2px; + font-family: monospace !important; +} + +.challengeMediaWrapper { + display: flex; + justify-content: center; + align-items: center; + margin: 5px 0; +} + +.challengeFooter { + display: flex; + justify-content: space-between; + align-items: center; + box-sizing: border-box; +} + +.challengeFooter button { + margin: 5px 5px 0 0; + cursor: pointer; + text-transform: capitalize; +} \ No newline at end of file diff --git a/src/components/challenge-modal/challenge-modal.tsx b/src/components/challenge-modal/challenge-modal.tsx new file mode 100644 index 00000000..336be334 --- /dev/null +++ b/src/components/challenge-modal/challenge-modal.tsx @@ -0,0 +1,125 @@ +import { useState } from 'react'; +import { Challenge as ChallengeType, useComment } from '@plebbit/plebbit-react-hooks'; +import { useTranslation } from 'react-i18next'; +import useChallenges from '../../hooks/use-challenges'; +import styles from './challenge-modal.module.css'; +import { getPublicationType } from '../../lib/utils/challenge-utils'; +import Draggable from 'react-draggable'; + +interface ChallengeProps { + challenge: ChallengeType; + closeModal: () => void; +} + +const Challenge = ({ challenge, closeModal }: ChallengeProps) => { + const { t } = useTranslation(); + + const challenges = challenge?.[0]?.challenges; + const publication = challenge?.[1]; + + const publicationType = getPublicationType(publication); + const { author, content, link, title } = publication || {}; + const { displayName } = author || {}; + + const [currentChallengeIndex, setCurrentChallengeIndex] = useState(0); + const [answers, setAnswers] = useState([]); + + const isTextChallenge = challenges[currentChallengeIndex].type === 'text/plain'; + const isImageChallenge = challenges[currentChallengeIndex].type === 'image/png'; + + const onAnswersChange = (e: React.ChangeEvent) => { + setAnswers((prevAnswers) => { + const updatedAnswers = [...prevAnswers]; + updatedAnswers[currentChallengeIndex] = e.target.value; + return updatedAnswers; + }); + }; + + const onSubmit = () => { + publication.publishChallengeAnswers(answers); + setAnswers([]); + closeModal(); + }; + + const onEnterKey = (e: React.KeyboardEvent) => { + if (e.key !== 'Enter') return; + if (challenges[currentChallengeIndex + 1]) { + setCurrentChallengeIndex((prev) => prev + 1); + } else { + onSubmit(); + } + }; + + return ( + +
+
+ Challenge for {publicationType} +
+
+
+ +
+ {title && ( +
+ +
+ )} + {content && ( +
+