diff options
Diffstat (limited to 'src/UsersSidePanel.cpp')
-rw-r--r-- | src/UsersSidePanel.cpp | 140 |
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); } } |