aboutsummaryrefslogtreecommitdiff
path: root/src/UsersSidePanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/UsersSidePanel.cpp')
-rw-r--r--src/UsersSidePanel.cpp140
1 files changed, 103 insertions, 37 deletions
diff --git a/src/UsersSidePanel.cpp b/src/UsersSidePanel.cpp
index c3f2a78..035826f 100644
--- a/src/UsersSidePanel.cpp
+++ b/src/UsersSidePanel.cpp
@@ -22,6 +22,49 @@ namespace dchat
const float AVATAR_DIAMETER = 40.0f;
const float AVATAR_PADDING_SIDE = 10.0f;
const float PADDING_BOTTOM = 20.0f;
+ const i64 USER_TIMEOUT_SEC = 10;
+
+ static void renderUser(Cache &cache, User *user, sf::Shader *circleShader, sf::RenderWindow &window, sf::Vector2f &position, const sf::Font *font, const float textHeight)
+ {
+ // Max avatar size = 1mb
+ const ContentByUrlResult avatarResult = cache.getContentByUrl(user->avatarUrl, 1024 * 1024);
+ if(avatarResult.type == ContentByUrlResult::Type::CACHED)
+ {
+ circleShader->setUniform("texture", sf::Shader::CurrentTexture);
+
+ if(avatarResult.cachedType == ContentByUrlResult::CachedType::TEXTURE)
+ {
+ // 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();
+ sprite.setPosition(sf::Vector2f(floor(position.x), 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(floor(position.x), floor(position.y)));
+ avatarResult.gif->setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.y));
+ avatarResult.gif->draw(window, circleShader);
+ }
+ }
+ else
+ {
+ sf::CircleShape avatarCircle(AVATAR_DIAMETER * 0.5f * Settings::getScaling(), 60 * Settings::getScaling());
+ avatarCircle.setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
+ avatarCircle.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(30, 30, 30));
+ window.draw(avatarCircle);
+ }
+
+ // TODO: Remove this shit
+ sf::String str = sf::String::fromUtf8(user->getName().begin(), user->getName().end());
+ sf::Text text(str, *font, FONT_SIZE * Settings::getScaling());
+ text.setPosition(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y + AVATAR_DIAMETER * 0.5f - textHeight * 0.5f));
+ text.setFillColor(sf::Color(15, 192, 252));
+ window.draw(text);
+ position.y += ((AVATAR_DIAMETER + PADDING_BOTTOM) * Settings::getScaling());
+ }
void UsersSidePanel::draw(sf::RenderWindow &window, Cache &cache)
{
@@ -38,59 +81,82 @@ namespace dchat
const sf::Font *font = ResourceCache::getFont("fonts/Roboto-Regular.ttf");
sf::Vector2f position(rect.getPosition().x + 10.0f, posY);
+ const float textHeight = font->getLineSpacing(FONT_SIZE * Settings::getScaling());
+
+ i64 timestamp = currentChannel->getSyncedTimestampUtcCombined();
+
+ u32 numOnlineUsers = 0;
+ u32 numOfflineUsers = 0;
+ for(User *user : currentChannel->getUsers())
+ {
+ bool hasUserTimedOut = false;
+ if(user->isOnlineUser())
+ {
+ auto onlineUser = static_cast<OnlineUser*>(user);
+ i64 pingTimeDiffSec = (timestamp - (i64)onlineUser->pingTimestamp) >> 32LL;
+ if(pingTimeDiffSec > USER_TIMEOUT_SEC)
+ hasUserTimedOut = true;
+ }
+
+ if(hasUserTimedOut)
+ ++numOfflineUsers;
+ else
+ ++numOnlineUsers;
+ }
+
// TODO: Remove this shit
sf::String str = "Online - ";
- str += to_string(currentChannel->getUsers().size());
- sf::Text text(str, *font, FONT_SIZE * Settings::getScaling() * 1.0f);
+ str += to_string(numOnlineUsers);
+ sf::Text text(str, *font, textHeight * 1.0f);
text.setPosition(position);
text.setFillColor(ColorScheme::getTextRegularColor() * sf::Color(255, 255, 255, 100));
window.draw(text);
position.y += floor(font->getLineSpacing(text.getCharacterSize()));
- position.y += (PADDING_BOTTOM * Settings::getScaling());
+ position.y += PADDING_BOTTOM * Settings::getScaling() * 0.5f;
sf::Shader *circleShader = ResourceCache::getShader("shaders/circleMask.glsl", sf::Shader::Fragment);
- const float textHeight = font->getLineSpacing(FONT_SIZE * Settings::getScaling());
for(User *user : currentChannel->getUsers())
{
- // Max avatar size = 1mb
- const ContentByUrlResult avatarResult = cache.getContentByUrl(user->avatarUrl, 1024 * 1024);
- if(avatarResult.type == ContentByUrlResult::Type::CACHED)
+ bool isUserOnline = true;
+ if(user->isOnlineUser())
{
- circleShader->setUniform("texture", sf::Shader::CurrentTexture);
-
- if(avatarResult.cachedType == ContentByUrlResult::CachedType::TEXTURE)
- {
- // 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();
- sprite.setPosition(sf::Vector2f(floor(position.x), 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(floor(position.x), floor(position.y)));
- avatarResult.gif->setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.y));
- avatarResult.gif->draw(window, circleShader);
- }
+ auto onlineUser = static_cast<OnlineUser*>(user);
+ i64 pingTimeDiffSec = (timestamp - (i64)onlineUser->pingTimestamp) >> 32LL;
+ if(pingTimeDiffSec > USER_TIMEOUT_SEC)
+ isUserOnline = false;
}
- else
+
+ if(isUserOnline)
+ renderUser(cache, user, circleShader, window, position, font, textHeight);
+ }
+
+ if(numOfflineUsers == 0) return;
+ position.y += PADDING_BOTTOM * Settings::getScaling();
+
+ // TODO: Remove this shit
+ str = "Offline - ";
+ str += to_string(numOfflineUsers);
+ text.setString(str);
+ text.setPosition(position);
+ text.setFillColor(ColorScheme::getTextRegularColor() * sf::Color(255, 255, 255, 100));
+ window.draw(text);
+ position.y += floor(font->getLineSpacing(text.getCharacterSize()));
+ position.y += PADDING_BOTTOM * Settings::getScaling() * 0.5f;
+
+ for(User *user : currentChannel->getUsers())
+ {
+ bool isUserOnline = true;
+ if(user->isOnlineUser())
{
- sf::CircleShape avatarCircle(AVATAR_DIAMETER * 0.5f * Settings::getScaling(), 60 * Settings::getScaling());
- avatarCircle.setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
- avatarCircle.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(30, 30, 30));
- window.draw(avatarCircle);
+ auto onlineUser = static_cast<OnlineUser*>(user);
+ i64 pingTimeDiffSec = (timestamp - (i64)onlineUser->pingTimestamp) >> 32LL;
+ if(pingTimeDiffSec > USER_TIMEOUT_SEC)
+ isUserOnline = false;
}
- // TODO: Remove this shit
- sf::String str = sf::String::fromUtf8(user->getName().begin(), user->getName().end());
- sf::Text text(str, *font, FONT_SIZE * Settings::getScaling());
- text.setPosition(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y + AVATAR_DIAMETER * 0.5f - textHeight * 0.5f));
- text.setFillColor(sf::Color(15, 192, 252));
- window.draw(text);
- position.y += ((AVATAR_DIAMETER + PADDING_BOTTOM) * Settings::getScaling());
+ if(!isUserOnline)
+ renderUser(cache, user, circleShader, window, position, font, textHeight);
}
}