mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-12-23 11:21:26 +00:00
Temp bans (#524)
* Updating translations. * Adding temp bans. * Using new lemmy-js-client with temp bans * Fixing some lint and dep issues
This commit is contained in:
parent
9abe811021
commit
4915193ae5
8 changed files with 1362 additions and 2006 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 1e0bb9920cda13bb128c87e85125b98ab8f319b6
|
Subproject commit 27a29ad5411438e4792e8e298aa5f4a3b60bb908
|
12
package.json
12
package.json
|
@ -20,7 +20,7 @@
|
||||||
"@typescript-eslint/parser": "^5.6.0",
|
"@typescript-eslint/parser": "^5.6.0",
|
||||||
"autosize": "^5.0.1",
|
"autosize": "^5.0.1",
|
||||||
"check-password-strength": "^2.0.3",
|
"check-password-strength": "^2.0.3",
|
||||||
"choices.js": "^9.0.1",
|
"choices.js": "^10.0.0",
|
||||||
"emoji-short-name": "^1.0.0",
|
"emoji-short-name": "^1.0.0",
|
||||||
"express": "~4.17.1",
|
"express": "~4.17.1",
|
||||||
"i18next": "^21.5.4",
|
"i18next": "^21.5.4",
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"register-service-worker": "^1.7.2",
|
"register-service-worker": "^1.7.2",
|
||||||
"rxjs": "^7.4.0",
|
"rxjs": "^7.4.0",
|
||||||
|
"sass": "^1.47.0",
|
||||||
"serialize-javascript": "^6.0.0",
|
"serialize-javascript": "^6.0.0",
|
||||||
"tippy.js": "^6.3.7",
|
"tippy.js": "^6.3.7",
|
||||||
"toastify-js": "^1.11.2",
|
"toastify-js": "^1.11.2",
|
||||||
|
@ -51,12 +52,12 @@
|
||||||
"@babel/core": "^7.16.0",
|
"@babel/core": "^7.16.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.16.4",
|
"@babel/plugin-transform-runtime": "^7.16.4",
|
||||||
"@babel/plugin-transform-typescript": "^7.16.1",
|
"@babel/plugin-transform-typescript": "^7.16.1",
|
||||||
"@babel/preset-env": "7.16.4",
|
"@babel/preset-env": "7.16.7",
|
||||||
"@babel/preset-typescript": "^7.16.0",
|
"@babel/preset-typescript": "^7.16.0",
|
||||||
"@babel/runtime": "^7.16.3",
|
"@babel/runtime": "^7.16.3",
|
||||||
"@types/autosize": "^4.0.0",
|
"@types/autosize": "^4.0.0",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/node": "^16.11.11",
|
"@types/node": "^17.0.8",
|
||||||
"@types/node-fetch": "^2.5.11",
|
"@types/node-fetch": "^2.5.11",
|
||||||
"@types/serialize-javascript": "^5.0.1",
|
"@types/serialize-javascript": "^5.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
||||||
|
@ -72,11 +73,10 @@
|
||||||
"husky": "^7.0.4",
|
"husky": "^7.0.4",
|
||||||
"import-sort-style-module": "^6.0.0",
|
"import-sort-style-module": "^6.0.0",
|
||||||
"iso-639-1": "^2.1.10",
|
"iso-639-1": "^2.1.10",
|
||||||
"lemmy-js-client": "0.15.0-rc.6",
|
"lemmy-js-client": "0.15.0-rc.34",
|
||||||
"lint-staged": "^12.1.2",
|
"lint-staged": "^12.1.2",
|
||||||
"mini-css-extract-plugin": "^2.4.5",
|
"mini-css-extract-plugin": "^2.4.5",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"node-sass": "^7.0.0",
|
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
"prettier-plugin-import-sort": "^0.0.7",
|
"prettier-plugin-import-sort": "^0.0.7",
|
||||||
"prettier-plugin-organize-imports": "^2.3.4",
|
"prettier-plugin-organize-imports": "^2.3.4",
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
"typescript": "^4.5.2",
|
"typescript": "^4.5.2",
|
||||||
"webpack": "5.65.0",
|
"webpack": "5.65.0",
|
||||||
"webpack-cli": "^4.9.1",
|
"webpack-cli": "^4.9.1",
|
||||||
"webpack-dev-server": "4.6.0",
|
"webpack-dev-server": "4.7.2",
|
||||||
"webpack-node-externals": "^3.0.0"
|
"webpack-node-externals": "^3.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -28,7 +28,8 @@ import {
|
||||||
authField,
|
authField,
|
||||||
canMod,
|
canMod,
|
||||||
colorList,
|
colorList,
|
||||||
getUnixTime,
|
futureDaysToUnixTime,
|
||||||
|
isBanned,
|
||||||
isMod,
|
isMod,
|
||||||
mdToHtml,
|
mdToHtml,
|
||||||
numToSI,
|
numToSI,
|
||||||
|
@ -51,7 +52,7 @@ interface CommentNodeState {
|
||||||
showBanDialog: boolean;
|
showBanDialog: boolean;
|
||||||
removeData: boolean;
|
removeData: boolean;
|
||||||
banReason: string;
|
banReason: string;
|
||||||
banExpires: string;
|
banExpireDays: number;
|
||||||
banType: BanType;
|
banType: BanType;
|
||||||
showConfirmTransferSite: boolean;
|
showConfirmTransferSite: boolean;
|
||||||
showConfirmTransferCommunity: boolean;
|
showConfirmTransferCommunity: boolean;
|
||||||
|
@ -96,7 +97,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
showBanDialog: false,
|
showBanDialog: false,
|
||||||
removeData: false,
|
removeData: false,
|
||||||
banReason: null,
|
banReason: null,
|
||||||
banExpires: null,
|
banExpireDays: null,
|
||||||
banType: BanType.Community,
|
banType: BanType.Community,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
viewSource: false,
|
viewSource: false,
|
||||||
|
@ -187,7 +188,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{i18n.t("bot_account").toLowerCase()}
|
{i18n.t("bot_account").toLowerCase()}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(cv.creator_banned_from_community || cv.creator.banned) && (
|
{(cv.creator_banned_from_community || isBanned(cv.creator)) && (
|
||||||
<div className="badge badge-danger mr-2">
|
<div className="badge badge-danger mr-2">
|
||||||
{i18n.t("banned")}
|
{i18n.t("banned")}
|
||||||
</div>
|
</div>
|
||||||
|
@ -614,7 +615,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{this.canAdmin && (
|
{this.canAdmin && (
|
||||||
<>
|
<>
|
||||||
{!this.isAdmin &&
|
{!this.isAdmin &&
|
||||||
(!cv.creator.banned ? (
|
(!isBanned(cv.creator) ? (
|
||||||
<button
|
<button
|
||||||
class="btn btn-link btn-animate text-muted"
|
class="btn btn-link btn-animate text-muted"
|
||||||
onClick={linkEvent(
|
onClick={linkEvent(
|
||||||
|
@ -637,7 +638,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{i18n.t("unban_from_site")}
|
{i18n.t("unban_from_site")}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
{!cv.creator.banned &&
|
{!isBanned(cv.creator) &&
|
||||||
cv.creator.local &&
|
cv.creator.local &&
|
||||||
(!this.state.showConfirmAppointAsAdmin ? (
|
(!this.state.showConfirmAppointAsAdmin ? (
|
||||||
<button
|
<button
|
||||||
|
@ -797,7 +798,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
)}
|
)}
|
||||||
{this.state.showBanDialog && (
|
{this.state.showBanDialog && (
|
||||||
<form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
|
<form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
|
||||||
<div class="form-group row">
|
<div class="form-group row col-12">
|
||||||
<label
|
<label
|
||||||
class="col-form-label"
|
class="col-form-label"
|
||||||
htmlFor={`mod-ban-reason-${cv.comment.id}`}
|
htmlFor={`mod-ban-reason-${cv.comment.id}`}
|
||||||
|
@ -812,6 +813,20 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
value={this.state.banReason}
|
value={this.state.banReason}
|
||||||
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
||||||
/>
|
/>
|
||||||
|
<label
|
||||||
|
class="col-form-label"
|
||||||
|
htmlFor={`mod-ban-expires-${cv.comment.id}`}
|
||||||
|
>
|
||||||
|
{i18n.t("expires")}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id={`mod-ban-expires-${cv.comment.id}`}
|
||||||
|
class="form-control mr-2"
|
||||||
|
placeholder={i18n.t("number_of_days")}
|
||||||
|
value={this.state.banExpireDays}
|
||||||
|
onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
|
||||||
|
/>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input
|
<input
|
||||||
|
@ -1191,8 +1206,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleModBanExpiresChange(i: CommentNode, event: any) {
|
handleModBanExpireDaysChange(i: CommentNode, event: any) {
|
||||||
i.state.banExpires = event.target.value;
|
i.state.banExpireDays = event.target.value;
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,7 +1238,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
ban,
|
ban,
|
||||||
remove_data: i.state.removeData,
|
remove_data: i.state.removeData,
|
||||||
reason: i.state.banReason,
|
reason: i.state.banReason,
|
||||||
expires: getUnixTime(i.state.banExpires),
|
expires: futureDaysToUnixTime(i.state.banExpireDays),
|
||||||
auth: authField(),
|
auth: authField(),
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.send(wsClient.banFromCommunity(form));
|
WebSocketService.Instance.send(wsClient.banFromCommunity(form));
|
||||||
|
@ -1238,7 +1253,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
ban,
|
ban,
|
||||||
remove_data: i.state.removeData,
|
remove_data: i.state.removeData,
|
||||||
reason: i.state.banReason,
|
reason: i.state.banReason,
|
||||||
expires: getUnixTime(i.state.banExpires),
|
expires: futureDaysToUnixTime(i.state.banExpireDays),
|
||||||
auth: authField(),
|
auth: authField(),
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.send(wsClient.banPerson(form));
|
WebSocketService.Instance.send(wsClient.banPerson(form));
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import autosize from "autosize";
|
import autosize from "autosize";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import {
|
import {
|
||||||
|
BannedPersonsResponse,
|
||||||
|
GetBannedPersons,
|
||||||
GetSiteConfig,
|
GetSiteConfig,
|
||||||
GetSiteConfigResponse,
|
GetSiteConfigResponse,
|
||||||
GetSiteResponse,
|
GetSiteResponse,
|
||||||
|
PersonViewSafe,
|
||||||
SaveSiteConfig,
|
SaveSiteConfig,
|
||||||
SiteResponse,
|
SiteResponse,
|
||||||
UserOperation,
|
UserOperation,
|
||||||
|
@ -34,6 +37,7 @@ interface AdminSettingsState {
|
||||||
siteConfigRes: GetSiteConfigResponse;
|
siteConfigRes: GetSiteConfigResponse;
|
||||||
siteConfigForm: SaveSiteConfig;
|
siteConfigForm: SaveSiteConfig;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
banned: PersonViewSafe[];
|
||||||
siteConfigLoading: boolean;
|
siteConfigLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +49,12 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
siteConfigForm: {
|
siteConfigForm: {
|
||||||
config_hjson: null,
|
config_hjson: null,
|
||||||
auth: authField(),
|
auth: null,
|
||||||
},
|
},
|
||||||
siteConfigRes: {
|
siteConfigRes: {
|
||||||
config_hjson: null,
|
config_hjson: null,
|
||||||
},
|
},
|
||||||
|
banned: [],
|
||||||
loading: true,
|
loading: true,
|
||||||
siteConfigLoading: null,
|
siteConfigLoading: null,
|
||||||
};
|
};
|
||||||
|
@ -67,20 +72,34 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
this.state.siteConfigRes = this.isoData.routeData[0];
|
this.state.siteConfigRes = this.isoData.routeData[0];
|
||||||
this.state.siteConfigForm.config_hjson =
|
this.state.siteConfigForm.config_hjson =
|
||||||
this.state.siteConfigRes.config_hjson;
|
this.state.siteConfigRes.config_hjson;
|
||||||
|
this.state.banned = this.isoData.routeData[1].banned;
|
||||||
this.state.siteConfigLoading = false;
|
this.state.siteConfigLoading = false;
|
||||||
this.state.loading = false;
|
this.state.loading = false;
|
||||||
} else {
|
} else {
|
||||||
|
this.state.siteConfigForm.auth = authField();
|
||||||
WebSocketService.Instance.send(
|
WebSocketService.Instance.send(
|
||||||
wsClient.getSiteConfig({
|
wsClient.getSiteConfig({
|
||||||
auth: authField(),
|
auth: authField(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
WebSocketService.Instance.send(
|
||||||
|
wsClient.getBannedPersons({
|
||||||
|
auth: authField(),
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
|
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
|
||||||
let form: GetSiteConfig = { auth: req.auth };
|
let promises: Promise<any>[] = [];
|
||||||
return [req.client.getSiteConfig(form)];
|
|
||||||
|
let siteConfigForm: GetSiteConfig = { auth: req.auth };
|
||||||
|
promises.push(req.client.getSiteConfig(siteConfigForm));
|
||||||
|
|
||||||
|
let bannedPersonsForm: GetBannedPersons = { auth: req.auth };
|
||||||
|
promises.push(req.client.getBannedPersons(bannedPersonsForm));
|
||||||
|
|
||||||
|
return promises;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -105,10 +124,6 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<HtmlTags
|
|
||||||
title={this.documentTitle}
|
|
||||||
path={this.context.router.route.match.url}
|
|
||||||
/>
|
|
||||||
{this.state.loading ? (
|
{this.state.loading ? (
|
||||||
<h5>
|
<h5>
|
||||||
<Spinner large />
|
<Spinner large />
|
||||||
|
@ -116,6 +131,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
) : (
|
) : (
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
|
<HtmlTags
|
||||||
|
title={this.documentTitle}
|
||||||
|
path={this.context.router.route.match.url}
|
||||||
|
/>
|
||||||
{this.state.siteRes.site_view.site.id && (
|
{this.state.siteRes.site_view.site.id && (
|
||||||
<SiteForm site={this.state.siteRes.site_view.site} />
|
<SiteForm site={this.state.siteRes.site_view.site} />
|
||||||
)}
|
)}
|
||||||
|
@ -149,7 +168,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
<>
|
<>
|
||||||
<h5>{i18n.t("banned_users")}</h5>
|
<h5>{i18n.t("banned_users")}</h5>
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
{this.state.siteRes.banned.map(banned => (
|
{this.state.banned.map(banned => (
|
||||||
<li class="list-inline-item">
|
<li class="list-inline-item">
|
||||||
<PersonListing person={banned.person} />
|
<PersonListing person={banned.person} />
|
||||||
</li>
|
</li>
|
||||||
|
@ -225,6 +244,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
this.state.siteRes.site_view = data.site_view;
|
this.state.siteRes.site_view = data.site_view;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
toast(i18n.t("site_saved"));
|
toast(i18n.t("site_saved"));
|
||||||
|
} else if (op == UserOperation.GetBannedPersons) {
|
||||||
|
let data = wsJsonToRes<BannedPersonsResponse>(msg).data;
|
||||||
|
this.state.banned = data.banned;
|
||||||
|
this.setState(this.state);
|
||||||
} else if (op == UserOperation.GetSiteConfig) {
|
} else if (op == UserOperation.GetSiteConfig) {
|
||||||
let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
|
let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
|
||||||
this.state.siteConfigRes = data;
|
this.state.siteConfigRes = data;
|
||||||
|
|
|
@ -896,19 +896,6 @@ export class Home extends Component<any, HomeState> {
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
} else if (op == UserOperation.BanPerson) {
|
} else if (op == UserOperation.BanPerson) {
|
||||||
let data = wsJsonToRes<BanPersonResponse>(msg).data;
|
let data = wsJsonToRes<BanPersonResponse>(msg).data;
|
||||||
let found = this.state.siteRes.banned.find(
|
|
||||||
p => (p.person.id = data.person_view.person.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove the banned if its found in the list, and the action is an unban
|
|
||||||
if (found && !data.banned) {
|
|
||||||
this.state.siteRes.banned = this.state.siteRes.banned.filter(
|
|
||||||
i => i.person.id !== data.person_view.person.id
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.state.siteRes.banned.push(data.person_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state.posts
|
this.state.posts
|
||||||
.filter(p => p.creator.id == data.person_view.person.id)
|
.filter(p => p.creator.id == data.person_view.person.id)
|
||||||
.forEach(p => (p.creator.banned = data.banned));
|
.forEach(p => (p.creator.banned = data.banned));
|
||||||
|
|
|
@ -26,8 +26,9 @@ import { UserService, WebSocketService } from "../../services";
|
||||||
import {
|
import {
|
||||||
authField,
|
authField,
|
||||||
canMod,
|
canMod,
|
||||||
getUnixTime,
|
futureDaysToUnixTime,
|
||||||
hostname,
|
hostname,
|
||||||
|
isBanned,
|
||||||
isImage,
|
isImage,
|
||||||
isMod,
|
isMod,
|
||||||
isVideo,
|
isVideo,
|
||||||
|
@ -54,7 +55,7 @@ interface PostListingState {
|
||||||
showBanDialog: boolean;
|
showBanDialog: boolean;
|
||||||
removeData: boolean;
|
removeData: boolean;
|
||||||
banReason: string;
|
banReason: string;
|
||||||
banExpires: string;
|
banExpireDays: number;
|
||||||
banType: BanType;
|
banType: BanType;
|
||||||
showConfirmTransferSite: boolean;
|
showConfirmTransferSite: boolean;
|
||||||
showConfirmTransferCommunity: boolean;
|
showConfirmTransferCommunity: boolean;
|
||||||
|
@ -90,7 +91,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
showBanDialog: false,
|
showBanDialog: false,
|
||||||
removeData: false,
|
removeData: false,
|
||||||
banReason: null,
|
banReason: null,
|
||||||
banExpires: null,
|
banExpireDays: null,
|
||||||
banType: BanType.Community,
|
banType: BanType.Community,
|
||||||
showConfirmTransferSite: false,
|
showConfirmTransferSite: false,
|
||||||
showConfirmTransferCommunity: false,
|
showConfirmTransferCommunity: false,
|
||||||
|
@ -294,7 +295,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{(post_view.creator_banned_from_community ||
|
{(post_view.creator_banned_from_community ||
|
||||||
post_view.creator.banned) && (
|
isBanned(post_view.creator)) && (
|
||||||
<span className="mx-1 badge badge-danger">{i18n.t("banned")}</span>
|
<span className="mx-1 badge badge-danger">{i18n.t("banned")}</span>
|
||||||
)}
|
)}
|
||||||
{post_view.creator_blocked && (
|
{post_view.creator_blocked && (
|
||||||
|
@ -900,7 +901,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
{this.canAdmin && (
|
{this.canAdmin && (
|
||||||
<>
|
<>
|
||||||
{!this.isAdmin &&
|
{!this.isAdmin &&
|
||||||
(!post_view.creator.banned ? (
|
(!isBanned(post_view.creator) ? (
|
||||||
<button
|
<button
|
||||||
class="btn btn-link btn-animate text-muted py-0"
|
class="btn btn-link btn-animate text-muted py-0"
|
||||||
onClick={linkEvent(this, this.handleModBanShow)}
|
onClick={linkEvent(this, this.handleModBanShow)}
|
||||||
|
@ -917,7 +918,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
{i18n.t("unban_from_site")}
|
{i18n.t("unban_from_site")}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
{!post_view.creator.banned && post_view.creator.local && (
|
{!isBanned(post_view.creator) && post_view.creator.local && (
|
||||||
<button
|
<button
|
||||||
class="btn btn-link btn-animate text-muted py-0"
|
class="btn btn-link btn-animate text-muted py-0"
|
||||||
onClick={linkEvent(this, this.handleAddAdmin)}
|
onClick={linkEvent(this, this.handleAddAdmin)}
|
||||||
|
@ -1013,7 +1014,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
)}
|
)}
|
||||||
{this.state.showBanDialog && (
|
{this.state.showBanDialog && (
|
||||||
<form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
|
<form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
|
||||||
<div class="form-group row">
|
<div class="form-group row col-12">
|
||||||
<label class="col-form-label" htmlFor="post-listing-ban-reason">
|
<label class="col-form-label" htmlFor="post-listing-ban-reason">
|
||||||
{i18n.t("reason")}
|
{i18n.t("reason")}
|
||||||
</label>
|
</label>
|
||||||
|
@ -1025,6 +1026,17 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
value={this.state.banReason}
|
value={this.state.banReason}
|
||||||
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
||||||
/>
|
/>
|
||||||
|
<label class="col-form-label" htmlFor={`mod-ban-expires`}>
|
||||||
|
{i18n.t("expires")}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id={`mod-ban-expires`}
|
||||||
|
class="form-control mr-2"
|
||||||
|
placeholder={i18n.t("number_of_days")}
|
||||||
|
value={this.state.banExpireDays}
|
||||||
|
onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
|
||||||
|
/>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input
|
<input
|
||||||
|
@ -1496,8 +1508,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleModBanExpiresChange(i: PostListing, event: any) {
|
handleModBanExpireDaysChange(i: PostListing, event: any) {
|
||||||
i.state.banExpires = event.target.value;
|
i.state.banExpireDays = event.target.value;
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,7 +1540,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
ban,
|
ban,
|
||||||
remove_data: i.state.removeData,
|
remove_data: i.state.removeData,
|
||||||
reason: i.state.banReason,
|
reason: i.state.banReason,
|
||||||
expires: getUnixTime(i.state.banExpires),
|
expires: futureDaysToUnixTime(i.state.banExpireDays),
|
||||||
auth: authField(),
|
auth: authField(),
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.send(wsClient.banFromCommunity(form));
|
WebSocketService.Instance.send(wsClient.banFromCommunity(form));
|
||||||
|
@ -1543,7 +1555,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
ban,
|
ban,
|
||||||
remove_data: i.state.removeData,
|
remove_data: i.state.removeData,
|
||||||
reason: i.state.banReason,
|
reason: i.state.banReason,
|
||||||
expires: getUnixTime(i.state.banExpires),
|
expires: futureDaysToUnixTime(i.state.banExpireDays),
|
||||||
auth: authField(),
|
auth: authField(),
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.send(wsClient.banPerson(form));
|
WebSocketService.Instance.send(wsClient.banPerson(form));
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
ListingType,
|
ListingType,
|
||||||
MyUserInfo,
|
MyUserInfo,
|
||||||
PersonBlockView,
|
PersonBlockView,
|
||||||
|
PersonSafe,
|
||||||
PersonViewSafe,
|
PersonViewSafe,
|
||||||
PostReportView,
|
PostReportView,
|
||||||
PostView,
|
PostView,
|
||||||
|
@ -285,6 +286,14 @@ export function getUnixTime(text: string): number {
|
||||||
return text ? new Date(text).getTime() / 1000 : undefined;
|
return text ? new Date(text).getTime() / 1000 : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function futureDaysToUnixTime(days: number): number {
|
||||||
|
return days
|
||||||
|
? Math.trunc(
|
||||||
|
new Date(Date.now() + 1000 * 60 * 60 * 24 * days).getTime() / 1000
|
||||||
|
)
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export function canMod(
|
export function canMod(
|
||||||
myUserInfo: MyUserInfo,
|
myUserInfo: MyUserInfo,
|
||||||
modIds: number[],
|
modIds: number[],
|
||||||
|
@ -1517,3 +1526,16 @@ const SHORTNUM_SI_FORMAT = new Intl.NumberFormat("en-US", {
|
||||||
export function numToSI(value: number): string {
|
export function numToSI(value: number): string {
|
||||||
return SHORTNUM_SI_FORMAT.format(value);
|
return SHORTNUM_SI_FORMAT.format(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isBanned(ps: PersonSafe): boolean {
|
||||||
|
// Add Z to convert from UTC date
|
||||||
|
if (ps.ban_expires) {
|
||||||
|
if (ps.banned && new Date(ps.ban_expires + "Z") > new Date()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ps.banned;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue