From: SleeplessOne1917
Date: Fri, 16 Jun 2023 20:00:46 +0000 (+0000)
Subject: Merge branch 'main' into generate-theme-css
X-Git-Url: http://these/git/?a=commitdiff_plain;h=d3a19751d5baa4b83d133bd8f78a00be3782335a;hp=3afd636b9e343e8fa6f50324c9898698dc414640;p=lemmy-ui.git
Merge branch 'main' into generate-theme-css
---
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 6df17d5..76916e6 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @dessalines @SleeplessOne1917
+* @dessalines @SleeplessOne1917 @alectrocute
diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml
index 2273a13..ae2d4e5 100644
--- a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml
@@ -21,7 +21,7 @@ body:
- label: Is this only a single bug? Do not put multiple bugs in one issue.
required: true
- label: Is this a server side (not related to the UI) issue? Use the [Lemmy back end](https://github.com/LemmyNet/lemmy) repo.
- required: true
+ required: false
- type: textarea
id: summary
attributes:
diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
index 2f6f3fc..3c75050 100644
--- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
+++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
@@ -19,7 +19,7 @@ body:
- label: Is this only a feature request? Do not put multiple feature requests in one issue.
required: true
- label: Is this a server side (not related to the UI) issue? Use the [Lemmy back end](https://github.com/LemmyNet/lemmy) repo.
- required: true
+ required: false
- type: textarea
id: problem
attributes:
diff --git a/Dockerfile b/Dockerfile
index 3d6d621..2b36581 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:alpine as builder
+FROM node:20.2-alpine as builder
RUN apk update && apk add curl yarn python3 build-base gcc wget git --no-cache
RUN curl -sf https://gobinaries.com/tj/node-prune | sh
diff --git a/dev.dockerfile b/dev.dockerfile
index 0e925c0..3bfc10d 100644
--- a/dev.dockerfile
+++ b/dev.dockerfile
@@ -1,4 +1,4 @@
-FROM node:alpine as builder
+FROM node:20.2-alpine as builder
RUN apk update && apk add curl yarn python3 build-base gcc wget git --no-cache
WORKDIR /usr/src/app
diff --git a/src/assets/css/main.css b/src/assets/css/main.css
index e1adfc5..82f8433 100644
--- a/src/assets/css/main.css
+++ b/src/assets/css/main.css
@@ -80,30 +80,6 @@
overflow-x: auto;
}
-.md-div table {
- border-collapse: collapse;
- width: 100%;
- margin-bottom: 1rem;
- border: 1px solid var(--dark);
-}
-
-.md-div table th,
-.md-div table td {
- padding: 0.3rem;
- vertical-align: top;
- border-top: 1px solid var(--dark);
- border: 1px solid var(--dark);
-}
-
-.md-div table thead th {
- vertical-align: bottom;
- border-bottom: 2px solid var(--dark);
-}
-
-.md-div table tbody + tbody {
- border-top: 2px solid var(--dark);
-}
-
.vote-bar {
margin-top: -6.5px;
}
diff --git a/src/server/index.tsx b/src/server/index.tsx
index 06dc33a..3a12ad7 100644
--- a/src/server/index.tsx
+++ b/src/server/index.tsx
@@ -421,7 +421,7 @@ async function createSsrHtml(root: string, isoData: IsoDataOptionalSite) {
-
+
{
const url = httpExternalPath(this.props.path);
const desc = this.props.description;
const image = this.props.image;
- const lang = getLanguages()[0];
return (
-
+
{["title", "og:title", "twitter:title"].map(t => (
diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx
index 9318d3b..a4459ac 100644
--- a/src/shared/components/common/markdown-textarea.tsx
+++ b/src/shared/components/common/markdown-textarea.tsx
@@ -184,53 +184,6 @@ export class MarkdownTextArea extends Component<
- {this.props.buttonTitle && (
-
- )}
- {this.props.replyType && (
-
- )}
- {this.state.content && (
-
- )}
- {/* A flex expander */}
-
-
- {this.props.showLanguage && (
-
- )}
{this.getFormatButton("bold", this.handleInsertBold)}
{this.getFormatButton("italic", this.handleInsertItalic)}
{this.getFormatButton("link", this.handleInsertLink)}
@@ -283,6 +236,57 @@ export class MarkdownTextArea extends Component<
+
+
+ {this.props.showLanguage && (
+
+ )}
+
+ {/* A flex expander */}
+
+
+ {this.props.buttonTitle && (
+
+ )}
+ {this.props.replyType && (
+
+ )}
+ {this.state.content && (
+
+ )}
+
);
diff --git a/src/shared/components/common/moment-time.tsx b/src/shared/components/common/moment-time.tsx
index 10714f5..30c1682 100644
--- a/src/shared/components/common/moment-time.tsx
+++ b/src/shared/components/common/moment-time.tsx
@@ -1,7 +1,7 @@
import { Component } from "inferno";
import moment from "moment";
import { i18n } from "../../i18next";
-import { capitalizeFirstLetter, getLanguages } from "../../utils";
+import { capitalizeFirstLetter } from "../../utils";
import { Icon } from "./icon";
interface MomentTimeProps {
@@ -15,9 +15,7 @@ export class MomentTime extends Component {
constructor(props: any, context: any) {
super(props, context);
- const lang = getLanguages();
-
- moment.locale(lang);
+ moment.locale([...i18n.languages]);
}
createdAndModifiedTimes() {
diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx
index 7dc150f..05fa55e 100644
--- a/src/shared/components/community/community.tsx
+++ b/src/shared/components/community/community.tsx
@@ -647,6 +647,12 @@ export class Community extends Component<
const blockCommunityRes = await HttpService.client.blockCommunity(form);
if (blockCommunityRes.state == "success") {
updateCommunityBlock(blockCommunityRes.data);
+ this.setState(s => {
+ if (s.communityRes.state == "success") {
+ s.communityRes.data.community_view.blocked =
+ blockCommunityRes.data.blocked;
+ }
+ });
}
}
diff --git a/src/shared/components/community/sidebar.tsx b/src/shared/components/community/sidebar.tsx
index a5c620f..57400f4 100644
--- a/src/shared/components/community/sidebar.tsx
+++ b/src/shared/components/community/sidebar.tsx
@@ -1,4 +1,5 @@
import { Component, InfernoNode, linkEvent } from "inferno";
+import { T } from "inferno-i18next-dess";
import { Link } from "inferno-router";
import {
AddModToCommunity,
@@ -63,7 +64,6 @@ interface SidebarState {
removeCommunityLoading: boolean;
leaveModTeamLoading: boolean;
followCommunityLoading: boolean;
- blockCommunityLoading: boolean;
purgeCommunityLoading: boolean;
}
@@ -77,7 +77,6 @@ export class Sidebar extends Component {
removeCommunityLoading: false,
leaveModTeamLoading: false,
followCommunityLoading: false,
- blockCommunityLoading: false,
purgeCommunityLoading: false,
};
@@ -104,7 +103,6 @@ export class Sidebar extends Component {
removeCommunityLoading: false,
leaveModTeamLoading: false,
followCommunityLoading: false,
- blockCommunityLoading: false,
purgeCommunityLoading: false,
});
}
@@ -144,10 +142,15 @@ export class Sidebar extends Component {
{myUSerInfo && this.blockCommunity()}
{!myUSerInfo && (
- {i18n.t("community_not_logged_in_alert", {
- community: name,
- instance: hostname(actor_id),
- })}
+
+ ##
#
+
)}
@@ -370,35 +373,18 @@ export class Sidebar extends Component {
}
blockCommunity() {
- const community_view = this.props.community_view;
- const blocked = this.props.community_view.blocked;
+ const { subscribed, blocked } = this.props.community_view;
return (
- {community_view.subscribed == "NotSubscribed" &&
- (blocked ? (
-
- ) : (
-
- ))}
+ {subscribed == "NotSubscribed" && (
+
+ )}
);
}
@@ -662,10 +648,11 @@ export class Sidebar extends Component {
}
handleBlockCommunity(i: Sidebar) {
- i.setState({ blockCommunityLoading: true });
+ const { community, blocked } = i.props.community_view;
+
i.props.onBlockCommunity({
- community_id: 0,
- block: !i.props.community_view.blocked,
+ community_id: community.id,
+ block: !blocked,
auth: myAuthRequired(),
});
}
diff --git a/src/shared/components/home/admin-settings.tsx b/src/shared/components/home/admin-settings.tsx
index 9b7256d..302e96b 100644
--- a/src/shared/components/home/admin-settings.tsx
+++ b/src/shared/components/home/admin-settings.tsx
@@ -39,6 +39,8 @@ interface AdminSettingsState {
instancesRes: RequestState;
bannedRes: RequestState;
leaveAdminTeamRes: RequestState;
+ emojiLoading: boolean;
+ loading: boolean;
themeList: string[];
isIsomorphic: boolean;
}
@@ -52,6 +54,8 @@ export class AdminSettings extends Component {
bannedRes: { state: "empty" },
instancesRes: { state: "empty" },
leaveAdminTeamRes: { state: "empty" },
+ emojiLoading: false,
+ loading: false,
themeList: [],
isIsomorphic: false,
};
@@ -81,6 +85,7 @@ export class AdminSettings extends Component {
bannedRes: { state: "loading" },
instancesRes: { state: "loading" },
themeList: [],
+ loading: true,
});
const auth = myAuthRequired();
@@ -95,6 +100,7 @@ export class AdminSettings extends Component {
bannedRes,
instancesRes,
themeList,
+ loading: false,
});
}
@@ -156,6 +162,7 @@ export class AdminSettings extends Component {
onSaveSite={this.handleEditSite}
siteRes={this.state.siteRes}
themeList={this.state.themeList}
+ loading={this.state.loading}
/>
@@ -174,6 +181,7 @@ export class AdminSettings extends Component
{
this.state.siteRes.site_view.local_site_rate_limit
}
onSaveSite={this.handleEditSite}
+ loading={this.state.loading}
/>
),
},
@@ -185,6 +193,7 @@ export class AdminSettings extends Component {
),
@@ -198,6 +207,7 @@ export class AdminSettings extends Component {
onCreate={this.handleCreateEmoji}
onDelete={this.handleDeleteEmoji}
onEdit={this.handleEditEmoji}
+ loading={this.state.emojiLoading}
/>
),
@@ -266,6 +276,8 @@ export class AdminSettings extends Component {
}
async handleEditSite(form: EditSite) {
+ this.setState({ loading: true });
+
const editRes = await HttpService.client.editSite(form);
if (editRes.state === "success") {
@@ -278,6 +290,8 @@ export class AdminSettings extends Component {
toast(i18n.t("site_saved"));
}
+ this.setState({ loading: false });
+
return editRes;
}
@@ -300,23 +314,35 @@ export class AdminSettings extends Component {
}
async handleEditEmoji(form: EditCustomEmoji) {
+ this.setState({ emojiLoading: true });
+
const res = await HttpService.client.editCustomEmoji(form);
if (res.state === "success") {
updateEmojiDataModel(res.data.custom_emoji);
}
+
+ this.setState({ emojiLoading: false });
}
async handleDeleteEmoji(form: DeleteCustomEmoji) {
+ this.setState({ emojiLoading: true });
+
const res = await HttpService.client.deleteCustomEmoji(form);
if (res.state === "success") {
removeFromEmojiDataModel(res.data.id);
}
+
+ this.setState({ emojiLoading: false });
}
async handleCreateEmoji(form: CreateCustomEmoji) {
+ this.setState({ emojiLoading: true });
+
const res = await HttpService.client.createCustomEmoji(form);
if (res.state === "success") {
updateEmojiDataModel(res.data.custom_emoji);
}
+
+ this.setState({ emojiLoading: false });
}
}
diff --git a/src/shared/components/home/emojis-form.tsx b/src/shared/components/home/emojis-form.tsx
index 171b7c9..f77f512 100644
--- a/src/shared/components/home/emojis-form.tsx
+++ b/src/shared/components/home/emojis-form.tsx
@@ -23,12 +23,12 @@ interface EmojiFormProps {
onEdit(form: EditCustomEmoji): void;
onCreate(form: CreateCustomEmoji): void;
onDelete(form: DeleteCustomEmoji): void;
+ loading: boolean;
}
interface EmojiFormState {
siteRes: GetSiteResponse;
customEmojis: CustomEmojiViewForm[];
- loading: boolean;
page: number;
}
@@ -47,7 +47,6 @@ export class EmojiForm extends Component {
private isoData = setIsoData(this.context);
private itemsPerPage = 15;
private emptyState: EmojiFormState = {
- loading: false,
siteRes: this.isoData.site_res,
customEmojis: this.isoData.site_res.custom_emojis.map((x, index) => ({
id: x.custom_emoji.id,
@@ -223,7 +222,7 @@ export class EmojiForm extends Component {
data-tippy-content={i18n.t("save")}
aria-label={i18n.t("save")}
disabled={
- this.state.loading ||
+ this.props.loading ||
!this.canEdit(cv) ||
!cv.changed
}
@@ -243,7 +242,7 @@ export class EmojiForm extends Component {
)}
data-tippy-content={i18n.t("delete")}
aria-label={i18n.t("delete")}
- disabled={this.state.loading}
+ disabled={this.props.loading}
title={i18n.t("delete")}
>
{
}
async componentDidMount() {
- if (!this.state.isIsomorphic) {
+ if (!this.state.isIsomorphic || !this.isoData.routeData.length) {
await Promise.all([this.fetchTrendingCommunities(), this.fetchData()]);
}
+
setupTippy();
}
@@ -456,7 +457,7 @@ export class Home extends Component {
}
trendingCommunities(isMobile = false) {
- switch (this.state.trendingCommunitiesRes.state) {
+ switch (this.state.trendingCommunitiesRes?.state) {
case "loading":
return (
@@ -573,7 +574,7 @@ export class Home extends Component {
const siteRes = this.state.siteRes;
if (dataType === DataType.Post) {
- switch (this.state.postsRes.state) {
+ switch (this.state.postsRes?.state) {
case "loading":
return (
diff --git a/src/shared/components/home/login.tsx b/src/shared/components/home/login.tsx
index 9491554..381c13b 100644
--- a/src/shared/components/home/login.tsx
+++ b/src/shared/components/home/login.tsx
@@ -186,7 +186,9 @@ export class Login extends Component {
UserService.Instance.myUserInfo = site.data.my_user;
}
- i.props.history.replace("/");
+ i.props.history.action === "PUSH"
+ ? i.props.history.back()
+ : i.props.history.replace("/");
break;
}
diff --git a/src/shared/components/home/rate-limit-form.tsx b/src/shared/components/home/rate-limit-form.tsx
index 74ed18e..0ce0126 100644
--- a/src/shared/components/home/rate-limit-form.tsx
+++ b/src/shared/components/home/rate-limit-form.tsx
@@ -24,6 +24,7 @@ interface RateLimitsProps {
interface RateLimitFormProps {
rateLimits: LocalSiteRateLimit;
onSaveSite(form: EditSite): void;
+ loading: boolean;
}
interface RateLimitFormState {
@@ -41,7 +42,6 @@ interface RateLimitFormState {
register?: number;
register_per_second?: number;
};
- loading: boolean;
}
function RateLimits({
@@ -117,7 +117,6 @@ function submitRateLimitForm(i: RateLimitsForm, event: any) {
}
);
- i.setState({ loading: true });
i.props.onSaveSite(form);
}
@@ -126,7 +125,6 @@ export default class RateLimitsForm extends Component<
RateLimitFormState
> {
state: RateLimitFormState = {
- loading: false,
form: this.props.rateLimits,
};
constructor(props: RateLimitFormProps, context: any) {
@@ -164,9 +162,9 @@ export default class RateLimitsForm extends Component<