use PostsFeed component

This commit is contained in:
srgooglo 2022-03-11 22:52:44 +01:00
parent 4da1a0b506
commit 81167c455e
4 changed files with 52 additions and 222 deletions

View File

@ -3,67 +3,15 @@ import * as antd from "antd"
import { Translation } from "react-i18next"
import { Icons } from "components/Icons"
import { Skeleton, ActionsBar, AdminTools } from "components"
import { Skeleton, PostsFeed } from "components"
import { Session, User } from "models"
import { SessionsView, StatisticsView } from "./components"
import "./index.less"
const SelfViewComponents = {
sessionsView: SessionsView,
statisticsView: StatisticsView,
}
const SelfViewTabDecorators = {
sessionsView: (
<div>
<Icons.Key /> Sessions
</div>
),
statisticsView: (
<div>
<Icons.PieChart /> Statistics
</div>
),
}
class SelfView extends React.Component {
renderComponents = () => {
const renderTagDecorator = (key) => {
if (typeof this.props.decorators[key] !== "undefined") {
return this.props.decorators[key]
}
return key
}
return Object.keys(this.props.components).map((key, index) => {
const Component = this.props.components[key]
return (
<antd.Tabs.TabPane tab={renderTagDecorator(key)} key={index}>
<div key={key}>
<Component {...this.props.componentProps} />
</div>
</antd.Tabs.TabPane>
)
})
}
render() {
return (
<antd.Tabs defaultActiveKey="0" centered>
{this.renderComponents()}
</antd.Tabs>
)
}
}
export default class Account extends React.Component {
static bindApp = ["userController", "sessionController"]
state = {
hasManager: false,
isSelf: false,
user: null,
sessions: null
@ -88,28 +36,11 @@ export default class Account extends React.Component {
state.user = await this.props.contexts.app.userController.getData({ username: requestedUser })
}
state.hasManager = await User.hasRole("manager")
state.hasAdmin = await User.hasRole("admin")
this.setState(state)
}
handleSignOutAll = () => {
return this.props.contexts.app.sessionController.destroyAllSessions()
}
openUserEdit = async () => {
const result = await AdminTools.open.dataManager(this.state.user)
if (result) {
this.setState({ user: result })
}
}
openRolesManager = async () => {
await AdminTools.open.rolesManager(this.state.user._id)
}
render() {
const user = this.state.user
@ -136,47 +67,19 @@ export default class Account extends React.Component {
</div>
</div>
<div className="extension">
<div className="rolesList">
{user.roles.map((role, index) => {
<div className="badgesList">
{user.badges.map((role, index) => {
return <antd.Tag>{role}</antd.Tag>
})}
</div>
</div>
</div>
{(this.state.isSelf || this.state.hasManager) && <ActionsBar spaced padding="8px">
<antd.Button
icon={<Icons.Edit />}
shape="round"
onClick={this.openUserEdit}
>
<Translation>
{(t) => <>{t("Edit")}</>}
</Translation>
</antd.Button>
{this.state.hasAdmin && <antd.Button
icon={<Icons.Link />}
shape="round"
onClick={this.openRolesManager}
>
<Translation>
{(t) => <>{t("Manage roles")}</>}
</Translation>
</antd.Button>}
</ActionsBar>}
{this.state.isSelf && (
<SelfView
components={SelfViewComponents}
decorators={SelfViewTabDecorators}
componentProps={{
sessions: this.state.sessions,
user: this.state.user,
handleSignOutAll: this.handleSignOutAll,
}}
/>
)}
<div className="posts">
<PostsFeed
fromUserId={user._id}
/>
</div>
</div>
)
}

View File

@ -1,67 +1,76 @@
@borderColor: #33333396;
@borderColor : #dddddd;
@borderRadius: 12px;
.account_wrapper {
.card {
display: flex;
display : flex;
flex-direction: column;
color: var(--background-color-contrast);
color : var(--background-color-contrast);
h1,h2,h3,h4,h5,h6,span {
h1,
h2,
h3,
h4,
h5,
h6,
span {
color: var(--background-color-contrast);
}
.header {
position: relative;
display: inline-flex;
position : relative;
display : inline-flex;
align-items: center;
z-index: 15;
width: 100%;
width : 100%;
padding: 12px;
font-family: "Roboto Mono", monospace;
//color: #333;
color: var(--background-color-contrast);
border: 1px solid @borderColor;
color : var(--background-color-contrast);
border : 1px solid var(--border-color);
border-radius: @borderRadius;
word-break: break-all;
img {
width: 70px;
width : 70px;
height: 70px;
}
h1 {
margin: 0;
margin : 0;
font-size: 35px;
span {
font-size: 12px;
}
}
}
}
.extension {
position: relative;
display: inline-flex;
top: -10px;
width: 100%;
display : inline-flex;
top : -10px;
width : 100%;
padding: 19px 10px 10px 10px;
border-top: 0;
border-top : 0;
border-right: 0;
border-style: solid;
border-width: 1px;
border-color: transparent @borderColor @borderColor @borderColor;
border-color : var(--border-color);
border-top-color: transparent;
border-radius: 0 0 @borderRadius @borderRadius;
}
}
> div {
>div {
margin-bottom: 10px;
}
}

View File

@ -1,88 +1,15 @@
import React from "react"
import * as antd from "antd"
import { PostCard, PostCreator } from "components"
import { InfiniteScroll } from "antd-mobile"
import { PostCreator, PostsFeed } from "components"
import "./index.less"
export default class PostsExplorer extends React.Component {
state = {
loading: true,
skipStep: 0,
lastLength: 0,
posts: [],
}
api = window.app.request
componentDidMount = async () => {
this.toogleLoading(true)
await this.fetchPosts()
window.app.ws.listen(`new.post`, (data) => {
this.addPost(data)
})
this.toogleLoading(false)
}
toogleLoading = (to) => {
this.setState({ loading: to ?? !this.state.loading })
}
addPost = (post) => {
this.setState({
posts: [post, ...this.state.posts],
})
}
fetchPosts = async () => {
const posts = await this.api.get.feed(undefined, {
feedSkip: this.state.skipStep,
}).catch(error => {
console.error(error)
antd.message.error(error)
return false
})
if (posts) {
console.log(posts)
this.setState({ posts: [...posts, ...this.state.posts,], lastLength: posts.length })
}
}
hasMore = () => {
return this.state.posts.length < this.state.lastLength
}
loadMore = async () => {
await this.setState({ skipStep: this.state.skipStep + 1 })
await this.fetchPosts()
}
render() {
if (this.state.loading) {
return <antd.Skeleton active />
}
return <div className="explore">
<div className="wrapper">
<div className="header">
<PostCreator />
</div>
{
this.state.posts.map(post => {
return <PostCard data={post} />
})
}
<InfiniteScroll loadMore={this.loadMore} hasMore={this.hasMore} >
<div>Loading more...</div>
</InfiniteScroll>
<div className="header">
<PostCreator />
</div>
<PostsFeed />
</div>
}
}

View File

@ -6,7 +6,7 @@
width: 100%;
.wrapper {
.header {
display : flex;
flex-direction : column;
align-items : center;
@ -14,18 +14,9 @@
width : 100%;
max-width: 40vw;
}
.header {
display : flex;
flex-direction : column;
align-items : center;
justify-content: center;
width: 100%;
}
>div {
margin-bottom: 15px;
}
>div {
margin-bottom: 15px;
}
}