move posts tabs

This commit is contained in:
SrGooglo 2023-02-24 14:42:07 +00:00
parent 3fd3045b83
commit 626ac1f754
9 changed files with 414 additions and 0 deletions

View File

@ -0,0 +1,126 @@
import React from "react"
import { Skeleton } from "antd"
import { Icons } from "components/Icons"
import { PostsList, Searcher } from "components"
import Post from "models/post"
import "./index.less"
export default class ExplorePosts extends React.Component {
state = {
loading: true,
initialLoading: true,
hasMorePosts: true,
posts: [],
focusedSearcher: false,
filledSearcher: false,
}
wsEvents = {
"post.new": async (data) => {
this.setState({
posts: [data, ...this.state.posts],
})
},
"post.delete": async (id) => {
this.setState({
posts: this.state.posts.filter((post) => {
return post._id !== id
}),
})
}
}
loadPosts = async ({
trim,
replace = false
} = {}) => {
await this.setState({
loading: true,
})
// get posts from api
const result = await Post.getExplorePosts({
trim: trim ?? this.state.posts.length,
})
console.log("Loaded posts => \n", result)
if (result) {
if (result.length === 0) {
await this.setState({
hasMorePosts: false,
})
return false
}
await this.setState({
posts: replace ? result : [...this.state.posts, ...result],
})
}
await this.setState({
loading: false,
})
if (this.state.initialLoading) {
await this.setState({
initialLoading: false,
})
}
}
toggleFocusSearcher = (to) => {
to = to ?? !this.state.focusedSearcher
this.setState({
focusedSearcher: to
})
}
toggleState = (key, to) => {
to = to ?? !this.state[key]
this.setState({
[key]: to
})
}
componentDidMount = async () => {
await this.loadPosts()
Object.keys(this.wsEvents).forEach((event) => {
window.app.cores.api.namespaces["main"].listenEvent(event, this.wsEvents[event])
})
}
componentWillUnmount = async () => {
Object.keys(this.wsEvents).forEach((event) => {
window.app.cores.api.namespaces["main"].unlistenEvent(event, this.wsEvents[event])
})
}
render() {
return <div className="postsExplore">
<div className="postsExplore_header">
<Searcher
autoFocus={false}
onFocus={() => this.toggleState("focusedSearcher", true)}
onUnfocus={() => this.toggleState("focusedSearcher", false)}
onFilled={() => this.toggleState("filledSearcher", true)}
onEmpty={() => this.toggleState("filledSearcher", false)}
/>
</div>
{
this.state.focusedSearcher || this.state.filledSearcher ? null : this.state.initialLoading ? <Skeleton active /> : <PostsList
loading={this.state.loading}
hasMorePosts={this.state.hasMorePosts}
onLoadMore={this.loadPosts}
posts={this.state.posts}
/>
}
</div>
}
}

View File

@ -0,0 +1,8 @@
.postsExplore {
width: 100%;
.postsExplore_header {
font-size: 1.3rem;
margin-bottom: 20px;
}
}

View File

@ -0,0 +1,119 @@
import React from "react"
import { Skeleton } from "antd"
import { PostsList } from "components"
import FeedModel from "models/feed"
import "./index.less"
const emptyListRender = () => {
return <div className="emptyFeed">
<h2>
We don't have any posts to show you.
</h2>
<p>
Search for new people to follow on <a onClick={() => app.setLocation("/home/explore")}>explore</a> tab, to start view their posts.
</p>
</div>
}
export default class Feed extends React.Component {
state = {
loading: true,
initialLoading: true,
hasMorePosts: true,
posts: [],
}
wsEvents = {
"post.new": (data) => {
this.setState({
posts: [data, ...this.state.posts],
})
},
"post.delete": (id) => {
this.setState({
posts: this.state.posts.filter((post) => {
return post._id !== id
}),
})
}
}
loadData = async ({
trim,
replace = false
} = {}) => {
await this.setState({
loading: true,
})
// get posts from api
const result = await FeedModel.getPostsFeed({
trim: trim ?? this.state.posts.length,
})
console.log("Loaded data => \n", result)
if (result) {
if (result.length === 0) {
await this.setState({
hasMorePosts: false,
loading: false,
initialLoading: false,
})
return false
}
await this.setState({
posts: replace ? result : [...this.state.posts, ...result],
})
}
await this.setState({
loading: false,
})
if (this.state.initialLoading) {
await this.setState({
initialLoading: false,
})
}
}
componentDidMount = async () => {
await this.loadData()
console.log(this.wsEvents)
Object.keys(this.wsEvents).forEach((event) => {
window.app.cores.api.namespaces["main"].listenEvent(event, this.wsEvents[event])
})
}
componentWillUnmount = async () => {
Object.keys(this.wsEvents).forEach((event) => {
window.app.cores.api.namespaces["main"].unlistenEvent(event, this.wsEvents[event])
})
}
render() {
return <div className="feed">
{
this.state.initialLoading ? <Skeleton active /> : <PostsList
loading={this.state.loading}
hasMorePosts={this.state.hasMorePosts}
emptyListRender={emptyListRender}
onLoadMore={this.loadData}
posts={this.state.posts}
{
...this.props
}
/>
}
</div>
}
}

View File

@ -0,0 +1,21 @@
.feed {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
.emptyFeed {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
margin-top: 20px;
}
}

View File

@ -0,0 +1,91 @@
import React from "react"
import { Skeleton } from "antd"
import { Icons } from "components/Icons"
import { PostsList } from "components"
import Post from "models/post"
import "./index.less"
const emptyListRender = () => {
return <div className="emptyFeed">
<h2>
You dont have any saved posts.
</h2>
</div>
}
export default class SavedPosts extends React.Component {
state = {
loading: true,
initialLoading: true,
hasMorePosts: true,
posts: [],
}
loadData = async ({
trim,
replace = false
} = {}) => {
await this.setState({
loading: true,
})
const result = await Post.getSavedPosts({
trim: trim ?? this.state.posts.length,
})
console.log("Loaded data => \n", result)
if (result) {
if (result.length === 0) {
await this.setState({
hasMorePosts: false,
loading: false,
initialLoading: false,
})
return false
}
await this.setState({
posts: replace ? result : [...this.state.posts, ...result],
})
}
await this.setState({
loading: false,
})
if (this.state.initialLoading) {
await this.setState({
initialLoading: false,
})
}
}
componentDidMount() {
this.loadData()
}
render() {
return <div className="savedPosts">
<div className="savedPosts_header">
<h1>
<Icons.Bookmark />
Saved Posts
</h1>
</div>
{
this.state.initialLoading ? <Skeleton active /> : <PostsList
loading={this.state.loading}
hasMorePosts={this.state.hasMorePosts}
emptyListRender={emptyListRender}
onLoadMore={this.loadData}
posts={this.state.posts}
/>
}
</div>
}
}

View File

@ -0,0 +1,7 @@
.savedPosts {
width: 100%;
.savedPosts_header {
font-size: 1.3rem;
}
}

View File

@ -0,0 +1,14 @@
import React from "react"
import { Result } from "antd"
import "./index.less"
export default (props) => {
return <div className="trendingsBrowser">
<Result
status="404"
title="Not implemented"
subTitle="Sorry, but this feature is not implemented yet."
/>
</div>
}

View File

@ -0,0 +1 @@
.trendingsBrowser {}

View File

@ -0,0 +1,27 @@
import FeedTab from "./components/feed"
import ExploreTab from "./components/explore"
import TrendingsTab from "./components/trendings"
import SavedPostsTab from "./components/savedPosts"
export default {
"feed": {
title: "Feed",
icon: "Rss",
component: FeedTab
},
"explore": {
title: "Explore",
icon: "Search",
component: ExploreTab
},
"trendings": {
title: "Trendings",
icon: "TrendingUp",
component: TrendingsTab
},
"savedPosts": {
title: "Saved posts",
icon: "Bookmark",
component: SavedPostsTab
}
}