File: pin_messages_box.cpp

package info (click to toggle)
telegram-desktop 4.6.5%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 53,300 kB
  • sloc: cpp: 605,857; python: 3,978; ansic: 1,636; sh: 965; makefile: 841; objc: 652; javascript: 187; xml: 165
file content (122 lines) | stat: -rw-r--r-- 3,271 bytes parent folder | download
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
/*
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 "boxes/pin_messages_box.h"

#include "apiwrap.h"
#include "data/data_chat.h"
#include "data/data_user.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/boxes/confirm_box.h"
#include "ui/widgets/checkbox.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"

namespace {

[[nodiscard]] bool IsOldForPin(
		MsgId id,
		not_null<PeerData*> peer,
		MsgId topicRootId) {
	const auto normal = peer->migrateToOrMe();
	const auto migrated = normal->migrateFrom();
	const auto top = Data::ResolveTopPinnedId(normal, topicRootId, migrated);
	if (!top) {
		return false;
	} else if (peer == migrated) {
		return peerIsChannel(top.peer) || (id < top.msg);
	} else if (migrated) {
		return peerIsChannel(top.peer) && (id < top.msg);
	} else {
		return (id < top.msg);
	}
}

} // namespace

void PinMessageBox(
		not_null<Ui::GenericBox*> box,
		not_null<PeerData*> peer,
		MsgId msgId) {
	struct State {
		QPointer<Ui::Checkbox> pinForPeer;
		QPointer<Ui::Checkbox> notify;
		mtpRequestId requestId = 0;
	};

	const auto pinningOld = IsOldForPin(msgId, peer, MsgId(0));
	const auto state = box->lifetime().make_state<State>();
	const auto api = box->lifetime().make_state<MTP::Sender>(
		&peer->session().mtp());

	auto checkbox = [&]() -> object_ptr<Ui::Checkbox> {
		if (peer->isUser() && !peer->isSelf()) {
			auto object = object_ptr<Ui::Checkbox>(
				box,
				tr::lng_pinned_also_for_other(
					tr::now,
					lt_user,
					peer->shortName()),
				false,
				st::urlAuthCheckbox);
			object->setAllowTextLines();
			state->pinForPeer = Ui::MakeWeak(object.data());
			return object;
		} else if (!pinningOld && (peer->isChat() || peer->isMegagroup())) {
			auto object = object_ptr<Ui::Checkbox>(
				box,
				tr::lng_pinned_notify(tr::now),
				true,
				st::urlAuthCheckbox);
			object->setAllowTextLines();
			state->notify = Ui::MakeWeak(object.data());
			return object;
		}
		return { nullptr };
	}();

	auto pinMessage = [=] {
		if (state->requestId) {
			return;
		}

		auto flags = MTPmessages_UpdatePinnedMessage::Flags(0);
		if (state->notify && !state->notify->checked()) {
			flags |= MTPmessages_UpdatePinnedMessage::Flag::f_silent;
		}
		if (state->pinForPeer && !state->pinForPeer->checked()) {
			flags |= MTPmessages_UpdatePinnedMessage::Flag::f_pm_oneside;
		}
		state->requestId = api->request(MTPmessages_UpdatePinnedMessage(
			MTP_flags(flags),
			peer->input,
			MTP_int(msgId)
		)).done([=](const MTPUpdates &result) {
			peer->session().api().applyUpdates(result);
			box->closeBox();
		}).fail([=] {
			box->closeBox();
		}).send();
	};

	Ui::ConfirmBox(box, {
		.text = (pinningOld
			? tr::lng_pinned_pin_old_sure()
			: (peer->isChat() || peer->isMegagroup())
			? tr::lng_pinned_pin_sure_group()
			: tr::lng_pinned_pin_sure()),
		.confirmed = std::move(pinMessage),
		.confirmText = tr::lng_pinned_pin(),
	});

	if (checkbox) {
		auto padding = st::boxPadding;
		padding.setTop(padding.bottom());
		box->addRow(std::move(checkbox), std::move(padding));
	}
}