summary refs log tree commit diff
path: root/src/GridImagePackModel.h
blob: 7e64f6c429b249431b0a021dc4ef44fa4ca9070d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QAbstractListModel>
#include <QMultiMap>
#include <QObject>
#include <QString>

#include <mtx/events/mscs/image_packs.hpp>

#include "CompletionProxyModel.h"

struct StickerImage
{
    Q_GADGET
    Q_PROPERTY(QString url MEMBER url CONSTANT)
    Q_PROPERTY(QString shortcode MEMBER shortcode CONSTANT)
    Q_PROPERTY(QString body MEMBER body CONSTANT)
    Q_PROPERTY(QStringList descriptor READ descriptor CONSTANT)
    Q_PROPERTY(QString markdown READ markdown CONSTANT)

public:
    QStringList descriptor() const
    {
        if (descriptor_.size() == 3)
            return QStringList{
              QString::fromStdString(descriptor_[0]),
              QString::fromStdString(descriptor_[1]),
              QString::fromStdString(descriptor_[2]),
            };
        else
            return {};
    }

    QString markdown() const
    {
        return QStringLiteral(
                 "<img data-mx-emoticon height=\"32\" src=\"%1\" alt=\"%2\" title=\"%2\">")
          .arg(url.toHtmlEscaped(), !body.isEmpty() ? body : shortcode);
    }

    QString url;
    QString shortcode;
    QString body;

    std::vector<std::string> descriptor_; // roomid, statekey, shortcode
};

struct SectionDescription
{
    Q_GADGET
    Q_PROPERTY(QString url MEMBER url CONSTANT)
    Q_PROPERTY(QString name MEMBER name CONSTANT)
    Q_PROPERTY(int firstRowWith MEMBER firstRowWith CONSTANT)

public:
    QString name;
    QString url;
    int firstRowWith = 0;
};

struct TextEmoji
{
    Q_GADGET
    Q_PROPERTY(QString unicode MEMBER unicode CONSTANT)
    Q_PROPERTY(QString unicodeName MEMBER unicodeName CONSTANT)
    Q_PROPERTY(QString shortcode MEMBER shortcode CONSTANT)

public:
    QString unicode;
    QString unicodeName;
    QString shortcode;
};

class GridImagePackModel final : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY newSearchString)
    Q_PROPERTY(QList<SectionDescription> sections READ sections NOTIFY newSearchString)

public:
    enum Roles
    {
        PackName = Qt::UserRole,
        Row,
    };

    GridImagePackModel(const std::string &roomId, bool stickers, QObject *parent = nullptr);
    QHash<int, QByteArray> roleNames() const override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role) const override;

    QString searchString() const { return searchString_; }
    void setSearchString(QString newValue);

    QList<SectionDescription> sections() const;

signals:
    void newSearchString();

private:
    std::string room_id;

    struct PackDesc
    {
        QString packname;
        QString packavatar;
        std::string room_id, state_key;

        std::vector<std::pair<mtx::events::msc2545::PackImage, QString>> images;
        std::vector<TextEmoji> emojis;
        std::size_t firstRow;
    };

    std::vector<PackDesc> packs;
    std::vector<size_t> rowToPack;
    int columns = 3;

    QString searchString_;
    trie<uint, std::pair<std::uint32_t, std::uint32_t>> trie_;
    std::vector<std::pair<std::uint32_t, std::uint32_t>> currentSearchResult;
    std::vector<std::size_t> rowToFirstRowEntryFromSearch;

    QString nameFromPack(const PackDesc &pack) const;
    QString avatarFromPack(const PackDesc &pack) const;
};