Merge remote-tracking branch 'origin/main' into add_open_links_in_new_tab_1

This commit is contained in:
Dessalines 2023-08-04 17:00:45 -04:00
commit 3f985558e8
133 changed files with 1234 additions and 1108 deletions

View file

@ -20,10 +20,11 @@
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"arrow-body-style": 0,
"curly": 0,
"eol-last": 0,
"eqeqeq": 0,
"eqeqeq": "error",
"func-style": 0,
"import/no-duplicates": 0,
"max-statements": 0,
@ -39,7 +40,7 @@
"no-useless-constructor": 0,
"no-useless-escape": 0,
"no-var": 0,
"prefer-const": 1,
"prefer-const": "error",
"prefer-rest-params": 0,
"prettier/prettier": "error",
"quote-props": 0,

View file

@ -8,12 +8,12 @@ fs.readdir(translationDir, (_err, files) => {
const lang = filename.split(".")[0];
try {
const json = JSON.parse(
fs.readFileSync(translationDir + filename, "utf8")
fs.readFileSync(translationDir + filename, "utf8"),
);
let data = `export const ${lang} = {\n translation: {`;
for (const key in json) {
if (key in json) {
const value = json[key].replace(/"/g, '\\"');
const value = json[key].replace(/"/g, '\\"').replace("\n", "\\n");
data += `\n ${key}: "${value}",`;
}
}
@ -67,14 +67,14 @@ ${optionKeys.map(key => `${indent}| "${key}"`).join("\n")};
export type I18nKeys = NoOptionI18nKeys | OptionI18nKeys;
export type TTypedOptions<TKey extends OptionI18nKeys> =${Array.from(
optionMap.entries()
optionMap.entries(),
).reduce(
(acc, [key, options]) =>
`${acc} TKey extends \"${key}\" ? ${
options.reduce((acc, cur) => acc + `${cur}: string | number; `, "{ ") +
"}"
} :\n${indent}`,
""
"",
)} (Record<string, unknown> | string);
export interface TFunctionTyped {

@ -1 +1 @@
Subproject commit 80726988d521cf727201af530c6009bbb1f3e2c2
Subproject commit 22637606f4a4455458e64cefe9f5ec33dccb6c52

View file

@ -35,16 +35,16 @@
},
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.21.0",
"@babel/plugin-transform-runtime": "^7.21.4",
"@babel/plugin-transform-typescript": "^7.21.3",
"@babel/preset-env": "7.21.5",
"@babel/plugin-transform-runtime": "^7.22.9",
"@babel/plugin-transform-typescript": "^7.22.9",
"@babel/preset-env": "7.22.9",
"@babel/preset-typescript": "^7.21.5",
"@babel/runtime": "^7.21.5",
"@emoji-mart/data": "^1.1.0",
"autosize": "^6.0.1",
"babel-loader": "^9.1.2",
"babel-plugin-inferno": "^6.6.0",
"bootstrap": "^5.2.3",
"bootstrap": "^5.3.1",
"check-password-strength": "^2.0.7",
"classnames": "^2.3.1",
"clean-webpack-plugin": "^4.0.0",
@ -58,7 +58,7 @@
"express": "~4.18.2",
"history": "^5.3.0",
"html-to-text": "^9.0.5",
"i18next": "^23.2.8",
"i18next": "^23.3.0",
"inferno": "^8.2.2",
"inferno-create-element": "^8.2.2",
"inferno-helmet": "^5.2.1",
@ -67,7 +67,7 @@
"inferno-router": "^8.2.2",
"inferno-server": "^8.2.2",
"jwt-decode": "^3.1.2",
"lemmy-js-client": "0.18.1",
"lemmy-js-client": "0.19.0-rc.1",
"lodash.isequal": "^4.5.0",
"markdown-it": "^13.0.1",
"markdown-it-container": "^3.0.0",
@ -81,20 +81,21 @@
"register-service-worker": "^1.7.2",
"run-node-webpack-plugin": "^1.3.0",
"sanitize-html": "^2.11.0",
"sass": "^1.63.6",
"sass": "^1.64.1",
"sass-loader": "^13.3.2",
"serialize-javascript": "^6.0.1",
"service-worker-webpack": "^1.0.0",
"sharp": "^0.32.1",
"sharp": "^0.32.4",
"tippy.js": "^6.3.7",
"toastify-js": "^1.12.0",
"tributejs": "^5.1.3",
"webpack": "5.88.1",
"webpack": "5.88.2",
"webpack-cli": "^5.1.4",
"webpack-node-externals": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.21.8",
"@babel/core": "^7.22.9",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@types/autosize": "^4.0.0",
"@types/bootstrap": "^5.2.6",
"@types/cookie": "^0.5.1",
@ -102,29 +103,29 @@
"@types/html-to-text": "^9.0.0",
"@types/lodash.isequal": "^4.5.6",
"@types/markdown-it": "^12.2.3",
"@types/markdown-it-container": "^2.0.5",
"@types/node": "^20.4.0",
"@types/markdown-it-container": "^2.0.6",
"@types/node": "^20.4.5",
"@types/path-browserify": "^1.0.0",
"@types/sanitize-html": "^2.9.0",
"@types/serialize-javascript": "^5.0.1",
"@types/toastify-js": "^1.11.1",
"@typescript-eslint/eslint-plugin": "^5.61.0",
"@typescript-eslint/parser": "^5.61.0",
"eslint": "^8.44.0",
"@types/toastify-js": "^1.12.0",
"@typescript-eslint/eslint-plugin": "^6.2.0",
"@typescript-eslint/parser": "^6.2.0",
"eslint": "^8.45.0",
"eslint-plugin-inferno": "^7.32.2",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-prettier": "^5.0.0",
"husky": "^8.0.3",
"import-sort-style-module": "^6.0.0",
"lint-staged": "^13.2.3",
"prettier": "^2.8.8",
"prettier": "^3.0.0",
"prettier-plugin-import-sort": "^0.0.7",
"prettier-plugin-organize-imports": "^3.2.2",
"prettier-plugin-packagejson": "^2.4.4",
"prettier-plugin-organize-imports": "^3.2.3",
"prettier-plugin-packagejson": "^2.4.5",
"rimraf": "^5.0.0",
"sortpack": "^2.3.4",
"style-loader": "^3.3.2",
"terser": "^5.18.2",
"terser": "^5.19.2",
"typescript": "^5.1.6",
"typescript-language-server": "^3.3.2",
"webpack-bundle-analyzer": "^4.9.0",

View file

@ -30,9 +30,18 @@ $mark-bg: $gray-900;
$text-muted: $gray-600;
$yiq-contrasted-threshold: 175;
$font-family-sans-serif: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol";
$font-family-sans-serif:
"Lato",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol";
$font-size-base: 0.9375rem;
$h1-font-size: 3rem;
$h2-font-size: 2.5rem;

View file

@ -29,9 +29,18 @@ $mark-bg: #333;
$text-muted: $gray-600;
$yiq-contrasted-threshold: 175;
$font-family-sans-serif: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol";
$font-family-sans-serif:
"Lato",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol";
$h1-font-size: 3rem;
$h2-font-size: 2.5rem;
$h3-font-size: 2rem;

View file

@ -23,8 +23,11 @@ option:disabled {
}
.form-control::placeholder {
text-shadow: 0.5px 0.5px 0 $secondary, 0.5px -0.5px 0 $secondary,
-0.5px 0.5px 0 $secondary, -0.5px -0.5px 0 $secondary;
text-shadow:
0.5px 0.5px 0 $secondary,
0.5px -0.5px 0 $secondary,
-0.5px 0.5px 0 $secondary,
-0.5px -0.5px 0 $secondary;
}
.input-group-text {

View file

@ -35,7 +35,7 @@ export default async (req: Request, res: Response) => {
const headers = setForwardedHeaders(req.headers);
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { fetchFunction: fetch, headers })
new LemmyHttp(getHttpBaseInternal(), { fetchFunction: fetch, headers }),
);
const { path, url, query } = req;
@ -48,9 +48,9 @@ export default async (req: Request, res: Response) => {
let errorPageData: ErrorPageData | undefined = undefined;
let try_site = await client.getSite(getSiteForm);
if (try_site.state === "failed" && try_site.msg == "not_logged_in") {
if (try_site.state === "failed" && try_site.msg === "not_logged_in") {
console.error(
"Incorrect JWT token, skipping auth so frontend can remove jwt cookie"
"Incorrect JWT token, skipping auth so frontend can remove jwt cookie",
);
getSiteForm.auth = undefined;
auth = undefined;
@ -90,7 +90,7 @@ export default async (req: Request, res: Response) => {
}
const error = Object.values(routeData).find(
res => res.state === "failed" && res.msg !== "couldnt_find_object" // TODO: find a better way of handling errors
res => res.state === "failed" && res.msg !== "couldnt_find_object", // TODO: find a better way of handling errors
) as FailedRequestState | undefined;
// Redirect to the 404 if there's an API error
@ -127,7 +127,7 @@ export default async (req: Request, res: Response) => {
res.statusCode = 500;
return res.send(
process.env.NODE_ENV === "development" ? err.message : "Server error"
process.env.NODE_ENV === "development" ? err.message : "Server error",
);
}
};

View file

@ -13,7 +13,7 @@ export default async (req: Request, res: Response) => {
if (!manifest || manifest.start_url !== getHttpBaseExternal()) {
const headers = setForwardedHeaders(req.headers);
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { fetchFunction: fetch, headers })
new LemmyHttp(getHttpBaseInternal(), { fetchFunction: fetch, headers }),
);
const site = await client.getSite({});

View file

@ -12,6 +12,6 @@ export default async ({ res }: { res: Response }) => {
process.env.LEMMY_UI_LEMMY_EXTERNAL_HOST +
`
Expires: 2024-01-01T04:59:00.000Z
`
`,
);
};

View file

@ -8,7 +8,7 @@ export default async ({ res }: { res: Response }) => {
path.resolve(
`./dist/service-worker${
process.env.NODE_ENV === "development" ? "-development" : ""
}.js`
)
}.js`,
),
);
};

View file

@ -25,7 +25,7 @@ server.use(
express.static(path.resolve("./dist"), {
maxAge: 24 * 60 * 60 * 1000, // 1 day
immutable: true,
})
}),
);
server.use(setCacheControl);

View file

@ -22,7 +22,7 @@ export function setDefaultCsp({
form-action 'self';
base-uri 'self';
frame-src *;
media-src * data:`.replace(/\s+/g, " ")
media-src * data:`.replace(/\s+/g, " "),
);
next();
@ -37,7 +37,7 @@ export function setDefaultCsp({
export function setCacheControl(
req: Request,
res: Response,
next: NextFunction
next: NextFunction,
) {
if (process.env.NODE_ENV !== "production") {
return next();

View file

@ -15,7 +15,7 @@ let appleTouchIcon: string | undefined = undefined;
export async function createSsrHtml(
root: string,
isoData: IsoDataOptionalSite,
cspNonce: string
cspNonce: string,
) {
const site = isoData.site_res;
@ -26,13 +26,13 @@ export async function createSsrHtml(
const customHtmlHeaderScriptTag = new RegExp("<script", "g");
const customHtmlHeaderWithNonce = customHtmlHeader.replace(
customHtmlHeaderScriptTag,
`<script nonce="${cspNonce}"`
`<script nonce="${cspNonce}"`,
);
if (!appleTouchIcon) {
appleTouchIcon = site?.site_view.site.icon
? `data:image/png;base64,${await sharp(
await fetchIconPng(site.site_view.site.icon)
await fetchIconPng(site.site_view.site.icon),
)
.resize(180, 180)
.extend({
@ -57,7 +57,7 @@ export async function createSsrHtml(
src="//cdn.jsdelivr.net/npm/eruda"
></script>
<script nonce={cspNonce}>eruda.init();</script>
</>
</>,
)
: "";

View file

@ -10,7 +10,7 @@ const defaultLogoPathDirectory = path.join(
process.cwd(),
"dist",
"assets",
"icons"
"icons",
);
export default async function ({
@ -34,7 +34,7 @@ export default async function ({
icons: await Promise.all(
iconSizes.map(async size => {
let src = await readFile(
path.join(defaultLogoPathDirectory, `icon-${size}x${size}.png`)
path.join(defaultLogoPathDirectory, `icon-${size}x${size}.png`),
).then(buf => buf.toString("base64"));
if (icon) {
@ -51,7 +51,7 @@ export default async function ({
src: `data:image/png;base64,${src}`,
purpose: "any maskable",
};
})
}),
),
shortcuts: [
{
@ -82,7 +82,7 @@ export default async function ({
description: "Create a community",
},
]
: []
: [],
),
related_applications: [
{

View file

@ -86,7 +86,7 @@ export class App extends Component<AppProps, any> {
);
}}
/>
)
),
)}
<Route component={ErrorPage} />
</Switch>

View file

@ -146,7 +146,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
{
count: Number(this.unreadApplicationCount),
formattedCount: numToSI(this.unreadApplicationCount),
}
},
)}
onMouseUp={linkEvent(this, handleCollapseClick)}
>
@ -323,9 +323,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
{
count: Number(this.unreadApplicationCount),
formattedCount: numToSI(
this.unreadApplicationCount
this.unreadApplicationCount,
),
}
},
)}
onMouseUp={linkEvent(this, handleCollapseClick)}
>
@ -336,9 +336,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
{
count: Number(this.unreadApplicationCount),
formattedCount: numToSI(
this.unreadApplicationCount
this.unreadApplicationCount,
),
}
},
)}
</span>
{this.unreadApplicationCount > 0 && (
@ -480,7 +480,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
}
get unreadInboxCount(): number {
if (this.state.unreadInboxCountRes.state == "success") {
if (this.state.unreadInboxCountRes.state === "success") {
const data = this.state.unreadInboxCountRes.data;
return data.replies + data.mentions + data.private_messages;
} else {
@ -489,7 +489,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
}
get unreadReportCount(): number {
if (this.state.unreadReportCountRes.state == "success") {
if (this.state.unreadReportCountRes.state === "success") {
const data = this.state.unreadReportCountRes.data;
return (
data.post_reports +
@ -502,7 +502,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
}
get unreadApplicationCount(): number {
if (this.state.unreadApplicationCountRes.state == "success") {
if (this.state.unreadApplicationCountRes.state === "success") {
const data = this.state.unreadApplicationCountRes.data;
return data.registration_applications;
} else {

View file

@ -22,8 +22,8 @@ export class Theme extends Component<Props> {
</Helmet>
);
} else if (
this.props.defaultTheme != "browser" &&
this.props.defaultTheme != "browser-compact"
this.props.defaultTheme !== "browser" &&
this.props.defaultTheme !== "browser-compact"
) {
return (
<Helmet>
@ -34,7 +34,7 @@ export class Theme extends Component<Props> {
/>
</Helmet>
);
} else if (this.props.defaultTheme == "browser-compact") {
} else if (this.props.defaultTheme === "browser-compact") {
return (
<Helmet>
<link

View file

@ -43,7 +43,7 @@ export class CommentForm extends Component<CommentFormProps, any> {
return (
<div
className={["comment-form", "mb-3", this.props.containerClass].join(
" "
" ",
)}
>
{UserService.Instance.myUserInfo ? (

View file

@ -198,7 +198,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & CommentNodeProps>
nextProps: Readonly<{ children?: InfernoNode } & CommentNodeProps>,
): void {
if (!deepEqual(this.props, nextProps)) {
this.setState({
@ -243,34 +243,34 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
const cv = this.commentView;
const purgeTypeText =
this.state.purgeType == PurgeType.Comment
this.state.purgeType === PurgeType.Comment
? I18NextService.i18n.t("purge_comment")
: `${I18NextService.i18n.t("purge")} ${cv.creator.name}`;
const canMod_ = canMod(
cv.creator.id,
this.props.moderators,
this.props.admins
this.props.admins,
);
const canModOnSelf = canMod(
cv.creator.id,
this.props.moderators,
this.props.admins,
UserService.Instance.myUserInfo,
true
true,
);
const canAdmin_ = canAdmin(cv.creator.id, this.props.admins);
const canAdminOnSelf = canAdmin(
cv.creator.id,
this.props.admins,
UserService.Instance.myUserInfo,
true
true,
);
const isMod_ = isMod(cv.creator.id, this.props.moderators);
const isAdmin_ = isAdmin(cv.creator.id, this.props.admins);
const amCommunityCreator_ = amCommunityCreator(
cv.creator.id,
this.props.moderators
this.props.moderators,
);
const moreRepliesBorderColor = this.props.node.depth
@ -278,13 +278,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
: colorList[0];
const showMoreChildren =
this.props.viewType == CommentViewType.Tree &&
this.props.viewType === CommentViewType.Tree &&
!this.state.collapsed &&
node.children.length == 0 &&
node.children.length === 0 &&
node.comment_view.counts.child_count > 0;
return (
<li className="comment">
<li className="comment list-unstyled">
<article
id={`comment-${cv.comment.id}`}
className={classNames(`details comment-node py-2`, {
@ -337,7 +337,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
<span className="badge text-bg-light d-none d-sm-inline me-2">
{
this.props.allLanguages.find(
lang => lang.id === cv.comment.language_id
lang => lang.id === cv.comment.language_id,
)?.name
}
</span>
@ -348,7 +348,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{showScores() && (
<>
<span
className="me-1 fw-bold"
className={`me-1 fw-bold ${this.scoreColor}`}
aria-label={I18NextService.i18n.t("number_of_points", {
count: Number(this.commentView.counts.score),
formattedCount: numToSI(this.commentView.counts.score),
@ -374,7 +374,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
onReplyCancel={this.handleReplyCancel}
disabled={this.props.locked}
finished={this.props.finished.get(
this.props.node.comment_view.comment.id
this.props.node.comment_view.comment.id,
)}
focus
allLanguages={this.props.allLanguages}
@ -472,13 +472,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleShowReportDialog
this.handleShowReportDialog,
)}
data-tippy-content={I18NextService.i18n.t(
"show_report_dialog"
"show_report_dialog",
)}
aria-label={I18NextService.i18n.t(
"show_report_dialog"
"show_report_dialog",
)}
>
<Icon icon="flag" />
@ -487,10 +487,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleBlockPerson
this.handleBlockPerson,
)}
data-tippy-content={I18NextService.i18n.t(
"block_user"
"block_user",
)}
aria-label={I18NextService.i18n.t("block_user")}
>
@ -531,7 +531,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleViewSource)}
data-tippy-content={I18NextService.i18n.t(
"view_source"
"view_source",
)}
aria-label={I18NextService.i18n.t("view_source")}
>
@ -548,7 +548,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleEditClick)}
data-tippy-content={I18NextService.i18n.t(
"edit"
"edit",
)}
aria-label={I18NextService.i18n.t("edit")}
>
@ -558,7 +558,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleDeleteComment
this.handleDeleteComment,
)}
data-tippy-content={
!cv.comment.deleted
@ -588,7 +588,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleDistinguishComment
this.handleDistinguishComment,
)}
data-tippy-content={
!cv.comment.distinguished
@ -619,7 +619,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleModRemoveShow
this.handleModRemoveShow,
)}
aria-label={I18NextService.i18n.t("remove")}
>
@ -630,7 +630,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleRemoveComment
this.handleRemoveComment,
)}
aria-label={I18NextService.i18n.t("restore")}
>
@ -652,14 +652,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleModBanFromCommunityShow
this.handleModBanFromCommunityShow,
)}
aria-label={I18NextService.i18n.t(
"ban_from_community"
"ban_from_community",
)}
>
{I18NextService.i18n.t(
"ban_from_community"
"ban_from_community",
)}
</button>
) : (
@ -667,7 +667,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleBanPersonFromCommunity
this.handleBanPersonFromCommunity,
)}
aria-label={I18NextService.i18n.t("unban")}
>
@ -684,13 +684,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleShowConfirmAppointAsMod
this.handleShowConfirmAppointAsMod,
)}
aria-label={
isMod_
? I18NextService.i18n.t("remove_as_mod")
: I18NextService.i18n.t(
"appoint_as_mod"
"appoint_as_mod",
)
}
>
@ -703,7 +703,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
<button
className="btn btn-link btn-animate text-muted"
aria-label={I18NextService.i18n.t(
"are_you_sure"
"are_you_sure",
)}
>
{I18NextService.i18n.t("are_you_sure")}
@ -712,7 +712,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleAddModToCommunity
this.handleAddModToCommunity,
)}
aria-label={I18NextService.i18n.t("yes")}
>
@ -726,7 +726,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleCancelConfirmAppointAsMod
this.handleCancelConfirmAppointAsMod,
)}
aria-label={I18NextService.i18n.t("no")}
>
@ -745,10 +745,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleShowConfirmTransferCommunity
this.handleShowConfirmTransferCommunity,
)}
aria-label={I18NextService.i18n.t(
"transfer_community"
"transfer_community",
)}
>
{I18NextService.i18n.t("transfer_community")}
@ -758,7 +758,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
<button
className="btn btn-link btn-animate text-muted"
aria-label={I18NextService.i18n.t(
"are_you_sure"
"are_you_sure",
)}
>
{I18NextService.i18n.t("are_you_sure")}
@ -767,7 +767,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleTransferCommunity
this.handleTransferCommunity,
)}
aria-label={I18NextService.i18n.t("yes")}
>
@ -782,7 +782,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
onClick={linkEvent(
this,
this
.handleCancelShowConfirmTransferCommunity
.handleCancelShowConfirmTransferCommunity,
)}
aria-label={I18NextService.i18n.t("no")}
>
@ -799,10 +799,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handlePurgePersonShow
this.handlePurgePersonShow,
)}
aria-label={I18NextService.i18n.t(
"purge_user"
"purge_user",
)}
>
{I18NextService.i18n.t("purge_user")}
@ -811,10 +811,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handlePurgeCommentShow
this.handlePurgeCommentShow,
)}
aria-label={I18NextService.i18n.t(
"purge_comment"
"purge_comment",
)}
>
{I18NextService.i18n.t("purge_comment")}
@ -825,10 +825,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleModBanShow
this.handleModBanShow,
)}
aria-label={I18NextService.i18n.t(
"ban_from_site"
"ban_from_site",
)}
>
{I18NextService.i18n.t("ban_from_site")}
@ -838,10 +838,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleBanPerson
this.handleBanPerson,
)}
aria-label={I18NextService.i18n.t(
"unban_from_site"
"unban_from_site",
)}
>
{this.state.banLoading ? (
@ -860,22 +860,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleShowConfirmAppointAsAdmin
this.handleShowConfirmAppointAsAdmin,
)}
aria-label={
isAdmin_
? I18NextService.i18n.t(
"remove_as_admin"
"remove_as_admin",
)
: I18NextService.i18n.t(
"appoint_as_admin"
"appoint_as_admin",
)
}
>
{isAdmin_
? I18NextService.i18n.t("remove_as_admin")
: I18NextService.i18n.t(
"appoint_as_admin"
"appoint_as_admin",
)}
</button>
) : (
@ -887,7 +887,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleAddAdmin
this.handleAddAdmin,
)}
aria-label={I18NextService.i18n.t("yes")}
>
@ -901,7 +901,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
this,
this.handleCancelConfirmAppointAsAdmin
this.handleCancelConfirmAppointAsAdmin,
)}
aria-label={I18NextService.i18n.t("no")}
>
@ -939,7 +939,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{I18NextService.i18n.t("x_more_replies", {
count: node.comment_view.counts.child_count,
formattedCount: numToSI(
node.comment_view.counts.child_count
node.comment_view.counts.child_count,
),
})}{" "}
@ -1114,7 +1114,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
onReplyCancel={this.handleReplyCancel}
disabled={this.props.locked}
finished={this.props.finished.get(
this.props.node.comment_view.comment.id
this.props.node.comment_view.comment.id,
)}
focus
allLanguages={this.props.allLanguages}
@ -1210,19 +1210,19 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
get myComment(): boolean {
return (
UserService.Instance.myUserInfo?.local_user_view.person.id ==
UserService.Instance.myUserInfo?.local_user_view.person.id ===
this.commentView.creator.id
);
}
get isPostCreator(): boolean {
return this.commentView.creator.id == this.commentView.post.creator_id;
return this.commentView.creator.id === this.commentView.post.creator_id;
}
get scoreColor() {
if (this.commentView.my_vote == 1) {
if (this.commentView.my_vote === 1) {
return "text-info";
} else if (this.commentView.my_vote == -1) {
} else if (this.commentView.my_vote === -1) {
return "text-danger";
} else {
return "text-muted";
@ -1299,13 +1299,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
}
isPersonMentionType(
item: CommentView | PersonMentionView | CommentReplyView
item: CommentView | PersonMentionView | CommentReplyView,
): item is PersonMentionView {
return (item as PersonMentionView).person_mention?.id !== undefined;
}
isCommentReplyType(
item: CommentView | PersonMentionView | CommentReplyView
item: CommentView | PersonMentionView | CommentReplyView,
): item is CommentReplyView {
return (item as CommentReplyView).comment_reply?.id !== undefined;
}
@ -1499,7 +1499,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
handleModBanBothSubmit(i: CommentNode, event: any) {
event.preventDefault();
if (i.state.banType == BanType.Community) {
if (i.state.banType === BanType.Community) {
i.handleBanPersonFromCommunity(i);
} else {
i.handleBanPerson(i);
@ -1552,7 +1552,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
event.preventDefault();
i.setState({ purgeLoading: true });
if (i.state.purgeType == PurgeType.Person) {
if (i.state.purgeType === PurgeType.Person) {
i.props.onPurgePerson({
person_id: i.commentView.creator.id,
reason: i.state.purgeReason,

View file

@ -33,9 +33,9 @@ export class CommentReport extends Component<
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & CommentReportProps>
nextProps: Readonly<{ children?: InfernoNode } & CommentReportProps>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState({ loading: false });
}
}
@ -44,7 +44,7 @@ export class CommentReport extends Component<
const r = this.props.report;
const comment = r.comment;
const tippyContent = I18NextService.i18n.t(
r.comment_report.resolved ? "unresolve_report" : "resolve_report"
r.comment_report.resolved ? "unresolve_report" : "resolve_report",
);
// Set the original post data ( a troll could change it )

View file

@ -13,13 +13,13 @@ interface BadgesProps {
}
const isCommunityAggregates = (
counts: CommunityAggregates | SiteAggregates
counts: CommunityAggregates | SiteAggregates,
): counts is CommunityAggregates => {
return "subscribers" in counts;
};
const isSiteAggregates = (
counts: CommunityAggregates | SiteAggregates
counts: CommunityAggregates | SiteAggregates,
): counts is SiteAggregates => {
return "communities" in counts;
};
@ -34,7 +34,7 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
{
count: Number(counts.users_active_day),
formattedCount: numToSI(counts.users_active_day),
}
},
)}
>
{I18NextService.i18n.t("number_of_users", {
@ -50,7 +50,7 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
{
count: Number(counts.users_active_week),
formattedCount: numToSI(counts.users_active_week),
}
},
)}
>
{I18NextService.i18n.t("number_of_users", {
@ -66,7 +66,7 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
{
count: Number(counts.users_active_month),
formattedCount: numToSI(counts.users_active_month),
}
},
)}
>
{I18NextService.i18n.t("number_of_users", {
@ -82,7 +82,7 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
{
count: Number(counts.users_active_half_year),
formattedCount: numToSI(counts.users_active_half_year),
}
},
)}
>
{I18NextService.i18n.t("number_of_users", {

View file

@ -48,6 +48,9 @@ export class CommentSortSelect extends Component<
{I18NextService.i18n.t("sort_type")}
</option>
<option value={"Hot"}>{I18NextService.i18n.t("hot")}</option>,
<option value={"Controversial"}>
{I18NextService.i18n.t("controversial")}
</option>
<option value={"Top"}>{I18NextService.i18n.t("top")}</option>,
<option value={"New"}>{I18NextService.i18n.t("new")}</option>
<option value={"Old"}>{I18NextService.i18n.t("old")}</option>

View file

@ -15,7 +15,7 @@ export class EmojiMart extends Component<EmojiMartProps> {
const div: any = document.getElementById("emoji-picker");
if (div) {
div.appendChild(
getEmojiMart(this.handleEmojiClick, this.props.pickerOptions)
getEmojiMart(this.handleEmojiClick, this.props.pickerOptions),
);
}
}

View file

@ -50,10 +50,10 @@ export class HtmlTags extends Component<HtmlTagsProps, any> {
name={n}
content={htmlToText(md.renderInline(desc))}
/>
)
),
)}
{["og:image", "twitter:image"].map(
p => image && <meta key={p} property={p} content={image} />
p => image && <meta key={p} property={p} content={image} />,
)}
</Helmet>
);

View file

@ -53,12 +53,12 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
<label
className={classNames(
"col-form-label",
`col-sm-${this.props.multiple ? 3 : 2}`
`col-sm-${this.props.multiple ? 3 : 2}`,
)}
htmlFor={this.id}
>
{I18NextService.i18n.t(
this.props.multiple ? "language_plural" : "language"
this.props.multiple ? "language_plural" : "language",
)}
</label>
{this.props.multiple && this.props.showLanguageWarning && (
@ -97,7 +97,7 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
this.props.siteLanguages,
this.props.showAll,
this.props.showSite,
UserService.Instance.myUserInfo
UserService.Instance.myUserInfo,
);
return (

View file

@ -30,7 +30,7 @@ export class ListingTypeSelect extends Component<
}
static getDerivedStateFromProps(
props: ListingTypeSelectProps
props: ListingTypeSelectProps,
): ListingTypeSelectState {
return {
type_: props.type_,

View file

@ -1,4 +1,4 @@
import { isBrowser } from "@utils/browser";
import { isBrowser, platform } from "@utils/browser";
import { numToSI, randomStr } from "@utils/helpers";
import autosize from "autosize";
import classNames from "classnames";
@ -21,7 +21,6 @@ import { EmojiPicker } from "./emoji-picker";
import { Icon, Spinner } from "./icon";
import { LanguageSelect } from "./language-select";
import ProgressBar from "./progress-bar";
interface MarkdownTextAreaProps {
/**
* Initial content inside the textarea
@ -202,7 +201,7 @@ export class MarkdownTextArea extends Component<
{this.getFormatButton("header", this.handleInsertHeader)}
{this.getFormatButton(
"strikethrough",
this.handleInsertStrikethrough
this.handleInsertStrikethrough,
)}
{this.getFormatButton("quote", this.handleInsertQuote)}
{this.getFormatButton("list", this.handleInsertList)}
@ -210,7 +209,7 @@ export class MarkdownTextArea extends Component<
{this.getFormatButton("subscript", this.handleInsertSubscript)}
{this.getFormatButton(
"superscript",
this.handleInsertSuperscript
this.handleInsertSuperscript,
)}
{this.getFormatButton("spoiler", this.handleInsertSpoiler)}
<a
@ -230,7 +229,7 @@ export class MarkdownTextArea extends Component<
"form-control border-0 rounded-top-0 rounded-bottom",
{
"d-none": this.state.previewMode,
}
},
)}
value={this.state.content}
onInput={linkEvent(this, this.handleContentChange)}
@ -329,7 +328,7 @@ export class MarkdownTextArea extends Component<
getFormatButton(
type: NoOptionI18nKeys,
handleClick: (i: MarkdownTextArea, event: any) => void
handleClick: (i: MarkdownTextArea, event: any) => void,
) {
let iconType: string;
@ -361,7 +360,7 @@ export class MarkdownTextArea extends Component<
handleEmoji(i: MarkdownTextArea, e: any) {
let value = e.native;
if (value == null) {
if (value === null) {
const emoji = customEmojisLookup.get(e.id)?.custom_emoji;
if (emoji) {
value = `![${emoji.alt_text}](${emoji.image_url} "${emoji.shortcode}")`;
@ -397,7 +396,7 @@ export class MarkdownTextArea extends Component<
count: Number(maxUploadImages),
formattedCount: numToSI(maxUploadImages),
}),
"danger"
"danger",
);
} else {
i.setState({
@ -425,7 +424,7 @@ export class MarkdownTextArea extends Component<
uploaded: (imageUploadStatus?.uploaded ?? 0) + 1,
},
}));
})
}),
);
} catch (e) {
errorOccurred = true;
@ -477,7 +476,7 @@ export class MarkdownTextArea extends Component<
// Keybind handler
// Keybinds inspired by github comment area
handleKeyBinds(i: MarkdownTextArea, event: KeyboardEvent) {
if (event.ctrlKey || event.metaKey) {
if (platform.isMac() ? event.metaKey : event.ctrlKey) {
switch (event.key) {
case "k": {
i.handleInsertLink(i, event);
@ -561,7 +560,7 @@ export class MarkdownTextArea extends Component<
i.setState({
content: `${content?.substring(
0,
start
start,
)}[${selectedText}]()${content?.substring(end)}`,
});
textarea.focus();
@ -585,7 +584,7 @@ export class MarkdownTextArea extends Component<
simpleSurroundBeforeAfter(
beforeChars: string,
afterChars: string,
emptyChars = "___"
emptyChars = "___",
) {
const content = this.state.content ?? "";
if (!this.state.content) {
@ -600,7 +599,7 @@ export class MarkdownTextArea extends Component<
this.setState({
content: `${content?.substring(
0,
start
start,
)}${beforeChars}${selectedText}${afterChars}${content?.substring(end)}`,
});
} else {
@ -615,12 +614,12 @@ export class MarkdownTextArea extends Component<
if (start !== end) {
textarea.setSelectionRange(
start + beforeChars.length,
end + afterChars.length
end + afterChars.length,
);
} else {
textarea.setSelectionRange(
start + beforeChars.length,
end + emptyChars.length + afterChars.length
end + emptyChars.length + afterChars.length,
);
}

View file

@ -25,11 +25,11 @@ export class MomentTime extends Component<MomentTimeProps, any> {
createdAndModifiedTimes() {
const updated = this.props.updated;
let line = `${capitalizeFirstLetter(
I18NextService.i18n.t("created")
I18NextService.i18n.t("created"),
)}: ${formatDate(this.props.published)}`;
if (updated) {
line += `\n\n\n${capitalizeFirstLetter(
I18NextService.i18n.t("modified")
I18NextService.i18n.t("modified"),
)} ${formatDate(updated)}`;
}
return line;

View file

@ -15,7 +15,7 @@ export class Paginator extends Component<PaginatorProps, any> {
<div className="paginator my-2">
<button
className="btn btn-secondary me-2"
disabled={this.props.page == 1}
disabled={this.props.page === 1}
onClick={linkEvent(this, this.handlePrev)}
>
{I18NextService.i18n.t("prev")}

View file

@ -104,10 +104,10 @@ class PasswordInput extends Component<PasswordInputProps, PasswordInputState> {
id={id}
onClick={linkEvent(this, handleToggleShow)}
aria-label={I18NextService.i18n.t(
`${show ? "show" : "hide"}_password`
`${show ? "show" : "hide"}_password`,
)}
data-tippy-content={I18NextService.i18n.t(
`${show ? "show" : "hide"}_password`
`${show ? "show" : "hide"}_password`,
)}
>
<Icon icon={`eye${show ? "-slash" : ""}`} inline />
@ -116,7 +116,7 @@ class PasswordInput extends Component<PasswordInputProps, PasswordInputState> {
{showStrength && value && (
<div className={this.passwordColorClass}>
{I18NextService.i18n.t(
this.passwordStrength as NoOptionI18nKeys
this.passwordStrength as NoOptionI18nKeys,
)}
</div>
)}
@ -146,7 +146,7 @@ class PasswordInput extends Component<PasswordInputProps, PasswordInputState> {
if (strength && ["weak", "medium"].includes(strength)) {
return "text-warning";
} else if (strength == "strong") {
} else if (strength === "strong") {
return "text-success";
} else {
return "text-danger";

View file

@ -56,7 +56,7 @@ export class PictrsImage extends Component<PictrsImageProps, any> {
const split = this.props.src.split("/pictrs/image/");
// If theres not multiple, then its not a pictrs image
if (split.length == 1) {
if (split.length === 1) {
return this.props.src;
}

View file

@ -42,9 +42,9 @@ export class RegistrationApplication extends Component<
componentWillReceiveProps(
nextProps: Readonly<
{ children?: InfernoNode } & RegistrationApplicationProps
>
>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState({
denyExpanded: false,
approveLoading: false,

View file

@ -83,7 +83,7 @@ export class SearchableSelect extends Component<
if (props.value) {
let selectedIndex = props.options.findIndex(
({ value }) => value === props.value?.toString()
({ value }) => value === props.value?.toString(),
);
if (selectedIndex < 0) {
@ -140,7 +140,7 @@ export class SearchableSelect extends Component<
(onSearch || searchText.length === 0
? options
: options.filter(({ label }) =>
label.toLowerCase().includes(searchText.toLowerCase())
label.toLowerCase().includes(searchText.toLowerCase()),
)
).map((option, index) => (
<button

View file

@ -54,6 +54,9 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
{I18NextService.i18n.t("active")}
</option>,
]}
<option value={"Controversial"}>
{I18NextService.i18n.t("controversial")}
</option>
<option value={"New"}>{I18NextService.i18n.t("new")}</option>
<option value={"Old"}>{I18NextService.i18n.t("old")}</option>
{!this.props.hideMostComments && [

View file

@ -45,7 +45,7 @@ export class UserBadges extends Component<UserBadgesProps> {
<span
className={classNames(
"row d-inline-flex gx-1",
this.props.classNames
this.props.classNames,
)}
>
{this.props.isBanned && (

View file

@ -193,7 +193,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
<button
type="button"
className={`btn-animate btn btn-link p-0 ${
this.props.my_vote == 1 ? "text-info" : "text-muted"
this.props.my_vote === 1 ? "text-info" : "text-muted"
}`}
onClick={linkEvent(this, handleUpvote)}
data-tippy-content={I18NextService.i18n.t("upvote")}
@ -220,7 +220,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
<button
type="button"
className={`btn-animate btn btn-link p-0 ${
this.props.my_vote == -1 ? "text-danger" : "text-muted"
this.props.my_vote === -1 ? "text-danger" : "text-muted"
}`}
onClick={linkEvent(this, handleDownvote)}
data-tippy-content={I18NextService.i18n.t("downvote")}

View file

@ -172,7 +172,7 @@ export class Communities extends Component<any, CommunitiesState> {
{numToSI(cv.counts.comments)}
</td>
<td className="text-right">
{cv.subscribed == "Subscribed" && (
{cv.subscribed === "Subscribed" && (
<button
className="btn btn-link d-inline-block"
onClick={linkEvent(
@ -181,7 +181,7 @@ export class Communities extends Component<any, CommunitiesState> {
communityId: cv.community.id,
follow: false,
},
this.handleFollow
this.handleFollow,
)}
>
{I18NextService.i18n.t("unsubscribe")}
@ -196,7 +196,7 @@ export class Communities extends Component<any, CommunitiesState> {
communityId: cv.community.id,
follow: true,
},
this.handleFollow
this.handleFollow,
)}
>
{I18NextService.i18n.t("subscribe")}
@ -209,7 +209,7 @@ export class Communities extends Component<any, CommunitiesState> {
)}
</td>
</tr>
)
),
)}
</tbody>
</table>
@ -301,7 +301,7 @@ export class Communities extends Component<any, CommunitiesState> {
event.preventDefault();
const searchParamEncoded = encodeURIComponent(i.state.searchText);
i.context.router.history.push(
`/search?q=${searchParamEncoded}&type=Communities`
`/search?q=${searchParamEncoded}&type=Communities`,
);
}
@ -322,7 +322,7 @@ export class Communities extends Component<any, CommunitiesState> {
return {
listCommunitiesResponse: await client.listCommunities(
listCommunitiesForm
listCommunitiesForm,
),
};
}
@ -369,12 +369,12 @@ export class Communities extends Component<any, CommunitiesState> {
findAndUpdateCommunity(res: RequestState<CommunityResponse>) {
this.setState(s => {
if (
s.listCommunitiesResponse.state == "success" &&
res.state == "success"
s.listCommunitiesResponse.state === "success" &&
res.state === "success"
) {
s.listCommunitiesResponse.data.communities = editCommunity(
res.data.community_view,
s.listCommunitiesResponse.data.communities
s.listCommunitiesResponse.data.communities,
);
}
return s;

View file

@ -231,7 +231,7 @@ export class CommunityForm extends Component<
checked={this.state.form.posting_restricted_to_mods}
onChange={linkEvent(
this,
this.handleCommunityPostingRestrictedToMods
this.handleCommunityPostingRestrictedToMods,
)}
/>
</div>
@ -330,7 +330,7 @@ export class CommunityForm extends Component<
handleCommunityPostingRestrictedToMods(i: CommunityForm, event: any) {
i.setState(
s => ((s.form.posting_restricted_to_mods = event.target.checked), s)
s => ((s.form.posting_restricted_to_mods = event.target.checked), s),
);
}

View file

@ -22,7 +22,7 @@ export class CommunityLink extends Component<CommunityLinkProps, any> {
render() {
const community = this.props.community;
let name_: string, title: string, link: string;
const local = community.local == null ? true : community.local;
const local = community.local === null ? true : community.local;
if (local) {
name_ = community.name;
title = community.title;

View file

@ -62,6 +62,7 @@ import {
LockPost,
MarkCommentReplyAsRead,
MarkPersonMentionAsRead,
MarkPostAsRead,
PostResponse,
PurgeComment,
PurgeCommunity,
@ -195,6 +196,7 @@ export class Community extends Component<
this.handleSavePost = this.handleSavePost.bind(this);
this.handlePurgePost = this.handlePurgePost.bind(this);
this.handleFeaturePost = this.handleFeaturePost.bind(this);
this.handleMarkPostAsRead = this.handleMarkPostAsRead.bind(this);
this.mainContentRef = createRef();
// Only fetch the data if coming from another route
if (FirstLoadService.isFirstLoad) {
@ -290,7 +292,7 @@ export class Community extends Component<
get documentTitle(): string {
const cRes = this.state.communityRes;
return cRes.state == "success"
return cRes.state === "success"
? `${cRes.data.community_view.community.title} - ${this.isoData.site_res.site_view.site.name}`
: "";
}
@ -431,6 +433,7 @@ export class Community extends Component<
onAddAdmin={this.handleAddAdmin}
onTransferCommunity={this.handleTransferCommunity}
onFeaturePost={this.handleFeaturePost}
onMarkPostAsRead={this.handleMarkPostAsRead}
/>
);
}
@ -570,7 +573,7 @@ export class Community extends Component<
};
this.props.history.push(
`/c/${this.props.match.params.name}${getQueryString(queryParams)}`
`/c/${this.props.match.params.name}${getQueryString(queryParams)}`,
);
await this.fetchData();
@ -626,11 +629,11 @@ export class Community extends Component<
this.updateCommunity(followCommunityRes);
// Update myUserInfo
if (followCommunityRes.state == "success") {
if (followCommunityRes.state === "success") {
const communityId = followCommunityRes.data.community_view.community.id;
const mui = UserService.Instance.myUserInfo;
if (mui) {
mui.follows = mui.follows.filter(i => i.community.id != communityId);
mui.follows = mui.follows.filter(i => i.community.id !== communityId);
}
}
}
@ -657,10 +660,10 @@ export class Community extends Component<
async handleBlockCommunity(form: BlockCommunity) {
const blockCommunityRes = await HttpService.client.blockCommunity(form);
if (blockCommunityRes.state == "success") {
if (blockCommunityRes.state === "success") {
updateCommunityBlock(blockCommunityRes.data);
this.setState(s => {
if (s.communityRes.state == "success") {
if (s.communityRes.state === "success") {
s.communityRes.data.community_view.blocked =
blockCommunityRes.data.blocked;
}
@ -670,7 +673,7 @@ export class Community extends Component<
async handleBlockPerson(form: BlockPerson) {
const blockPersonRes = await HttpService.client.blockPerson(form);
if (blockPersonRes.state == "success") {
if (blockPersonRes.state === "success") {
updatePersonBlock(blockPersonRes.data);
}
}
@ -753,14 +756,14 @@ export class Community extends Component<
async handleCommentReport(form: CreateCommentReport) {
const reportRes = await HttpService.client.createCommentReport(form);
if (reportRes.state == "success") {
if (reportRes.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
async handlePostReport(form: CreatePostReport) {
const reportRes = await HttpService.client.createPostReport(form);
if (reportRes.state == "success") {
if (reportRes.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
@ -778,14 +781,14 @@ export class Community extends Component<
async handleAddAdmin(form: AddAdmin) {
const addAdminRes = await HttpService.client.addAdmin(form);
if (addAdminRes.state == "success") {
if (addAdminRes.state === "success") {
this.setState(s => ((s.siteRes.admins = addAdminRes.data.admins), s));
}
}
async handleTransferCommunity(form: TransferCommunity) {
const transferCommunityRes = await HttpService.client.transferCommunity(
form
form,
);
toast(I18NextService.i18n.t("transfer_community"));
this.updateCommunityFull(transferCommunityRes);
@ -801,6 +804,11 @@ export class Community extends Component<
await HttpService.client.markPersonMentionAsRead(form);
}
async handleMarkPostAsRead(form: MarkPostAsRead) {
const res = await HttpService.client.markPostAsRead(form);
this.findAndUpdatePost(res);
}
async handleBanFromCommunity(form: BanFromCommunity) {
const banRes = await HttpService.client.banFromCommunity(form);
this.updateBanFromCommunity(banRes);
@ -813,20 +821,20 @@ export class Community extends Component<
updateBanFromCommunity(banRes: RequestState<BanFromCommunityResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.postsRes.state == "success") {
if (s.postsRes.state === "success") {
s.postsRes.data.posts
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
if (s.commentsRes.state == "success") {
if (s.commentsRes.state === "success") {
s.commentsRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
return s;
@ -836,16 +844,16 @@ export class Community extends Component<
updateBan(banRes: RequestState<BanPersonResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.postsRes.state == "success") {
if (s.postsRes.state === "success") {
s.postsRes.data.posts
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
if (s.commentsRes.state == "success") {
if (s.commentsRes.state === "success") {
s.commentsRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
return s;
@ -855,7 +863,7 @@ export class Community extends Component<
updateCommunity(res: RequestState<CommunityResponse>) {
this.setState(s => {
if (s.communityRes.state == "success" && res.state == "success") {
if (s.communityRes.state === "success" && res.state === "success") {
s.communityRes.data.community_view = res.data.community_view;
s.communityRes.data.discussion_languages =
res.data.discussion_languages;
@ -866,7 +874,7 @@ export class Community extends Component<
updateCommunityFull(res: RequestState<GetCommunityResponse>) {
this.setState(s => {
if (s.communityRes.state == "success" && res.state == "success") {
if (s.communityRes.state === "success" && res.state === "success") {
s.communityRes.data.community_view = res.data.community_view;
s.communityRes.data.moderators = res.data.moderators;
}
@ -875,7 +883,7 @@ export class Community extends Component<
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
if (purgeRes.state === "success") {
toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
@ -883,10 +891,10 @@ export class Community extends Component<
findAndUpdateComment(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments = editComment(
res.data.comment_view,
s.commentsRes.data.comments
s.commentsRes.data.comments,
);
s.finished.set(res.data.comment_view.comment.id, true);
}
@ -896,13 +904,13 @@ export class Community extends Component<
createAndUpdateComments(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments.unshift(res.data.comment_view);
// Set finished for the parent
s.finished.set(
getCommentParentId(res.data.comment_view.comment) ?? 0,
true
true,
);
}
return s;
@ -911,10 +919,10 @@ export class Community extends Component<
findAndUpdateCommentReply(res: RequestState<CommentReplyResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments = editWith(
res.data.comment_reply_view,
s.commentsRes.data.comments
s.commentsRes.data.comments,
);
}
return s;
@ -923,10 +931,10 @@ export class Community extends Component<
findAndUpdatePost(res: RequestState<PostResponse>) {
this.setState(s => {
if (s.postsRes.state == "success" && res.state == "success") {
if (s.postsRes.state === "success" && res.state === "success") {
s.postsRes.data.posts = editPost(
res.data.post_view,
s.postsRes.data.posts
s.postsRes.data.posts,
);
}
return s;
@ -936,7 +944,7 @@ export class Community extends Component<
updateModerators(res: RequestState<AddModToCommunityResponse>) {
// Update the moderators
this.setState(s => {
if (s.communityRes.state == "success" && res.state == "success") {
if (s.communityRes.state === "success" && res.state === "success") {
s.communityRes.data.moderators = res.data.moderators;
}
return s;

View file

@ -79,15 +79,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & SidebarProps>
nextProps: Readonly<{ children?: InfernoNode } & SidebarProps>,
): void {
if (this.props.moderators != nextProps.moderators) {
if (this.props.moderators !== nextProps.moderators) {
this.setState({
showConfirmLeaveModTeam: false,
});
}
if (this.props.community_view != nextProps.community_view) {
if (this.props.community_view !== nextProps.community_view) {
this.setState({
showEdit: false,
showPurgeDialog: false,
@ -292,7 +292,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
onClick={linkEvent(this, this.handleBlockCommunity)}
>
{I18NextService.i18n.t(
blocked ? "unblock_community" : "block_community"
blocked ? "unblock_community" : "block_community",
)}
</button>
)
@ -332,7 +332,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
className="btn btn-link text-muted d-inline-block"
onClick={linkEvent(
this,
this.handleShowConfirmLeaveModTeamClick
this.handleShowConfirmLeaveModTeamClick,
)}
>
{I18NextService.i18n.t("leave_mod_team")}
@ -356,7 +356,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
className="btn btn-link text-muted d-inline-block"
onClick={linkEvent(
this,
this.handleCancelLeaveModTeamClick
this.handleCancelLeaveModTeamClick,
)}
>
{I18NextService.i18n.t("no")}

View file

@ -274,7 +274,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
onClick={linkEvent(this, this.handleLeaveAdminTeam)}
className="btn btn-danger mb-2"
>
{this.state.leaveAdminTeamRes.state == "loading" ? (
{this.state.leaveAdminTeamRes.state === "loading" ? (
<Spinner />
) : (
I18NextService.i18n.t("leave_admin_team")

View file

@ -11,7 +11,6 @@ import { customEmojisLookup } from "../../markdown";
import { HttpService, I18NextService } from "../../services";
import { pictrsDeleteToast, toast } from "../../toast";
import { EmojiMart } from "../common/emoji-mart";
import { HtmlTags } from "../common/html-tags";
import { Icon, Spinner } from "../common/icon";
import { Paginator } from "../common/paginator";
@ -66,17 +65,9 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
this.handlePageChange = this.handlePageChange.bind(this);
this.handleEmojiClick = this.handleEmojiClick.bind(this);
}
get documentTitle(): string {
return I18NextService.i18n.t("custom_emojis");
}
render() {
return (
<div className="home-emojis-form col-12">
<HtmlTags
title={this.documentTitle}
path={this.context.router.route.match.url}
/>
<h1 className="h4 mb-4">{I18NextService.i18n.t("custom_emojis")}</h1>
{customEmojisLookup.size > 0 && (
<div>
@ -118,8 +109,8 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
Number((this.state.page - 1) * this.itemsPerPage),
Number(
(this.state.page - 1) * this.itemsPerPage +
this.itemsPerPage
)
this.itemsPerPage,
),
)
.map((cv, index) => (
<tr key={index} ref={e => (this.scrollRef[cv.shortcode] = e)}>
@ -139,11 +130,11 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
className="btn btn-sm btn-secondary pointer"
htmlFor={`file-uploader-${index}`}
data-tippy-content={I18NextService.i18n.t(
"upload_image"
"upload_image",
)}
>
{capitalizeFirstLetter(
I18NextService.i18n.t("upload")
I18NextService.i18n.t("upload"),
)}
<input
name={`file-uploader-${index}`}
@ -153,7 +144,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
className="d-none"
onChange={linkEvent(
{ form: this, index: index },
this.handleImageUpload
this.handleImageUpload,
)}
/>
</label>
@ -168,7 +159,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
value={cv.shortcode}
onInput={linkEvent(
{ form: this, index: index },
this.handleEmojiShortCodeChange
this.handleEmojiShortCodeChange,
)}
/>
</td>
@ -180,7 +171,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
value={cv.category}
onInput={linkEvent(
{ form: this, index: index },
this.handleEmojiCategoryChange
this.handleEmojiCategoryChange,
)}
/>
</td>
@ -192,7 +183,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
value={cv.image_url}
onInput={linkEvent(
{ form: this, index: index, overrideValue: null },
this.handleEmojiImageUrlChange
this.handleEmojiImageUrlChange,
)}
/>
</td>
@ -204,7 +195,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
value={cv.alt_text}
onInput={linkEvent(
{ form: this, index: index },
this.handleEmojiAltTextChange
this.handleEmojiAltTextChange,
)}
/>
</td>
@ -216,7 +207,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
value={cv.keywords}
onInput={linkEvent(
{ form: this, index: index },
this.handleEmojiKeywordChange
this.handleEmojiKeywordChange,
)}
/>
</td>
@ -231,7 +222,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
}
onClick={linkEvent(
{ i: this, cv: cv },
this.handleEditEmojiClick
this.handleEditEmojiClick,
)}
data-tippy-content={I18NextService.i18n.t("save")}
aria-label={I18NextService.i18n.t("save")}
@ -241,7 +232,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
<Spinner />
) : (
capitalizeFirstLetter(
I18NextService.i18n.t("save")
I18NextService.i18n.t("save"),
)
)}
</button>
@ -250,7 +241,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
{ i: this, index: index, cv: cv },
this.handleDeleteEmojiClick
this.handleDeleteEmojiClick,
)}
data-tippy-content={I18NextService.i18n.t("delete")}
aria-label={I18NextService.i18n.t("delete")}
@ -290,8 +281,8 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
cv.shortcode.length > 0;
const noDuplicateShortCodes =
this.state.customEmojis.filter(
x => x.shortcode == cv.shortcode && x.id != cv.id
).length == 0;
x => x.shortcode === cv.shortcode && x.id !== cv.id,
).length === 0;
return noEmptyFields && noDuplicateShortCodes && !cv.loading && cv.changed;
}
@ -308,7 +299,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
const view = customEmojisLookup.get(e.id);
if (view) {
const page = this.state.customEmojis.find(
x => x.id == view.custom_emoji.id
x => x.id === view.custom_emoji.id,
)?.page;
if (page) {
this.setState({ page: page });
@ -319,7 +310,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
handleEmojiCategoryChange(
props: { form: EmojiForm; index: number },
event: any
event: any,
) {
const custom_emojis = [...props.form.state.customEmojis];
const pagedIndex =
@ -335,7 +326,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
handleEmojiShortCodeChange(
props: { form: EmojiForm; index: number },
event: any
event: any,
) {
const custom_emojis = [...props.form.state.customEmojis];
const pagedIndex =
@ -355,7 +346,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
index,
overrideValue,
}: { form: EmojiForm; index: number; overrideValue: string | null },
event: any
event: any,
) {
form.setState(prevState => {
const custom_emojis = [...form.state.customEmojis];
@ -376,7 +367,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
changed: true,
loading: false,
}
: ce
: ce,
),
};
});
@ -384,7 +375,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
handleEmojiAltTextChange(
props: { form: EmojiForm; index: number },
event: any
event: any,
) {
const custom_emojis = [...props.form.state.customEmojis];
const pagedIndex =
@ -400,7 +391,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
handleEmojiKeywordChange(
props: { form: EmojiForm; index: number },
event: any
event: any,
) {
const custom_emojis = [...props.form.state.customEmojis];
const pagedIndex =
@ -420,7 +411,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
cv: CustomEmojiViewForm;
}) {
const pagedIndex = (d.i.state.page - 1) * d.i.itemsPerPage + d.index;
if (d.cv.id != 0) {
if (d.cv.id !== 0) {
d.i.props.onDelete({
id: d.cv.id,
auth: myAuthRequired(),
@ -485,7 +476,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
handleImageUpload(
{ form, index }: { form: EmojiForm; index: number },
event: any
event: any,
) {
let file: any;
if (event.target) {
@ -498,7 +489,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
form.setState(prevState => ({
...prevState,
customEmojis: prevState.customEmojis.map((cv, i) =>
i === index ? { ...cv, loading: true } : cv
i === index ? { ...cv, loading: true } : cv,
),
}));
@ -510,7 +501,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
pictrsDeleteToast(file.name, res.data.delete_url as string);
form.handleEmojiImageUrlChange(
{ form: form, index: index, overrideValue: res.data.url as string },
event
event,
);
} else if (res.data.msg === "too_large") {
toast(I18NextService.i18n.t("upload_too_large"), "danger");

View file

@ -59,6 +59,7 @@ import {
LockPost,
MarkCommentReplyAsRead,
MarkPersonMentionAsRead,
MarkPostAsRead,
PostResponse,
PurgeComment,
PurgeItemResponse,
@ -268,6 +269,7 @@ export class Home extends Component<any, HomeState> {
this.handleSavePost = this.handleSavePost.bind(this);
this.handlePurgePost = this.handlePurgePost.bind(this);
this.handleFeaturePost = this.handleFeaturePost.bind(this);
this.handleMarkPostAsRead = this.handleMarkPostAsRead.bind(this);
// Only fetch the data if coming from another route
if (FirstLoadService.isFirstLoad) {
@ -285,9 +287,8 @@ export class Home extends Component<any, HomeState> {
HomeCacheService.postsRes = postsRes;
}
this.state.tagline = getRandomFromList(
this.state?.siteRes?.taglines ?? []
)?.content;
this.state.tagline = getRandomFromList(this.state?.siteRes?.taglines ?? [])
?.content;
}
componentWillUnmount() {
@ -298,7 +299,7 @@ export class Home extends Component<any, HomeState> {
if (
!this.state.isIsomorphic ||
!Object.values(this.isoData.routeData).some(
res => res.state === "success" || res.state === "failed"
res => res.state === "success" || res.state === "failed",
)
) {
await Promise.all([this.fetchTrendingCommunities(), this.fetchData()]);
@ -359,7 +360,7 @@ export class Home extends Component<any, HomeState> {
return {
trendingCommunitiesRes: await client.listCommunities(
trendingCommunitiesForm
trendingCommunitiesForm,
),
commentsRes,
postsRes,
@ -699,6 +700,7 @@ export class Home extends Component<any, HomeState> {
onAddAdmin={this.handleAddAdmin}
onTransferCommunity={this.handleTransferCommunity}
onFeaturePost={this.handleFeaturePost}
onMarkPostAsRead={this.handleMarkPostAsRead}
/>
);
}
@ -777,7 +779,7 @@ export class Home extends Component<any, HomeState> {
<div className="col-auto ps-0">
{getRss(
listingType ??
this.state.siteRes.site_view.local_site.default_post_listing_type
this.state.siteRes.site_view.local_site.default_post_listing_type,
)}
</div>
</div>
@ -900,7 +902,7 @@ export class Home extends Component<any, HomeState> {
async handleBlockPerson(form: BlockPerson) {
const blockPersonRes = await HttpService.client.blockPerson(form);
if (blockPersonRes.state == "success") {
if (blockPersonRes.state === "success") {
updatePersonBlock(blockPersonRes.data);
}
}
@ -971,14 +973,14 @@ export class Home extends Component<any, HomeState> {
async handleCommentReport(form: CreateCommentReport) {
const reportRes = await HttpService.client.createCommentReport(form);
if (reportRes.state == "success") {
if (reportRes.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
async handlePostReport(form: CreatePostReport) {
const reportRes = await HttpService.client.createPostReport(form);
if (reportRes.state == "success") {
if (reportRes.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
@ -996,7 +998,7 @@ export class Home extends Component<any, HomeState> {
async handleAddAdmin(form: AddAdmin) {
const addAdminRes = await HttpService.client.addAdmin(form);
if (addAdminRes.state == "success") {
if (addAdminRes.state === "success") {
this.setState(s => ((s.siteRes.admins = addAdminRes.data.admins), s));
}
}
@ -1026,22 +1028,27 @@ export class Home extends Component<any, HomeState> {
this.updateBan(banRes);
}
async handleMarkPostAsRead(form: MarkPostAsRead) {
const res = await HttpService.client.markPostAsRead(form);
this.findAndUpdatePost(res);
}
updateBanFromCommunity(banRes: RequestState<BanFromCommunityResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.postsRes.state == "success") {
if (s.postsRes.state === "success") {
s.postsRes.data.posts
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
if (s.commentsRes.state == "success") {
if (s.commentsRes.state === "success") {
s.commentsRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
return s;
@ -1051,16 +1058,16 @@ export class Home extends Component<any, HomeState> {
updateBan(banRes: RequestState<BanPersonResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.postsRes.state == "success") {
if (s.postsRes.state === "success") {
s.postsRes.data.posts
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
if (s.commentsRes.state == "success") {
if (s.commentsRes.state === "success") {
s.commentsRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
return s;
@ -1069,7 +1076,7 @@ export class Home extends Component<any, HomeState> {
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
if (purgeRes.state === "success") {
toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
@ -1077,10 +1084,10 @@ export class Home extends Component<any, HomeState> {
findAndUpdateComment(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments = editComment(
res.data.comment_view,
s.commentsRes.data.comments
s.commentsRes.data.comments,
);
s.finished.set(res.data.comment_view.comment.id, true);
}
@ -1090,13 +1097,13 @@ export class Home extends Component<any, HomeState> {
createAndUpdateComments(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments.unshift(res.data.comment_view);
// Set finished for the parent
s.finished.set(
getCommentParentId(res.data.comment_view.comment) ?? 0,
true
true,
);
}
return s;
@ -1105,10 +1112,10 @@ export class Home extends Component<any, HomeState> {
findAndUpdateCommentReply(res: RequestState<CommentReplyResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments = editWith(
res.data.comment_reply_view,
s.commentsRes.data.comments
s.commentsRes.data.comments,
);
}
return s;
@ -1117,10 +1124,10 @@ export class Home extends Component<any, HomeState> {
findAndUpdatePost(res: RequestState<PostResponse>) {
this.setState(s => {
if (s.postsRes.state == "success" && res.state == "success") {
if (s.postsRes.state === "success" && res.state === "success") {
s.postsRes.data.posts = editPost(
res.data.post_view,
s.postsRes.data.posts
s.postsRes.data.posts,
);
}
return s;

View file

@ -38,7 +38,7 @@ export class LoginReset extends Component<any, State> {
get documentTitle(): string {
return `${capitalizeFirstLetter(
I18NextService.i18n.t("forgot_password")
I18NextService.i18n.t("forgot_password"),
)} - ${this.state.siteRes.site_view.site.name}`;
}
@ -127,7 +127,7 @@ export class LoginReset extends Component<any, State> {
const res = await HttpService.client.passwordReset({ email });
if (res.state == "success") {
if (res.state === "success") {
toast(I18NextService.i18n.t("reset_password_mail_sent"));
i.context.router.history.push("/login");
}

View file

@ -48,7 +48,7 @@ export class Login extends Component<any, State> {
}
get isLemmyMl(): boolean {
return isBrowser() && window.location.hostname == "lemmy.ml";
return isBrowser() && window.location.hostname === "lemmy.ml";
}
render() {
@ -124,7 +124,7 @@ export class Login extends Component<any, State> {
<div className="mb-3 row">
<div className="col-sm-10">
<button type="submit" className="btn btn-secondary">
{this.state.loginRes.state == "loading" ? (
{this.state.loginRes.state === "loading" ? (
<Spinner />
) : (
I18NextService.i18n.t("login")

View file

@ -88,7 +88,7 @@ function RateLimits({
function handleRateLimitChange(
{ rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm },
event: any
event: any,
) {
ctx.setState(prev => ({
...prev,
@ -101,7 +101,7 @@ function handleRateLimitChange(
function handlePerSecondChange(
{ rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm },
event: any
event: any,
) {
ctx.setState(prev => ({
...prev,
@ -122,7 +122,7 @@ function submitRateLimitForm(i: RateLimitsForm, event: any) {
},
{
auth,
}
},
);
i.props.onSaveSite(form);
@ -159,11 +159,11 @@ export default class RateLimitsForm extends Component<
})}
handleRateLimit={linkEvent(
{ rateLimitType, ctx: this },
handleRateLimitChange
handleRateLimitChange,
)}
handleRateLimitPerSecond={linkEvent(
{ rateLimitType, ctx: this },
handlePerSecondChange
handlePerSecondChange,
)}
rateLimitValue={this.state.form[rateLimitType]}
rateLimitPerSecondValue={

View file

@ -141,7 +141,7 @@ export class Setup extends Component<any, State> {
<div className="mb-3 row">
<div className="col-sm-10">
<button type="submit" className="btn btn-secondary">
{this.state.registerRes.state == "loading" ? (
{this.state.registerRes.state === "loading" ? (
<Spinner />
) : (
I18NextService.i18n.t("sign_up")
@ -184,7 +184,7 @@ export class Setup extends Component<any, State> {
registerRes: await HttpService.client.register(form),
});
if (i.state.registerRes.state == "success") {
if (i.state.registerRes.state === "success") {
const data = i.state.registerRes.data;
UserService.Instance.login({ res: data });

View file

@ -71,7 +71,7 @@ export class Signup extends Component<any, State> {
});
this.setState(s => {
if (s.captchaRes.state == "success") {
if (s.captchaRes.state === "success") {
s.form.captcha_uuid = s.captchaRes.data.ok?.uuid;
}
return s;
@ -85,12 +85,12 @@ export class Signup extends Component<any, State> {
titleName(siteView: SiteView): string {
return I18NextService.i18n.t(
siteView.local_site.private_instance ? "apply_to_join" : "sign_up"
siteView.local_site.private_instance ? "apply_to_join" : "sign_up",
);
}
get isLemmyMl(): boolean {
return isBrowser() && window.location.hostname == "lemmy.ml";
return isBrowser() && window.location.hostname === "lemmy.ml";
}
render() {
@ -213,7 +213,7 @@ export class Signup extends Component<any, State> {
<div
className="md-div"
dangerouslySetInnerHTML={mdToHtml(
siteView.local_site.application_question
siteView.local_site.application_question,
)}
/>
)}
@ -269,7 +269,7 @@ export class Signup extends Component<any, State> {
<div className="mb-3 row">
<div className="col-sm-10">
<button type="submit" className="btn btn-secondary">
{this.state.registerRes.state == "loading" ? (
{this.state.registerRes.state === "loading" ? (
<Spinner />
) : (
this.titleName(siteView)
@ -311,7 +311,7 @@ export class Signup extends Component<any, State> {
value={this.state.form.captcha_answer}
onInput={linkEvent(
this,
this.handleRegisterCaptchaAnswerChange
this.handleRegisterCaptchaAnswerChange,
)}
required
/>
@ -424,7 +424,7 @@ export class Signup extends Component<any, State> {
handleRegisterEmailChange(i: Signup, event: any) {
i.state.form.email = event.target.value;
if (i.state.form.email == "") {
if (i.state.form.email === "") {
i.state.form.email = undefined;
}
i.setState(i.state);
@ -469,7 +469,7 @@ export class Signup extends Component<any, State> {
// This was a bad bug, it should only build the new audio on a new file.
// Replays would stop prematurely if this was rebuilt every time.
if (i.state.captchaRes.state == "success" && i.state.captchaRes.data.ok) {
if (i.state.captchaRes.state === "success" && i.state.captchaRes.data.ok) {
const captchaRes = i.state.captchaRes.data.ok;
if (!i.audio) {
const base64 = `data:audio/wav;base64,${captchaRes.wav}`;

View file

@ -293,7 +293,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
</select>
</div>
</div>
{this.state.siteForm.registration_mode == "RequireApplication" && (
{this.state.siteForm.registration_mode === "RequireApplication" && (
<div className="mb-3 row">
<label className="col-12 col-form-label">
{I18NextService.i18n.t("application_questionnaire")}
@ -319,7 +319,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
checked={this.state.siteForm.community_creation_admin_only}
onChange={linkEvent(
this,
this.handleSiteCommunityCreationAdminOnly
this.handleSiteCommunityCreationAdminOnly,
)}
/>
<label
@ -341,7 +341,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
checked={this.state.siteForm.require_email_verification}
onChange={linkEvent(
this,
this.handleSiteRequireEmailVerification
this.handleSiteRequireEmailVerification,
)}
/>
<label
@ -363,7 +363,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
checked={this.state.siteForm.application_email_admins}
onChange={linkEvent(
this,
this.handleSiteApplicationEmailAdmins
this.handleSiteApplicationEmailAdmins,
)}
/>
<label
@ -631,7 +631,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
}
componentDidUpdate(
prevProps: Readonly<{ children?: InfernoNode } & SiteFormProps>
prevProps: Readonly<{ children?: InfernoNode } & SiteFormProps>,
) {
if (
!(
@ -694,7 +694,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
className="btn btn-sm bg-danger"
onClick={linkEvent(
{ key, instance },
this.handleRemoveInstance
this.handleRemoveInstance,
)}
>
<Icon
@ -722,7 +722,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
handleInstanceEnterPress(
key: InstanceKey,
event: InfernoKeyboardEvent<HTMLInputElement>
event: InfernoKeyboardEvent<HTMLInputElement>,
) {
if (event.code.toLowerCase() === "enter") {
event.preventDefault();
@ -863,7 +863,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
handleDeleteTaglineClick(
i: SiteForm,
index: number,
event: InfernoMouseEvent<HTMLButtonElement>
event: InfernoMouseEvent<HTMLButtonElement>,
) {
event.preventDefault();
const taglines = i.state.siteForm.taglines;
@ -878,7 +878,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
handleAddTaglineClick(
i: SiteForm,
event: InfernoMouseEvent<HTMLButtonElement>
event: InfernoMouseEvent<HTMLButtonElement>,
) {
event.preventDefault();
if (!i.state.siteForm.taglines) {
@ -969,7 +969,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
handleSiteActorNameMaxLength(i: SiteForm, event: any) {
i.setState(
s => ((s.siteForm.actor_name_max_length = Number(event.target.value)), s)
s => ((s.siteForm.actor_name_max_length = Number(event.target.value)), s),
);
}

View file

@ -3,7 +3,6 @@ import { capitalizeFirstLetter } from "@utils/helpers";
import { Component, InfernoMouseEvent, linkEvent } from "inferno";
import { EditSite, Tagline } from "lemmy-js-client";
import { I18NextService } from "../../services";
import { HtmlTags } from "../common/html-tags";
import { Icon, Spinner } from "../common/icon";
import { MarkdownTextArea } from "../common/markdown-textarea";
@ -26,17 +25,10 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
constructor(props: any, context: any) {
super(props, context);
}
get documentTitle(): string {
return I18NextService.i18n.t("taglines");
}
render() {
return (
<div className="tagline-form col-12">
<HtmlTags
title={this.documentTitle}
path={this.context.router.route.match.url}
/>
<h1 className="h4 mb-4">{I18NextService.i18n.t("taglines")}</h1>
<div className="table-responsive col-12">
<table id="taglines_table" className="table table-sm table-hover">
@ -48,7 +40,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
{this.state.taglines.map((cv, index) => (
<tr key={index}>
<td>
{this.state.editingRow == index && (
{this.state.editingRow === index && (
<MarkdownTextArea
initialContent={cv}
onContentChange={s =>
@ -59,14 +51,14 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
siteLanguages={[]}
/>
)}
{this.state.editingRow != index && <div>{cv}</div>}
{this.state.editingRow !== index && <div>{cv}</div>}
</td>
<td className="text-right">
<button
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
{ i: this, index: index },
this.handleEditTaglineClick
this.handleEditTaglineClick,
)}
data-tippy-content={I18NextService.i18n.t("edit")}
aria-label={I18NextService.i18n.t("edit")}
@ -78,7 +70,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(
{ i: this, index: index },
this.handleDeleteTaglineClick
this.handleDeleteTaglineClick,
)}
data-tippy-content={I18NextService.i18n.t("delete")}
aria-label={I18NextService.i18n.t("delete")}
@ -141,7 +133,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
handleEditTaglineClick(d: { i: TaglineForm; index: number }, event: any) {
event.preventDefault();
if (d.i.state.editingRow == d.index) {
if (d.i.state.editingRow === d.index) {
d.i.setState({ editingRow: undefined });
} else {
d.i.setState({ editingRow: d.index });
@ -157,7 +149,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
handleAddTaglineClick(
i: TaglineForm,
event: InfernoMouseEvent<HTMLButtonElement>
event: InfernoMouseEvent<HTMLButtonElement>,
) {
event.preventDefault();
const newTaglines = [...i.state.taglines];

View file

@ -121,7 +121,7 @@ function getActionFromString(action?: string): ModlogActionType {
const getModlogActionMapper =
(
actionType: ModlogActionType,
getAction: (view: View) => { id: number; when_: string }
getAction: (view: View) => { id: number; when_: string },
) =>
(view: View & { moderator?: Person; admin?: Person }): ModlogType => {
const { id, when_ } = getAction(view);
@ -155,111 +155,111 @@ function buildCombined({
.map(
getModlogActionMapper(
"ModRemovePost",
({ mod_remove_post }: ModRemovePostView) => mod_remove_post
)
({ mod_remove_post }: ModRemovePostView) => mod_remove_post,
),
)
.concat(
locked_posts.map(
getModlogActionMapper(
"ModLockPost",
({ mod_lock_post }: ModLockPostView) => mod_lock_post
)
)
({ mod_lock_post }: ModLockPostView) => mod_lock_post,
),
),
)
.concat(
featured_posts.map(
getModlogActionMapper(
"ModFeaturePost",
({ mod_feature_post }: ModFeaturePostView) => mod_feature_post
)
)
({ mod_feature_post }: ModFeaturePostView) => mod_feature_post,
),
),
)
.concat(
removed_comments.map(
getModlogActionMapper(
"ModRemoveComment",
({ mod_remove_comment }: ModRemoveCommentView) => mod_remove_comment
)
)
({ mod_remove_comment }: ModRemoveCommentView) => mod_remove_comment,
),
),
)
.concat(
removed_communities.map(
getModlogActionMapper(
"ModRemoveCommunity",
({ mod_remove_community }: ModRemoveCommunityView) =>
mod_remove_community
)
)
mod_remove_community,
),
),
)
.concat(
banned_from_community.map(
getModlogActionMapper(
"ModBanFromCommunity",
({ mod_ban_from_community }: ModBanFromCommunityView) =>
mod_ban_from_community
)
)
mod_ban_from_community,
),
),
)
.concat(
added_to_community.map(
getModlogActionMapper(
"ModAddCommunity",
({ mod_add_community }: ModAddCommunityView) => mod_add_community
)
)
({ mod_add_community }: ModAddCommunityView) => mod_add_community,
),
),
)
.concat(
transferred_to_community.map(
getModlogActionMapper(
"ModTransferCommunity",
({ mod_transfer_community }: ModTransferCommunityView) =>
mod_transfer_community
)
)
mod_transfer_community,
),
),
)
.concat(
added.map(
getModlogActionMapper("ModAdd", ({ mod_add }: ModAddView) => mod_add)
)
getModlogActionMapper("ModAdd", ({ mod_add }: ModAddView) => mod_add),
),
)
.concat(
banned.map(
getModlogActionMapper("ModBan", ({ mod_ban }: ModBanView) => mod_ban)
)
getModlogActionMapper("ModBan", ({ mod_ban }: ModBanView) => mod_ban),
),
)
.concat(
admin_purged_persons.map(
getModlogActionMapper(
"AdminPurgePerson",
({ admin_purge_person }: AdminPurgePersonView) => admin_purge_person
)
)
({ admin_purge_person }: AdminPurgePersonView) => admin_purge_person,
),
),
)
.concat(
admin_purged_communities.map(
getModlogActionMapper(
"AdminPurgeCommunity",
({ admin_purge_community }: AdminPurgeCommunityView) =>
admin_purge_community
)
)
admin_purge_community,
),
),
)
.concat(
admin_purged_posts.map(
getModlogActionMapper(
"AdminPurgePost",
({ admin_purge_post }: AdminPurgePostView) => admin_purge_post
)
)
({ admin_purge_post }: AdminPurgePostView) => admin_purge_post,
),
),
)
.concat(
admin_purged_comments.map(
getModlogActionMapper(
"AdminPurgeComment",
({ admin_purge_comment }: AdminPurgeCommentView) =>
admin_purge_comment
)
)
admin_purge_comment,
),
),
);
// Sort them by time
@ -622,7 +622,7 @@ async function createNewOptions({
if (id) {
const selectedUser = oldOptions.find(
({ value }) => value === id.toString()
({ value }) => value === id.toString(),
);
if (selectedUser) {
@ -634,7 +634,7 @@ async function createNewOptions({
newOptions.push(
...(await fetchUsers(text))
.slice(0, Number(fetchLimit))
.map<Choice>(personToChoice)
.map<Choice>(personToChoice),
);
}
@ -658,7 +658,7 @@ export class Modlog extends Component<
constructor(
props: RouteComponentProps<{ communityId?: string }>,
context: any
context: any,
) {
super(props, context);
this.handlePageChange = this.handlePageChange.bind(this);
@ -698,7 +698,7 @@ export class Modlog extends Component<
get combined() {
const res = this.state.res;
const combined = res.state == "success" ? buildCombined(res.data) : [];
const combined = res.state === "success" ? buildCombined(res.data) : [];
return (
<tbody>
@ -723,7 +723,7 @@ export class Modlog extends Component<
get amAdminOrMod(): boolean {
const amMod_ =
this.state.communityRes.state == "success" &&
this.state.communityRes.state === "success" &&
amMod(this.state.communityRes.data.moderators);
return amAdmin() || amMod_;
}
@ -731,7 +731,7 @@ export class Modlog extends Component<
modOrAdminText(person?: Person): string {
return person &&
this.isoData.site_res.admins.some(
({ person: { id } }) => id === person.id
({ person: { id } }) => id === person.id,
)
? I18NextService.i18n.t("admin")
: I18NextService.i18n.t("mod");
@ -939,8 +939,8 @@ export class Modlog extends Component<
this.props.history.push(
`/modlog${communityId ? `/${communityId}` : ""}${getQueryString(
queryParams
)}`
queryParams,
)}`,
);
await this.refetch();

View file

@ -188,20 +188,20 @@ export class Inbox extends Component<any, InboxState> {
const mui = UserService.Instance.myUserInfo;
return mui
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
"inbox"
"inbox",
)} - ${this.state.siteRes.site_view.site.name}`
: "";
}
get hasUnreads(): boolean {
if (this.state.unreadOrAll == UnreadOrAll.Unread) {
if (this.state.unreadOrAll === UnreadOrAll.Unread) {
const { repliesRes, mentionsRes, messagesRes } = this.state;
const replyCount =
repliesRes.state == "success" ? repliesRes.data.replies.length : 0;
repliesRes.state === "success" ? repliesRes.data.replies.length : 0;
const mentionCount =
mentionsRes.state == "success" ? mentionsRes.data.mentions.length : 0;
mentionsRes.state === "success" ? mentionsRes.data.mentions.length : 0;
const messageCount =
messagesRes.state == "success"
messagesRes.state === "success"
? messagesRes.data.private_messages.length
: 0;
@ -242,11 +242,11 @@ export class Inbox extends Component<any, InboxState> {
className="btn btn-secondary mb-2 mb-sm-3"
onClick={linkEvent(this, this.handleMarkAllAsRead)}
>
{this.state.markAllAsReadRes.state == "loading" ? (
{this.state.markAllAsReadRes.state === "loading" ? (
<Spinner />
) : (
capitalizeFirstLetter(
I18NextService.i18n.t("mark_all_as_read")
I18NextService.i18n.t("mark_all_as_read"),
)
)}
</button>
@ -445,22 +445,22 @@ export class Inbox extends Component<any, InboxState> {
buildCombined(): ReplyType[] {
const replies: ReplyType[] =
this.state.repliesRes.state == "success"
this.state.repliesRes.state === "success"
? this.state.repliesRes.data.replies.map(this.replyToReplyType)
: [];
const mentions: ReplyType[] =
this.state.mentionsRes.state == "success"
this.state.mentionsRes.state === "success"
? this.state.mentionsRes.data.mentions.map(this.mentionToReplyType)
: [];
const messages: ReplyType[] =
this.state.messagesRes.state == "success"
this.state.messagesRes.state === "success"
? this.state.messagesRes.data.private_messages.map(
this.messageToReplyType
this.messageToReplyType,
)
: [];
return [...replies, ...mentions, ...messages].sort((a, b) =>
b.published.localeCompare(a.published)
b.published.localeCompare(a.published),
);
}
@ -559,9 +559,9 @@ export class Inbox extends Component<any, InboxState> {
all() {
if (
this.state.repliesRes.state == "loading" ||
this.state.mentionsRes.state == "loading" ||
this.state.messagesRes.state == "loading"
this.state.repliesRes.state === "loading" ||
this.state.mentionsRes.state === "loading" ||
this.state.messagesRes.state === "loading"
) {
return (
<h1 className="h4">
@ -754,7 +754,7 @@ export class Inbox extends Component<any, InboxState> {
async refetch() {
const sort = this.state.sort;
const unread_only = this.state.unreadOrAll == UnreadOrAll.Unread;
const unread_only = this.state.unreadOrAll === UnreadOrAll.Unread;
const page = this.state.page;
const limit = fetchLimit;
const auth = myAuthRequired();
@ -806,7 +806,7 @@ export class Inbox extends Component<any, InboxState> {
}),
});
if (i.state.markAllAsReadRes.state == "success") {
if (i.state.markAllAsReadRes.state === "success") {
i.setState({
repliesRes: { state: "empty" },
mentionsRes: { state: "empty" },
@ -837,7 +837,7 @@ export class Inbox extends Component<any, InboxState> {
async handleBlockPerson(form: BlockPerson) {
const blockPersonRes = await HttpService.client.blockPerson(form);
if (blockPersonRes.state == "success") {
if (blockPersonRes.state === "success") {
updatePersonBlock(blockPersonRes.data);
}
}
@ -868,7 +868,7 @@ export class Inbox extends Component<any, InboxState> {
async handleDeleteComment(form: DeleteComment) {
const res = await HttpService.client.deleteComment(form);
if (res.state == "success") {
if (res.state === "success") {
toast(I18NextService.i18n.t("deleted"));
this.findAndUpdateComment(res);
}
@ -876,7 +876,7 @@ export class Inbox extends Component<any, InboxState> {
async handleRemoveComment(form: RemoveComment) {
const res = await HttpService.client.removeComment(form);
if (res.state == "success") {
if (res.state === "success") {
toast(I18NextService.i18n.t("remove_comment"));
this.findAndUpdateComment(res);
}
@ -958,9 +958,9 @@ export class Inbox extends Component<any, InboxState> {
async handleCreateMessage(form: CreatePrivateMessage) {
const res = await HttpService.client.createPrivateMessage(form);
this.setState(s => {
if (s.messagesRes.state == "success" && res.state == "success") {
if (s.messagesRes.state === "success" && res.state === "success") {
s.messagesRes.data.private_messages.unshift(
res.data.private_message_view
res.data.private_message_view,
);
}
@ -973,7 +973,7 @@ export class Inbox extends Component<any, InboxState> {
if (s.messagesRes.state === "success" && res.state === "success") {
s.messagesRes.data.private_messages = editPrivateMessage(
res.data.private_message_view,
s.messagesRes.data.private_messages
s.messagesRes.data.private_messages,
);
}
return s;
@ -982,20 +982,20 @@ export class Inbox extends Component<any, InboxState> {
updateBanFromCommunity(banRes: RequestState<BanFromCommunityResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.repliesRes.state == "success") {
if (s.repliesRes.state === "success") {
s.repliesRes.data.replies
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
if (s.mentionsRes.state == "success") {
if (s.mentionsRes.state === "success") {
s.mentionsRes.data.mentions
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
return s;
@ -1005,16 +1005,16 @@ export class Inbox extends Component<any, InboxState> {
updateBan(banRes: RequestState<BanPersonResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.repliesRes.state == "success") {
if (s.repliesRes.state === "success") {
s.repliesRes.data.replies
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
if (s.mentionsRes.state == "success") {
if (s.mentionsRes.state === "success") {
s.mentionsRes.data.mentions
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
return s;
@ -1023,40 +1023,40 @@ export class Inbox extends Component<any, InboxState> {
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
if (purgeRes.state === "success") {
toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
}
reportToast(
res: RequestState<PrivateMessageReportResponse | CommentReportResponse>
res: RequestState<PrivateMessageReportResponse | CommentReportResponse>,
) {
if (res.state == "success") {
if (res.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
// A weird case, since you have only replies and mentions, not comment responses
findAndUpdateComment(res: RequestState<CommentResponse>) {
if (res.state == "success") {
if (res.state === "success") {
this.setState(s => {
if (s.repliesRes.state == "success") {
if (s.repliesRes.state === "success") {
s.repliesRes.data.replies = editWith(
res.data.comment_view,
s.repliesRes.data.replies
s.repliesRes.data.replies,
);
}
if (s.mentionsRes.state == "success") {
if (s.mentionsRes.state === "success") {
s.mentionsRes.data.mentions = editWith(
res.data.comment_view,
s.mentionsRes.data.mentions
s.mentionsRes.data.mentions,
);
}
// Set finished for the parent
s.finished.set(
getCommentParentId(res.data.comment_view.comment) ?? 0,
true
true,
);
return s;
});
@ -1065,10 +1065,10 @@ export class Inbox extends Component<any, InboxState> {
findAndUpdateCommentReply(res: RequestState<CommentReplyResponse>) {
this.setState(s => {
if (s.repliesRes.state == "success" && res.state == "success") {
if (s.repliesRes.state === "success" && res.state === "success") {
s.repliesRes.data.replies = editCommentReply(
res.data.comment_reply_view,
s.repliesRes.data.replies
s.repliesRes.data.replies,
);
}
return s;
@ -1077,10 +1077,10 @@ export class Inbox extends Component<any, InboxState> {
findAndUpdateMention(res: RequestState<PersonMentionResponse>) {
this.setState(s => {
if (s.mentionsRes.state == "success" && res.state == "success") {
if (s.mentionsRes.state === "success" && res.state === "success") {
s.mentionsRes.data.mentions = editMention(
res.data.person_mention_view,
s.mentionsRes.data.mentions
s.mentionsRes.data.mentions,
);
}
return s;

View file

@ -81,7 +81,7 @@ export class PasswordChange extends Component<any, State> {
<div className="mb-3 row">
<div className="col-sm-10">
<button type="submit" className="btn btn-secondary">
{this.state.passwordChangeRes.state == "loading" ? (
{this.state.passwordChangeRes.state === "loading" ? (
<Spinner />
) : (
capitalizeFirstLetter(I18NextService.i18n.t("save"))

View file

@ -25,6 +25,7 @@ import {
LockPost,
MarkCommentReplyAsRead,
MarkPersonMentionAsRead,
MarkPostAsRead,
PersonView,
PostView,
PurgeComment,
@ -84,6 +85,7 @@ interface PersonDetailsProps {
onSavePost(form: SavePost): void;
onFeaturePost(form: FeaturePost): void;
onPurgePost(form: PurgePost): void;
onMarkPostAsRead(form: MarkPostAsRead): void;
}
enum ItemEnum {
@ -200,6 +202,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
onAddModToCommunity={this.props.onAddModToCommunity}
onAddAdmin={this.props.onAddAdmin}
onTransferCommunity={this.props.onTransferCommunity}
onMarkPostAsRead={this.props.onMarkPostAsRead}
/>
);
}
@ -311,6 +314,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
onAddModToCommunity={this.props.onAddModToCommunity}
onAddAdmin={this.props.onAddAdmin}
onTransferCommunity={this.props.onTransferCommunity}
onMarkPostAsRead={this.props.onMarkPostAsRead}
/>
<hr className="my-3" />
</>

View file

@ -57,7 +57,7 @@ export class PersonListing extends Component<PersonListingProps, any> {
{
"text-muted": this.props.muted,
"text-info": !this.props.muted,
}
},
)}
to={link}
>

View file

@ -60,6 +60,7 @@ import {
LockPost,
MarkCommentReplyAsRead,
MarkPersonMentionAsRead,
MarkPostAsRead,
PersonView,
PostResponse,
PurgeComment,
@ -132,7 +133,7 @@ function getViewFromProps(view?: string): PersonDetailsView {
const getCommunitiesListing = (
translationKey: NoOptionI18nKeys,
communityViews?: { community: Community }[]
communityViews?: { community: Community }[],
) =>
communityViews &&
communityViews.length > 0 && (
@ -208,6 +209,7 @@ export class Profile extends Component<
this.handlePurgePost = this.handlePurgePost.bind(this);
this.handleFeaturePost = this.handleFeaturePost.bind(this);
this.handleModBanSubmit = this.handleModBanSubmit.bind(this);
this.handleMarkPostAsRead = this.handleMarkPostAsRead.bind(this);
// Only fetch the data if coming from another route
if (FirstLoadService.isFirstLoad) {
@ -266,7 +268,7 @@ export class Profile extends Component<
if (mui && res.state === "success") {
this.setState({
personBlocked: mui.person_blocks.some(
({ target: { id } }) => id === res.data.person_view.person.id
({ target: { id } }) => id === res.data.person_view.person.id,
),
});
}
@ -300,7 +302,7 @@ export class Profile extends Component<
get documentTitle(): string {
const siteName = this.state.siteRes.site_view.site.name;
const res = this.state.personRes;
return res.state == "success"
return res.state === "success"
? `@${res.data.person_view.person.name} - ${siteName}`
: siteName;
}
@ -376,6 +378,7 @@ export class Profile extends Component<
onSavePost={this.handleSavePost}
onPurgePost={this.handlePurgePost}
onFeaturePost={this.handleFeaturePost}
onMarkPostAsRead={this.handleMarkPostAsRead}
/>
</div>
@ -530,7 +533,7 @@ export class Profile extends Component<
}
onClick={linkEvent(
pv.person.id,
this.handleUnblockPerson
this.handleUnblockPerson,
)}
>
{I18NextService.i18n.t("unblock_user")}
@ -542,7 +545,7 @@ export class Profile extends Component<
}
onClick={linkEvent(
pv.person.id,
this.handleBlockPerson
this.handleBlockPerson,
)}
>
{I18NextService.i18n.t("block_user")}
@ -764,7 +767,7 @@ export class Profile extends Component<
const personRes = i.state.personRes;
if (personRes.state == "success") {
if (personRes.state === "success") {
const person = personRes.data.person_view.person;
const ban = !person.banned;
@ -793,7 +796,7 @@ export class Profile extends Component<
block,
auth: myAuthRequired(),
});
if (res.state == "success") {
if (res.state === "success") {
updatePersonBlock(res.data);
}
}
@ -924,7 +927,7 @@ export class Profile extends Component<
async handleAddAdmin(form: AddAdmin) {
const addAdminRes = await HttpService.client.addAdmin(form);
if (addAdminRes.state == "success") {
if (addAdminRes.state === "success") {
this.setState(s => ((s.siteRes.admins = addAdminRes.data.admins), s));
}
}
@ -944,6 +947,11 @@ export class Profile extends Component<
await HttpService.client.markPersonMentionAsRead(form);
}
async handleMarkPostAsRead(form: MarkPostAsRead) {
const res = await HttpService.client.markPostAsRead(form);
this.findAndUpdatePost(res);
}
async handleBanFromCommunity(form: BanFromCommunity) {
const banRes = await HttpService.client.banFromCommunity(form);
this.updateBanFromCommunity(banRes);
@ -958,17 +966,17 @@ export class Profile extends Component<
// Maybe not necessary
if (banRes.state === "success") {
this.setState(s => {
if (s.personRes.state == "success") {
if (s.personRes.state === "success") {
s.personRes.data.posts
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
s.personRes.data.comments
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
return s;
@ -978,14 +986,14 @@ export class Profile extends Component<
updateBan(banRes: RequestState<BanPersonResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (s.personRes.state == "success") {
if (s.personRes.state === "success") {
s.personRes.data.posts
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
s.personRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
s.personRes.data.person_view.person.banned = banRes.data.banned;
}
@ -995,7 +1003,7 @@ export class Profile extends Component<
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
if (purgeRes.state === "success") {
toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
@ -1003,10 +1011,10 @@ export class Profile extends Component<
findAndUpdateComment(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.personRes.state == "success" && res.state == "success") {
if (s.personRes.state === "success" && res.state === "success") {
s.personRes.data.comments = editComment(
res.data.comment_view,
s.personRes.data.comments
s.personRes.data.comments,
);
s.finished.set(res.data.comment_view.comment.id, true);
}
@ -1016,12 +1024,12 @@ export class Profile extends Component<
createAndUpdateComments(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.personRes.state == "success" && res.state == "success") {
if (s.personRes.state === "success" && res.state === "success") {
s.personRes.data.comments.unshift(res.data.comment_view);
// Set finished for the parent
s.finished.set(
getCommentParentId(res.data.comment_view.comment) ?? 0,
true
true,
);
}
return s;
@ -1030,10 +1038,10 @@ export class Profile extends Component<
findAndUpdateCommentReply(res: RequestState<CommentReplyResponse>) {
this.setState(s => {
if (s.personRes.state == "success" && res.state == "success") {
if (s.personRes.state === "success" && res.state === "success") {
s.personRes.data.comments = editWith(
res.data.comment_reply_view,
s.personRes.data.comments
s.personRes.data.comments,
);
}
return s;
@ -1042,10 +1050,10 @@ export class Profile extends Component<
findAndUpdatePost(res: RequestState<PostResponse>) {
this.setState(s => {
if (s.personRes.state == "success" && res.state == "success") {
if (s.personRes.state === "success" && res.state === "success") {
s.personRes.data.posts = editPost(
res.data.post_view,
s.personRes.data.posts
s.personRes.data.posts,
);
}
return s;

View file

@ -80,7 +80,7 @@ export class RegistrationApplications extends Component<
const mui = UserService.Instance.myUserInfo;
return mui
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
"registration_applications"
"registration_applications",
)} - ${this.state.siteRes.site_view.site.name}`
: "";
}
@ -220,7 +220,7 @@ export class RegistrationApplications extends Component<
}
async refetch() {
const unread_only = this.state.unreadOrAll == UnreadOrAll.Unread;
const unread_only = this.state.unreadOrAll === UnreadOrAll.Unread;
this.setState({
appsRes: { state: "loading" },
});
@ -236,13 +236,13 @@ export class RegistrationApplications extends Component<
async handleApproveApplication(form: ApproveRegistrationApplication) {
const approveRes = await HttpService.client.approveRegistrationApplication(
form
form,
);
this.setState(s => {
if (s.appsRes.state == "success" && approveRes.state == "success") {
if (s.appsRes.state === "success" && approveRes.state === "success") {
s.appsRes.data.registration_applications = editRegistrationApplication(
approveRes.data.registration_application,
s.appsRes.data.registration_applications
s.appsRes.data.registration_applications,
);
}
return s;

View file

@ -140,7 +140,7 @@ export class Reports extends Component<any, ReportsState> {
const mui = UserService.Instance.myUserInfo;
return mui
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
"reports"
"reports",
)} - ${this.state.siteRes.site_view.site.name}`
: "";
}
@ -352,25 +352,25 @@ export class Reports extends Component<any, ReportsState> {
get buildCombined(): ItemType[] {
const commentRes = this.state.commentReportsRes;
const comments =
commentRes.state == "success"
commentRes.state === "success"
? commentRes.data.comment_reports.map(this.commentReportToItemType)
: [];
const postRes = this.state.postReportsRes;
const posts =
postRes.state == "success"
postRes.state === "success"
? postRes.data.post_reports.map(this.postReportToItemType)
: [];
const pmRes = this.state.messageReportsRes;
const privateMessages =
pmRes.state == "success"
pmRes.state === "success"
? pmRes.data.private_message_reports.map(
this.privateMessageReportToItemType
this.privateMessageReportToItemType,
)
: [];
return [...comments, ...posts, ...privateMessages].sort((a, b) =>
b.published.localeCompare(a.published)
b.published.localeCompare(a.published),
);
}
@ -557,7 +557,7 @@ export class Reports extends Component<any, ReportsState> {
};
data.messageReportsRes = await client.listPrivateMessageReports(
privateMessageReportsForm
privateMessageReportsForm,
);
}
@ -565,7 +565,7 @@ export class Reports extends Component<any, ReportsState> {
}
async refetch() {
const unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
const unresolved_only = this.state.unreadOrAll === UnreadOrAll.Unread;
const page = this.state.page;
const limit = fetchLimit;
const auth = myAuthRequired();
@ -594,7 +594,7 @@ export class Reports extends Component<any, ReportsState> {
if (amAdmin()) {
this.setState({
messageReportsRes: await HttpService.client.listPrivateMessageReports(
form
form,
),
});
}
@ -617,10 +617,10 @@ export class Reports extends Component<any, ReportsState> {
findAndUpdateCommentReport(res: RequestState<CommentReportResponse>) {
this.setState(s => {
if (s.commentReportsRes.state == "success" && res.state == "success") {
if (s.commentReportsRes.state === "success" && res.state === "success") {
s.commentReportsRes.data.comment_reports = editCommentReport(
res.data.comment_report_view,
s.commentReportsRes.data.comment_reports
s.commentReportsRes.data.comment_reports,
);
}
return s;
@ -629,10 +629,10 @@ export class Reports extends Component<any, ReportsState> {
findAndUpdatePostReport(res: RequestState<PostReportResponse>) {
this.setState(s => {
if (s.postReportsRes.state == "success" && res.state == "success") {
if (s.postReportsRes.state === "success" && res.state === "success") {
s.postReportsRes.data.post_reports = editPostReport(
res.data.post_report_view,
s.postReportsRes.data.post_reports
s.postReportsRes.data.post_reports,
);
}
return s;
@ -640,14 +640,14 @@ export class Reports extends Component<any, ReportsState> {
}
findAndUpdatePrivateMessageReport(
res: RequestState<PrivateMessageReportResponse>
res: RequestState<PrivateMessageReportResponse>,
) {
this.setState(s => {
if (s.messageReportsRes.state == "success" && res.state == "success") {
if (s.messageReportsRes.state === "success" && res.state === "success") {
s.messageReportsRes.data.private_message_reports =
editPrivateMessageReport(
res.data.private_message_report_view,
s.messageReportsRes.data.private_message_reports
s.messageReportsRes.data.private_message_reports,
);
}
return s;

View file

@ -392,7 +392,7 @@ export class Settings extends Component<any, SettingsState> {
className="btn btn-sm"
onClick={linkEvent(
{ ctx: this, recipientId: pb.target.id },
this.handleUnblockPerson
this.handleUnblockPerson,
)}
data-tippy-content={I18NextService.i18n.t("unblock_user")}
>
@ -436,10 +436,10 @@ export class Settings extends Component<any, SettingsState> {
className="btn btn-sm"
onClick={linkEvent(
{ ctx: this, communityId: cb.community.id },
this.handleUnblockCommunity
this.handleUnblockCommunity,
)}
data-tippy-content={I18NextService.i18n.t(
"unblock_community"
"unblock_community",
)}
>
<Icon icon="x" classes="icon-inline" />
@ -588,6 +588,7 @@ export class Settings extends Component<any, SettingsState> {
selectedLanguageIds={selectedLangs}
multiple={true}
showLanguageWarning={true}
showAll={true}
showSite
onChange={this.handleDiscussionLanguageChange}
/>
@ -767,7 +768,7 @@ export class Settings extends Component<any, SettingsState> {
}
onChange={linkEvent(
this,
this.handleSendNotificationsToEmailChange
this.handleSendNotificationsToEmailChange,
)}
/>
<label
@ -815,7 +816,7 @@ export class Settings extends Component<any, SettingsState> {
className="btn d-block btn-danger"
onClick={linkEvent(
this,
this.handleDeleteAccountShowConfirmToggle
this.handleDeleteAccountShowConfirmToggle,
)}
>
{I18NextService.i18n.t("delete_account")}
@ -834,7 +835,7 @@ export class Settings extends Component<any, SettingsState> {
value={this.state.deleteAccountForm.password}
onInput={linkEvent(
this,
this.handleDeleteAccountPasswordChange
this.handleDeleteAccountPasswordChange,
)}
className="my-2"
/>
@ -854,7 +855,7 @@ export class Settings extends Component<any, SettingsState> {
type="button"
onClick={linkEvent(
this,
this.handleDeleteAccountShowConfirmToggle
this.handleDeleteAccountShowConfirmToggle,
)}
>
{I18NextService.i18n.t("cancel")}
@ -904,7 +905,7 @@ export class Settings extends Component<any, SettingsState> {
id="user-remove-totp"
type="checkbox"
checked={
this.state.saveUserSettingsForm.generate_totp_2fa == false
this.state.saveUserSettingsForm.generate_totp_2fa === false
}
onChange={linkEvent(this, this.handleRemoveTotp)}
/>
@ -941,7 +942,7 @@ export class Settings extends Component<any, SettingsState> {
if (text.length > 0) {
searchCommunityOptions.push(
...(await fetchCommunities(text)).map(communityToChoice)
...(await fetchCommunities(text)).map(communityToChoice),
);
}
@ -1002,7 +1003,7 @@ export class Settings extends Component<any, SettingsState> {
handleShowNsfwChange(i: Settings, event: any) {
i.setState(
s => ((s.saveUserSettingsForm.show_nsfw = event.target.checked), s)
s => ((s.saveUserSettingsForm.show_nsfw = event.target.checked), s),
);
}
@ -1012,13 +1013,13 @@ export class Settings extends Component<any, SettingsState> {
mui.local_user_view.local_user.show_avatars = event.target.checked;
}
i.setState(
s => ((s.saveUserSettingsForm.show_avatars = event.target.checked), s)
s => ((s.saveUserSettingsForm.show_avatars = event.target.checked), s),
);
}
handleBotAccount(i: Settings, event: any) {
i.setState(
s => ((s.saveUserSettingsForm.bot_account = event.target.checked), s)
s => ((s.saveUserSettingsForm.bot_account = event.target.checked), s),
);
}
@ -1026,13 +1027,13 @@ export class Settings extends Component<any, SettingsState> {
i.setState(
s => (
(s.saveUserSettingsForm.show_bot_accounts = event.target.checked), s
)
),
);
}
handleReadPosts(i: Settings, event: any) {
i.setState(
s => ((s.saveUserSettingsForm.show_read_posts = event.target.checked), s)
s => ((s.saveUserSettingsForm.show_read_posts = event.target.checked), s),
);
}
@ -1040,7 +1041,7 @@ export class Settings extends Component<any, SettingsState> {
i.setState(
s => (
(s.saveUserSettingsForm.show_new_post_notifs = event.target.checked), s
)
),
);
}
@ -1058,7 +1059,7 @@ export class Settings extends Component<any, SettingsState> {
mui.local_user_view.local_user.show_scores = event.target.checked;
}
i.setState(
s => ((s.saveUserSettingsForm.show_scores = event.target.checked), s)
s => ((s.saveUserSettingsForm.show_scores = event.target.checked), s),
);
}
@ -1083,7 +1084,7 @@ export class Settings extends Component<any, SettingsState> {
(s.saveUserSettingsForm.send_notifications_to_email =
event.target.checked),
s
)
),
);
}
@ -1095,17 +1096,19 @@ export class Settings extends Component<any, SettingsState> {
handleInterfaceLangChange(i: Settings, event: any) {
const newLang = event.target.value ?? "browser";
I18NextService.i18n.changeLanguage(
newLang === "browser" ? navigator.languages : newLang
newLang === "browser" ? navigator.languages : newLang,
);
i.setState(
s => ((s.saveUserSettingsForm.interface_language = event.target.value), s)
s => (
(s.saveUserSettingsForm.interface_language = event.target.value), s
),
);
}
handleDiscussionLanguageChange(val: number[]) {
this.setState(
s => ((s.saveUserSettingsForm.discussion_languages = val), s)
s => ((s.saveUserSettingsForm.discussion_languages = val), s),
);
}
@ -1115,7 +1118,7 @@ export class Settings extends Component<any, SettingsState> {
handleListingTypeChange(val: ListingType) {
this.setState(
s => ((s.saveUserSettingsForm.default_listing_type = val), s)
s => ((s.saveUserSettingsForm.default_listing_type = val), s),
);
}
@ -1145,33 +1148,33 @@ export class Settings extends Component<any, SettingsState> {
handleDisplayNameChange(i: Settings, event: any) {
i.setState(
s => ((s.saveUserSettingsForm.display_name = event.target.value), s)
s => ((s.saveUserSettingsForm.display_name = event.target.value), s),
);
}
handleMatrixUserIdChange(i: Settings, event: any) {
i.setState(
s => ((s.saveUserSettingsForm.matrix_user_id = event.target.value), s)
s => ((s.saveUserSettingsForm.matrix_user_id = event.target.value), s),
);
}
handleNewPasswordChange(i: Settings, event: any) {
const newPass: string | undefined =
event.target.value == "" ? undefined : event.target.value;
event.target.value === "" ? undefined : event.target.value;
i.setState(s => ((s.changePasswordForm.new_password = newPass), s));
}
handleNewPasswordVerifyChange(i: Settings, event: any) {
const newPassVerify: string | undefined =
event.target.value == "" ? undefined : event.target.value;
event.target.value === "" ? undefined : event.target.value;
i.setState(
s => ((s.changePasswordForm.new_password_verify = newPassVerify), s)
s => ((s.changePasswordForm.new_password_verify = newPassVerify), s),
);
}
handleOldPasswordChange(i: Settings, event: any) {
const oldPass: string | undefined =
event.target.value == "" ? undefined : event.target.value;
event.target.value === "" ? undefined : event.target.value;
i.setState(s => ((s.changePasswordForm.old_password = oldPass), s));
}

View file

@ -35,7 +35,7 @@ export class VerifyEmail extends Component<any, State> {
}),
});
if (this.state.verifyRes.state == "success") {
if (this.state.verifyRes.state === "success") {
toast(I18NextService.i18n.t("email_verified"));
this.props.history.push("/login");
}
@ -61,7 +61,7 @@ export class VerifyEmail extends Component<any, State> {
<div className="row">
<div className="col-12 col-lg-6 offset-lg-3 mb-4">
<h1 className="h4 mb-4">{I18NextService.i18n.t("verify_email")}</h1>
{this.state.verifyRes.state == "loading" && (
{this.state.verifyRes.state === "loading" && (
<h5>
<Spinner large />
</h5>

View file

@ -121,7 +121,7 @@ export class CreatePost extends Component<
const { communityId } = getCreatePostQueryParams();
const initialCommunitiesRes = await fetchCommunitiesForOptions(
HttpService.client
HttpService.client,
);
this.setState({

View file

@ -122,7 +122,7 @@ function copySuggestedTitle(d: { i: PostForm; suggestedTitle?: string }) {
const sTitle = d.suggestedTitle;
if (sTitle) {
d.i.setState(
s => ((s.form.name = sTitle?.substring(0, MAX_POST_TITLE_LENGTH)), s)
s => ((s.form.name = sTitle?.substring(0, MAX_POST_TITLE_LENGTH)), s),
);
d.i.setState({ suggestedPostsRes: { state: "empty" } });
setTimeout(() => {
@ -271,9 +271,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
({ community: { id, title } }) => ({
label: title,
value: id.toString(),
})
}),
) ?? []
).filter(option => option.value !== selectedCommunityChoice.value)
).filter(option => option.value !== selectedCommunityChoice.value),
),
};
} else {
@ -284,7 +284,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
({ community: { id, title } }) => ({
label: title,
value: id.toString(),
})
}),
) ?? [],
};
}
@ -310,16 +310,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & PostFormProps>
nextProps: Readonly<{ children?: InfernoNode } & PostFormProps>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState(
s => (
(s.form.community_id = getIdFromString(
nextProps.selectedCommunityChoice?.value
nextProps.selectedCommunityChoice?.value,
)),
s
)
),
);
}
}
@ -367,7 +367,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
</a>
<a
href={`${ghostArchiveUrl}/search?term=${encodeURIComponent(
url
url,
)}`}
className="me-2 d-inline-block float-right text-muted small fw-bold"
rel={relTags}
@ -376,7 +376,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
</a>
<a
href={`${archiveTodayUrl}/?run=1&url=${encodeURIComponent(
url
url,
)}`}
className="me-2 d-inline-block float-right text-muted small fw-bold"
rel={relTags}
@ -447,6 +447,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
onAddModToCommunity={() => {}}
onAddAdmin={() => {}}
onTransferCommunity={() => {}}
onMarkPostAsRead={() => {}}
/>
</>
)}
@ -590,7 +591,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
className="mt-1 small border-0 bg-transparent p-0 d-block text-muted fw-bold pointer"
onClick={linkEvent(
{ i: this, suggestedTitle },
copySuggestedTitle
copySuggestedTitle,
)}
>
{I18NextService.i18n.t("copy_suggested_title", { title: "" })}{" "}
@ -641,6 +642,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
onAddModToCommunity={() => {}}
onAddAdmin={() => {}}
onTransferCommunity={() => {}}
onMarkPostAsRead={() => {}}
/>
</>
)

View file

@ -1,4 +1,4 @@
import { myAuthRequired } from "@utils/app";
import { myAuth, myAuthRequired } from "@utils/app";
import { canShare, share } from "@utils/browser";
import { getExternalHost, getHttpBase } from "@utils/env";
import {
@ -34,6 +34,7 @@ import {
FeaturePost,
Language,
LockPost,
MarkPostAsRead,
PersonView,
PostView,
PurgePerson,
@ -130,6 +131,7 @@ interface PostListingProps {
onAddModToCommunity(form: AddModToCommunity): void;
onAddAdmin(form: AddAdmin): void;
onTransferCommunity(form: TransferCommunity): void;
onMarkPostAsRead(form: MarkPostAsRead): void;
}
export class PostListing extends Component<PostListingProps, PostListingState> {
@ -783,7 +785,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
get unreadCount(): number | undefined {
const pv = this.postView;
return pv.unread_comments == pv.counts.comments || pv.unread_comments == 0
return pv.unread_comments === pv.counts.comments || pv.unread_comments === 0
? undefined
: pv.unread_comments;
}
@ -1154,7 +1156,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
removeAndBanDialogs() {
const post = this.postView;
const purgeTypeText =
this.state.purgeType == PurgeType.Post
this.state.purgeType === PurgeType.Post
? I18NextService.i18n.t("purge_post")
: `${I18NextService.i18n.t("purge")} ${post.creator.name}`;
return (
@ -1423,7 +1425,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
private get myPost(): boolean {
return (
this.postView.creator.id ==
this.postView.creator.id ===
UserService.Instance.myUserInfo?.local_user_view.person.id
);
}
@ -1662,7 +1664,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
const ban = !i.props.post_view.creator_banned_from_community;
// If its an unban, restore all their data
if (ban == false) {
if (ban === false) {
i.setState({ removeData: false });
}
const person_id = i.props.post_view.creator.id;
@ -1670,7 +1672,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
const reason = i.state.banReason;
const expires = futureDaysToUnixTime(i.state.banExpireDays);
if (i.state.banType == BanType.Community) {
if (i.state.banType === BanType.Community) {
const community_id = i.postView.community.id;
i.props.onBanPersonFromCommunity({
community_id,
@ -1741,6 +1743,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
event.preventDefault();
i.setState({ imageExpanded: !i.state.imageExpanded });
setupTippy();
const auth = myAuth();
if (auth && !i.props.post_view.read) {
i.props.onMarkPostAsRead({
post_id: i.props.post_view.post.id,
read: true,
auth: auth,
});
}
}
handleViewSource(i: PostListing) {

View file

@ -14,6 +14,7 @@ import {
FeaturePost,
Language,
LockPost,
MarkPostAsRead,
PostView,
PurgePerson,
PurgePost,
@ -49,6 +50,7 @@ interface PostListingsProps {
onAddModToCommunity(form: AddModToCommunity): void;
onAddAdmin(form: AddAdmin): void;
onTransferCommunity(form: TransferCommunity): void;
onMarkPostAsRead(form: MarkPostAsRead): void;
}
export class PostListings extends Component<PostListingsProps, any> {
@ -95,6 +97,7 @@ export class PostListings extends Component<PostListingsProps, any> {
onAddModToCommunity={this.props.onAddModToCommunity}
onAddAdmin={this.props.onAddAdmin}
onTransferCommunity={this.props.onTransferCommunity}
onMarkPostAsRead={this.props.onMarkPostAsRead}
/>
{idx + 1 !== this.posts.length && <hr className="my-3" />}
</>
@ -141,7 +144,7 @@ export class PostListings extends Component<PostListingsProps, any> {
// Sort by oldest
// Remove the ones that have no length
for (const e of urlMap.entries()) {
if (e[1].length == 1) {
if (e[1].length === 1) {
urlMap.delete(e[0]);
} else {
e[1].sort((a, b) => a.post.published.localeCompare(b.post.published));
@ -155,7 +158,7 @@ export class PostListings extends Component<PostListingsProps, any> {
const found = urlMap.get(url);
if (found) {
// If its the oldest, add
if (pv.post.id == found[0].post.id) {
if (pv.post.id === found[0].post.id) {
this.duplicatesMap.set(pv.post.id, found.slice(1));
}
// Otherwise, delete it

View file

@ -26,9 +26,9 @@ export class PostReport extends Component<PostReportProps, PostReportState> {
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & PostReportProps>
nextProps: Readonly<{ children?: InfernoNode } & PostReportProps>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState({ loading: false });
}
}
@ -38,7 +38,7 @@ export class PostReport extends Component<PostReportProps, PostReportState> {
const resolver = r.resolver;
const post = r.post;
const tippyContent = I18NextService.i18n.t(
r.post_report.resolved ? "unresolve_report" : "resolve_report"
r.post_report.resolved ? "unresolve_report" : "resolve_report",
);
// Set the original post data ( a troll could change it )
@ -87,6 +87,7 @@ export class PostReport extends Component<PostReportProps, PostReportState> {
onAddModToCommunity={() => {}}
onAddAdmin={() => {}}
onTransferCommunity={() => {}}
onMarkPostAsRead={() => {}}
/>
<div>
{I18NextService.i18n.t("reporter")}:{" "}

View file

@ -63,6 +63,7 @@ import {
LockPost,
MarkCommentReplyAsRead,
MarkPersonMentionAsRead,
MarkPostAsRead,
PostResponse,
PurgeComment,
PurgeCommunity,
@ -171,6 +172,7 @@ export class Post extends Component<any, PostState> {
this.handleSavePost = this.handleSavePost.bind(this);
this.handlePurgePost = this.handlePurgePost.bind(this);
this.handleFeaturePost = this.handleFeaturePost.bind(this);
this.handleMarkPostAsRead = this.handleMarkPostAsRead.bind(this);
this.state = { ...this.state, commentSectionRef: createRef() };
@ -290,7 +292,7 @@ export class Post extends Component<any, PostState> {
get checkScrollIntoCommentsParam() {
return Boolean(
new URLSearchParams(this.props.location.search).get("scrollToComments")
new URLSearchParams(this.props.location.search).get("scrollToComments"),
);
}
@ -309,7 +311,7 @@ export class Post extends Component<any, PostState> {
const wrappedElement = document.getElementsByClassName("comments")[0];
if (wrappedElement && this.isBottom(wrappedElement)) {
const commentCount =
this.state.commentsRes.state == "success"
this.state.commentsRes.state === "success"
? this.state.commentsRes.data.comments.length
: 0;
@ -323,13 +325,13 @@ export class Post extends Component<any, PostState> {
get documentTitle(): string {
const siteName = this.state.siteRes.site_view.site.name;
return this.state.postRes.state == "success"
return this.state.postRes.state === "success"
? `${this.state.postRes.data.post_view.post.name} - ${siteName}`
: siteName;
}
get imageTag(): string | undefined {
if (this.state.postRes.state == "success") {
if (this.state.postRes.state === "success") {
const post = this.state.postRes.data.post_view.post;
const thumbnail = post.thumbnail_url;
const url = post.url;
@ -384,6 +386,7 @@ export class Post extends Component<any, PostState> {
onAddAdmin={this.handleAddAdmin}
onTransferCommunity={this.handleTransferCommunity}
onFeaturePost={this.handleFeaturePost}
onMarkPostAsRead={this.handleMarkPostAsRead}
/>
<div ref={this.state.commentSectionRef} className="mb-2" />
<CommentForm
@ -413,9 +416,9 @@ export class Post extends Component<any, PostState> {
{this.state.showSidebarMobile && this.sidebar()}
</div>
{this.sortRadios()}
{this.state.commentViewType == CommentViewType.Tree &&
{this.state.commentViewType === CommentViewType.Tree &&
this.commentsTree()}
{this.state.commentViewType == CommentViewType.Flat &&
{this.state.commentViewType === CommentViewType.Flat &&
this.commentsFlat()}
</main>
<aside className="d-none d-md-block col-md-4 col-lg-3">
@ -475,6 +478,22 @@ export class Post extends Component<any, PostState> {
>
{I18NextService.i18n.t("top")}
</label>
<input
id={`${radioId}-controversial`}
type="radio"
className="btn-check"
value={"Controversial"}
checked={this.state.commentSort === "Controversial"}
onChange={linkEvent(this, this.handleCommentSortChange)}
/>
<label
htmlFor={`${radioId}-controversial`}
className={classNames("btn btn-outline-secondary pointer", {
active: this.state.commentSort === "Controversial",
})}
>
{I18NextService.i18n.t("controversial")}
</label>
<input
id={`${radioId}-new`}
type="radio"
@ -535,7 +554,7 @@ export class Post extends Component<any, PostState> {
const commentsRes = this.state.commentsRes;
const postRes = this.state.postRes;
if (commentsRes.state == "success" && postRes.state == "success") {
if (commentsRes.state === "success" && postRes.state === "success") {
return (
<div>
<CommentNodes
@ -607,7 +626,7 @@ export class Post extends Component<any, PostState> {
const showContextButton = depth ? depth > 0 : false;
return (
res.state == "success" && (
res.state === "success" && (
<div>
{!!this.state.commentId && (
<>
@ -664,10 +683,10 @@ export class Post extends Component<any, PostState> {
}
commentTree(): CommentNodeI[] {
if (this.state.commentsRes.state == "success") {
if (this.state.commentsRes.state === "success") {
return buildCommentsTree(
this.state.commentsRes.data.comments,
!!this.state.commentId
!!this.state.commentId,
);
} else {
return [];
@ -696,16 +715,16 @@ export class Post extends Component<any, PostState> {
}
handleViewPost(i: Post) {
if (i.state.postRes.state == "success") {
if (i.state.postRes.state === "success") {
const id = i.state.postRes.data.post_view.post.id;
i.context.router.history.push(`/post/${id}`);
}
}
handleViewContext(i: Post) {
if (i.state.commentsRes.state == "success") {
if (i.state.commentsRes.state === "success") {
const parentId = getCommentParentId(
i.state.commentsRes.data.comments.at(0)?.comment
i.state.commentsRes.data.comments.at(0)?.comment,
);
if (parentId) {
i.context.router.history.push(`/comment/${parentId}`);
@ -732,7 +751,7 @@ export class Post extends Component<any, PostState> {
const communityId = followCommunityRes.data.community_view.community.id;
const mui = UserService.Instance.myUserInfo;
if (mui) {
mui.follows = mui.follows.filter(i => i.community.id != communityId);
mui.follows = mui.follows.filter(i => i.community.id !== communityId);
}
}
}
@ -759,10 +778,10 @@ export class Post extends Component<any, PostState> {
async handleBlockCommunity(form: BlockCommunity) {
const blockCommunityRes = await HttpService.client.blockCommunity(form);
if (blockCommunityRes.state == "success") {
if (blockCommunityRes.state === "success") {
updateCommunityBlock(blockCommunityRes.data);
this.setState(s => {
if (s.postRes.state == "success") {
if (s.postRes.state === "success") {
s.postRes.data.community_view.blocked =
blockCommunityRes.data.blocked;
}
@ -772,7 +791,7 @@ export class Post extends Component<any, PostState> {
async handleBlockPerson(form: BlockPerson) {
const blockPersonRes = await HttpService.client.blockPerson(form);
if (blockPersonRes.state == "success") {
if (blockPersonRes.state === "success") {
updatePersonBlock(blockPersonRes.data);
}
}
@ -855,14 +874,14 @@ export class Post extends Component<any, PostState> {
async handleCommentReport(form: CreateCommentReport) {
const reportRes = await HttpService.client.createCommentReport(form);
if (reportRes.state == "success") {
if (reportRes.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
async handlePostReport(form: CreatePostReport) {
const reportRes = await HttpService.client.createPostReport(form);
if (reportRes.state == "success") {
if (reportRes.state === "success") {
toast(I18NextService.i18n.t("report_created"));
}
}
@ -887,7 +906,7 @@ export class Post extends Component<any, PostState> {
async handleTransferCommunity(form: TransferCommunity) {
const transferCommunityRes = await HttpService.client.transferCommunity(
form
form,
);
this.updateCommunityFull(transferCommunityRes);
}
@ -895,8 +914,8 @@ export class Post extends Component<any, PostState> {
async handleFetchChildren(form: GetComments) {
const moreCommentsRes = await HttpService.client.getComments(form);
if (
this.state.commentsRes.state == "success" &&
moreCommentsRes.state == "success"
this.state.commentsRes.state === "success" &&
moreCommentsRes.state === "success"
) {
const newComments = moreCommentsRes.data.comments;
// Remove the first comment, since it is the parent
@ -917,6 +936,11 @@ export class Post extends Component<any, PostState> {
await HttpService.client.markPersonMentionAsRead(form);
}
async handleMarkPostAsRead(form: MarkPostAsRead) {
const res = await HttpService.client.markPostAsRead(form);
this.updatePost(res);
}
async handleBanFromCommunity(form: BanFromCommunity) {
const banRes = await HttpService.client.banFromCommunity(form);
this.updateBan(banRes);
@ -929,21 +953,21 @@ export class Post extends Component<any, PostState> {
updateBanFromCommunity(banRes: RequestState<BanFromCommunityResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (
s.postRes.state == "success" &&
s.postRes.data.post_view.creator.id ==
s.postRes.state === "success" &&
s.postRes.data.post_view.creator.id ===
banRes.data.person_view.person.id
) {
s.postRes.data.post_view.creator_banned_from_community =
banRes.data.banned;
}
if (s.commentsRes.state == "success") {
if (s.commentsRes.state === "success") {
s.commentsRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(
c => (c.creator_banned_from_community = banRes.data.banned)
c => (c.creator_banned_from_community = banRes.data.banned),
);
}
return s;
@ -953,18 +977,18 @@ export class Post extends Component<any, PostState> {
updateBan(banRes: RequestState<BanPersonResponse>) {
// Maybe not necessary
if (banRes.state == "success") {
if (banRes.state === "success") {
this.setState(s => {
if (
s.postRes.state == "success" &&
s.postRes.data.post_view.creator.id ==
s.postRes.state === "success" &&
s.postRes.data.post_view.creator.id ===
banRes.data.person_view.person.id
) {
s.postRes.data.post_view.creator.banned = banRes.data.banned;
}
if (s.commentsRes.state == "success") {
if (s.commentsRes.state === "success") {
s.commentsRes.data.comments
.filter(c => c.creator.id == banRes.data.person_view.person.id)
.filter(c => c.creator.id === banRes.data.person_view.person.id)
.forEach(c => (c.creator.banned = banRes.data.banned));
}
return s;
@ -974,7 +998,7 @@ export class Post extends Component<any, PostState> {
updateCommunity(communityRes: RequestState<CommunityResponse>) {
this.setState(s => {
if (s.postRes.state == "success" && communityRes.state == "success") {
if (s.postRes.state === "success" && communityRes.state === "success") {
s.postRes.data.community_view = communityRes.data.community_view;
}
return s;
@ -983,7 +1007,7 @@ export class Post extends Component<any, PostState> {
updateCommunityFull(res: RequestState<GetCommunityResponse>) {
this.setState(s => {
if (s.postRes.state == "success" && res.state == "success") {
if (s.postRes.state === "success" && res.state === "success") {
s.postRes.data.community_view = res.data.community_view;
s.postRes.data.moderators = res.data.moderators;
}
@ -993,7 +1017,7 @@ export class Post extends Component<any, PostState> {
updatePost(post: RequestState<PostResponse>) {
this.setState(s => {
if (s.postRes.state == "success" && post.state == "success") {
if (s.postRes.state === "success" && post.state === "success") {
s.postRes.data.post_view = post.data.post_view;
}
return s;
@ -1001,7 +1025,7 @@ export class Post extends Component<any, PostState> {
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
if (purgeRes.state === "success") {
toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
@ -1015,7 +1039,7 @@ export class Post extends Component<any, PostState> {
// Set finished for the parent
s.finished.set(
getCommentParentId(res.data.comment_view.comment) ?? 0,
true
true,
);
}
return s;
@ -1024,10 +1048,10 @@ export class Post extends Component<any, PostState> {
findAndUpdateComment(res: RequestState<CommentResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments = editComment(
res.data.comment_view,
s.commentsRes.data.comments
s.commentsRes.data.comments,
);
s.finished.set(res.data.comment_view.comment.id, true);
}
@ -1037,10 +1061,10 @@ export class Post extends Component<any, PostState> {
findAndUpdateCommentReply(res: RequestState<CommentReplyResponse>) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
if (s.commentsRes.state === "success" && res.state === "success") {
s.commentsRes.data.comments = editWith(
res.data.comment_reply_view,
s.commentsRes.data.comments
s.commentsRes.data.comments,
);
}
return s;
@ -1050,7 +1074,7 @@ export class Post extends Component<any, PostState> {
updateModerators(res: RequestState<AddModToCommunityResponse>) {
// Update the moderators
this.setState(s => {
if (s.postRes.state == "success" && res.state == "success") {
if (s.postRes.state === "success" && res.state === "success") {
s.postRes.data.moderators = res.data.moderators;
}
return s;

View file

@ -94,7 +94,7 @@ export class CreatePrivateMessage extends Component<
}
get documentTitle(): string {
if (this.state.recipientRes.state == "success") {
if (this.state.recipientRes.state === "success") {
const name_ = this.state.recipientRes.data.person_view.person.name;
return `${I18NextService.i18n.t("create_private_message")} - ${name_}`;
} else {
@ -144,7 +144,7 @@ export class CreatePrivateMessage extends Component<
async handlePrivateMessageCreate(form: CreatePrivateMessageI) {
const res = await HttpService.client.createPrivateMessage(form);
if (res.state == "success") {
if (res.state === "success") {
toast(I18NextService.i18n.t("message_sent"));
// Navigate to the front

View file

@ -56,9 +56,9 @@ export class PrivateMessageForm extends Component<
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageFormProps>
nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageFormProps>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState({ loading: false, content: undefined, previewMode: false });
}
}

View file

@ -29,9 +29,9 @@ export class PrivateMessageReport extends Component<Props, State> {
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & Props>
nextProps: Readonly<{ children?: InfernoNode } & Props>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState({ loading: false });
}
}
@ -40,7 +40,7 @@ export class PrivateMessageReport extends Component<Props, State> {
const r = this.props.report;
const pmr = r.private_message_report;
const tippyContent = I18NextService.i18n.t(
r.private_message_report.resolved ? "unresolve_report" : "resolve_report"
r.private_message_report.resolved ? "unresolve_report" : "resolve_report",
);
return (

View file

@ -59,15 +59,15 @@ export class PrivateMessage extends Component<
get mine(): boolean {
return (
UserService.Instance.myUserInfo?.local_user_view.person.id ==
UserService.Instance.myUserInfo?.local_user_view.person.id ===
this.props.private_message_view.creator.id
);
}
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageProps>
nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageProps>,
): void {
if (this.props != nextProps) {
if (this.props !== nextProps) {
this.setState({
showReply: false,
showEdit: false,

View file

@ -209,20 +209,20 @@ const communityListing = ({
getListing(
<CommunityLink community={community} />,
subscribers,
"number_of_subscribers"
"number_of_subscribers",
);
const personListing = ({ person, counts: { comment_count } }: PersonView) =>
getListing(
<PersonListing person={person} showApubName />,
comment_count,
"number_of_comments"
"number_of_comments",
);
function getListing(
listing: JSX.ElementClass,
count: number,
translationKey: "number_of_comments" | "number_of_subscribers"
translationKey: "number_of_comments" | "number_of_subscribers",
) {
return (
<>
@ -386,7 +386,7 @@ export class Search extends Component<any, SearchState> {
};
listCommunitiesResponse = await client.listCommunities(
listCommunitiesForm
listCommunitiesForm,
);
}
@ -431,7 +431,7 @@ export class Search extends Component<any, SearchState> {
auth,
};
resolveObjectResponse = await HttpService.silent_client.resolveObject(
resolveObjectForm
resolveObjectForm,
);
// If we return this object with a state of failed, the catch-all-handler will redirect
@ -545,7 +545,7 @@ export class Search extends Component<any, SearchState> {
} = this.state;
const hasCommunities =
communitiesRes.state == "success" &&
communitiesRes.state === "success" &&
communitiesRes.data.communities.length > 0;
return (
@ -564,7 +564,7 @@ export class Search extends Component<any, SearchState> {
{searchTypes.map(option => (
<option value={option} key={option}>
{I18NextService.i18n.t(
option.toString().toLowerCase() as NoOptionI18nKeys
option.toString().toLowerCase() as NoOptionI18nKeys,
)}
</option>
))}
@ -619,7 +619,7 @@ export class Search extends Component<any, SearchState> {
} = this.state;
// Push the possible resolve / federated objects first
if (resolveObjectResponse.state == "success") {
if (resolveObjectResponse.state === "success") {
const { comment, post, community, person } = resolveObjectResponse.data;
if (comment) {
@ -646,7 +646,7 @@ export class Search extends Component<any, SearchState> {
...(posts?.map(postViewToCombined) ?? []),
...(communities?.map(communityViewToCombined) ?? []),
...(users?.map(personViewSafeToCombined) ?? []),
]
],
);
}
@ -663,8 +663,8 @@ export class Search extends Component<any, SearchState> {
(b.data as PersonView).counts.comment_score) -
((a.data as CommentView | PostView).counts.score |
(a.data as CommunityView).counts.subscribers |
(a.data as PersonView).counts.comment_score)
)
(a.data as PersonView).counts.comment_score),
),
);
}
@ -706,6 +706,7 @@ export class Search extends Component<any, SearchState> {
onAddModToCommunity={() => {}}
onAddAdmin={() => {}}
onTransferCommunity={() => {}}
onMarkPostAsRead={() => {}}
/>
)}
{i.type_ === "comments" && (
@ -856,6 +857,7 @@ export class Search extends Component<any, SearchState> {
onAddModToCommunity={() => {}}
onAddAdmin={() => {}}
onTransferCommunity={() => {}}
onMarkPostAsRead={() => {}}
/>
</div>
</div>
@ -984,7 +986,7 @@ export class Search extends Component<any, SearchState> {
this.setState({ searchCreatorLoading: true });
const selectedChoice = creatorSearchOptions.find(
choice => getIdFromString(choice.value) === creatorId
choice => getIdFromString(choice.value) === creatorId,
);
if (selectedChoice) {
@ -1011,7 +1013,7 @@ export class Search extends Component<any, SearchState> {
const newOptions: Choice[] = [];
const selectedChoice = communitySearchOptions.find(
choice => getIdFromString(choice.value) === communityId
choice => getIdFromString(choice.value) === communityId,
);
if (selectedChoice) {

View file

@ -23,6 +23,14 @@ export let md: MarkdownIt = new MarkdownIt();
export let mdNoImages: MarkdownIt = new MarkdownIt();
// Zero disables all rules.
// Only explicitly allow a limited set of rules safe for use in post titles.
export const mdLimited: MarkdownIt = new MarkdownIt("zero").enable([
"emphasis",
"backticks",
"strikethrough",
]);
export const customEmojis: EmojiMartCategory[] = [];
export let customEmojisLookup: Map<string, CustomEmojiView> = new Map<
@ -43,7 +51,7 @@ export function mdToHtmlNoImages(text: string) {
}
export function mdToHtmlInline(text: string) {
return { __html: md.renderInline(text) };
return { __html: mdLimited.renderInline(text) };
}
const spoilerConfig = {
@ -183,13 +191,13 @@ export function setupMarkdown() {
idx: number,
options: MarkdownIt.Options,
env: any,
self: Renderer
self: Renderer,
) {
//Provide custom renderer for our emojis to allow us to add a css class and force size dimensions on them.
const item = tokens[idx] as any;
const title = item.attrs.length >= 3 ? item.attrs[2][1] : "";
const customEmoji = customEmojisLookup.get(title);
const isCustomEmoji = customEmoji != undefined;
const isCustomEmoji = customEmoji !== undefined;
if (!isCustomEmoji) {
return defaultRenderer?.(tokens, idx, options, env, self) ?? "";
}
@ -207,7 +215,7 @@ export function setupMarkdown() {
export function setupEmojiDataModel(custom_emoji_views: CustomEmojiView[]) {
const groupedEmojis = groupBy(
custom_emoji_views,
x => x.custom_emoji.category
x => x.custom_emoji.category,
);
for (const [category, emojis] of Object.entries(groupedEmojis)) {
customEmojis.push({
@ -222,7 +230,7 @@ export function setupEmojiDataModel(custom_emoji_views: CustomEmojiView[]) {
});
}
customEmojisLookup = new Map(
custom_emoji_views.map(view => [view.custom_emoji.shortcode, view])
custom_emoji_views.map(view => [view.custom_emoji.shortcode, view]),
);
}
@ -234,9 +242,9 @@ export function updateEmojiDataModel(custom_emoji_view: CustomEmojiView) {
skins: [{ src: custom_emoji_view.custom_emoji.image_url }],
};
const categoryIndex = customEmojis.findIndex(
x => x.id == custom_emoji_view.custom_emoji.category
x => x.id === custom_emoji_view.custom_emoji.category,
);
if (categoryIndex == -1) {
if (categoryIndex === -1) {
customEmojis.push({
id: custom_emoji_view.custom_emoji.category,
name: custom_emoji_view.custom_emoji.category,
@ -244,9 +252,9 @@ export function updateEmojiDataModel(custom_emoji_view: CustomEmojiView) {
});
} else {
const emojiIndex = customEmojis[categoryIndex].emojis.findIndex(
x => x.id == custom_emoji_view.custom_emoji.shortcode
x => x.id === custom_emoji_view.custom_emoji.shortcode,
);
if (emojiIndex == -1) {
if (emojiIndex === -1) {
customEmojis[categoryIndex].emojis.push(emoji);
} else {
customEmojis[categoryIndex].emojis[emojiIndex] = emoji;
@ -254,7 +262,7 @@ export function updateEmojiDataModel(custom_emoji_view: CustomEmojiView) {
}
customEmojisLookup.set(
custom_emoji_view.custom_emoji.shortcode,
custom_emoji_view
custom_emoji_view,
);
}
@ -268,10 +276,10 @@ export function removeFromEmojiDataModel(id: number) {
}
if (!view) return;
const categoryIndex = customEmojis.findIndex(
x => x.id == view?.custom_emoji.category
x => x.id === view?.custom_emoji.category,
);
const emojiIndex = customEmojis[categoryIndex].emojis.findIndex(
x => x.id == view?.custom_emoji.shortcode
x => x.id === view?.custom_emoji.shortcode,
);
customEmojis[categoryIndex].emojis = customEmojis[
categoryIndex
@ -282,7 +290,7 @@ export function removeFromEmojiDataModel(id: number) {
export function getEmojiMart(
onEmojiSelect: (e: any) => void,
customPickerOptions: any = {}
customPickerOptions: any = {},
) {
const pickerOptions = {
...customPickerOptions,
@ -306,10 +314,9 @@ export function setupTribute() {
return `${item.original.val} ${shortName}`;
},
selectTemplate: (item: any) => {
const customEmoji = customEmojisLookup.get(
item.original.key
)?.custom_emoji;
if (customEmoji == undefined) return `${item.original.val}`;
const customEmoji = customEmojisLookup.get(item.original.key)
?.custom_emoji;
if (customEmoji === undefined) return `${item.original.val}`;
else
return `![${customEmoji.alt_text}](${customEmoji.image_url} "${customEmoji.shortcode}")`;
},
@ -321,7 +328,7 @@ export function setupTribute() {
Array.from(customEmojisLookup.entries()).map(k => ({
key: k[0],
val: `<img class="icon icon-emoji" src="${k[1].custom_emoji.image_url}" title="${k[1].custom_emoji.shortcode}" alt="${k[1].custom_emoji.alt_text}" />`,
}))
})),
),
allowSpaces: false,
autocompleteMode: true,

View file

@ -49,7 +49,7 @@ class WrappedLemmyHttpClient {
this.#client = client;
for (const key of Object.getOwnPropertyNames(
Object.getPrototypeOf(this.#client)
Object.getPrototypeOf(this.#client),
)) {
if (key !== "constructor") {
WrappedLemmyHttpClient.prototype[key] = async (...args) => {
@ -80,7 +80,7 @@ export function wrapClient(client: LemmyHttp, silent = false) {
// unfortunately, this verbose cast is necessary
return new WrappedLemmyHttpClient(
client,
silent
silent,
) as unknown as WrappedLemmyHttp;
}

View file

@ -28,7 +28,7 @@ export function pictrsDeleteToast(filename: string, deleteUrl: string) {
"failed_to_delete_picture",
{
filename,
}
},
);
const backgroundColor = `var(--bs-light)`;

View file

@ -4,7 +4,7 @@ import { CommentNodeI } from "../../interfaces";
export default function buildCommentsTree(
comments: CommentView[],
parentComment: boolean
parentComment: boolean,
): CommentNodeI[] {
const map = new Map<number, CommentNodeI>();
const depthOffset = !parentComment

View file

@ -2,7 +2,7 @@ import { CommentView } from "lemmy-js-client";
import { CommentNodeI } from "../../interfaces";
export default function commentsToFlatNodes(
comments: CommentView[]
comments: CommentView[],
): CommentNodeI[] {
const nodes: CommentNodeI[] = [];
for (const comment of comments) {

View file

@ -3,7 +3,7 @@ import { hostname } from "@utils/helpers";
import { CommunityTribute } from "@utils/types";
export default async function communitySearch(
text: string
text: string,
): Promise<CommunityTribute[]> {
const communitiesResponse = await fetchCommunities(text);

View file

@ -1,7 +1,7 @@
import { CommentSortType, SortType } from "lemmy-js-client";
export default function convertCommentSortType(
sort: SortType
sort: SortType,
): CommentSortType {
switch (sort) {
case "TopAll":

View file

@ -3,7 +3,7 @@ import { CommentReplyView } from "lemmy-js-client";
export default function editCommentReply(
data: CommentReplyView,
replies: CommentReplyView[]
replies: CommentReplyView[],
): CommentReplyView[] {
return editListImmutable("comment_reply", data, replies);
}

View file

@ -3,7 +3,7 @@ import { CommentReportView } from "lemmy-js-client";
export default function editCommentReport(
data: CommentReportView,
reports: CommentReportView[]
reports: CommentReportView[],
): CommentReportView[] {
return editListImmutable("comment_report", data, reports);
}

View file

@ -3,7 +3,7 @@ import { CommentView } from "lemmy-js-client";
export default function editComment(
data: CommentView,
comments: CommentView[]
comments: CommentView[],
): CommentView[] {
return editListImmutable("comment", data, comments);
}

View file

@ -3,7 +3,7 @@ import { CommunityView } from "lemmy-js-client";
export default function editCommunity(
data: CommunityView,
communities: CommunityView[]
communities: CommunityView[],
): CommunityView[] {
return editListImmutable("community", data, communities);
}

View file

@ -3,7 +3,7 @@ import { PersonMentionView } from "lemmy-js-client";
export default function editMention(
data: PersonMentionView,
comments: PersonMentionView[]
comments: PersonMentionView[],
): PersonMentionView[] {
return editListImmutable("person_mention", data, comments);
}

View file

@ -3,7 +3,7 @@ import { PostReportView } from "lemmy-js-client";
export default function editPostReport(
data: PostReportView,
reports: PostReportView[]
reports: PostReportView[],
) {
return editListImmutable("post_report", data, reports);
}

View file

@ -3,7 +3,7 @@ import { PostView } from "lemmy-js-client";
export default function editPost(
data: PostView,
posts: PostView[]
posts: PostView[],
): PostView[] {
return editListImmutable("post", data, posts);
}

View file

@ -3,7 +3,7 @@ import { PrivateMessageReportView } from "lemmy-js-client";
export default function editPrivateMessageReport(
data: PrivateMessageReportView,
reports: PrivateMessageReportView[]
reports: PrivateMessageReportView[],
): PrivateMessageReportView[] {
return editListImmutable("private_message_report", data, reports);
}

View file

@ -3,7 +3,7 @@ import { PrivateMessageView } from "lemmy-js-client";
export default function editPrivateMessage(
data: PrivateMessageView,
messages: PrivateMessageView[]
messages: PrivateMessageView[],
): PrivateMessageView[] {
return editListImmutable("private_message", data, messages);
}

View file

@ -3,7 +3,7 @@ import { RegistrationApplicationView } from "lemmy-js-client";
export default function editRegistrationApplication(
data: RegistrationApplicationView,
apps: RegistrationApplicationView[]
apps: RegistrationApplicationView[],
): RegistrationApplicationView[] {
return editListImmutable("registration_application", data, apps);
}

View file

@ -2,13 +2,13 @@ import { WithComment } from "@utils/types";
export default function editWith<D extends WithComment, L extends WithComment>(
{ comment, counts, saved, my_vote }: D,
list: L[]
list: L[],
) {
return [
...list.map(c =>
c.comment.id === comment.id
? { ...c, comment, counts, saved, my_vote }
: c
: c,
),
];
}

View file

@ -1,7 +1,7 @@
import { Comment } from "lemmy-js-client";
export default function getCommentParentId(
comment?: Comment
comment?: Comment,
): number | undefined {
const split = comment?.path.split(".");
// remove the 0

View file

@ -1,7 +1,7 @@
import { Comment } from "lemmy-js-client";
export default function getDepthFromComment(
comment?: Comment
comment?: Comment,
): number | undefined {
const len = comment?.path.split(".").length;
return len ? len - 2 : undefined;

View file

@ -1,6 +1,6 @@
export default function getUpdatedSearchId(
id?: number | null,
urlId?: number | null
urlId?: number | null,
) {
return id === null
? undefined

View file

@ -5,7 +5,7 @@ import { CommentNodeI } from "../../interfaces";
export default function insertCommentIntoTree(
tree: CommentNodeI[],
cv: CommentView,
parentComment: boolean
parentComment: boolean,
) {
// Building a fake node to be used for later
const node: CommentNodeI = {

View file

@ -1,5 +1,5 @@
export default function isAuthPath(pathname: string) {
return /^\/(create_.*?|inbox|settings|admin|reports|registration_applications)\b/g.test(
pathname
pathname,
);
}

View file

@ -3,7 +3,7 @@ import { UserService } from "../../services";
export default function isPostBlocked(
pv: PostView,
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo,
): boolean {
return (
(myUserInfo?.community_blocks

View file

@ -1,9 +1,9 @@
import { VoteType } from "../../interfaces";
export default function newVote(voteType: VoteType, myVote?: number): number {
if (voteType == VoteType.Upvote) {
return myVote == 1 ? 0 : 1;
if (voteType === VoteType.Upvote) {
return myVote === 1 ? 0 : 1;
} else {
return myVote == -1 ? 0 : -1;
return myVote === -1 ? 0 : -1;
}
}

View file

@ -3,7 +3,7 @@ import { UserService } from "../../services";
export default function nsfwCheck(
pv: PostView,
myUserInfo = UserService.Instance.myUserInfo
myUserInfo = UserService.Instance.myUserInfo,
): boolean {
const nsfw = pv.post.nsfw || pv.community.nsfw;
const myShowNsfw = myUserInfo?.local_user_view.local_user.show_nsfw ?? false;

View file

@ -3,7 +3,7 @@ import { hostname } from "@utils/helpers";
import { PersonTribute } from "@utils/types";
export default async function personSearch(
text: string
text: string,
): Promise<PersonTribute[]> {
const usersResponse = await fetchUsers(text);

Some files were not shown because too many files have changed in this diff Show more