From 2274f51e8d5148e7591bd6190942c5b98044c4b5 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 28 Apr 2022 16:42:15 -0400 Subject: [PATCH] Adding site sidebar for remote communities. Fixes #626 (#640) --- package.json | 2 +- src/shared/components/community/community.tsx | 25 +- src/shared/components/home/home.tsx | 259 ++--------------- src/shared/components/home/site-form.tsx | 2 + src/shared/components/home/site-sidebar.tsx | 267 ++++++++++++++++++ yarn.lock | 8 +- 6 files changed, 310 insertions(+), 253 deletions(-) create mode 100644 src/shared/components/home/site-sidebar.tsx diff --git a/package.json b/package.json index f43e5f6..729b6b1 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "eslint-plugin-prettier": "^4.0.0", "husky": "^7.0.4", "import-sort-style-module": "^6.0.0", - "lemmy-js-client": "0.16.0-rc.1", + "lemmy-js-client": "0.16.4-rc.1", "lint-staged": "^12.4.1", "mini-css-extract-plugin": "^2.6.0", "node-fetch": "^2.6.1", diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx index ab92308..dc26d94 100644 --- a/src/shared/components/community/community.tsx +++ b/src/shared/components/community/community.tsx @@ -60,6 +60,7 @@ import { Icon, Spinner } from "../common/icon"; import { Paginator } from "../common/paginator"; import { SortSelect } from "../common/sort-select"; import { Sidebar } from "../community/sidebar"; +import { SiteSidebar } from "../home/site-sidebar"; import { PostListings } from "../post/post-listings"; import { CommunityLink } from "./community-link"; @@ -268,13 +269,20 @@ export class Community extends Component { /> {this.state.showSidebarMobile && ( - + <> + + {!cv.community.local && this.state.communityRes.site && ( + + )} + )} {this.selects()} @@ -292,6 +300,9 @@ export class Community extends Component { online={this.state.communityRes.online} enableNsfw={this.state.siteRes.site_view.site.enable_nsfw} /> + {!cv.community.local && this.state.communityRes.site && ( + + )} diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index 3f6282a..0010cd9 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -40,9 +40,7 @@ import { getListingTypeFromProps, getPageFromProps, getSortTypeFromProps, - mdToHtml, notifyPost, - numToSI, relTags, restoreScrollPosition, saveCommentRes, @@ -59,7 +57,6 @@ import { wsUserOp, } from "../../utils"; import { CommentNodes } from "../comment/comment-nodes"; -import { BannerIconHeader } from "../common/banner-icon-header"; import { DataTypeSelect } from "../common/data-type-select"; import { HtmlTags } from "../common/html-tags"; import { Icon, Spinner } from "../common/icon"; @@ -67,18 +64,15 @@ import { ListingTypeSelect } from "../common/listing-type-select"; import { Paginator } from "../common/paginator"; import { SortSelect } from "../common/sort-select"; import { CommunityLink } from "../community/community-link"; -import { PersonListing } from "../person/person-listing"; import { PostListings } from "../post/post-listings"; -import { SiteForm } from "./site-form"; +import { SiteSidebar } from "./site-sidebar"; interface HomeState { trendingCommunities: CommunityView[]; siteRes: GetSiteResponse; - showEditSite: boolean; showSubscribedMobile: boolean; showTrendingMobile: boolean; showSidebarMobile: boolean; - sidebarCollapsed: boolean; subscribedCollapsed: boolean; loading: boolean; posts: PostView[]; @@ -109,12 +103,10 @@ export class Home extends Component { private emptyState: HomeState = { trendingCommunities: [], siteRes: this.isoData.site_res, - showEditSite: false, showSubscribedMobile: false, showTrendingMobile: false, showSidebarMobile: false, subscribedCollapsed: false, - sidebarCollapsed: false, loading: true, posts: [], comments: [], @@ -128,7 +120,6 @@ export class Home extends Component { super(props, context); this.state = this.emptyState; - this.handleEditCancel = this.handleEditCancel.bind(this); this.handleSortChange = this.handleSortChange.bind(this); this.handleListingTypeChange = this.handleListingTypeChange.bind(this); this.handleDataTypeChange = this.handleDataTypeChange.bind(this); @@ -293,6 +284,7 @@ export class Home extends Component { } mobileView() { + let siteRes = this.state.siteRes; return (
@@ -337,19 +329,22 @@ export class Home extends Component { classes="icon-inline" /> - {this.state.showSubscribedMobile && ( -
-
{this.subscribedCommunities()}
-
+ {this.state.showSidebarMobile && ( + )} {this.state.showTrendingMobile && (
{this.trendingCommunities()}
)} - {this.state.showSidebarMobile && ( + {this.state.showSubscribedMobile && (
-
{this.sidebar()}
+
{this.subscribedCommunities()}
)}
@@ -358,6 +353,7 @@ export class Home extends Component { } mySidebar() { + let siteRes = this.state.siteRes; return (
{!this.state.loading && ( @@ -370,9 +366,12 @@ export class Home extends Component {
-
-
{this.sidebar()}
-
+ {UserService.Instance.myUserInfo && UserService.Instance.myUserInfo.follows.length > 0 && ( @@ -460,30 +459,6 @@ export class Home extends Component { ); } - sidebar() { - let site = this.state.siteRes.site_view.site; - return ( -
- {!this.state.showEditSite ? ( -
-
- {this.siteName()} - {this.adminButtons()} -
- {!this.state.sidebarCollapsed && ( - <> - - {this.siteInfo()} - - )} -
- ) : ( - - )} -
- ); - } - updateUrl(paramUpdates: UrlParams) { const listingTypeStr = paramUpdates.listingType || this.state.listingType; const dataTypeStr = paramUpdates.dataType || DataType[this.state.dataType]; @@ -494,179 +469,6 @@ export class Home extends Component { ); } - siteInfo() { - let site = this.state.siteRes.site_view.site; - return ( -
- {site.description &&
{site.description}
} - {site.sidebar && this.siteSidebar()} - {this.badges()} - {this.admins()} -
- ); - } - - siteName() { - let site = this.state.siteRes.site_view.site; - return ( - site.name && ( -
- {site.name} - -
- ) - ); - } - - admins() { - return ( -
    -
  • {i18n.t("admins")}:
  • - {this.state.siteRes.admins.map(av => ( -
  • - -
  • - ))} -
- ); - } - - badges() { - let counts = this.state.siteRes.site_view.counts; - return ( -
    -
  • - {i18n.t("number_online", { - count: this.state.siteRes.online, - formattedCount: numToSI(this.state.siteRes.online), - })} -
  • -
  • - {i18n.t("number_of_users", { - count: counts.users_active_day, - formattedCount: numToSI(counts.users_active_day), - })}{" "} - / {i18n.t("day")} -
  • -
  • - {i18n.t("number_of_users", { - count: counts.users_active_week, - formattedCount: numToSI(counts.users_active_week), - })}{" "} - / {i18n.t("week")} -
  • -
  • - {i18n.t("number_of_users", { - count: counts.users_active_month, - formattedCount: numToSI(counts.users_active_month), - })}{" "} - / {i18n.t("month")} -
  • -
  • - {i18n.t("number_of_users", { - count: counts.users_active_half_year, - formattedCount: numToSI(counts.users_active_half_year), - })}{" "} - / {i18n.t("number_of_months", { count: 6, formattedCount: 6 })} -
  • -
  • - {i18n.t("number_of_users", { - count: counts.users, - formattedCount: numToSI(counts.users), - })} -
  • -
  • - {i18n.t("number_of_communities", { - count: counts.communities, - formattedCount: numToSI(counts.communities), - })} -
  • -
  • - {i18n.t("number_of_posts", { - count: counts.posts, - formattedCount: numToSI(counts.posts), - })} -
  • -
  • - {i18n.t("number_of_comments", { - count: counts.comments, - formattedCount: numToSI(counts.comments), - })} -
  • -
  • - - {i18n.t("modlog")} - -
  • -
- ); - } - - adminButtons() { - return ( - this.canAdmin && ( -
    -
  • - -
  • -
- ) - ); - } - - siteSidebar() { - return ( -
- ); - } - posts() { return (
@@ -767,25 +569,6 @@ export class Home extends Component { ); } - get canAdmin(): boolean { - return ( - UserService.Instance.myUserInfo && - this.state.siteRes.admins - .map(a => a.person.id) - .includes(UserService.Instance.myUserInfo.local_user_view.person.id) - ); - } - - handleEditClick(i: Home) { - i.state.showEditSite = true; - i.setState(i.state); - } - - handleEditCancel() { - this.state.showEditSite = false; - this.setState(this.state); - } - handleShowSubscribedMobile(i: Home) { i.state.showSubscribedMobile = !i.state.showSubscribedMobile; i.setState(i.state); @@ -806,11 +589,6 @@ export class Home extends Component { i.setState(i.state); } - handleCollapseSidebar(i: Home) { - i.state.sidebarCollapsed = !i.state.sidebarCollapsed; - i.setState(i.state); - } - handlePageChange(page: number) { this.updateUrl({ page }); window.scrollTo(0, 0); @@ -873,7 +651,6 @@ export class Home extends Component { } else if (op == UserOperation.EditSite) { let data = wsJsonToRes(msg).data; this.state.siteRes.site_view = data.site_view; - this.state.showEditSite = false; this.setState(this.state); toast(i18n.t("site_saved")); } else if (op == UserOperation.GetPosts) { diff --git a/src/shared/components/home/site-form.tsx b/src/shared/components/home/site-form.tsx index 20e1db0..50797e6 100644 --- a/src/shared/components/home/site-form.tsx +++ b/src/shared/components/home/site-form.tsx @@ -16,6 +16,7 @@ import { MarkdownTextArea } from "../common/markdown-textarea"; interface SiteFormProps { site?: Site; // If a site is given, that means this is an edit onCancel?(): any; + onEdit?(): any; } interface SiteFormState { @@ -404,6 +405,7 @@ export class SiteForm extends Component { i.state.loading = true; if (i.props.site) { WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm)); + i.props.onEdit(); } else { let form: CreateSite = { name: i.state.siteForm.name || "My site", diff --git a/src/shared/components/home/site-sidebar.tsx b/src/shared/components/home/site-sidebar.tsx new file mode 100644 index 0000000..b5bf2bb --- /dev/null +++ b/src/shared/components/home/site-sidebar.tsx @@ -0,0 +1,267 @@ +import { Component, linkEvent } from "inferno"; +import { Link } from "inferno-router"; +import { PersonViewSafe, Site, SiteAggregates } from "lemmy-js-client"; +import { i18n } from "../../i18next"; +import { UserService } from "../../services"; +import { mdToHtml, numToSI } from "../../utils"; +import { BannerIconHeader } from "../common/banner-icon-header"; +import { Icon } from "../common/icon"; +import { PersonListing } from "../person/person-listing"; +import { SiteForm } from "./site-form"; + +interface SiteSidebarProps { + site: Site; + counts?: SiteAggregates; + admins?: PersonViewSafe[]; + online?: number; +} + +interface SiteSidebarState { + collapsed: boolean; + showEdit: boolean; +} + +export class SiteSidebar extends Component { + private emptyState: SiteSidebarState = { + collapsed: false, + showEdit: false, + }; + + constructor(props: any, context: any) { + super(props, context); + this.state = this.emptyState; + this.handleEditCancel = this.handleEditCancel.bind(this); + this.handleEditSite = this.handleEditSite.bind(this); + } + + render() { + let site = this.props.site; + return ( +
+
+ {!this.state.showEdit ? ( +
+
+ {this.siteName()} + {this.props.admins && this.adminButtons()} +
+ {!this.state.collapsed && ( + <> + + {this.siteInfo()} + + )} +
+ ) : ( + + )} +
+
+ ); + } + + siteName() { + let site = this.props.site; + return ( + site.name && ( +
+ {site.name} + +
+ ) + ); + } + + siteInfo() { + let site = this.props.site; + return ( +
+ {site.description &&
{site.description}
} + {site.sidebar && this.siteSidebar()} + {this.props.counts && this.badges()} + {this.props.admins && this.admins()} +
+ ); + } + + adminButtons() { + return ( + this.canAdmin && ( +
    +
  • + +
  • +
+ ) + ); + } + + siteSidebar() { + return ( +
+ ); + } + + admins() { + return ( +
    +
  • {i18n.t("admins")}:
  • + {this.props.admins?.map(av => ( +
  • + +
  • + ))} +
+ ); + } + + badges() { + let counts = this.props.counts; + let online = this.props.online; + return ( +
    +
  • + {i18n.t("number_online", { + count: online, + formattedCount: numToSI(online), + })} +
  • +
  • + {i18n.t("number_of_users", { + count: counts.users_active_day, + formattedCount: numToSI(counts.users_active_day), + })}{" "} + / {i18n.t("day")} +
  • +
  • + {i18n.t("number_of_users", { + count: counts.users_active_week, + formattedCount: numToSI(counts.users_active_week), + })}{" "} + / {i18n.t("week")} +
  • +
  • + {i18n.t("number_of_users", { + count: counts.users_active_month, + formattedCount: numToSI(counts.users_active_month), + })}{" "} + / {i18n.t("month")} +
  • +
  • + {i18n.t("number_of_users", { + count: counts.users_active_half_year, + formattedCount: numToSI(counts.users_active_half_year), + })}{" "} + / {i18n.t("number_of_months", { count: 6, formattedCount: 6 })} +
  • +
  • + {i18n.t("number_of_users", { + count: counts.users, + formattedCount: numToSI(counts.users), + })} +
  • +
  • + {i18n.t("number_of_communities", { + count: counts.communities, + formattedCount: numToSI(counts.communities), + })} +
  • +
  • + {i18n.t("number_of_posts", { + count: counts.posts, + formattedCount: numToSI(counts.posts), + })} +
  • +
  • + {i18n.t("number_of_comments", { + count: counts.comments, + formattedCount: numToSI(counts.comments), + })} +
  • +
  • + + {i18n.t("modlog")} + +
  • +
+ ); + } + + get canAdmin(): boolean { + return ( + UserService.Instance.myUserInfo && + this.props.admins + .map(a => a.person.id) + .includes(UserService.Instance.myUserInfo.local_user_view.person.id) + ); + } + + handleCollapseSidebar(i: SiteSidebar) { + i.state.collapsed = !i.state.collapsed; + i.setState(i.state); + } + + handleEditClick(i: SiteSidebar) { + i.state.showEdit = true; + i.setState(i.state); + } + + handleEditSite() { + this.state.showEdit = false; + this.setState(this.state); + } + + handleEditCancel() { + this.state.showEdit = false; + this.setState(this.state); + } +} diff --git a/yarn.lock b/yarn.lock index 0e2321e..71c4304 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4813,10 +4813,10 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -lemmy-js-client@0.16.0-rc.1: - version "0.16.0-rc.1" - resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.16.0-rc.1.tgz#14c4a526abf4b171c8afe4efbe2a62dcaf6a6f17" - integrity sha512-0hR/gHHsokp46whIHGMBQO2zBKWM7bT6mwKNMZxPvyJo+YW9EbKTO5edjF5E4v8nf3FuIE+gFtm5NFAjCaeWJg== +lemmy-js-client@0.16.4-rc.1: + version "0.16.4-rc.1" + resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.16.4-rc.1.tgz#dfa94a152a7abe75f50f2599a8d9b40c143f37ff" + integrity sha512-94Xh7A/WDywRaJ0GPXPaXZhyXqMzK0gAISNSB8m++2mC1WJalOqfjR72q/7PmLGxfjYO88/aWSz4Sk0SXWJjCw== levn@^0.4.1: version "0.4.1" -- 2.44.1