mirror of
https://github.com/Awesome-Technologies/synapse-admin.git
synced 2024-10-31 06:55:15 +03:00
Show links to media content from local users and reports (#508)
Change-Id: Ia8993470a9dd5e479c028013b5be6723f569814d
This commit is contained in:
parent
531d8f2d7f
commit
c6f9dbec18
6 changed files with 78 additions and 2 deletions
|
@ -15,6 +15,7 @@ import {
|
||||||
useRecordContext,
|
useRecordContext,
|
||||||
useTranslate,
|
useTranslate,
|
||||||
} from "react-admin";
|
} from "react-admin";
|
||||||
|
import { MXCField } from "./media";
|
||||||
import PageviewIcon from "@mui/icons-material/Pageview";
|
import PageviewIcon from "@mui/icons-material/Pageview";
|
||||||
import ReportIcon from "@mui/icons-material/Warning";
|
import ReportIcon from "@mui/icons-material/Warning";
|
||||||
import ViewListIcon from "@mui/icons-material/ViewList";
|
import ViewListIcon from "@mui/icons-material/ViewList";
|
||||||
|
@ -89,6 +90,8 @@ export const ReportShow = props => {
|
||||||
<TextField source="event_json.type" />
|
<TextField source="event_json.type" />
|
||||||
<TextField source="event_json.content.msgtype" />
|
<TextField source="event_json.content.msgtype" />
|
||||||
<TextField source="event_json.content.body" />
|
<TextField source="event_json.content.body" />
|
||||||
|
<TextField source="event_json.content.info.mimetype" />
|
||||||
|
<MXCField source="event_json.content.url" />
|
||||||
<TextField source="event_json.content.format" />
|
<TextField source="event_json.content.format" />
|
||||||
<TextField source="event_json.content.formatted_body" />
|
<TextField source="event_json.content.formatted_body" />
|
||||||
<TextField source="event_json.content.algorithm" />
|
<TextField source="event_json.content.algorithm" />
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import get from "lodash/get";
|
||||||
import {
|
import {
|
||||||
BooleanInput,
|
BooleanInput,
|
||||||
Button,
|
Button,
|
||||||
|
@ -14,10 +15,12 @@ import {
|
||||||
useRefresh,
|
useRefresh,
|
||||||
useTranslate,
|
useTranslate,
|
||||||
} from "react-admin";
|
} from "react-admin";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import BlockIcon from "@mui/icons-material/Block";
|
import BlockIcon from "@mui/icons-material/Block";
|
||||||
import ClearIcon from "@mui/icons-material/Clear";
|
import ClearIcon from "@mui/icons-material/Clear";
|
||||||
import DeleteSweepIcon from "@mui/icons-material/DeleteSweep";
|
import DeleteSweepIcon from "@mui/icons-material/DeleteSweep";
|
||||||
import {
|
import {
|
||||||
|
Box,
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
DialogContentText,
|
||||||
|
@ -27,7 +30,9 @@ import {
|
||||||
import IconCancel from "@mui/icons-material/Cancel";
|
import IconCancel from "@mui/icons-material/Cancel";
|
||||||
import LockIcon from "@mui/icons-material/Lock";
|
import LockIcon from "@mui/icons-material/Lock";
|
||||||
import LockOpenIcon from "@mui/icons-material/LockOpen";
|
import LockOpenIcon from "@mui/icons-material/LockOpen";
|
||||||
|
import FileOpenIcon from "@mui/icons-material/FileOpen";
|
||||||
import { alpha, useTheme } from "@mui/material/styles";
|
import { alpha, useTheme } from "@mui/material/styles";
|
||||||
|
import { getMediaUrl } from "../synapse/synapse";
|
||||||
|
|
||||||
const DeleteMediaDialog = ({ open, loading, onClose, onSubmit }) => {
|
const DeleteMediaDialog = ({ open, loading, onClose, onSubmit }) => {
|
||||||
const translate = useTranslate();
|
const translate = useTranslate();
|
||||||
|
@ -333,3 +338,49 @@ export const QuarantineMediaButton = props => {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ViewMediaButton = ({ media_id, label }) => {
|
||||||
|
const translate = useTranslate();
|
||||||
|
const url = getMediaUrl(media_id);
|
||||||
|
return (
|
||||||
|
<Box style={{ whiteSpace: "pre" }}>
|
||||||
|
<Tooltip title={translate("resources.users_media.action.open")}>
|
||||||
|
<span>
|
||||||
|
<Button
|
||||||
|
component={Link}
|
||||||
|
to={url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
style={{ minWidth: 0, paddingLeft: 0, paddingRight: 0 }}
|
||||||
|
>
|
||||||
|
<FileOpenIcon />
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
{label}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MediaIDField = ({ source }) => {
|
||||||
|
const homeserver = localStorage.getItem("home_server");
|
||||||
|
const record = useRecordContext();
|
||||||
|
if (!record) return null;
|
||||||
|
|
||||||
|
const src = get(record, source)?.toString();
|
||||||
|
if (!src) return null;
|
||||||
|
|
||||||
|
return <ViewMediaButton media_id={`${homeserver}/${src}`} label={src} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MXCField = ({ source }) => {
|
||||||
|
const record = useRecordContext();
|
||||||
|
if (!record) return null;
|
||||||
|
|
||||||
|
const src = get(record, source)?.toString();
|
||||||
|
if (!src) return null;
|
||||||
|
|
||||||
|
const media_id = src.replace("mxc://", "");
|
||||||
|
|
||||||
|
return <ViewMediaButton media_id={media_id} label={src} />;
|
||||||
|
};
|
||||||
|
|
|
@ -51,7 +51,11 @@ import { Link } from "react-router-dom";
|
||||||
import AvatarField from "./AvatarField";
|
import AvatarField from "./AvatarField";
|
||||||
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
|
||||||
import { DeviceRemoveButton } from "./devices";
|
import { DeviceRemoveButton } from "./devices";
|
||||||
import { ProtectMediaButton, QuarantineMediaButton } from "./media";
|
import {
|
||||||
|
MediaIDField,
|
||||||
|
ProtectMediaButton,
|
||||||
|
QuarantineMediaButton,
|
||||||
|
} from "./media";
|
||||||
|
|
||||||
const choices_medium = [
|
const choices_medium = [
|
||||||
{ id: "email", name: "resources.users.email" },
|
{ id: "email", name: "resources.users.email" },
|
||||||
|
@ -449,13 +453,13 @@ export const UserEdit = props => {
|
||||||
sort={{ field: "created_ts", order: "DESC" }}
|
sort={{ field: "created_ts", order: "DESC" }}
|
||||||
>
|
>
|
||||||
<Datagrid style={{ width: "100%" }}>
|
<Datagrid style={{ width: "100%" }}>
|
||||||
|
<MediaIDField source="media_id" />
|
||||||
<DateField source="created_ts" showTime options={date_format} />
|
<DateField source="created_ts" showTime options={date_format} />
|
||||||
<DateField
|
<DateField
|
||||||
source="last_access_ts"
|
source="last_access_ts"
|
||||||
showTime
|
showTime
|
||||||
options={date_format}
|
options={date_format}
|
||||||
/>
|
/>
|
||||||
<TextField source="media_id" />
|
|
||||||
<NumberField source="media_length" />
|
<NumberField source="media_length" />
|
||||||
<TextField source="media_type" />
|
<TextField source="media_type" />
|
||||||
<TextField source="upload_name" />
|
<TextField source="upload_name" />
|
||||||
|
|
|
@ -208,6 +208,9 @@ const de = {
|
||||||
format: "Nachrichtenformat",
|
format: "Nachrichtenformat",
|
||||||
formatted_body: "Formatierter Nachrichteninhalt",
|
formatted_body: "Formatierter Nachrichteninhalt",
|
||||||
algorithm: "Verschlüsselungsalgorithmus",
|
algorithm: "Verschlüsselungsalgorithmus",
|
||||||
|
info: {
|
||||||
|
mimetype: "Typ",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -256,6 +259,9 @@ const de = {
|
||||||
created_ts: "Erstellt",
|
created_ts: "Erstellt",
|
||||||
last_access_ts: "Letzter Zugriff",
|
last_access_ts: "Letzter Zugriff",
|
||||||
},
|
},
|
||||||
|
action: {
|
||||||
|
open: "Mediendatei in neuem Fenster öffnen",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
delete_media: {
|
delete_media: {
|
||||||
name: "Medien",
|
name: "Medien",
|
||||||
|
|
|
@ -205,6 +205,10 @@ const en = {
|
||||||
format: "format",
|
format: "format",
|
||||||
formatted_body: "formatted content",
|
formatted_body: "formatted content",
|
||||||
algorithm: "algorithm",
|
algorithm: "algorithm",
|
||||||
|
url: "URL",
|
||||||
|
info: {
|
||||||
|
mimetype: "Type",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -253,6 +257,9 @@ const en = {
|
||||||
created_ts: "Created",
|
created_ts: "Created",
|
||||||
last_access_ts: "Last access",
|
last_access_ts: "Last access",
|
||||||
},
|
},
|
||||||
|
action: {
|
||||||
|
open: "Open media file in new window",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
delete_media: {
|
delete_media: {
|
||||||
name: "Media",
|
name: "Media",
|
||||||
|
|
|
@ -53,3 +53,8 @@ export const getSupportedLoginFlows = async baseUrl => {
|
||||||
const response = await fetchUtils.fetchJson(loginFlowsUrl, { method: "GET" });
|
const response = await fetchUtils.fetchJson(loginFlowsUrl, { method: "GET" });
|
||||||
return response.json.flows;
|
return response.json.flows;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getMediaUrl = media_id => {
|
||||||
|
const baseUrl = localStorage.getItem("base_url");
|
||||||
|
return `${baseUrl}/_matrix/media/v1/download/${media_id}?allow_redirect=true`;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue