mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Fixes #53 last read message indicator
This commit is contained in:
parent
418189d39c
commit
0f4ec70bf3
|
@ -145,7 +145,8 @@ void MessageLayout::actuallyLayout(int width, MessageElement::Flags flags)
|
|||
}
|
||||
|
||||
// Painting
|
||||
void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection &selection)
|
||||
void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection &selection,
|
||||
bool isLastReadMessage, bool isWindowFocused)
|
||||
{
|
||||
QPixmap *pixmap = this->buffer.get();
|
||||
singletons::ThemeManager &themeManager = singletons::ThemeManager::getInstance();
|
||||
|
@ -180,6 +181,16 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
|
|||
// draw gif emotes
|
||||
this->container.paintAnimatedElements(painter, y);
|
||||
|
||||
// draw last read message line
|
||||
if (isLastReadMessage) {
|
||||
QColor color = isWindowFocused ? themeManager.tabs.selected.backgrounds.regular.color()
|
||||
: themeManager.tabs.selected.backgrounds.unfocused.color();
|
||||
|
||||
QBrush brush = QBrush(color, Qt::VerPattern);
|
||||
|
||||
painter.fillRect(0, y + this->container.getHeight() - 1, this->container.width, 1, brush);
|
||||
}
|
||||
|
||||
this->bufferValid = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ public:
|
|||
bool layout(int width, float scale, MessageElement::Flags flags);
|
||||
|
||||
// Painting
|
||||
void paint(QPainter &painter, int y, int messageIndex, Selection &selection);
|
||||
void paint(QPainter &painter, int y, int messageIndex, Selection &selection,
|
||||
bool isLastReadMessage, bool isWindowFocused);
|
||||
void invalidateBuffer();
|
||||
void deleteBuffer();
|
||||
|
||||
|
|
|
@ -96,6 +96,9 @@ ChannelView::ChannelView(BaseWidget *parent)
|
|||
auto e = new QResizeEvent(this->size(), this->size());
|
||||
this->resizeEvent(e);
|
||||
delete e;
|
||||
|
||||
singletons::SettingManager::getInstance().showLastMessageIndicator.connect(
|
||||
[this](auto, auto) { this->update(); }, this->managedConnections);
|
||||
}
|
||||
|
||||
ChannelView::~ChannelView()
|
||||
|
@ -410,6 +413,17 @@ void ChannelView::pause(int msecTimeout)
|
|||
this->pauseTimeout.start(msecTimeout);
|
||||
}
|
||||
|
||||
void ChannelView::updateLastReadMessage()
|
||||
{
|
||||
auto _snapshot = this->getMessagesSnapshot();
|
||||
|
||||
if (_snapshot.getLength() > 0) {
|
||||
this->lastReadMessage = _snapshot[_snapshot.getLength() - 1];
|
||||
}
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
void ChannelView::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
this->scrollBar.resize(this->scrollBar.width(), height());
|
||||
|
@ -477,11 +491,17 @@ void ChannelView::drawMessages(QPainter &painter)
|
|||
(fmod(this->scrollBar.getCurrentValue(), 1)));
|
||||
|
||||
messages::MessageLayout *end = nullptr;
|
||||
bool windowFocused = this->window() == QApplication::activeWindow();
|
||||
|
||||
for (size_t i = start; i < messagesSnapshot.getLength(); ++i) {
|
||||
messages::MessageLayout *layout = messagesSnapshot[i].get();
|
||||
|
||||
layout->paint(painter, y, i, this->selection);
|
||||
bool isLastMessage = false;
|
||||
if (singletons::SettingManager::getInstance().showLastMessageIndicator) {
|
||||
isLastMessage = this->lastReadMessage.get() == layout;
|
||||
}
|
||||
|
||||
layout->paint(painter, y, i, this->selection, isLastMessage, windowFocused);
|
||||
|
||||
y += layout->getHeight();
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
void setEnableScrollingToBottom(bool);
|
||||
bool getEnableScrollingToBottom() const;
|
||||
void pause(int msecTimeout);
|
||||
void updateLastReadMessage();
|
||||
|
||||
void setChannel(SharedChannel channel);
|
||||
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> getMessagesSnapshot();
|
||||
|
@ -72,6 +73,7 @@ private:
|
|||
bool messageWasAdded = false;
|
||||
bool paused = false;
|
||||
QTimer pauseTimeout;
|
||||
messages::MessageLayoutPtr lastReadMessage;
|
||||
|
||||
messages::LimitedQueueSnapshot<messages::MessageLayoutPtr> snapshot;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#define WINDOW_TOPMOST "Window always on top (requires restart)"
|
||||
#define INPUT_EMPTY "Hide input box when empty"
|
||||
#define LAST_MSG "Show last read message indicator"
|
||||
#define LAST_MSG "Show last read message indicator (marks the spot where you left the window)"
|
||||
#define PAUSE_HOVERING "When hovering"
|
||||
|
||||
#define STREAMLINK_QUALITY "Choose", "Source", "High", "Medium", "Low", "Audio only"
|
||||
|
|
|
@ -252,6 +252,11 @@ void Split::updateGifEmotes()
|
|||
this->view.queueUpdate();
|
||||
}
|
||||
|
||||
void Split::updateLastReadMessage()
|
||||
{
|
||||
this->view.updateLastReadMessage();
|
||||
}
|
||||
|
||||
void Split::giveFocus(Qt::FocusReason reason)
|
||||
{
|
||||
this->input.textInput.setFocus(reason);
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
bool hasFocus() const;
|
||||
void layoutMessages();
|
||||
void updateGifEmotes();
|
||||
void updateLastReadMessage();
|
||||
|
||||
void drag();
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ void SplitContainer::addToLayout(Split *widget, std::pair<int, int> position)
|
|||
this->refreshCurrentFocusCoordinates();
|
||||
}
|
||||
|
||||
const std::vector<Split *> &SplitContainer::getChatWidgets() const
|
||||
const std::vector<Split *> &SplitContainer::getSplits() const
|
||||
{
|
||||
return this->splits;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
std::pair<int, int> removeFromLayout(Split *widget);
|
||||
void addToLayout(Split *widget, std::pair<int, int> position = std::pair<int, int>(-1, -1));
|
||||
|
||||
const std::vector<Split *> &getChatWidgets() const;
|
||||
const std::vector<Split *> &getSplits() const;
|
||||
NotebookTab *getTab() const;
|
||||
|
||||
void addChat(bool openChannelNameDialog = false, std::string chatUUID = std::string());
|
||||
|
|
|
@ -107,7 +107,7 @@ void Window::repaintVisibleChatWidgets(Channel *channel)
|
|||
return;
|
||||
}
|
||||
|
||||
const std::vector<Split *> &widgets = page->getChatWidgets();
|
||||
const std::vector<Split *> &widgets = page->getSplits();
|
||||
|
||||
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
|
||||
Split *widget = *it;
|
||||
|
@ -140,6 +140,27 @@ void Window::closeEvent(QCloseEvent *)
|
|||
this->closed();
|
||||
}
|
||||
|
||||
bool Window::event(QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::WindowActivate:
|
||||
break;
|
||||
|
||||
case QEvent::WindowDeactivate: {
|
||||
auto page = this->notebook.getSelectedPage();
|
||||
|
||||
if (page != nullptr) {
|
||||
std::vector<Split *> splits = page->getSplits();
|
||||
|
||||
for (Split *split : splits) {
|
||||
split->updateLastReadMessage();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
};
|
||||
return BaseWindow::event(e);
|
||||
}
|
||||
|
||||
void Window::loadGeometry()
|
||||
{
|
||||
bool doSetGeometry = false;
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
virtual bool event(QEvent *event) override;
|
||||
|
||||
private:
|
||||
singletons::ThemeManager &themeManager;
|
||||
|
|
Loading…
Reference in a new issue