2017-09-13 17:01:23 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
|
|
|
|
|
|
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
It is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
In addition, as a special exception, the copyright holders give permission
|
|
|
|
to link the code of portions of this program with the OpenSSL library.
|
|
|
|
|
|
|
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|
|
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|
|
|
*/
|
2017-09-24 15:46:37 +00:00
|
|
|
#include "info/profile/info_profile_inner_widget.h"
|
2017-09-13 17:01:23 +00:00
|
|
|
|
2017-09-18 16:39:45 +00:00
|
|
|
#include <rpl/combine.h>
|
2017-09-26 19:42:58 +00:00
|
|
|
#include <rpl/flatten_latest.h>
|
2017-09-25 09:02:55 +00:00
|
|
|
#include "info/profile/info_profile_button.h"
|
|
|
|
#include "info/profile/info_profile_widget.h"
|
|
|
|
#include "info/profile/info_profile_text.h"
|
|
|
|
#include "info/profile/info_profile_values.h"
|
|
|
|
#include "info/profile/info_profile_cover.h"
|
|
|
|
#include "info/profile/info_profile_icon.h"
|
2017-09-25 16:06:53 +00:00
|
|
|
#include "info/profile/info_profile_members.h"
|
2017-09-13 17:01:23 +00:00
|
|
|
#include "boxes/abstract_box.h"
|
2017-09-20 10:23:57 +00:00
|
|
|
#include "boxes/add_contact_box.h"
|
2017-09-26 19:42:58 +00:00
|
|
|
#include "boxes/confirm_box.h"
|
2017-09-13 17:01:23 +00:00
|
|
|
#include "mainwidget.h"
|
2017-09-26 19:42:58 +00:00
|
|
|
#include "auth_session.h"
|
|
|
|
#include "apiwrap.h"
|
2017-09-15 17:34:41 +00:00
|
|
|
#include "window/window_controller.h"
|
2017-09-21 19:21:33 +00:00
|
|
|
#include "storage/storage_shared_media.h"
|
2017-09-13 17:01:23 +00:00
|
|
|
#include "lang/lang_keys.h"
|
|
|
|
#include "styles/style_info.h"
|
2017-09-26 19:42:58 +00:00
|
|
|
#include "styles/style_boxes.h"
|
2017-09-13 17:01:23 +00:00
|
|
|
#include "ui/widgets/buttons.h"
|
|
|
|
#include "ui/widgets/checkbox.h"
|
2017-09-26 17:57:01 +00:00
|
|
|
#include "ui/widgets/scroll_area.h"
|
2017-09-25 09:02:55 +00:00
|
|
|
#include "ui/wrap/slide_wrap.h"
|
|
|
|
#include "ui/wrap/vertical_layout.h"
|
2017-09-26 18:55:53 +00:00
|
|
|
#include "history/history_shared_media.h"
|
|
|
|
#include "profile/profile_common_groups_section.h"
|
2017-09-13 17:01:23 +00:00
|
|
|
|
|
|
|
namespace Info {
|
|
|
|
namespace Profile {
|
|
|
|
|
2017-09-15 17:34:41 +00:00
|
|
|
InnerWidget::InnerWidget(
|
|
|
|
QWidget *parent,
|
2017-09-25 16:06:53 +00:00
|
|
|
rpl::producer<Wrap> &&wrapValue,
|
2017-09-15 17:34:41 +00:00
|
|
|
not_null<Window::Controller*> controller,
|
|
|
|
not_null<PeerData*> peer)
|
2017-09-13 17:01:23 +00:00
|
|
|
: RpWidget(parent)
|
2017-09-15 17:34:41 +00:00
|
|
|
, _controller(controller)
|
2017-09-13 17:01:23 +00:00
|
|
|
, _peer(peer)
|
2017-09-25 16:06:53 +00:00
|
|
|
, _content(setupContent(this, std::move(wrapValue))) {
|
2017-09-25 09:02:55 +00:00
|
|
|
_content->heightValue()
|
|
|
|
| rpl::start([this](int height) {
|
|
|
|
TWidget::resizeToWidth(width());
|
2017-09-26 17:57:01 +00:00
|
|
|
_desiredHeight.fire(countDesiredHeight());
|
2017-09-25 09:02:55 +00:00
|
|
|
}, lifetime());
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
bool InnerWidget::canHideDetailsEver() const {
|
|
|
|
return (_peer->isChat() || _peer->isMegagroup());
|
|
|
|
}
|
|
|
|
|
|
|
|
rpl::producer<bool> InnerWidget::canHideDetails() const {
|
|
|
|
using namespace rpl::mappers;
|
2017-09-25 09:02:55 +00:00
|
|
|
return MembersCountValue(_peer)
|
2017-09-21 19:21:33 +00:00
|
|
|
| rpl::map($1 > 0);
|
|
|
|
}
|
|
|
|
|
2017-09-25 09:02:55 +00:00
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
2017-09-25 16:06:53 +00:00
|
|
|
RpWidget *parent,
|
2017-09-26 17:57:01 +00:00
|
|
|
rpl::producer<Wrap> &&wrapValue) {
|
2017-09-25 09:02:55 +00:00
|
|
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
|
|
|
auto cover = result->add(object_ptr<Cover>(
|
|
|
|
result,
|
2017-09-21 19:21:33 +00:00
|
|
|
_peer)
|
|
|
|
);
|
|
|
|
cover->setOnlineCount(rpl::single(0));
|
2017-09-25 09:02:55 +00:00
|
|
|
auto details = setupDetails(parent);
|
2017-09-21 19:21:33 +00:00
|
|
|
if (canHideDetailsEver()) {
|
|
|
|
cover->setToggleShown(canHideDetails());
|
2017-09-25 09:02:55 +00:00
|
|
|
result->add(object_ptr<Ui::SlideWrap<>>(
|
|
|
|
result,
|
2017-09-21 19:21:33 +00:00
|
|
|
std::move(details))
|
|
|
|
)->toggleOn(cover->toggledValue());
|
2017-09-13 17:01:23 +00:00
|
|
|
} else {
|
2017-09-25 09:02:55 +00:00
|
|
|
result->add(std::move(details));
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
2017-09-25 09:02:55 +00:00
|
|
|
result->add(setupSharedMedia(result));
|
|
|
|
result->add(object_ptr<BoxContentDivider>(result));
|
2017-09-21 19:21:33 +00:00
|
|
|
if (auto user = _peer->asUser()) {
|
2017-09-25 09:02:55 +00:00
|
|
|
result->add(setupUserActions(result, user));
|
|
|
|
//} else if (auto channel = _peer->asChannel()) {
|
|
|
|
// if (!channel->isMegagroup()) {
|
|
|
|
// setupChannelActions(result, channel);
|
|
|
|
// }
|
2017-09-21 19:21:33 +00:00
|
|
|
}
|
2017-09-25 16:06:53 +00:00
|
|
|
if (_peer->isChat() || _peer->isMegagroup()) {
|
2017-09-26 17:57:01 +00:00
|
|
|
_members = result->add(object_ptr<Members>(
|
2017-09-25 16:06:53 +00:00
|
|
|
result,
|
2017-09-26 17:57:01 +00:00
|
|
|
_controller,
|
2017-09-25 16:06:53 +00:00
|
|
|
std::move(wrapValue),
|
2017-09-26 17:57:01 +00:00
|
|
|
_peer)
|
|
|
|
);
|
|
|
|
_members->scrollToRequests()
|
|
|
|
| rpl::start([this](Ui::ScrollToRequest request) {
|
|
|
|
auto min = (request.ymin < 0)
|
|
|
|
? request.ymin
|
|
|
|
: mapFromGlobal(_members->mapToGlobal({ 0, request.ymin })).y();
|
|
|
|
auto max = (request.ymin < 0)
|
|
|
|
? mapFromGlobal(_members->mapToGlobal({ 0, 0 })).y()
|
|
|
|
: (request.ymax < 0)
|
|
|
|
? request.ymax
|
|
|
|
: mapFromGlobal(_members->mapToGlobal({ 0, request.ymax })).y();
|
|
|
|
_scrollToRequests.fire({ min, max });
|
|
|
|
}, _members->lifetime());
|
2017-09-25 16:06:53 +00:00
|
|
|
}
|
2017-09-25 09:02:55 +00:00
|
|
|
return std::move(result);
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::setupDetails(
|
2017-09-13 17:01:23 +00:00
|
|
|
RpWidget *parent) const {
|
|
|
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
|
|
|
result->add(object_ptr<BoxContentDivider>(result));
|
2017-09-21 10:28:34 +00:00
|
|
|
result->add(createSkipWidget(result));
|
2017-09-21 19:21:33 +00:00
|
|
|
result->add(setupInfo(result));
|
2017-09-13 17:01:23 +00:00
|
|
|
result->add(setupMuteToggle(result));
|
|
|
|
if (auto user = _peer->asUser()) {
|
2017-09-21 19:21:33 +00:00
|
|
|
setupUserButtons(result, user);
|
|
|
|
//} else if (auto channel = _peer->asChannel()) {
|
|
|
|
// if (!channel->isMegagroup()) {
|
|
|
|
// setupChannelButtons(result, channel);
|
|
|
|
// }
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
2017-09-21 10:28:34 +00:00
|
|
|
result->add(createSkipWidget(result));
|
2017-09-18 17:04:45 +00:00
|
|
|
return std::move(result);
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::setupInfo(
|
2017-09-13 17:01:23 +00:00
|
|
|
RpWidget *parent) const {
|
|
|
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
2017-09-21 19:21:33 +00:00
|
|
|
auto tracker = MultiLineTracker();
|
|
|
|
auto addInfoLine = [&](
|
|
|
|
LangKey label,
|
|
|
|
rpl::producer<TextWithEntities> &&text,
|
|
|
|
bool selectByDoubleClick = false,
|
|
|
|
const style::FlatLabel &textSt = st::infoLabeled) {
|
2017-09-25 09:02:55 +00:00
|
|
|
auto line = result->add(CreateTextWithLabel(
|
2017-09-21 19:21:33 +00:00
|
|
|
result,
|
|
|
|
Lang::Viewer(label) | WithEmptyEntities(),
|
|
|
|
std::move(text),
|
|
|
|
textSt,
|
|
|
|
st::infoProfileLabeledPadding,
|
|
|
|
selectByDoubleClick));
|
|
|
|
tracker.track(line);
|
|
|
|
return line;
|
|
|
|
};
|
|
|
|
auto addInfoOneLine = [&](
|
|
|
|
LangKey label,
|
|
|
|
rpl::producer<TextWithEntities> &&text) {
|
|
|
|
addInfoLine(
|
|
|
|
label,
|
|
|
|
std::move(text),
|
|
|
|
true,
|
|
|
|
st::infoLabeledOneLine);
|
|
|
|
};
|
|
|
|
if (auto user = _peer->asUser()) {
|
2017-09-25 09:02:55 +00:00
|
|
|
addInfoOneLine(lng_info_mobile_label, PhoneValue(user));
|
|
|
|
addInfoLine(lng_info_bio_label, BioValue(user));
|
|
|
|
addInfoOneLine(lng_info_username_label, UsernameValue(user));
|
2017-09-21 19:21:33 +00:00
|
|
|
} else {
|
2017-09-25 09:02:55 +00:00
|
|
|
addInfoOneLine(lng_info_link_label, LinkValue(_peer));
|
|
|
|
addInfoLine(lng_info_about_label, AboutValue(_peer));
|
2017-09-21 19:21:33 +00:00
|
|
|
}
|
|
|
|
result->add(object_ptr<Ui::SlideWrap<>>(
|
|
|
|
result,
|
|
|
|
object_ptr<Ui::PlainShadow>(result, st::shadowFg),
|
|
|
|
st::infoProfileSeparatorPadding)
|
|
|
|
)->toggleOn(std::move(tracker).atLeastOneShownValue());
|
|
|
|
object_ptr<FloatingIcon>(
|
2017-09-13 17:01:23 +00:00
|
|
|
result,
|
2017-09-21 19:21:33 +00:00
|
|
|
st::infoIconInformation,
|
|
|
|
st::infoInformationIconPosition);
|
|
|
|
return std::move(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::setupMuteToggle(
|
|
|
|
RpWidget *parent) const {
|
|
|
|
auto result = object_ptr<Button>(
|
|
|
|
parent,
|
2017-09-13 17:01:23 +00:00
|
|
|
Lang::Viewer(lng_profile_enable_notifications),
|
2017-09-21 19:21:33 +00:00
|
|
|
st::infoNotificationsButton);
|
|
|
|
result->toggleOn(
|
2017-09-25 09:02:55 +00:00
|
|
|
NotificationsEnabledValue(_peer)
|
2017-09-21 19:21:33 +00:00
|
|
|
)->clicks()
|
2017-09-18 17:04:45 +00:00
|
|
|
| rpl::start([this](auto) {
|
2017-09-13 17:01:23 +00:00
|
|
|
App::main()->updateNotifySetting(
|
|
|
|
_peer,
|
|
|
|
_peer->isMuted()
|
|
|
|
? NotifySettingSetNotify
|
|
|
|
: NotifySettingSetMuted);
|
2017-09-21 19:21:33 +00:00
|
|
|
}, result->lifetime());
|
2017-09-13 17:01:23 +00:00
|
|
|
object_ptr<FloatingIcon>(
|
|
|
|
result,
|
2017-09-21 10:28:34 +00:00
|
|
|
st::infoIconNotifications,
|
|
|
|
st::infoNotificationsIconPosition);
|
2017-09-18 17:04:45 +00:00
|
|
|
return std::move(result);
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
void InnerWidget::setupUserButtons(
|
2017-09-13 17:01:23 +00:00
|
|
|
Ui::VerticalLayout *wrap,
|
|
|
|
not_null<UserData*> user) const {
|
2017-09-21 19:21:33 +00:00
|
|
|
using namespace rpl::mappers;
|
2017-09-21 10:28:34 +00:00
|
|
|
auto tracker = MultiLineTracker();
|
|
|
|
auto topSkip = wrap->add(createSlideSkipWidget(wrap));
|
|
|
|
auto addButton = [&](rpl::producer<QString> &&text) {
|
|
|
|
auto result = wrap->add(object_ptr<Ui::SlideWrap<Button>>(
|
2017-09-20 18:40:23 +00:00
|
|
|
wrap,
|
2017-09-21 10:28:34 +00:00
|
|
|
object_ptr<Button>(
|
|
|
|
wrap,
|
|
|
|
std::move(text),
|
|
|
|
st::infoMainButton)));
|
|
|
|
tracker.track(result);
|
|
|
|
return result;
|
|
|
|
};
|
2017-09-21 19:21:33 +00:00
|
|
|
addButton(
|
|
|
|
Lang::Viewer(lng_profile_send_message) | ToUpperValue()
|
|
|
|
)->toggleOn(
|
|
|
|
_controller->historyPeer.value()
|
|
|
|
| rpl::map($1 != user)
|
|
|
|
)->entity()->clicks()
|
2017-09-18 17:04:45 +00:00
|
|
|
| rpl::start([this, user](auto&&) {
|
2017-09-15 17:34:41 +00:00
|
|
|
_controller->showPeerHistory(
|
2017-09-13 17:01:23 +00:00
|
|
|
user,
|
|
|
|
Ui::ShowWay::Forward);
|
2017-09-21 19:21:33 +00:00
|
|
|
}, wrap->lifetime());
|
|
|
|
|
|
|
|
addButton(
|
|
|
|
Lang::Viewer(lng_info_add_as_contact) | ToUpperValue()
|
|
|
|
)->toggleOn(
|
2017-09-25 09:02:55 +00:00
|
|
|
CanAddContactValue(user)
|
2017-09-21 19:21:33 +00:00
|
|
|
)->entity()->clicks()
|
2017-09-18 17:04:45 +00:00
|
|
|
| rpl::start([user](auto&&) {
|
2017-09-20 10:23:57 +00:00
|
|
|
auto firstName = user->firstName;
|
|
|
|
auto lastName = user->lastName;
|
|
|
|
auto phone = user->phone().isEmpty()
|
|
|
|
? App::phoneFromSharedContact(user->bareId())
|
|
|
|
: user->phone();
|
|
|
|
Ui::show(Box<AddContactBox>(firstName, lastName, phone));
|
2017-09-21 19:21:33 +00:00
|
|
|
}, wrap->lifetime());
|
2017-09-21 10:28:34 +00:00
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
topSkip->toggleOn(std::move(tracker).atLeastOneShownValue());
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
2017-09-13 17:01:23 +00:00
|
|
|
RpWidget *parent) const {
|
2017-09-21 19:21:33 +00:00
|
|
|
using namespace rpl::mappers;
|
|
|
|
|
|
|
|
auto content = object_ptr<Ui::VerticalLayout>(parent);
|
2017-09-21 10:28:34 +00:00
|
|
|
auto tracker = MultiLineTracker();
|
2017-09-21 19:21:33 +00:00
|
|
|
auto addButton = [&](
|
|
|
|
rpl::producer<int> &&count,
|
|
|
|
auto textFromCount) {
|
2017-09-25 09:02:55 +00:00
|
|
|
auto forked = std::move(count)
|
2017-09-21 19:21:33 +00:00
|
|
|
| start_spawning(content->lifetime());
|
|
|
|
auto button = content->add(object_ptr<Ui::SlideWrap<Button>>(
|
|
|
|
content,
|
|
|
|
object_ptr<Button>(
|
|
|
|
content,
|
|
|
|
rpl::duplicate(forked)
|
|
|
|
| rpl::map([textFromCount](int count) {
|
|
|
|
return (count > 0)
|
|
|
|
? textFromCount(count)
|
|
|
|
: QString();
|
|
|
|
}),
|
|
|
|
st::infoSharedMediaButton))
|
|
|
|
)->toggleOn(
|
|
|
|
rpl::duplicate(forked)
|
|
|
|
| rpl::map($1 > 0));
|
|
|
|
tracker.track(button);
|
|
|
|
return button;
|
2017-09-20 19:44:22 +00:00
|
|
|
};
|
2017-09-21 19:21:33 +00:00
|
|
|
using MediaType = Storage::SharedMediaType;
|
|
|
|
auto mediaText = [](MediaType type) {
|
|
|
|
switch (type) {
|
|
|
|
case MediaType::Photo: return lng_profile_photos;
|
|
|
|
case MediaType::Video: return lng_profile_videos;
|
|
|
|
case MediaType::File: return lng_profile_files;
|
|
|
|
case MediaType::MusicFile: return lng_profile_songs;
|
|
|
|
case MediaType::Link: return lng_profile_shared_links;
|
|
|
|
case MediaType::VoiceFile: return lng_profile_audios;
|
|
|
|
case MediaType::RoundFile: return lng_profile_rounds;
|
|
|
|
}
|
|
|
|
Unexpected("Type in setupSharedMedia()");
|
2017-09-13 17:01:23 +00:00
|
|
|
};
|
2017-09-21 19:21:33 +00:00
|
|
|
auto addMediaButton = [&](MediaType type) {
|
|
|
|
return addButton(
|
2017-09-25 09:02:55 +00:00
|
|
|
SharedMediaCountValue(_peer, type),
|
2017-09-21 19:21:33 +00:00
|
|
|
[phrase = mediaText(type)](int count) {
|
|
|
|
return phrase(lt_count, count);
|
2017-09-26 18:55:53 +00:00
|
|
|
}
|
|
|
|
)->entity()->clicks()
|
|
|
|
| rpl::start([peer = _peer, type](auto&&) {
|
|
|
|
SharedMediaShowOverview(type, App::history(peer));
|
|
|
|
}, content->lifetime());
|
2017-09-21 19:21:33 +00:00
|
|
|
};
|
|
|
|
auto addCommonGroupsButton = [&](not_null<UserData*> user) {
|
|
|
|
return addButton(
|
2017-09-25 09:02:55 +00:00
|
|
|
CommonGroupsCountValue(user),
|
2017-09-21 19:21:33 +00:00
|
|
|
[](int count) {
|
|
|
|
return lng_profile_common_groups(lt_count, count);
|
2017-09-26 18:55:53 +00:00
|
|
|
}
|
|
|
|
)->entity()->clicks()
|
|
|
|
| rpl::start([peer = _peer](auto&&) {
|
|
|
|
App::main()->showSection(
|
|
|
|
::Profile::CommonGroups::SectionMemento(
|
|
|
|
peer->asUser()),
|
|
|
|
anim::type::normal,
|
|
|
|
anim::activation::normal);
|
|
|
|
}, content->lifetime());
|
2017-09-21 19:21:33 +00:00
|
|
|
};
|
|
|
|
addMediaButton(MediaType::Photo);
|
|
|
|
addMediaButton(MediaType::Video);
|
|
|
|
addMediaButton(MediaType::File);
|
|
|
|
addMediaButton(MediaType::MusicFile);
|
|
|
|
addMediaButton(MediaType::Link);
|
2017-09-13 17:01:23 +00:00
|
|
|
if (auto user = _peer->asUser()) {
|
2017-09-21 19:21:33 +00:00
|
|
|
addCommonGroupsButton(user);
|
|
|
|
}
|
|
|
|
addMediaButton(MediaType::VoiceFile);
|
|
|
|
addMediaButton(MediaType::RoundFile);
|
|
|
|
|
|
|
|
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
|
|
|
parent,
|
|
|
|
object_ptr<Ui::VerticalLayout>(parent)
|
|
|
|
);
|
|
|
|
result->toggleOn(tracker.atLeastOneShownValue());
|
|
|
|
auto layout = result->entity();
|
|
|
|
|
|
|
|
layout->add(object_ptr<BoxContentDivider>(result));
|
|
|
|
auto cover = layout->add(object_ptr<SharedMediaCover>(layout));
|
|
|
|
if (canHideDetailsEver()) {
|
|
|
|
cover->setToggleShown(canHideDetails());
|
|
|
|
layout->add(object_ptr<Ui::SlideWrap<>>(
|
|
|
|
layout,
|
|
|
|
std::move(content))
|
|
|
|
)->toggleOn(cover->toggledValue());
|
2017-09-13 17:01:23 +00:00
|
|
|
} else {
|
2017-09-21 19:21:33 +00:00
|
|
|
layout->add(std::move(content));
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
2017-09-21 19:21:33 +00:00
|
|
|
layout->add(object_ptr<Ui::FixedHeightWidget>(
|
|
|
|
layout,
|
|
|
|
st::infoSharedMediaBottomSkip)
|
|
|
|
)->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
|
|
object_ptr<FloatingIcon>(
|
2017-09-13 17:01:23 +00:00
|
|
|
result,
|
2017-09-21 19:21:33 +00:00
|
|
|
st::infoIconMediaPhoto,
|
|
|
|
st::infoSharedMediaIconPosition);
|
|
|
|
return std::move(result);
|
|
|
|
}
|
2017-09-13 17:01:23 +00:00
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::setupUserActions(
|
|
|
|
RpWidget *parent,
|
|
|
|
not_null<UserData*> user) const {
|
|
|
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
2017-09-26 19:42:58 +00:00
|
|
|
result->add(createSkipWidget(result));
|
|
|
|
auto addButton = [&](
|
|
|
|
rpl::producer<QString> &&text,
|
|
|
|
rpl::producer<bool> &&toggleOn,
|
|
|
|
auto &&callback,
|
|
|
|
const style::InfoProfileButton &st
|
|
|
|
= st::infoSharedMediaButton) {
|
|
|
|
return result->add(object_ptr<Ui::SlideWrap<Button>>(
|
2017-09-21 19:21:33 +00:00
|
|
|
result,
|
|
|
|
object_ptr<Button>(
|
|
|
|
result,
|
|
|
|
std::move(text),
|
2017-09-26 19:42:58 +00:00
|
|
|
st))
|
|
|
|
)->toggleOn(
|
|
|
|
std::move(toggleOn)
|
|
|
|
)->entity()->clicks()
|
|
|
|
| rpl::start([callback = std::move(callback)](auto&&) {
|
|
|
|
callback();
|
|
|
|
}, result->lifetime());
|
2017-09-21 19:21:33 +00:00
|
|
|
};
|
2017-09-26 19:42:58 +00:00
|
|
|
|
|
|
|
addButton(
|
|
|
|
Lang::Viewer(lng_profile_share_contact),
|
|
|
|
CanShareContactValue(user),
|
|
|
|
[user] { App::main()->shareContactLayer(user); });
|
|
|
|
addButton(
|
|
|
|
Lang::Viewer(lng_info_edit_contact),
|
|
|
|
IsContactValue(user),
|
|
|
|
[user] { Ui::show(Box<AddContactBox>(user)); });
|
|
|
|
addButton(
|
|
|
|
Lang::Viewer(lng_profile_clear_history),
|
|
|
|
rpl::single(true),
|
|
|
|
[user] {
|
|
|
|
auto confirmation = lng_sure_delete_history(lt_contact, App::peerName(user));
|
|
|
|
Ui::show(Box<ConfirmBox>(confirmation, lang(lng_box_delete), st::attentionBoxButton, [user] {
|
|
|
|
Ui::hideLayer();
|
|
|
|
App::main()->clearHistory(user);
|
|
|
|
Ui::showPeerHistory(user, ShowAtUnreadMsgId);
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
addButton(
|
|
|
|
Lang::Viewer(lng_profile_delete_conversation),
|
|
|
|
rpl::single(true),
|
|
|
|
[user] {
|
|
|
|
auto confirmation = lng_sure_delete_history(lt_contact, App::peerName(user));
|
|
|
|
auto confirmButton = lang(lng_box_delete);
|
|
|
|
Ui::show(Box<ConfirmBox>(confirmation, confirmButton, st::attentionBoxButton, [user] {
|
|
|
|
Ui::hideLayer();
|
|
|
|
Ui::showChatsList();
|
|
|
|
App::main()->deleteConversation(user);
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!user->isSelf()) {
|
|
|
|
result->add(CreateSkipWidget(
|
|
|
|
result,
|
|
|
|
st::infoBlockButtonSkip));
|
|
|
|
|
|
|
|
auto text = PeerUpdateValue(user, Notify::PeerUpdate::Flag::UserIsBlocked)
|
|
|
|
| rpl::map([user](auto&&) {
|
|
|
|
switch (user->blockStatus()) {
|
|
|
|
case UserData::BlockStatus::Blocked:
|
|
|
|
return Lang::Viewer(lng_profile_unblock_user);
|
|
|
|
case UserData::BlockStatus::NotBlocked:
|
|
|
|
return Lang::Viewer(lng_profile_block_user);
|
|
|
|
default:
|
|
|
|
return rpl::single(QString());
|
|
|
|
}
|
|
|
|
})
|
|
|
|
| rpl::flatten_latest()
|
|
|
|
| rpl::start_spawning(result->lifetime());
|
|
|
|
addButton(
|
|
|
|
rpl::duplicate(text),
|
|
|
|
rpl::duplicate(text)
|
|
|
|
| rpl::map([](const QString &text) {
|
|
|
|
return !text.isEmpty();
|
|
|
|
}),
|
|
|
|
[user] {
|
|
|
|
if (user->isBlocked()) {
|
|
|
|
Auth().api().unblockUser(user);
|
|
|
|
} else {
|
|
|
|
Auth().api().blockUser(user);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
st::infoBlockButton);
|
|
|
|
}
|
|
|
|
result->add(createSkipWidget(result));
|
|
|
|
|
2017-09-21 19:21:33 +00:00
|
|
|
object_ptr<FloatingIcon>(
|
|
|
|
result,
|
|
|
|
st::infoIconActions,
|
|
|
|
st::infoIconPosition);
|
2017-09-18 17:04:45 +00:00
|
|
|
return std::move(result);
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
2017-09-21 10:28:34 +00:00
|
|
|
object_ptr<Ui::RpWidget> InnerWidget::createSkipWidget(
|
|
|
|
RpWidget *parent) const {
|
|
|
|
return Ui::CreateSkipWidget(parent, st::infoProfileSkip);
|
|
|
|
}
|
|
|
|
|
|
|
|
object_ptr<Ui::SlideWrap<>> InnerWidget::createSlideSkipWidget(
|
|
|
|
RpWidget *parent) const {
|
|
|
|
return Ui::CreateSlideSkipWidget(parent, st::infoProfileSkip);
|
|
|
|
}
|
|
|
|
|
2017-09-26 17:57:01 +00:00
|
|
|
int InnerWidget::countDesiredHeight() const {
|
|
|
|
return _content->height() + (_members
|
|
|
|
? (_members->desiredHeight() - _members->height())
|
|
|
|
: 0);
|
|
|
|
}
|
|
|
|
|
2017-09-13 17:01:23 +00:00
|
|
|
void InnerWidget::visibleTopBottomUpdated(
|
|
|
|
int visibleTop,
|
|
|
|
int visibleBottom) {
|
2017-09-25 16:06:53 +00:00
|
|
|
setChildVisibleTopBottom(_content, visibleTop, visibleBottom);
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InnerWidget::saveState(not_null<Memento*> memento) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void InnerWidget::restoreState(not_null<Memento*> memento) {
|
|
|
|
}
|
|
|
|
|
|
|
|
int InnerWidget::resizeGetHeight(int newWidth) {
|
|
|
|
_content->resizeToWidth(newWidth);
|
2017-09-21 10:28:34 +00:00
|
|
|
_content->moveToLeft(0, 0);
|
|
|
|
return qMax(_content->heightNoMargins(), _minHeight);
|
2017-09-13 17:01:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Profile
|
|
|
|
} // namespace Info
|