File indexing completed on 2024-05-12 05:04:09
0001 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu> 0002 // SPDX-License-Identifier: GPL-3.0-or-later 0003 0004 #include "identity.h" 0005 0006 #include "abstractaccount.h" 0007 #include "relationship.h" 0008 0009 using namespace Qt::Literals::StringLiterals; 0010 0011 QString Identity::displayName() const 0012 { 0013 return !m_displayName.isEmpty() ? m_displayName : m_username; 0014 } 0015 0016 QString Identity::username() const 0017 { 0018 return m_username; 0019 } 0020 0021 QString Identity::bio() const 0022 { 0023 return m_bio; 0024 } 0025 0026 QString Identity::account() const 0027 { 0028 return m_account; 0029 } 0030 0031 bool Identity::locked() const 0032 { 0033 return m_locked; 0034 } 0035 0036 QString Identity::visibility() const 0037 { 0038 return m_visibility; 0039 } 0040 0041 QUrl Identity::avatarUrl() const 0042 { 0043 return m_avatarUrl; 0044 } 0045 0046 QUrl Identity::backgroundUrl() const 0047 { 0048 return m_backgroundUrl; 0049 } 0050 0051 int Identity::followersCount() const 0052 { 0053 return m_followersCount; 0054 } 0055 0056 int Identity::followingCount() const 0057 { 0058 return m_followingCount; 0059 } 0060 0061 int Identity::statusesCount() const 0062 { 0063 return m_statusesCount; 0064 } 0065 0066 int Identity::permission() const 0067 { 0068 return m_permission; 0069 } 0070 0071 QJsonArray Identity::fields() const 0072 { 0073 return m_fields; 0074 } 0075 0076 Relationship *Identity::relationship() const 0077 { 0078 return m_relationship; 0079 } 0080 0081 void Identity::setRelationship(Relationship *r) 0082 { 0083 if (m_relationship == r) { 0084 return; 0085 } 0086 0087 // delete old relationship object if we receive a new one 0088 delete m_relationship; 0089 0090 m_relationship = r; 0091 Q_EMIT relationshipChanged(); 0092 } 0093 0094 void Identity::reparentIdentity(AbstractAccount *parent) 0095 { 0096 m_parent = parent; 0097 } 0098 0099 void Identity::fromSourceData(const QJsonObject &doc) 0100 { 0101 m_id = doc["id"_L1].toString(); 0102 m_displayName = doc["display_name"_L1].toString(); 0103 m_username = doc["username"_L1].toString(); 0104 m_account = doc["acct"_L1].toString(); 0105 m_bio = doc["note"_L1].toString(); 0106 m_locked = doc["locked"_L1].toBool(); 0107 m_backgroundUrl = QUrl(doc["header"_L1].toString()); 0108 m_avatarUrl = QUrl(doc["avatar"_L1].toString()); 0109 m_followersCount = doc["followers_count"_L1].toInt(); 0110 m_followingCount = doc["following_count"_L1].toInt(); 0111 m_statusesCount = doc["statuses_count"_L1].toInt(); 0112 m_fields = doc["fields"_L1].toArray(); 0113 m_url = QUrl(doc["url"_L1].toString()); 0114 m_permission = doc["role"_L1]["permissions"_L1].toString().toInt(); 0115 // When the user data is ourselves, we get source.privacy 0116 // with the default post privacy setting for the user. all others 0117 // will get empty strings. 0118 QJsonObject source = doc["source"_L1].toObject(); 0119 m_visibility = source["privacy"_L1].toString(); 0120 0121 m_displayNameHtml = m_displayName.replace(QLatin1Char('<'), QStringLiteral("<")).replace(QLatin1Char('>'), QStringLiteral(">")); 0122 0123 const auto emojis = CustomEmoji::parseCustomEmojis(doc["emojis"_L1].toArray()); 0124 0125 m_displayNameHtml = CustomEmoji::replaceCustomEmojis(emojis, m_displayNameHtml); 0126 m_bio = CustomEmoji::replaceCustomEmojis(emojis, m_bio); 0127 0128 const QString baseUrl = m_url.toDisplayString(QUrl::RemovePath); 0129 0130 // Attempt to replace the tag URLs with proper ones, although this should really be handled by the Mastodon API 0131 m_bio = m_bio.replace(baseUrl + QStringLiteral("/tags/"), QStringLiteral("hashtag:/"), Qt::CaseInsensitive); 0132 0133 // Even worse, mentions are not given proper ids so we must figure it out on our own. 0134 // The account could be on a different server, so let's take advantage of web+ap and use that 0135 // to search for the account! 0136 // TODO: Mentions have a specific CSS class in the HTML, maybe we can use that instead of dirty regex? 0137 static QRegularExpression re(QStringLiteral(R"((?:href="?)(?:https?|ftp):\S[^"]+)")); 0138 const auto match = re.match(m_bio); 0139 if (re.isValid()) { 0140 for (int i = 0; i <= match.lastCapturedIndex(); ++i) { 0141 const int start = match.capturedStart(i); 0142 const int length = match.capturedLength(i); 0143 const QString captured = match.captured(i); 0144 if (captured.contains('@'_L1)) { 0145 // The length of "href=" which is used in the regex. 0146 const int hrefLength = 6; 0147 m_bio = m_bio.replace(start + hrefLength, length - hrefLength, QStringLiteral("web+ap:/") + captured.mid(hrefLength)); 0148 } 0149 } 0150 } 0151 0152 Q_EMIT identityUpdated(); 0153 } 0154 0155 QString Identity::id() const 0156 { 0157 return m_id; 0158 } 0159 0160 QString Identity::displayNameHtml() const 0161 { 0162 return !m_displayNameHtml.isEmpty() ? m_displayNameHtml : m_username; 0163 } 0164 0165 QUrl Identity::url() const 0166 { 0167 return m_url; 0168 } 0169 0170 #include "moc_identity.cpp"