mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-11 08:48:14 +00:00
Added initial implementation of api for usernames.
This commit is contained in:
parent
29663a410a
commit
51cead1445
@ -162,6 +162,8 @@ PRIVATE
|
|||||||
api/api_unread_things.h
|
api/api_unread_things.h
|
||||||
api/api_updates.cpp
|
api/api_updates.cpp
|
||||||
api/api_updates.h
|
api/api_updates.h
|
||||||
|
api/api_user_names.cpp
|
||||||
|
api/api_user_names.h
|
||||||
api/api_user_privacy.cpp
|
api/api_user_privacy.cpp
|
||||||
api/api_user_privacy.h
|
api/api_user_privacy.h
|
||||||
api/api_views.cpp
|
api/api_views.cpp
|
||||||
@ -545,6 +547,7 @@ PRIVATE
|
|||||||
data/data_user.h
|
data/data_user.h
|
||||||
data/data_user_photos.cpp
|
data/data_user_photos.cpp
|
||||||
data/data_user_photos.h
|
data/data_user_photos.h
|
||||||
|
data/data_user_names.h
|
||||||
data/data_wall_paper.cpp
|
data/data_wall_paper.cpp
|
||||||
data/data_wall_paper.h
|
data/data_wall_paper.h
|
||||||
data/data_web_page.cpp
|
data/data_web_page.cpp
|
||||||
|
203
Telegram/SourceFiles/api/api_user_names.cpp
Normal file
203
Telegram/SourceFiles/api/api_user_names.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "api/api_user_names.h"
|
||||||
|
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] Data::Username UsernameFromTL(const MTPUsername &username) {
|
||||||
|
return {
|
||||||
|
.username = qs(username.data().vusername()),
|
||||||
|
.active = username.data().is_active(),
|
||||||
|
.editable = username.data().is_editable(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Usernames::Usernames(not_null<ApiWrap*> api)
|
||||||
|
: _session(&api->session())
|
||||||
|
, _api(&api->instance()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<Data::Usernames> Usernames::loadUsernames(
|
||||||
|
not_null<PeerData*> peer) const {
|
||||||
|
return [=](auto consumer) {
|
||||||
|
auto lifetime = rpl::lifetime();
|
||||||
|
|
||||||
|
const auto push = [consumer](
|
||||||
|
const auto &usernames,
|
||||||
|
const auto &username) {
|
||||||
|
if (usernames) {
|
||||||
|
if (usernames->v.empty()) {
|
||||||
|
// Probably will never happen.
|
||||||
|
consumer.put_next({});
|
||||||
|
} else {
|
||||||
|
auto parsed = FromTL(*usernames);
|
||||||
|
if ((parsed.size() == 1)
|
||||||
|
&& username
|
||||||
|
&& (parsed.front().username == qs(*username))) {
|
||||||
|
// Probably will never happen.
|
||||||
|
consumer.put_next({});
|
||||||
|
} else {
|
||||||
|
consumer.put_next(std::move(parsed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
consumer.put_next({});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto requestUser = [&](const MTPInputUser &data) {
|
||||||
|
_session->api().request(MTPusers_GetUsers(
|
||||||
|
MTP_vector<MTPInputUser>(1, data)
|
||||||
|
)).done([=](const MTPVector<MTPUser> &result) {
|
||||||
|
result.v.front().match([&](const MTPDuser &data) {
|
||||||
|
push(data.vusernames(), data.vusername());
|
||||||
|
consumer.put_done();
|
||||||
|
}, [&](const MTPDuserEmpty&) {
|
||||||
|
consumer.put_next({});
|
||||||
|
consumer.put_done();
|
||||||
|
});
|
||||||
|
}).send();
|
||||||
|
};
|
||||||
|
const auto requestChannel = [&](const MTPInputChannel &data) {
|
||||||
|
_session->api().request(MTPchannels_GetChannels(
|
||||||
|
MTP_vector<MTPInputChannel>(1, data)
|
||||||
|
)).done([=](const MTPmessages_Chats &result) {
|
||||||
|
result.match([&](const auto &data) {
|
||||||
|
data.vchats().v.front().match([&](const MTPDchannel &c) {
|
||||||
|
push(c.vusernames(), c.vusername());
|
||||||
|
consumer.put_done();
|
||||||
|
}, [&](auto &&) {
|
||||||
|
consumer.put_next({});
|
||||||
|
consumer.put_done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).send();
|
||||||
|
};
|
||||||
|
if (peer->isSelf()) {
|
||||||
|
requestUser(MTP_inputUserSelf());
|
||||||
|
} else if (const auto user = peer->asUser()) {
|
||||||
|
requestUser(user->inputUser);
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
requestChannel(channel->inputChannel);
|
||||||
|
}
|
||||||
|
return lifetime;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> Usernames::toggle(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QString &username,
|
||||||
|
bool active) {
|
||||||
|
const auto peerId = peer->id;
|
||||||
|
const auto it = _toggleRequests.find(peerId);
|
||||||
|
const auto found = (it != end(_toggleRequests));
|
||||||
|
auto &entry = (!found
|
||||||
|
? _toggleRequests.emplace(
|
||||||
|
peerId,
|
||||||
|
Entry{ .usernames = { username } }).first
|
||||||
|
: it)->second;
|
||||||
|
if (ranges::contains(entry.usernames, username)) {
|
||||||
|
if (found) {
|
||||||
|
return entry.done.events();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry.usernames.push_back(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto finish = [=] {
|
||||||
|
const auto it = _toggleRequests.find(peerId);
|
||||||
|
if (it != end(_toggleRequests)) {
|
||||||
|
auto &list = it->second.usernames;
|
||||||
|
list.erase(ranges::remove(list, username), end(list));
|
||||||
|
if (list.empty()) {
|
||||||
|
it->second.done.fire_done();
|
||||||
|
_toggleRequests.remove(peerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (peer->isSelf()) {
|
||||||
|
_api.request(MTPaccount_ToggleUsername(
|
||||||
|
MTP_string(username),
|
||||||
|
MTP_bool(active)
|
||||||
|
)).done(finish).fail(finish).send();
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
_api.request(MTPchannels_ToggleUsername(
|
||||||
|
channel->inputChannel,
|
||||||
|
MTP_string(username),
|
||||||
|
MTP_bool(active)
|
||||||
|
)).done(finish).fail(finish).send();
|
||||||
|
} else {
|
||||||
|
return rpl::never<>();
|
||||||
|
}
|
||||||
|
return entry.done.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> Usernames::reorder(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const std::vector<QString> &usernames) {
|
||||||
|
const auto peerId = peer->id;
|
||||||
|
const auto it = _reorderRequests.find(peerId);
|
||||||
|
if (it != end(_reorderRequests)) {
|
||||||
|
_api.request(it->second).cancel();
|
||||||
|
_reorderRequests.erase(peerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [=](auto consumer) {
|
||||||
|
auto lifetime = rpl::lifetime();
|
||||||
|
|
||||||
|
auto tlUsernames = ranges::views::all(
|
||||||
|
usernames
|
||||||
|
) | ranges::views::transform([](const QString &username) {
|
||||||
|
return MTP_string(username);
|
||||||
|
}) | ranges::to<QVector<MTPstring>>;
|
||||||
|
|
||||||
|
const auto finish = [=] {
|
||||||
|
if (_reorderRequests.contains(peerId)) {
|
||||||
|
_reorderRequests.erase(peerId);
|
||||||
|
}
|
||||||
|
consumer.put_done();
|
||||||
|
};
|
||||||
|
if (usernames.empty()) {
|
||||||
|
crl::on_main([=] { consumer.put_done(); });
|
||||||
|
return lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer->isSelf()) {
|
||||||
|
const auto requestId = _api.request(MTPaccount_ReorderUsernames(
|
||||||
|
MTP_vector<MTPstring>(std::move(tlUsernames))
|
||||||
|
)).done(finish).fail(finish).send();
|
||||||
|
_reorderRequests.emplace(peerId, requestId);
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
const auto requestId = _api.request(MTPchannels_ReorderUsernames(
|
||||||
|
channel->inputChannel,
|
||||||
|
MTP_vector<MTPstring>(std::move(tlUsernames))
|
||||||
|
)).done(finish).fail(finish).send();
|
||||||
|
_reorderRequests.emplace(peerId, requestId);
|
||||||
|
}
|
||||||
|
return lifetime;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Data::Usernames Usernames::FromTL(const MTPVector<MTPUsername> &usernames) {
|
||||||
|
return ranges::views::all(
|
||||||
|
usernames.v
|
||||||
|
) | ranges::views::transform(UsernameFromTL) | ranges::to_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Api
|
53
Telegram/SourceFiles/api/api_user_names.h
Normal file
53
Telegram/SourceFiles/api/api_user_names.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/data_user_names.h"
|
||||||
|
#include "mtproto/sender.h"
|
||||||
|
|
||||||
|
class ApiWrap;
|
||||||
|
class PeerData;
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
|
||||||
|
class Usernames final {
|
||||||
|
public:
|
||||||
|
explicit Usernames(not_null<ApiWrap*> api);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<Data::Usernames> loadUsernames(
|
||||||
|
not_null<PeerData*> peer) const;
|
||||||
|
[[nodiscard]] rpl::producer<> toggle(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QString &username,
|
||||||
|
bool active);
|
||||||
|
[[nodiscard]] rpl::producer<> reorder(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const std::vector<QString> &usernames);
|
||||||
|
|
||||||
|
static Data::Usernames FromTL(const MTPVector<MTPUsername> &usernames);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
MTP::Sender _api;
|
||||||
|
|
||||||
|
using Key = PeerId;
|
||||||
|
struct Entry final {
|
||||||
|
rpl::event_stream<> done;
|
||||||
|
std::vector<QString> usernames;
|
||||||
|
};
|
||||||
|
base::flat_map<Key, Entry> _toggleRequests;
|
||||||
|
base::flat_map<Key, mtpRequestId> _reorderRequests;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Api
|
@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "api/api_ringtones.h"
|
#include "api/api_ringtones.h"
|
||||||
#include "api/api_transcribes.h"
|
#include "api/api_transcribes.h"
|
||||||
#include "api/api_premium.h"
|
#include "api/api_premium.h"
|
||||||
|
#include "api/api_user_names.h"
|
||||||
#include "data/notify/data_notify_settings.h"
|
#include "data/notify/data_notify_settings.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
@ -169,7 +170,8 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
|
|||||||
, _unreadThings(std::make_unique<Api::UnreadThings>(this))
|
, _unreadThings(std::make_unique<Api::UnreadThings>(this))
|
||||||
, _ringtones(std::make_unique<Api::Ringtones>(this))
|
, _ringtones(std::make_unique<Api::Ringtones>(this))
|
||||||
, _transcribes(std::make_unique<Api::Transcribes>(this))
|
, _transcribes(std::make_unique<Api::Transcribes>(this))
|
||||||
, _premium(std::make_unique<Api::Premium>(this)) {
|
, _premium(std::make_unique<Api::Premium>(this))
|
||||||
|
, _usernames(std::make_unique<Api::Usernames>(this)) {
|
||||||
crl::on_main(session, [=] {
|
crl::on_main(session, [=] {
|
||||||
// You can't use _session->lifetime() in the constructor,
|
// You can't use _session->lifetime() in the constructor,
|
||||||
// only queued, because it is not constructed yet.
|
// only queued, because it is not constructed yet.
|
||||||
@ -4073,3 +4075,7 @@ Api::Transcribes &ApiWrap::transcribes() {
|
|||||||
Api::Premium &ApiWrap::premium() {
|
Api::Premium &ApiWrap::premium() {
|
||||||
return *_premium;
|
return *_premium;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Api::Usernames &ApiWrap::usernames() {
|
||||||
|
return *_usernames;
|
||||||
|
}
|
||||||
|
@ -77,6 +77,7 @@ class UnreadThings;
|
|||||||
class Ringtones;
|
class Ringtones;
|
||||||
class Transcribes;
|
class Transcribes;
|
||||||
class Premium;
|
class Premium;
|
||||||
|
class Usernames;
|
||||||
|
|
||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
@ -369,6 +370,7 @@ public:
|
|||||||
[[nodiscard]] Api::Ringtones &ringtones();
|
[[nodiscard]] Api::Ringtones &ringtones();
|
||||||
[[nodiscard]] Api::Transcribes &transcribes();
|
[[nodiscard]] Api::Transcribes &transcribes();
|
||||||
[[nodiscard]] Api::Premium &premium();
|
[[nodiscard]] Api::Premium &premium();
|
||||||
|
[[nodiscard]] Api::Usernames &usernames();
|
||||||
|
|
||||||
void updatePrivacyLastSeens();
|
void updatePrivacyLastSeens();
|
||||||
|
|
||||||
@ -675,6 +677,7 @@ private:
|
|||||||
const std::unique_ptr<Api::Ringtones> _ringtones;
|
const std::unique_ptr<Api::Ringtones> _ringtones;
|
||||||
const std::unique_ptr<Api::Transcribes> _transcribes;
|
const std::unique_ptr<Api::Transcribes> _transcribes;
|
||||||
const std::unique_ptr<Api::Premium> _premium;
|
const std::unique_ptr<Api::Premium> _premium;
|
||||||
|
const std::unique_ptr<Api::Usernames> _usernames;
|
||||||
|
|
||||||
mtpRequestId _wallPaperRequestId = 0;
|
mtpRequestId _wallPaperRequestId = 0;
|
||||||
QString _wallPaperSlug;
|
QString _wallPaperSlug;
|
||||||
|
20
Telegram/SourceFiles/data/data_user_names.h
Normal file
20
Telegram/SourceFiles/data/data_user_names.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
|
||||||
|
struct Username final {
|
||||||
|
QString username;
|
||||||
|
bool active = false;
|
||||||
|
bool editable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Usernames = std::vector<Username>;
|
||||||
|
|
||||||
|
} // namespace Data
|
Loading…
Reference in New Issue
Block a user