diff --git a/README.md b/README.md
index 903f4f1..5e5c84b 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,28 @@
This project is built using [react-admin](https://marmelab.com/react-admin/).
-Use `yarn install` after cloning this repo.
+It needs at least Synapse v1.13.0 for all functions to work as expected!
-Use `yarn start` to launch the webserver.
+## Step-By-Step install:
+
+You have two options:
+
+1. Download the source code from github and run using nodejs
+2. Run the Docker container
+
+Steps for 1):
+
+- make sure you have installed the following: git, yarn, nodejs
+- download the source code: `git clone https://github.com/Awesome-Technologies/synapse-admin.git`
+- change into downloaded directory: `cd synapse-admin`
+- download dependencies: `yarn install`
+- start web server: `yarn start`
+
+Steps for 2):
+
+- run the Docker container: `docker run -p 8080:80 awesometechnologies/synapse-admin`
+- browse to http://localhost:8080
+
+## Screenshots
+
+
diff --git a/screenshots.jpg b/screenshots.jpg
new file mode 100644
index 0000000..9a08375
Binary files /dev/null and b/screenshots.jpg differ
diff --git a/src/components/users.js b/src/components/users.js
index 7ae40a1..a1f80f8 100644
--- a/src/components/users.js
+++ b/src/components/users.js
@@ -1,4 +1,5 @@
import React, { 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";
@@ -19,7 +20,6 @@ import {
FormTab,
BooleanField,
BooleanInput,
- ImageField,
PasswordInput,
TextField,
TextInput,
@@ -34,6 +34,19 @@ import {
} from "react-admin";
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
import { RemoveDeviceButton } from "./devices";
+import { makeStyles } from "@material-ui/core/styles";
+
+const useStyles = makeStyles({
+ small: {
+ height: "40px",
+ width: "40px",
+ },
+ large: {
+ height: "120px",
+ width: "120px",
+ float: "right",
+ },
+});
const UserPagination = props => (
@@ -64,40 +77,36 @@ const UserBulkActionButtons = props => {
);
};
-export const UserList = props => (
-
}
- filterDefaultValues={{ guests: true, deactivated: false }}
- bulkActionButtons={}
- pagination={}
- >
-
-
-
-
-
- {/* Hack since the users endpoint does not give displaynames in the list*/}
-
-
-
-
-
-
-
-
+const AvatarField = ({ source, className, record = {} }) => (
+
);
+export const UserList = props => {
+ const classes = useStyles();
+ return (
+
}
+ filterDefaultValues={{ guests: true, deactivated: false }}
+ bulkActionButtons={}
+ pagination={}
+ >
+
+
+
+
+
+
+
+
+
+ );
+};
+
// https://matrix.org/docs/spec/appendices#user-identifiers
const validateUser = regex(
/^@[a-z0-9._=\-/]+:.*/,
@@ -145,12 +154,15 @@ const UserTitle = ({ record }) => {
const translate = useTranslate();
return (
- {translate("resources.users.name")}{" "}
+ {translate("resources.users.name", {
+ smart_count: 1,
+ })}{" "}
{record ? `"${record.displayname}"` : ""}
);
};
export const UserEdit = props => {
+ const classes = useStyles();
const translate = useTranslate();
return (
}>
@@ -159,6 +171,11 @@ export const UserEdit = props => {
label={translate("resources.users.name", { smart_count: 1 })}
icon={}
>
+
diff --git a/src/i18n/de.js b/src/i18n/de.js
index 066bc64..98898b1 100644
--- a/src/i18n/de.js
+++ b/src/i18n/de.js
@@ -36,6 +36,7 @@ export default {
displayname: "Anzeigename",
password: "Passwort",
avatar_url: "Avatar URL",
+ avatar_src: "Avatar",
medium: "Medium",
threepids: "3PIDs",
address: "Adresse",
diff --git a/src/i18n/en.js b/src/i18n/en.js
index 88b4b29..f83efd3 100644
--- a/src/i18n/en.js
+++ b/src/i18n/en.js
@@ -35,6 +35,7 @@ export default {
displayname: "Displayname",
password: "Password",
avatar_url: "Avatar URL",
+ avatar_src: "Avatar",
medium: "Medium",
threepids: "3PIDs",
address: "Address",
diff --git a/src/synapse/dataProvider.js b/src/synapse/dataProvider.js
index d728d4f..6a2da69 100644
--- a/src/synapse/dataProvider.js
+++ b/src/synapse/dataProvider.js
@@ -14,24 +14,32 @@ const jsonClient = (url, options = {}) => {
return fetchUtils.fetchJson(url, options);
};
+const mxcUrlToHttp = mxcUrl => {
+ const homeserver = localStorage.getItem("base_url");
+ const re = /^mxc:\/\/([^/]+)\/(\w+)/;
+ var ret = re.exec(mxcUrl);
+ console.log("mxcClient " + ret);
+ if (ret == null) return null;
+ const serverName = ret[1];
+ const mediaId = ret[2];
+ return `${homeserver}/_matrix/media/r0/thumbnail/${serverName}/${mediaId}?width=24&height=24&method=scale`;
+};
+
const resourceMap = {
users: {
path: "/_synapse/admin/v2/users",
map: u => ({
...u,
id: u.name,
+ avatar_src: mxcUrlToHttp(u.avatar_url),
is_guest: !!u.is_guest,
admin: !!u.admin,
deactivated: !!u.deactivated,
// need timestamp in milliseconds
creation_ts_ms: u.creation_ts * 1000,
}),
+ total: json => json.total,
data: "users",
- total: (json, from, perPage) => {
- return json.next_token
- ? parseInt(json.next_token, 10) + perPage
- : from + json.users.length;
- },
getMany: id => ({
endpoint: `/_synapse/admin/v2/users/${id}`,
}),