import React from "react" import * as antd from "antd" import { Icons } from "components/Icons" import { PostCard, LoadMore } from "components" //import { ViewportList } from "react-viewport-list" import AutoSizer from "react-virtualized-auto-sizer" import PostModel from "models/post" import "./index.less" const LoadingComponent = () => { return } const NoResultComponent = () => { return } export class PostsListsComponent extends React.Component { state = { openPost: null, loading: false, resumingLoading: false, initialLoading: true, realtimeUpdates: true, hasMore: true, list: this.props.list ?? [], } parentRef = this.props.innerRef listRef = React.createRef() timelineWsEvents = { "feed.new": (data) => { console.log("New feed => ", data) if (!this.state.realtimeUpdates) { return } this.setState({ list: [data, ...this.state.list], }) }, "post.new": (data) => { console.log("New post => ", data) if (!this.state.realtimeUpdates) { return } this.setState({ list: [data, ...this.state.list], }) }, "post.delete": (id) => { console.log("Deleted post => ", id) this.setState({ list: this.state.list.filter((post) => { return post._id !== id }), }) } } handleLoad = async (fn, params = {}) => { this.setState({ loading: true, }) let payload = { trim: this.state.list.length, } if (this.props.loadFromModelProps) { payload = { ...payload, ...this.props.loadFromModelProps, } } if (params.replace) { payload.trim = 0 } const result = await fn(payload).catch((err) => { console.error(err) app.message.error("Failed to load more posts") return null }) console.log("Loaded posts => ", result) if (result) { if (result.length === 0) { return this.setState({ hasMore: false, }) } if (params.replace) { this.setState({ list: result, }) } else { this.setState({ list: [...this.state.list, ...result], }) } } this.setState({ loading: false, }) } addPost = (post) => { this.setState({ list: [post, ...this.state.list], }) } removePost = (id) => { this.setState({ list: this.state.list.filter((post) => { return post._id !== id }), }) } _hacks = { addPost: this.addPost, removePost: this.removePost, addRandomPost: () => { this.addPost({ _id: Math.random().toString(36).substring(7), message: `Random post ${Math.random().toString(36).substring(7)}`, user: { _id: Math.random().toString(36).substring(7), username: "random user", } }) } } onResumeRealtimeUpdates = async () => { console.log("Resuming realtime updates") this.setState({ resumingLoading: true, }) // scroll to top this.listRef.current.scrollTo({ top: 0, behavior: "smooth", }) await this.handleLoad(this.props.loadFromModel, { replace: true, }) // fetch new posts this.setState({ realtimeUpdates: true, resumingLoading: false, }) } onScrollList = (e) => { const { scrollTop } = e.target if (this.state.resumingLoading) { return null } console.log("Scrolling => ", scrollTop) if (scrollTop > 200) { this.setState({ realtimeUpdates: false, }) } else { if (!this.state.realtimeUpdates && !this.state.resumingLoading) { this.onResumeRealtimeUpdates() } } } componentDidMount = async () => { if (typeof this.props.loadFromModel === "function") { await this.handleLoad(this.props.loadFromModel) } this.setState({ initialLoading: false, }) if (this.props.watchTimeline) { if (!Array.isArray(this.props.watchTimeline)) { console.error("watchTimeline prop must be an array") } else { this.props.watchTimeline.forEach((event) => { if (typeof this.timelineWsEvents[event] !== "function") { console.error(`The event "${event}" is not defined in the timelineWsEvents object`) } app.cores.api.listenEvent(event, this.timelineWsEvents[event]) }) } } if (this.props.realtime) { if (this.listRef && this.listRef.current) { this.listRef.current.addEventListener("scroll", this.onScrollList) } } window._hacks = this._hacks } componentWillUnmount = async () => { if (this.props.watchTimeline) { if (!Array.isArray(this.props.watchTimeline)) { console.error("watchTimeline prop must be an array") } else { this.props.watchTimeline.forEach((event) => { if (typeof this.timelineWsEvents[event] !== "function") { console.error(`The event "${event}" is not defined in the timelineWsEvents object`) } app.cores.api.unlistenEvent(event, this.timelineWsEvents[event]) }) } } if (this.props.realtime) { if (this.listRef && this.listRef.current) { this.listRef.current.removeEventListener("scroll", this.onScrollList) } } window._hacks = null } componentDidUpdate = async (prevProps) => { if (prevProps.list !== this.props.list) { this.setState({ list: this.props.list, }) } } onLikePost = async (data) => { let result = await PostModel.toogleLike({ post_id: data._id }).catch(() => { antd.message.error("Failed to like post") return false }) return result } onSavePost = async (data) => { let result = await PostModel.toogleSave({ post_id: data._id }).catch(() => { antd.message.error("Failed to save post") return false }) return result } onDeletePost = async (data) => { antd.Modal.confirm({ title: "Are you sure you want to delete this post?", content: "This action is irreversible", okText: "Yes", okType: "danger", cancelText: "No", onOk: async () => { await PostModel.deletePost({ post_id: data._id }).catch(() => { antd.message.error("Failed to delete post") }) }, }) } onToogleOpen = (to, data) => { if (typeof this.props.onOpenPost === "function") { this.props.onOpenPost(to, data) } } onLoadMore = async () => { if (typeof this.props.onLoadMore === "function") { return this.handleLoad(this.props.onLoadMore) } else if (this.props.loadFromModel) { return this.handleLoad(this.props.loadFromModel) } } render() { if (this.state.initialLoading) { return } if (this.state.list.length === 0) { if (typeof this.props.emptyListRender === "function") { return React.createElement(this.props.emptyListRender) } return

Whoa, nothing on here...

} return {({ height, width }) => { console.log("AutoSizer => ", height, width) return { !this.state.realtimeUpdates &&
} > Resume
} { this.state.list.map((post) => { return }) }
}}
} } export default React.forwardRef((props, ref) => )