Merge pull request #3141 from SaurabhCodesAI/wire-notifyv2

Wire Complete implementation of Issue #2923 todos
This commit is contained in:
csoler 2026-02-23 22:03:25 +01:00 committed by GitHub
commit c686375050
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 3165 additions and 242 deletions

View File

@ -999,7 +999,10 @@ if(RS_GXSTHEWIRE)
src/gui/TheWire/PulseViewGroup.h
src/gui/TheWire/PulseReply.h
src/gui/TheWire/PulseReplySeperator.h
src/gui/TheWire/PulseMessage.h
src/gui/TheWire/PulseMessage.h
src/gui/TheWire/WireUserNotify.h
src/gui/feeds/WireNotifyGroupItem.h
src/gui/feeds/WireNotifyPostItem.h
)
list(
@ -1012,7 +1015,9 @@ if(RS_GXSTHEWIRE)
src/gui/TheWire/PulseViewGroup.ui
src/gui/TheWire/PulseReply.ui
src/gui/TheWire/PulseReplySeperator.ui
src/gui/TheWire/PulseMessage.ui
src/gui/TheWire/PulseMessage.ui
src/gui/feeds/WireNotifyGroupItem.ui
src/gui/feeds/WireNotifyPostItem.ui
)
list(
@ -1028,6 +1033,9 @@ if(RS_GXSTHEWIRE)
src/gui/TheWire/PulseReply.cpp
src/gui/TheWire/PulseReplySeperator.cpp
src/gui/TheWire/PulseMessage.cpp
src/gui/TheWire/WireUserNotify.cpp
src/gui/feeds/WireNotifyGroupItem.cpp
src/gui/feeds/WireNotifyPostItem.cpp
)
list(
@ -1112,6 +1120,7 @@ if(RS_GXSGUI)
src/gui/gxs/GxsFeedWidget.h
src/util/TokenQueue.h
src/util/RsGxsUpdateBroadcast.h
src/gui/gxs/GxsStatisticsProvider.h
)
list(
@ -1147,6 +1156,7 @@ if(RS_GXSGUI)
src/gui/gxs/GxsFeedWidget.cpp
src/util/TokenQueue.cpp
src/util/RsGxsUpdateBroadcast.cpp
src/gui/gxs/GxsStatisticsProvider.cpp
)
endif(RS_GXSGUI)

View File

@ -463,7 +463,6 @@ void MainWindow::initStackedPage()
#endif
#ifdef RS_USE_WIRE
WireDialog *wireDialog = NULL;
addPage(wireDialog = new WireDialog(ui->stackPages), grp, &notify);
#endif
@ -1081,6 +1080,11 @@ void SetForegroundWindowInternal(HWND hWnd)
case Posted:
_instance->ui->stackPages->setCurrentPage( _instance->postedDialog );
return true ;
#ifdef RS_USE_WIRE
case Wire:
_instance->ui->stackPages->setCurrentPage( _instance->wireDialog );
return true ;
#endif
default:
std::cerr << "Show page called on value that is not handled yet. Please code it! (value = " << page << ")" << std::endl;
}
@ -1118,6 +1122,11 @@ void SetForegroundWindowInternal(HWND hWnd)
if (page == _instance->messagesDialog) {
return Messages;
}
#ifdef RS_USE_WIRE
if (page == _instance->wireDialog) {
return Wire;
}
#endif
#if 0
if (page == _instance->channelFeed) {
return Channels;
@ -1157,6 +1166,7 @@ void SetForegroundWindowInternal(HWND hWnd)
return _instance->transfersDialog->searchDialog;
case Messages:
return _instance->messagesDialog;
case Channels:
return _instance->gxschannelDialog;
case Forums:
@ -1165,6 +1175,10 @@ void SetForegroundWindowInternal(HWND hWnd)
return _instance->postedDialog;
case Home:
return _instance->homePage;
#ifdef RS_USE_WIRE
case Wire:
return _instance->wireDialog;
#endif
}
return NULL;

View File

@ -71,7 +71,9 @@ class BandwidthGraph;
class MainPage;
class NewsFeed;
class UserNotify;
#ifdef RS_USE_WIRE
class WireDialog;
#endif
#ifdef MESSENGER_WINDOW
class MessengerWindow;
#endif
@ -107,7 +109,10 @@ public:
Posted = 11, /** Posted links */
People = 12, /** People page. */
Options = 13, /** People page. */
Home = 14 /** Home page. */
Home = 14, /** Home page. */
#ifdef RS_USE_WIRE
Wire = 15 /** Wire page. */
#endif
};
@ -167,7 +172,9 @@ public:
GxsChannelDialog *gxschannelDialog ;
GxsForumsDialog *gxsforumDialog ;
PostedDialog *postedDialog;
#ifdef RS_USE_WIRE
WireDialog *wireDialog;
#endif
// ForumsDialog *forumsDialog;
// ChannelFeed *channelFeed;
Idle *idle;

View File

@ -31,6 +31,7 @@
#include <retroshare/rspeers.h>
#include <retroshare/rsplugin.h>
#include <retroshare/rsposted.h>
#include <retroshare/rswire.h>
#include "util/misc.h"
#include "util/qtthreadsutils.h"
@ -49,6 +50,8 @@
#include "feeds/PostedGroupItem.h"
#include "feeds/SecurityItem.h"
#include "feeds/SecurityIpItem.h"
#include "feeds/WireNotifyGroupItem.h"
#include "feeds/WireNotifyPostItem.h"
#include "settings/rsettingswin.h"
#include "settings/rsharesettings.h"
@ -83,7 +86,8 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed),
RsEventType::GXS_CHANNELS ,
RsEventType::GXS_FORUMS ,
RsEventType::GXS_POSTED ,
RsEventType::MAIL_STATUS
RsEventType::MAIL_STATUS ,
RsEventType::WIRE
})
{
/* Invoke the Qt Designer generated object setup routine */
@ -129,6 +133,9 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed),
" <li>Channel and Board comments</li>"
" <li>New Mail messages</li>"
" <li>Private messages from your friends</li>"
#ifdef RS_USE_WIRE
" <li>New Wire pulses and mentions</li>"
#endif
" </ul> </p>"
).arg(QString::number(2*H));
@ -216,6 +223,10 @@ void NewsFeed::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
if(event->mType == RsEventType::MAIL_STATUS && (!!(flags & RsFeedTypeFlags::RS_FEED_TYPE_MSG)))
handleMailEvent(event);
if(event->mType == RsEventType::WIRE && (!!(flags & RsFeedTypeFlags::RS_FEED_TYPE_WIRE)))
handleWireEvent(event);
}
void NewsFeed::handleMailEvent(std::shared_ptr<const RsEvent> event)
@ -503,6 +514,35 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr<const RsEvent> event)
MessageComposer::addConnectAttemptMsg(e.mPgpId, e.mSslId, QString::fromStdString(det.name + "(" + det.location + ")"));
}
void NewsFeed::handleWireEvent(std::shared_ptr<const RsEvent> event)
{
const RsWireEvent *pe =
dynamic_cast<const RsWireEvent*>(event.get());
if(!pe) return;
switch(pe->mWireEventCode)
{
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true, RsWireEventCode::FOLLOW_STATUS_CHANGED));
break;
case RsWireEventCode::NEW_WIRE:
addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true, RsWireEventCode::NEW_WIRE));
break;
case RsWireEventCode::NEW_POST:
addFeedItem( new WireNotifyPostItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, pe->mWireMsgId, true));
break;
case RsWireEventCode::WIRE_UPDATED:
addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true, RsWireEventCode::WIRE_UPDATED));
break;
// case RsWireEventCode::POST_UPDATED:
// addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true));
// break;
default: break;
}
sendNewsFeedChanged();
}
void NewsFeed::testFeeds(RsFeedTypeFlags /*notifyFlags*/)
{
RsFeedTypeFlags flags = RsFeedTypeFlags(Settings->getNewsFeedFlags());

View File

@ -49,6 +49,7 @@ const uint32_t NEWSFEED_POSTEDNEWLIST = 0x000b;
const uint32_t NEWSFEED_POSTEDMSGLIST = 0x000c;
const uint32_t NEWSFEED_CIRCLELIST = 0x000d;
const uint32_t NEWSFEED_CHANNELPUBKEYLIST= 0x000e;
const uint32_t NEWSFEED_WIRELIST = 0x0010;
namespace Ui {
class NewsFeed;
@ -107,6 +108,7 @@ private:
void handleMailEvent(std::shared_ptr<const RsEvent> event);
void handlePostedEvent(std::shared_ptr<const RsEvent> event);
void handleChannelEvent(std::shared_ptr<const RsEvent> event);
void handleWireEvent(std::shared_ptr<const RsEvent> event);
void addFeedItem(FeedItem *item);
void addFeedItemIfUnique(FeedItem *item, bool replace);

View File

@ -54,7 +54,7 @@ private:
/* GxsGroupFrameDialog */
virtual QString text(TextType type) override;
virtual QString icon(IconType type) override;
virtual QString settingsGroupName() override{ return "PostedDialog"; }
virtual QString settingsGroupName() { return "PostedDialog"; }
virtual GxsGroupDialog *createNewGroupDialog() override;
virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override;
virtual int shareKeyType() override;

View File

@ -23,7 +23,7 @@
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}

View File

@ -28,7 +28,7 @@ class PostedUserNotify : public GxsUserNotify
Q_OBJECT
public:
explicit PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
explicit PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;

View File

@ -33,6 +33,7 @@
#include "FileTransfer/SearchDialog.h"
#include "gxschannels/GxsChannelDialog.h"
#include "gxsforums/GxsForumsDialog.h"
#include "TheWire/WireDialog.h"
#include "msgs/MessageComposer.h"
#include "Posted/PostedDialog.h"
#include "util/misc.h"
@ -74,7 +75,8 @@
#define HOST_IDENTITY "identity"
#define HOST_FILE_TREE "collection"
#define HOST_CHAT_ROOM "chat_room"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate|extra|private_chat|public_msg|posted|identity|collection|chat_room"
#define HOST_REGEXP "file|person|forum|channel|wire|search|message|certificate|extra|private_chat|public_msg|posted|identity|collection|chat_room"
#define HOST_WIRE "wire"
#define FILE_NAME "name"
#define FILE_SIZE "size"
@ -92,6 +94,10 @@
#define CHANNEL_ID "id"
#define CHANNEL_MSGID "msgid"
#define WIRE_NAME "name"
#define WIRE_ID "id"
#define WIRE_MSGID "msgid"
#define SEARCH_KEYWORDS "keywords"
#define MESSAGE_ID "id"
@ -289,6 +295,19 @@ void RetroShareLink::fromUrl(const QUrl& url)
return;
}
if (url.host() == HOST_WIRE) {
_type = TYPE_WIRE;
_name = decodedQueryItemValue(urlQuery, WIRE_NAME);
_hash = urlQuery.queryItemValue(WIRE_ID);
_msgId = urlQuery.queryItemValue(WIRE_MSGID);
#ifdef DEBUG_RSLINK
std::cerr << "Got a wire link!!" << std::endl;
#endif
check();
return;
}
if (url.host() == HOST_SEARCH) {
_type = TYPE_SEARCH;
_name = decodedQueryItemValue(urlQuery, SEARCH_KEYWORDS);
@ -468,7 +487,7 @@ RetroShareLink RetroShareLink::createPerson(const RsPgpId& id)
return link;
}
//For Forum, Channel & Posted
//For Forum, Channel, Posted and Wire
RetroShareLink RetroShareLink::createGxsGroupLink(const RetroShareLink::enumType &linkType, const RsGxsGroupId &groupId, const QString &groupName)
{
RetroShareLink link;
@ -793,6 +812,17 @@ void RetroShareLink::check()
_valid = false;
break;
case TYPE_WIRE:
if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_SEARCH:
if(_size != 0)
_valid = false;
@ -886,6 +916,8 @@ QString RetroShareLink::title() const
return QString("Forum id: %1").arg(hash());
case TYPE_CHANNEL:
return QString("Channel id: %1").arg(hash());
case TYPE_WIRE:
return QString("Wire id: %1").arg(hash());
case TYPE_SEARCH:
return QString("Search files");
@ -1073,6 +1105,17 @@ QString RetroShareLink::toString() const
break;
case TYPE_WIRE:
url.setScheme(RSLINK_SCHEME);
url.setHost(HOST_WIRE);
urlQuery.addQueryItem(WIRE_NAME, encodeItem(_name));
urlQuery.addQueryItem(WIRE_ID, _hash);
if (!_msgId.isEmpty()) {
urlQuery.addQueryItem(WIRE_MSGID, _msgId);
}
break;
}
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
@ -1307,6 +1350,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
case TYPE_FILE:
case TYPE_FORUM:
case TYPE_CHANNEL:
case TYPE_WIRE:
case TYPE_SEARCH:
case TYPE_MESSAGE:
case TYPE_CERTIFICATE:
@ -1355,6 +1399,12 @@ static void processList(const QStringList &list, const QString &textSingular, co
QStringList channelUnknown;
QStringList channelMsgUnknown;
// wire
QStringList wireFound;
QStringList wireMsgFound;
QStringList wireUnknown;
QStringList wireMsgUnknown;
// search
QStringList searchStarted;
@ -1381,9 +1431,9 @@ static void processList(const QStringList &list, const QString &textSingular, co
QList<QStringList*> processedList;
QList<QStringList*> errorList;
processedList << &fileAdded << &personAdded << &forumFound << &channelFound << &searchStarted << &messageStarted << &postedFound << &chatroomFound;
errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown << &postedUnknown << &postedMsgUnknown << &chatroomUnknown;
// not needed: forumFound, channelFound, messageStarted
processedList << &fileAdded << &personAdded << &forumFound << &channelFound << &wireFound << &searchStarted << &messageStarted << &postedFound << &chatroomFound;
errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &wireUnknown << &wireMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown << &postedUnknown << &postedMsgUnknown << &chatroomUnknown;
// not needed: forumFound, channelFound, wireFound, messageStarted
// we want to merge all single file links into one collection
// if a collection tree link is found it is processed independen for the other file links
@ -1475,6 +1525,34 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
break;
case TYPE_WIRE:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process WireRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl;
#endif
MainWindow::showWindow(MainWindow::Wire);
WireDialog *wireDialog = dynamic_cast<WireDialog*>(MainWindow::getPage(MainWindow::Wire));
if (!wireDialog) {
return false;
}
if (wireDialog->navigate(RsGxsGroupId(link.id().toStdString()), RsGxsMessageId(link.msgId().toStdString()))) {
if (link.msgId().isEmpty()) {
wireFound.append(link.name());
} else {
wireMsgFound.append(link.name());
}
} else {
if (link.msgId().isEmpty()) {
wireUnknown.append(link.name());
} else {
wireMsgUnknown.append(link.name());
}
}
}
break;
case TYPE_SEARCH:
{
#ifdef DEBUG_RSLINK
@ -1764,7 +1842,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
else
{
ChatDialog* chatDialog = ChatDialog::getChat(chatId, (RsChatFlags)Settings->getChatFlags());
ChatDialog* chatDialog = ChatDialog::getChat(chatId, (RsChatFlags)Settings->getChatFlags());
if (chatDialog) {
chatroomFound.append(link.name());
} else {
@ -1861,6 +1939,16 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
}
// wire
if (flag & RSLINK_PROCESS_NOTIFY_ERROR) {
if (!wireUnknown.isEmpty()) {
processList(wireUnknown, QObject::tr("Wire not found"), QObject::tr("Wires not found"), result);
}
if (!wireMsgUnknown.isEmpty()) {
processList(wireMsgUnknown, QObject::tr("Wire message not found"), QObject::tr("Wire messages not found"), result);
}
}
// message
if (flag & RSLINK_PROCESS_NOTIFY_ERROR) {
if (!messageReceipientNotAccepted.isEmpty()) {
@ -2044,3 +2132,4 @@ void RSLinkClipboard::parseText(QString text, QList<RetroShareLink> &links,Retro
pos += rx.matchedLength();
}
}

View File

@ -75,7 +75,8 @@ class RetroShareLink
TYPE_POSTED = 0x0b,
TYPE_IDENTITY = 0x0c,
TYPE_FILE_TREE = 0x0d,
TYPE_CHAT_ROOM = 0x0e
TYPE_CHAT_ROOM = 0x0e,
TYPE_WIRE = 0x0f
};
public:

View File

@ -54,7 +54,7 @@ PulseAddDialog::PulseAddDialog(QWidget *parent)
ui.pushButton_remove->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/mail/delete.png")));
ui.frame_picture->hide();
ui.pushButton_picture->hide();
//ui.pushButton_picture->hide();
// initially hiding the browse button as the attach image button is not pressed
//ui.frame_PictureBrowse->hide();
@ -135,29 +135,35 @@ void PulseAddDialog::cleanup()
std::cerr << "PulseAddDialog::cleanup() cleaning up old replyto";
std::cerr << std::endl;
QLayout *layout = ui.widget_replyto->layout();
// completely delete layout and sublayouts
QLayoutItem * item;
while ((item = layout->takeAt(0)))
if (layout)
{
if (QWidget *widget = item->widget())
// completely delete layout and sublayouts
QLayoutItem * item;
while ((item = layout->takeAt(0)))
{
std::cerr << "PulseAddDialog::cleanup() removing widget";
std::cerr << std::endl;
widget->hide();
delete widget;
}
else
{
std::cerr << "PulseAddDialog::cleanup() removing item";
std::cerr << std::endl;
delete item;
if (QWidget *widget = item->widget())
{
std::cerr << "PulseAddDialog::cleanup() removing widget";
std::cerr << std::endl;
widget->hide();
delete widget;
}
else
{
std::cerr << "PulseAddDialog::cleanup() removing item";
std::cerr << std::endl;
delete item;
}
}
// then finally
delete layout;
}
// then finally
delete layout;
mIsReply = false;
}
mReplyToPulse = RsWirePulse();
mReplyType = 0;
ui.frame_reply->setVisible(false);
ui.comboBox_sentiment->setCurrentIndex(0);
ui.lineEdit_URL->setText("");
@ -260,6 +266,13 @@ void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId
if(grpId.isNull()){
return;
}
mIsReply = true;
mReplyType = replyType;
ui.postButton->setEnabled(false);
ui.postButton->setText(tr("Loading..."));
show();
/* fetch in the background */
RsThread::async([this,grpId,msgId,replyType](){
@ -269,12 +282,14 @@ void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId
if(!rsWire->getWireGroup(grpId,pGroup))
{
std::cerr << __PRETTY_FUNCTION__ << "PulseAddDialog::setRplyTo() failed to fetch group id: " << grpId << std::endl;
RsQThreadUtils::postToObject([this]() { hide(); }, this);
return;
}
if (!rsWire->getWirePulse(grpId, msgId, pPulse))
{
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch pulse of group id: " << grpId << std::endl;
RsQThreadUtils::postToObject([this]() { hide(); }, this);
return;
}
@ -292,6 +307,7 @@ void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId
* Qt::QueuedConnection is important!
*/
mGroup = *pGroup;
setReplyTo(*pPulse, pPulse, pGroup->mMeta.mGroupName, replyType);
}, this );
@ -408,6 +424,21 @@ void PulseAddDialog::postReplyPulse()
std::cerr << "PulseAddDialog::postReplyPulse()";
std::cerr << std::endl;
if (mReplyToPulse.mMeta.mGroupId.isNull()) {
std::cerr << "PulseAddDialog::postReplyPulse() reply data not ready yet";
std::cerr << std::endl;
return;
}
if (mGroup.mMeta.mGroupId.isNull()) {
std::cerr << "PulseAddDialog::postReplyPulse() group not set";
std::cerr << std::endl;
return;
}
ui.postButton->setEnabled(false);
setCursor(Qt::WaitCursor);
RsWirePulseSPtr pPulse(new RsWirePulse());
pPulse->mSentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
@ -440,6 +471,11 @@ void PulseAddDialog::postReplyPulse()
{
std::cerr << "PulseAddDialog::postReplyPulse() FAILED";
std::cerr << std::endl;
RsQThreadUtils::postToObject([this]()
{
setCursor(Qt::ArrowCursor);
ui.postButton->setEnabled(true);
}, this);
return;
}
@ -451,6 +487,7 @@ void PulseAddDialog::postReplyPulse()
* Qt::QueuedConnection is important!
*/
setCursor(Qt::ArrowCursor);
clearDialog();
hide();
}, this );

View File

@ -44,6 +44,7 @@ public:
void setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, uint32_t replyType);
void setGroup(const RsGxsGroupId &grpId);
void setGroup(RsWireGroup &group);
private slots:
void addURL();
@ -57,8 +58,6 @@ private slots:
void removePictures();
private:
// OLD VERSIONs, private now.
void setGroup(RsWireGroup &group);
void setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType);
void postOriginalPulse();

View File

@ -57,6 +57,8 @@ void PulseReply::setup()
connect(toolButton_republish, SIGNAL(clicked()), this, SLOT(actionRepublish()));
connect(toolButton_like, SIGNAL(clicked()), this, SLOT(actionLike()));
connect(toolButton_view, SIGNAL(clicked()), this, SLOT(actionViewPulse()));
// hided it takes to much space
label_authorName->hide();
}
void PulseReply::showReplyLine(bool enable)
@ -150,6 +152,26 @@ void PulseReply::setReferenceString(QString ref)
void PulseReply::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && IS_MSG_UNPROCESSED(mPulse->mMeta.mMsgStatus))
{
uint32_t token;
RsGxsGrpMsgIdPair msgPair = std::make_pair(mPulse->mMeta.mGroupId, mPulse->mMeta.mMsgId);
rsWire->setMessageReadStatus(token, msgPair, true);
}
QWidget::mousePressEvent(event);
}
//void WireDialog::setAllMessagesReadDo(bool read, uint32_t &token)
//{
// if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
// return;
// }
// foreach (RsWirePulseItem *item, mPostItems) {
// RsGxsGrpMsgIdPair msgPair = std::make_pair(item->groupId(), item->messageId());
// rsWire->setMessageReadStatus(token, msgPair, read);
// }
//}

View File

@ -511,7 +511,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -532,21 +532,11 @@
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#2e3436;&quot;&gt;· Apr 13 ·&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>64</width>
<height>18</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>

View File

@ -56,6 +56,7 @@ void PulseTopLevel::setup()
connect(toolButton_republish, SIGNAL(clicked()), this, SLOT(actionRepublish()));
connect(toolButton_like, SIGNAL(clicked()), this, SLOT(actionLike()));
connect(toolButton_view, SIGNAL(clicked()), this, SLOT(actionViewPulse()));
connect(toolButton_copyLink, SIGNAL(clicked()), this, SLOT(actionCopyLink()));
}
void PulseTopLevel::setRefMessage(QString /*msg*/, uint32_t /*image_count*/)

View File

@ -731,6 +731,53 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="copyLink_HL">
<item>
<spacer name="copyLink_LHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton_copyLink">
<property name="text">
<string>COPY LINK</string>
</property>
<property name="icon">
<iconset resource="TheWire_images.qrc">
<normaloff>:/images/link.svg</normaloff>:/images/link.svg</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="copyLink_RHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@ -28,6 +28,7 @@
#include "WireGroupDialog.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/RetroShareLink.h"
#include "gui/common/FilesDefs.h"
#include "util/DateTime.h"
@ -50,6 +51,7 @@ void PulseViewGroup::setup()
{
if (mGroup) {
connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow()));
connect(toolButton_copyProfileLink, SIGNAL(clicked()), this, SLOT(actionCopyProfileLink()));
label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName));
label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString())));
@ -116,8 +118,14 @@ void PulseViewGroup::setup()
label_extra_republishes->setText(BoldString(ToNumberUnits(republishes)));
label_extra_likes->setText(BoldString(ToNumberUnits(likes)));
// hide follow.
widget_actions->setVisible(false);
uint32_t following = mGroup->mGroupFollowing;
label_extra_following->setText(BoldString(ToNumberUnits(following)));
uint32_t followers = mGroup->mGroupFollowers;
label_extra_followers->setText(BoldString(ToNumberUnits(followers)));
// hide follow button but keep copy link visible.
followButton->setVisible(false);
}
else
{
@ -133,14 +141,17 @@ void PulseViewGroup::setGroupSet()
{
if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) {
editButton->show();
toolButton_copyProfileLink->show();
}
else if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
editButton->hide();
toolButton_copyProfileLink->show();
}
else
{
editButton->hide();
toolButton_copyProfileLink->show();
}
}
@ -156,6 +167,29 @@ void PulseViewGroup::actionFollow()
}
}
void PulseViewGroup::actionCopyProfileLink()
{
std::cerr << "PulseViewGroup::actionCopyProfileLink()";
std::cerr << std::endl;
if (!mGroup) {
std::cerr << "PulseViewGroup::actionCopyProfileLink() GROUP invalid";
std::cerr << std::endl;
return;
}
RetroShareLink link = RetroShareLink::createGxsGroupLink(
RetroShareLink::TYPE_WIRE,
mGroup->mMeta.mGroupId,
QString::fromStdString(mGroup->mMeta.mGroupName));
if (link.valid()) {
QList<RetroShareLink> urls;
urls.push_back(link);
RSLinkClipboard::copyLinks(urls);
}
}
void PulseViewGroup::editProfile()
{
RsGxsGroupId groupId = mGroup->mMeta.mGroupId;

View File

@ -35,6 +35,7 @@ public:
private slots:
void actionFollow();
void actionCopyProfileLink();
void editProfile();
protected:

View File

@ -25,6 +25,18 @@
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="PulseViewGroup_VL">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="plainFrame">
<property name="sizePolicy">
@ -210,6 +222,27 @@
</property>
</widget>
</item>
<item row="0" column="3" rowspan="3">
<widget class="QToolButton" name="toolButton_copyProfileLink">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>COPY LINK</string>
</property>
<property name="icon">
<iconset resource="TheWire_images.qrc">
<normaloff>:/images/link.svg</normaloff>:/images/link.svg</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -481,6 +514,74 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="extra_following_HL">
<item>
<widget class="QLabel" name="label_extra_following">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;0&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="extra_following_Label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#2e3436;&quot;&gt;Following&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="extra_following_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="extra_followers_HL">
<item>
<widget class="QLabel" name="label_extra_followers">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;0&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="extra_followers_Label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#2e3436;&quot;&gt;Followers&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="extra_followers_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="widget_replies_HSpacer">
<property name="orientation">

View File

@ -25,8 +25,11 @@
#include "PulseViewItem.h"
#include "retroshare/rsgxsflags.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
#include "gui/RetroShareLink.h"
#include "util/DateTime.h"
/** Constructor */
@ -238,6 +241,35 @@ void PulseDataItem::actionRate()
}
}
void PulseDataItem::actionCopyLink()
{
std::cerr << "PulseDataItem::actionCopyLink()";
std::cerr << std::endl;
if (!mPulse) {
std::cerr << "PulseDataItem::actionCopyLink() PULSE invalid";
std::cerr << std::endl;
return;
}
std::string linkName = mPulse->mMeta.mMsgName;
if (linkName.empty()) {
linkName = mPulse->mPulseText.substr(0, 50);
}
RetroShareLink link = RetroShareLink::createGxsMessageLink(
RetroShareLink::TYPE_WIRE,
mPulse->mMeta.mGroupId,
mPulse->mMeta.mMsgId,
QString::fromStdString(linkName));
if (link.valid()) {
QList<RetroShareLink> urls;
urls.push_back(link);
RSLinkClipboard::copyLinks(urls);
}
}
void PulseDataItem::showPulse()
@ -463,3 +495,13 @@ QString ToNumberUnits(uint32_t count)
return ans;
}
void PulseDataItem::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && IS_MSG_UNPROCESSED(mPulse->mMeta.mMsgStatus))
{
uint32_t token;
RsGxsGrpMsgIdPair msgPair = std::make_pair(mPulse->mMeta.mGroupId, mPulse->mMeta.mMsgId);
rsWire->setMessageReadStatus(token, msgPair, true);
}
QWidget::mousePressEvent(event);
}

View File

@ -114,6 +114,7 @@ private slots:
void actionFollow();
void actionFollowParent();
void actionRate();
void actionCopyLink();
// Action interfaces --------------------------
protected:
@ -137,8 +138,11 @@ protected:
//
void setReference(uint32_t flags, RsGxsGroupId groupId, std::string groupName);
void mousePressEvent(QMouseEvent *event);
// DATA.
RsWirePulseSPtr mPulse;
};

View File

@ -25,20 +25,27 @@
#include "gui/settings/rsharesettings.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
#include "gui/gxs/GxsStatisticsProvider.h"
#include "gui/gxs/GxsGroupShareKey.h"
#include "PulseViewGroup.h"
#include "PulseReplySeperator.h"
#include "WireUserNotify.h"
#include "util/qtthreadsutils.h"
#include "util/misc.h"
#include <retroshare/rspeers.h>
#include <retroshare/rswire.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <QTimer>
#include <QMessageBox>
#include <QMenu>
#include <QActionGroup>
/****************************************************************
* TheWire Display Widget.
@ -54,19 +61,24 @@
// #define GROUP_SET_RECOMMENDED (5)
#define WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE 1
/** Constructor */
WireDialog::WireDialog(QWidget *parent)
: MainPage(parent), mGroupSet(GROUP_SET_ALL)
, mAddDialog(nullptr), mGroupSelected(nullptr), mWireQueue(nullptr)
, mHistoryIndex(-1), mEventHandlerId(0)
, mAddDialog(nullptr), mGroupSelected(nullptr)
, mHistoryIndex(-1), mEventHandlerId(0), mSortAscending(false)
, mAccountSortType(0), mHideInactiveAccounts(false)
{
ui.setupUi(this);
mInterface = rsWire;
mSettingsName = "WireDialog";
mDistSyncAllowed = true;
mStateHelper = nullptr;
connect( ui.toolButton_createAccount, SIGNAL(clicked()), this, SLOT(createGroup()));
connect( ui.toolButton_createPulse, SIGNAL(clicked()), this, SLOT(createPulse()));
connect( ui.toolButton_home, SIGNAL(clicked()), this, SLOT(showHomeFeed()));
connect( ui.lineEdit_searchUsers, SIGNAL(textChanged(const QString&)), this, SLOT(filterUsers(const QString&)));
connect(ui.comboBox_groupSet, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGroupSet(int)));
connect(ui.comboBox_filterTime, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFilterTime(int)));
@ -76,12 +88,48 @@ WireDialog::WireDialog(QWidget *parent)
ui.toolButton_back->setEnabled(false);
ui.toolButton_forward->setEnabled(false);
// Setup filter menu
QMenu *filterMenu = new QMenu(this);
QAction *sortAscAction = filterMenu->addAction(tr("Sort by Ascending"));
sortAscAction->setCheckable(true);
sortAscAction->setChecked(mSortAscending);
connect(sortAscAction, SIGNAL(triggered()), this, SLOT(toggleSortAscending()));
ui.toolButton_filter->setMenu(filterMenu);
// Setup account filter menu
QMenu *accountMenu = new QMenu(this);
QActionGroup *sortGroup = new QActionGroup(this);
QAction *sortByName = accountMenu->addAction(tr("Sort by Name"));
sortByName->setCheckable(true);
sortByName->setChecked(true);
sortByName->setData(0);
sortGroup->addAction(sortByName);
QAction *sortByActivity = accountMenu->addAction(tr("Sort by Activity"));
sortByActivity->setCheckable(true);
sortByActivity->setData(1);
sortGroup->addAction(sortByActivity);
accountMenu->addSeparator();
QAction *hideInactiveAction = accountMenu->addAction(tr("Hide inactive (>30d)"));
hideInactiveAction->setCheckable(true);
hideInactiveAction->setChecked(false);
connect(sortGroup, SIGNAL(triggered(QAction*)), this, SLOT(sortAccountsChanged(QAction*)));
connect(hideInactiveAction, SIGNAL(toggled(bool)), this, SLOT(hideInactiveChanged(bool)));
ui.toolButton_accountFilter->setMenu(accountMenu);
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
timer->start(1000);
/* setup TokenQueue */
mWireQueue = new TokenQueue(rsWire->getTokenService(), this);
mCountChildMsgs = false;
mShouldUpdateGroupStatistics = false;
mDistSyncAllowed = true;
requestGroupData();
@ -110,27 +158,33 @@ void WireDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
#endif
// The following switch statements refresh the wire feed whenever there is a new event
switch(e->mWireEventCode)
{
case RsWireEventCode::READ_STATUS_CHANGED:
updateGroupStatisticsReal(e->mWireGroupId); // update the list immediately
return;
case RsWireEventCode::STATISTICS_CHANGED:
case RsWireEventCode::NEW_POST:
case RsWireEventCode::NEW_REPLY:
case RsWireEventCode::NEW_LIKE:
case RsWireEventCode::NEW_REPUBLISH:
case RsWireEventCode::POST_UPDATED:
case RsWireEventCode::NEW_WIRE:
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
case RsWireEventCode::NEW_WIRE:
updateGroupStatisticsReal(e->mWireGroupId);
break;
default:
refreshGroups();
#ifdef GXSWIRE_DEBUG
RsDbg() << " Unknown event occured: "<< e->mWireEventCode << std::endl;
#endif
break;
}
refreshGroups();
}
}
@ -140,12 +194,148 @@ WireDialog::~WireDialog()
processSettings(false);
clearTwitterView();
std::cerr << "WireDialog::~WireDialog()" << std::endl;
delete(mWireQueue);
rsEvents->unregisterEventsHandler(mEventHandlerId);
}
UserNotify *WireDialog::createUserNotify(QObject *parent)
{
return new WireUserNotify(rsWire, this, parent);
}
//QString WireDialog::getHelpString() const
//{
// int H = misc::getFontSizeFactor("HelpButton").height();
// QString hlp_str = tr(
// "<h1><img width=\"%1\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Boards</h1>"
// "<p>The wire service is a day to day social network service.</p>"
// "<p>The Wire service allows you to share your pulses, republish someone else's pulses, like "
// "a pulse.</p>"
// "<p>A pulse is like a channel or board post. It can be a image or a text or both. You can "
// "only see the pulses of the people you follow.</p>"
// "<p>Wire posts are kept for %2 days, and sync-ed over the last %3 days, unless you change this.</p>"
// ).arg( QString::number(2*H)
// , QString::number(rsWire->getDefaultStoragePeriod()/86400)
// , QString::number(rsWire->getDefaultSyncPeriod()/86400));
// return hlp_str ;
//}
//QString WireDialog::text(TextType type)
//{
// switch (type) {
// case TEXT_NAME:
// return tr("Wire");
// case TEXT_NEW:
// return tr("Create Wire");
//// Dont know what this does
//// case TEXT_TODO:
//// return "<b>Open points:</b><ul>"
//// "<li>Subreddits/tag to posts support"
//// "<li>Picture Support"
//// "<li>Navigate channel link"
//// "</ul>";
// case TEXT_YOUR_GROUP:
// return tr("My Wire");
// case TEXT_SUBSCRIBED_GROUP:
// return tr("Followed Wires");
// case TEXT_POPULAR_GROUP:
// return tr("Popular Wires");
// case TEXT_OTHER_GROUP:
// return tr("Other Wires");
// }
// return "";
//}
//QString WireDialog::icon(IconType type)
//{
// switch (type) {
// case ICON_NAME:
// return ":/icons/png/postedlinks.png";
// case ICON_NEW:
// return ":/icons/png/add.png";
// case ICON_YOUR_GROUP:
// return "";
// case ICON_SUBSCRIBED_GROUP:
// return "";
// case ICON_POPULAR_GROUP:
// return "";
// case ICON_OTHER_GROUP:
// return "";
// case ICON_SEARCH:
// return ":/images/find.png";
// case ICON_DEFAULT:
// return ":/icons/png/posted.png";
// }
// return "";
//}
//bool WireDialog::getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo)
//{
// std::vector<RsWireGroup> groups;
// // request all group infos at once
// if(! rsWire->getGroups(std::list<RsGxsGroupId>(),groups))
// return false;
// /* Save groups to fill icons and description */
// for (auto& group: groups)
// groupInfo.push_back(new RsWireGroup(group));
// return true;
//}
bool WireDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat)
{
// What follows is a hack to replace the GXS group statistics by the actual count of unread messages in wire,
// which should take into account old post versions, discard replies and likes, etc.
RsWireStatistics s;
bool res = rsWire->getWireStatistics(groupId,s);
if(!res)
return false;
stat.mGrpId = groupId;
stat.mNumMsgs = s.mNumberOfPulses;
stat.mTotalSizeOfMsgs = 0; // hopefuly unused. Required the loading of the full channel data, so not very convenient.
stat.mNumThreadMsgsNew = s.mNumberOfNewPulses;
stat.mNumThreadMsgsUnread = s.mNumberOfUnreadPulses;
stat.mNumChildMsgsNew = 0;
stat.mNumChildMsgsUnread = 0;
return true;
}
//GxsGroupDialog *WireDialog::createNewGroupDialog()
//{
// return new WireGroupDialog(this);
//}
//GxsGroupDialog *WireDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId)
//{
// return new WireGroupDialog(mode, groupId, this);
//}
//int WireDialog::shareKeyType()
//{
// return GroupShareKey::NO_KEY_SHARE;
//}
//GxsMessageFrameWidget *WireDialog::createMessageFrameWidget(const RsGxsGroupId &groupId)
//{
// // to do
//// return new WireListWidgetWithModel(groupId);
//}
void WireDialog::processSettings(bool load)
{
Settings->beginGroup("WireDialog");
@ -177,6 +367,33 @@ void WireDialog::refreshGroups()
requestGroupData();
}
void WireDialog::showHomeFeed()
{
mGroupSet = GROUP_SET_SUBSCRIBED;
ui.comboBox_groupSet->setCurrentIndex(GROUP_SET_SUBSCRIBED);
mGroupSelected = nullptr;
showGroups();
}
void WireDialog::filterUsers(const QString &text)
{
QLayout *alayout = ui.groupsWidget->layout();
QString filterText = text.toLower();
for (int i = 0; i < alayout->count(); ++i)
{
QLayoutItem *item = alayout->itemAt(i);
QWidget *widget = item->widget();
WireGroupItem *groupItem = dynamic_cast<WireGroupItem *>(widget);
if (groupItem)
{
bool visible = filterText.isEmpty() || groupItem->matchesFilter(filterText);
groupItem->setVisible(visible);
}
}
}
void WireDialog::addGroup(QWidget *item)
{
QLayout *alayout = ui.groupsWidget->layout();
@ -197,7 +414,7 @@ bool WireDialog::setupPulseAddDialog()
mAddDialog->cleanup();
int idx = ui.groupChooser->currentIndex();
if (idx < 0) {
if (idx < 0 || idx >= (int)mOwnGroups.size()) {
std::cerr << "WireDialog::setupPulseAddDialog() ERROR GETTING AuthorId!";
std::cerr << std::endl;
@ -205,9 +422,8 @@ bool WireDialog::setupPulseAddDialog()
return false;
}
// publishing group.
RsWireGroup group = mOwnGroups[idx];
mAddDialog->setGroup(group.mMeta.mGroupId);
mAddDialog->setGroup(group);
return true;
}
@ -217,14 +433,12 @@ void WireDialog::subscribe(RsGxsGroupId &groupId)
{
uint32_t token;
rsWire->subscribeToGroup(token, groupId, true);
mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE);
}
void WireDialog::unsubscribe(RsGxsGroupId &groupId)
{
uint32_t token;
rsWire->subscribeToGroup(token, groupId, false);
mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE);
}
void WireDialog::notifyGroupSelection(WireGroupItem *item)
@ -388,6 +602,12 @@ void WireDialog::selectGroupSet(int index)
if (mGroupSet < 0) {
mGroupSet = GROUP_SET_ALL;
}
// show follow label and account filter only when All is selected
bool showFollow = (mGroupSet == GROUP_SET_ALL);
ui.followLabel->setVisible(showFollow);
ui.toolButton_accountFilter->setVisible(showFollow);
showGroups();
}
@ -399,9 +619,26 @@ void WireDialog::selectFilterTime(int index)
showSelectedGroups();
}
void WireDialog::toggleSortAscending()
{
mSortAscending = !mSortAscending;
showSelectedGroups();
}
void WireDialog::sortAccountsChanged(QAction *action)
{
mAccountSortType = action->data().toInt();
showGroups();
}
void WireDialog::hideInactiveChanged(bool checked)
{
mHideInactiveAccounts = checked;
showGroups();
}
void WireDialog::showSelectedGroups()
{
ui.comboBox_filterTime->setEnabled(false);
if (mGroupSelected)
{
// request data.
@ -419,12 +656,15 @@ void WireDialog::showSelectedGroups()
void WireDialog::showGroups()
{
ui.comboBox_filterTime->setEnabled(false);
deleteGroups();
std::list<RsGxsGroupId> allGroupIds;
std::vector<RsWireGroup> groupsToShow;
// Collect groups that match the current filter
rstime_t now = time(nullptr);
rstime_t thirtyDaysAgo = now - (30 * 24 * 60 * 60);
/* depends on the comboBox */
for (auto &it : mAllGroups)
{
bool add = (mGroupSet == GROUP_SET_ALL);
@ -444,13 +684,39 @@ void WireDialog::showGroups()
}
}
if (add) {
addGroup(it.second);
// request data.
std::list<RsGxsGroupId> grpIds;
grpIds.push_back(it.second.mMeta.mGroupId);
allGroupIds.push_back(it.second.mMeta.mGroupId);
// Filter inactive accounts if checkbox is checked
if (add && mHideInactiveAccounts) {
rstime_t lastPost = it.second.mMeta.mLastPost;
if (lastPost == 0 || lastPost < thirtyDaysAgo) {
add = false;
}
}
if (add) {
groupsToShow.push_back(it.second);
}
}
// Sort groups based on selection
if (mAccountSortType == 0) {
// Sort by name (alphabetical)
std::sort(groupsToShow.begin(), groupsToShow.end(),
[](const RsWireGroup &a, const RsWireGroup &b) {
return QString::fromStdString(a.mMeta.mGroupName).toLower() <
QString::fromStdString(b.mMeta.mGroupName).toLower();
});
} else {
// Sort by activity (most recent first)
std::sort(groupsToShow.begin(), groupsToShow.end(),
[](const RsWireGroup &a, const RsWireGroup &b) {
return a.mMeta.mLastPost > b.mMeta.mLastPost;
});
}
// Add sorted groups to UI
for (auto &group : groupsToShow) {
addGroup(group);
allGroupIds.push_back(group.mMeta.mGroupId);
}
requestGroupsPulses(allGroupIds);
@ -464,24 +730,21 @@ void WireDialog::requestGroupData()
std::cerr << "WireDialog::requestGroupData()";
std::cerr << std::endl;
RsTokReqOptions opts;
uint32_t token;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
mWireQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0);
}
std::vector<RsWireGroup> groups;
rsWire->getGroups({}, groups);
bool WireDialog::loadGroupData(const uint32_t &token)
{
std::cerr << "WireDialog::loadGroupData()";
std::cerr << std::endl;
updateGroups(groups);
showGroups();
std::vector<RsWireGroup> groups;
rsWire->getGroupData(token, groups);
// save list of groups.
updateGroups(groups);
showGroups();
return true;
if (!mNavigatePendingGroupId.isNull()) {
if (!mNavigatePendingMsgId.isNull()) {
requestPulseFocus(mNavigatePendingGroupId, mNavigatePendingMsgId);
} else {
requestGroupFocus(mNavigatePendingGroupId);
}
mNavigatePendingGroupId.clear();
mNavigatePendingMsgId.clear();
}
}
rstime_t WireDialog::getFilterTimestamp()
@ -507,60 +770,6 @@ rstime_t WireDialog::getFilterTimestamp()
return filterTimestamp;
}
void WireDialog::acknowledgeGroup(const uint32_t &token, const uint32_t &userType)
{
/* reload groups */
std::cerr << "WireDialog::acknowledgeGroup(usertype: " << userType << ")";
std::cerr << std::endl;
RsGxsGroupId grpId;
rsWire->acknowledgeGrp(token, grpId);
refreshGroups();
}
/**************************** Request / Response Filling of Data ************************/
void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
std::cerr << "WireDialog::loadRequest()";
std::cerr << std::endl;
if (queue == mWireQueue)
{
/* now switch on req */
switch(req.mType)
{
case TOKENREQ_GROUPINFO:
switch(req.mAnsType)
{
case RS_TOKREQ_ANSTYPE_DATA:
loadGroupData(req.mToken);
break;
case RS_TOKREQ_ANSTYPE_ACK:
acknowledgeGroup(req.mToken, req.mUserType);
break;
default:
std::cerr << "WireDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE";
std::cerr << std::endl;
break;
}
break;
default:
std::cerr << "WireDialog::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
}
}
/**************************** Request / Response Filling of Data ************************/
/****************************************************************************************/
// TWITTER VIEW.
@ -598,39 +807,36 @@ void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
void WireDialog::PVHreply(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId)
{
std::cerr << "WireDialog::PVHreply() GroupId: " << groupId;
std::cerr << "MsgId: " << msgId;
std::cerr << " MsgId: " << msgId;
std::cerr << std::endl;
if (setupPulseAddDialog())
{
mAddDialog->setReplyTo(groupId, msgId, WIRE_PULSE_TYPE_REPLY);
mAddDialog->show();
}
}
void WireDialog::PVHrepublish(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId)
{
std::cerr << "WireDialog::PVHrepublish() GroupId: " << groupId;
std::cerr << "MsgId: " << msgId;
std::cerr << " MsgId: " << msgId;
std::cerr << std::endl;
if (setupPulseAddDialog())
{
mAddDialog->setReplyTo(groupId, msgId, WIRE_PULSE_TYPE_REPUBLISH);
mAddDialog->show();
}
}
void WireDialog::PVHlike(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId)
{
std::cerr << "WireDialog::PVHlike() GroupId: " << groupId;
std::cerr << "MsgId: " << msgId;
std::cerr << " MsgId: " << msgId;
std::cerr << std::endl;
if (setupPulseAddDialog())
{
mAddDialog->setReplyTo(groupId, msgId, WIRE_PULSE_TYPE_LIKE);
mAddDialog->show();
}
}
@ -675,7 +881,6 @@ void WireDialog::PVHfollow(const RsGxsGroupId &groupId)
uint32_t token;
rsWire->subscribeToGroup(token, groupId, true);
mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE);
}
void WireDialog::PVHrate(const RsGxsId &authorId)
@ -689,7 +894,6 @@ void WireDialog::PVHrate(const RsGxsId &authorId)
void WireDialog::postTestTwitterView()
{
clearTwitterView();
std::cerr << "WireDialog::postTestTwitterView()" << std::endl;
addTwitterView(new PulseTopLevel(NULL,RsWirePulseSPtr()));
addTwitterView(new PulseReply(NULL,RsWirePulseSPtr()));
@ -846,7 +1050,6 @@ void WireDialog::requestPulseFocus(const RsGxsGroupId groupId, const RsGxsMessag
void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId msgId)
{
clearTwitterView();
std::cerr << "WireDialog::showPulseFocus()" << std::endl;
// background thread for loading.
RsThread::async([this, groupId, msgId]()
@ -876,8 +1079,6 @@ void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId
void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse)
{
clearTwitterView();
std::cerr << "WireDialog::postPulseFocus()" << std::endl;
if (!pPulse)
{
std::cerr << "WireDialog::postPulseFocus() Invalid pulse";
@ -950,7 +1151,7 @@ void WireDialog::requestGroupFocus(const RsGxsGroupId groupId)
void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
{
clearTwitterView();
std::cerr << "WireDialog::showGroupFocus()" << std::endl;
// background thread for loading.
RsThread::async([this, groupId]()
{
@ -980,6 +1181,8 @@ void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list<RsWirePulseSPtr> pulses)
{
clearTwitterView();
std::cerr << "WireDialog::postGroupFocus()";
std::cerr << std::endl;
@ -1027,7 +1230,6 @@ void WireDialog::requestGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
{
clearTwitterView();
std::cerr << "WireDialog::showGroupPulses()" << std::endl;
// background thread for loading.
RsThread::async([this, groupIds]()
@ -1054,6 +1256,7 @@ void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
{
clearTwitterView();
std::cerr << "WireDialog::postGroupsPulses()";
std::cerr << std::endl;
@ -1077,3 +1280,166 @@ void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
}
}
void WireDialog::getServiceStatistics(GxsServiceStatistic& stats) const
{
if(!mCachedGroupStats.empty())
{
stats = GxsServiceStatistic(); // clears everything
for(auto& it: mCachedGroupStats)
{
const GxsGroupStatistic& s(it.second);
stats.mNumMsgs += s.mNumMsgs;
stats.mNumGrps += 1;
stats.mSizeOfMsgs += s.mTotalSizeOfMsgs;
stats.mNumThreadMsgsNew += s.mNumThreadMsgsNew;
stats.mNumThreadMsgsUnread += s.mNumThreadMsgsUnread;
stats.mNumChildMsgsNew += s.mNumChildMsgsNew ;
stats.mNumChildMsgsUnread += s.mNumChildMsgsUnread ;
}
// Also save the service statistics in conf file, so that we can display it right away at start.
Settings->beginGroup(mSettingsName);
Settings->setValue("NumMsgs", stats.mNumMsgs );
Settings->setValue("NumGrps", stats.mNumGrps );
Settings->setValue("SizeOfMessages", stats.mSizeOfMsgs );
Settings->setValue("NumThreadMsgsNew", stats.mNumThreadMsgsNew );
Settings->setValue("NumThreadMsgsUnread",stats.mNumThreadMsgsUnread);
Settings->setValue("NumChildMsgsNew", stats.mNumChildMsgsNew );
Settings->setValue("NumChildMsgsUnread", stats.mNumChildMsgsUnread );
Settings->endGroup();
}
else // Get statistics from settings if no cache is already present: allows to display at start.
{
Settings->beginGroup(mSettingsName);
stats.mNumMsgs = Settings->value("NumMsgs",QVariant(0)).toInt();
stats.mNumGrps = Settings->value("NumGrps",QVariant(0)).toInt();
stats.mSizeOfMsgs = Settings->value("SizeOfMessages",QVariant(0)).toInt();
stats.mNumThreadMsgsNew = Settings->value("NumThreadMsgsNew",QVariant(0)).toInt();
stats.mNumThreadMsgsUnread = Settings->value("NumThreadMsgsUnread",QVariant(0)).toInt();
stats.mNumChildMsgsNew = Settings->value("NumChildMsgsNew",QVariant(0)).toInt();
stats.mNumChildMsgsUnread = Settings->value("NumChildMsgsUnread",QVariant(0)).toInt();
Settings->endGroup();
}
}
void WireDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
{
mGroupStatisticsToUpdate.insert(groupId);
mShouldUpdateGroupStatistics = true;
}
void WireDialog::updateGroupStatisticsReal(const RsGxsGroupId &groupId)
{
RsThread::async([this,groupId]()
{
GxsGroupStatistic stats;
if(! getGroupStatistics(groupId, stats))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to collect group statistics for group " << groupId << std::endl;
return;
}
RsQThreadUtils::postToObject( [this,stats, groupId]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete, note that
* Qt::QueuedConnection is important!
*/
// QTreeWidgetItem *item = ui.scrollAreaWidgetContents->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString()));
// if (item)
// ui.scrollAreaWidgetContents->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread);
mCachedGroupStats[groupId] = stats;
getUserNotify()->updateIcon();
}, this );
});
}
bool WireDialog::navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId)
{
if (groupId.isNull()) {
return false;
}
// if groups not loaded yet, save for later
if (mAllGroups.empty()) {
mNavigatePendingGroupId = groupId;
mNavigatePendingMsgId = msgId;
return true;
}
if (!msgId.isNull()) {
requestPulseFocus(groupId, msgId);
} else {
requestGroupFocus(groupId);
}
return true;
}
GxsMessageFrameWidget *WireDialog::messageWidget(const RsGxsGroupId &groupId)
{
// int tabCount = ui.tabWidget->count();
// for (int index = 0; index < tabCount; ++index)
// {
// GxsMessageFrameWidget *childWidget = dynamic_cast<GxsMessageFrameWidget*>(ui.tabWidget->widget(index));
// if (childWidget && childWidget->groupId() == groupId)
// return childWidget;
// }
return NULL;
}
//void GxsGroupFrameDialog::changedCurrentGroup(const QString& groupId)
//{
// if (mInFill) {
// return;
// }
// if (groupId.isEmpty())
// {
// auto w = currentWidget();
// if(w)
// w->setGroupId(RsGxsGroupId());
// return;
// }
// mGroupId = RsGxsGroupId(groupId.toStdString());
// if (mGroupId.isNull())
// return;
// /* search exisiting tab */
// GxsMessageFrameWidget *msgWidget = messageWidget(mGroupId);
// // check that we have at least one tab
// if(msgWidget)
// ui.messageTabWidget->setCurrentWidget(msgWidget);
// else
// {
// if(useTabs() || ui.messageTabWidget->count()==0)
// {
// msgWidget = createMessageWidget(RsGxsGroupId(groupId.toStdString()));
// ui.messageTabWidget->setCurrentWidget(msgWidget);
// }
// else
// currentWidget()->setGroupId(mGroupId);
// }
//}

View File

@ -34,9 +34,11 @@
#include "gui/TheWire/PulseViewItem.h"
#include "gui/TheWire/PulseTopLevel.h"
#include "gui/TheWire/PulseReply.h"
#include "gui/gxs/GxsStatisticsProvider.h"
#include "util/TokenQueue.h"
class UIStateHelper;
class GxsMessageFrameWidget;
class RsGxsIfaceHelper;
#define IMAGE_WIRE ":/icons/wire.png"
@ -68,7 +70,7 @@ public:
};
//---------------------------------------------------------
class WireDialog : public MainPage, public TokenResponse, public WireGroupHolder, public PulseViewHolder
class WireDialog : public MainPage, public GxsStatisticsProvider, public WireGroupHolder, public PulseViewHolder
{
Q_OBJECT
@ -118,15 +120,35 @@ public:
void showGroupsPulses(const std::list<RsGxsGroupId>& groupIds);
void postGroupsPulses(std::list<RsWirePulseSPtr> pulses);
void getServiceStatistics(GxsServiceStatistic& stats) const override;
virtual bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId);
protected:
bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat);
UserNotify *createUserNotify(QObject *parent) override;
virtual void updateGroupStatistics(const RsGxsGroupId &groupId);
virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
private slots:
void createGroup();
void createPulse();
void showHomeFeed();
void filterUsers(const QString &text);
void checkUpdate();
void refreshGroups();
void selectGroupSet(int index);
void selectFilterTime(int index);
// Filter menu actions
void toggleSortAscending();
// Account filter slots
void sortAccountsChanged(QAction *action);
void hideInactiveChanged(bool checked);
// history navigation.
void back();
void forward();
@ -150,16 +172,13 @@ private:
// Loading Data.
void requestGroupData();
bool loadGroupData(const uint32_t &token);
void acknowledgeGroup(const uint32_t &token, const uint32_t &userType);
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override;
GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
int mGroupSet;
PulseAddDialog *mAddDialog;
WireGroupItem *mGroupSelected;
TokenQueue *mWireQueue;
std::map<RsGxsGroupId, RsWireGroup> mAllGroups;
std::vector<RsWireGroup> mOwnGroups;
@ -170,6 +189,21 @@ private:
int32_t mHistoryIndex;
std::vector<WireViewHistory> mHistory;
bool mSortAscending;
int mAccountSortType;
bool mHideInactiveAccounts;
// Members for GxsStatisticsProvider interface support
QString mSettingsName;
RsGxsIfaceHelper *mInterface;
bool mDistSyncAllowed;
std::map<RsGxsGroupId,GxsGroupStatistic> mCachedGroupStats;
bool mShouldUpdateGroupStatistics;
std::set<RsGxsGroupId> mGroupStatisticsToUpdate;
bool mCountChildMsgs;
RsGxsGroupId mNavigatePendingGroupId;
RsGxsMessageId mNavigatePendingMsgId;
UIStateHelper *mStateHelper;
/* UI - from Designer */
Ui::WireDialog ui;

View File

@ -87,6 +87,20 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_home">
<property name="text">
<string>Home</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/home.png</normaloff>:/icons/png/home.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -178,18 +192,49 @@
</widget>
</item>
<item>
<widget class="QLabel" name="followLabel">
<property name="font">
<font>
<pointsize>10</pointsize>
<bold>true</bold>
</font>
<widget class="QLineEdit" name="lineEdit_searchUsers">
<property name="placeholderText">
<string>Search...</string>
</property>
<property name="text">
<string>Who to Follow</string>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="accountFilterLayout">
<item>
<widget class="QLabel" name="followLabel">
<property name="font">
<font>
<pointsize>10</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Who to Follow</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_accountFilter">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/options.png</normaloff>:/icons/png/options.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QScrollArea" name="trans_scrollAreaWidgetContents_groups">
<property name="widgetResizable">
@ -224,7 +269,7 @@
</item>
</layout>
</widget>
<widget class="QTabWidget" name="tabWidget">
<widget class="RSTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>3</horstretch>
@ -363,6 +408,20 @@
</item>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_filter">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/mail/filter24.png</normaloff>:/icons/mail/filter24.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -432,6 +491,12 @@
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
<customwidget>
<class>RSTabWidget</class>
<extends>QTabWidget</extends>
<header>gui/common/RSTabWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>

View File

@ -34,7 +34,7 @@ const uint32_t WireCreateEnabledFlags = (
GXS_GROUP_FLAGS_DISTRIBUTION |
// GXS_GROUP_FLAGS_PUBLISHSIGN |
// GXS_GROUP_FLAGS_SHAREKEYS | // disabled because the UI doesn't handle it yet.
// GXS_GROUP_FLAGS_PERSONALSIGN |
GXS_GROUP_FLAGS_PERSONALSIGN |
// GXS_GROUP_FLAGS_COMMENTS |
GXS_GROUP_FLAGS_EXTRA |
0);

View File

@ -210,6 +210,15 @@ const QPixmap *WireGroupItem::getPixmap()
return NULL;
}
bool WireGroupItem::matchesFilter(const QString &filterText) const
{
if (filterText.isEmpty())
return true;
QString groupName = QString::fromStdString(mGroup.mMeta.mGroupName).toLower();
return groupName.contains(filterText);
}
void WireGroupItem::editGroupDetails()
{
RsGxsGroupId groupId = mGroup.mMeta.mGroupId;

View File

@ -51,6 +51,7 @@ public:
const QPixmap *getPixmap();
RsGxsGroupId &groupId();
bool matchesFilter(const QString &filterText) const;
private slots:
void show();

View File

@ -0,0 +1,62 @@
/*******************************************************************************
* retroshare-gui/src/gui/TheWire/WireUserNotify.cpp *
* *
* Copyright (C) 2014 by Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "retroshare/rswire.h"
#include "WireUserNotify.h"
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
WireUserNotify::WireUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}
bool WireUserNotify::hasSetting(QString *name, QString *group)
{
if (name) *name = tr("Wire Post");
if (group) *group = "Wire";
return true;
}
QIcon WireUserNotify::getIcon()
{
return FilesDefs::getIconFromQtResourcePath(":/icons/png/wire-circle.png");
}
QIcon WireUserNotify::getMainIcon(bool hasNew)
{
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/wire-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/wire-circle.png");
}
//QString WireUserNotify::getTrayMessage(bool plural)
//{
// return plural ? tr("You have %1 new wire pulse") : tr("You have %1 new wire pulse");
//}
//QString WireUserNotify::getNotifyMessage(bool plural)
//{
// return plural ? tr("%1 new wire pulse") : tr("%1 new wire pulse");
//}
void WireUserNotify::iconClicked()
{
MainWindow::showWindow(MainWindow::Wire);
}

View File

@ -0,0 +1,45 @@
/*******************************************************************************
* retroshare-gui/src/gui/TheWire/WireUserNotify.h *
* *
* Copyright (C) 2014 by Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef WIREUSERNOTIFY_H
#define WIREUSERNOTIFY_H
#include "gui/gxs/GxsUserNotify.h"
class WireUserNotify : public GxsUserNotify
{
Q_OBJECT
public:
explicit WireUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;
private:
virtual QIcon getIcon() override;
virtual QIcon getMainIcon(bool hasNew) override;
//virtual QString getTrayMessage(bool plural) override;
//virtual QString getNotifyMessage(bool plural) override;
virtual void iconClicked() override;
};
#endif // WIREUSERNOTIFY_H

View File

@ -38,6 +38,9 @@ enum class RsFeedTypeFlags: uint32_t {
RS_FEED_TYPE_POSTED = 0x1000,
RS_FEED_TYPE_SECURITY_IP = 0x2000,
RS_FEED_TYPE_CIRCLE = 0x4000,
#ifdef RS_USE_WIRE
RS_FEED_TYPE_WIRE = 0x8000,
#endif
RS_FEED_ITEM_PEER_CONNECT = RS_FEED_TYPE_PEER | 0x0001,
RS_FEED_ITEM_PEER_DISCONNECT = RS_FEED_TYPE_PEER | 0x0002,

View File

@ -0,0 +1,281 @@
/*******************************************************************************
* gui/feeds/WireNotifyGroupItem.cpp *
* *
* Copyright (c) 2014, Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "WireNotifyGroupItem.h"
#include "ui_WireNotifyGroupItem.h"
#include "FeedHolder.h"
#include "util/qtthreadsutils.h"
#include "gui/common/FilesDefs.h"
#include "gui/RetroShareLink.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/MainWindow.h"
#include "gui/TheWire/WireDialog.h"
#include "util/DateTime.h"
/****
* #define DEBUG_ITEM 1
****/
WireNotifyGroupItem::WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate, RsWireEventCode eventCode) :
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsWire, autoUpdate),
mEventCode(eventCode)
{
setup();
requestGroup();
addEventHandler();
}
void WireNotifyGroupItem::addEventHandler()
{
mEventHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event)
{
RsQThreadUtils::postToObject([=]()
{
const auto *e = dynamic_cast<const RsWireEvent*>(event.get());
if(!e || e->mWireGroupId != this->groupId())
return;
switch(e->mWireEventCode)
{
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
case RsWireEventCode::WIRE_UPDATED:
mGroup = RsWireGroup();
requestGroup();
break;
default:
break;
}
}, this );
}, mEventHandlerId, RsEventType::WIRE );
}
WireNotifyGroupItem::~WireNotifyGroupItem()
{
rsEvents->unregisterEventsHandler(mEventHandlerId);
delete(ui);
}
void WireNotifyGroupItem::setup()
{
/* Invoke the Qt Designer generated object setup routine */
ui = new(Ui::WireNotifyGroupItem);
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
/* clear ui */
ui->nameLabel->setText(tr("Loading..."));
ui->titleLabel->clear();
ui->descLabel->clear();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->subscribeButton, SIGNAL(clicked()), this, SLOT(subscribeWire()));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyGroupLink()));
connect(ui->nameLabel, SIGNAL(linkActivated(QString)), this, SLOT(openWireGroup()));
//ui->copyLinkButton->hide(); // No link type at this moment
ui->expandFrame->hide();
}
bool WireNotifyGroupItem::setGroup(const RsWireGroup &group)
{
if (groupId() != group.mMeta.mGroupId) {
std::cerr << "WireNotifyGroupItem::setContent() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mGroup = group;
fill();
return true;
}
void WireNotifyGroupItem::loadGroup()
{
RsThread::async([this]()
{
// 1 - get group data
#ifdef DEBUG_ITEM
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif
std::vector<RsWireGroup> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() };
if(!rsWire->getGroups(groupIds,groups))
{
RsErr() << "WireNotifyGroupItem::loadGroup() ERROR getting data" << std::endl;
deferred_update();
return;
}
if (groups.size() != 1)
{
std::cerr << "WireNotifyGroupItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
deferred_update();
return;
}
RsWireGroup group(groups[0]);
RsQThreadUtils::postToObject( [group,this]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */
setGroup(group);
}, this );
});
}
QString WireNotifyGroupItem::groupName()
{
return QString::fromUtf8(mGroup.mMeta.mGroupName.c_str());
}
void WireNotifyGroupItem::fill()
{
/* fill in */
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyGroupItem::fill()";
std::cerr << std::endl;
#endif
// No link type at this moment
RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_WIRE, mGroup.mMeta.mGroupId, groupName());
ui->nameLabel->setText(link.toHtml());
ui->descLabel->setText(QString::fromUtf8(mGroup.mTagline.c_str()));
if (mGroup.mHeadshot.mData != NULL) {
QPixmap wireImage;
GxsIdDetails::loadPixmapFromData(mGroup.mHeadshot.mData, mGroup.mHeadshot.mSize, wireImage,GxsIdDetails::ORIGINAL);
ui->logoLabel->setPixmap(QPixmap(wireImage));
} else {
ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png"));
}
//TODO - nice icon for subscribed group
// if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) {
// ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png"));
// } else {
// ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png"));
// }
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) {
ui->subscribeButton->setEnabled(false);
} else {
ui->subscribeButton->setEnabled(true);
}
if(mGroup.mMeta.mLastPost==0)
ui->infoLastPost->setText(tr("Never"));
else
ui->infoLastPost->setText(DateTime::formatLongDateTime(mGroup.mMeta.mLastPost));
// Set title based on event type
switch(mEventCode)
{
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
ui->titleLabel->setText(tr("Now Following"));
break;
case RsWireEventCode::WIRE_UPDATED:
ui->titleLabel->setText(tr("Wire Updated"));
break;
case RsWireEventCode::NEW_WIRE:
default:
ui->titleLabel->setText(tr("New Wire"));
break;
}
if (mIsHome)
{
/* disable buttons */
ui->clearButton->setEnabled(false);
}
}
void WireNotifyGroupItem::toggle()
{
expand(ui->expandFrame->isHidden());
}
void WireNotifyGroupItem::doExpand(bool open)
{
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
if (open)
{
ui->expandFrame->show();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png")));
ui->expandButton->setToolTip(tr("Hide"));
}
else
{
ui->expandFrame->hide();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png")));
ui->expandButton->setToolTip(tr("Expand"));
}
emit sizeChanged(this);
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
}
}
void WireNotifyGroupItem::subscribeWire()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyGroupItem::subscribeWire()";
std::cerr << std::endl;
#endif
//subscribe(); does not work for wire, bug? -> GxsGroupFeedItem::subscribe()
uint32_t token;
rsWire->subscribeToGroup(token, mGroup.mMeta.mGroupId, true);
}
void WireNotifyGroupItem::openWireGroup()
{
MainWindow::showWindow(MainWindow::Wire);
WireDialog *wireDialog = dynamic_cast<WireDialog*>(MainWindow::getPage(MainWindow::Wire));
if (wireDialog)
{
wireDialog->navigate(mGroup.mMeta.mGroupId, RsGxsMessageId());
}
removeItem();
}

View File

@ -0,0 +1,74 @@
/*******************************************************************************
* gui/feeds/WireNotifyGroupItem.h *
* *
* Copyright (c) 2014, Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef WIRENOTIFYGROUPITEM_H
#define WIRENOTIFYGROUPITEM_H
#include <retroshare/rswire.h>
#include "gui/feeds/GxsGroupFeedItem.h"
namespace Ui {
class WireNotifyGroupItem;
}
class FeedHolder;
class WireNotifyGroupItem : public GxsGroupFeedItem
{
Q_OBJECT
public:
/** Default Constructor */
WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate, RsWireEventCode eventCode = RsWireEventCode::NEW_WIRE);
~WireNotifyGroupItem();
bool setGroup(const RsWireGroup &group);
uint64_t uniqueIdentifier() const override { return hash_64bits("WireNotifyGroupItem " + groupId().toStdString()) ; }
protected:
/* FeedItem */
virtual void doExpand(bool open);
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup() override;
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_WIRE; }
private slots:
void toggle() override;
void subscribeWire();
void openWireGroup();
private:
void fill();
void setup();
void addEventHandler();
private:
RsWireGroup mGroup;
RsWireEventCode mEventCode;
/** Qt Designer generated object */
Ui::WireNotifyGroupItem *ui;
RsEventsHandlerId_t mEventHandlerId;
};
#endif // WIRENOTIFYGROUPITEM_H

View File

@ -0,0 +1,403 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WireNotifyGroupItem</class>
<widget class="QWidget" name="WireNotifyGroupItem">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>618</width>
<height>191</height>
</rect>
</property>
<layout class="QGridLayout" name="WireNotifyGroupItem_GL">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="feedFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>154</red>
<green>154</green>
<blue>154</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="feedFrame_GL">
<item row="0" column="0">
<layout class="QGridLayout" name="top_GL">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/png/posted.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="title_HL">
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Wire</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nameLabel">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">name</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="title_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="infoLastPostLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Last activity</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoLastPost">
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="buttons_HL">
<item>
<widget class="QPushButton" name="subscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Follow to User&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Follow</string>
</property>
</widget>
</item>
<item>
<spacer name="buttons_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>254</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Copy RetroShare Link</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/copy.png</normaloff>:/icons/png/copy.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Expand</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/down-arrow.png</normaloff>:/icons/png/down-arrow.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QFrame" name="expandFrame">
<layout class="QVBoxLayout" name="expandFrame_VL">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Wire Description</string>
</property>
<layout class="QHBoxLayout" name="groupBox_HL">
<item>
<widget class="QLabel" name="iconLabel">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>:/images/contacts24.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="descLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Description
of Wire</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,522 @@
/*******************************************************************************
* gui/feeds/WireNotifyPostItem.cpp *
* *
* Copyright (c) 2012, Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QStyle>
#include "WireNotifyPostItem.h"
#include "ui_WireNotifyPostItem.h"
#include "FeedHolder.h"
#include "util/qtthreadsutils.h"
#include "gui/RetroShareLink.h"
#include "gui/common/FilesDefs.h"
#include "gui/gxs/GxsIdDetails.h"
#include "util/stringutil.h"
#include "util/DateTime.h"
#include "util/misc.h"
#include <iostream>
#include <cmath>
WireNotifyPostItem::WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool autoUpdate, const std::set<RsGxsMessageId> &older_versions) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, false, rsWire, autoUpdate)
{
mLoadingStatus = LOADING_STATUS_NO_DATA;
mLoadingGroup = false;
mLoadingMessage = false;
mLoadingComment = false;
QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup();
}
void WireNotifyPostItem::paintEvent(QPaintEvent *e)
{
/* This method employs a trick to trigger a deferred loading. The post and group is requested only
* when actually displayed on the screen. */
if(mLoadingStatus != LOADING_STATUS_FILLED && !mGroupMeta.mGroupId.isNull() && !mPulse.mMeta.mMsgId.isNull() )
mLoadingStatus = LOADING_STATUS_HAS_DATA;
if(mGroupMeta.mGroupId.isNull() && !mLoadingGroup)
requestGroup();
if(mPulse.mMeta.mMsgId.isNull() && !mLoadingMessage)
requestMessage();
switch(mLoadingStatus)
{
case LOADING_STATUS_FILLED:
case LOADING_STATUS_NO_DATA:
default:
break;
case LOADING_STATUS_HAS_DATA:
fill();
setGroup(mGroup);
mLoadingStatus = LOADING_STATUS_FILLED;
break;
}
GxsFeedItem::paintEvent(e) ;
}
WireNotifyPostItem::~WireNotifyPostItem()
{
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(GROUP_ITEM_LOADING_TIMEOUT_ms);
while( (mLoadingGroup || mLoadingMessage || mLoadingComment)
&& std::chrono::steady_clock::now() < timeout)
{
RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for "
<< (mLoadingGroup ? "Group " : "")
<< (mLoadingMessage ? "Message " : "")
<< (mLoadingComment ? "Comment " : "")
<< "loading." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
delete ui;
}
bool WireNotifyPostItem::isUnread() const
{
return IS_MSG_UNREAD(mPulse.mMeta.mMsgStatus) ;
}
void WireNotifyPostItem::setup()
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::WireNotifyPostItem;
ui->setupUi(this);
// Manually set icons to allow to use clever resource sharing that is missing in Qt for Icons loaded from Qt resource file.
// This is particularly important here because a wire may contain many posts, so duplicating the QImages here is deadly for the
// memory.
// ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default-video.png"));
//ui->warn_image_label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/status_unknown.png"));
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
//ui->editButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/pencil-edit-button.png"));
// ui->copyLinkButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/copy.png"));
// ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/down-arrow.png"));
// ui->readAndClearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/correct.png"));
// ui->clearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/exit2.png"));
setAttribute(Qt::WA_DeleteOnClose, true);
mInFill = false;
mCloseOnRead = false;
/* clear ui */
ui->titleLabel->setText(tr("Loading..."));
ui->titleLabel->setOpenExternalLinks(false); //To get linkActivated working
connect(ui->titleLabel, SIGNAL(linkActivated(QString)), this, SLOT(on_linkActivated(QString)));
ui->datetimelabel->clear();
// ui->newCommentLabel->hide();
// ui->commLabel->hide();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem()));
connect(ui->unsubscribeButton, SIGNAL(clicked()), this, SLOT(unsubscribe()));
//connect(ui->editButton, SIGNAL(clicked()), this, SLOT(edit(void)));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
// hide unsubscribe button not necessary
ui->unsubscribeButton->hide();
//ui->warn_image_label->hide();
//ui->warning_label->hide();
ui->titleLabel->setMinimumWidth(100);
ui->subjectLabel->setMinimumWidth(100);
//ui->warning_label->setMinimumWidth(100);
ui->feedFrame->setProperty("new", false);
ui->feedFrame->style()->unpolish(ui->feedFrame);
ui->feedFrame->style()->polish( ui->feedFrame);
ui->expandFrame->hide();
}
bool WireNotifyPostItem::setPost(const RsWirePulse &pulse, bool doFill)
{
if (groupId() != pulse.mMeta.mGroupId || messageId() != pulse.mMeta.mMsgId) {
std::cerr << "WireNotifyPostItem::setPost() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mPulse = pulse;
if (doFill) {
fill();
}
// updateItem();
return true;
}
void WireNotifyPostItem::expandFill(bool first)
{
GxsFeedItem::expandFill(first);
if (first) {
// fillExpandFrame();
}
}
QString WireNotifyPostItem::messageName()
{
if (!mPulse.mMeta.mMsgName.empty())
return QString::fromUtf8(mPulse.mMeta.mMsgName.c_str());
return tr("New Pulse");
}
void WireNotifyPostItem::loadMessage()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::loadMessage()";
std::cerr << std::endl;
#endif
mLoadingMessage = true;
RsGxsGroupId grpId = groupId();
RsGxsMessageId msgId = messageId();
RsThread::async([this, grpId, msgId]()
{
RsWirePulseSPtr pPulse;
if (!rsWire->getWirePulse(grpId, msgId, pPulse))
{
RsErr() << "WireNotifyPostItem::loadMessage() ERROR getting pulse" << std::endl;
mLoadingMessage = false;
deferred_update();
return;
}
if (pPulse)
{
#ifdef DEBUG_ITEM
std::cerr << (void*)this << ": Obtained post, with msgId = " << pPulse->mMeta.mMsgId << std::endl;
#endif
const RsWirePulse pulse(*pPulse);
RsQThreadUtils::postToObject([pulse, this]()
{
mPulse = pulse;
mLoadingMessage = false;
update(); // triggers paintEvent if needed
}, this);
}
else
{
RsQThreadUtils::postToObject([this]()
{
removeItem();
mLoadingMessage = false;
update();
}, this);
}
});
}
void WireNotifyPostItem::loadComment()
{
// TODO: implement Wire comment loading when Wire comments are supported
}
void WireNotifyPostItem::loadGroup()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyGroupItem::loadGroup()";
std::cerr << std::endl;
#endif
mLoadingGroup = true;
RsThread::async([this]()
{
// 1 - get group data
// std::vector<RsWireGroup> groups;
// std::list<std::shared_ptr<RsWireGroup>> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() };
std::vector<RsWireGroup> groups;
if(!rsWire->getGroups(groupIds,groups)) // would be better to call channel Summaries for a single group
{
RsErr() << "WireNotifyPostItem::loadGroup() ERROR getting data" << std::endl;
mLoadingGroup = false;
deferred_update();
return;
}
if (groups.size() != 1)
{
std::cerr << "WireNotifyPostItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
mLoadingGroup = false;
deferred_update();
return;
}
RsWireGroup group = groups[0];
RsQThreadUtils::postToObject( [group,this]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */
mGroup = group;
mGroupMeta = group.mMeta;
mLoadingGroup = false;
update(); // triggers paintEvent if needed
}, this );
});
}
QString WireNotifyPostItem::groupName()
{
return QString::fromUtf8(mGroupMeta.mGroupName.c_str());
}
void WireNotifyPostItem::doExpand(bool open)
{
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
if (open)
{
ui->expandFrame->show();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png")));
ui->expandButton->setToolTip(tr("Hide"));
// readToggled(false);
}
else
{
ui->expandFrame->hide();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png")));
ui->expandButton->setToolTip(tr("Expand"));
}
emit sizeChanged(this);
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
}
}
void WireNotifyPostItem::fill()
{
/* fill in */
// if (isLoading()) {
// /* Wait for all requests */
//return;
// }
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::fill()";
std::cerr << std::endl;
#endif
mInFill = true;
QString title;
QString msgText;
// Determine pulse type for display
QString pulseTypeStr;
if (mPulse.mPulseType & WIRE_PULSE_TYPE_LIKE) {
pulseTypeStr = tr("Like");
} else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPUBLISH) {
pulseTypeStr = tr("Republish");
} else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPLY) {
pulseTypeStr = tr("Reply");
} else {
pulseTypeStr = tr("Pulse");
}
if (mCloseOnRead && !IS_MSG_NEW(mPulse.mMeta.mMsgStatus)) {
removeItem();
}
msgText = pulseTypeStr + ": ";
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_WIRE, mPulse.mMeta.mGroupId, mPulse.mMeta.mMsgId, messageName());
msgText += msgLink.toHtml();
ui->subjectLabel->setText(msgText);
ui->pulseMessage->setText(QString::fromUtf8(mPulse.mPulseText.c_str()));
ui->datetimelabel->setText(DateTime::formatLongDateTime(mPulse.mRefPublishTs));
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
{
ui->unsubscribeButton->setEnabled(true);
}
else
{
ui->unsubscribeButton->setEnabled(false);
}
ui->readButton->hide();
ui->newLabel->hide();
ui->copyLinkButton->hide();
if (IS_MSG_NEW(mPulse.mMeta.mMsgStatus)) {
mCloseOnRead = true;
}
mInFill = false;
}
void WireNotifyPostItem::setReadStatus(bool isNew, bool isUnread)
{
if (isNew)
mPulse.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_NEW;
else
mPulse.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_NEW;
if (isUnread)
{
mPulse.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
whileBlocking(ui->readButton)->setChecked(true);
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
}
else
{
mPulse.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
whileBlocking(ui->readButton)->setChecked(false);
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png"));
}
//ui->newLabel->setVisible(isNew);
//ui->feedFrame->setProperty("new", isNew);
//ui->feedFrame->style()->unpolish(ui->feedFrame);
//ui->feedFrame->style()->polish( ui->feedFrame);
}
void WireNotifyPostItem::setGroup(const RsWireGroup &group)
{
ui->groupName->setText(QString::fromStdString(group.mMeta.mGroupName));
ui->groupName->setToolTip(QString::fromStdString(group.mMeta.mGroupName) + "@" + QString::fromStdString(group.mMeta.mAuthorId.toStdString()));
ui->groupName->hide();
QString title;
// Determine pulse type for title
QString pulseTypeStr;
if (mPulse.mPulseType & WIRE_PULSE_TYPE_LIKE) {
pulseTypeStr = tr("New Like");
} else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPUBLISH) {
pulseTypeStr = tr("New Republish");
} else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPLY) {
pulseTypeStr = tr("New Reply");
} else {
pulseTypeStr = tr("Wire Feed");
}
title = pulseTypeStr + ": ";
RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_WIRE, group.mMeta.mGroupId, groupName());
title += link.toHtml();
ui->titleLabel->setText(title);
if (group.mHeadshot.mData )
{
QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(
group.mHeadshot.mData,
group.mHeadshot.mSize,
pixmap,GxsIdDetails::ORIGINAL))
{
ui->logoLabel->setPixmap(pixmap);
}
}
else
{
// default.
QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png");
ui->logoLabel->setPixmap(pixmap);
}
}
/*********** SPECIFIC FUNCTIONS ***********************/
void WireNotifyPostItem::readAndClearItem()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::readAndClearItem()";
std::cerr << std::endl;
#endif
readToggled(false);
removeItem();
}
void WireNotifyPostItem::readToggled(bool /*checked*/)
{
if (mInFill) {
return;
}
mCloseOnRead = false;
RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId());
//rsWire->setMessageReadStatus(msgPair, isUnread());
//setReadStatus(false, checked); // Updated by events
}
void WireNotifyPostItem::on_linkActivated(QString link)
{
RetroShareLink rsLink(link);
if (rsLink.valid() ) {
QList<RetroShareLink> rsLinks;
rsLinks.append(rsLink);
RetroShareLink::process(rsLinks);
removeItem();
return;
}
}

View File

@ -0,0 +1,104 @@
/*******************************************************************************
* gui/feeds/WireNotifyPostItem.h *
* *
* Copyright (c) 2012, Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef WIRENOTIFYPOSTITEM_H
#define WIRENOTIFYPOSTITEM_H
#include <QMetaType>
#include <QWidget>
#include <retroshare/rswire.h>
#include "gui/feeds/GxsFeedItem.h"
#include "gui/feeds/GxsGroupFeedItem.h"
namespace Ui {
class WireNotifyPostItem;
}
class FeedHolder;
class SubFileItem;
class WireNotifyPostItem : public GxsFeedItem
{
Q_OBJECT
public:
WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
virtual ~WireNotifyPostItem();
uint64_t uniqueIdentifier() const override { return hash_64bits("WireNotifyPostItem " + messageId().toStdString()); }
bool setPost(const RsWirePulse& pulse, bool doFill = true);
void setGroup(const RsWireGroup &group);
bool isUnread() const ;
void setReadStatus(bool isNew, bool isUnread);
protected:
/* FeedItem */
virtual void doExpand(bool open);
virtual void expandFill(bool first);
virtual void paintEvent(QPaintEvent *) override;
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup() override;
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_WIRE; }
/* GxsFeedItem */
// virtual QString messageName();
virtual void loadMessage();
virtual void loadComment();
virtual QString messageName() override;
private slots:
/* default stuff */
//void toggle() override;
void readAndClearItem();
void readToggled(bool checked);
void on_linkActivated(QString link);
private:
void setup();
void fill();
private:
bool mInFill;
bool mCloseOnRead;
LoadingStatus mLoadingStatus;
bool mLoadingMessage;
bool mLoadingGroup;
bool mLoadingComment;
RsGroupMetaData mGroupMeta;
RsWirePulse mPulse;
RsWireGroup mGroup;
/** Qt Designer generated object */
Ui::WireNotifyPostItem *ui;
};
Q_DECLARE_METATYPE(RsWirePulse)
#endif // WIRENOTIFYPOSTITEM_H

View File

@ -0,0 +1,418 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WireNotifyPostItem</class>
<widget class="QWidget" name="WireNotifyPostItem">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>822</width>
<height>175</height>
</rect>
</property>
<layout class="QGridLayout" name="WireNotifyPostItem_GL">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="feedFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Shape::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="feedFrame_VL">
<item>
<layout class="QHBoxLayout" name="mainTopHLayout">
<item>
<layout class="QVBoxLayout" name="logo_VLayout">
<item>
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="mainRTopVLayout">
<item>
<layout class="QHBoxLayout" name="tilteHLayout">
<item>
<widget class="QLabel" name="groupName">
<property name="font">
<font>
<pointsize>12</pointsize>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Wire Subject</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="datetimelabel">
<property name="font">
<font>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">DateTime</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="newLabel">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="pulseMessage">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttonHLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QLabel" name="subjectLabel">
<property name="font">
<font>
<pointsize>11</pointsize>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="readButton">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Toggle Message Read Status</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="unsubscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Unsubscribe From Wire</string>
</property>
<property name="text">
<string>Unsubscribe</string>
</property>
</widget>
</item>
<item>
<spacer name="buttons_HSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Copy RetroShare Link</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Expand</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/down-arrow.png</normaloff>:/icons/png/down-arrow.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="readAndClearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Set as read and remove item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/correct.png</normaloff>:/icons/png/correct.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="expandFrame">
<layout class="QVBoxLayout" name="expandFrame_VL">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="msgFrame">
<property name="frameShape">
<enum>QFrame::Shape::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="msgFrame_VL">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="msgLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>6</number>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByKeyboard|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="feedFrame_VSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -72,7 +72,7 @@ static const uint32_t DELAY_BETWEEN_GROUP_STATISTICS_UPDATE = 120; // do not upd
/** Constructor */
GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl,const QString& settings_name, QWidget *parent,bool allow_dist_sync)
: MainPage(parent),mSettingsName(settings_name)
: MainPage(parent), mSettingsName(settings_name)
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::GxsGroupFrameDialog();
@ -173,7 +173,7 @@ void GxsGroupFrameDialog::initUi()
processSettings(true);
if (groupFrameSettingsType() != GroupFrameSettings::Nothing) {
connect(RsGUIEventManager::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
connect(RsGUIEventManager::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
settingsChanged();
}
@ -470,9 +470,7 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
uint32_t current_store_time = checkDelay(mInterface->getStoragePeriod(mGroupId))/86400 ;
uint32_t current_sync_time = checkDelay(mInterface->getSyncPeriod(mGroupId))/86400 ;
#ifdef DEBUG_GROUPFRAMEDIALOG
std::cerr << "Got sync=" << current_sync_time << ". store=" << current_store_time << std::endl;
#endif
QAction *actnn = NULL;
QMenu *ctxMenu2 = contextMnu.addMenu(tr("Synchronise posts of last...")) ;

View File

@ -27,6 +27,7 @@
#include "gui/RetroShareLink.h"
#include "gui/settings/rsharesettings.h"
#include "util/RsUserdata.h"
#include "GxsStatisticsProvider.h"
#include <inttypes.h>
@ -44,7 +45,7 @@ class UIStateHelper;
struct RsGxsCommentService;
class GxsCommentDialog;
class GxsGroupFrameDialog : public MainPage
class GxsGroupFrameDialog : public MainPage, public GxsStatisticsProvider
{
Q_OBJECT
@ -74,13 +75,13 @@ public:
GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, const QString& settings_name,QWidget *parent = 0,bool allow_dist_sync=false);
virtual ~GxsGroupFrameDialog();
bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId);
virtual bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId);
virtual QString getHelpString() const =0;
virtual void getGroupList(std::map<RsGxsGroupId,RsGroupMetaData> &groups) ;
void getServiceStatistics(GxsServiceStatistic& stats) const ;
void getServiceStatistics(GxsServiceStatistic& stats) const override;
static uint32_t checkDelay(uint32_t time_in_secs);
@ -99,17 +100,13 @@ protected:
virtual void checkRequestGroup(const RsGxsGroupId& /* grpId */) {} // overload this one in order to retrieve full group data when the group is browsed
void updateMessageSummaryList(RsGxsGroupId groupId);
void updateGroupStatistics(const RsGxsGroupId &groupId);
virtual const std::set<TurtleRequestId> getSearchRequests() const { return std::set<TurtleRequestId>(); } // overload this for subclasses that provide distant search
// These two need to be overloaded by subsclasses, possibly calling the blocking API, since they are used asynchroneously.
// This needs to be overloaded by subsclasses, possibly calling the blocking API, since it is used asynchroneously.
virtual bool getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo) =0;
virtual bool getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo) =0;
virtual bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) =0;
void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
void updateMessageSummaryListReal(RsGxsGroupId groupId);
void updateMessageSummaryListReal(RsGxsGroupId groupId);
private slots:
void todo();
@ -154,7 +151,6 @@ private slots:
private:
virtual QString text(TextType type) = 0;
virtual QString icon(IconType type) = 0;
virtual QString settingsGroupName() = 0;
virtual TurtleRequestId distantSearch(const QString& search_string) ;
virtual GxsGroupDialog *createNewGroupDialog() = 0;
@ -186,16 +182,31 @@ private:
// subscribe/unsubscribe ack.
GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
virtual GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
GxsMessageFrameWidget *createMessageWidget(const RsGxsGroupId &groupId);
GxsCommentDialog *commentWidget(const RsGxsMessageId &msgId);
protected:
void updateSearchResults(const TurtleRequestId &sid);
void updateSearchResults(); // update all searches
virtual void updateGroupStatistics(const RsGxsGroupId &groupId);
virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
bool mCountChildMsgs; // Count unread child messages?
// This needs to be overloaded by subclasses, possibly calling the blocking API, since it is used asynchronously.
virtual bool getGroupStatistics(const RsGxsGroupId& groupId, GxsGroupStatistic& stat) = 0;
QString mSettingsName;
RsGxsIfaceHelper *mInterface;
bool mDistSyncAllowed;
std::map<RsGxsGroupId,GxsGroupStatistic> mCachedGroupStats;
bool mShouldUpdateGroupStatistics;
std::set<RsGxsGroupId> mGroupStatisticsToUpdate;
bool mCountChildMsgs;
RsGxsGroupId mNavigatePendingGroupId;
RsGxsMessageId mNavigatePendingMsgId;
UIStateHelper *mStateHelper;
private:
GxsMessageFrameWidget *currentWidget() const;
@ -203,36 +214,26 @@ private:
bool mInitialized;
bool mInFill;
bool mDistSyncAllowed;
QString mSettingsName;
RsGxsGroupId mGroupId;
RsGxsIfaceHelper *mInterface;
QTreeWidgetItem *mYourGroups;
QTreeWidgetItem *mSubscribedGroups;
QTreeWidgetItem *mPopularGroups;
QTreeWidgetItem *mOtherGroups;
RsGxsGroupId mNavigatePendingGroupId;
RsGxsMessageId mNavigatePendingMsgId;
// Message summary list update
bool mShouldUpdateMessageSummaryList ; // whether we should update the counting for groups. This takes some CPU so we only do it when needed.
std::set<RsGxsGroupId> mGroupIdsSummaryToUpdate;
// GroupStatistics update
bool mShouldUpdateGroupStatistics;
rstime_t mLastGroupStatisticsUpdateTs;
std::set<RsGxsGroupId> mGroupStatisticsToUpdate;
UIStateHelper *mStateHelper;
/** Qt Designer generated object */
Ui::GxsGroupFrameDialog *ui;
std::map<RsGxsGroupId,RsGroupMetaData> mCachedGroupMetas;
std::map<RsGxsGroupId,GxsGroupStatistic> mCachedGroupStats;
std::map<uint32_t,QTreeWidgetItem*> mSearchGroupsItems ;
std::map<uint32_t,std::set<RsGxsGroupId> > mKnownGroups;

View File

@ -62,7 +62,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/konversation.png</pixmap>
<pixmap>:/images/konversation.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
@ -74,7 +74,6 @@
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>

View File

@ -0,0 +1,21 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxs/GxsStatisticsProvider.cpp *
* *
* Copyright 2012-2013 by Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "GxsStatisticsProvider.h"

View File

@ -0,0 +1,35 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxs/GxsStatisticsProvider.h *
* *
* Copyright 2012-2013 by Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef GXSSTATISTICSPROVIDER_H
#define GXSSTATISTICSPROVIDER_H
#include "retroshare/rsgxsifacetypes.h"
// Interface for GxsUserNotify to query service statistics.
class GxsStatisticsProvider
{
public:
virtual ~GxsStatisticsProvider() = default;
virtual void getServiceStatistics(GxsServiceStatistic& stats) const = 0;
};
#endif // GXSSTATISTICSPROVIDER_H

View File

@ -26,7 +26,7 @@
#define TOKEN_TYPE_STATISTICS 1
GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper */*ifaceImpl*/, const GxsGroupFrameDialog *g,QObject *parent) : UserNotify(parent), mGroupFrameDialog(g)
GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper */*ifaceImpl*/, const GxsStatisticsProvider *g,QObject *parent) : UserNotify(parent), mGxsStatisticsProvider(g)
{
mNewThreadMessageCount = 0;
mNewChildMessageCount = 0;
@ -42,7 +42,7 @@ void GxsUserNotify::startUpdate()
GxsServiceStatistic stats;
mGroupFrameDialog->getServiceStatistics(stats);
mGxsStatisticsProvider->getServiceStatistics(stats);
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information

View File

@ -23,7 +23,7 @@
#include <QObject>
#include "gui/common/UserNotify.h"
#include "gui/gxs/GxsGroupFrameDialog.h"
#include "gui/gxs/GxsStatisticsProvider.h"
class RsGxsIfaceHelper;
class RsGxsUpdateBroadcastBase;
@ -33,7 +33,7 @@ class GxsUserNotify : public UserNotify
Q_OBJECT
public:
GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual ~GxsUserNotify();
protected:
@ -46,7 +46,8 @@ protected:
bool mCountChildMsgs; // Count new child messages?
private:
const GxsGroupFrameDialog *mGroupFrameDialog;
const GxsStatisticsProvider *mGxsStatisticsProvider;
unsigned int mNewThreadMessageCount;
unsigned int mNewChildMessageCount;

View File

@ -71,7 +71,7 @@ private:
/* GxsGroupFrameDialog */
virtual QString text(TextType type) override;
virtual QString icon(IconType type) override;
virtual QString settingsGroupName() override { return "ChannelDialog"; }
virtual QString settingsGroupName() { return "ChannelDialog"; }
virtual GxsGroupDialog *createNewGroupDialog() override;
virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override;
virtual int shareKeyType() override;

View File

@ -23,7 +23,7 @@
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}

View File

@ -22,14 +22,13 @@
#define GXSCHANNELUSERNOTIFY_H
#include "gui/gxs/GxsUserNotify.h"
#include "gui/gxs/GxsGroupFrameDialog.h"
class GxsChannelUserNotify : public GxsUserNotify
{
Q_OBJECT
public:
explicit GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
explicit GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;

View File

@ -23,7 +23,7 @@
#include "GxsForumUserNotify.h"
#include "gui/MainWindow.h"
GxsForumUserNotify::GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsForumUserNotify::GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
mCountChildMsgs = true;

View File

@ -28,7 +28,7 @@ class GxsForumUserNotify : public GxsUserNotify
Q_OBJECT
public:
explicit GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
explicit GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;

View File

@ -53,7 +53,7 @@ private:
/* GxsGroupFrameDialog */
QString text(TextType type)override ;
QString icon(IconType type)override ;
QString settingsGroupName() override { return "ForumsDialog"; }
QString settingsGroupName() { return "ForumsDialog"; }
GxsGroupDialog *createNewGroupDialog() override;
GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override;

View File

@ -356,7 +356,8 @@
<file>icons/fullscreen-exit.png</file>
<file>icons/notification.png</file>
<file>icons/wire.png</file>
<file>icons/wire-circle.png</file>
<file>icons/png/wire-notify.png</file>
<file>icons/png/wire-circle.png</file>
<file>icons/folder-account.svg</file>
<file>icons/notification.svg</file>
<file>icons/groups/blue.svg</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -167,6 +167,10 @@ NotifyPage::NotifyPage(QWidget * parent, Qt::WindowFlags flags)
connect(ui.notify_Security, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags()));
connect(ui.notify_SecurityIp, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags()));
#ifdef RS_USE_WIRE
connect(ui.notify_Wire, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags()));
#endif
connect(ui.systray_ChatLobby, SIGNAL(toggled(bool)), this, SLOT(updateSystrayChatLobby()));
connect(ui.systray_GroupChat, SIGNAL(toggled(bool)), this, SLOT(updateSystrayGroupChat()));
@ -207,6 +211,11 @@ RsFeedTypeFlags NotifyPage::getNewsFlags()
if (ui.notify_SecurityIp->isChecked())
newsFlags |= RsFeedTypeFlags::RS_FEED_TYPE_SECURITY_IP;
#ifdef RS_USE_WIRE
if (ui.notify_Wire->isChecked())
newsFlags |= RsFeedTypeFlags::RS_FEED_TYPE_WIRE;
#endif
return newsFlags;
}
@ -312,8 +321,13 @@ void NotifyPage::load()
whileBlocking(ui.notify_Forums )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_FORUM));
whileBlocking(ui.notify_Posted )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_POSTED));
#if 0
whileBlocking(ui.notify_Blogs)->setChecked(newsflags & RS_FEED_TYPE_BLOG);
whileBlocking(ui.notify_Blogs)->setChecked(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_BLOG);
#endif
#ifdef RS_USE_WIRE
whileBlocking(ui.notify_Wire)->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_WIRE));
#endif
whileBlocking(ui.notify_Chat )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_CHAT));
whileBlocking(ui.notify_Messages )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_MSG));
whileBlocking(ui.notify_Chat )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_CHAT));

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>569</width>
<height>512</height>
<height>526</height>
</rect>
</property>
<layout class="QVBoxLayout" name="NotifyPageVLayout">
@ -86,6 +86,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="notify_Wire">
<property name="text">
<string>Wire</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="notify_Messages">
<property name="text">
@ -471,6 +478,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RSComboBox</class>
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>notify_Peers</tabstop>
<tabstop>notify_Channels</tabstop>
@ -495,13 +509,6 @@
<tabstop>systray_ChatLobby</tabstop>
<tabstop>pushButtonDisableAll</tabstop>
</tabstops>
<customwidgets>
<customwidget>
<class>RSComboBox</class>
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -143,6 +143,10 @@ void RshareSettings::initSettings()
RsNotifyPopupFlags defNotify = (RsNotifyPopupFlags::RS_POPUP_CONNECT | RsNotifyPopupFlags::RS_POPUP_MSG);
RsFeedTypeFlags defNewsFeed = (RsFeedTypeFlags::RS_FEED_TYPE_MSG | RsFeedTypeFlags::RS_FEED_TYPE_FILES | RsFeedTypeFlags::RS_FEED_TYPE_SECURITY | RsFeedTypeFlags::RS_FEED_TYPE_SECURITY_IP | RsFeedTypeFlags::RS_FEED_TYPE_CIRCLE | RsFeedTypeFlags::RS_FEED_TYPE_CHANNEL |RsFeedTypeFlags::RS_FEED_TYPE_FORUM | RsFeedTypeFlags::RS_FEED_TYPE_POSTED);
#ifdef RS_USE_WIRE
defNewsFeed = (defNewsFeed | RsFeedTypeFlags::RS_FEED_TYPE_WIRE);
#endif
setDefault(SETTING_NEWSFEED_FLAGS, (int)defNewsFeed);
setDefault(SETTING_CHAT_FLAGS, defChat);
setDefault(SETTING_NOTIFY_FLAGS, (int)defNotify);
@ -1114,6 +1118,10 @@ static QString groupFrameSettingsTypeToString(GroupFrameSettings::Type type)
return "Channel";
case GroupFrameSettings::Posted:
return "Posted";
#ifdef RS_USE_WIRE
case GroupFrameSettings::Wire:
return "Wire";
#endif
}
return "";

View File

@ -44,7 +44,7 @@ class QMainWindow;
class GroupFrameSettings
{
public:
enum Type { Nothing, Forum, Channel, Posted };
enum Type { Nothing, Forum, Channel, Posted, Wire };
public:
GroupFrameSettings()

View File

@ -117,7 +117,7 @@ CONFIG += gxscircles
## To enable unfinished services
#CONFIG += wikipoos
#CONFIG += gxsthewire
CONFIG += gxsthewire
#CONFIG += gxsphotoshare
DEFINES += RS_RELEASE_VERSION
@ -1228,7 +1228,10 @@ gxsthewire {
gui/TheWire/PulseReply.h \
gui/TheWire/PulseReplySeperator.h \
gui/TheWire/PulseMessage.h \
gui/TheWire/CustomFrame.h \
gui/TheWire/CustomFrame.h \
gui/TheWire/WireUserNotify.h \
gui/feeds/WireNotifyGroupItem.h \
gui/feeds/WireNotifyPostItem.h \
FORMS += gui/TheWire/WireDialog.ui \
gui/TheWire/WireGroupItem.ui \
@ -1239,7 +1242,9 @@ gxsthewire {
gui/TheWire/PulseReply.ui \
gui/TheWire/PulseReplySeperator.ui \
gui/TheWire/PulseMessage.ui \
gui/feeds/WireNotifyGroupItem.ui \
gui/feeds/WireNotifyPostItem.ui \
SOURCES += gui/TheWire/WireDialog.cpp \
gui/TheWire/WireGroupItem.cpp \
gui/TheWire/WireGroupDialog.cpp \
@ -1251,7 +1256,10 @@ gxsthewire {
gui/TheWire/PulseReply.cpp \
gui/TheWire/PulseReplySeperator.cpp \
gui/TheWire/PulseMessage.cpp \
gui/TheWire/CustomFrame.cpp \
gui/TheWire/CustomFrame.cpp \
gui/TheWire/WireUserNotify.cpp \
gui/feeds/WireNotifyGroupItem.cpp \
gui/feeds/WireNotifyPostItem.cpp \
RESOURCES += gui/TheWire/TheWire_images.qrc
}
@ -1447,7 +1455,7 @@ gxsgui {
# gui/gxs/GxsFeedWidget.h \
util/TokenQueue.h \
util/RsGxsUpdateBroadcast.h \
gui/gxs/GxsStatisticsProvider.h \
# gui/gxs/GxsMsgDialog.h \
FORMS += gui/gxs/GxsGroupDialog.ui \
@ -1478,7 +1486,7 @@ gxsgui {
# gui/gxs/GxsFeedWidget.cpp \
util/TokenQueue.cpp \
util/RsGxsUpdateBroadcast.cpp \
gui/gxs/GxsStatisticsProvider.cpp \
# gui/gxs/GxsMsgDialog.cpp \

View File

@ -33,6 +33,9 @@
CONFIG *= retroshare_gui
no_retroshare_gui:CONFIG -= retroshare_gui
# Enable TheWire - RsWire - is intended to be a Twitter clone
CONFIG *= gxsthewire
# Enable GXS distant syncronization
CONFIG *= gxsdistsync