Add basic structure for (un)subscribing from lists

pull/21833/head
Travis Ralston 2019-10-31 15:53:18 -06:00
parent b93508728a
commit 39b657ce7c
4 changed files with 166 additions and 14 deletions

View File

@ -18,6 +18,6 @@ limitations under the License.
@mixin mx_Settings_fullWidthField;
}
.mx_MjolnirUserSettingsTab_personalRule {
.mx_MjolnirUserSettingsTab_listItem {
margin-bottom: 2px;
}

View File

@ -18,8 +18,9 @@ import React from 'react';
import {_t} from "../../../../../languageHandler";
import {Mjolnir} from "../../../../../mjolnir/Mjolnir";
import {ListRule} from "../../../../../mjolnir/ListRule";
import {RULE_SERVER, RULE_USER} from "../../../../../mjolnir/BanList";
import {BanList, RULE_SERVER, RULE_USER} from "../../../../../mjolnir/BanList";
import Modal from "../../../../../Modal";
import MatrixClientPeg from "../../../../../MatrixClientPeg";
const sdk = require("../../../../..");
@ -30,6 +31,7 @@ export default class MjolnirUserSettingsTab extends React.Component {
this.state = {
busy: false,
newPersonalRule: "",
newList: "",
};
}
@ -37,6 +39,10 @@ export default class MjolnirUserSettingsTab extends React.Component {
this.setState({newPersonalRule: e.target.value});
};
_onNewListChanged = (e) => {
this.setState({newList: e.target.value});
};
_onAddPersonalRule = async (e) => {
e.preventDefault();
e.stopPropagation();
@ -55,8 +61,8 @@ export default class MjolnirUserSettingsTab extends React.Component {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to remove Mjolnir rule', '', ErrorDialog, {
title: _t('Error removing ignored user/server'),
Modal.createTrackedDialog('Failed to add Mjolnir rule', '', ErrorDialog, {
title: _t('Error adding ignored user/server'),
description: _t('Something went wrong. Please try again or view your console for hints.'),
});
} finally {
@ -64,6 +70,28 @@ export default class MjolnirUserSettingsTab extends React.Component {
}
};
_onSubscribeList = async (e) => {
e.preventDefault();
e.stopPropagation();
this.setState({busy: true});
try {
const room = await MatrixClientPeg.get().joinRoom(this.state.newList);
await Mjolnir.sharedInstance().subscribeToList(room.roomId);
this.setState({newList: ""}); // this will also cause the new rule to be rendered
} catch (e) {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to subscribe to Mjolnir list', '', ErrorDialog, {
title: _t('Error subscribing to list'),
description: _t('Please verify the room ID or alias and try again.'),
});
} finally {
this.setState({busy: false});
}
};
async _removePersonalRule(rule: ListRule) {
this.setState({busy: true});
try {
@ -82,6 +110,28 @@ export default class MjolnirUserSettingsTab extends React.Component {
}
}
async _unsubscribeFromList(list: BanList) {
this.setState({busy: true});
try {
await Mjolnir.sharedInstance().unsubscribeFromList(list.roomId);
await MatrixClientPeg.get().leave(list.roomId);
} catch (e) {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to unsubscribe from Mjolnir list', '', ErrorDialog, {
title: _t('Error unsubscribing from list'),
description: _t('Please try again or view your console for hints.'),
});
} finally {
this.setState({busy: false});
}
}
_viewListRules(list: BanList) {
// TODO
}
_renderPersonalBanListRules() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
@ -92,9 +142,12 @@ export default class MjolnirUserSettingsTab extends React.Component {
const tiles = [];
for (const rule of rules) {
tiles.push(
<li key={rule.entity} className="mx_MjolnirUserSettingsTab_personalRule">
<AccessibleButton kind="danger_sm" onClick={() => this._removePersonalRule(rule)}
disabled={this.state.busy}>
<li key={rule.entity} className="mx_MjolnirUserSettingsTab_listItem">
<AccessibleButton
kind="danger_sm"
onClick={() => this._removePersonalRule(rule)}
disabled={this.state.busy}
>
{_t("Remove")}
</AccessibleButton>&nbsp;
<code>{rule.entity}</code>
@ -102,9 +155,52 @@ export default class MjolnirUserSettingsTab extends React.Component {
);
}
return <div><p>{_t("You are currently ignoring:")}</p>
return (
<div>
<p>{_t("You are currently ignoring:")}</p>
<ul>{tiles}</ul>
</div>;
</div>
);
}
_renderSubscribedBanLists() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const personalList = Mjolnir.sharedInstance().getPersonalList();
const lists = Mjolnir.sharedInstance().lists.filter(b => personalList ? personalList.roomId !== b.roomId : true);
if (!lists || lists.length <= 0) return <i>{_t("You are not subscribed to any lists")}</i>;
const tiles = [];
for (const list of lists) {
const room = MatrixClientPeg.get().getRoom(list.roomId);
const name = room ? <span>{room.name} (<code>{list.roomId}</code>)</span> : <code>list.roomId</code>;
tiles.push(
<li key={list.roomId} className="mx_MjolnirUserSettingsTab_listItem">
<AccessibleButton
kind="danger_sm"
onClick={() => this._unsubscribeFromList(list)}
disabled={this.state.busy}
>
{_t("Unsubscribe")}
</AccessibleButton>&nbsp;
<AccessibleButton
kind="primary_sm"
onClick={() => this._viewListRules(list)}
disabled={this.state.busy}
>
{_t("View rules")}
</AccessibleButton>&nbsp;
{name}
</li>,
);
}
return (
<div>
<p>{_t("You are currently subscribed to:")}</p>
<ul>{tiles}</ul>
</div>
);
}
render() {
@ -155,8 +251,12 @@ export default class MjolnirUserSettingsTab extends React.Component {
value={this.state.newPersonalRule}
onChange={this._onPersonalRuleChanged}
/>
<AccessibleButton type="submit" kind="primary" onClick={this._onAddPersonalRule}
disabled={this.state.busy}>
<AccessibleButton
type="submit"
kind="primary"
onClick={this._onAddPersonalRule}
disabled={this.state.busy}
>
{_t("Ignore")}
</AccessibleButton>
</form>
@ -171,7 +271,28 @@ export default class MjolnirUserSettingsTab extends React.Component {
"If this isn't what you want, please use a different tool to ignore users.",
)}</span>
</div>
<p>TODO</p>
<div>
{this._renderSubscribedBanLists()}
</div>
<div>
<form onSubmit={this._onSubscribeList} autoComplete="off">
<Field
id="mx_MjolnirUserSettingsTab_subscriptionAdd"
type="text"
label={_t("Room ID or alias of ban list")}
value={this.state.newList}
onChange={this._onNewListChanged}
/>
<AccessibleButton
type="submit"
kind="primary"
onClick={this._onSubscribeList}
disabled={this.state.busy}
>
{_t("Subscribe")}
</AccessibleButton>
</form>
</div>
</div>
</div>
);

View File

@ -641,11 +641,20 @@
"click to reveal": "click to reveal",
"Labs": "Labs",
"Ignored/Blocked": "Ignored/Blocked",
"Error removing ignored user/server": "Error removing ignored user/server",
"Error adding ignored user/server": "Error adding ignored user/server",
"Something went wrong. Please try again or view your console for hints.": "Something went wrong. Please try again or view your console for hints.",
"Error subscribing to list": "Error subscribing to list",
"Please verify the room ID or alias and try again.": "Please verify the room ID or alias and try again.",
"Error removing ignored user/server": "Error removing ignored user/server",
"Error unsubscribing from list": "Error unsubscribing from list",
"Please try again or view your console for hints.": "Please try again or view your console for hints.",
"You have not ignored anyone.": "You have not ignored anyone.",
"Remove": "Remove",
"You are currently ignoring:": "You are currently ignoring:",
"You are not subscribed to any lists": "You are not subscribed to any lists",
"Unsubscribe": "Unsubscribe",
"View rules": "View rules",
"You are currently subscribed to:": "You are currently subscribed to:",
"Ignored users": "Ignored users",
"⚠ These settings are meant for advanced users.": "⚠ These settings are meant for advanced users.",
"Add users and servers you want to ignore here. Use asterisks to have Riot match any characters. For example, <code>@bot:*</code> would ignore all users that have the name 'bot' on any server.": "Add users and servers you want to ignore here. Use asterisks to have Riot match any characters. For example, <code>@bot:*</code> would ignore all users that have the name 'bot' on any server.",
@ -658,6 +667,8 @@
"Subscribed lists": "Subscribed lists",
"Subscribing to a ban list will cause you to join it!": "Subscribing to a ban list will cause you to join it!",
"If this isn't what you want, please use a different tool to ignore users.": "If this isn't what you want, please use a different tool to ignore users.",
"Room ID or alias of ban list": "Room ID or alias of ban list",
"Subscribe": "Subscribe",
"Notifications": "Notifications",
"Start automatically after system login": "Start automatically after system login",
"Always show the window menu bar": "Always show the window menu bar",

View File

@ -33,6 +33,14 @@ export class Mjolnir {
constructor() {
}
get roomIds(): string[] {
return this._roomIds;
}
get lists(): BanList[] {
return this._lists;
}
start() {
this._mjolnirWatchRef = SettingsStore.watchSetting("mjolnirRooms", null, this._onListsChanged.bind(this));
@ -101,6 +109,18 @@ export class Mjolnir {
return list;
}
async subscribeToList(roomId: string) {
const roomIds = [...this._roomIds, roomId];
await SettingsStore.setValue("mjolnirRooms", null, SettingLevel.ACCOUNT, roomIds);
this._lists.push(new BanList(roomId));
}
async unsubscribeFromList(roomId: string) {
const roomIds = this._roomIds.filter(r => r !== roomId);
await SettingsStore.setValue("mjolnirRooms", null, SettingLevel.ACCOUNT, roomIds);
this._lists = this._lists.filter(b => b.roomId !== roomId);
}
_onEvent(event) {
if (!MatrixClientPeg.get()) return;
if (!this._roomIds.includes(event.getRoomId())) return;