forked from blue/squawk
experimenting with qml
This commit is contained in:
parent
38159eafeb
commit
4e6bd04b02
@ -12,6 +12,7 @@ include(GNUInstallDirs)
|
|||||||
include_directories(.)
|
include_directories(.)
|
||||||
|
|
||||||
find_package(Qt5Widgets CONFIG REQUIRED)
|
find_package(Qt5Widgets CONFIG REQUIRED)
|
||||||
|
find_package(Qt5QuickCompiler CONFIG REQUIRED)
|
||||||
find_package(Qt5LinguistTools)
|
find_package(Qt5LinguistTools)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
5
main.cpp
5
main.cpp
@ -77,6 +77,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
new Shared::Global(); //translates enums
|
new Shared::Global(); //translates enums
|
||||||
|
|
||||||
|
// QtQuickControls2 Style
|
||||||
|
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
|
||||||
|
qputenv("QT_QUICK_CONTROLS_STYLE", "Material");
|
||||||
|
}
|
||||||
|
|
||||||
Squawk w;
|
Squawk w;
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
|
79
resources/qml/feed.qml
Normal file
79
resources/qml/feed.qml
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: list
|
||||||
|
verticalLayoutDirection: ListView.BottomToTop
|
||||||
|
|
||||||
|
required model
|
||||||
|
|
||||||
|
delegate: RowLayout {
|
||||||
|
id: root
|
||||||
|
width: ListView.view.width
|
||||||
|
|
||||||
|
// placeholder
|
||||||
|
Item {
|
||||||
|
Layout.preferredWidth: root.layoutDirection === Qt.LeftToRight ? 5 : 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avatar {
|
||||||
|
// id: avatar
|
||||||
|
// visible: !sentByMe
|
||||||
|
// avatarUrl: root.avatarUrl
|
||||||
|
// Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||||
|
// name: root.senderName
|
||||||
|
// Layout.preferredHeight: Kirigami.Units.gridUnit * 2.2
|
||||||
|
// Layout.preferredWidth: Kirigami.Units.gridUnit * 2.2
|
||||||
|
// }
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.preferredWidth: content.width + 16
|
||||||
|
Layout.preferredHeight: content.height + 16
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: messageBubble
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
color: "blue"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
spacing: 5
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: model.sender
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: model.text
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.maximumWidth: root.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// message meta data: date, deliveryState
|
||||||
|
RowLayout {
|
||||||
|
Layout.bottomMargin: -4
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: dateLabel
|
||||||
|
text: model.date
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icon {
|
||||||
|
// source: "edit-symbolic"
|
||||||
|
// visible: model.correction
|
||||||
|
// Layout.preferredHeight: 10
|
||||||
|
// Layout.preferredWidth: 10
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -160,5 +160,7 @@
|
|||||||
<file>images/fallback/light/small/favorite.svg</file>
|
<file>images/fallback/light/small/favorite.svg</file>
|
||||||
<file>images/fallback/light/small/unfavorite.svg</file>
|
<file>images/fallback/light/small/unfavorite.svg</file>
|
||||||
<file>images/fallback/light/small/add.svg</file>
|
<file>images/fallback/light/small/add.svg</file>
|
||||||
|
|
||||||
|
<file>qml/feed.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -7,8 +7,7 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
# Find the QtWidgets library
|
# Find the QtWidgets library
|
||||||
find_package(Qt5Widgets CONFIG REQUIRED)
|
find_package(Qt5 CONFIG REQUIRED COMPONENTS Widgets DBus Core)
|
||||||
find_package(Qt5DBus CONFIG REQUIRED)
|
|
||||||
find_package(Boost 1.36.0 CONFIG REQUIRED)
|
find_package(Boost 1.36.0 CONFIG REQUIRED)
|
||||||
if(Boost_FOUND)
|
if(Boost_FOUND)
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
@ -20,6 +20,15 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
const QHash<int, QByteArray> MessageFeed::roles = {
|
||||||
|
{Text, "text"},
|
||||||
|
{Sender, "sender"},
|
||||||
|
{Date, "date"},
|
||||||
|
{DeliveryState, "deliveryState"},
|
||||||
|
{Correction, "correction"},
|
||||||
|
{SentByMe,"sentByMe"}
|
||||||
|
};
|
||||||
|
|
||||||
MessageFeed::MessageFeed(QObject* parent):
|
MessageFeed::MessageFeed(QObject* parent):
|
||||||
QAbstractListModel(parent),
|
QAbstractListModel(parent),
|
||||||
storage(),
|
storage(),
|
||||||
@ -69,25 +78,43 @@ void MessageFeed::removeMessage(const QString& id)
|
|||||||
QVariant MessageFeed::data(const QModelIndex& index, int role) const
|
QVariant MessageFeed::data(const QModelIndex& index, int role) const
|
||||||
{
|
{
|
||||||
int i = index.row();
|
int i = index.row();
|
||||||
if (syncState == syncing) {
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
QVariant answer;
|
QVariant answer;
|
||||||
switch (role) {
|
|
||||||
case Qt::DisplayRole: {
|
StorageByTime::const_iterator itr = indexByTime.nth(i);
|
||||||
if (i == -1) {
|
if (itr != indexByTime.end()) {
|
||||||
return "Loading...";
|
const Shared::Message* msg = *itr;
|
||||||
}
|
|
||||||
|
switch (role) {
|
||||||
StorageByTime::const_iterator itr = indexByTime.nth(i);
|
case Text:
|
||||||
if (itr != indexByTime.end()) {
|
answer = msg->getBody();
|
||||||
const Shared::Message* msg = *itr;
|
break;
|
||||||
answer = msg->getFrom() + ": " + msg->getBody();
|
case Sender:
|
||||||
}
|
answer = msg->getFrom();
|
||||||
|
break;
|
||||||
|
case Date:
|
||||||
|
answer = msg->getTime();
|
||||||
|
break;
|
||||||
|
case DeliveryState:
|
||||||
|
answer = static_cast<unsigned int>(msg->getState());
|
||||||
|
break;
|
||||||
|
case Correction:
|
||||||
|
answer = msg->getEdited();
|
||||||
|
break;
|
||||||
|
case SentByMe:
|
||||||
|
answer = msg->getOutgoing();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (role) {
|
||||||
|
case Text:
|
||||||
|
answer = "loading...";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
answer = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return answer;
|
return answer;
|
||||||
@ -115,27 +142,28 @@ bool MessageFeed::canFetchMore(const QModelIndex& parent) const
|
|||||||
void MessageFeed::fetchMore(const QModelIndex& parent)
|
void MessageFeed::fetchMore(const QModelIndex& parent)
|
||||||
{
|
{
|
||||||
if (syncState == incomplete) {
|
if (syncState == incomplete) {
|
||||||
beginInsertRows(QModelIndex(), 0, 0);
|
beginInsertRows(QModelIndex(), storage.size(), storage.size());
|
||||||
syncState = syncing;
|
syncState = syncing;
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
if (storage.size() == 0) {
|
if (storage.size() == 0) {
|
||||||
emit requestArchive("");
|
emit requestArchive("");
|
||||||
} else {
|
} else {
|
||||||
emit requestArchive((*indexByTime.nth(0))->getId());
|
emit requestArchive((*indexByTime.rbegin())->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageFeed::responseArchive(const std::list<Shared::Message> list)
|
void MessageFeed::responseArchive(const std::list<Shared::Message> list)
|
||||||
{
|
{
|
||||||
|
Storage::size_type size = storage.size();
|
||||||
if (syncState == syncing) {
|
if (syncState == syncing) {
|
||||||
beginRemoveRows(QModelIndex(), 0, 0);
|
beginRemoveRows(QModelIndex(), size, size);
|
||||||
syncState = incomplete;
|
syncState = incomplete;
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
beginInsertRows(QModelIndex(), 0, list.size() - 1);
|
beginInsertRows(QModelIndex(), size, size + list.size() - 1);
|
||||||
for (const Shared::Message& msg : list) {
|
for (const Shared::Message& msg : list) {
|
||||||
Shared::Message* copy = new Shared::Message(msg);
|
Shared::Message* copy = new Shared::Message(msg);
|
||||||
storage.insert(copy);
|
storage.insert(copy);
|
||||||
@ -143,3 +171,7 @@ void MessageFeed::responseArchive(const std::list<Shared::Message> list)
|
|||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> MessageFeed::roleNames() const
|
||||||
|
{
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
@ -47,6 +47,8 @@ public:
|
|||||||
|
|
||||||
bool canFetchMore(const QModelIndex & parent) const override;
|
bool canFetchMore(const QModelIndex & parent) const override;
|
||||||
void fetchMore(const QModelIndex & parent) override;
|
void fetchMore(const QModelIndex & parent) override;
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
void responseArchive(const std::list<Shared::Message> list);
|
void responseArchive(const std::list<Shared::Message> list);
|
||||||
|
|
||||||
unsigned int unreadMessagesCount() const;
|
unsigned int unreadMessagesCount() const;
|
||||||
@ -54,6 +56,15 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void requestArchive(const QString& before);
|
void requestArchive(const QString& before);
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum MessageRoles {
|
||||||
|
Text = Qt::UserRole + 1,
|
||||||
|
Sender,
|
||||||
|
Date,
|
||||||
|
DeliveryState,
|
||||||
|
Correction,
|
||||||
|
SentByMe
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
enum SyncState {
|
enum SyncState {
|
||||||
incomplete,
|
incomplete,
|
||||||
@ -81,7 +92,8 @@ private:
|
|||||||
Shared::Message,
|
Shared::Message,
|
||||||
QDateTime,
|
QDateTime,
|
||||||
&Shared::Message::getTime
|
&Shared::Message::getTime
|
||||||
>
|
>,
|
||||||
|
std::greater<QDateTime>
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
> Storage;
|
> Storage;
|
||||||
@ -94,6 +106,7 @@ private:
|
|||||||
|
|
||||||
SyncState syncState;
|
SyncState syncState;
|
||||||
|
|
||||||
|
static const QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
# Find the QtWidgets library
|
# Find the QtWidgets library
|
||||||
find_package(Qt5Widgets CONFIG REQUIRED)
|
find_package(Qt5Widgets CONFIG REQUIRED COMPONENTS Widgets Quick Qml QuickControls2 Core)
|
||||||
|
|
||||||
add_subdirectory(vcard)
|
add_subdirectory(vcard)
|
||||||
|
|
||||||
@ -21,9 +21,12 @@ set(squawkWidgets_SRC
|
|||||||
joinconference.cpp
|
joinconference.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tell CMake to create the helloworld executable
|
|
||||||
add_library(squawkWidgets ${squawkWidgets_SRC})
|
add_library(squawkWidgets ${squawkWidgets_SRC})
|
||||||
|
|
||||||
# Use the Widgets module from Qt 5.
|
# Use the Widgets module from Qt 5.
|
||||||
target_link_libraries(squawkWidgets vCardUI)
|
target_link_libraries(squawkWidgets vCardUI)
|
||||||
target_link_libraries(squawkWidgets Qt5::Widgets)
|
target_link_libraries(squawkWidgets Qt5::Widgets)
|
||||||
|
target_link_libraries(squawkWidgets Qt5::Qml)
|
||||||
|
target_link_libraries(squawkWidgets Qt5::QuickControls2)
|
||||||
|
|
||||||
|
qt5_use_modules(squawkWidgets Quick Qml QuickControls2 Core Widgets)
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
|
||||||
Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
|
Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
|
||||||
Conversation(false, acc, p_contact->getJid(), "", parent),
|
Conversation(false, acc, p_contact, p_contact->getJid(), "", parent),
|
||||||
contact(p_contact)
|
contact(p_contact)
|
||||||
{
|
{
|
||||||
setName(p_contact->getContactName());
|
setName(p_contact->getContactName());
|
||||||
@ -28,8 +28,6 @@ Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
|
|||||||
setAvatar(p_contact->getAvatarPath());
|
setAvatar(p_contact->getAvatarPath());
|
||||||
|
|
||||||
connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged);
|
connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged);
|
||||||
|
|
||||||
feed->setModel(p_contact->feed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Chat::~Chat()
|
Chat::~Chat()
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, const QString pRes, QWidget* parent):
|
Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, const QString pJid, const QString pRes, QWidget* parent):
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
isMuc(muc),
|
isMuc(muc),
|
||||||
account(acc),
|
account(acc),
|
||||||
@ -45,7 +45,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
filesLayout(0),
|
filesLayout(0),
|
||||||
overlay(new QWidget()),
|
overlay(new QWidget()),
|
||||||
filesToAttach(),
|
filesToAttach(),
|
||||||
feed(0),
|
feed(new QQuickView()),
|
||||||
scroll(down),
|
scroll(down),
|
||||||
manualSliderChange(false),
|
manualSliderChange(false),
|
||||||
requestingHistory(false),
|
requestingHistory(false),
|
||||||
@ -53,7 +53,14 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1)
|
tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
feed = m_ui->feed;
|
|
||||||
|
feed->setColor(QWidget::palette().color(QPalette::Base));
|
||||||
|
feed->setInitialProperties({{"model", QVariant::fromValue(el->feed)}});
|
||||||
|
feed->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
|
feed->setSource(QUrl("qrc:/qml/feed.qml"));
|
||||||
|
QWidget *container = QWidget::createWindowContainer(feed, this);
|
||||||
|
container->setAutoFillBackground(false);
|
||||||
|
m_ui->widget->layout()->addWidget(container);
|
||||||
|
|
||||||
connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged);
|
connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged);
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QListView>
|
#include <QQuickView>
|
||||||
|
|
||||||
#include "shared/message.h"
|
#include "shared/message.h"
|
||||||
#include "order.h"
|
#include "order.h"
|
||||||
@ -72,7 +72,7 @@ class Conversation : public QWidget
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Conversation(bool muc, Models::Account* acc, const QString pJid, const QString pRes, QWidget* parent = 0);
|
Conversation(bool muc, Models::Account* acc, Models::Element* el, const QString pJid, const QString pRes, QWidget* parent = 0);
|
||||||
~Conversation();
|
~Conversation();
|
||||||
|
|
||||||
QString getJid() const;
|
QString getJid() const;
|
||||||
@ -133,6 +133,7 @@ protected:
|
|||||||
down
|
down
|
||||||
};
|
};
|
||||||
Models::Account* account;
|
Models::Account* account;
|
||||||
|
Models::Element* element;
|
||||||
QString palJid;
|
QString palJid;
|
||||||
QString activePalResource;
|
QString activePalResource;
|
||||||
QScopedPointer<Ui::Conversation> m_ui;
|
QScopedPointer<Ui::Conversation> m_ui;
|
||||||
@ -145,7 +146,7 @@ protected:
|
|||||||
FlowLayout* filesLayout;
|
FlowLayout* filesLayout;
|
||||||
QWidget* overlay;
|
QWidget* overlay;
|
||||||
W::Order<Badge*, Badge::Comparator> filesToAttach;
|
W::Order<Badge*, Badge::Comparator> filesToAttach;
|
||||||
QListView* feed;
|
QQuickView* feed;
|
||||||
Scroll scroll;
|
Scroll scroll;
|
||||||
bool manualSliderChange;
|
bool manualSliderChange;
|
||||||
bool requestingHistory;
|
bool requestingHistory;
|
||||||
|
@ -214,37 +214,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QListView" name="feed">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
<property name="showDropIndicator" stdset="0">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="selectionMode">
|
|
||||||
<enum>QAbstractItemView::NoSelection</enum>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollMode">
|
|
||||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollMode">
|
|
||||||
<enum>QAbstractItemView::ScrollPerItem</enum>
|
|
||||||
</property>
|
|
||||||
<property name="isWrapping" stdset="0">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "room.h"
|
#include "room.h"
|
||||||
|
|
||||||
Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
|
Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
|
||||||
Conversation(true, acc, p_room->getJid(), "", parent),
|
Conversation(true, acc, p_room, p_room->getJid(), "", parent),
|
||||||
room(p_room)
|
room(p_room)
|
||||||
{
|
{
|
||||||
setName(p_room->getName());
|
setName(p_room->getName());
|
||||||
@ -29,8 +29,6 @@ Room::Room(Models::Account* acc, Models::Room* p_room, QWidget* parent):
|
|||||||
connect(room, &Models::Room::childChanged, this, &Room::onRoomChanged);
|
connect(room, &Models::Room::childChanged, this, &Room::onRoomChanged);
|
||||||
connect(room, &Models::Room::participantJoined, this, &Room::onParticipantJoined);
|
connect(room, &Models::Room::participantJoined, this, &Room::onParticipantJoined);
|
||||||
connect(room, &Models::Room::participantLeft, this, &Room::onParticipantLeft);
|
connect(room, &Models::Room::participantLeft, this, &Room::onParticipantLeft);
|
||||||
|
|
||||||
feed->setModel(p_room->feed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Room::~Room()
|
Room::~Room()
|
||||||
|
Loading…
Reference in New Issue
Block a user