import { Avatar, Button, Col, Drawer, Form, Layout, Modal, Progress, Row, Tag, TagProps, Tooltip } from "antd"; import { EyeOutlined } from "@ant-design/icons"; import { Link } from "react-router-dom"; import { MoodCreateModal } from "../Mood/MoodCreate"; import { NLView } from "../../types"; import { SelectMood, SelectMoodForm } from "../../Components/SelectMood"; import { Spin } from "../../Components/Spin"; import { useActions, useAppState } from "../../overmind"; import { useCachedMood, useCachedMoods, useCachedPost, useCachedUser } from "../../hooks/useCached"; import { useEffect, useRef, useState } from "react"; import { useParams } from "react-router"; import useForm from "antd/lib/form/hooks/useForm"; // import { ContentImage, contentImageUrl } from "../../Components/Image"; import { Ebene } from "../../Components/Icons/Ebene"; import { MoodReadResponse, PostReadResponse, RatingUpdateResponse } from "@newstackdev/iosdk-newgraph-client-js"; import { NFTIcon } from "../../Components/Icons/NTFIcon"; import PostReportModal from "./components/PostModal"; // import { NewcoinLink } from "../Profile"; import { BlockExplorerLink, blockExplorerUrl } from "../../Components/Links"; import { ContentImage } from "../../Components/Image"; // import { ContentLayout } from "../Components/ContentLayout"; import { ContentLayoutDeepLike } from "../../Components/ContentLayout"; import { Edit } from "../../Components/Icons/Edit"; import { EyeClosed } from "../../Components/Icons/EyeClosed"; import { EyeOpen } from "../../Components/Icons/EyeOpen"; import { LargeArrowBack } from "../../Components/Icons/LargeArrowBack"; import { Share } from "../../Components/Share"; import { Tags } from "./components/Tags"; import { VerifiedIcon } from "../../Components/Icons/VerifiedIcon"; import { Vote } from "../../Components/Vote"; import { fischerYates } from "../../utils/random"; import { isEmpty } from "lodash"; import { useVerified } from "../../hooks/useVerified"; import Title from "../Explore/Title"; import useMediaQuery from "../../hooks/useMediaQuery"; export const useVotingStreamMood = () => { const { moodId, postId, id } = useParams<{ moodId: string; postId: string; id: string; }>(); const state = useAppState(); const currPost = useCachedPost({ id: postId || id }, true); const { cachedMoods, isCachedMoodsLoading } = useCachedMoods(); const [availableMoods, setAvailableMoods] = useState>([]); const [index, setIndex] = useState(-1); const [currMood, setCurrMood] = useState(); const [moodPosts, setMoodPosts] = useState>([]); const getIndex = () => { if (!currMood?.id) return; if (index && moodPosts[index]?.id == currPost.id) return; console.log("mp:", currMood.id, currPost.id); const ix = moodPosts.findIndex((p) => p.id === postId); setIndex(ix > 0 ? ix : 0); }; useEffect(() => { if (!isEmpty(cachedMoods)) { const randomizedMoods = fischerYates(Object.values(cachedMoods)) as MoodReadResponse[]; const currentMood = randomizedMoods.find(async (mood) => { const randomizedMoodId = (await mood).id; return randomizedMoodId === moodId; }); setAvailableMoods(randomizedMoods); setCurrMood(currentMood); setMoodPosts(currentMood?.posts || []); } }, [state.api.auth.moods, isCachedMoodsLoading, cachedMoods]); useEffect(() => { if (!isEmpty(availableMoods) && !isEmpty(moodPosts)) { getIndex(); if (!moodPosts[index + 1]?.id) { const updatedMood = availableMoods[availableMoods.findIndex((mood) => mood.id === currMood?.id) + 1]; setCurrMood(updatedMood); setMoodPosts(updatedMood?.posts || []); setIndex(0); } } }, [state.routing.location, currPost, currMood, availableMoods, moodPosts]); const getPosts = (m?: MoodReadResponse) => { const cm = state.api.cache.moods[m?.id || ""]; return cm && cm.posts ? cm.posts : []; }; const nextPath = () => { const _nextPostId = moodPosts[index + 1]?.id; const nextMood = _nextPostId ? currMood : undefined; const _moodPosts = getPosts(nextMood) || []; const nextPost = _nextPostId || (_moodPosts && _moodPosts[0] && _moodPosts[0].id); const nextPath = nextMood ? `/folder/${nextMood?.id}/${nextPost}` : "/explore"; //(index != null) && moodPosts[index + 1]?.id ? return nextPath; }; return { nextPath, currMood, currPost, index, contextType: "mood", contextValue: moodId, }; }; const useVotingStreamTags = () => { const { tags, postId, id } = useParams<{ tags: string; postId: string; id: string; }>(); const currPost = useCachedPost({ id: postId || id }, true); const [index, setIndex] = useState(-1); const actions = useActions(); const state = useAppState(); // const currTags = useCachedPostSearch({ tags }, true); const tagsPosts = state.lists.search.posts.results?.value || []; const getIndex = () => { if (!tags) return; const ix = tagsPosts.findIndex((p) => p.id === postId); setIndex(ix > 0 ? ix : 0); }; useEffect(() => getIndex(), [state.routing.location, currPost]); const nextPath = () => { const _nextPostId = tagsPosts[index + 1]?.id; // const nextTags = ??? just make it one tag less or e.g. one of the tags on the last post const nextPath = `/tags/${tags}/${_nextPostId}`; return nextPath; }; return { nextPath, currPost, index, contextType: "tags", contextValue: tags, }; }; //TODO move funcitons to separate file export const round = (n) => Math.round(n * 10000) / 10000; export const sumScore = (tagRels?: { score?: number }[]) => { if (!(tagRels instanceof Array)) return 0; const w = 1 / tagRels.length; return round(tagRels.reduce((r, c) => r + w * (c.score || 0), 0)); }; export const bySumScore = (a, b) => sumScore(b["_rel"]) - sumScore(a["_rel"]); const SvgPolygons: NLView<{ visionTags?: { value?: string; polygons?: { x: number; y: number }[][]; }[]; }> = ({ visionTags }) => !visionTags ? ( <> ) : (
{visionTags?.map((t) => ( {t.polygons?.map((polygon) => ( <> {visionTags.length > 1 ? ( {t.value} ) : ( <> )} `${point.x * 100},${point.y * 100}`).join(" ")} > {/* {polygon.map(point => <>{point.x}{point.y})} */} ))} ))}
); type Polygon = { x: number; y: number }[]; export type SimplifiedTag = { value?: string; polygons?: Polygon[]; }; export const postBase: (useVotingStreamHook: typeof useVotingStreamTags, votingEnabled?: boolean) => NLView = (useVotingStreamHook, votingEnabled = true) => () => { const state = useAppState(); const actions = useActions(); const [copyToClipboard, setCopyToClipboard] = useState(false); const [isEyeOpened, setIsEyeOpened] = useState(false); const [isEyeOpenedResponzive, setIsEyeOpenedResponzive] = useState(false); const [visible, setVisible] = useState(false); const isResponzive = useMediaQuery("(max-width: 1024px)"); // const moodsToAttach = (state.api.auth.moods || []).filter((m) => m.id); // current users's moods const nextInStream = useVotingStreamHook(); //useVotingStreamTags(); const ref = useRef(); const containerDeeplike = useRef(); const { contextType, contextValue, currPost, nextPath, index } = nextInStream; const author = useCachedUser({ id: currPost ? currPost?.author?.id : "" }); const username = currPost?.author?.username || author?.username || author?.displayName; const { verifiedUsers } = useVerified([username || ""]); const isVerifiedUser = verifiedUsers && username && verifiedUsers.includes(username); const [hilightTag, setHilightTag] = useState([]); const navigateToNext = () => { const location = nextPath(); if (!location) return; actions.routing.historyPush({ location }); }; const addToMoods = async (form?: { moods: { id: string }[] }) => { console.log("attachToMoods: Calling..."); if (form?.moods?.length) await actions.api.post.attachToMoods({ post: currPost, moods: form?.moods || [], }); console.log("attachToMoods: done Attaching to moods..."); navigateToNext(); }; const doneVoting = (rating: number) => { if (rating > 0) { actions.api.post.rate({ post: currPost, amount: rating, contextType, contextValue, messageWrapper: (msg: string, rating: any) => rating.TxID_mintFile ? ( {msg}
click for a newscan receipt
) : ( <>{msg} ), // mood: currMood }); } if (rating < 100) { return navigateToNext(); } window.addEventListener("keydown", function (e) { if (e.keyCode === 32 && e.target === document.body && rating === 100) { e.preventDefault(); window.scrollTo(0, 500); !isResponzive && setIsEyeOpened(true); } }); // if at 100 the mood will show itself }; // else either at 100% or stopped rating // if (currMood.id && index === -1) return ; if (!contextType && !(index >= 0)) return ; const url = [window.location.protocol, "//", window.location.host, state.routing.location].join(""); const isVisionTag = ( t: | { _rel?: { source: string; polygons: SimplifiedTag["polygons"]; }[]; } | any, ) => t._rel?.find((r) => r.source === "vision" && r.polygons); const nonVisionTags: SimplifiedTag[] = currPost.tags?.filter((t) => !isVisionTag(t)).map((t) => ({ ...t, polygons: [] })) || []; const visionTags: SimplifiedTag[] = currPost.tags ?.filter((t) => isVisionTag(t)) .map((t) => ({ ...t, polygons: JSON.parse(t._rel?.find((r) => r.source === "vision")?.polygons || "[]"), })) || []; useEffect(() => { actions.ux.setFooterVisibility({ footerShown: false }); return () => { actions.ux.setFooterVisibility({ footerShown: true }); }; }, []); return ( <> { const eh = (e) => { if (e.which !== 32) return; window.removeEventListener("keyup", eh); e.preventDefault(); navigateToNext(); }; window.addEventListener("keyup", eh); return () => { window.removeEventListener("keyup", eh); }; }} info={ {isResponzive && ( } className="u-margin-right-small" /> {username &&

{username}

}
)}

{currPost.title || "Folder name"}

{username} {isVerifiedUser && } {currPost.description} {currPost.author?.newcoinPoolTx && ( Creator pool )} {currPost?.author?.newcoinPoolTx && ( {currPost.newcoinMintTx === "REQUESTED" ? ( /* + currPost.newcoinMintTx || ""*/

Minting NFT...

) : currPost.newcoinMintTx === "FAILED" ? (

NFT Minting failed, please contact us for more details

) : ( <> See minted NFT )}
)} {/* */} {/* infobox */} {currPost.tags?.length ? ( isEyeOpened ? ( { setHilightTag([]); setIsEyeOpened(false); }} onMouseOver={() => setHilightTag(visionTags)} onMouseOut={() => setHilightTag([])} > ) : ( { if (isResponzive) { setIsEyeOpenedResponzive(true); setVisible((p) => !p); } else setIsEyeOpened(true); }} > ) ) : ( <> )} {/* infobox */}
} > {/PROCESSING/i.test(currPost.contentUrl || "") ? ( ) : ( )} {hilightTag?.length ? : <>}
); }; export const Post = postBase(useVotingStreamMood, false); export const PostInMood = postBase(useVotingStreamMood); export const PostInTags = postBase(useVotingStreamTags); { /* } visible={state.flows.rating.value === 100} style={{ textAlign: "center" }} >

{state.flows.rating.value}

//TODO look at addtoMoods
*/ }