diff --git a/res/css/views/settings/tabs/user/_MjolnirUserSettingsTab.scss b/res/css/views/settings/tabs/user/_MjolnirUserSettingsTab.scss index 930dbeb440..c60cbc5dea 100644 --- a/res/css/views/settings/tabs/user/_MjolnirUserSettingsTab.scss +++ b/res/css/views/settings/tabs/user/_MjolnirUserSettingsTab.scss @@ -18,6 +18,6 @@ limitations under the License. @mixin mx_Settings_fullWidthField; } -.mx_MjolnirUserSettingsTab_personalRule { +.mx_MjolnirUserSettingsTab_listItem { margin-bottom: 2px; } diff --git a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js index 97f92bb0b2..4e05b57567 100644 --- a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js @@ -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( -
{rule.entity}
@@ -102,9 +155,52 @@ export default class MjolnirUserSettingsTab extends React.Component {
);
}
- return {_t("You are currently ignoring:")}
-{_t("You are currently ignoring:")}
+{list.roomId}
) : list.roomId
;
+ tiles.push(
+ {_t("You are currently subscribed to:")}
+TODO
+@bot:*
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, @bot:*
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",
diff --git a/src/mjolnir/Mjolnir.js b/src/mjolnir/Mjolnir.js
index d90ea9cd04..5edfe3750e 100644
--- a/src/mjolnir/Mjolnir.js
+++ b/src/mjolnir/Mjolnir.js
@@ -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;