matrix-moderation-widget

A widget for moderating with mjolnir. Highly WIP. Use at your own risk!
git clone git://archive.git.mtrnord.blog/MTRNord/matrix-moderation-widget.git
Log | Files | Refs | README | LICENSE

NewRoomForm.tsx (4220B)


      1 import { PureComponent } from "react";
      2 import { DEV_NORDGEDANKEN_MJOLNIR_BANLISTS, MJjolnirBanlists, M_ROOM_MEMBER, M_ROOM_POWERLEVELS } from "../../windowExt";
      3 type Props = Record<string, unknown>;
      4 type State = {
      5     room: string;
      6     roomId?: string;
      7     user_id: string;
      8 };
      9 class NewRoomForm extends PureComponent<Props, State> {
     10     constructor(props: Props | Readonly<Props>) {
     11         super(props);
     12         const urlParams = (new URL(window.location.href)).searchParams;
     13         const roomId = urlParams.get("room_id") ?? undefined;
     14         this.state = {
     15             room: "",
     16             roomId: roomId,
     17             user_id: ""
     18         };
     19     }
     20 
     21     async componentDidMount() {
     22         // TODO use to get the bot if available
     23         const banlist_codes = await window.widget_api.readStateEvents(DEV_NORDGEDANKEN_MJOLNIR_BANLISTS, 250_000_000_000, undefined, [this.state.roomId ?? "*"]) as MJjolnirBanlists[];
     24     }
     25 
     26     handleInputChange(event: { target: { type: string, checked?: boolean, value: string | boolean, name: string; }; }) {
     27         const target = event.target;
     28         const value = target.type === 'checkbox' ? target.checked : target.value;
     29         const name = target.name;
     30         this.setState({
     31             [name]: value
     32         } as unknown as State);
     33     }
     34 
     35     async handleSubmit(ev: { preventDefault: () => void; }) {
     36         ev.preventDefault();
     37 
     38         if (this.state.user_id === "" || this.state.room === "") {
     39             return;
     40         }
     41         if (this.state.room.startsWith("!")) {
     42             // TODO patch power_levels
     43             // TODO fix race due to perms
     44             window.widget_api.requestCapabilityToSendState(M_ROOM_MEMBER);
     45             window.widget_api.requestCapabilityToReceiveState(M_ROOM_POWERLEVELS);
     46             window.widget_api.requestCapabilityToSendState(M_ROOM_POWERLEVELS);
     47             await window.widget_api.updateRequestedCapabilities();
     48             await window.widget_api.sendStateEvent(M_ROOM_MEMBER, this.state.user_id, {
     49                 displayname: "Administrator",
     50                 is_direct: false,
     51                 membership: "invite"
     52             }, this.state.room);
     53         }
     54 
     55         await window.widget_api.sendRoomEvent("m.room.message", {
     56             msgtype: "m.text",
     57             body: `!mjolnir rooms add ${this.state.room}`,
     58         }, this.state.roomId);
     59     }
     60 
     61     render() {
     62         const { room, user_id } = this.state;
     63         return (
     64             <>
     65                 <h3 className="text-2xl font-bold text-gray-900 dark:text-gray-200 mb-2">Protect a new Room</h3>
     66                 <form onSubmit={this.handleSubmit.bind(this)} className="grid grid-cols-1 gap-4">
     67                     <label className="block w-96">
     68                         <span className="text-gray-900 dark:text-gray-200 visually-hidden mb-2">Room (required)</span>
     69                         <div className="mt-1 w-full flex flex-row box-border items-center cursor-text duration-300 max-w-full">
     70                             <input required placeholder="Room (required)" className="rounded py-1.5 px-2 min-w-[1.25rem] flex-[1] border-none placeholder:text-gray-900 text-gray-900" type="text" name="room" value={room} onChange={this.handleInputChange.bind(this)} />
     71                         </div>
     72                     </label>
     73                     <label className="block w-96">
     74                         <span className="text-gray-900 dark:text-gray-200 visually-hidden mb-2">Bot user_id (required as we can't know)</span>
     75                         <div className="mt-1 w-full flex flex-row box-border items-center cursor-text duration-300 max-w-full">
     76                             <input required placeholder="Bot user_id (required as we can't know)" className="rounded py-1.5 px-2 min-w-[1.25rem] flex-[1] border-none placeholder:text-gray-900 text-gray-900" type="text" name="user_id" value={user_id} onChange={this.handleInputChange.bind(this)} />
     77                         </div>
     78                     </label>
     79                     <input className="bg-green-400 hover:bg-green-500 cursor-pointer h-10 rounded dark:text-gray-900 text-gray-200 w-96" type="submit" value="Protect" />
     80                 </form>
     81             </>
     82         );
     83     }
     84 }
     85 
     86 export default NewRoomForm;