Add buttons to protect and unprotect media from quarantine

This commit is contained in:
dklimpel 2021-06-03 20:45:08 +02:00
parent 985673b161
commit fd28c7cf5b
6 changed files with 99 additions and 5 deletions

View File

@ -4,7 +4,7 @@
This project is built using [react-admin](https://marmelab.com/react-admin/).
It needs at least Synapse v1.32.0 for all functions to work as expected!
It needs at least Synapse v1.36.0 for all functions to work as expected!
You get your server version with the request `/_synapse/admin/v1/server_version`.
See also [Synapse version API](https://github.com/matrix-org/synapse/blob/develop/docs/admin_api/version_api.rst).

View File

@ -10,16 +10,20 @@ import {
SaveButton,
SimpleForm,
Toolbar,
useCreate,
useDelete,
useNotify,
useRefresh,
useTranslate,
} from "react-admin";
import IconCancel from "@material-ui/icons/Cancel";
import DeleteSweepIcon from "@material-ui/icons/DeleteSweep";
import Dialog from "@material-ui/core/Dialog";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import DeleteSweepIcon from "@material-ui/icons/DeleteSweep";
import IconCancel from "@material-ui/icons/Cancel";
import LockIcon from "@material-ui/icons/Lock";
import LockOpenIcon from "@material-ui/icons/LockOpen";
const useStyles = makeStyles(
theme => ({
@ -143,3 +147,64 @@ export const DeleteMediaButton = props => {
</Fragment>
);
};
export const ProtectMediaButton = props => {
const { record } = props;
const refresh = useRefresh();
const notify = useNotify();
const [create, { loading }] = useCreate("protect_media");
const [deleteOne] = useDelete("protect_media");
if (!record) return null;
const handleProtect = () => {
create(
{ payload: { data: record } },
{
onSuccess: () => {
notify("resources.protect_media.action.send_success");
refresh();
},
onFailure: () =>
notify("resources.protect_media.action.send_failure", "error"),
}
);
};
const handleUnprotect = () => {
deleteOne(
{ payload: { ...record } },
{
onSuccess: () => {
notify("resources.protect_media.action.send_success");
refresh();
},
onFailure: () =>
notify("resources.protect_media.action.send_failure", "error"),
}
);
};
return (
<Fragment>
{!record.safe_from_quarantine && !record.quarantined_by && (
<Button
label="resources.protect_media.action.create"
onClick={handleProtect}
disabled={loading}
>
<LockIcon />
</Button>
)}
{record.safe_from_quarantine && (
<Button
label="resources.protect_media.action.delete"
onClick={handleUnprotect}
disabled={loading}
>
<LockOpenIcon />
</Button>
)}
</Fragment>
);
};

View File

@ -1,12 +1,12 @@
import React, { cloneElement, Fragment } from "react";
import Avatar from "@material-ui/core/Avatar";
import PersonPinIcon from "@material-ui/icons/PersonPin";
import ContactMailIcon from "@material-ui/icons/ContactMail";
import DevicesIcon from "@material-ui/icons/Devices";
import GetAppIcon from "@material-ui/icons/GetApp";
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
import NotificationsIcon from "@material-ui/icons/Notifications";
import PermMediaIcon from "@material-ui/icons/PermMedia";
import PersonPinIcon from "@material-ui/icons/PersonPin";
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
import ViewListIcon from "@material-ui/icons/ViewList";
import {
ArrayInput,
@ -47,6 +47,7 @@ import {
} from "react-admin";
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
import { DeviceRemoveButton } from "./devices";
import { ProtectMediaButton } from "./media";
import { makeStyles } from "@material-ui/core/styles";
const redirect = (basePath, id, data) => {
@ -454,6 +455,7 @@ export const UserEdit = props => {
<TextField source="upload_name" />
<TextField source="quarantined_by" />
<BooleanField source="safe_from_quarantine" />
<ProtectMediaButton />
<DeleteButton mutationMode="pessimistic" redirect={false} />
</Datagrid>
</ReferenceManyField>

View File

@ -262,6 +262,14 @@ const de = {
"Diese API löscht die lokalen Medien von der Festplatte des eigenen Servers. Dies umfasst alle lokalen Miniaturbilder und Kopien von Medien. Diese API wirkt sich nicht auf Medien aus, die sich in externen Medien-Repositories befinden.",
},
},
protect_media: {
action: {
create: "Schützen",
delete: "Schutz aufheben",
send_success: "Erfolgreich den Schutz-Status geändert.",
send_failure: "Beim Versenden ist ein Fehler aufgetreten.",
},
},
pushers: {
name: "Pusher |||| Pushers",
fields: {

View File

@ -258,6 +258,14 @@ const en = {
"This API deletes the local media from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to external media repositories.",
},
},
protect_media: {
action: {
create: "Protect",
delete: "Unprotect",
send_success: "Successfully changed the protection status.",
send_failure: "An error has occurred.",
},
},
pushers: {
name: "Pusher |||| Pushers",
fields: {

View File

@ -183,6 +183,17 @@ const resourceMap = {
method: "POST",
}),
},
protect_media: {
map: pm => ({ id: pm.media_id }),
create: params => ({
endpoint: `/_synapse/admin/v1/media/protect/${params.media_id}`,
method: "POST",
}),
delete: params => ({
endpoint: `/_synapse/admin/v1/media/unprotect/${params.media_id}`,
method: "POST",
}),
},
servernotices: {
map: n => ({ id: n.event_id }),
create: data => ({