added user posts in profile & collapse sidebar

This commit is contained in:
srgooglo 2020-10-30 13:49:06 +01:00
parent 7f43427cb8
commit 1b557a49af
6 changed files with 224 additions and 196 deletions

View File

@ -4,7 +4,7 @@ import * as Icons from 'components/Icons'
import styles from './index.less'
import classnames from 'classnames'
import { connect } from 'umi'
import { __legacy__objectToArray, queryObjectToString} from 'core'
import { __legacy__objectToArray, queryObjectToString } from 'core'
@connect(({ app }) => ({ app }))
export default class Sider_Default extends React.Component {
@ -14,20 +14,20 @@ export default class Sider_Default extends React.Component {
menus: null
}
toogleCollapse(){
toogleCollapse() {
window.toogleSidebarCollapse()
}
componentDidMount(){
componentDidMount() {
this.setState({ menus: this.props.menus, loading: false })
}
renderMenus(data, position){
if(!position) return null
renderMenus(data, position) {
if (!position) return null
return data.map(e => {
if (!e.attributes) e.attributes = {}
let componentPosition = e.attributes.position || "top"
let componentPosition = e.attributes.position || "top"
return componentPosition == position
? (
<antd.Menu.Item icon={e.icon} key={e.id}>
@ -46,33 +46,34 @@ export default class Sider_Default extends React.Component {
return (
<div className={styles.left_sider_wrapper}>
<antd.Layout.Sider
onDoubleClick={() => { window.toogleSidebarCollapse() }}
collapsed={this.props.app.sidebar_collapsed || false}
trigger={null}
className={styles.left_sider_container}
width="175px"
style={{ flex:'unset' }}
style={{ flex: 'unset' }}
>
<div onClick={() => {handleClickMenu({key: ''})}} className={classnames(styles.left_sider_header, {[styles.emb]: this.props.app.embedded})}>
<div onClick={() => { handleClickMenu({ key: '' }) }} className={classnames(styles.left_sider_header, { [styles.emb]: this.props.app.embedded })}>
<img className={styles.logotype} src={this.props.logo} />
</div>
</div>
<div className={styles.left_sider_menuContainer}>
<antd.Menu
selectable={false}
className={styles.left_sider_menuItems}
onClick={handleClickMenu}
>
{this.renderMenus(this.state.menus, "top")}
</antd.Menu>
<div className={styles.left_sider_footer}>
<antd.Menu
selectable={false}
className={styles.left_sider_menuItems}
onClick={handleClickMenu}
>
{this.renderMenus(this.state.menus, "top")}
{this.renderMenus(this.state.menus, "bottom")}
</antd.Menu>
<div className={styles.left_sider_footer}>
<antd.Menu
selectable={false}
className={styles.left_sider_menuItems}
onClick={handleClickMenu}
>
{this.renderMenus(this.state.menus, "bottom")}
</antd.Menu>
</div>
</div>
</div>
</antd.Layout.Sider>
</div>

View File

@ -0,0 +1,141 @@
import React from 'react'
import { List } from 'antd'
import { connect } from 'umi'
import settings from 'core/libs/settings'
import verbosity from 'core/libs/verbosity'
import { PostCard, PostCreator, Invalid } from 'components'
import * as antd from 'antd'
import styles from './index.less'
@connect(({ app, socket }) => ({ app, socket }))
export default class PostsFeed extends React.Component {
state = {
socket: null,
feed: null,
renderError: false
}
addPostToRender(payload) {
let postSchema = {
id: this.state.feed[0].id + 1,
post_time: "who knows",
postText: "empty",
publisher: "me",
post_likes: 2500
}
if (typeof(payload) !== "undefined") {
postSchema = { ...postSchema, ...payload }
}
let updated = this.state.feed
updated.push(postSchema)
this.setState({ feed: updated })
this.goPostById(postSchema.id)
}
goPostById(id) {
document.getElementById(id).scrollIntoView({
behavior: "smooth",
block: "center",
inline: "center"
})
}
getUserIdByProps(id) {
if(typeof(id) == "string") {
return new Number(id)
}
return id
}
fetchFeed() {
const { socket } = this.state
if (socket) {
const requestPayload = {
from: this.props.from ?? "feed",
userToken: this.props.app.session_token,
id: this.getUserIdByProps(this.props.fromID) ?? this.props.app.session_uuid
}
const requestCallback = (data) => {
if (Array.isArray(data.response)) {
this.setState({ feed: data.response })
} else {
verbosity([`error gathering posts >`, data])
this.setState({ renderError: true })
}
}
socket._emit("get", requestPayload, requestCallback)
}
}
handlePostActions(action, post_id, callback) {
const { socket } = this.state
if (socket) {
const requestPayload = {
userToken: this.props.app.session_token,
post_id,
action
}
socket._emit("actions", requestPayload, (res) => callback(res))
}
}
componentDidMount() {
window.addPostToRender = (...context) => this.addPostToRender(...context)
if (this.props.app.session_valid) {
this.props.dispatch({
type: "socket/use",
persistent: true,
scope: "posts",
then: (data) => {
this.setState({ socket: data })
this.fetchFeed()
}
})
}
}
componentWillUnmount() {
if (this.state.socket) {
this.state.socket.remove()
}
}
render() {
if (!this.props.app.session_valid) {
return <Invalid type="SESSION_INVALID" />
}
if (!this.state.feed) {
return (
<antd.Card bordered="false" >
<antd.Skeleton active />
</antd.Card>
)
}
if (this.state.renderError) {
return (
<Invalid type="SESSION_INVALID" />
)
}
return (
<div className={styles.exploreWrapper}>
<List
//loadMore={loadMore}
dataSource={this.state.feed}
renderItem={item => (
<PostCard handleActions={(...context) => this.handlePostActions(...context)} payload={item} />
)}
/>
</div>
)
}
}

View File

@ -0,0 +1,3 @@
.exploreWrapper{
}

View File

@ -13,6 +13,7 @@ import * as AppLayout from './Layout/index.js'
import ListedMenu from './ListedMenu/index.tsx'
import FloatComponent from './FloatComponent'
import ParamsList from './ParamsList'
import PostsFeed from './PostFeed'
// User Components
@ -23,6 +24,7 @@ import PostCard from './PostCard'
// Mix & Export all
export {
PostsFeed,
Splash,
ParamsList,
FloatComponent,

View File

@ -6,15 +6,15 @@ import styles from './index.less'
import FollowButton from './components/follow'
import Menu from './components/menu'
import { PostsFeed } from 'components'
import * as antd from 'antd'
import { connect } from 'umi'
const matchRegexp = pathMatchRegexp('/@/:id', location.pathname)
class UserLayout extends React.Component{
class UserLayout extends React.Component {
state = {
styleComponent: "UserLayout",
userString: matchRegexp[1],
userString: pathMatchRegexp('/@/:id', location.pathname)[1],
layoutData: {
avatar: null,
cover: null,
@ -24,55 +24,55 @@ class UserLayout extends React.Component{
}
}
componentDidMount(){
componentDidMount() {
const { layoutData } = this.props
if (layoutData) {
this.setState({ layoutData: {...this.state.layoutData, ...layoutData} })
this.setState({ layoutData: { ...this.state.layoutData, ...layoutData } })
}
}
render(){
render() {
const { styleComponent } = this.state
const toStyles = e => styles[`${styleComponent}_${e}`]
return(
return (
<div className={toStyles("wrapper")} >
<div className={toStyles("cover")}>
<img src={this.state.layoutData.cover} />
</div>
<div className={toStyles("header")}>
<div className={toStyles("cover")}>
<img src={this.state.layoutData.cover} />
</div>
<div className={toStyles("header")}>
<div className={toStyles("avatar")}>
<antd.Avatar shape="square" src={this.state.layoutData.avatar} />
</div>
<div className={toStyles("title")}>
<antd.Tooltip title={`${this.state.layoutData.followers ?? "Non-existent"} Followers`}>
<h1>{this.state.userString}</h1>
</antd.Tooltip>
<span
style={{
fontSize: '14px',
fontWeight: '100',
lineHeight: '0',
marginBottom: '5px',
}}
dangerouslySetInnerHTML={{
__html: this.state.layoutData.about,
}}
/>
</div>
<div className={toStyles("options")}>
<div><FollowButton followed={this.state.layoutData.follow} /></div>
</div>
<div className={toStyles("avatar")}>
<antd.Avatar shape="square" src={this.state.layoutData.avatar} />
</div>
<div className={toStyles("content")}>
<div className={toStyles("title")}>
<antd.Tooltip title={`${this.state.layoutData.followers ?? "Non-existent"} Followers`}>
<h1>{this.state.userString}</h1>
</antd.Tooltip>
<span
style={{
fontSize: '14px',
fontWeight: '100',
lineHeight: '0',
marginBottom: '5px',
}}
dangerouslySetInnerHTML={{
__html: this.state.layoutData.about,
}}
/>
</div>
<div className={toStyles("options")}>
<div><FollowButton followed={this.state.layoutData.follow} /></div>
</div>
</div>
<div className={toStyles("content")}>
</div>
</div>
)
}
@ -89,7 +89,9 @@ export default class UserIndexer extends React.Component {
promiseState = async state => new Promise(resolve => this.setState(state, resolve));
componentDidMount(){
componentDidMount() {
const matchRegexp = pathMatchRegexp('/@/:id', location.pathname)
if (matchRegexp && this.props.app.session_valid) {
this.props.dispatch({
type: "user/get",
@ -98,16 +100,16 @@ export default class UserIndexer extends React.Component {
username: matchRegexp[1]
},
callback: (callbackResponse) => {
if(callbackResponse.code == 200){
if (callbackResponse.code == 200) {
this.setState({ loading: false, layoutData: callbackResponse.response })
}else{
} else {
this.setState({ ErrorCode: callbackResponse.code })
return HandleError({ code: callbackResponse.code, msg: "no message provided" })
}
}
})
}else{
} else {
this.setState({ ErrorCode: 140 })
}
}
@ -118,7 +120,13 @@ export default class UserIndexer extends React.Component {
if (this.state.loading) {
return <div style={{ display: "flex", width: "100%", justifyContent: "center", alignContent: "center" }}><antd.Card style={{ width: "100%" }} ><antd.Skeleton active /></antd.Card></div>
}
return <UserLayout layoutData={this.state.layoutData} />
return (
<div>
<UserLayout layoutData={this.state.layoutData} />
<PostsFeed from="user" fromID={this.state.layoutData.user_id} />
</div>
)
}
}

View File

@ -1,135 +1,8 @@
import React from 'react'
import { List } from 'antd'
import endpoints from 'config/endpoints'
import { v3_model } from 'core/libs'
import { connect } from 'umi'
import settings from 'core/libs/settings'
import verbosity from 'core/libs/verbosity'
import { PostCard, PostCreator, Invalid } from 'components'
import * as antd from 'antd'
import styles from './index.less'
import { PostsFeed } from 'components'
@connect(({ app, socket }) => ({ app, socket }))
export default class Explore extends React.Component {
state = {
socket: null,
feed: null,
renderError: false
}
addPostToRender(payload) {
let postSchema = {
id: this.state.feed[0].id + 1,
post_time: "who knows",
postText: "empty",
publisher: "me",
post_likes: 2500
}
if (typeof(payload) !== "undefined") {
postSchema = { ...postSchema, ...payload }
}
let updated = this.state.feed
updated.push(postSchema)
this.setState({ feed: updated })
this.goPostById(postSchema.id)
}
goPostById(id) {
document.getElementById(id).scrollIntoView({
behavior: "smooth",
block: "center",
inline: "center"
})
}
fetchFeed() {
const { socket } = this.state
if (socket) {
const requestPayload = {
from: "feed",
userToken: this.props.app.session_token
}
const requestCallback = (data) => {
if (Array.isArray(data.response)) {
this.setState({ feed: data.response })
} else {
verbosity([`error gathering posts >`, data])
this.setState({ renderError: true })
}
}
socket._emit("get", requestPayload, requestCallback)
}
}
handlePostActions(action, post_id, callback) {
const { socket } = this.state
if (socket) {
const requestPayload = {
userToken: this.props.app.session_token,
post_id,
action
}
socket._emit("actions", requestPayload, (res) => callback(res))
}
}
componentDidMount() {
window.addPostToRender = (...context) => this.addPostToRender(...context)
if (this.props.app.session_valid) {
this.props.dispatch({
type: "socket/use",
persistent: true,
scope: "posts",
then: (data) => {
this.setState({ socket: data })
this.fetchFeed()
}
})
}
}
componentWillUnmount() {
if (this.state.socket) {
this.state.socket.remove()
}
}
render() {
if (!this.props.app.session_valid) {
return <Invalid type="SESSION_INVALID" />
}
if (!this.state.feed) {
return (
<antd.Card bordered="false" >
<antd.Skeleton active />
</antd.Card>
)
}
if (this.state.renderError) {
return (
<Invalid type="SESSION_INVALID" />
)
}
return (
<div className={styles.exploreWrapper}>
<List
//loadMore={loadMore}
dataSource={this.state.feed}
renderItem={item => (
<PostCard handleActions={(...context) => this.handlePostActions(...context)} payload={item} />
)}
/>
</div>
)
return <PostsFeed />
}
}