void ChatHandler::tick() { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ // first fetch lobbies std::vector<Lobby> lobbies; std::list<ChatLobbyId> subscribed_ids; mRsMsgs->getChatLobbyList(subscribed_ids); for(std::list<ChatLobbyId>::iterator lit = subscribed_ids.begin(); lit != subscribed_ids.end(); ++lit) { ChatLobbyInfo info; if(mRsMsgs->getChatLobbyInfo(*lit,info)) { Lobby l; l.id = *lit; l.name = info.lobby_name; l.topic = info.lobby_topic; l.subscribed = true; l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC); l.is_broadcast = false; l.gxs_id = info.gxs_id; lobbies.push_back(l); } } ChatId id = ChatId::makeBroadcastId(); { Lobby l; l.id = id.toLobbyId(); l.name = "BroadCast"; l.topic = "Retroshare broadcast chat: messages are sent to all connected friends."; l.subscribed = true; l.auto_subscribe = false; l.is_private = false; l.is_broadcast = true; l.gxs_id = id.toGxsId(); lobbies.push_back(l); } std::vector<VisibleChatLobbyRecord> unsubscribed_lobbies; mRsMsgs->getListOfNearbyChatLobbies(unsubscribed_lobbies); for(std::vector<VisibleChatLobbyRecord>::iterator vit = unsubscribed_lobbies.begin(); vit != unsubscribed_lobbies.end(); ++vit) { const VisibleChatLobbyRecord& info = *vit; if(std::find(subscribed_ids.begin(), subscribed_ids.end(), info.lobby_id) == subscribed_ids.end()) { Lobby l; l.id = info.lobby_id; l.name = info.lobby_name; l.topic = info.lobby_topic; l.subscribed = false; l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC); l.is_broadcast = false; l.gxs_id = RsGxsId(); lobbies.push_back(l); } } // process new messages bool changed = false; bool lobby_unread_count_changed = false; std::vector<std::list<ChatMessage>::iterator> done; std::vector<RsPeerId> peers_changed; bool gxs_id_failed = false; // to prevent asking for multiple failing gxs ids in one tick, to not flush the cache for(std::list<ChatMessage>::iterator lit = mRawMsgs.begin(); lit != mRawMsgs.end(); ++lit) { ChatMessage& msg = *lit; std::string author_id; std::string author_name; if(msg.chat_id.isBroadcast()) { author_id = msg.broadcast_peer_id.toStdString(); author_name = mRsPeers->getPeerName(msg.broadcast_peer_id); } else if(msg.chat_id.isGxsId()) { author_id = msg.chat_id.toGxsId().toStdString(); RsIdentityDetails details; if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details)) { author_name = details.mNickname; } else { gxs_id_failed = true; continue; } } else if(msg.chat_id.isLobbyId()) { author_id = msg.lobby_peer_gxs_id.toStdString(); RsIdentityDetails details; if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.lobby_peer_gxs_id, details)) { author_name = details.mNickname; lobby_unread_count_changed = true; } else { gxs_id_failed = true; continue; } } else if(msg.chat_id.isPeerId()) { RsPeerId id; if(msg.incoming) id = msg.chat_id.toPeerId(); else id = mRsPeers->getOwnId(); author_id = id.toStdString(); author_name = mRsPeers->getPeerName(id); if(std::find(peers_changed.begin(), peers_changed.end(), msg.chat_id.toPeerId()) == peers_changed.end()) peers_changed.push_back(msg.chat_id.toPeerId()); } else { std::cerr << "Error in ChatHandler::tick(): unhandled chat_id=" << msg.chat_id.toStdString() << std::endl; // remove from queue, so msgs with wrong ids to not pile up done.push_back(lit); continue; } if(mChatInfo.find(msg.chat_id) == mChatInfo.end()) { ChatInfo info; info.is_broadcast = msg.chat_id.isBroadcast(); info.is_gxs_id = msg.chat_id.isGxsId(); info.is_lobby = msg.chat_id.isLobbyId(); info.is_peer = msg.chat_id.isPeerId(); if(msg.chat_id.isLobbyId()) { for(std::vector<Lobby>::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) { if(vit->id == msg.chat_id.toLobbyId()) info.remote_author_name = vit->name; } } else if(msg.chat_id.isGxsId()) { RsIdentityDetails details; if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details)) { info.remote_author_id = msg.chat_id.toGxsId().toStdString(); info.remote_author_name = details.mNickname; } else { gxs_id_failed = true; continue; } } else if(msg.chat_id.isPeerId()) { info.remote_author_id = msg.chat_id.toPeerId().toStdString(); info.remote_author_name = mRsPeers->getPeerName(msg.chat_id.toPeerId()); } mChatInfo[msg.chat_id] = info; } Msg m; m.read = !msg.incoming; m.incoming = msg.incoming; m.was_send = msg.online; m.author_id = author_id; m.author_name = author_name; // remove html tags from chat message // extract links form href getPlainText(msg.msg, m.msg, m.links); m.recv_time = msg.recvTime; m.send_time = msg.sendTime; m.id = RSRandom::random_u32(); mMsgs[msg.chat_id].push_back(m); done.push_back(lit); changed = true; } for(std::vector<std::list<ChatMessage>::iterator>::iterator vit = done.begin(); vit != done.end(); ++vit) mRawMsgs.erase(*vit); // send changes if(changed) { mStateTokenServer->replaceToken(mMsgStateToken); mStateTokenServer->replaceToken(mUnreadMsgsStateToken); } for(std::vector<RsPeerId>::iterator vit = peers_changed.begin(); vit != peers_changed.end(); ++vit) { const std::list<Msg>& msgs = mMsgs[ChatId(*vit)]; uint32_t count = 0; for(std::list<Msg>::const_iterator lit = msgs.begin(); lit != msgs.end(); ++lit) if(!lit->read) count++; if(mUnreadMsgNotify) mUnreadMsgNotify->notifyUnreadMsgCountChanged(*vit, count); } std::sort(lobbies.begin(), lobbies.end(), &compare_lobby_id); if(lobby_unread_count_changed || mLobbies != lobbies) { mStateTokenServer->replaceToken(mLobbiesStateToken); mLobbies = lobbies; } }
PaintChatWindow::PaintChatWindow(QWidget *parent, ChatId chatId, ChatWidget *chatWidget) : QMainWindow(parent), chatId(chatId), chatType(ChatWidget::CHATTYPE_UNKNOWN), chatWidget(chatWidget), ui(new Ui::PaintChatWindow) { ui->setupUi(this); connect(ui->paintWidget,SIGNAL(haveUpdate()),SLOT(on_haveUpdate())); connect(ui->penWidthSpinBox,SIGNAL(valueChanged(int)),this,SLOT(penChanged())); ui->pushButton1px->setChecked(true); ui->pushButtonPen->setChecked(true); ui->paintWidget->color=Qt::black; ui->paintWidget->penWidth=1; timer=new QTimer(this); connect(timer,SIGNAL(timeout()),SLOT(on_timer())); timer->start(500); QIcon icon ; icon.addPixmap(QPixmap(":/images/colors.png")); setWindowIcon(icon); QPixmap pix(24, 24); pix.fill(currentColor); ui->pushButtonPrimaryColor->setIcon(pix); chatType = chatWidget->chatType(); // Disabled // if(chatType == ChatWidget::CHATTYPE_PRIVATE) // { // ui->label->setText(QString::fromStdString(std::string("Paintchat with ")+rsPeers->getPeerName(peerId))); // setWindowTitle(QString::fromStdString(rsPeers->getPeerName(peerId)+" - PaintChat")); // ImageResource res; // res.fromQImage(ui->paintWidget->getImage()); // paintChatService->init(peerId,res); // ui->progressBar->hide(); // } if(chatType == ChatWidget::CHATTYPE_LOBBY) { ui->progressBar->setRange(0,100); ui->progressBar->setValue(0); ChatLobbyId id; id = chatId.toLobbyId(); std::string nick, lobby; RsGxsId gxsid; RsIdentityDetails details; rsMsgs->getIdentityForChatLobby(id, gxsid); for(int i=0;i<3;++i) if(rsIdentity->getIdDetails(gxsid,details)) break ; else usleep(1000*300) ; nick = details.mNickname; ChatLobbyInfo info; rsMsgs->getChatLobbyInfo(id, info); lobby = info.lobby_name; std::string label = nick + "@" + lobby; ui->label->setText(QString::fromStdString(label)); setWindowTitle(QString::fromStdString(label + " - PaintChat")); } ui->lblWarning->setVisible(false); }