parent
86a06c9ef9
commit
45f5a53069
|
@ -31,6 +31,7 @@ add_subdirectory(vendor)
|
|||
|
||||
add_subdirectory(libs/ApplicationCore)
|
||||
add_subdirectory(libs/Assets)
|
||||
add_subdirectory(libs/ChatSection)
|
||||
add_subdirectory(libs/Helpers)
|
||||
add_subdirectory(libs/Onboarding)
|
||||
add_subdirectory(libs/Wallet)
|
||||
|
|
|
@ -67,6 +67,7 @@ target_link_libraries(${PROJECT_NAME}
|
|||
# TODO: Use Status:: namespace
|
||||
Status::ApplicationCore
|
||||
Status::Helpers
|
||||
Status::ChatSection
|
||||
Status::Onboarding
|
||||
Status::Wallet
|
||||
Status::Assets
|
||||
|
|
|
@ -45,16 +45,30 @@ Item {
|
|||
//type: // TODO: appController.bannerController.type
|
||||
visible: false // TODO: appController.bannerController.visible
|
||||
}
|
||||
Loader {
|
||||
|
||||
StackLayout {
|
||||
id: container
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
sourceComponent: navBar.currentSection
|
||||
currentIndex: navBar.currentIndex
|
||||
|
||||
Repeater{
|
||||
model: appSections.sections
|
||||
|
||||
delegate: Loader {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
sourceComponent: modelData.content
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusApplicationSections {
|
||||
id: appSections
|
||||
appController: root.appController
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,33 @@ import QtQml
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
import Status.Application
|
||||
import Status.Application.Navigation
|
||||
import Status.Controls.Navigation
|
||||
import Status.Wallet
|
||||
import Status.ChatSection as ChatSectionModule
|
||||
|
||||
Item {
|
||||
property var sections: [walletSection, settingsSection]
|
||||
id: root
|
||||
|
||||
required property ApplicationController appController
|
||||
property var sections: [chatSection, walletSection, settingsSection]
|
||||
|
||||
ButtonGroup {
|
||||
id: oneSectionSelectedGroup
|
||||
}
|
||||
|
||||
ApplicationSection {
|
||||
id: chatSection
|
||||
navigationSection: SimpleNavBarSection {
|
||||
name: "Chat"
|
||||
mutuallyExclusiveGroup: oneSectionSelectedGroup
|
||||
}
|
||||
content: ChatSectionModule.MainView {
|
||||
sectionId: root.appController.dbSettings.publicKey
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationSection {
|
||||
id: walletSection
|
||||
navigationSection: SimpleNavBarSection {
|
||||
|
@ -21,6 +37,7 @@ Item {
|
|||
}
|
||||
content: WalletView {}
|
||||
}
|
||||
|
||||
ApplicationSection {
|
||||
id: settingsSection
|
||||
navigationSection: SimpleNavBarSection {
|
||||
|
|
|
@ -31,6 +31,7 @@ Item {
|
|||
OnboardingView {
|
||||
onUserLoggedIn: function (statusAccount) {
|
||||
splashScreenPopup.open()
|
||||
appController.initOnLogin();
|
||||
//appController.statusAccount = statusAccount
|
||||
contentLoader.sourceComponent = mainViewComponent
|
||||
}
|
||||
|
|
|
@ -1,15 +1,30 @@
|
|||
#include "ApplicationController.h"
|
||||
|
||||
#include <QtQml/QQmlEngine>
|
||||
|
||||
namespace Status::Application {
|
||||
|
||||
ApplicationController::ApplicationController(QObject *parent)
|
||||
: QObject{parent}
|
||||
, m_dataProvider(std::make_unique<DataProvider>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ApplicationController::initOnLogin()
|
||||
{
|
||||
auto dbSettings = m_dataProvider->getSettings();
|
||||
m_dbSettings = std::make_shared<DbSettingsObj>(dbSettings);
|
||||
}
|
||||
|
||||
QObject *ApplicationController::dbSettings() const
|
||||
{
|
||||
return m_dbSettings.get();
|
||||
}
|
||||
|
||||
QObject *ApplicationController::statusAccount() const
|
||||
{
|
||||
QQmlEngine::setObjectOwnership(m_statusAccount, QQmlEngine::CppOwnership);
|
||||
return m_statusAccount;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "DbSettingsObj.h"
|
||||
#include "DataProvider.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QtQml/qqmlregistration.h>
|
||||
|
@ -18,17 +20,25 @@ class ApplicationController : public QObject
|
|||
QML_ELEMENT
|
||||
|
||||
Q_PROPERTY(QObject* statusAccount READ statusAccount WRITE setStatusAccount NOTIFY statusAccountChanged)
|
||||
Q_PROPERTY(QObject* dbSettings READ dbSettings CONSTANT)
|
||||
|
||||
public:
|
||||
explicit ApplicationController(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void initOnLogin();
|
||||
|
||||
QObject *statusAccount() const;
|
||||
void setStatusAccount(QObject *newStatusAccount);
|
||||
|
||||
QObject* dbSettings() const;
|
||||
|
||||
signals:
|
||||
void statusAccountChanged();
|
||||
|
||||
private:
|
||||
QObject* m_statusAccount{};
|
||||
std::unique_ptr<DataProvider> m_dataProvider;
|
||||
std::shared_ptr<DbSettingsObj> m_dbSettings;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,8 +6,12 @@ target_include_directories(${PROJECT_NAME}
|
|||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ApplicationController.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ApplicationController.cpp
|
||||
ApplicationController.h
|
||||
ApplicationController.cpp
|
||||
DataProvider.h
|
||||
DataProvider.cpp
|
||||
DbSettingsObj.h
|
||||
DbSettingsObj.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
CMakeLists.txt
|
||||
)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#include "DataProvider.h"
|
||||
|
||||
using namespace Status::Application;
|
||||
|
||||
namespace StatusGo = Status::StatusGo;
|
||||
|
||||
DataProvider::DataProvider()
|
||||
: QObject(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
StatusGo::Settings::SettingsDto DataProvider::getSettings() const
|
||||
{
|
||||
try {
|
||||
return StatusGo::Settings::getSettings();
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
qWarning() << "DataProvider::getSettings, error: " << e.what();
|
||||
}
|
||||
catch (...) {
|
||||
qWarning() << "DataProvider::getSettings, unknown error";
|
||||
}
|
||||
return StatusGo::Settings::SettingsDto{};
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <StatusGo/SettingsAPI>
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
namespace Status::Application {
|
||||
|
||||
class DataProvider: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DataProvider();
|
||||
|
||||
StatusGo::Settings::SettingsDto getSettings() const;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
#include "DbSettingsObj.h"
|
||||
|
||||
using namespace Status::Application;
|
||||
|
||||
DbSettingsObj::DbSettingsObj(StatusGo::Settings::SettingsDto rawData)
|
||||
: QObject(nullptr)
|
||||
, m_data(std::move(rawData))
|
||||
{
|
||||
}
|
||||
|
||||
QString DbSettingsObj::address() const
|
||||
{
|
||||
return m_data.address;
|
||||
}
|
||||
|
||||
void DbSettingsObj::setAddress(const QString& value)
|
||||
{
|
||||
if (m_data.address == value)
|
||||
return;
|
||||
m_data.address = value;
|
||||
emit addressChanged();
|
||||
}
|
||||
|
||||
QString DbSettingsObj::displayName() const
|
||||
{
|
||||
return m_data.displayName;
|
||||
}
|
||||
|
||||
void DbSettingsObj::setDisplayName(const QString& value)
|
||||
{
|
||||
if (m_data.displayName == value)
|
||||
return;
|
||||
m_data.displayName = value;
|
||||
emit displayNameChanged();
|
||||
}
|
||||
|
||||
QString DbSettingsObj::preferredName() const
|
||||
{
|
||||
return m_data.preferredName;
|
||||
}
|
||||
|
||||
void DbSettingsObj::setPreferredName(const QString& value)
|
||||
{
|
||||
if (m_data.preferredName == value)
|
||||
return;
|
||||
m_data.preferredName = value;
|
||||
emit preferredNameChanged();
|
||||
}
|
||||
|
||||
QString DbSettingsObj::keyUid() const
|
||||
{
|
||||
return m_data.keyUid;
|
||||
}
|
||||
|
||||
void DbSettingsObj::setKeyUid(const QString& value)
|
||||
{
|
||||
if (m_data.keyUid == value)
|
||||
return;
|
||||
m_data.keyUid = value;
|
||||
emit keyUidChanged();
|
||||
}
|
||||
|
||||
QString DbSettingsObj::publicKey() const
|
||||
{
|
||||
return m_data.publicKey;
|
||||
}
|
||||
|
||||
void DbSettingsObj::setPublicKey(const QString& value)
|
||||
{
|
||||
if (m_data.publicKey == value)
|
||||
return;
|
||||
m_data.publicKey = value;
|
||||
emit publicKeyChanged();
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <StatusGo/SettingsAPI>
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
namespace Status::Application {
|
||||
|
||||
class DbSettingsObj: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString address READ address NOTIFY addressChanged)
|
||||
Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged)
|
||||
Q_PROPERTY(QString preferredName READ preferredName NOTIFY preferredNameChanged)
|
||||
Q_PROPERTY(QString keyUid READ keyUid NOTIFY keyUidChanged)
|
||||
Q_PROPERTY(QString publicKey READ publicKey NOTIFY publicKeyChanged)
|
||||
|
||||
|
||||
public:
|
||||
explicit DbSettingsObj(StatusGo::Settings::SettingsDto rawData);
|
||||
|
||||
[[nodiscard]] QString address() const;
|
||||
void setAddress(const QString& address);
|
||||
|
||||
[[nodiscard]] QString displayName() const;
|
||||
void setDisplayName(const QString& value);
|
||||
|
||||
[[nodiscard]] QString preferredName() const;
|
||||
void setPreferredName(const QString& value);
|
||||
|
||||
[[nodiscard]] QString keyUid() const;
|
||||
void setKeyUid(const QString& value);
|
||||
|
||||
[[nodiscard]] QString publicKey() const;
|
||||
void setPublicKey(const QString& value);
|
||||
|
||||
|
||||
signals:
|
||||
void addressChanged();
|
||||
void displayNameChanged();
|
||||
void preferredNameChanged();
|
||||
void keyUidChanged();
|
||||
void publicKeyChanged();
|
||||
|
||||
private:
|
||||
StatusGo::Settings::SettingsDto m_data;
|
||||
};
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace fs = std::filesystem;
|
|||
namespace Status::ApplicationCore {
|
||||
|
||||
namespace {
|
||||
/// `status-go` data location
|
||||
constexpr auto statusFolder = "Status";
|
||||
constexpr auto dataSubfolder = "data";
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ void UserConfiguration::setUserDataFolder(const QString &newUserDataFolder)
|
|||
|
||||
void UserConfiguration::generateReleaseConfiguration()
|
||||
{
|
||||
m_userDataFolder = toPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))/dataSubfolder;
|
||||
m_userDataFolder = toPath(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation))/statusFolder/dataSubfolder;
|
||||
emit userDataFolderChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,11 @@ class UserConfiguration: public QObject
|
|||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
// Not sure why `qmlUserDataFolder` is writable??? We should not change it from the qml side.
|
||||
// Even from the backend side this will be set only on the app start, and it will contain
|
||||
// necessary data for each created account, so even we're switching accounts, this will be the same path.
|
||||
Q_PROPERTY(QString userDataFolder READ qmlUserDataFolder WRITE setUserDataFolder NOTIFY userDataFolderChanged)
|
||||
|
||||
public:
|
||||
explicit UserConfiguration(QObject *parent = nullptr);
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
project(ChatSection
|
||||
VERSION 0.1.0
|
||||
LANGUAGES CXX)
|
||||
|
||||
set(QT_NO_CREATE_VERSIONLESS_FUNCTIONS true)
|
||||
|
||||
find_package(Qt6 ${STATUS_QT_VERSION} COMPONENTS Quick Qml Concurrent REQUIRED)
|
||||
qt6_standard_project_setup()
|
||||
|
||||
qt6_add_qml_module(${PROJECT_NAME}
|
||||
URI Status.ChatSection
|
||||
VERSION 1.0
|
||||
|
||||
QML_FILES
|
||||
qml/Status/ChatSection/NavigationView.qml
|
||||
qml/Status/ChatSection/ContentView.qml
|
||||
qml/Status/ChatSection/MainView.qml
|
||||
|
||||
# Required to suppress "qmllint may not work" warning
|
||||
OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Status/${PROJECT_NAME}/
|
||||
)
|
||||
add_library(Status::ChatSection ALIAS ChatSection)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
|
||||
# Workaround to Qt6's *_qmltyperegistrations.cpp
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/Status/ChatSection/
|
||||
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
Qt6::Quick
|
||||
Qt6::Qml
|
||||
Qt6::Concurrent
|
||||
|
||||
Status::ApplicationCore
|
||||
|
||||
Status::StatusGoQt
|
||||
)
|
||||
|
||||
# QtCreator needs this
|
||||
set(QML_IMPORT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/qml;${QML_IMPORT_PATH} CACHE STRING "For QtCreator" FORCE)
|
||||
list(REMOVE_DUPLICATES QML_IMPORT_PATH)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${PROJECT_NAME}
|
||||
RUNTIME
|
||||
)
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
include/Status/ChatSection/ChatSectionController.h
|
||||
src/ChatSectionController.cpp
|
||||
include/Status/ChatSection/ChatItem.h
|
||||
src/ChatItem.cpp
|
||||
include/Status/ChatSection/ChatDataProvider.h
|
||||
src/ChatDataProvider.cpp
|
||||
)
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <StatusGo/ChatAPI>
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
namespace Status::ChatSection {
|
||||
|
||||
class ChatDataProvider: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatDataProvider();
|
||||
|
||||
StatusGo::Chats::ChannelGroupDto getSectionData(const QString& sectionId) const;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include <StatusGo/ChatAPI>
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
namespace Status::ChatSection {
|
||||
|
||||
class ChatItem: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString id READ id CONSTANT)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
|
||||
Q_PROPERTY(QColor color READ color NOTIFY colorChanged)
|
||||
Q_PROPERTY(bool muted READ muted NOTIFY mutedChanged)
|
||||
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
|
||||
|
||||
public:
|
||||
explicit ChatItem(StatusGo::Chats::ChatDto rawData);
|
||||
|
||||
[[nodiscard]] QString id() const;
|
||||
|
||||
[[nodiscard]] QString name() const;
|
||||
void setName(const QString& value);
|
||||
|
||||
[[nodiscard]] QString description() const;
|
||||
void setDescription(const QString& value);
|
||||
|
||||
[[nodiscard]] QColor color() const;
|
||||
void setColor(const QColor& value);
|
||||
|
||||
[[nodiscard]] bool muted() const;
|
||||
void setMuted(bool value);
|
||||
|
||||
[[nodiscard]] bool active() const;
|
||||
void setActive(bool value);
|
||||
|
||||
signals:
|
||||
void nameChanged();
|
||||
void descriptionChanged();
|
||||
void colorChanged();
|
||||
void mutedChanged();
|
||||
void activeChanged();
|
||||
|
||||
private:
|
||||
StatusGo::Chats::ChatDto m_data;
|
||||
};
|
||||
|
||||
using ChatItemPtr = std::shared_ptr<ChatItem>;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "ChatItem.h"
|
||||
#include "ChatDataProvider.h"
|
||||
|
||||
#include <Helpers/QObjectVectorModel.h>
|
||||
|
||||
namespace Status::ChatSection {
|
||||
|
||||
class ChatSectionController: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
Q_PROPERTY(QAbstractListModel* chatsModel READ chatsModel NOTIFY chatsModelChanged)
|
||||
Q_PROPERTY(ChatItem* currentChat READ currentChat NOTIFY currentChatChanged)
|
||||
|
||||
public:
|
||||
ChatSectionController();
|
||||
|
||||
QAbstractListModel* chatsModel() const;
|
||||
ChatItem* currentChat() const;
|
||||
|
||||
Q_INVOKABLE void init(const QString& sectionId);
|
||||
Q_INVOKABLE void setCurrentChatIndex(int index);
|
||||
|
||||
signals:
|
||||
void chatsModelChanged();
|
||||
void currentChatChanged();
|
||||
|
||||
private:
|
||||
using ChatsModel = Helpers::QObjectVectorModel<ChatItem>;
|
||||
std::shared_ptr<ChatsModel> m_chats;
|
||||
std::unique_ptr<ChatDataProvider> m_dataProvider;
|
||||
ChatItemPtr m_currentChat;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Status.ChatSection
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property var selectedChat
|
||||
|
||||
ColumnLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Label {
|
||||
text: "selected chat: %1".arg(root.selectedChat.name)
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "chat id: %1".arg(root.selectedChat.id)
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "description: %1".arg(root.selectedChat.description)
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "chat color"
|
||||
color: root.selectedChat.color
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "is active: %1".arg(root.selectedChat.active)
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "is muted: %1".arg(root.selectedChat.muted)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
import QtQml
|
||||
|
||||
import Qt.labs.platform
|
||||
|
||||
import Status.ChatSection
|
||||
|
||||
import Status.Containers
|
||||
import Status.Controls.Navigation
|
||||
|
||||
PanelAndContentBase {
|
||||
id: root
|
||||
|
||||
required property string sectionId
|
||||
|
||||
implicitWidth: 1232
|
||||
implicitHeight: 770
|
||||
|
||||
ChatSectionController {
|
||||
id: chatSectionController
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
chatSectionController.init(root.sectionId)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: mainLayout
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
NavigationView {
|
||||
id: panel
|
||||
|
||||
Layout.preferredWidth: root.panelWidth
|
||||
Layout.fillHeight: true
|
||||
|
||||
chatSectionController: chatSectionController
|
||||
}
|
||||
|
||||
ContentView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
selectedChat: chatSectionController.currentChat
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Status.ChatSection
|
||||
|
||||
import Status.Containers
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property var chatSectionController
|
||||
|
||||
ColumnLayout {
|
||||
anchors.left: leftLine.right
|
||||
anchors.top: parent.top
|
||||
anchors.right: rightLine.left
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
Label {
|
||||
text: qsTr("Chats")
|
||||
}
|
||||
|
||||
LayoutSpacer {
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
model: root.chatSectionController.chatsModel
|
||||
|
||||
onCurrentIndexChanged: root.chatSectionController.setCurrentChatIndex(currentIndex)
|
||||
|
||||
clip: true
|
||||
|
||||
delegate: ItemDelegate {
|
||||
width: ListView.view.width
|
||||
highlighted: ListView.isCurrentItem
|
||||
|
||||
onClicked: ListView.view.currentIndex = index
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 4
|
||||
|
||||
RowLayout {
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 15
|
||||
Layout.preferredHeight: Layout.preferredWidth
|
||||
Layout.leftMargin: 5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
radius: width/2
|
||||
color: chat.color
|
||||
}
|
||||
Label {
|
||||
Layout.leftMargin: 10
|
||||
Layout.topMargin: 5
|
||||
Layout.rightMargin: 10
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
text: chat.name
|
||||
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
elide: Label.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SideLine { id: leftLine; anchors.left: parent.left }
|
||||
SideLine { id: rightLine; anchors.right: parent.right }
|
||||
|
||||
component SideLine: Rectangle {
|
||||
color: "black"
|
||||
width: 1
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#include "ChatDataProvider.h"
|
||||
|
||||
using namespace Status::ChatSection;
|
||||
|
||||
namespace StatusGo = Status::StatusGo;
|
||||
|
||||
ChatDataProvider::ChatDataProvider()
|
||||
: QObject(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
StatusGo::Chats::ChannelGroupDto ChatDataProvider::getSectionData(const QString& sectionId) const
|
||||
{
|
||||
try {
|
||||
auto result = StatusGo::Chats::getChats();
|
||||
for(auto chGroup : result.allChannelGroups) {
|
||||
if (chGroup.id == sectionId)
|
||||
return chGroup;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
qWarning() << "ChatDataProvider::getSectionData, error: " << e.what();
|
||||
}
|
||||
catch (...) {
|
||||
qWarning() << "ChatDataProvider::getSectionData, unknown error";
|
||||
}
|
||||
return StatusGo::Chats::ChannelGroupDto{};
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#include "Status/ChatSection/ChatItem.h"
|
||||
|
||||
using namespace Status::ChatSection;
|
||||
|
||||
ChatItem::ChatItem(StatusGo::Chats::ChatDto rawData)
|
||||
: QObject(nullptr)
|
||||
, m_data(std::move(rawData))
|
||||
{
|
||||
}
|
||||
|
||||
QString ChatItem::id() const
|
||||
{
|
||||
return m_data.id;
|
||||
}
|
||||
|
||||
QString ChatItem::name() const
|
||||
{
|
||||
return m_data.name;
|
||||
}
|
||||
|
||||
void ChatItem::setName(const QString& value)
|
||||
{
|
||||
if (m_data.name == value)
|
||||
return;
|
||||
m_data.name = value;
|
||||
emit nameChanged();
|
||||
}
|
||||
|
||||
QString ChatItem::description() const
|
||||
{
|
||||
return m_data.description;
|
||||
}
|
||||
|
||||
void ChatItem::setDescription(const QString& value)
|
||||
{
|
||||
if (m_data.description == value)
|
||||
return;
|
||||
m_data.description = value;
|
||||
emit descriptionChanged();
|
||||
}
|
||||
|
||||
QColor ChatItem::color() const
|
||||
{
|
||||
return m_data.color;
|
||||
}
|
||||
|
||||
void ChatItem::setColor(const QColor& value)
|
||||
{
|
||||
if (m_data.color == value)
|
||||
return;
|
||||
m_data.color = value;
|
||||
emit colorChanged();
|
||||
}
|
||||
|
||||
bool ChatItem::muted() const
|
||||
{
|
||||
return m_data.muted;
|
||||
}
|
||||
|
||||
void ChatItem::setMuted(bool value)
|
||||
{
|
||||
if (m_data.muted == value)
|
||||
return;
|
||||
m_data.muted = value;
|
||||
emit mutedChanged();
|
||||
}
|
||||
|
||||
bool ChatItem::active() const
|
||||
{
|
||||
return m_data.active;
|
||||
}
|
||||
|
||||
void ChatItem::setActive(bool value)
|
||||
{
|
||||
if (m_data.active == value)
|
||||
return;
|
||||
m_data.active = value;
|
||||
emit activeChanged();
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include "Status/ChatSection/ChatSectionController.h"
|
||||
|
||||
using namespace Status::ChatSection;
|
||||
|
||||
ChatSectionController::ChatSectionController()
|
||||
: QObject(nullptr)
|
||||
, m_dataProvider(std::make_unique<ChatDataProvider>())
|
||||
{
|
||||
}
|
||||
|
||||
void ChatSectionController::init(const QString& sectionId)
|
||||
{
|
||||
auto chatSectionData = m_dataProvider->getSectionData(sectionId);
|
||||
std::vector<ChatItemPtr> model;
|
||||
for (auto c : chatSectionData.chats) {
|
||||
model.push_back(std::make_shared<ChatItem>(std::move(c)));
|
||||
}
|
||||
m_chats = std::make_shared<ChatsModel>(std::move(model), "chat");
|
||||
setCurrentChatIndex(0);
|
||||
emit chatsModelChanged();
|
||||
}
|
||||
|
||||
QAbstractListModel* ChatSectionController::chatsModel() const
|
||||
{
|
||||
return m_chats.get();
|
||||
}
|
||||
|
||||
ChatItem* ChatSectionController::currentChat() const
|
||||
{
|
||||
return m_currentChat.get();
|
||||
}
|
||||
|
||||
void ChatSectionController::setCurrentChatIndex(int index)
|
||||
{
|
||||
assert(index >= 0 && index < m_chats->size());
|
||||
|
||||
auto chat = m_chats->get(index);
|
||||
if (m_currentChat == chat)
|
||||
return;
|
||||
|
||||
m_currentChat = chat;
|
||||
emit currentChatChanged();
|
||||
}
|
|
@ -35,17 +35,17 @@ endif()
|
|||
|
||||
set(BUILD_GENERATED_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/template/BuildConfiguration.h.in"
|
||||
configure_file("template/BuildConfiguration.h.in"
|
||||
"${BUILD_GENERATED_DIRECTORY}/Helpers/BuildConfiguration.h"
|
||||
@ONLY)
|
||||
|
||||
target_include_directories(Helpers
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
src
|
||||
${BUILD_GENERATED_DIRECTORY}
|
||||
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers
|
||||
src/Helpers
|
||||
${BUILD_GENERATED_DIRECTORY}/Helpers
|
||||
)
|
||||
|
||||
|
@ -66,12 +66,14 @@ install(
|
|||
|
||||
target_sources(Helpers
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/conversions.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/conversions.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/helpers.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/logs.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/logs.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/NamedType.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/QObjectVectorModel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Helpers/Singleton.h
|
||||
src/Helpers/conversions.h
|
||||
src/Helpers/conversions.cpp
|
||||
src/Helpers/helpers.h
|
||||
src/Helpers/logs.h
|
||||
src/Helpers/logs.cpp
|
||||
src/Helpers/NamedType.h
|
||||
src/Helpers/QObjectVectorModel.h
|
||||
src/Helpers/Singleton.h
|
||||
src/Helpers/Macros.h
|
||||
src/Helpers/JsonMacros.h
|
||||
)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "Macros.h"
|
||||
|
||||
#define STATUS_READ_NLOHMAN_JSON_PROPERTY_3_ARGS(FIELD, NAME, REQUIRED) \
|
||||
if(REQUIRED) \
|
||||
j.at(NAME).get_to(d.FIELD); \
|
||||
else if(j.contains(NAME)) \
|
||||
j.at(NAME).get_to(d.FIELD); \
|
||||
|
||||
#define STATUS_READ_NLOHMAN_JSON_PROPERTY_2_ARGS(FIELD, NAME) \
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY_3_ARGS(FIELD, NAME, true)
|
||||
|
||||
#define STATUS_READ_NLOHMAN_JSON_PROPERTY_1_ARGS(FIELD) \
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY_2_ARGS(FIELD, #FIELD)
|
||||
|
||||
// This macro reads prop from the nlohman json object. It implies that nlohman json object is named `j` and the struct
|
||||
// instance that json object should be mapped to is named `d`.
|
||||
//
|
||||
// If the field is required this macro reads a property from nlohmann json object and sets it to the passed field,
|
||||
// in case the property doesn't exist an error is thrown.
|
||||
//
|
||||
// If the field is not required this macro reads a property from nlohmann json object and sets it to the passed field
|
||||
// only if the property exists it cannot throws an error ever.
|
||||
//
|
||||
// Usage: STATUS_READ_NLOHMAN_JSON_PROPERTY(field)
|
||||
// STATUS_READ_NLOHMAN_JSON_PROPERTY(field, "realFieldName")
|
||||
// STATUS_READ_NLOHMAN_JSON_PROPERTY(field, "realFieldName", false)
|
||||
//
|
||||
#define STATUS_READ_NLOHMAN_JSON_PROPERTY(...) \
|
||||
STATUS_EXPAND( \
|
||||
STATUS_MACRO_SELECTOR_3_ARGS( \
|
||||
__VA_ARGS__, \
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY_3_ARGS, \
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY_2_ARGS, \
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY_1_ARGS \
|
||||
)(__VA_ARGS__) \
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
// Macro arguments are completely macro-expanded before they are substituted into a macro body.
|
||||
#define STATUS_EXPAND(x) x
|
||||
|
||||
// 2 arguments macro selector.
|
||||
#define STATUS_MACRO_SELECTOR_2_ARGS(_1, _2, selected, ...) \
|
||||
selected
|
||||
|
||||
// 3 arguments macro selector.
|
||||
#define STATUS_MACRO_SELECTOR_3_ARGS(_1, _2, _3, selected, ...) \
|
||||
selected
|
|
@ -37,13 +37,13 @@ add_library(Status::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
|||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo
|
||||
src/StatusGo
|
||||
# TODO: Workaround to QML_ELEMENT Qt6
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo
|
||||
src/StatusGo
|
||||
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
src
|
||||
)
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
@ -69,35 +69,45 @@ install(
|
|||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/General.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/General.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Utils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Utils.cpp
|
||||
src/StatusGo/General.h
|
||||
src/StatusGo/General.cpp
|
||||
src/StatusGo/Types.h
|
||||
src/StatusGo/Utils.h
|
||||
src/StatusGo/Utils.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/Accounts.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/Accounts.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/accounts_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/AccountsAPI.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/AccountsAPI.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/ChatOrWalletAccount.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Accounts/ChatOrWalletAccount.cpp
|
||||
src/StatusGo/Accounts/Accounts.h
|
||||
src/StatusGo/Accounts/Accounts.cpp
|
||||
src/StatusGo/Accounts/accounts_types.h
|
||||
src/StatusGo/Accounts/AccountsAPI.h
|
||||
src/StatusGo/Accounts/AccountsAPI.cpp
|
||||
src/StatusGo/Accounts/ChatOrWalletAccount.h
|
||||
src/StatusGo/Accounts/ChatOrWalletAccount.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Messenger/Service.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Messenger/Service.cpp
|
||||
src/StatusGo/Chat/ChatAPI.h
|
||||
src/StatusGo/Chat/ChatAPI.cpp
|
||||
src/StatusGo/Chat/ChatDto.h
|
||||
src/StatusGo/Chat/ChatDto.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Metadata/api_response.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Metadata/api_response.cpp
|
||||
src/StatusGo/Messenger/Service.h
|
||||
src/StatusGo/Messenger/Service.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/SignalsManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/SignalsManager.cpp
|
||||
src/StatusGo/Metadata/api_response.h
|
||||
src/StatusGo/Metadata/api_response.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/BigInt.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/BigInt.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/DerivedAddress.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/NetworkConfiguration.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/Token.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/wallet_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/WalletApi.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StatusGo/Wallet/WalletApi.cpp
|
||||
src/StatusGo/SignalsManager.h
|
||||
src/StatusGo/SignalsManager.cpp
|
||||
|
||||
src/StatusGo/Settings/SettingsAPI.h
|
||||
src/StatusGo/Settings/SettingsAPI.cpp
|
||||
src/StatusGo/Settings/SettingsDto.h
|
||||
src/StatusGo/Settings/SettingsDto.cpp
|
||||
|
||||
src/StatusGo/Wallet/BigInt.h
|
||||
src/StatusGo/Wallet/BigInt.cpp
|
||||
src/StatusGo/Wallet/DerivedAddress.h
|
||||
src/StatusGo/Wallet/NetworkConfiguration.h
|
||||
src/StatusGo/Wallet/Token.h
|
||||
src/StatusGo/Wallet/wallet_types.h
|
||||
src/StatusGo/Wallet/WalletApi.h
|
||||
src/StatusGo/Wallet/WalletApi.cpp
|
||||
)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#include "ChatAPI.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "Metadata/api_response.h"
|
||||
|
||||
#include <libstatus.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
using namespace Status::StatusGo;
|
||||
|
||||
Chats::AllChannelGroupsDto Chats::getChats()
|
||||
{
|
||||
json inputJson = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", "chat_getChats"},
|
||||
{"params", json::array()}
|
||||
};
|
||||
|
||||
auto result = Utils::statusGoCallPrivateRPC(inputJson.dump().c_str());
|
||||
const auto resultJson = json::parse(result);
|
||||
checkPrivateRpcCallResultAndReportError(resultJson);
|
||||
|
||||
return resultJson.get<CallPrivateRpcResponse>().result;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "ChatDto.h"
|
||||
|
||||
namespace Status::StatusGo::Chats
|
||||
{
|
||||
/// \brief Retrieve all available channel groups
|
||||
AllChannelGroupsDto getChats();
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
#include "ChatDto.h"
|
||||
|
||||
#include <Helpers/conversions.h>
|
||||
#include <Helpers/JsonMacros.h>
|
||||
|
||||
using namespace Status::StatusGo;
|
||||
|
||||
void Chats::to_json(json& j, const Category& d) {
|
||||
j = {{"id", d.id},
|
||||
{"name", d.name},
|
||||
{"position", d.position},
|
||||
};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, Category& d) {
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(name)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(position)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(id, "category_id", false)
|
||||
if (!j.contains("category_id")){
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(id, "id", false)
|
||||
}
|
||||
}
|
||||
|
||||
void Chats::to_json(json& j, const Permission& d) {
|
||||
j = {{"access", d.access},
|
||||
{"ens_only", d.ensOnly},
|
||||
};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, Permission& d) {
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(access, "access", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(ensOnly, "ens_only", false)
|
||||
}
|
||||
|
||||
void Chats::to_json(json& j, const Images& d) {
|
||||
j = {{"large", d.large},
|
||||
{"thumbnail", d.thumbnail},
|
||||
{"banner", d.banner},
|
||||
};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, Images& d) {
|
||||
constexpr auto large = "large";
|
||||
if(j.contains(large))
|
||||
j[large].at("uri").get_to(d.large);
|
||||
|
||||
constexpr auto thumbnail = "thumbnail";
|
||||
if(j.contains(thumbnail))
|
||||
j[thumbnail].at("uri").get_to(d.thumbnail);
|
||||
|
||||
constexpr auto banner = "banner";
|
||||
if(j.contains(banner))
|
||||
j[banner].at("uri").get_to(d.banner);
|
||||
}
|
||||
|
||||
void Chats::to_json(json& j, const ChatMember& d) {
|
||||
j = {{"id", d.id},
|
||||
{"admin", d.admin},
|
||||
{"joined", d.joined},
|
||||
{"roles", d.roles},
|
||||
};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, ChatMember& d) {
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(id)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(joined)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(roles)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(admin, "admin", false)
|
||||
}
|
||||
|
||||
void Chats::to_json(json& j, const ChatDto& d) {
|
||||
j = {{"id", d.id},
|
||||
{"name", d.name},
|
||||
{"description", d.description},
|
||||
{"color", d.color},
|
||||
{"emoji", d.emoji},
|
||||
{"active", d.active},
|
||||
{"timestamp", d.timestamp},
|
||||
{"lastClockValue", d.lastClockValue},
|
||||
{"deletedAtClockValue", d.deletedAtClockValue},
|
||||
{"readMessagesAtClockValue", d.readMessagesAtClockValue},
|
||||
{"unviewedMessagesCount", d.unviewedMessagesCount},
|
||||
{"unviewedMentionsCount", d.unviewedMentionsCount},
|
||||
{"canPost", d.canPost},
|
||||
{"alias", d.alias},
|
||||
{"identicon", d.icon},
|
||||
{"muted", d.muted},
|
||||
{"position", d.position},
|
||||
{"communityId", d.communityId},
|
||||
{"profile", d.profile},
|
||||
{"joined", d.joined},
|
||||
{"syncedTo", d.syncedTo},
|
||||
{"syncedFrom", d.syncedFrom},
|
||||
{"highlight", d.highlight},
|
||||
{"categoryId", d.categoryId},
|
||||
{"permissions", d.permissions},
|
||||
{"chatType", d.chatType},
|
||||
{"members", d.members},
|
||||
};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, ChatDto& d) {
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(id)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(name)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(description)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(color)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(emoji)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(active)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(timestamp)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(lastClockValue)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(deletedAtClockValue)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(readMessagesAtClockValue)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(unviewedMessagesCount)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(unviewedMentionsCount)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(canPost)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(alias, "alias", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(icon, "icon", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(muted)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(position, "position", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(communityId)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(profile, "profile", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(joined)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(syncedTo)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(syncedFrom)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(highlight, "highlight", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(permissions, "permissions", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(chatType)
|
||||
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(categoryId, "categoryId", false)
|
||||
if (!j.contains("categoryId")) {
|
||||
// Communities have `categoryID` and chats have `categoryId`
|
||||
// This should be fixed in status-go, but would be a breaking change
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(categoryId, "categoryID", false)
|
||||
}
|
||||
|
||||
// Add community ID if needed
|
||||
if (!d.communityId.isEmpty() && !d.id.contains(d.communityId)) {
|
||||
d.id = d.communityId + d.id;
|
||||
}
|
||||
|
||||
constexpr auto membersKey = "members";
|
||||
if (j.contains(membersKey)) {
|
||||
if (j[membersKey].is_array()) {
|
||||
j.at(membersKey).get_to(d.members);
|
||||
}
|
||||
else if (j[membersKey].is_object()) {
|
||||
auto obj = j[membersKey];
|
||||
for (json::const_iterator it = obj.cbegin(); it != obj.cend(); ++it) {
|
||||
ChatMember chatMember;
|
||||
it.value().get_to(chatMember);
|
||||
chatMember.id = it.key().c_str();
|
||||
d.members.emplace_back(std::move(chatMember));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Chats::to_json(json& j, const ChannelGroupDto& d) {
|
||||
j = {{"id", d.id},
|
||||
{"admin", d.admin},
|
||||
{"verified", d.verified},
|
||||
{"name", d.name},
|
||||
{"description", d.description},
|
||||
{"introMessage", d.introMessage},
|
||||
{"outroMessage", d.outroMessage},
|
||||
{"canManageUsers", d.canManageUsers},
|
||||
{"color", d.color},
|
||||
{"muted", d.muted},
|
||||
{"images", d.images},
|
||||
{"permissions", d.permissions},
|
||||
{"channelGroupType", d.channelGroupType},
|
||||
{"chats", d.chats},
|
||||
{"categories", d.categories},
|
||||
{"members", d.members},
|
||||
};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, ChannelGroupDto& d) {
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(admin)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(verified)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(name)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(description)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(introMessage)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(outroMessage)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(canManageUsers)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(color)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(muted)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(images)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(permissions, "permissions", false)
|
||||
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(channelGroupType)
|
||||
if (d.channelGroupType.isEmpty())
|
||||
d.channelGroupType = ChannelGroupTypeUnknown;
|
||||
|
||||
constexpr auto chats = "chats";
|
||||
if (j.contains(chats)) {
|
||||
auto obj = j[chats];
|
||||
for (json::const_iterator it = obj.cbegin(); it != obj.cend(); ++it) {
|
||||
ChatDto chatDto;
|
||||
it.value().get_to(chatDto);
|
||||
d.chats.emplace_back(std::move(chatDto));
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto categories = "categories";
|
||||
if (j.contains(categories)) {
|
||||
auto obj = j[categories];
|
||||
for (json::const_iterator it = obj.cbegin(); it != obj.cend(); ++it) {
|
||||
Category category;
|
||||
it.value().get_to(category);
|
||||
d.categories.emplace_back(std::move(category));
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto membersKey = "members";
|
||||
if (j.contains(membersKey)) {
|
||||
if (j[membersKey].is_object()) {
|
||||
auto obj = j[membersKey];
|
||||
for (json::const_iterator it = obj.cbegin(); it != obj.cend(); ++it) {
|
||||
ChatMember chatMember;
|
||||
it.value().get_to(chatMember);
|
||||
chatMember.id = it.key().c_str();
|
||||
d.members.emplace_back(std::move(chatMember));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Chats::to_json(json& j, const AllChannelGroupsDto& d) {
|
||||
j = {{"id", d.allChannelGroups}};
|
||||
}
|
||||
|
||||
void Chats::from_json(const json& j, AllChannelGroupsDto& d) {
|
||||
for (json::const_iterator it = j.cbegin(); it != j.cend(); ++it) {
|
||||
ChannelGroupDto channelGroupDto;
|
||||
it.value().get_to(channelGroupDto);
|
||||
channelGroupDto.id = it.key().c_str();
|
||||
d.allChannelGroups.emplace_back(std::move(channelGroupDto));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QColor>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace Status::StatusGo::Chats {
|
||||
|
||||
constexpr auto ChannelGroupTypeUnknown = "unknown";
|
||||
constexpr auto ChannelGroupTypePersonal = "personal";
|
||||
constexpr auto ChannelGroupTypeCommunity = "community";
|
||||
|
||||
enum ChatType
|
||||
{
|
||||
Unknown = 0,
|
||||
OneToOne = 1,
|
||||
Public = 2,
|
||||
PrivateGroupChat = 3,
|
||||
Profile = 4,
|
||||
CommunityChat = 6
|
||||
};
|
||||
|
||||
struct Category {
|
||||
QString id;
|
||||
QString name;
|
||||
int position;
|
||||
};
|
||||
|
||||
struct Permission {
|
||||
int access;
|
||||
bool ensOnly;
|
||||
};
|
||||
|
||||
struct Images {
|
||||
QString thumbnail;
|
||||
QString large;
|
||||
QString banner;
|
||||
};
|
||||
|
||||
struct ChatMember {
|
||||
QString id;
|
||||
bool admin;
|
||||
bool joined;
|
||||
std::vector<int> roles;
|
||||
};
|
||||
|
||||
struct ChatDto {
|
||||
QString id; // ID is the id of the chat, for public chats it is the name e.g. status,
|
||||
// for one-to-one is the hex encoded public key and for group chats is a random
|
||||
// uuid appended with the hex encoded pk of the creator of the chat
|
||||
QString name;
|
||||
QString description;
|
||||
QColor color;
|
||||
QString emoji;
|
||||
bool active; // indicates whether the chat has been soft deleted
|
||||
ChatType chatType;
|
||||
quint64 timestamp; // indicates the last time this chat has received/sent a message
|
||||
quint64 lastClockValue; // indicates the last clock value to be used when sending messages
|
||||
quint64 deletedAtClockValue; // indicates the clock value at time of deletion, messages with lower clock value of this should be discarded
|
||||
quint64 readMessagesAtClockValue;
|
||||
int unviewedMessagesCount;
|
||||
int unviewedMentionsCount;
|
||||
std::vector<ChatMember> members;
|
||||
QString alias;
|
||||
QString icon;
|
||||
bool muted;
|
||||
QString communityId; // set if chat belongs to a community
|
||||
QString profile;
|
||||
quint64 joined; // indicates when the user joined the chat last time
|
||||
quint64 syncedTo;
|
||||
quint64 syncedFrom;
|
||||
bool canPost;
|
||||
int position;
|
||||
QString categoryId;
|
||||
bool highlight;
|
||||
Permission permissions;
|
||||
};
|
||||
|
||||
struct ChannelGroupDto {
|
||||
QString id;
|
||||
QString channelGroupType;
|
||||
bool admin;
|
||||
bool verified;
|
||||
QString name;
|
||||
QString ensName;
|
||||
QString description;
|
||||
QString introMessage;
|
||||
QString outroMessage;
|
||||
std::vector<ChatDto> chats;
|
||||
std::vector<Category> categories;
|
||||
Images images;
|
||||
Permission permissions;
|
||||
std::vector<ChatMember> members;
|
||||
bool canManageUsers;
|
||||
QColor color;
|
||||
bool muted;
|
||||
bool historyArchiveSupportEnabled;
|
||||
bool pinMessageAllMembersEnabled;
|
||||
};
|
||||
|
||||
struct AllChannelGroupsDto {
|
||||
std::vector<ChannelGroupDto> allChannelGroups;
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(ChatType, {
|
||||
{Unknown, "Unknown"},
|
||||
{OneToOne, "OneToOne"},
|
||||
{Public, "Public"},
|
||||
{PrivateGroupChat, "PrivateGroupChat"},
|
||||
{Profile, "Profile"},
|
||||
{CommunityChat, "CommunityChat"},
|
||||
})
|
||||
|
||||
void to_json(json& j, const Category& d);
|
||||
void from_json(const json& j, Category& d);
|
||||
void to_json(json& j, const Permission& d);
|
||||
void from_json(const json& j, Permission& d);
|
||||
void to_json(json& j, const Images& d);
|
||||
void from_json(const json& j, Images& d);
|
||||
void to_json(json& j, const ChatMember& d);
|
||||
void from_json(const json& j, ChatMember& d);
|
||||
void to_json(json& j, const ChatDto& d);
|
||||
void from_json(const json& j, ChatDto& d);
|
||||
void to_json(json& j, const ChannelGroupDto& d);
|
||||
void from_json(const json& j, ChannelGroupDto& d);
|
||||
void to_json(json& j, const AllChannelGroupsDto& d);
|
||||
void from_json(const json& j, AllChannelGroupsDto& d);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "Chat/ChatAPI.h"
|
||||
#include "Chat/ChatDto.h"
|
|
@ -0,0 +1,27 @@
|
|||
#include "SettingsAPI.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "Metadata/api_response.h"
|
||||
|
||||
#include <libstatus.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
using namespace Status::StatusGo;
|
||||
|
||||
Settings::SettingsDto Settings::getSettings()
|
||||
{
|
||||
json inputJson = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", "settings_getSettings"},
|
||||
{"params", json::array()}
|
||||
};
|
||||
|
||||
auto result = Utils::statusGoCallPrivateRPC(inputJson.dump().c_str());
|
||||
const auto resultJson = json::parse(result);
|
||||
checkPrivateRpcCallResultAndReportError(resultJson);
|
||||
|
||||
return resultJson.get<CallPrivateRpcResponse>().result;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "SettingsDto.h"
|
||||
|
||||
namespace Status::StatusGo::Settings
|
||||
{
|
||||
/// \brief Retrieve settings
|
||||
SettingsDto getSettings();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "SettingsDto.h"
|
||||
|
||||
#include <Helpers/conversions.h>
|
||||
#include <Helpers/JsonMacros.h>
|
||||
|
||||
using namespace Status::StatusGo;
|
||||
|
||||
void Settings::to_json(json& j, const SettingsDto& d) {
|
||||
j = {{"address", d.address},
|
||||
{"display-name", d.displayName},
|
||||
{"preferred-name", d.preferredName},
|
||||
{"key-uid", d.keyUid},
|
||||
{"public-key", d.publicKey},
|
||||
};
|
||||
}
|
||||
|
||||
void Settings::from_json(const json& j, SettingsDto& d) {
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(address)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(displayName, "display-name")
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(preferredName, "preferred-name", false)
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(keyUid, "key-uid")
|
||||
STATUS_READ_NLOHMAN_JSON_PROPERTY(publicKey, "public-key")
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QColor>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace Status::StatusGo::Settings {
|
||||
|
||||
struct SettingsDto {
|
||||
QString address;
|
||||
QString displayName;
|
||||
QString preferredName;
|
||||
QString keyUid;
|
||||
QString publicKey;
|
||||
};
|
||||
|
||||
void to_json(json& j, const SettingsDto& d);
|
||||
void from_json(const json& j, SettingsDto& d);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "Settings/SettingsAPI.h"
|
||||
#include "Settings/SettingsDto.h"
|
|
@ -1,4 +1,6 @@
|
|||
import QtQuick.Layouts
|
||||
import QtQuick
|
||||
|
||||
GridLayout {
|
||||
Item {
|
||||
height: 16
|
||||
width: 1
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ Item {
|
|||
implicitWidth: 78
|
||||
implicitHeight: mainLayout.implicitHeight
|
||||
|
||||
readonly property Component currentSection: listView.currentItem.content
|
||||
property alias currentIndex: listView.currentIndex
|
||||
|
||||
required property var sections
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
project(Wallet
|
||||
project(Wallet # To rename this to WalletSection????
|
||||
VERSION 0.1.0
|
||||
LANGUAGES CXX)
|
||||
|
||||
|
|
Loading…
Reference in New Issue