parent
2054aad975
commit
553a97c8bb
12 changed files with 412 additions and 0 deletions
|
|
@ -15,6 +15,11 @@ static constexpr int emojiSize = 14;
|
|||
static constexpr int headerFontSize = 21;
|
||||
static constexpr int typingNotificationFontSize = 11;
|
||||
|
||||
namespace popup {
|
||||
static constexpr int font = fontSize;
|
||||
static constexpr int avatar = 28;
|
||||
}
|
||||
|
||||
namespace receipts {
|
||||
static constexpr int font = 12;
|
||||
}
|
||||
|
|
|
|||
63
include/SuggestionsPopup.hpp
Normal file
63
include/SuggestionsPopup.hpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPoint>
|
||||
#include <QWidget>
|
||||
|
||||
class Avatar;
|
||||
|
||||
struct SearchResult
|
||||
{
|
||||
QString user_id;
|
||||
QString display_name;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(SearchResult)
|
||||
Q_DECLARE_METATYPE(QVector<SearchResult>)
|
||||
|
||||
class PopupItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor)
|
||||
|
||||
public:
|
||||
PopupItem(QWidget *parent, const QString &user_id);
|
||||
|
||||
QColor hoverColor() const { return hoverColor_; }
|
||||
void setHoverColor(QColor &color) { hoverColor_ = color; }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
signals:
|
||||
void clicked(const QString &display_name);
|
||||
|
||||
private:
|
||||
QHBoxLayout *topLayout_;
|
||||
|
||||
Avatar *avatar_;
|
||||
QLabel *userName_;
|
||||
QString user_id_;
|
||||
|
||||
QColor hoverColor_;
|
||||
};
|
||||
|
||||
class SuggestionsPopup : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SuggestionsPopup(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void addUsers(const QVector<SearchResult> &users);
|
||||
|
||||
signals:
|
||||
void itemSelected(const QString &user);
|
||||
|
||||
private:
|
||||
QVBoxLayout *layout_;
|
||||
};
|
||||
|
|
@ -18,7 +18,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPaintEvent>
|
||||
#include <QTextEdit>
|
||||
|
|
@ -26,15 +30,20 @@
|
|||
|
||||
#include "FlatButton.h"
|
||||
#include "LoadingIndicator.h"
|
||||
#include "SuggestionsPopup.hpp"
|
||||
|
||||
#include "dialogs/PreviewUploadOverlay.h"
|
||||
|
||||
#include "emoji/PickButton.h"
|
||||
|
||||
class RoomState;
|
||||
|
||||
namespace dialogs {
|
||||
class PreviewUploadOverlay;
|
||||
}
|
||||
|
||||
struct SearchResult;
|
||||
|
||||
class FilteredTextEdit : public QTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -61,18 +70,45 @@ signals:
|
|||
void video(QSharedPointer<QIODevice> data, const QString &filename);
|
||||
void file(QSharedPointer<QIODevice> data, const QString &filename);
|
||||
|
||||
//! Trigger the suggestion popup.
|
||||
void showSuggestions(const QString &query);
|
||||
void resultsRetrieved(const QVector<SearchResult> &results);
|
||||
|
||||
public slots:
|
||||
void showResults(const QVector<SearchResult> &results);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
bool canInsertFromMimeData(const QMimeData *source) const override;
|
||||
void insertFromMimeData(const QMimeData *source) override;
|
||||
void focusOutEvent(QFocusEvent *event) override
|
||||
{
|
||||
popup_.hide();
|
||||
QWidget::focusOutEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
std::deque<QString> true_history_, working_history_;
|
||||
size_t history_index_;
|
||||
QTimer *typingTimer_;
|
||||
|
||||
SuggestionsPopup popup_;
|
||||
|
||||
void closeSuggestions() { popup_.hide(); }
|
||||
void resetAnchor() { atTriggerPosition_ = -1; }
|
||||
|
||||
QString query()
|
||||
{
|
||||
auto cursor = textCursor();
|
||||
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
|
||||
return cursor.selectedText();
|
||||
}
|
||||
|
||||
dialogs::PreviewUploadOverlay previewDialog_;
|
||||
|
||||
//! Latest position of the '@' character that triggers the username completer.
|
||||
int atTriggerPosition_ = -1;
|
||||
|
||||
void textChanged();
|
||||
void uploadData(const QByteArray data, const QString &media, const QString &filename);
|
||||
void afterCompletion(int);
|
||||
|
|
@ -97,6 +133,7 @@ public slots:
|
|||
void openFileSelection();
|
||||
void hideUploadSpinner();
|
||||
void focusLineEdit() { input_->setFocus(); }
|
||||
void setRoomState(QSharedPointer<RoomState> state) { currState_ = state; }
|
||||
|
||||
private slots:
|
||||
void addSelectedEmoji(const QString &emoji);
|
||||
|
|
@ -132,5 +169,8 @@ private:
|
|||
FlatButton *sendMessageBtn_;
|
||||
emoji::PickButton *emojiBtn_;
|
||||
|
||||
//! State of the current room.
|
||||
QSharedPointer<RoomState> currState_;
|
||||
|
||||
QColor borderColor_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,4 +54,8 @@ scaleDown(uint64_t max_width, uint64_t max_height, const ImageType &source)
|
|||
return source.scaled(
|
||||
final_width, final_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
//! Calculate the Levenshtein distance between two strings with character skipping.
|
||||
int
|
||||
levenshtein_distance(const std::string &s1, const std::string &s2);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue