From d47c9d8b6ee6740ef1de3a7f63605ceff68bc77e Mon Sep 17 00:00:00 2001
From: Luke Barnard <luke@matrix.org>
Date: Mon, 12 Feb 2018 18:02:55 +0000
Subject: [PATCH] Add context menu to TagPanel

See https://github.com/matrix-org/matrix-react-sdk/pull/1743
---
 .../views/context_menus/TagTileContextMenu.js | 68 +++++++++++++++++++
 src/i18n/strings/en_EN.json                   | 17 ++---
 src/skins/vector/css/_components.scss         |  5 +-
 .../structures/_TagPanel.scss                 | 18 +++++
 .../context_menus/_TagTileContextMenu.scss    | 44 ++++++++++++
 5 files changed, 142 insertions(+), 10 deletions(-)
 create mode 100644 src/components/views/context_menus/TagTileContextMenu.js
 create mode 100644 src/skins/vector/css/vector-web/views/context_menus/_TagTileContextMenu.scss

diff --git a/src/components/views/context_menus/TagTileContextMenu.js b/src/components/views/context_menus/TagTileContextMenu.js
new file mode 100644
index 00000000..4ec6c515
--- /dev/null
+++ b/src/components/views/context_menus/TagTileContextMenu.js
@@ -0,0 +1,68 @@
+/*
+Copyright 2018 New Vector Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import PropTypes from 'prop-types';
+import { _t } from 'matrix-react-sdk/lib/languageHandler';
+import dis from 'matrix-react-sdk/lib/dispatcher';
+import TagOrderActions from 'matrix-react-sdk/lib/actions/TagOrderActions';
+import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
+
+export default class TagTileContextMenu extends React.Component {
+    static propTypes = {
+        tag: PropTypes.string.isRequired,
+        /* callback called when the menu is dismissed */
+        onFinished: PropTypes.func.isRequired,
+    };
+
+    constructor() {
+        super();
+
+        this._onViewCommunityClick = this._onViewCommunityClick.bind(this);
+        this._onRemoveClick = this._onRemoveClick.bind(this);
+    }
+
+    _onViewCommunityClick() {
+        dis.dispatch({
+            action: 'view_group',
+            group_id: this.props.tag,
+        });
+        this.props.onFinished();
+    }
+
+    _onRemoveClick() {
+        dis.dispatch(TagOrderActions.removeTag(
+            // XXX: Context menus don't have a MatrixClient context
+            MatrixClientPeg.get(),
+            this.props.tag,
+        ));
+        this.props.onFinished();
+    }
+
+    render() {
+        return <div>
+            <div className="mx_TagTileContextMenu_item" onClick={this._onViewCommunityClick} >
+                <img className="mx_TagTileContextMenu_item_icon" src="img/icons-groups.svg" width="15" height="15" />
+                { _t('View Community') }
+            </div>
+            <hr className="mx_TagTileContextMenu_separator" />
+            <div className="mx_TagTileContextMenu_item" onClick={this._onRemoveClick} >
+                <img className="mx_TagTileContextMenu_item_icon" src="img/icon_context_delete.svg" width="15" height="15" />
+                { _t('Remove') }
+            </div>
+        </div>;
+    }
+}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 819c0cfa..bbb94a60 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -43,9 +43,6 @@
     "Off": "Off",
     "On": "On",
     "Noisy": "Noisy",
-    "Failed to set direct chat tag": "Failed to set direct chat tag",
-    "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
-    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
     "Search…": "Search…",
     "Search": "Search",
     "This Room": "This Room",
@@ -68,8 +65,6 @@
     "What's New": "What's New",
     "Update": "Update",
     "What's new?": "What's new?",
-    "Appear Offline": "Appear Offline",
-    "Away": "Away",
     "A new version of Riot is available.": "A new version of Riot is available.",
     "To return to your account in future you need to <u>set a password</u>": "To return to your account in future you need to <u>set a password</u>",
     "Set Password": "Set Password",
@@ -126,6 +121,7 @@
     "Resend": "Resend",
     "Cancel Sending": "Cancel Sending",
     "Forward Message": "Forward Message",
+    "Reply": "Reply",
     "Unpin Message": "Unpin Message",
     "Pin Message": "Pin Message",
     "View Source": "View Source",
@@ -134,6 +130,10 @@
     "Permalink": "Permalink",
     "Quote": "Quote",
     "Source URL": "Source URL",
+    "Online": "Online",
+    "Away": "Away",
+    "Appear Offline": "Appear Offline",
+    "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
     "Failed to set Direct Message status of room": "Failed to set Direct Message status of room",
     "unknown error code": "unknown error code",
     "Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s",
@@ -147,6 +147,7 @@
     "Favourite": "Favourite",
     "Low Priority": "Low Priority",
     "Direct Chat": "Direct Chat",
+    "View Community": "View Community",
     "Sorry, your browser is <b>not</b> able to run Riot.": "Sorry, your browser is <b>not</b> able to run Riot.",
     "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.",
     "Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.": "Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.",
@@ -156,10 +157,10 @@
     "Couldn't load home page": "Couldn't load home page",
     "Login": "Login",
     "Register": "Register",
-    "Invite to this room": "Invite to this room",
     "Members": "Members",
     "%(count)s Members|other": "%(count)s Members",
     "%(count)s Members|one": "%(count)s Member",
+    "Invite to this room": "Invite to this room",
     "Files": "Files",
     "Notifications": "Notifications",
     "Rooms": "Rooms",
@@ -189,6 +190,7 @@
     "Search for a room": "Search for a room",
     "#example": "#example",
     "more": "more",
+    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
     "Expand panel": "Expand panel",
     "Collapse panel": "Collapse panel",
     "Filter room names": "Filter room names",
@@ -219,6 +221,5 @@
     "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot",
     "Dev chat for the Riot/Web dev team": "Dev chat for the Riot/Web dev team",
     "Dev chat for the Dendrite dev team": "Dev chat for the Dendrite dev team",
-    "Co-ordination for Riot/Web translators": "Co-ordination for Riot/Web translators",
-    "Reply": "Reply"
+    "Co-ordination for Riot/Web translators": "Co-ordination for Riot/Web translators"
 }
diff --git a/src/skins/vector/css/_components.scss b/src/skins/vector/css/_components.scss
index faf358bd..837fe453 100644
--- a/src/skins/vector/css/_components.scss
+++ b/src/skins/vector/css/_components.scss
@@ -36,10 +36,10 @@
 @import "./matrix-react-sdk/views/elements/_EditableItemList.scss";
 @import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss";
 @import "./matrix-react-sdk/views/elements/_ProgressBar.scss";
+@import "./matrix-react-sdk/views/elements/_Quote.scss";
 @import "./matrix-react-sdk/views/elements/_RichText.scss";
 @import "./matrix-react-sdk/views/elements/_RoleButton.scss";
 @import "./matrix-react-sdk/views/elements/_ToolTipButton.scss";
-@import "./matrix-react-sdk/views/elements/_Quote.scss";
 @import "./matrix-react-sdk/views/groups/_GroupPublicityToggle.scss";
 @import "./matrix-react-sdk/views/groups/_GroupRoomList.scss";
 @import "./matrix-react-sdk/views/groups/_GroupUserSettings.scss";
@@ -65,6 +65,7 @@
 @import "./matrix-react-sdk/views/rooms/_PinnedEventTile.scss";
 @import "./matrix-react-sdk/views/rooms/_PinnedEventsPanel.scss";
 @import "./matrix-react-sdk/views/rooms/_PresenceLabel.scss";
+@import "./matrix-react-sdk/views/rooms/_QuotePreview.scss";
 @import "./matrix-react-sdk/views/rooms/_RoomHeader.scss";
 @import "./matrix-react-sdk/views/rooms/_RoomList.scss";
 @import "./matrix-react-sdk/views/rooms/_RoomPreviewBar.scss";
@@ -72,7 +73,6 @@
 @import "./matrix-react-sdk/views/rooms/_RoomTile.scss";
 @import "./matrix-react-sdk/views/rooms/_SearchableEntityList.scss";
 @import "./matrix-react-sdk/views/rooms/_TopUnreadMessagesBar.scss";
-@import "./matrix-react-sdk/views/rooms/_QuotePreview.scss";
 @import "./matrix-react-sdk/views/settings/_DevicesPanel.scss";
 @import "./matrix-react-sdk/views/settings/_IntegrationsManager.scss";
 @import "./matrix-react-sdk/views/voip/_CallView.scss";
@@ -89,6 +89,7 @@
 @import "./vector-web/views/context_menus/_MessageContextMenu.scss";
 @import "./vector-web/views/context_menus/_PresenceContextMenuOption.scss";
 @import "./vector-web/views/context_menus/_RoomTileContextMenu.scss";
+@import "./vector-web/views/context_menus/_TagTileContextMenu.scss";
 @import "./vector-web/views/dialogs/_ChangelogDialog.scss";
 @import "./vector-web/views/dialogs/_DevtoolsDialog.scss";
 @import "./vector-web/views/dialogs/_SetEmailDialog.scss";
diff --git a/src/skins/vector/css/matrix-react-sdk/structures/_TagPanel.scss b/src/skins/vector/css/matrix-react-sdk/structures/_TagPanel.scss
index 91199a11..ba745b11 100644
--- a/src/skins/vector/css/matrix-react-sdk/structures/_TagPanel.scss
+++ b/src/skins/vector/css/matrix-react-sdk/structures/_TagPanel.scss
@@ -37,6 +37,7 @@ limitations under the License.
 .mx_TagPanel .mx_TagTile {
     padding: 6px 3px;
     opacity: 0.5;
+    position: relative;
 }
 .mx_TagPanel .mx_TagTile:focus,
 .mx_TagPanel .mx_TagTile:hover,
@@ -64,6 +65,23 @@ limitations under the License.
     left: 5px;
 }
 
+.mx_TagTile_context_button {
+    min-width: 15px;
+    height: 15px;
+    position: absolute;
+    right: -5px;
+    top: 1px;
+    border-radius: 8px;
+    background-color: $neutral-badge-color;
+    color: #ffffff;
+    font-weight: 600;
+    font-size: 10px;
+    text-align: center;
+    padding-top: 1px;
+    padding-left: 4px;
+    padding-right: 4px;
+}
+
 .mx_TagPanel_createGroupButton {
     opacity: 0.5;
     margin-bottom: 17px;
diff --git a/src/skins/vector/css/vector-web/views/context_menus/_TagTileContextMenu.scss b/src/skins/vector/css/vector-web/views/context_menus/_TagTileContextMenu.scss
new file mode 100644
index 00000000..759b92bd
--- /dev/null
+++ b/src/skins/vector/css/vector-web/views/context_menus/_TagTileContextMenu.scss
@@ -0,0 +1,44 @@
+/*
+Copyright 2018 New Vector Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_TagTileContextMenu_item {
+    padding-top: 8px;
+    padding-right: 20px;
+    padding-bottom: 8px;
+    cursor: pointer;
+    white-space: nowrap;
+    display: flex;
+    align-items: center;
+    line-height: 16px;
+}
+
+
+.mx_TagTileContextMenu_item_icon {
+    padding-right: 8px;
+    padding-left: 4px;
+    display: inline-block
+}
+
+.mx_TagTileContextMenu_separator {
+    margin-top: 0;
+    margin-bottom: 0;
+    border-bottom-style: none;
+    border-left-style: none;
+    border-right-style: none;
+    border-top-style: solid;
+    border-top-width: 1px;
+    border-color: $menu-border-color;
+}