Refactor completion menu

- Use new Avatar
- Use required property in delegate
This commit is contained in:
Carl Schwan
2023-07-22 19:55:16 +02:00
parent 8546d76a54
commit 75cd77facb
4 changed files with 55 additions and 40 deletions

View File

@@ -218,8 +218,8 @@ void ChatDocumentHandler::setRoom(NeoChatRoom *room)
void ChatDocumentHandler::complete(int index) void ChatDocumentHandler::complete(int index)
{ {
if (m_completionModel->autoCompletionType() == CompletionModel::User) { if (m_completionModel->autoCompletionType() == CompletionModel::User) {
auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Text).toString(); auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::DisplayNameRole).toString();
auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString(); auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('@'), cursorPosition() - 1); auto at = text.lastIndexOf(QLatin1Char('@'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
@@ -232,7 +232,7 @@ void ChatDocumentHandler::complete(int index)
pushMention({cursor, name, 0, 0, id}); pushMention({cursor, name, 0, 0, id});
m_highlighter->rehighlight(); m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == CompletionModel::Command) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Command) {
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString(); auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('/')); auto at = text.lastIndexOf(QLatin1Char('/'));
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
@@ -240,7 +240,7 @@ void ChatDocumentHandler::complete(int index)
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor); cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
cursor.insertText(QStringLiteral("/%1 ").arg(command)); cursor.insertText(QStringLiteral("/%1 ").arg(command));
} else if (m_completionModel->autoCompletionType() == CompletionModel::Room) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Room) {
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString(); auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1); auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
@@ -253,7 +253,7 @@ void ChatDocumentHandler::complete(int index)
pushMention({cursor, alias, 0, 0, alias}); pushMention({cursor, alias, 0, 0, alias});
m_highlighter->rehighlight(); m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) {
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString(); auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char(':')); auto at = text.lastIndexOf(QLatin1Char(':'));
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());

View File

@@ -53,54 +53,54 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
} }
auto filterIndex = m_filterModel->index(index.row(), 0); auto filterIndex = m_filterModel->index(index.row(), 0);
if (m_autoCompletionType == User) { if (m_autoCompletionType == User) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole); return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, UserListModel::UserIdRole); return m_filterModel->data(filterIndex, UserListModel::UserIdRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, UserListModel::AvatarRole); return m_filterModel->data(filterIndex, UserListModel::AvatarRole);
} }
} }
if (m_autoCompletionType == Command) { if (m_autoCompletionType == Command) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ") return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ")
+ m_filterModel->data(filterIndex, ActionsModel::Parameters).toString(); + m_filterModel->data(filterIndex, ActionsModel::Parameters).toString();
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, ActionsModel::Description); return m_filterModel->data(filterIndex, ActionsModel::Description);
} }
if (role == Icon) { if (role == IconNameRole) {
return QStringLiteral("invalid"); return QStringLiteral("invalid");
} }
if (role == ReplacedText) { if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix); return m_filterModel->data(filterIndex, ActionsModel::Prefix);
} }
} }
if (m_autoCompletionType == Room) { if (m_autoCompletionType == Room) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole); return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole); return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole); return m_filterModel->data(filterIndex, RoomListModel::AvatarRole);
} }
} }
if (m_autoCompletionType == Emoji) { if (m_autoCompletionType == Emoji) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole); return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl); return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
} }
if (role == ReplacedText) { if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole); return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole); return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
} }
} }
@@ -111,10 +111,10 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> CompletionModel::roleNames() const QHash<int, QByteArray> CompletionModel::roleNames() const
{ {
return { return {
{Text, "text"}, {DisplayNameRole, "displayName"},
{Subtitle, "subtitle"}, {SubtitleRole, "subtitle"},
{Icon, "icon"}, {IconNameRole, "iconName"},
{ReplacedText, "replacedText"}, {ReplacedTextRole, "replacedText"},
}; };
} }

View File

@@ -64,10 +64,10 @@ public:
* @brief Defines the model roles. * @brief Defines the model roles.
*/ */
enum Roles { enum Roles {
Text = Qt::DisplayRole, /**< The main text to show. */ DisplayNameRole = Qt::DisplayRole, /**< The main text to show. */
Subtitle, /**< The subtitle text to show. */ SubtitleRole, /**< The subtitle text to show. */
Icon, /**< The icon to show. */ IconNameRole, /**< The icon to show. */
ReplacedText, /**< The text to replace the input text with for the completion. */ ReplacedTextRole, /**< The text to replace the input text with for the completion. */
}; };
Q_ENUM(Roles) Q_ENUM(Roles)

View File

@@ -8,6 +8,8 @@ import QtQuick.Controls 2.15 as QQC2
import Qt.labs.qmlmodels 1.0 import Qt.labs.qmlmodels 1.0
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -43,6 +45,7 @@ QQC2.Popup {
rightPadding: 0 rightPadding: 0
topPadding: 0 topPadding: 0
bottomPadding: 0 bottomPadding: 0
implicitHeight: Math.min(completions.contentHeight, Kirigami.Units.gridUnit * 10) implicitHeight: Math.min(completions.contentHeight, Kirigami.Units.gridUnit * 10)
contentItem: ListView { contentItem: ListView {
@@ -53,23 +56,35 @@ QQC2.Popup {
currentIndex: 0 currentIndex: 0
keyNavigationWraps: true keyNavigationWraps: true
highlightMoveDuration: 100 highlightMoveDuration: 100
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
text: model.text id: completionDelegate
subtitle: model.subtitle ?? ""
labelItem.textFormat: Text.PlainText required property int index
subtitleItem.textFormat: Text.PlainText required property string displayName
leading: RowLayout { required property string subtitle
Kirigami.Avatar { required property string iconName
visible: model.icon !== "invalid"
Layout.preferredWidth: height text: displayName
Layout.fillHeight: true
source: model.icon === "invalid" ? "" : ("image://mxc/" + model.icon) contentItem: RowLayout {
name: model.text KirigamiComponents.Avatar {
visible: completionDelegate.iconName !== "invalid"
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
source: completionDelegate.iconName === "invalid" ? "" : ("image://" + completionDelegate.iconName)
name: completionDelegate.text
}
Delegates.SubtitleContentItem {
itemDelegate: completionDelegate
labelItem.textFormat: Text.PlainText
subtitle: completionDelegate.subtitle ?? ""
subtitleItem.textFormat: Text.PlainText
} }
} }
onClicked: completionMenu.chatDocumentHandler.complete(model.index) onClicked: completionMenu.chatDocumentHandler.complete(completionDelegate.index)
} }
} }
background: Rectangle { background: Rectangle {
color: Kirigami.Theme.backgroundColor color: Kirigami.Theme.backgroundColor
} }