mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-22 12:21:13 +00:00
Adds a loading skeleton to posts, comments and trending communities (#2311)
* creates the initial loading skeleton for the home page * initial setup for the trending communities loading skeleton * adds posts loading skeleton to the community page * finishes the creation of all loading skeletons for large devices * finishes loading skeleton for smaller screens * removes unecessary code for the loading skeleton * [loading skeleton] removes unecessary mock code * [loading skeleton] removes custom css classes and adds more bootstrap css classes on the skeleton loading * replaces custom styles with bootstrap classes * rendes only one component for desktop and mobile screens Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com> * fixes lint's indentation problems * transforms span tags into self-closing tags * removes every inline style from the loading-skeleton.tsx file --------- Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
This commit is contained in:
parent
4dbf8fd2f1
commit
72553e429b
5 changed files with 139 additions and 47 deletions
|
@ -1 +1 @@
|
|||
Subproject commit b4c63029e598c022a04fc21acb45855645bd6794
|
||||
Subproject commit 62c8418021bc39543c87b4ae3dcf2419d13f61e0
|
118
src/shared/components/common/loading-skeleton.tsx
Normal file
118
src/shared/components/common/loading-skeleton.tsx
Normal file
|
@ -0,0 +1,118 @@
|
|||
import { Component } from "inferno";
|
||||
|
||||
interface LoadingSkeletonProps {
|
||||
itemCount?: number;
|
||||
}
|
||||
|
||||
interface LoadingSkeletonLineProps {
|
||||
size: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
||||
}
|
||||
|
||||
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} h-100`} />
|
||||
</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 ps-2 pe-4">
|
||||
<div className="row">
|
||||
<div className="col flex-grow-0 pe-0">
|
||||
<div className="d-flex placeholder-glow img-icon">
|
||||
<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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
import { IRoutePropsWithFetch } from "../../routes";
|
||||
|
||||
|
@ -435,11 +439,7 @@ export class Community extends Component<CommunityRouteProps, State> {
|
|||
if (dataType === DataType.Post) {
|
||||
switch (this.state.postsRes.state) {
|
||||
case "loading":
|
||||
return (
|
||||
<h5>
|
||||
<Spinner large />
|
||||
</h5>
|
||||
);
|
||||
return <PostsLoadingSkeleton />;
|
||||
case "success":
|
||||
return (
|
||||
<PostListings
|
||||
|
@ -472,11 +472,7 @@ export class Community extends Component<CommunityRouteProps, State> {
|
|||
} else {
|
||||
switch (this.state.commentsRes.state) {
|
||||
case "loading":
|
||||
return (
|
||||
<h5>
|
||||
<Spinner large />
|
||||
</h5>
|
||||
);
|
||||
return <CommentsLoadingSkeleton />;
|
||||
case "success":
|
||||
return (
|
||||
<CommentNodes
|
||||
|
|
|
@ -92,7 +92,7 @@ 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";
|
||||
|
@ -100,6 +100,11 @@ 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";
|
||||
import { RouteComponentProps } from "inferno-router/dist/Route";
|
||||
import { IRoutePropsWithFetch } from "../../routes";
|
||||
|
||||
|
@ -531,11 +536,7 @@ export class Home extends Component<HomeRouteProps, 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 (
|
||||
|
@ -704,11 +705,7 @@ export class Home extends Component<HomeRouteProps, 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 (
|
||||
|
@ -744,11 +741,7 @@ export class Home extends Component<HomeRouteProps, 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 (
|
||||
|
|
|
@ -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";
|
||||
import { RouteComponentProps } from "inferno-router/dist/Route";
|
||||
import { IRoutePropsWithFetch } from "../../routes";
|
||||
|
||||
|
@ -583,11 +584,7 @@ export class Inbox extends Component<InboxRouteProps, 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>
|
||||
|
@ -598,11 +595,7 @@ export class Inbox extends Component<InboxRouteProps, 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 (
|
||||
|
@ -645,11 +638,7 @@ export class Inbox extends Component<InboxRouteProps, 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 (
|
||||
|
@ -695,11 +684,7 @@ export class Inbox extends Component<InboxRouteProps, 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 (
|
||||
|
|
Loading…
Reference in a new issue