import React, { useState, useEffect } from 'react' import fetch from 'unfetch' import LoadingIndicator from '../components/LoadingIndicator' import Sleep from '../components/sleep' import NewsEntry from '../components/newsEntry' import Composer from '../components/composer' import Header from '../components/header' import Modal from '../components/modal' import styles from './forum.module.css' import constants from '../constants.json' const forumPostPerPage = 5 function fetchEntry(postKey, forumName) { return new Promise((resolve) => { fetch( `${constants.apiUrl}forumEntry?forumName=${forumName}&postKey=${postKey}`, { credentials: 'include', } ) .then((resp) => { return resp.json() }) .then((res) => { resolve(res) }) }) } function fetchForum(forumName, from) { return new Promise((resolve) => { fetch( `${constants.apiUrl}forumEntries?forumName=${forumName}&getContent=true${ from ? `&from=${from}` : '' }&count=${forumPostPerPage}`, { credentials: 'include', } ) .then((resp) => { return resp.json() }) .then((res) => { resolve(res) }) }) } function addPost(title, content, forumName) { return new Promise((resolve) => { fetch(constants.apiUrl + 'addPost', { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ forumName: forumName, title: title, content: content, }), }) .then((res) => { return res.json() }) .then((res) => { resolve(res) }) }) } function updateForumPost(forum, postKey, postData) { return Object.keys(forum).reduce((acc, key) => { const entry = forum[key] if (key === postKey) { acc = { ...acc, [key]: postData, } } else { acc = { ...acc, [key]: entry, } } return acc }, {}) } const NewsEntryContainer = ({ postKey, setNews, news, userId, newsEntryData, onTitleClick, forumName, }) => { const [error, setError] = useState(false) useEffect(() => { if (!newsEntryData && !error) { fetchEntry(postKey, forumName) .then((res) => { const { success, entry, msg } = res if (success) { setNews({ [postKey]: entry, ...news }) } else { alert(msg) setError(true) } }) .catch((e) => { console.error(e) setError(true) }) } }, []) if (!newsEntryData) { return } if (error) { return
Lil fuckup
} return ( { fetch(constants.apiUrl + 'rmPost', { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ forumName: forumName, postKey: postKey, }), }) .then((res) => { return res.json() }) .then((res) => { const { success, msg } = res if (success) { setNews( Object.keys(news).reduce((acc, key) => { const entry = news[key] if (key !== postKey) { acc = { ...acc, [key]: entry, } } return acc }, {}) ) } else { alert(msg) } }) }} onNewsReact={({ reaction, isDelete }) => { fetch(constants.apiUrl + 'react', { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ reaction: reaction, postKey: postKey, isDelete: isDelete, forumName: forumName, }), }) .then((res) => { return res.json() }) .then((res) => { setNews(updateForumPost(news, postKey, res.postData)) }) }} onCommentReact={({ path, reaction, isDelete }) => { fetch(constants.apiUrl + 'react', { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'reaction', postKey: postKey, path: path, reaction: reaction, isDelete: isDelete, forumName: forumName, }), }) .then((res) => { return res.json() }) .then((res) => { const { success, postData, msg } = res if (success) { setNews(updateForumPost(news, postKey, postData)) } else { alert(msg) } }) }} onDelete={(path) => { fetch(constants.apiUrl + 'comment', { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'delete', path: path, postKey: postKey, forumName: forumName, }), }) .then((res) => { return res.json() }) .then((res) => { const { success, postData, msg } = res if (success) { setNews(updateForumPost(news, postKey, postData)) } else { alert(msg) } }) }} onComment={(path, content) => { fetch(constants.apiUrl + 'comment', { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'add', path: path, content: content, postKey: postKey, forumName: forumName, }), }) .then((res) => { return res.json() }) .then((res) => { const { success, postData, msg } = res if (success) { setNews(updateForumPost(news, postKey, postData)) } else { alert(msg) } }) }} /> ) } export default function Forum({ router, globalData, globalState, setGlobalState, forumName, children, allowPost, }) { const userId = globalData.userId const [news, setNews] = useState(null) const [nextEntryKey, setNextEntryKey] = useState() const [fetchingForum, setFetchingForum] = useState(false) const [postInModalKey, setPostInModalKey] = useState() const [isUploading, setIsUploading] = useState(false) useEffect(() => { if (globalState[forumName]) { const { entries, nextKey } = globalState[forumName] setNextEntryKey(nextKey) setNews(entries) } else { setFetchingForum(true) fetchForum(forumName).then((res) => { setFetchingForum(false) const { entries, nextKey } = res setNextEntryKey(nextKey) setNews(entries) setGlobalState({ [forumName]: res }) }) } }, []) useEffect(() => { const postKey = router.query.postKey ? decodeURIComponent(router.query.postKey) : '' if (postKey) { setPostInModalKey(postKey) } }, [router.query.postKey]) const renderNews = () => { if (news) { const newsItems = Object.keys(news).map((postKey) => { const newsEntryData = news[postKey] return ( { setPostInModalKey(postKey) router.replace( `${router.pathname}?postKey=${encodeURIComponent(postKey)}`, undefined, { shallow: true } ) }} key={postKey} postKey={postKey} setNews={setNews} news={news} userId={userId} newsEntryData={newsEntryData} /> ) }) return (
{allowPost && ( { setIsUploading(true) addPost(title, content, forumName).then((res) => { const { success, newPostKey, newEntry, msg } = res if (success) { setNews({ [newPostKey]: newEntry, ...news }) } else { alert(msg) } setIsUploading(false) }) }} /> )} {isUploading && (
{'Feltöltés ...'}
)}
{newsItems}
{nextEntryKey ? (
{ if (fetchingForum) { return } setFetchingForum(true) fetchForum(forumName, nextEntryKey).then((res) => { setFetchingForum(false) const { entries, nextKey } = res setNextEntryKey(nextKey) setNews({ ...news, ...entries }) setGlobalState({ news: { entries: { ...news, ...entries }, nextKey: nextKey, }, }) }) }} > {fetchingForum ? ( ) : ( 'Több bejegyzés betöltése' )}
) : (
{newsItems.length === 0 ? 'Üres fórum' : 'The end'}
)}
) } else { return } } return (
{children || null} {renderNews()} {postInModalKey && ( { setPostInModalKey(undefined) router.replace(router.pathname, undefined, { shallow: true }) }} > {news ? ( ) : ( )} )}
) }