aboutsummaryrefslogtreecommitdiff
path: root/src/MessageBoard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MessageBoard.cpp')
-rw-r--r--src/MessageBoard.cpp180
1 files changed, 107 insertions, 73 deletions
diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp
index 4366d9b..d058f82 100644
--- a/src/MessageBoard.cpp
+++ b/src/MessageBoard.cpp
@@ -1,21 +1,24 @@
#include "../include/MessageBoard.hpp"
#include "../include/Settings.hpp"
#include "../include/ResourceCache.hpp"
-#include "../include/Gif.hpp"
-#include "../include/ChannelSidePanel.hpp"
+#include "../include/RoomSidePanel.hpp"
#include "../include/UsersSidePanel.hpp"
-#include "../include/ChannelTopPanel.hpp"
+#include "../include/RoomTopPanel.hpp"
#include "../include/Chatbar.hpp"
#include "../include/ColorScheme.hpp"
+#include "../include/StaticImage.hpp"
+#include "../include/Gif.hpp"
#include "../include/Theme.hpp"
#include "../include/GlobalContextMenu.hpp"
-#include "../include/Channel.hpp"
#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Window/Mouse.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/Text.hpp>
+#include <dchat/Cache.hpp>
+#include <dchat/Room.hpp>
+#include <dchat/User.hpp>
#include <cmath>
using namespace std;
@@ -42,8 +45,8 @@ namespace dchat
// Merge messages from same user that are sent within one minute
const int MERGE_TEXT_TIMESTAMP_DIFF_SEC = 60;
- MessageBoard::MessageBoard(Channel *_channel) :
- channel(_channel),
+ MessageBoard::MessageBoard(std::shared_ptr<Room> _room) :
+ room(_room),
scroll(0.0),
scrollSpeed(0.0),
totalHeight(0.0),
@@ -53,10 +56,16 @@ namespace dchat
{
scrollbar.backgroundColor = sf::Color(49, 52, 57);
scrollbar.scrollColor = sf::Color(37, 39, 44);
+
+ offlineUser = make_shared<User>(odhtdb::Signature::PublicKey());
+ offlineUser->nickname = "You";
+ systemUser = make_shared<User>(odhtdb::Signature::PublicKey());
+ systemUser->nickname = "System";
}
MessageBoard::~MessageBoard()
{
+ // TODO: Re-add
for(Message *message : messages)
{
delete message;
@@ -68,7 +77,7 @@ namespace dchat
{
for(usize i = 0; i < messages.size(); ++i)
{
- if(message->timestampSeconds < messages[i]->timestampSeconds)
+ if(message->roomMessage->timestampSeconds < messages[i]->roomMessage->timestampSeconds)
return i;
}
return messages.size();
@@ -80,38 +89,41 @@ namespace dchat
// throw std::runtime_error("Failed to create render target for message board!");
dirty = true;
}
-
- bool MessageBoard::addMessage(Message *message, const odhtdb::Hash &id)
+
+ bool MessageBoard::addMessage(Message *message)
{
lock_guard<mutex> lock(messageProcessMutex);
- bool emptyHash = id.isEmpty();
- if(!emptyHash && messageIdMap.find(id) != messageIdMap.end())
+ bool emptyHash = message->roomMessage->id.isEmpty();
+ if(!emptyHash && messageIdMap.find(message->roomMessage->id) != messageIdMap.end())
{
delete message;
return false;
}
+
auto positionToAddMessage = findPositionToInsertMessageByTimestamp(message);
if(positionToAddMessage == messages.size())
scrollToBottom = true;
+
messages.insert(messages.begin() + positionToAddMessage, message);
- message->id = id;
+
if(!emptyHash)
- messageIdMap[id] = message;
+ messageIdMap[message->roomMessage->id] = message;
+
dirty = true;
return true;
}
-
+
void MessageBoard::deleteMessage(const odhtdb::Hash &id, const odhtdb::Signature::PublicKey &requestedByUser)
{
lock_guard<mutex> lock(messageProcessMutex);
auto it = messageIdMap.find(id);
if(it == messageIdMap.end()) return;
- if(it->second->user->isOnlineUser())
+ if(it->second->onlineUser)
{
- auto onlineUser = static_cast<const OnlineUser*>(it->second->user);
- if(onlineUser->getPublicKey() != requestedByUser)
+ const auto &publicKey = it->second->roomMessage->creator->publicKey;
+ if(publicKey != requestedByUser)
{
- fprintf(stderr, "Warning: user %s requested to delete a message owned by user %s, ignoring request\n", requestedByUser.toString().c_str(), onlineUser->getPublicKey().toString().c_str());
+ fprintf(stderr, "Warning: user %s requested to delete a message owned by user %s, ignoring request\n", requestedByUser.toString().c_str(), publicKey.toString().c_str());
return;
}
}
@@ -128,9 +140,33 @@ namespace dchat
break;
}
}
+
+ dirty = true;
+ }
+
+ void MessageBoard::addOfflineUserMessage(std::string msg, bool plainText)
+ {
+ auto roomMessage = make_shared<RoomMessage>();
+ roomMessage->creator = offlineUser;
+ roomMessage->timestampSeconds = time(NULL);
+ roomMessage->text = move(msg);
+ Message *message = new Message(roomMessage, plainText);
+ message->onlineUser = false;
+ addMessage(message);
+ }
+
+ void MessageBoard::addSystemUserMessage(std::string msg, bool plainText)
+ {
+ auto roomMessage = make_shared<RoomMessage>();
+ roomMessage->creator = systemUser;
+ roomMessage->timestampSeconds = time(NULL);
+ roomMessage->text = move(msg);
+ Message *message = new Message(roomMessage, plainText);
+ message->onlineUser = false;
+ addMessage(message);
}
- void MessageBoard::drawDefault(sf::RenderWindow &window, Cache &cache)
+ void MessageBoard::drawDefault(sf::RenderWindow &window, Cache *cache)
{
const float LINE_SPACING = 5.0f * Settings::getScaling();
const float MESSAGE_PADDING_TOP = 25.0f;
@@ -149,7 +185,7 @@ namespace dchat
sf::Shader *circleShader = ResourceCache::getShader("shaders/circleMask.glsl", sf::Shader::Fragment);
- sf::Vector2<double> position(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling(), ChannelTopPanel::getHeight() + PADDING_TOP);
+ sf::Vector2<double> position(RoomSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling(), RoomTopPanel::getHeight() + PADDING_TOP);
double startHeight = position.y;
position.y += scroll;
@@ -163,15 +199,19 @@ namespace dchat
bool mergeTextWithPrev = false;
if(i > 0)
{
- Message *prevMessage = messages[i - 1];
- mergeTextWithPrev = prevMessage->user == message->user && (message->timestampSeconds == 0 || message->timestampSeconds - prevMessage->timestampSeconds <= MERGE_TEXT_TIMESTAMP_DIFF_SEC);
+ const Message *prevMessage = messages[i - 1];
+ mergeTextWithPrev = prevMessage->roomMessage->creator == message->roomMessage->creator &&
+ (message->roomMessage->timestampSeconds == 0 ||
+ message->roomMessage->timestampSeconds - prevMessage->roomMessage->timestampSeconds <= MERGE_TEXT_TIMESTAMP_DIFF_SEC);
}
bool mergeTextWithNext = false;
if(i < numMessages - 1)
{
- Message *nextMessage = messages[i + 1];
- mergeTextWithNext = nextMessage->user == message->user && (nextMessage->timestampSeconds == 0 || nextMessage->timestampSeconds - message->timestampSeconds <= MERGE_TEXT_TIMESTAMP_DIFF_SEC);
+ const Message *nextMessage = messages[i + 1];
+ mergeTextWithNext = nextMessage->roomMessage->creator == message->roomMessage->creator &&
+ (nextMessage->roomMessage->timestampSeconds == 0 ||
+ nextMessage->roomMessage->timestampSeconds - message->roomMessage->timestampSeconds <= MERGE_TEXT_TIMESTAMP_DIFF_SEC);
}
bool visible = false;
@@ -185,23 +225,24 @@ namespace dchat
{
visible = true;
string usernameStr;
- if(message->user->type == User::Type::ONLINE_DISCORD_USER)
- {
- usernameStr = "(Discord) ";
- usernameStr += message->user->getName();
- }
- else
- {
- usernameStr = message->user->getName();
- }
+ // TODO: Add bridge user
+ // if(message->creator->type == User::Type::ONLINE_DISCORD_USER)
+ // {
+ // usernameStr = "(Discord) ";
+ // usernameStr += message->user->getName();
+ // }
+ // else
+ // {
+ usernameStr = message->roomMessage->creator->nickname;
+ //}
sf::Text usernameText(sf::String::fromUtf8(usernameStr.begin(), usernameStr.end()), *usernameFont, usernameTextCharacterSize);
usernameText.setFillColor(sf::Color(15, 192, 252));
usernameText.setPosition(sf::Vector2f(floor(startX + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y)));
window.draw(usernameText);
- if(message->timestampSeconds)
+ if(message->roomMessage->timestampSeconds)
{
- time_t time = (time_t)message->timestampSeconds;
+ time_t time = (time_t)message->roomMessage->timestampSeconds;
struct tm *localTimePtr = localtime(&time);
char date[30];
strftime(date, sizeof(date), "%Y-%m-%d at %T", localTimePtr);
@@ -213,27 +254,31 @@ namespace dchat
}
// Max avatar size = 1mb
- const ContentByUrlResult avatarResult = cache.getContentByUrl(message->user->avatarUrl, 1024 * 1024);
+ const ContentByUrlResult avatarResult = cache->getContentByUrl(message->roomMessage->creator->avatarUrl, 1024 * 1024);
if(avatarResult.type == ContentByUrlResult::Type::CACHED)
{
circleShader->setUniform("texture", sf::Shader::CurrentTexture);
- if(avatarResult.cachedType == ContentByUrlResult::CachedType::TEXTURE)
+ if(avatarResult.cachedType == ContentByUrlResult::CachedType::STATIC_IMAGE)
{
+ auto *staticImage = static_cast<SfmlStaticImage*>(avatarResult.staticImage);
// TODO: Store this sprite somewhere, might not be efficient to create a new sprite object every frame
- sf::Sprite sprite(*avatarResult.texture);
- auto textureSize = avatarResult.texture->getSize();
+ sf::Sprite sprite(staticImage->texture);
+ auto textureSize = staticImage->texture.getSize();
sprite.setPosition(sf::Vector2f(startX, floor(position.y)));
sprite.setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)textureSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)textureSize.y));
window.draw(sprite, circleShader);
}
else if(avatarResult.cachedType == ContentByUrlResult::CachedType::GIF)
{
- auto gifSize = avatarResult.gif->getSize();
- avatarResult.gif->setPosition(sf::Vector2f(startX, floor(position.y)));
- avatarResult.gif->setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.y));
- avatarResult.gif->setColor(sf::Color::White);
- avatarResult.gif->draw(window, circleShader);
+ auto *gif = static_cast<SfmlGif*>(avatarResult.gif);
+ gif->update();
+ auto gifSize = gif->getSize();
+ sf::Sprite sprite(gif->texture);
+ sprite.setPosition(sf::Vector2f(startX, floor(position.y)));
+ sprite.setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.y));
+ sprite.setColor(sf::Color::White);
+ window.draw(sprite, circleShader);
}
}
else
@@ -280,7 +325,7 @@ namespace dchat
totalHeight = (position.y - scroll) - startHeight;
}
- void MessageBoard::drawSimple(sf::RenderWindow &window, Cache &cache)
+ void MessageBoard::drawSimple(sf::RenderWindow &window, Cache *cache)
{
const float LINE_SPACING = 20.0f * Settings::getScaling();
const float MESSAGE_PADDING_TOP = 0.0f;
@@ -295,7 +340,7 @@ namespace dchat
const int timestampTextCharacterSize = 15 * Settings::getScaling();
const float timestampTextHeight = timestampFont->getLineSpacing(timestampTextCharacterSize);
- sf::Vector2<double> position(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling() + usernameMaxWidth, ChannelTopPanel::getHeight() + PADDING_TOP);
+ sf::Vector2<double> position(RoomSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling() + usernameMaxWidth, RoomTopPanel::getHeight() + PADDING_TOP);
double startHeight = position.y;
position.y += scroll;
usize numMessages = messages.size();
@@ -305,16 +350,16 @@ namespace dchat
position.y += (MESSAGE_PADDING_TOP * Settings::getScaling());
if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y)
{
- sf::String usernameTextStr = sf::String::fromUtf8(message->user->getName().begin(), message->user->getName().end());
+ sf::String usernameTextStr = sf::String::fromUtf8(message->roomMessage->creator->nickname.begin(), message->roomMessage->creator->nickname.end());
usernameTextStr += " - ";
sf::Text usernameText(usernameTextStr, *usernameFont, usernameTextCharacterSize);
usernameText.setFillColor(sf::Color(15, 192, 252));
usernameText.setPosition(sf::Vector2f(floor(position.x - usernameText.getLocalBounds().width), floor(position.y)));
window.draw(usernameText);
- if(message->timestampSeconds)
+ if(message->roomMessage->timestampSeconds)
{
- time_t time = (time_t)message->timestampSeconds;
+ time_t time = (time_t)message->roomMessage->timestampSeconds;
struct tm *localTimePtr = localtime(&time);
char date[30];
strftime(date, sizeof(date), "%Y-%m-%d at %T", localTimePtr);
@@ -337,13 +382,13 @@ namespace dchat
totalHeight = (position.y - scroll) - startHeight;
}
- void MessageBoard::processEvent(const sf::Event &event, Cache &cache)
+ void MessageBoard::processEvent(const sf::Event &event, Cache *cache)
{
lock_guard<mutex> lock(messageProcessMutex);
- OnlineLocalUser *onlineLocalUser = nullptr;
- if(channel->getLocalUser()->type == User::Type::ONLINE_LOCAL_USER)
- onlineLocalUser = static_cast<OnlineLocalUser*>(channel->getLocalUser());
+ std::shared_ptr<User> onlineLocalUser = nullptr;
+ if(room)
+ onlineLocalUser = room->localUser;
bool openContextMenu = false;
if(onlineLocalUser && event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Button::Right)
@@ -358,14 +403,15 @@ namespace dchat
message->text.processEvent(event, cache);
auto textPos = message->text.getPosition();
- if(openContextMenu && message->user == channel->getLocalUser() && event.mouseButton.x >= textPos.x && event.mouseButton.x <= textPos.x + message->text.getMaxWidth() && event.mouseButton.y >= textPos.y && event.mouseButton.y <= textPos.y + message->text.getHeight())
+ if(openContextMenu && message->roomMessage->creator == onlineLocalUser && event.mouseButton.x >= textPos.x && event.mouseButton.x <= textPos.x + message->text.getMaxWidth() && event.mouseButton.y >= textPos.y && event.mouseButton.y <= textPos.y + message->text.getHeight())
{
auto contextMenu = GlobalContextMenu::getEditMessageContextMenu();
contextMenu->setPosition(sf::Vector2f(event.mouseButton.x, event.mouseButton.y));
contextMenu->setVisible(true);
- GlobalContextMenu::setClickDeleteMessageCallbackFunc([this, message, onlineLocalUser](ContextMenuItem *menuItem)
+ GlobalContextMenu::setClickDeleteMessageCallbackFunc([](ContextMenuItem *menuItem)
{
- channel->deleteMessage(message->id, onlineLocalUser->getPublicKey());
+ // TODO: Add: room->deleteMessage();
+ //channel->deleteMessage(message->id, onlineLocalUser->getPublicKey());
GlobalContextMenu::setClickDeleteMessageCallbackFunc(nullptr);
});
}
@@ -382,12 +428,12 @@ namespace dchat
}
}
- void MessageBoard::draw(sf::RenderWindow &window, Cache &cache)
+ void MessageBoard::draw(sf::RenderWindow &window, Cache *cache)
{
auto windowSize = window.getSize();
- backgroundSizeWithoutPadding = sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth()), floor(windowSize.y - ChannelTopPanel::getHeight() - Chatbar::getHeight()));
- backgroundSize = sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - PADDING_SIDE * Settings::getScaling() * 2.0f), floor(windowSize.y - ChannelTopPanel::getHeight() - Chatbar::getHeight() - PADDING_TOP));
- backgroundPos = sf::Vector2f(ChannelSidePanel::getWidth(), ChannelTopPanel::getHeight());
+ backgroundSizeWithoutPadding = sf::Vector2f(floor(windowSize.x - RoomSidePanel::getWidth()), floor(windowSize.y - RoomTopPanel::getHeight() - Chatbar::getHeight()));
+ backgroundSize = sf::Vector2f(floor(windowSize.x - RoomSidePanel::getWidth() - PADDING_SIDE * Settings::getScaling() * 2.0f), floor(windowSize.y - RoomTopPanel::getHeight() - Chatbar::getHeight() - PADDING_TOP));
+ backgroundPos = sf::Vector2f(RoomSidePanel::getWidth(), RoomTopPanel::getHeight());
//if(backgroundSize != staticContentTexture.getSize())
// updateStaticContentTexture(backgroundSize);
@@ -399,7 +445,7 @@ namespace dchat
sf::RectangleShape backgroundRect(backgroundSizeWithoutPadding);
backgroundRect.setFillColor(ColorScheme::getBackgroundColor());
- backgroundRect.setPosition(ChannelSidePanel::getWidth(), ChannelTopPanel::getHeight());
+ backgroundRect.setPosition(RoomSidePanel::getWidth(), RoomTopPanel::getHeight());
window.draw(backgroundRect);
double deltaTimeMicro = (double)frameTimer.getElapsedTime().asMicroseconds();
@@ -472,16 +518,4 @@ namespace dchat
//textureSprite.setPosition(backgroundPos);
//window.draw(textureSprite);
}
-
- Message* MessageBoard::getLatestMessage()
- {
- if(!messages.empty())
- return messages.back();
- return nullptr;
- }
-
- const std::vector<Message*>& MessageBoard::getMessages() const
- {
- return messages;
- }
}