Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add popup menu support for chat header and chat list #6671

Merged
merged 1 commit into from
Dec 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clj-rn.conf.edn
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"react-native/Libraries/vendor/emitter/EventEmitter"
"react-native-fetch-polyfill"
"react-native-desktop-linking"
"react-native-desktop-menu"
"react-native-desktop-notification"
"text-encoding"
"js-sha3"
Expand Down
4 changes: 2 additions & 2 deletions desktop/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <QDirIterator>
#include <QFile>
#include <QFontDatabase>
#include <QGuiApplication>
#include <QApplication>
#include <QMutexLocker>
#include <QProcess>
#include <QQuickView>
Expand Down Expand Up @@ -242,7 +242,7 @@ void renameRealmDirs() {

int main(int argc, char **argv) {
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QApplication app(argc, argv);

QCoreApplication::setApplicationName("Status");

Expand Down
1 change: 1 addition & 0 deletions desktop_files/package.json.orig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"node_modules/react-native-securerandom/desktop",
"modules/react-native-status/desktop",
"modules/react-native-desktop-linking/desktop",
"modules/react-native-desktop-menu/desktop",
"modules/react-native-desktop-notification/desktop",
"node_modules/google-breakpad"
],
Expand Down
9 changes: 9 additions & 0 deletions modules/react-native-desktop-menu/desktop/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_TYPE_NAMES ${REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_TYPE_NAMES}
\"DesktopMenu\" PARENT_SCOPE)

set(REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_SRC ${REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_SRC}
${CMAKE_CURRENT_SOURCE_DIR}/desktopmenu.cpp PARENT_SCOPE)

include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
64 changes: 64 additions & 0 deletions modules/react-native-desktop-menu/desktop/desktopmenu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "desktopmenu.h"
#include "bridge.h"

#include <QCoreApplication>
#include <QDebug>
#include <QMenu>
#include <QCursor>

Q_LOGGING_CATEGORY(DESKTOPMENU, "DesktopMenu")

namespace {
struct RegisterQMLMetaType {
RegisterQMLMetaType() { qRegisterMetaType<DesktopMenu *>(); }
} registerMetaType;
} // namespace

class DesktopMenuPrivate {
public:
Bridge *bridge = nullptr;
void createMenu(const QStringList& items, double callback);
private:
void onTriggered(QAction* action);
};

void DesktopMenuPrivate::createMenu(const QStringList& items, double callback) {
QMenu* menu = new QMenu();
for (const QString& name : items) {
menu->addAction(name);
}
QObject::connect(menu, &QMenu::triggered, [=](QAction* action) {
bridge->invokePromiseCallback(callback, QVariantList{action->text()});
});
QObject::connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater);
menu->popup(QCursor::pos());
}

DesktopMenu::DesktopMenu(QObject *parent)
: QObject(parent), d_ptr(new DesktopMenuPrivate) {
}

DesktopMenu::~DesktopMenu() {
}

void DesktopMenu::setBridge(Bridge *bridge) {
Q_D(DesktopMenu);

d->bridge = bridge;
}

QString DesktopMenu::moduleName() { return "DesktopMenuManager"; }

QList<ModuleMethod *> DesktopMenu::methodsToExport() {
return QList<ModuleMethod *>{};
}

QVariantMap DesktopMenu::constantsToExport() { return QVariantMap(); }

void DesktopMenu::show(const QStringList& items, double callback) {
Q_D(DesktopMenu);
d_ptr->createMenu(items, callback);

}


34 changes: 34 additions & 0 deletions modules/react-native-desktop-menu/desktop/desktopmenu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef DESKTOPMENU_H
#define DESKTOPMENU_H

#include "moduleinterface.h"

#include <QLoggingCategory>
#include <QVariantMap>

Q_DECLARE_LOGGING_CATEGORY(MENU)

class DesktopMenuPrivate;
class DesktopMenu : public QObject, public ModuleInterface {
Q_OBJECT
Q_INTERFACES(ModuleInterface)

Q_DECLARE_PRIVATE(DesktopMenu)

public:
Q_INVOKABLE DesktopMenu(QObject* parent = 0);
virtual ~DesktopMenu();

void setBridge(Bridge* bridge) override;

QString moduleName() override;
QList<ModuleMethod*> methodsToExport() override;
QVariantMap constantsToExport() override;

Q_INVOKABLE void show(const QStringList& items, double callback);

private:
QScopedPointer<DesktopMenuPrivate> d_ptr;
};

#endif // DESKTOPMENU_H
29 changes: 29 additions & 0 deletions modules/react-native-desktop-menu/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

type MenuItems = Array<{
text?: string,
onPress?: ?Function,
}>;

const NativeModules = require('react-native').NativeModules;

class DesktopMenu {

static show(
menuItems?: MenuItems
): void {
var itemNames = menuItems.map(i => i.text);
var itemMap = new Map();
for (let i = 0; i < menuItems.length; ++i) {
itemMap.set(menuItems[i].text, menuItems[i].onPress);
}
NativeModules.DesktopMenuManager.show(
itemNames,
(name) => {
(itemMap.get(name))();
}
);
}
}

module.exports = DesktopMenu;
13 changes: 13 additions & 0 deletions modules/react-native-desktop-menu/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"private": true,
"nativePackage": true,
"name": "react-native-desktop-menu",
"version": "1.0.0",
"description": "Native popup and context menus for Desktop",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
(def fetch (.-default (js/require "react-native-fetch-polyfill")))
(def i18n (js/require "react-native-i18n"))
(def desktop-linking (.-DesktopLinking (.-NativeModules react-native)))
(def desktop-menu (js/require "react-native-desktop-menu"))

(def react-native-firebase #js {})
(def nfc-manager #js {})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@
(def background-timer (.-default (js/require "react-native-background-timer")))
(def react-navigation (js/require "react-navigation"))
(def desktop-linking #js {:addEventListener (fn [])})
(def desktop-menu #js {:addEventListener (fn [])})
1 change: 1 addition & 0 deletions scripts/build-desktop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ external_modules_dir=( \
'modules/react-native-status/desktop' \
'node_modules/google-breakpad' \
'modules/react-native-desktop-linking/desktop' \
'modules/react-native-desktop-menu/desktop' \
'modules/react-native-desktop-notification/desktop' \
)

Expand Down
28 changes: 28 additions & 0 deletions src/status_im/ui/components/popup_menu/views.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(ns status-im.ui.components.popup-menu.views
(:require [status-im.ui.components.react :as react]
[status-im.react-native.js-dependencies :as rn-dependencies]
[status-im.utils.platform :as platform]
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]))

(defn show-desktop-menu [items]
(.show rn-dependencies/desktop-menu
(clj->js (mapv #(hash-map :text (:text %1) :onPress (:on-select %1)) items))))

(defn get-chat-menu-items [group-chat public? chat-id]
(->> [(when (and (not group-chat) (not public?))
{:text (i18n/label :t/view-profile)
:on-select #(re-frame/dispatch [:show-profile-desktop chat-id])})
(when (and group-chat (not public?))
{:text (i18n/label :t/group-info)
:on-select #(re-frame/dispatch [:show-group-chat-profile])})
{:text (i18n/label :t/clear-history)
:on-select #(re-frame/dispatch [:chat.ui/clear-history-pressed])}
{:text (i18n/label :t/delete-chat)
:on-select #(re-frame/dispatch [(if (and group-chat (not public?))
:group-chats.ui/remove-chat-pressed
:chat.ui/remove-chat-pressed)
chat-id])}]
(remove nil?)))

26 changes: 8 additions & 18 deletions src/status_im/ui/screens/desktop/main/chat/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.screens.desktop.main.chat.styles :as styles]
[status-im.contact.db :as contact.db]
[status-im.ui.components.popup-menu.views :as popup-menu]
[status-im.i18n :as i18n]
[status-im.ui.screens.desktop.main.chat.events :as chat.events]
[status-im.ui.screens.chat.message.message :as chat.message]))
Expand Down Expand Up @@ -49,24 +50,13 @@
public?
[react/text {:style styles/public-chat-text}
(i18n/label :t/public-chat)])]]
[react/view
(when (and (not group-chat) (not public?))
[react/text {:style (styles/profile-actions-text colors/black)
:on-press #(re-frame/dispatch [:show-profile-desktop public-key])}
(i18n/label :t/view-profile)])
(when (and group-chat (not public?))
[react/text {:style (styles/profile-actions-text colors/black)
:on-press #(re-frame/dispatch [:show-group-chat-profile])}
(i18n/label :t/group-info)])
[react/text {:style (styles/profile-actions-text colors/black)
:on-press #(re-frame/dispatch [:chat.ui/clear-history-pressed])}
(i18n/label :t/clear-history)]
[react/text {:style (styles/profile-actions-text colors/black)
:on-press #(re-frame/dispatch [(if (and group-chat (not public?))
:group-chats.ui/remove-chat-pressed
:chat.ui/remove-chat-pressed)
chat-id])}
(i18n/label :t/delete-chat)]]]))
[react/touchable-highlight
{:on-press #(popup-menu/show-desktop-menu
(popup-menu/get-chat-menu-items group-chat public? chat-id))}
[vector-icons/icon :icons/dots-horizontal
{:style {:tint-color colors/black
:width 24
:height 24}}]]]))

(views/defview message-author-name [{:keys [from]}]
(views/letsubs [incoming-name [:contacts/contact-name-by-identity from]]
Expand Down
12 changes: 10 additions & 2 deletions src/status_im/ui/screens/desktop/main/tabs/home/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]
[status-im.ui.screens.desktop.main.tabs.home.styles :as styles]
[status-im.ui.components.popup-menu.views :as popup-menu]
[clojure.string :as string]
[status-im.ui.screens.home.views.inner-item :as chat-item]
[taoensso.timbre :as log]
Expand Down Expand Up @@ -57,8 +58,15 @@
[react/view {:style styles/timestamp}
[chat-item/message-timestamp (:timestamp last-message)]]])))

(defn chat-list-item [[chat-id chat]]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])}
(defn chat-list-item [[chat-id
{:keys [group-chat public?] :as chat}]]
[react/touchable-highlight
{:on-press (fn [arg]
(let [right-click? (= "right" (.-button (.-nativeEvent arg)))]
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
(when right-click?
(popup-menu/show-desktop-menu
(popup-menu/get-chat-menu-items group-chat public? chat-id)))))}
[chat-list-item-inner-view (assoc chat :chat-id chat-id)]])

(defn tag-view [tag {:keys [on-press]}]
Expand Down
1 change: 0 additions & 1 deletion test/cljs/status_im/react_native/js_dependencies.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
(def linear-gradient #js {})
(def nfc #js {})
(def orientation #js {})
(def popup-menu #js {})
(def qr-code #js {})
(def nfc-manager #js {:default #js {}})
(def react-native
Expand Down