Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a loading skeleton to posts, comments and trending communities #2311

Merged
merged 17 commits into from Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
127 changes: 127 additions & 0 deletions src/shared/components/common/loading-skeleton.tsx
@@ -0,0 +1,127 @@
import { Component } from "inferno";

interface LoadingSkeletonProps {
itemCount?: number;
}

interface LoadingSkeletonLineProps {
size: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
dessalines marked this conversation as resolved.
Show resolved Hide resolved
}

class LoadingSkeletonLine extends Component<LoadingSkeletonLineProps, any> {
render() {
const className = "placeholder placeholder-lg col-" + this.props.size;
return (
<p className="placeholder-glow m-0">
<span className={className} style={{ height: "1.3em" }} />
rodrigo-fm marked this conversation as resolved.
Show resolved Hide resolved
</p>
);
}
}

export class PostsLoadingSkeleton extends Component<LoadingSkeletonProps, any> {
render() {
return Array.from({ length: this.props.itemCount ?? 10 }, (_, index) => (
<PostsLoadingSkeletonItem key={index} />
));
}
}

class PostThumbnailLoadingSkeleton extends Component<any, any> {
render() {
return (
<div className="thumbnail rounded d-flex justify-content-center placeholder-glow">
<span className="placeholder placeholder-lg h-100 w-100 rounded" />
</div>
);
}
}

class PostsLoadingSkeletonItem extends Component<any, any> {
render() {
return (
<div className="my-3">
<div className="col flex-grow-1">
<div className="row">
<div className="col flex-grow-0 order-last order-sm-first">
<PostThumbnailLoadingSkeleton />
</div>
<div className="col flex-grow-1">
<LoadingSkeletonLine size={12} />
<LoadingSkeletonLine size={8} />
<LoadingSkeletonLine size={4} />
</div>
</div>
</div>
</div>
);
}
}

export class TrendingCommunitiesLoadingSkeleton extends Component<
LoadingSkeletonProps,
any
> {
render() {
return (
<div className="mb-2">
{Array.from({ length: this.props.itemCount ?? 10 }, (_, index) => (
<TrendingCommunitiesLoadingSkeletonItem key={index} />
))}
</div>
);
}
}

class TrendingCommunitiesLoadingSkeletonItem extends Component<any, any> {
render() {
return (
<div
className="col flex-grow-1 mt-2"
style={{
rodrigo-fm marked this conversation as resolved.
Show resolved Hide resolved
"padding-left": "calc(var(--bs-gutter-x) *0.5)",
"padding-right": "calc(var(--bs-gutter-x) * 1)",
}}
>
<div className="row">
<div className="col flex-grow-0 pe-0">
<div
className="d-flex placeholder-glow"
style={{ width: "1.5rem", height: "1.5rem" }}
rodrigo-fm marked this conversation as resolved.
Show resolved Hide resolved
rodrigo-fm marked this conversation as resolved.
Show resolved Hide resolved
>
<span className="placeholder placeholder-lg w-100 h-100 rounded-circle" />
</div>
</div>
<div className="col flex-grow-1 pe-0">
<LoadingSkeletonLine size={12} />
</div>
</div>
</div>
);
}
}

export class CommentsLoadingSkeleton extends Component<any, any> {
render() {
return Array.from({ length: this.props.itemCount ?? 10 }, (_, index) => (
<CommentsLoadingSkeletonItem key={index} />
));
}
}

class CommentsLoadingSkeletonItem extends Component<any, any> {
render() {
return (
<div className="col flex-grow-1 my-2 p-2">
<div className="row">
<div className="col flex-grow-1">
<LoadingSkeletonLine size={6} />
<LoadingSkeletonLine size={12} />
<LoadingSkeletonLine size={7} />
<LoadingSkeletonLine size={4} />
</div>
</div>
</div>
);
}
}
16 changes: 6 additions & 10 deletions src/shared/components/community/community.tsx
Expand Up @@ -100,6 +100,10 @@ import { PostListings } from "../post/post-listings";
import { CommunityLink } from "./community-link";
import { PaginatorCursor } from "../common/paginator-cursor";
import { getHttpBaseInternal } from "../../utils/env";
import {
CommentsLoadingSkeleton,
PostsLoadingSkeleton,
} from "../common/loading-skeleton";
import { Sidebar } from "./sidebar";

type CommunityData = RouteDataResponse<{
Expand Down Expand Up @@ -417,11 +421,7 @@ export class Community extends Component<
if (dataType === DataType.Post) {
switch (this.state.postsRes.state) {
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
return <PostsLoadingSkeleton />;
case "success":
return (
<PostListings
Expand Down Expand Up @@ -454,11 +454,7 @@ export class Community extends Component<
} else {
switch (this.state.commentsRes.state) {
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
return <CommentsLoadingSkeleton />;
case "success":
return (
<CommentNodes
Expand Down
25 changes: 9 additions & 16 deletions src/shared/components/home/home.tsx
Expand Up @@ -92,14 +92,19 @@ import { toast } from "../../toast";
import { CommentNodes } from "../comment/comment-nodes";
import { DataTypeSelect } from "../common/data-type-select";
import { HtmlTags } from "../common/html-tags";
import { Icon, Spinner } from "../common/icon";
import { Icon } from "../common/icon";
import { ListingTypeSelect } from "../common/listing-type-select";
import { SortSelect } from "../common/sort-select";
import { CommunityLink } from "../community/community-link";
import { PostListings } from "../post/post-listings";
import { SiteSidebar } from "./site-sidebar";
import { PaginatorCursor } from "../common/paginator-cursor";
import { getHttpBaseInternal } from "../../utils/env";
import {
CommentsLoadingSkeleton,
PostsLoadingSkeleton,
TrendingCommunitiesLoadingSkeleton,
} from "../common/loading-skeleton";

interface HomeState {
postsRes: RequestState<GetPostsResponse>;
Expand Down Expand Up @@ -514,11 +519,7 @@ export class Home extends Component<any, HomeState> {
trendingCommunities() {
switch (this.state.trendingCommunitiesRes?.state) {
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
return <TrendingCommunitiesLoadingSkeleton itemCount={5} />;
case "success": {
const trending = this.state.trendingCommunitiesRes.data.communities;
return (
Expand Down Expand Up @@ -687,11 +688,7 @@ export class Home extends Component<any, HomeState> {
case "empty":
return <div style="min-height: 20000px;"></div>;
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
return <PostsLoadingSkeleton />;
case "success": {
const posts = this.state.postsRes.data.posts;
return (
Expand Down Expand Up @@ -727,11 +724,7 @@ export class Home extends Component<any, HomeState> {
} else {
switch (this.state.commentsRes.state) {
case "loading":
return (
<h5>
<Spinner large />
</h5>
);
return <CommentsLoadingSkeleton />;
case "success": {
const comments = this.state.commentsRes.data.comments;
return (
Expand Down
25 changes: 5 additions & 20 deletions src/shared/components/person/inbox.tsx
Expand Up @@ -80,6 +80,7 @@ import { Icon, Spinner } from "../common/icon";
import { Paginator } from "../common/paginator";
import { PrivateMessage } from "../private_message/private-message";
import { getHttpBaseInternal } from "../../utils/env";
import { CommentsLoadingSkeleton } from "../common/loading-skeleton";

enum UnreadOrAll {
Unread,
Expand Down Expand Up @@ -573,11 +574,7 @@ export class Inbox extends Component<any, InboxState> {
this.state.mentionsRes.state === "loading" ||
this.state.messagesRes.state === "loading"
) {
return (
<h1 className="h4">
<Spinner large />
</h1>
);
return <CommentsLoadingSkeleton />;
} else {
return (
<div>{this.buildCombined().map(r => this.renderReplyType(r))}</div>
Expand All @@ -588,11 +585,7 @@ export class Inbox extends Component<any, InboxState> {
replies() {
switch (this.state.repliesRes.state) {
case "loading":
return (
<h1 className="h4">
<Spinner large />
</h1>
);
return <CommentsLoadingSkeleton />;
case "success": {
const replies = this.state.repliesRes.data.replies;
return (
Expand Down Expand Up @@ -635,11 +628,7 @@ export class Inbox extends Component<any, InboxState> {
mentions() {
switch (this.state.mentionsRes.state) {
case "loading":
return (
<h1 className="h4">
<Spinner large />
</h1>
);
return <CommentsLoadingSkeleton />;
case "success": {
const mentions = this.state.mentionsRes.data.mentions;
return (
Expand Down Expand Up @@ -685,11 +674,7 @@ export class Inbox extends Component<any, InboxState> {
messages() {
switch (this.state.messagesRes.state) {
case "loading":
return (
<h1 className="h4">
<Spinner large />
</h1>
);
return <CommentsLoadingSkeleton />;
case "success": {
const messages = this.state.messagesRes.data.private_messages;
return (
Expand Down