Compare commits
9 Commits
c1bcbede9b
...
7236ecc034
Author | SHA1 | Date |
---|---|---|
detiam | 7236ecc034 | |
23rd | 2c4d8418c1 | |
23rd | 9fcb5d6f31 | |
23rd | 38fc6bfbb9 | |
23rd | 804991a69c | |
23rd | 7388f46adf | |
John Preston | 10c427127e | |
John Preston | c6d034174b | |
detiam | 9409fb344f |
|
@ -546,7 +546,7 @@ rightsToggle: Toggle(defaultToggle) {
|
||||||
vsize: 5px;
|
vsize: 5px;
|
||||||
vshift: 1px;
|
vshift: 1px;
|
||||||
stroke: 2px;
|
stroke: 2px;
|
||||||
duration: 120;
|
duration: universalDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
rightsButton: SettingsButton(defaultSettingsButton) {
|
rightsButton: SettingsButton(defaultSettingsButton) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_user_names.h"
|
#include "api/api_user_names.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "base/event_filter.h"
|
||||||
#include "boxes/peers/edit_participants_box.h"
|
#include "boxes/peers/edit_participants_box.h"
|
||||||
#include "boxes/peers/edit_peer_color_box.h"
|
#include "boxes/peers/edit_peer_color_box.h"
|
||||||
#include "boxes/peers/edit_peer_common.h"
|
#include "boxes/peers/edit_peer_common.h"
|
||||||
|
@ -27,6 +28,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
#include "boxes/username_box.h"
|
#include "boxes/username_box.h"
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
|
#include "chat_helpers/tabbed_panel.h"
|
||||||
|
#include "chat_helpers/tabbed_selector.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
@ -47,6 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_app_config.h"
|
#include "main/main_app_config.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "ui/boxes/boost_box.h"
|
#include "ui/boxes/boost_box.h"
|
||||||
|
#include "ui/controls/emoji_button.h"
|
||||||
#include "ui/controls/userpic_button.h"
|
#include "ui/controls/userpic_button.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/vertical_list.h"
|
#include "ui/vertical_list.h"
|
||||||
|
@ -61,6 +65,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "api/api_invite_links.h"
|
#include "api/api_invite_links.h"
|
||||||
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -533,7 +538,7 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
|
||||||
_wrap,
|
_wrap,
|
||||||
object_ptr<Ui::InputField>(
|
object_ptr<Ui::InputField>(
|
||||||
_wrap,
|
_wrap,
|
||||||
st::defaultInputField,
|
st::editPeerTitleField,
|
||||||
(_isBot
|
(_isBot
|
||||||
? tr::lng_dlg_new_bot_name
|
? tr::lng_dlg_new_bot_name
|
||||||
: _isGroup
|
: _isGroup
|
||||||
|
@ -555,6 +560,76 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
|
||||||
submitTitle();
|
submitTitle();
|
||||||
}, result->entity()->lifetime());
|
}, result->entity()->lifetime());
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto field = result->entity();
|
||||||
|
const auto container = _box->getDelegate()->outerContainer();
|
||||||
|
using Selector = ChatHelpers::TabbedSelector;
|
||||||
|
using PanelPtr = base::unique_qptr<ChatHelpers::TabbedPanel>;
|
||||||
|
const auto emojiPanelPtr = field->lifetime().make_state<PanelPtr>(
|
||||||
|
base::make_unique_q<ChatHelpers::TabbedPanel>(
|
||||||
|
container,
|
||||||
|
ChatHelpers::TabbedPanelDescriptor{
|
||||||
|
.ownedSelector = object_ptr<Selector>(
|
||||||
|
nullptr,
|
||||||
|
ChatHelpers::TabbedSelectorDescriptor{
|
||||||
|
.show = _navigation->uiShow(),
|
||||||
|
.st = st::defaultComposeControls.tabbed,
|
||||||
|
.level = Window::GifPauseReason::Layer,
|
||||||
|
.mode = Selector::Mode::PeerTitle,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
const auto emojiPanel = emojiPanelPtr->get();
|
||||||
|
emojiPanel->setDesiredHeightValues(
|
||||||
|
1.,
|
||||||
|
st::emojiPanMinHeight / 2,
|
||||||
|
st::emojiPanMinHeight);
|
||||||
|
emojiPanel->hide();
|
||||||
|
emojiPanel->selector()->setCurrentPeer(_peer);
|
||||||
|
emojiPanel->selector()->emojiChosen(
|
||||||
|
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||||
|
Ui::InsertEmojiAtCursor(field->textCursor(), data.emoji);
|
||||||
|
field->setFocus();
|
||||||
|
}, field->lifetime());
|
||||||
|
emojiPanel->setDropDown(true);
|
||||||
|
|
||||||
|
const auto emojiToggle = Ui::CreateChild<Ui::EmojiButton>(
|
||||||
|
field,
|
||||||
|
st::defaultComposeControls.files.emoji);
|
||||||
|
emojiToggle->show();
|
||||||
|
emojiToggle->installEventFilter(emojiPanel);
|
||||||
|
emojiToggle->addClickHandler([=] { emojiPanel->toggleAnimated(); });
|
||||||
|
|
||||||
|
const auto updateEmojiPanelGeometry = [=] {
|
||||||
|
const auto parent = emojiPanel->parentWidget();
|
||||||
|
const auto global = emojiToggle->mapToGlobal({ 0, 0 });
|
||||||
|
const auto local = parent->mapFromGlobal(global);
|
||||||
|
emojiPanel->moveTopRight(
|
||||||
|
local.y() + emojiToggle->height(),
|
||||||
|
local.x() + emojiToggle->width() * 3);
|
||||||
|
};
|
||||||
|
|
||||||
|
base::install_event_filter(container, [=](not_null<QEvent*> event) {
|
||||||
|
const auto type = event->type();
|
||||||
|
if (type == QEvent::Move || type == QEvent::Resize) {
|
||||||
|
crl::on_main(field, [=] { updateEmojiPanelGeometry(); });
|
||||||
|
}
|
||||||
|
return base::EventFilterResult::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
|
field->widthValue() | rpl::start_with_next([=](int width) {
|
||||||
|
const auto &p = st::editPeerTitleEmojiPosition;
|
||||||
|
emojiToggle->moveToRight(p.x(), p.y(), width);
|
||||||
|
updateEmojiPanelGeometry();
|
||||||
|
}, emojiToggle->lifetime());
|
||||||
|
|
||||||
|
base::install_event_filter(emojiToggle, [=](not_null<QEvent*> event) {
|
||||||
|
if (event->type() == QEvent::Enter) {
|
||||||
|
updateEmojiPanelGeometry();
|
||||||
|
}
|
||||||
|
return base::EventFilterResult::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_controls.title = result->entity();
|
_controls.title = result->entity();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
#include "styles/style_basic.h"
|
||||||
#include "styles/style_calls.h"
|
#include "styles/style_calls.h"
|
||||||
#include "styles/style_chat_helpers.h" // style::GroupCallUserpics
|
#include "styles/style_chat_helpers.h" // style::GroupCallUserpics
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
@ -49,7 +50,6 @@ enum class BarState {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kUpdateDebugTimeoutMs = crl::time(500);
|
constexpr auto kUpdateDebugTimeoutMs = crl::time(500);
|
||||||
constexpr auto kSwitchStateDuration = 120;
|
|
||||||
|
|
||||||
constexpr auto kMinorBlobAlpha = 76. / 255.;
|
constexpr auto kMinorBlobAlpha = 76. / 255.;
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ void TopBar::initControls() {
|
||||||
};
|
};
|
||||||
|
|
||||||
_switchStateAnimation.stop();
|
_switchStateAnimation.stop();
|
||||||
const auto duration = (to - from) * kSwitchStateDuration;
|
const auto duration = (to - from) * st::universalDuration;
|
||||||
_switchStateAnimation.start(
|
_switchStateAnimation.start(
|
||||||
_switchStateCallback,
|
_switchStateCallback,
|
||||||
from,
|
from,
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/widgets/fields/input_field.h"
|
#include "ui/widgets/fields/input_field.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "styles/style_basic.h"
|
||||||
#include "styles/style_calls.h"
|
#include "styles/style_calls.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -26,7 +27,6 @@ namespace {
|
||||||
constexpr auto kRoundRadius = 9;
|
constexpr auto kRoundRadius = 9;
|
||||||
constexpr auto kMaxGroupCallLength = 40;
|
constexpr auto kMaxGroupCallLength = 40;
|
||||||
constexpr auto kSwitchDuration = 200;
|
constexpr auto kSwitchDuration = 200;
|
||||||
constexpr auto kSelectDuration = 120;
|
|
||||||
|
|
||||||
class GraphicButton final : public Ui::AbstractButton {
|
class GraphicButton final : public Ui::AbstractButton {
|
||||||
public:
|
public:
|
||||||
|
@ -103,7 +103,7 @@ void GraphicButton::setToggled(bool value) {
|
||||||
[=] { update(); },
|
[=] { update(); },
|
||||||
_toggled ? 0. : 1.,
|
_toggled ? 0. : 1.,
|
||||||
_toggled ? 1. : 0.,
|
_toggled ? 1. : 0.,
|
||||||
kSelectDuration);
|
st::universalDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicButton::paintEvent(QPaintEvent *e) {
|
void GraphicButton::paintEvent(QPaintEvent *e) {
|
||||||
|
|
|
@ -1108,8 +1108,6 @@ historyRecordVoiceFgOver: historyComposeIconFgOver;
|
||||||
historyRecordVoiceFgInactive: attentionButtonFg;
|
historyRecordVoiceFgInactive: attentionButtonFg;
|
||||||
historyRecordVoiceFgActive: windowBgActive;
|
historyRecordVoiceFgActive: windowBgActive;
|
||||||
historyRecordVoiceFgActiveIcon: windowFgActive;
|
historyRecordVoiceFgActiveIcon: windowFgActive;
|
||||||
historyRecordVoiceShowDuration: 120;
|
|
||||||
historyRecordVoiceDuration: 120;
|
|
||||||
historyRecordVoice: icon {{ "chat/input_record", historyRecordVoiceFg }};
|
historyRecordVoice: icon {{ "chat/input_record", historyRecordVoiceFg }};
|
||||||
historyRecordVoiceOver: icon {{ "chat/input_record", historyRecordVoiceFgOver }};
|
historyRecordVoiceOver: icon {{ "chat/input_record", historyRecordVoiceFgOver }};
|
||||||
historyRecordVoiceOnceBg: icon {{ "voice_lock/audio_once_bg", historySendIconFg }};
|
historyRecordVoiceOnceBg: icon {{ "voice_lock/audio_once_bg", historySendIconFg }};
|
||||||
|
|
|
@ -468,7 +468,8 @@ EmojiListWidget::EmojiListWidget(
|
||||||
std::move(descriptor.paused))
|
std::move(descriptor.paused))
|
||||||
, _show(std::move(descriptor.show))
|
, _show(std::move(descriptor.show))
|
||||||
, _features(descriptor.features)
|
, _features(descriptor.features)
|
||||||
, _mode(descriptor.mode)
|
, _onlyUnicodeEmoji(descriptor.mode == Mode::PeerTitle)
|
||||||
|
, _mode(_onlyUnicodeEmoji ? Mode::Full : descriptor.mode)
|
||||||
, _api(&session().mtp())
|
, _api(&session().mtp())
|
||||||
, _staticCount(_mode == Mode::Full ? kEmojiSectionCount : 1)
|
, _staticCount(_mode == Mode::Full ? kEmojiSectionCount : 1)
|
||||||
, _premiumIcon(_mode == Mode::EmojiStatus
|
, _premiumIcon(_mode == Mode::EmojiStatus
|
||||||
|
@ -490,7 +491,8 @@ EmojiListWidget::EmojiListWidget(
|
||||||
|
|
||||||
if (_mode != Mode::RecentReactions
|
if (_mode != Mode::RecentReactions
|
||||||
&& _mode != Mode::BackgroundEmoji
|
&& _mode != Mode::BackgroundEmoji
|
||||||
&& _mode != Mode::ChannelStatus) {
|
&& _mode != Mode::ChannelStatus
|
||||||
|
&& !_onlyUnicodeEmoji) {
|
||||||
setupSearch();
|
setupSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1052,7 +1054,7 @@ void EmojiListWidget::fillRecent() {
|
||||||
const auto test = session().isTestMode();
|
const auto test = session().isTestMode();
|
||||||
for (const auto &one : list) {
|
for (const auto &one : list) {
|
||||||
const auto document = std::get_if<RecentEmojiDocument>(&one.id.data);
|
const auto document = std::get_if<RecentEmojiDocument>(&one.id.data);
|
||||||
if (document && document->test != test) {
|
if (document && ((document->test != test) || _onlyUnicodeEmoji)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_recent.push_back({
|
_recent.push_back({
|
||||||
|
@ -2129,7 +2131,9 @@ void EmojiListWidget::refreshCustom() {
|
||||||
auto old = base::take(_custom);
|
auto old = base::take(_custom);
|
||||||
const auto session = &this->session();
|
const auto session = &this->session();
|
||||||
const auto premiumPossible = session->premiumPossible();
|
const auto premiumPossible = session->premiumPossible();
|
||||||
const auto premiumMayBeBought = premiumPossible
|
const auto onlyUnicodeEmoji = _onlyUnicodeEmoji || !premiumPossible;
|
||||||
|
const auto premiumMayBeBought = (!onlyUnicodeEmoji)
|
||||||
|
&& premiumPossible
|
||||||
&& !session->premium()
|
&& !session->premium()
|
||||||
&& !_allowWithoutPremium;
|
&& !_allowWithoutPremium;
|
||||||
const auto owner = &session->data();
|
const auto owner = &session->data();
|
||||||
|
@ -2189,7 +2193,7 @@ void EmojiListWidget::refreshCustom() {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}();
|
}();
|
||||||
if (premium && !premiumPossible) {
|
if (premium && onlyUnicodeEmoji) {
|
||||||
return;
|
return;
|
||||||
} else if (valid) {
|
} else if (valid) {
|
||||||
i->thumbnailDocument = it->second->lookupThumbnailDocument();
|
i->thumbnailDocument = it->second->lookupThumbnailDocument();
|
||||||
|
@ -2223,7 +2227,7 @@ void EmojiListWidget::refreshCustom() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (premium && !premiumPossible) {
|
if (premium && onlyUnicodeEmoji) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_custom.push_back({
|
_custom.push_back({
|
||||||
|
|
|
@ -76,6 +76,7 @@ enum class EmojiListMode {
|
||||||
RecentReactions,
|
RecentReactions,
|
||||||
UserpicBuilder,
|
UserpicBuilder,
|
||||||
BackgroundEmoji,
|
BackgroundEmoji,
|
||||||
|
PeerTitle,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EmojiListDescriptor {
|
struct EmojiListDescriptor {
|
||||||
|
@ -379,6 +380,7 @@ private:
|
||||||
|
|
||||||
const std::shared_ptr<Show> _show;
|
const std::shared_ptr<Show> _show;
|
||||||
const ComposeFeatures _features;
|
const ComposeFeatures _features;
|
||||||
|
const bool _onlyUnicodeEmoji;
|
||||||
Mode _mode = Mode::Full;
|
Mode _mode = Mode::Full;
|
||||||
std::unique_ptr<Ui::TabbedSearch> _search;
|
std::unique_ptr<Ui::TabbedSearch> _search;
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
|
|
|
@ -38,7 +38,6 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kShowExactDelay = crl::time(300);
|
constexpr auto kShowExactDelay = crl::time(300);
|
||||||
constexpr auto kMaxNonScrolledEmoji = 7;
|
constexpr auto kMaxNonScrolledEmoji = 7;
|
||||||
constexpr auto kAnimationDuration = crl::time(120);
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -528,7 +527,7 @@ void SuggestionsWidget::setSelected(int selected, anim::type animated) {
|
||||||
[=] { update(); },
|
[=] { update(); },
|
||||||
_selected,
|
_selected,
|
||||||
selected,
|
selected,
|
||||||
kAnimationDuration,
|
st::universalDuration,
|
||||||
anim::sineInOut);
|
anim::sineInOut);
|
||||||
if (_scrollMax > 0) {
|
if (_scrollMax > 0) {
|
||||||
const auto selectedMax = int(_rows.size()) - 3;
|
const auto selectedMax = int(_rows.size()) - 3;
|
||||||
|
@ -560,7 +559,7 @@ void SuggestionsWidget::scrollTo(int value, anim::type animated) {
|
||||||
[=] { update(); },
|
[=] { update(); },
|
||||||
_scrollValue,
|
_scrollValue,
|
||||||
value,
|
value,
|
||||||
kAnimationDuration,
|
st::universalDuration,
|
||||||
anim::sineInOut);
|
anim::sineInOut);
|
||||||
}
|
}
|
||||||
_scrollValue = value;
|
_scrollValue = value;
|
||||||
|
|
|
@ -540,6 +540,8 @@ TabbedSelector::Tab TabbedSelector::createTab(SelectorTab type, int index) {
|
||||||
? EmojiMode::FullReactions
|
? EmojiMode::FullReactions
|
||||||
: _mode == Mode::RecentReactions
|
: _mode == Mode::RecentReactions
|
||||||
? EmojiMode::RecentReactions
|
? EmojiMode::RecentReactions
|
||||||
|
: _mode == Mode::PeerTitle
|
||||||
|
? EmojiMode::PeerTitle
|
||||||
: EmojiMode::Full),
|
: EmojiMode::Full),
|
||||||
.customTextColor = _customTextColor,
|
.customTextColor = _customTextColor,
|
||||||
.paused = paused,
|
.paused = paused,
|
||||||
|
@ -958,6 +960,9 @@ void TabbedSelector::beforeHiding() {
|
||||||
_beforeHidingCallback(_currentTabType);
|
_beforeHidingCallback(_currentTabType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Ui::InFocusChain(this)) {
|
||||||
|
window()->setFocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::afterShown() {
|
void TabbedSelector::afterShown() {
|
||||||
|
|
|
@ -86,6 +86,7 @@ enum class TabbedSelectorMode {
|
||||||
BackgroundEmoji,
|
BackgroundEmoji,
|
||||||
FullReactions,
|
FullReactions,
|
||||||
RecentReactions,
|
RecentReactions,
|
||||||
|
PeerTitle,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TabbedSelectorDescriptor {
|
struct TabbedSelectorDescriptor {
|
||||||
|
|
|
@ -116,7 +116,7 @@ dialogsSpeakingDenominator: 8.;
|
||||||
|
|
||||||
dialogsImportantBarHeight: 37px;
|
dialogsImportantBarHeight: 37px;
|
||||||
|
|
||||||
dialogsWidthDuration: 120;
|
dialogsWidthDuration: universalDuration;
|
||||||
dialogsTextWidthMin: 150px;
|
dialogsTextWidthMin: 150px;
|
||||||
|
|
||||||
dialogsTextPalette: TextPalette(defaultTextPalette) {
|
dialogsTextPalette: TextPalette(defaultTextPalette) {
|
||||||
|
|
|
@ -290,7 +290,10 @@ RecentRow::RecentRow(not_null<PeerData*> peer)
|
||||||
} else if (const auto chat = peer->asChat()) {
|
} else if (const auto chat = peer->asChat()) {
|
||||||
if (chat->count > 0) {
|
if (chat->count > 0) {
|
||||||
setCustomStatus(
|
setCustomStatus(
|
||||||
tr::lng_chat_status_members(tr::now, lt_count, chat->count));
|
tr::lng_chat_status_members(
|
||||||
|
tr::now,
|
||||||
|
lt_count_decimal,
|
||||||
|
chat->count));
|
||||||
}
|
}
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
if (channel->membersCountKnown()) {
|
if (channel->membersCountKnown()) {
|
||||||
|
@ -298,7 +301,7 @@ RecentRow::RecentRow(not_null<PeerData*> peer)
|
||||||
? tr::lng_chat_status_subscribers
|
? tr::lng_chat_status_subscribers
|
||||||
: tr::lng_chat_status_members)(
|
: tr::lng_chat_status_members)(
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_count,
|
lt_count_decimal,
|
||||||
channel->membersCount()));
|
channel->membersCount()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,7 +658,7 @@ void MyChannelsController::appendRow(not_null<ChannelData*> channel) {
|
||||||
? tr::lng_chat_status_subscribers
|
? tr::lng_chat_status_subscribers
|
||||||
: tr::lng_chat_status_members)(
|
: tr::lng_chat_status_members)(
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_count,
|
lt_count_decimal,
|
||||||
channel->membersCount()));
|
channel->membersCount()));
|
||||||
}
|
}
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
|
@ -819,7 +822,7 @@ void RecommendationsController::appendRow(not_null<ChannelData*> channel) {
|
||||||
? tr::lng_chat_status_subscribers
|
? tr::lng_chat_status_subscribers
|
||||||
: tr::lng_chat_status_members)(
|
: tr::lng_chat_status_members)(
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_count,
|
lt_count_decimal,
|
||||||
channel->membersCount()));
|
channel->membersCount()));
|
||||||
}
|
}
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
|
|
|
@ -302,7 +302,7 @@ TTLButton::TTLButton(
|
||||||
[=] { update(); },
|
[=] { update(); },
|
||||||
isActive ? 0. : 1.,
|
isActive ? 0. : 1.,
|
||||||
isActive ? 1. : 0.,
|
isActive ? 1. : 0.,
|
||||||
st::historyRecordVoiceShowDuration);
|
st::universalDuration);
|
||||||
});
|
});
|
||||||
|
|
||||||
Ui::RpWidget::shownValue() | rpl::start_with_next([=](bool shown) {
|
Ui::RpWidget::shownValue() | rpl::start_with_next([=](bool shown) {
|
||||||
|
@ -1058,9 +1058,11 @@ void RecordLock::drawProgress(QPainter &p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordLock::startLockingAnimation(float64 to) {
|
void RecordLock::startLockingAnimation(float64 to) {
|
||||||
auto callback = [=](float64 value) { setProgress(value); };
|
_lockEnderAnimation.start(
|
||||||
const auto &duration = st::historyRecordVoiceShowDuration;
|
[=](float64 value) { setProgress(value); },
|
||||||
_lockEnderAnimation.start(std::move(callback), 0., to, duration);
|
0.,
|
||||||
|
to,
|
||||||
|
st::universalDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordLock::requestPaintProgress(float64 progress) {
|
void RecordLock::requestPaintProgress(float64 progress) {
|
||||||
|
@ -1453,7 +1455,7 @@ void VoiceRecordBar::init() {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
_listen = nullptr;
|
_listen = nullptr;
|
||||||
}
|
}
|
||||||
}, 1., 0., st::historyRecordVoiceShowDuration * 2);
|
}, 1., 0., st::universalDuration * 2);
|
||||||
setLevelAsSend();
|
setLevelAsSend();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1473,7 +1475,6 @@ void VoiceRecordBar::init() {
|
||||||
// _lockShowing = false;
|
// _lockShowing = false;
|
||||||
|
|
||||||
const auto to = 1.;
|
const auto to = 1.;
|
||||||
const auto &duration = st::historyRecordVoiceShowDuration;
|
|
||||||
auto callback = [=](float64 value) {
|
auto callback = [=](float64 value) {
|
||||||
paintShowListenCallback(value);
|
paintShowListenCallback(value);
|
||||||
if (to == value) {
|
if (to == value) {
|
||||||
|
@ -1481,7 +1482,11 @@ void VoiceRecordBar::init() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_showListenAnimation.stop();
|
_showListenAnimation.stop();
|
||||||
_showListenAnimation.start(std::move(callback), 0., to, duration);
|
_showListenAnimation.start(
|
||||||
|
std::move(callback),
|
||||||
|
0.,
|
||||||
|
to,
|
||||||
|
st::universalDuration);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
_lock->locks(
|
_lock->locks(
|
||||||
|
@ -1498,15 +1503,16 @@ void VoiceRecordBar::init() {
|
||||||
|
|
||||||
setLevelAsSend();
|
setLevelAsSend();
|
||||||
|
|
||||||
const auto &duration = st::historyRecordVoiceShowDuration;
|
|
||||||
const auto from = 0.;
|
|
||||||
const auto to = 1.;
|
|
||||||
auto callback = [=](float64 value) {
|
auto callback = [=](float64 value) {
|
||||||
_lock->requestPaintLockToStopProgress(value);
|
_lock->requestPaintLockToStopProgress(value);
|
||||||
update();
|
update();
|
||||||
updateTTLGeometry(TTLAnimationType::RightLeft, value);
|
updateTTLGeometry(TTLAnimationType::RightLeft, value);
|
||||||
};
|
};
|
||||||
_lockToStopAnimation.start(std::move(callback), from, to, duration);
|
_lockToStopAnimation.start(
|
||||||
|
std::move(callback),
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
st::universalDuration);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
_send->events(
|
_send->events(
|
||||||
|
@ -1523,7 +1529,7 @@ void VoiceRecordBar::init() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_recordingTipRequired = true;
|
_recordingTipRequired = true;
|
||||||
_startTimer.callOnce(st::historyRecordVoiceShowDuration);
|
_startTimer.callOnce(st::universalDuration);
|
||||||
} else if (e->type() == QEvent::MouseButtonRelease) {
|
} else if (e->type() == QEvent::MouseButtonRelease) {
|
||||||
if (base::take(_recordingTipRequired)) {
|
if (base::take(_recordingTipRequired)) {
|
||||||
_recordingTipRequests.fire({});
|
_recordingTipRequests.fire({});
|
||||||
|
@ -1556,23 +1562,24 @@ void VoiceRecordBar::init() {
|
||||||
|
|
||||||
void VoiceRecordBar::activeAnimate(bool active) {
|
void VoiceRecordBar::activeAnimate(bool active) {
|
||||||
const auto to = active ? 1. : 0.;
|
const auto to = active ? 1. : 0.;
|
||||||
const auto &duration = st::historyRecordVoiceDuration;
|
|
||||||
if (_activeAnimation.animating()) {
|
if (_activeAnimation.animating()) {
|
||||||
_activeAnimation.change(to, duration);
|
_activeAnimation.change(to, st::universalDuration);
|
||||||
} else {
|
} else {
|
||||||
auto callback = [=] {
|
auto callback = [=] {
|
||||||
update(_messageRect);
|
update(_messageRect);
|
||||||
_level->requestPaintColor(activeAnimationRatio());
|
_level->requestPaintColor(activeAnimationRatio());
|
||||||
};
|
};
|
||||||
const auto from = active ? 0. : 1.;
|
_activeAnimation.start(
|
||||||
_activeAnimation.start(std::move(callback), from, to, duration);
|
std::move(callback),
|
||||||
|
active ? 0. : 1.,
|
||||||
|
to,
|
||||||
|
st::universalDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceRecordBar::visibilityAnimate(bool show, Fn<void()> &&callback) {
|
void VoiceRecordBar::visibilityAnimate(bool show, Fn<void()> &&callback) {
|
||||||
const auto to = show ? 1. : 0.;
|
const auto to = show ? 1. : 0.;
|
||||||
const auto from = show ? 0. : 1.;
|
const auto from = show ? 0. : 1.;
|
||||||
const auto &duration = st::historyRecordVoiceShowDuration;
|
|
||||||
auto animationCallback = [=, callback = std::move(callback)](auto value) {
|
auto animationCallback = [=, callback = std::move(callback)](auto value) {
|
||||||
if (!_listen) {
|
if (!_listen) {
|
||||||
_level->requestPaintProgress(value);
|
_level->requestPaintProgress(value);
|
||||||
|
@ -1589,7 +1596,11 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn<void()> &&callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_showAnimation.start(std::move(animationCallback), from, to, duration);
|
_showAnimation.start(
|
||||||
|
std::move(animationCallback),
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
st::universalDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceRecordBar::setStartRecordingFilter(FilterCallback &&callback) {
|
void VoiceRecordBar::setStartRecordingFilter(FilterCallback &&callback) {
|
||||||
|
|
|
@ -196,8 +196,8 @@ void VoiceRecordButton::init() {
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
};
|
};
|
||||||
const auto duration = st::historyRecordVoiceDuration * 2;
|
constexpr auto kDuration = st::universalDuration * 2;
|
||||||
_stateChangedAnimation.start(std::move(callback), 0., to, duration);
|
_stateChangedAnimation.start(std::move(callback), 0., to, kDuration);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,8 +548,6 @@ QSize WebPage::countCurrentSize(int newWidth) {
|
||||||
const auto twoTitleLines = 2 * st::webPageTitleFont->height;
|
const auto twoTitleLines = 2 * st::webPageTitleFont->height;
|
||||||
const auto descriptionLineHeight = st::webPageDescriptionFont->height;
|
const auto descriptionLineHeight = st::webPageDescriptionFont->height;
|
||||||
if (asArticle() || specialRightPix) {
|
if (asArticle() || specialRightPix) {
|
||||||
const auto sponsoredUserpic = (_sponsoredData
|
|
||||||
&& _sponsoredData->peer);
|
|
||||||
constexpr auto kSponsoredUserpicLines = 2;
|
constexpr auto kSponsoredUserpicLines = 2;
|
||||||
_pixh = lineHeight
|
_pixh = lineHeight
|
||||||
* (_stickerSet
|
* (_stickerSet
|
||||||
|
@ -576,8 +574,7 @@ QSize WebPage::countCurrentSize(int newWidth) {
|
||||||
newHeight += _titleLines * lineHeight;
|
newHeight += _titleLines * lineHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto descriptionHeight = _description.countHeight(
|
const auto descriptionHeight = _description.countHeight(wleft);
|
||||||
sponsoredUserpic ? innerWidth : wleft);
|
|
||||||
const auto restLines = (linesMax - _siteNameLines - _titleLines);
|
const auto restLines = (linesMax - _siteNameLines - _titleLines);
|
||||||
if (descriptionHeight < restLines * descriptionLineHeight) {
|
if (descriptionHeight < restLines * descriptionLineHeight) {
|
||||||
// We have height for all the lines.
|
// We have height for all the lines.
|
||||||
|
@ -677,7 +674,6 @@ void WebPage::ensurePhotoMediaCreated() const {
|
||||||
|
|
||||||
bool WebPage::hasHeavyPart() const {
|
bool WebPage::hasHeavyPart() const {
|
||||||
return _photoMedia
|
return _photoMedia
|
||||||
|| (_sponsoredData && !_sponsoredData->userpicView.null())
|
|
||||||
|| (_stickerSet)
|
|| (_stickerSet)
|
||||||
|| (_attach ? _attach->hasHeavyPart() : false);
|
|| (_attach ? _attach->hasHeavyPart() : false);
|
||||||
}
|
}
|
||||||
|
@ -688,9 +684,6 @@ void WebPage::unloadHeavyPart() {
|
||||||
}
|
}
|
||||||
_description.unloadPersistentAnimation();
|
_description.unloadPersistentAnimation();
|
||||||
_photoMedia = nullptr;
|
_photoMedia = nullptr;
|
||||||
if (_sponsoredData) {
|
|
||||||
_sponsoredData->userpicView = Ui::PeerUserpicView();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPage::draw(Painter &p, const PaintContext &context) const {
|
void WebPage::draw(Painter &p, const PaintContext &context) const {
|
||||||
|
@ -834,21 +827,6 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
|
||||||
// as its width only affects the title.
|
// as its width only affects the title.
|
||||||
paintw -= pw + st::webPagePhotoDelta;
|
paintw -= pw + st::webPagePhotoDelta;
|
||||||
}
|
}
|
||||||
} else if (asSponsored && _sponsoredData->peer) {
|
|
||||||
const auto size = _pixh;
|
|
||||||
const auto sizeHq = size * style::DevicePixelRatio();
|
|
||||||
const auto userpicPos = QPoint(inner.left() + paintw - size, tshift);
|
|
||||||
const auto &peer = _sponsoredData->peer;
|
|
||||||
auto &view = _sponsoredData->userpicView;
|
|
||||||
if (const auto cloud = peer->userpicCloudImage(view)) {
|
|
||||||
Ui::ValidateUserpicCache(view, cloud, nullptr, sizeHq, true);
|
|
||||||
p.drawImage(QRect(userpicPos, QSize(size, size)), view.cached);
|
|
||||||
} else {
|
|
||||||
const auto r = sizeHq * Ui::ForumUserpicRadiusMultiplier();
|
|
||||||
const auto empty = peer->generateUserpicImage(view, sizeHq, r);
|
|
||||||
p.drawImage(QRect(userpicPos, QSize(size, size)), empty);
|
|
||||||
}
|
|
||||||
// paintw -= size + st::webPagePhotoDelta;
|
|
||||||
}
|
}
|
||||||
if (_siteNameLines) {
|
if (_siteNameLines) {
|
||||||
p.setPen(cache->icon);
|
p.setPen(cache->icon);
|
||||||
|
|
|
@ -139,8 +139,6 @@ private:
|
||||||
std::unique_ptr<StickerSet> _stickerSet;
|
std::unique_ptr<StickerSet> _stickerSet;
|
||||||
|
|
||||||
struct SponsoredData final {
|
struct SponsoredData final {
|
||||||
PeerData *peer = nullptr;
|
|
||||||
Ui::PeerUserpicView userpicView;
|
|
||||||
QString buttonText;
|
QString buttonText;
|
||||||
bool isLinkInternal = false;
|
bool isLinkInternal = false;
|
||||||
|
|
||||||
|
|
|
@ -722,6 +722,10 @@ editPeerHistoryVisibilityTopSkip: 8px;
|
||||||
editPeerPhotoMargins: margins(22px, 8px, 22px, 8px);
|
editPeerPhotoMargins: margins(22px, 8px, 22px, 8px);
|
||||||
editPeerTitle: defaultInputField;
|
editPeerTitle: defaultInputField;
|
||||||
editPeerTitleMargins: margins(27px, 13px, 22px, 8px);
|
editPeerTitleMargins: margins(27px, 13px, 22px, 8px);
|
||||||
|
editPeerTitleEmojiPosition: point(0px, 23px);
|
||||||
|
editPeerTitleField: InputField(defaultInputField) {
|
||||||
|
textMargins: margins(0px, 28px, 30px, 4px);
|
||||||
|
}
|
||||||
editPeerDescription: InputField(defaultInputField) {
|
editPeerDescription: InputField(defaultInputField) {
|
||||||
textBg: transparent;
|
textBg: transparent;
|
||||||
textMargins: margins(0px, 7px, 0px, 7px);
|
textMargins: margins(0px, 7px, 0px, 7px);
|
||||||
|
|
|
@ -58,7 +58,16 @@ void PickUntilBox(not_null<Ui::GenericBox*> box, Fn<void(TimeId)> callback) {
|
||||||
|
|
||||||
EmojiStatusPanel::EmojiStatusPanel() = default;
|
EmojiStatusPanel::EmojiStatusPanel() = default;
|
||||||
|
|
||||||
EmojiStatusPanel::~EmojiStatusPanel() = default;
|
EmojiStatusPanel::~EmojiStatusPanel() {
|
||||||
|
if (hasFocus()) {
|
||||||
|
// Panel will try to return focus to the layer widget, the problem is
|
||||||
|
// we are destroying the layer widget probably right now and focusing
|
||||||
|
// it will lead to a crash, because it destroys its children (how we
|
||||||
|
// got here) after it clears focus out of itself. So if you return
|
||||||
|
// the focus inside a child destructor, it won't be cleared at all.
|
||||||
|
_panel->window()->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiStatusPanel::setChooseFilter(Fn<bool(DocumentId)> filter) {
|
void EmojiStatusPanel::setChooseFilter(Fn<bool(DocumentId)> filter) {
|
||||||
_chooseFilter = std::move(filter);
|
_chooseFilter = std::move(filter);
|
||||||
|
|
|
@ -66,5 +66,3 @@ userpicBuilderEmojiColorPlus: IconButton(userpicBuilderEmojiColorMinus) {
|
||||||
}
|
}
|
||||||
|
|
||||||
userpicBuilderEmojiToggleStickersIcon: icon {{ "menu/stickers", emojiIconFg }};
|
userpicBuilderEmojiToggleStickersIcon: icon {{ "menu/stickers", emojiIconFg }};
|
||||||
|
|
||||||
userpicBuilderEmojiSlideDuration: 120;
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ void ColorsLine::fillButtons() {
|
||||||
wasChosen->setSelectedProgress(1. - progress);
|
wasChosen->setSelectedProgress(1. - progress);
|
||||||
}
|
}
|
||||||
nowChosen->setSelectedProgress(progress);
|
nowChosen->setSelectedProgress(progress);
|
||||||
}, 0., 1., st::userpicBuilderEmojiSlideDuration);
|
}, 0., 1., st::universalDuration);
|
||||||
});
|
});
|
||||||
if (i < _colors->size()) {
|
if (i < _colors->size()) {
|
||||||
button->setBrush((*_colors)[i]);
|
button->setBrush((*_colors)[i]);
|
||||||
|
@ -164,7 +164,7 @@ void ColorsLine::fillButtons() {
|
||||||
setLastChosen();
|
setLastChosen();
|
||||||
});
|
});
|
||||||
for (const auto &wrap : _wraps) {
|
for (const auto &wrap : _wraps) {
|
||||||
wrap->setDuration(st::userpicBuilderEmojiSlideDuration);
|
wrap->setDuration(st::universalDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ void ColorsLine::processChange(
|
||||||
const auto left = anim::interpolate(wasLeft, nowLeft, value);
|
const auto left = anim::interpolate(wasLeft, nowLeft, value);
|
||||||
_wraps[i]->moveToLeft(left, 0);
|
_wraps[i]->moveToLeft(left, 0);
|
||||||
}
|
}
|
||||||
}, 0., 1., st::userpicBuilderEmojiSlideDuration);
|
}, 0., 1., st::universalDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorsLine::setLastChosen() const {
|
void ColorsLine::setLastChosen() const {
|
||||||
|
|
|
@ -493,7 +493,7 @@ not_null<Ui::VerticalLayout*> CreateUserpicBuilder(
|
||||||
1. - progress);
|
1. - progress);
|
||||||
}
|
}
|
||||||
state->circleButtons[now]->setSelectedProgress(progress);
|
state->circleButtons[now]->setSelectedProgress(progress);
|
||||||
}, 0., 1., st::userpicBuilderEmojiSlideDuration);
|
}, 0., 1., st::universalDuration);
|
||||||
state->colorIndex = now;
|
state->colorIndex = now;
|
||||||
|
|
||||||
const auto result = isSpecial
|
const auto result = isSpecial
|
||||||
|
|
|
@ -1491,7 +1491,7 @@ void AttachWebView::show(
|
||||||
_catchingCancelInShowCall = true;
|
_catchingCancelInShowCall = true;
|
||||||
_panel = Ui::BotWebView::Show({
|
_panel = Ui::BotWebView::Show({
|
||||||
.url = url,
|
.url = url,
|
||||||
.userDataPath = _session->domain().local().webviewDataPath(),
|
.storageId = _session->local().resolveStorageIdBots(),
|
||||||
.title = std::move(title),
|
.title = std::move(title),
|
||||||
.bottom = rpl::single('@' + _bot->username()),
|
.bottom = rpl::single('@' + _bot->username()),
|
||||||
.delegate = static_cast<Ui::BotWebView::Delegate*>(this),
|
.delegate = static_cast<Ui::BotWebView::Delegate*>(this),
|
||||||
|
|
|
@ -119,7 +119,6 @@ introCodeDigitFont: font(20px);
|
||||||
introCodeDigitHeight: 50px;
|
introCodeDigitHeight: 50px;
|
||||||
introCodeDigitBorderWidth: 4px;
|
introCodeDigitBorderWidth: 4px;
|
||||||
introCodeDigitSkip: 10px;
|
introCodeDigitSkip: 10px;
|
||||||
introCodeDigitAnimatioDuration: 120;
|
|
||||||
|
|
||||||
introPasswordHint: FlatLabel(introDescription) {
|
introPasswordHint: FlatLabel(introDescription) {
|
||||||
textFg: windowFg;
|
textFg: windowFg;
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/rect.h"
|
#include "ui/rect.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
#include "styles/style_basic.h"
|
||||||
#include "styles/style_intro.h"
|
#include "styles/style_intro.h"
|
||||||
#include "styles/style_layers.h" // boxRadius
|
#include "styles/style_layers.h" // boxRadius
|
||||||
|
|
||||||
|
@ -91,7 +92,6 @@ void CodeDigit::setDigit(int digit) {
|
||||||
}
|
}
|
||||||
_dataDigit = digit;
|
_dataDigit = digit;
|
||||||
if (_viewDigit != digit) {
|
if (_viewDigit != digit) {
|
||||||
constexpr auto kDuration = st::introCodeDigitAnimatioDuration;
|
|
||||||
_animation.stop();
|
_animation.stop();
|
||||||
if (digit == kDigitNone) {
|
if (digit == kDigitNone) {
|
||||||
_animation.start([=](float64 value) {
|
_animation.start([=](float64 value) {
|
||||||
|
@ -99,10 +99,10 @@ void CodeDigit::setDigit(int digit) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
_viewDigit = digit;
|
_viewDigit = digit;
|
||||||
}
|
}
|
||||||
}, 1., 0., kDuration);
|
}, 1., 0., st::universalDuration);
|
||||||
} else {
|
} else {
|
||||||
_viewDigit = digit;
|
_viewDigit = digit;
|
||||||
_animation.start([=] { update(); }, 0., 1., kDuration);
|
_animation.start([=] { update(); }, 0, 1., st::universalDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,6 +224,7 @@ void Step::createSession(
|
||||||
account->createSession(user, std::move(settings));
|
account->createSession(user, std::move(settings));
|
||||||
|
|
||||||
// "this" is already deleted here by creating the main widget.
|
// "this" is already deleted here by creating the main widget.
|
||||||
|
account->local().enforceModernStorageIdBots();
|
||||||
account->local().writeMtpData();
|
account->local().writeMtpData();
|
||||||
auto &session = account->session();
|
auto &session = account->session();
|
||||||
session.data().chatsFilters().setPreloaded(filters);
|
session.data().chatsFilters().setPreloaded(filters);
|
||||||
|
|
|
@ -292,12 +292,12 @@ void Controller::initControls() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::show(
|
void Controller::show(
|
||||||
const QString &dataPath,
|
const Webview::StorageId &storageId,
|
||||||
Prepared page,
|
Prepared page,
|
||||||
base::flat_map<QByteArray, rpl::producer<bool>> inChannelValues) {
|
base::flat_map<QByteArray, rpl::producer<bool>> inChannelValues) {
|
||||||
page.script = fillInChannelValuesScript(std::move(inChannelValues));
|
page.script = fillInChannelValuesScript(std::move(inChannelValues));
|
||||||
InvokeQueued(_container, [=, page = std::move(page)]() mutable {
|
InvokeQueued(_container, [=, page = std::move(page)]() mutable {
|
||||||
showInWindow(dataPath, std::move(page));
|
showInWindow(storageId, std::move(page));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ void Controller::createWindow() {
|
||||||
window->show();
|
window->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::createWebview(const QString &dataPath) {
|
void Controller::createWebview(const Webview::StorageId &storageId) {
|
||||||
Expects(!_webview);
|
Expects(!_webview);
|
||||||
|
|
||||||
const auto window = _window.get();
|
const auto window = _window.get();
|
||||||
|
@ -397,7 +397,7 @@ void Controller::createWebview(const QString &dataPath) {
|
||||||
_container,
|
_container,
|
||||||
Webview::WindowConfig{
|
Webview::WindowConfig{
|
||||||
.opaqueBg = st::windowBg->c,
|
.opaqueBg = st::windowBg->c,
|
||||||
.userDataPath = dataPath,
|
.storageId = storageId,
|
||||||
});
|
});
|
||||||
const auto raw = _webview.get();
|
const auto raw = _webview.get();
|
||||||
|
|
||||||
|
@ -558,7 +558,9 @@ void Controller::createWebview(const QString &dataPath) {
|
||||||
raw->init(R"()");
|
raw->init(R"()");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::showInWindow(const QString &dataPath, Prepared page) {
|
void Controller::showInWindow(
|
||||||
|
const Webview::StorageId &storageId,
|
||||||
|
Prepared page) {
|
||||||
Expects(_container != nullptr);
|
Expects(_container != nullptr);
|
||||||
|
|
||||||
const auto url = page.url;
|
const auto url = page.url;
|
||||||
|
@ -571,7 +573,7 @@ void Controller::showInWindow(const QString &dataPath, Prepared page) {
|
||||||
const auto index = i->second;
|
const auto index = i->second;
|
||||||
_index = index;
|
_index = index;
|
||||||
if (!_webview) {
|
if (!_webview) {
|
||||||
createWebview(dataPath);
|
createWebview(storageId);
|
||||||
if (_webview && _webview->widget()) {
|
if (_webview && _webview->widget()) {
|
||||||
auto id = u"iv/page%1.html"_q.arg(index);
|
auto id = u"iv/page%1.html"_q.arg(index);
|
||||||
if (!_hash.isEmpty()) {
|
if (!_hash.isEmpty()) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "iv/iv_delegate.h"
|
#include "iv/iv_delegate.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/text/text.h"
|
#include "ui/text/text.h"
|
||||||
|
#include "webview/webview_common.h"
|
||||||
|
|
||||||
class Painter;
|
class Painter;
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void show(
|
void show(
|
||||||
const QString &dataPath,
|
const Webview::StorageId &storageId,
|
||||||
Prepared page,
|
Prepared page,
|
||||||
base::flat_map<QByteArray, rpl::producer<bool>> inChannelValues);
|
base::flat_map<QByteArray, rpl::producer<bool>> inChannelValues);
|
||||||
void update(Prepared page);
|
void update(Prepared page);
|
||||||
|
@ -90,11 +91,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createWindow();
|
void createWindow();
|
||||||
void createWebview(const QString &dataPath);
|
void createWebview(const Webview::StorageId &storageId);
|
||||||
[[nodiscard]] QByteArray navigateScript(int index, const QString &hash);
|
[[nodiscard]] QByteArray navigateScript(int index, const QString &hash);
|
||||||
[[nodiscard]] QByteArray reloadScript(int index);
|
[[nodiscard]] QByteArray reloadScript(int index);
|
||||||
|
|
||||||
void showInWindow(const QString &dataPath, Prepared page);
|
void showInWindow(const Webview::StorageId &storageId, Prepared page);
|
||||||
[[nodiscard]] QByteArray fillInChannelValuesScript(
|
[[nodiscard]] QByteArray fillInChannelValuesScript(
|
||||||
base::flat_map<QByteArray, rpl::producer<bool>> inChannelValues);
|
base::flat_map<QByteArray, rpl::producer<bool>> inChannelValues);
|
||||||
[[nodiscard]] QByteArray toggleInChannelScript(
|
[[nodiscard]] QByteArray toggleInChannelScript(
|
||||||
|
|
|
@ -31,13 +31,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "lottie/lottie_common.h" // Lottie::ReadContent.
|
#include "lottie/lottie_common.h" // Lottie::ReadContent.
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/session/session_show.h"
|
#include "main/session/session_show.h"
|
||||||
#include "media/streaming/media_streaming_loader.h"
|
#include "media/streaming/media_streaming_loader.h"
|
||||||
#include "media/view/media_view_open_common.h"
|
#include "media/view/media_view_open_common.h"
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
#include "storage/storage_domain.h"
|
#include "storage/storage_account.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/layers/layer_widget.h"
|
#include "ui/layers/layer_widget.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
@ -348,9 +347,8 @@ void Shown::showWindowed(Prepared result) {
|
||||||
createController();
|
createController();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto domain = &_session->domain();
|
|
||||||
_controller->show(
|
_controller->show(
|
||||||
domain->local().webviewDataPath(),
|
_session->local().resolveStorageIdOther(),
|
||||||
std::move(result),
|
std::move(result),
|
||||||
base::duplicate(_inChannelValues));
|
base::duplicate(_inChannelValues));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2644,6 +2644,10 @@ bool MainWidget::eventFilter(QObject *o, QEvent *e) {
|
||||||
if (e->type() == QEvent::FocusIn) {
|
if (e->type() == QEvent::FocusIn) {
|
||||||
if (widget && relevantForDialogsFocus(widget)) {
|
if (widget && relevantForDialogsFocus(widget)) {
|
||||||
_dialogs->updateHasFocus(widget);
|
_dialogs->updateHasFocus(widget);
|
||||||
|
} else if (widget == window()) {
|
||||||
|
crl::on_main(this, [=] {
|
||||||
|
_controller->widget()->setInnerFocus();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (e->type() == QEvent::MouseButtonPress) {
|
} else if (e->type() == QEvent::MouseButtonPress) {
|
||||||
if (widget && (widget->window() == window())) {
|
if (widget && (widget->window() == window())) {
|
||||||
|
|
|
@ -5190,27 +5190,43 @@ void OverlayWidget::handleKeyPress(not_null<QKeyEvent*> e) {
|
||||||
void OverlayWidget::handleWheelEvent(not_null<QWheelEvent*> e) {
|
void OverlayWidget::handleWheelEvent(not_null<QWheelEvent*> e) {
|
||||||
constexpr auto step = int(QWheelEvent::DefaultDeltasPerStep);
|
constexpr auto step = int(QWheelEvent::DefaultDeltasPerStep);
|
||||||
|
|
||||||
|
const auto _thisWheelDelta = e->angleDelta().y();
|
||||||
const auto acceptForJump = !_stories
|
const auto acceptForJump = !_stories
|
||||||
&& ((e->source() == Qt::MouseEventNotSynthesized)
|
&& ((e->source() == Qt::MouseEventNotSynthesized)
|
||||||
|| (e->source() == Qt::MouseEventSynthesizedBySystem));
|
|| (e->source() == Qt::MouseEventSynthesizedBySystem));
|
||||||
_verticalWheelDelta += e->angleDelta().y();
|
|
||||||
while (qAbs(_verticalWheelDelta) >= step) {
|
const bool directionChanges =
|
||||||
if (_verticalWheelDelta < 0) {
|
std::signbit(_lastWheelDelta) != std::signbit(_thisWheelDelta);
|
||||||
_verticalWheelDelta += step;
|
|
||||||
|
if ((qAbs(_thisWheelDelta) != step) && directionChanges) {
|
||||||
|
// linux: first scroll after direction changes on hi-res wheel in
|
||||||
|
// libinput is unreliable. offen lost first half of it's value,
|
||||||
|
// or even only remain one with 15 delta, so we just hardcode it
|
||||||
|
// to same as step here, other system should be fine too.
|
||||||
|
_absWheelDelta = _thisWheelDelta > 0 ? step : step * -1;
|
||||||
|
} else {
|
||||||
|
_absWheelDelta += _thisWheelDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (qAbs(_absWheelDelta) >= step) {
|
||||||
|
if (_absWheelDelta < 0) {
|
||||||
|
// _absWheelDelta += step;
|
||||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
zoomOut();
|
zoomOut();
|
||||||
} else if (acceptForJump) {
|
} else if (acceptForJump) {
|
||||||
moveToNext(1);
|
moveToNext(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_verticalWheelDelta -= step;
|
// _absWheelDelta -= step;
|
||||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
zoomIn();
|
zoomIn();
|
||||||
} else if (acceptForJump) {
|
} else if (acceptForJump) {
|
||||||
moveToNext(-1);
|
moveToNext(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_absWheelDelta = 0; // reset to 0 to reduce pic move jump or skip.
|
||||||
}
|
}
|
||||||
|
_lastWheelDelta = _thisWheelDelta; // record last wheel delta
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::setZoomLevel(int newZoom, bool force) {
|
void OverlayWidget::setZoomLevel(int newZoom, bool force) {
|
||||||
|
|
|
@ -725,7 +725,8 @@ private:
|
||||||
rpl::event_stream<TouchBarItemType> _touchbarDisplay;
|
rpl::event_stream<TouchBarItemType> _touchbarDisplay;
|
||||||
rpl::event_stream<bool> _touchbarFullscreenToggled;
|
rpl::event_stream<bool> _touchbarFullscreenToggled;
|
||||||
|
|
||||||
int _verticalWheelDelta = 0;
|
int _absWheelDelta = 0;
|
||||||
|
int _lastWheelDelta = 0;
|
||||||
|
|
||||||
bool _themePreviewShown = false;
|
bool _themePreviewShown = false;
|
||||||
uint64 _themePreviewId = 0;
|
uint64 _themePreviewId = 0;
|
||||||
|
|
|
@ -11,8 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "payments/ui/payments_panel.h"
|
#include "payments/ui/payments_panel.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
#include "storage/storage_account.h"
|
||||||
#include "storage/storage_domain.h"
|
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "data/data_user.h" // UserData::isBot.
|
#include "data/data_user.h" // UserData::isBot.
|
||||||
|
@ -25,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_cloud_password.h"
|
#include "api/api_cloud_password.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "webview/webview_interface.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
@ -877,8 +875,8 @@ void CheckoutProcess::performInitialSilentValidation() {
|
||||||
_form->validateInformation(saved);
|
_form->validateInformation(saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CheckoutProcess::panelWebviewDataPath() {
|
Webview::StorageId CheckoutProcess::panelWebviewStorageId() {
|
||||||
return _session->domain().local().webviewDataPath();
|
return _session->local().resolveStorageIdOther();
|
||||||
}
|
}
|
||||||
|
|
||||||
Webview::ThemeParams CheckoutProcess::panelWebviewThemeParams() {
|
Webview::ThemeParams CheckoutProcess::panelWebviewThemeParams() {
|
||||||
|
|
|
@ -7,8 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "payments/ui/payments_panel_delegate.h"
|
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
|
#include "payments/ui/payments_panel_delegate.h"
|
||||||
|
#include "webview/webview_common.h"
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
class PasscodeBox;
|
class PasscodeBox;
|
||||||
|
@ -153,7 +154,7 @@ private:
|
||||||
void panelShowBox(object_ptr<Ui::BoxContent> box) override;
|
void panelShowBox(object_ptr<Ui::BoxContent> box) override;
|
||||||
QVariant panelClickHandlerContext() override;
|
QVariant panelClickHandlerContext() override;
|
||||||
|
|
||||||
QString panelWebviewDataPath() override;
|
Webview::StorageId panelWebviewStorageId() override;
|
||||||
Webview::ThemeParams panelWebviewThemeParams() override;
|
Webview::ThemeParams panelWebviewThemeParams() override;
|
||||||
|
|
||||||
std::optional<QDate> panelOverrideExpireDateThreshold() override;
|
std::optional<QDate> panelOverrideExpireDateThreshold() override;
|
||||||
|
|
|
@ -547,7 +547,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
|
||||||
container,
|
container,
|
||||||
Webview::WindowConfig{
|
Webview::WindowConfig{
|
||||||
.opaqueBg = params.opaqueBg,
|
.opaqueBg = params.opaqueBg,
|
||||||
.userDataPath = _delegate->panelWebviewDataPath(),
|
.storageId = _delegate->panelWebviewStorageId(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto raw = &_webview->window;
|
const auto raw = &_webview->window;
|
||||||
|
|
|
@ -18,6 +18,7 @@ class BoxContent;
|
||||||
|
|
||||||
namespace Webview {
|
namespace Webview {
|
||||||
struct ThemeParams;
|
struct ThemeParams;
|
||||||
|
struct StorageId;
|
||||||
} // namespace Webview
|
} // namespace Webview
|
||||||
|
|
||||||
namespace Payments::Ui {
|
namespace Payments::Ui {
|
||||||
|
@ -59,7 +60,7 @@ public:
|
||||||
virtual void panelShowBox(object_ptr<BoxContent> box) = 0;
|
virtual void panelShowBox(object_ptr<BoxContent> box) = 0;
|
||||||
virtual QVariant panelClickHandlerContext() = 0;
|
virtual QVariant panelClickHandlerContext() = 0;
|
||||||
|
|
||||||
virtual QString panelWebviewDataPath() = 0;
|
virtual Webview::StorageId panelWebviewStorageId() = 0;
|
||||||
virtual Webview::ThemeParams panelWebviewThemeParams() = 0;
|
virtual Webview::ThemeParams panelWebviewThemeParams() = 0;
|
||||||
|
|
||||||
virtual std::optional<QDate> panelOverrideExpireDateThreshold() = 0;
|
virtual std::optional<QDate> panelOverrideExpireDateThreshold() = 0;
|
||||||
|
|
|
@ -165,16 +165,7 @@ Cover::Cover(
|
||||||
}, _name->lifetime());
|
}, _name->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
Cover::~Cover() {
|
Cover::~Cover() = default;
|
||||||
if (_emojiStatusPanel.hasFocus()) {
|
|
||||||
// Panel will try to return focus to the layer widget, the problem is
|
|
||||||
// we are destroying the layer widget probably right now and focusing
|
|
||||||
// it will lead to a crash, because it destroys its children (how we
|
|
||||||
// got here) after it clears focus out of itself. So if you return
|
|
||||||
// the focus inside a child destructor, it won't be cleared at all.
|
|
||||||
window()->setFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cover::setupChildGeometry() {
|
void Cover::setupChildGeometry() {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/serialize_peer.h"
|
#include "storage/serialize_peer.h"
|
||||||
#include "storage/serialize_document.h"
|
#include "storage/serialize_document.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
|
#include "main/main_domain.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "mtproto/mtproto_config.h"
|
#include "mtproto/mtproto_config.h"
|
||||||
#include "mtproto/mtproto_dc_options.h"
|
#include "mtproto/mtproto_dc_options.h"
|
||||||
|
@ -35,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
#include "export/export_settings.h"
|
#include "export/export_settings.h"
|
||||||
|
#include "webview/webview_interface.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
@ -91,6 +93,7 @@ enum { // Local Storage Keys
|
||||||
lskMasksKeys = 0x16, // no data
|
lskMasksKeys = 0x16, // no data
|
||||||
lskCustomEmojiKeys = 0x17, // no data
|
lskCustomEmojiKeys = 0x17, // no data
|
||||||
lskSearchSuggestions = 0x18, // no data
|
lskSearchSuggestions = 0x18, // no data
|
||||||
|
lskWebviewTokens = 0x19, // data: QByteArray bots, QByteArray other
|
||||||
};
|
};
|
||||||
|
|
||||||
auto EmptyMessageDraftSources()
|
auto EmptyMessageDraftSources()
|
||||||
|
@ -303,6 +306,7 @@ Account::ReadMapResult Account::readMapWith(
|
||||||
quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0;
|
quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0;
|
||||||
quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0;
|
quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0;
|
||||||
quint64 searchSuggestionsKey = 0;
|
quint64 searchSuggestionsKey = 0;
|
||||||
|
QByteArray webviewStorageTokenBots, webviewStorageTokenOther;
|
||||||
while (!map.stream.atEnd()) {
|
while (!map.stream.atEnd()) {
|
||||||
quint32 keyType;
|
quint32 keyType;
|
||||||
map.stream >> keyType;
|
map.stream >> keyType;
|
||||||
|
@ -411,6 +415,11 @@ Account::ReadMapResult Account::readMapWith(
|
||||||
case lskSearchSuggestions: {
|
case lskSearchSuggestions: {
|
||||||
map.stream >> searchSuggestionsKey;
|
map.stream >> searchSuggestionsKey;
|
||||||
} break;
|
} break;
|
||||||
|
case lskWebviewTokens: {
|
||||||
|
map.stream
|
||||||
|
>> webviewStorageTokenBots
|
||||||
|
>> webviewStorageTokenOther;
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType));
|
LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType));
|
||||||
return ReadMapResult::Failed;
|
return ReadMapResult::Failed;
|
||||||
|
@ -448,6 +457,8 @@ Account::ReadMapResult Account::readMapWith(
|
||||||
_exportSettingsKey = exportSettingsKey;
|
_exportSettingsKey = exportSettingsKey;
|
||||||
_searchSuggestionsKey = searchSuggestionsKey;
|
_searchSuggestionsKey = searchSuggestionsKey;
|
||||||
_oldMapVersion = mapData.version;
|
_oldMapVersion = mapData.version;
|
||||||
|
_webviewStorageIdBots.token = webviewStorageTokenBots;
|
||||||
|
_webviewStorageIdOther.token = webviewStorageTokenOther;
|
||||||
|
|
||||||
if (_oldMapVersion < AppVersion) {
|
if (_oldMapVersion < AppVersion) {
|
||||||
writeMapDelayed();
|
writeMapDelayed();
|
||||||
|
@ -553,6 +564,12 @@ void Account::writeMap() {
|
||||||
mapSize += sizeof(quint32) + 3 * sizeof(quint64);
|
mapSize += sizeof(quint32) + 3 * sizeof(quint64);
|
||||||
}
|
}
|
||||||
if (_searchSuggestionsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_searchSuggestionsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
|
if (!_webviewStorageIdBots.token.isEmpty()
|
||||||
|
|| !_webviewStorageIdOther.token.isEmpty()) {
|
||||||
|
mapSize += sizeof(quint32)
|
||||||
|
+ Serialize::bytearraySize(_webviewStorageIdBots.token)
|
||||||
|
+ Serialize::bytearraySize(_webviewStorageIdOther.token);
|
||||||
|
}
|
||||||
|
|
||||||
EncryptedDescriptor mapData(mapSize);
|
EncryptedDescriptor mapData(mapSize);
|
||||||
if (!self.isEmpty()) {
|
if (!self.isEmpty()) {
|
||||||
|
@ -616,6 +633,13 @@ void Account::writeMap() {
|
||||||
mapData.stream << quint32(lskSearchSuggestions);
|
mapData.stream << quint32(lskSearchSuggestions);
|
||||||
mapData.stream << quint64(_searchSuggestionsKey);
|
mapData.stream << quint64(_searchSuggestionsKey);
|
||||||
}
|
}
|
||||||
|
if (!_webviewStorageIdBots.token.isEmpty()
|
||||||
|
|| !_webviewStorageIdOther.token.isEmpty()) {
|
||||||
|
mapData.stream << quint32(lskWebviewTokens);
|
||||||
|
mapData.stream
|
||||||
|
<< _webviewStorageIdBots.token
|
||||||
|
<< _webviewStorageIdOther.token;
|
||||||
|
}
|
||||||
map.writeEncrypted(mapData, _localKey);
|
map.writeEncrypted(mapData, _localKey);
|
||||||
|
|
||||||
_mapChanged = false;
|
_mapChanged = false;
|
||||||
|
@ -655,11 +679,27 @@ void Account::reset() {
|
||||||
_cacheTotalTimeLimit = Database::Settings().totalTimeLimit;
|
_cacheTotalTimeLimit = Database::Settings().totalTimeLimit;
|
||||||
_cacheBigFileTotalSizeLimit = Database::Settings().totalSizeLimit;
|
_cacheBigFileTotalSizeLimit = Database::Settings().totalSizeLimit;
|
||||||
_cacheBigFileTotalTimeLimit = Database::Settings().totalTimeLimit;
|
_cacheBigFileTotalTimeLimit = Database::Settings().totalTimeLimit;
|
||||||
|
|
||||||
|
const auto wvbots = _webviewStorageIdBots.path;
|
||||||
|
const auto wvother = _webviewStorageIdOther.path;
|
||||||
|
const auto wvclear = [](Webview::StorageId &storageId) {
|
||||||
|
Webview::ClearStorageDataByToken(
|
||||||
|
base::take(storageId).token.toStdString());
|
||||||
|
};
|
||||||
|
wvclear(_webviewStorageIdBots);
|
||||||
|
wvclear(_webviewStorageIdOther);
|
||||||
|
|
||||||
_mapChanged = true;
|
_mapChanged = true;
|
||||||
writeMap();
|
writeMap();
|
||||||
writeMtpData();
|
writeMtpData();
|
||||||
|
|
||||||
crl::async([base = _basePath, temp = _tempPath, names = std::move(names)] {
|
crl::async([
|
||||||
|
base = _basePath,
|
||||||
|
temp = _tempPath,
|
||||||
|
names = std::move(names),
|
||||||
|
wvbots,
|
||||||
|
wvother
|
||||||
|
] {
|
||||||
for (const auto &name : names) {
|
for (const auto &name : names) {
|
||||||
if (!name.endsWith(u"map0"_q)
|
if (!name.endsWith(u"map0"_q)
|
||||||
&& !name.endsWith(u"map1"_q)
|
&& !name.endsWith(u"map1"_q)
|
||||||
|
@ -669,6 +709,12 @@ void Account::reset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QDir(LegacyTempDirectory()).removeRecursively();
|
QDir(LegacyTempDirectory()).removeRecursively();
|
||||||
|
if (!wvbots.isEmpty()) {
|
||||||
|
QDir(wvbots).removeRecursively();
|
||||||
|
}
|
||||||
|
if (!wvother.isEmpty()) {
|
||||||
|
QDir(wvother).removeRecursively();
|
||||||
|
}
|
||||||
QDir(temp).removeRecursively();
|
QDir(temp).removeRecursively();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3080,6 +3126,54 @@ bool Account::isBotTrustedOpenWebView(PeerId botId) {
|
||||||
&& ((i->second & BotTrustFlag::OpenWebView) != 0);
|
&& ((i->second & BotTrustFlag::OpenWebView) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Account::enforceModernStorageIdBots() {
|
||||||
|
if (_webviewStorageIdBots.token.isEmpty()) {
|
||||||
|
_webviewStorageIdBots.token = QByteArray::fromStdString(
|
||||||
|
Webview::GenerateStorageToken());
|
||||||
|
writeMapDelayed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Webview::StorageId Account::resolveStorageIdBots() {
|
||||||
|
if (!_webviewStorageIdBots) {
|
||||||
|
auto &token = _webviewStorageIdBots.token;
|
||||||
|
const auto legacy = Webview::LegacyStorageIdToken();
|
||||||
|
if (token.isEmpty()) {
|
||||||
|
auto legacyTaken = false;
|
||||||
|
const auto &list = _owner->domain().accounts();
|
||||||
|
for (const auto &[index, account] : list) {
|
||||||
|
if (account.get() != _owner.get()) {
|
||||||
|
const auto &id = account->local()._webviewStorageIdBots;
|
||||||
|
if (id.token == legacy) {
|
||||||
|
legacyTaken = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token = legacyTaken
|
||||||
|
? QByteArray::fromStdString(Webview::GenerateStorageToken())
|
||||||
|
: legacy;
|
||||||
|
writeMapDelayed();
|
||||||
|
}
|
||||||
|
_webviewStorageIdBots.path = (token == legacy)
|
||||||
|
? (BaseGlobalPath() + u"webview"_q)
|
||||||
|
: (_databasePath + u"wvbots"_q);
|
||||||
|
}
|
||||||
|
return _webviewStorageIdBots;
|
||||||
|
}
|
||||||
|
|
||||||
|
Webview::StorageId Account::resolveStorageIdOther() {
|
||||||
|
if (!_webviewStorageIdOther) {
|
||||||
|
if (_webviewStorageIdOther.token.isEmpty()) {
|
||||||
|
_webviewStorageIdOther.token = QByteArray::fromStdString(
|
||||||
|
Webview::GenerateStorageToken());
|
||||||
|
writeMapDelayed();
|
||||||
|
}
|
||||||
|
_webviewStorageIdOther.path = _databasePath + u"wvother"_q;
|
||||||
|
}
|
||||||
|
return _webviewStorageIdOther;
|
||||||
|
}
|
||||||
|
|
||||||
bool Account::encrypt(
|
bool Account::encrypt(
|
||||||
const void *src,
|
const void *src,
|
||||||
void *dst,
|
void *dst,
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/cache/storage_cache_database.h"
|
#include "storage/cache/storage_cache_database.h"
|
||||||
#include "data/stickers/data_stickers_set.h"
|
#include "data/stickers/data_stickers_set.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
|
#include "webview/webview_common.h"
|
||||||
|
|
||||||
class History;
|
class History;
|
||||||
|
|
||||||
|
@ -169,6 +170,10 @@ public:
|
||||||
void markBotTrustedOpenWebView(PeerId botId);
|
void markBotTrustedOpenWebView(PeerId botId);
|
||||||
[[nodiscard]] bool isBotTrustedOpenWebView(PeerId botId);
|
[[nodiscard]] bool isBotTrustedOpenWebView(PeerId botId);
|
||||||
|
|
||||||
|
void enforceModernStorageIdBots();
|
||||||
|
[[nodiscard]] Webview::StorageId resolveStorageIdBots();
|
||||||
|
[[nodiscard]] Webview::StorageId resolveStorageIdOther();
|
||||||
|
|
||||||
[[nodiscard]] bool encrypt(
|
[[nodiscard]] bool encrypt(
|
||||||
const void *src,
|
const void *src,
|
||||||
void *dst,
|
void *dst,
|
||||||
|
@ -309,6 +314,9 @@ private:
|
||||||
bool _recentHashtagsAndBotsWereRead = false;
|
bool _recentHashtagsAndBotsWereRead = false;
|
||||||
bool _searchSuggestionsRead = false;
|
bool _searchSuggestionsRead = false;
|
||||||
|
|
||||||
|
Webview::StorageId _webviewStorageIdBots;
|
||||||
|
Webview::StorageId _webviewStorageIdOther;
|
||||||
|
|
||||||
int _oldMapVersion = 0;
|
int _oldMapVersion = 0;
|
||||||
|
|
||||||
base::Timer _writeMapTimer;
|
base::Timer _writeMapTimer;
|
||||||
|
|
|
@ -268,10 +268,6 @@ void Domain::clearOldVersion() {
|
||||||
_oldVersion = 0;
|
_oldVersion = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Domain::webviewDataPath() const {
|
|
||||||
return BaseGlobalPath() + "webview";
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> Domain::localPasscodeChanged() const {
|
rpl::producer<> Domain::localPasscodeChanged() const {
|
||||||
return _passcodeKeyChanged.events();
|
return _passcodeKeyChanged.events();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,6 @@ public:
|
||||||
[[nodiscard]] int oldVersion() const;
|
[[nodiscard]] int oldVersion() const;
|
||||||
void clearOldVersion();
|
void clearOldVersion();
|
||||||
|
|
||||||
[[nodiscard]] QString webviewDataPath() const;
|
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> localPasscodeChanged() const;
|
[[nodiscard]] rpl::producer<> localPasscodeChanged() const;
|
||||||
[[nodiscard]] bool hasLocalPasscode() const;
|
[[nodiscard]] bool hasLocalPasscode() const;
|
||||||
|
|
||||||
|
|
|
@ -313,12 +313,12 @@ Panel::Progress::Progress(QWidget *parent, Fn<QRect()> rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel::Panel(
|
Panel::Panel(
|
||||||
const QString &userDataPath,
|
const Webview::StorageId &storageId,
|
||||||
rpl::producer<QString> title,
|
rpl::producer<QString> title,
|
||||||
not_null<Delegate*> delegate,
|
not_null<Delegate*> delegate,
|
||||||
MenuButtons menuButtons,
|
MenuButtons menuButtons,
|
||||||
bool allowClipboardRead)
|
bool allowClipboardRead)
|
||||||
: _userDataPath(userDataPath)
|
: _storageId(storageId)
|
||||||
, _delegate(delegate)
|
, _delegate(delegate)
|
||||||
, _menuButtons(menuButtons)
|
, _menuButtons(menuButtons)
|
||||||
, _widget(std::make_unique<SeparatePanel>())
|
, _widget(std::make_unique<SeparatePanel>())
|
||||||
|
@ -597,7 +597,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
|
||||||
container,
|
container,
|
||||||
Webview::WindowConfig{
|
Webview::WindowConfig{
|
||||||
.opaqueBg = params.opaqueBg,
|
.opaqueBg = params.opaqueBg,
|
||||||
.userDataPath = _userDataPath,
|
.storageId = _storageId,
|
||||||
});
|
});
|
||||||
const auto raw = &_webview->window;
|
const auto raw = &_webview->window;
|
||||||
|
|
||||||
|
@ -1339,7 +1339,7 @@ rpl::lifetime &Panel::lifetime() {
|
||||||
|
|
||||||
std::unique_ptr<Panel> Show(Args &&args) {
|
std::unique_ptr<Panel> Show(Args &&args) {
|
||||||
auto result = std::make_unique<Panel>(
|
auto result = std::make_unique<Panel>(
|
||||||
args.userDataPath,
|
args.storageId,
|
||||||
std::move(args.title),
|
std::move(args.title),
|
||||||
args.delegate,
|
args.delegate,
|
||||||
args.menuButtons,
|
args.menuButtons,
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
#include "base/flags.h"
|
#include "base/flags.h"
|
||||||
|
#include "webview/webview_common.h"
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
class QJsonValue;
|
class QJsonValue;
|
||||||
|
@ -23,7 +24,6 @@ class SeparatePanel;
|
||||||
|
|
||||||
namespace Webview {
|
namespace Webview {
|
||||||
struct Available;
|
struct Available;
|
||||||
struct ThemeParams;
|
|
||||||
} // namespace Webview
|
} // namespace Webview
|
||||||
|
|
||||||
namespace Ui::BotWebView {
|
namespace Ui::BotWebView {
|
||||||
|
@ -72,7 +72,7 @@ public:
|
||||||
class Panel final : public base::has_weak_ptr {
|
class Panel final : public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
Panel(
|
Panel(
|
||||||
const QString &userDataPath,
|
const Webview::StorageId &storageId,
|
||||||
rpl::producer<QString> title,
|
rpl::producer<QString> title,
|
||||||
not_null<Delegate*> delegate,
|
not_null<Delegate*> delegate,
|
||||||
MenuButtons menuButtons,
|
MenuButtons menuButtons,
|
||||||
|
@ -144,7 +144,7 @@ private:
|
||||||
[[nodiscard]] QRect progressRect() const;
|
[[nodiscard]] QRect progressRect() const;
|
||||||
void setupProgressGeometry();
|
void setupProgressGeometry();
|
||||||
|
|
||||||
QString _userDataPath;
|
Webview::StorageId _storageId;
|
||||||
const not_null<Delegate*> _delegate;
|
const not_null<Delegate*> _delegate;
|
||||||
bool _closeNeedConfirmation = false;
|
bool _closeNeedConfirmation = false;
|
||||||
bool _hasSettingsButton = false;
|
bool _hasSettingsButton = false;
|
||||||
|
@ -172,7 +172,7 @@ private:
|
||||||
|
|
||||||
struct Args {
|
struct Args {
|
||||||
QString url;
|
QString url;
|
||||||
QString userDataPath;
|
Webview::StorageId storageId;
|
||||||
rpl::producer<QString> title;
|
rpl::producer<QString> title;
|
||||||
rpl::producer<QString> bottom;
|
rpl::producer<QString> bottom;
|
||||||
not_null<Delegate*> delegate;
|
not_null<Delegate*> delegate;
|
||||||
|
|
|
@ -632,7 +632,7 @@ historyPollRadio: Radio(defaultRadio) {
|
||||||
diameter: 18px;
|
diameter: 18px;
|
||||||
thickness: 2px;
|
thickness: 2px;
|
||||||
skip: 65px; // * 0.1
|
skip: 65px; // * 0.1
|
||||||
duration: 120;
|
duration: universalDuration;
|
||||||
rippleAreaPadding: 8px;
|
rippleAreaPadding: 8px;
|
||||||
}
|
}
|
||||||
historyPollRadioOpacity: 0.7;
|
historyPollRadioOpacity: 0.7;
|
||||||
|
|
|
@ -40,7 +40,7 @@ void SendButton::setType(Type type) {
|
||||||
[=] { update(); },
|
[=] { update(); },
|
||||||
0.,
|
0.,
|
||||||
1.,
|
1.,
|
||||||
st::historyRecordVoiceDuration);
|
st::universalDuration);
|
||||||
setPointerCursor(_type != Type::Slowmode);
|
setPointerCursor(_type != Type::Slowmode);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/style/style_palette_colorizer.h"
|
#include "ui/style/style_palette_colorizer.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "webview/webview_interface.h"
|
|
||||||
#include "boxes/background_box.h"
|
#include "boxes/background_box.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
#include "webview/webview_common.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7c346c6b042266b5adb116a2114df1d46b37c03f
|
Subproject commit 9f9bcaaec922644406faadda4d37014c9dec2dd9
|
Loading…
Reference in New Issue