void ChatForm::onFileRecvRequest(ToxFile file) { if (file.friendId != f->getFriendID()) return; Widget::getInstance()->newFriendMessageAlert(file.friendId); QString name; ToxId friendId = f->getToxId(); if (friendId != previousId) { name = f->getDisplayedName(); previousId = friendId; } ChatMessage::Ptr msg = ChatMessage::createFileTransferMessage(name, file, false, QDateTime::currentDateTime()); insertChatMessage(msg); ChatLineContentProxy* proxy = static_cast<ChatLineContentProxy*>(msg->getContent(1)); assert(proxy->getWidgetType() == ChatLineContentProxy::FileTransferWidgetType); FileTransferWidget* tfWidget = static_cast<FileTransferWidget*>(proxy->getWidget()); // there is auto-accept for that conact if (!Settings::getInstance().getAutoAcceptDir(f->getToxId()).isEmpty()) { tfWidget->autoAcceptTransfer(Settings::getInstance().getAutoAcceptDir(f->getToxId())); } else if (Settings::getInstance().getAutoSaveEnabled()) { //global autosave to global directory tfWidget->autoAcceptTransfer(Settings::getInstance().getGlobalAutoAcceptDir()); } Widget::getInstance()->updateFriendActivity(f); }
ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString& rawMessage, SystemMessageType type, const QDateTime& date) { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); QString text = rawMessage.toHtmlEscaped(); QString img; switch (type) { case INFO: img = ":/ui/chatArea/info.svg"; break; case ERROR: img = ":/ui/chatArea/error.svg"; break; case TYPING: img = ":/ui/chatArea/typing.svg"; break; } QFont baseFont = Settings::getInstance().getChatMessageFont(); msg->addColumn(new Image(QSize(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text("<b>" + text + "</b>", baseFont, false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), baseFont), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; }
void ChatForm::onFileRecvRequest(ToxFile file) { if (file.friendId != f->getFriendID()) return; Widget* w = Widget::getInstance(); if (!w->isFriendWidgetCurActiveWidget(f)|| w->isMinimized() || !w->isActiveWindow()) { w->newMessageAlert(f->getFriendWidget()); f->setEventFlag(true); f->getFriendWidget()->updateStatusLight(); } QString name; ToxId friendId = f->getToxId(); if (friendId != previousId) { name = f->getDisplayedName(); previousId = friendId; } ChatMessage::Ptr msg = ChatMessage::createFileTransferMessage(name, file, false, QDateTime::currentDateTime()); insertChatMessage(msg); if (!Settings::getInstance().getAutoAcceptDir(f->getToxId()).isEmpty() || Settings::getInstance().getAutoSaveEnabled()) { ChatLineContentProxy* proxy = static_cast<ChatLineContentProxy*>(msg->getContent(1)); assert(proxy->getWidgetType() == ChatLineContentProxy::FileTransferWidgetType); FileTransferWidget* tfWidget = static_cast<FileTransferWidget*>(proxy->getWidget()); tfWidget->autoAcceptTransfer(Settings::getInstance().getAutoAcceptDir(f->getToxId())); } }
ChatMessage::Ptr ChatMessage::createBusyNotification() { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); // TODO: Bigger font msg->addColumn(new Text(QObject::tr("Resizing"), Style::getFont(Style::ExtraBig), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); return msg; }
ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date) { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 320, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; }
ChatMessage::Ptr ChatMessage::createBusyNotification() { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); QFont baseFont = Settings::getInstance().getChatMessageFont(); baseFont.setPixelSize(baseFont.pixelSize() + 2); baseFont.setBold(true); msg->addColumn(new Text(QObject::tr("Resizing"), baseFont, false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); return msg; }
void ChatForm::SendMessageStr(QString msg) { if (msg.isEmpty()) return; bool isAction = msg.startsWith(ACTION_PREFIX, Qt::CaseInsensitive); if (isAction) msg.remove(0, ACTION_PREFIX.length()); QList<CString> splittedMsg = Core::splitMessage(msg, TOX_MAX_MESSAGE_LENGTH); QDateTime timestamp = QDateTime::currentDateTime(); for (CString& c_msg : splittedMsg) { QString qt_msg = CString::toString(c_msg.data(), c_msg.size()); QString qt_msg_hist = qt_msg; if (isAction) qt_msg_hist = ACTION_PREFIX + qt_msg; bool status = !Settings::getInstance().getFauxOfflineMessaging(); ChatMessage::Ptr ma = addSelfMessage(qt_msg, isAction, timestamp, false); int rec; if (isAction) rec = Core::getInstance()->sendAction(f->getFriendID(), qt_msg); else rec = Core::getInstance()->sendMessage(f->getFriendID(), qt_msg); Profile* profile = Nexus::getProfile(); if (profile->isHistoryEnabled()) { auto* offMsgEngine = getOfflineMsgEngine(); profile->getHistory()->addNewMessage(f->getToxId().publicKey, qt_msg_hist, Core::getInstance()->getSelfId().publicKey, timestamp, status, Core::getInstance()->getUsername(), [offMsgEngine,rec,ma](int64_t id) { offMsgEngine->registerReceipt(rec, id, ma); }); } else { // TODO: Make faux-offline messaging work partially with the history disabled ma->markAsSent(QDateTime::currentDateTime()); } msgEdit->setLastMessage(msg); //set last message only when sending it Widget::getInstance()->updateFriendActivity(f); } }
ChatMessage::Ptr ChatMessage::createTypingNotification() { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); // Note: "[user]..." is just a placeholder. The actual text is set in ChatForm::setFriendTyping() // // FIXME: Due to circumstances, placeholder is being used in a case where // user received typing notifications constantly since contact came online. // This causes "[user]..." to be displayed in place of user nick, as long // as user will keep typing. Issue #1280 msg->addColumn(new NotificationIcon(QSize(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text("[user]...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); return msg; }
ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date) { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); QFont baseFont = Settings::getInstance().getChatMessageFont(); QFont authorFont = baseFont; if (isMe) authorFont.setBold(true); msg->addColumn(new Text(sender, authorFont, true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 320, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), baseFont), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; }
ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QString &rawMessage, MessageType type, bool isMe, const QDateTime &date) { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); QString text = rawMessage.toHtmlEscaped(); QString senderText = sender; const QColor actionColor = QColor("#1818FF"); // has to match the color in innerStyle.css (div.action) //smileys if (Settings::getInstance().getUseEmoticons()) text = SmileyPack::getInstance().smileyfied(text); //quotes (green text) text = detectQuotes(detectAnchors(text), type); //text styling if (Settings::getInstance().getStylePreference() != Settings::StyleType::NONE) text = detectStyle(text); switch(type) { case NORMAL: text = wrapDiv(text, "msg"); break; case ACTION: senderText = "*"; text = wrapDiv(QString("%1 %2").arg(sender.toHtmlEscaped(), text), "action"); msg->setAsAction(); break; case ALERT: text = wrapDiv(text, "alert"); break; } // Note: Eliding cannot be enabled for RichText items. (QTBUG-17207) QFont baseFont = Settings::getInstance().getChatMessageFont(); QFont authorFont = baseFont; if (isMe) authorFont.setBold(true); msg->addColumn(new Text(senderText, authorFont, true, sender, type == ACTION ? actionColor : Qt::black), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, baseFont, false, ((type == ACTION) && isMe) ? QString("%1 %2").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 360.0/1.6), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if (!date.isNull()) msg->markAsSent(date); return msg; }
void ChatForm::loadHistory(QDateTime since, bool processUndelivered) { QDateTime now = historyBaselineDate.addMSecs(-1); if (since > now) return; if (!earliestMessage.isNull()) { if (earliestMessage < since) return; if (earliestMessage < now) { now = earliestMessage; now = now.addMSecs(-1); } } auto msgs = HistoryKeeper::getInstance()->getChatHistory(HistoryKeeper::ctSingle, f->getToxID().publicKey, since, now); ToxId storedPrevId = previousId; ToxId prevId; QList<ChatLine::Ptr> historyMessages; QDate lastDate(1,0,0); for (const auto &it : msgs) { // Show the date every new day QDateTime msgDateTime = it.timestamp.toLocalTime(); QDate msgDate = msgDateTime.date(); if (msgDate > lastDate) { lastDate = msgDate; historyMessages.append(ChatMessage::createChatInfoMessage(msgDate.toString(Settings::getInstance().getDateFormat()), ChatMessage::INFO, QDateTime())); } // Show each messages ToxId authorId = ToxId(it.sender); QString authorStr = authorId.isActiveProfile() ? Core::getInstance()->getUsername() : resolveToxID(authorId); bool isAction = it.message.startsWith("/me ", Qt::CaseInsensitive); ChatMessage::Ptr msg = ChatMessage::createChatMessage(authorStr, isAction ? it.message.right(it.message.length() - 4) : it.message, isAction ? ChatMessage::ACTION : ChatMessage::NORMAL, authorId.isActiveProfile(), QDateTime()); if (!isAction && (prevId == authorId) && (prevMsgDateTime.secsTo(msgDateTime) < getChatLog()->repNameAfter) ) msg->hideSender(); prevId = authorId; prevMsgDateTime = msgDateTime; if (it.isSent || !authorId.isActiveProfile()) { msg->markAsSent(msgDateTime); } else { if (processUndelivered) { int rec; if (!isAction) rec = Core::getInstance()->sendMessage(f->getFriendID(), msg->toString()); else rec = Core::getInstance()->sendAction(f->getFriendID(), msg->toString()); getOfflineMsgEngine()->registerReceipt(rec, it.id, msg); } } historyMessages.append(msg); } previousId = storedPrevId; int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); earliestMessage = since; chatWidget->insertChatlineOnTop(historyMessages); savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; chatWidget->verticalScrollBar()->setValue(savedSliderPos); }