Merge pull request #165 from hyperspacedev/HD-36-profile-search-masonry

[HD-36] Enable masonry layout for Search and Profile pages
This commit is contained in:
Marquis Kurt 2020-01-23 13:19:02 -05:00 committed by GitHub
commit f2fe5cbb31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 34 deletions

View File

@ -335,5 +335,9 @@ export const styles = (theme: Theme) =>
"my-masonry-grid_column": {
// non-standard name fixes react-masonry-css bug :shrug:
padding: 5
},
noTopPaddingMargin: {
marginTop: 0,
paddingTop: 0
}
});

View File

@ -25,6 +25,8 @@ import Post from "../components/Post";
import { withSnackbar } from "notistack";
import { LinkableIconButton } from "../interfaces/overrides";
import { emojifyString } from "../utilities/emojis";
import Masonry from "react-masonry-css";
import { getUserDefaultBool } from "..//utilities/settings";
import AccountEditIcon from "mdi-material-ui/AccountEdit";
import PersonAddIcon from "@material-ui/icons/PersonAdd";
@ -44,6 +46,7 @@ interface IProfilePageState {
viewDidError?: boolean;
viewDidErrorCode?: string;
blockDialogOpen: boolean;
isMasonryLayout?: boolean;
}
class ProfilePage extends Component<any, IProfilePageState> {
@ -59,7 +62,8 @@ class ProfilePage extends Component<any, IProfilePageState> {
this.state = {
viewIsLoading: true,
blockDialogOpen: false
blockDialogOpen: false,
isMasonryLayout: getUserDefaultBool("isMasonryLayout")
};
}
@ -305,8 +309,36 @@ class ProfilePage extends Component<any, IProfilePageState> {
}
}
renderPosts(posts: Status[]) {
const { classes } = this.props;
const postComponents = posts.map((post: Status) => {
return <Post key={post.id} post={post} client={this.client} />;
});
if (this.state.isMasonryLayout) {
return (
<Masonry
className={classes.masonryGrid}
columnClassName={classes["my-masonry-grid_column"]}
breakpointCols={{
default: 4,
2000: 3,
1400: 2,
1050: 1
}}
>
{postComponents}
</Masonry>
);
} else {
return <div>{postComponents}</div>;
}
}
render() {
const { classes } = this.props;
const containerClasses = `${classes.pageContentLayoutConstraints} ${
this.state.isMasonryLayout ? classes.pageLayoutMasonry : ""
}`;
return (
<div className={classes.pageLayoutMinimalConstraints}>
<div className={classes.pageHeroBackground}>
@ -464,7 +496,7 @@ class ProfilePage extends Component<any, IProfilePageState> {
</div>
</div>
</div>
<div className={classes.pageContentLayoutConstraints}>
<div className={containerClasses}>
{this.state.viewDidError ? (
<Paper className={classes.errorCard}>
<Typography variant="h4">Bummer.</Typography>
@ -482,15 +514,7 @@ class ProfilePage extends Component<any, IProfilePageState> {
)}
{this.state.posts ? (
<div>
{this.state.posts.map((post: Status) => {
return (
<Post
key={post.id}
post={post}
client={this.client}
/>
);
})}
{this.renderPosts(this.state.posts)}
<br />
{this.state.viewDidLoad &&
!this.state.viewDidError ? (

View File

@ -26,6 +26,8 @@ import { withSnackbar } from "notistack";
import Post from "../components/Post";
import { Status } from "../types/Status";
import { Account } from "../types/Account";
import Masonry from "react-masonry-css";
import { getUserDefaultBool } from "../utilities/settings";
interface ISearchPageState {
query: string[] | string;
@ -36,6 +38,7 @@ interface ISearchPageState {
viewDidLoad?: boolean;
viewDidError?: boolean;
viewDidErrorCode?: string;
isMasonryLayout: boolean;
}
class SearchPage extends Component<any, ISearchPageState> {
@ -54,7 +57,8 @@ class SearchPage extends Component<any, ISearchPageState> {
this.state = {
viewIsLoading: true,
query: searchParams.query,
type: searchParams.type
type: searchParams.type,
isMasonryLayout: getUserDefaultBool("isMasonryLayout")
};
if (searchParams.type === "tag") {
@ -195,7 +199,7 @@ class SearchPage extends Component<any, ISearchPageState> {
showAllAccountsFromQuery() {
const { classes } = this.props;
return (
<div>
<div className={classes.pageLayoutConstraints}>
<ListSubheader>Accounts</ListSubheader>
{this.state.results &&
@ -260,22 +264,44 @@ class SearchPage extends Component<any, ISearchPageState> {
);
}
renderPosts(posts: Status[]) {
const { classes } = this.props;
const postComponents = posts.map((post: Status) => {
return <Post key={post.id} post={post} client={this.client} />;
});
if (this.state.isMasonryLayout) {
return (
<Masonry
className={classes.masonryGrid}
columnClassName={classes["my-masonry-grid_column"]}
breakpointCols={{
default: 4,
2000: 3,
1400: 2,
1050: 1
}}
>
{postComponents}
</Masonry>
);
} else {
return <div>{postComponents}</div>;
}
}
showAllPostsFromQuery() {
const { classes } = this.props;
const containerClasses = `${classes.pageLayoutConstraints} ${
this.state.isMasonryLayout
? classes.pageLayoutMasonry + " " + classes.noTopPaddingMargin
: ""
}`;
return (
<div>
<div className={containerClasses}>
<ListSubheader>Posts</ListSubheader>
{this.state.results ? (
this.state.results.statuses.length > 0 ? (
this.state.results.statuses.map((post: Status) => {
return (
<Post
key={post.id}
post={post}
client={this.client}
/>
);
})
this.renderPosts(this.state.results.statuses)
) : (
<Typography
variant="caption"
@ -291,20 +317,15 @@ class SearchPage extends Component<any, ISearchPageState> {
showAllPostsWithTag() {
const { classes } = this.props;
const containerClasses = `${classes.pageLayoutMaxConstraints} ${
this.state.isMasonryLayout ? classes.pageLayoutMasonry : ""
}`;
return (
<div>
<div className={containerClasses}>
<ListSubheader>Tagged posts</ListSubheader>
{this.state.tagResults ? (
this.state.tagResults.length > 0 ? (
this.state.tagResults.map((post: Status) => {
return (
<Post
key={post.id}
post={post}
client={this.client}
/>
);
})
this.renderPosts(this.state.tagResults)
) : (
<Typography
variant="caption"
@ -321,7 +342,7 @@ class SearchPage extends Component<any, ISearchPageState> {
render() {
const { classes } = this.props;
return (
<div className={classes.pageLayoutConstraints}>
<div>
{this.state.type && this.state.type === "tag" ? (
this.showAllPostsWithTag()
) : (