| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "data/business/data_business_info.h"
- #include "apiwrap.h"
- #include "base/unixtime.h"
- #include "data/business/data_business_common.h"
- #include "data/data_document.h"
- #include "data/data_session.h"
- #include "data/data_user.h"
- #include "main/main_session.h"
- namespace Data {
- namespace {
- [[nodiscard]] MTPBusinessWorkHours ToMTP(const WorkingHours &data) {
- const auto list = data.intervals.normalized().list;
- const auto proj = [](const WorkingInterval &data) {
- return MTPBusinessWeeklyOpen(MTP_businessWeeklyOpen(
- MTP_int(data.start / 60),
- MTP_int(data.end / 60)));
- };
- return MTP_businessWorkHours(
- MTP_flags(0),
- MTP_string(data.timezoneId),
- MTP_vector_from_range(list | ranges::views::transform(proj)));
- }
- [[nodiscard]] MTPBusinessAwayMessageSchedule ToMTP(
- const AwaySchedule &data) {
- Expects(data.type != AwayScheduleType::Never);
- return (data.type == AwayScheduleType::Always)
- ? MTP_businessAwayMessageScheduleAlways()
- : (data.type == AwayScheduleType::OutsideWorkingHours)
- ? MTP_businessAwayMessageScheduleOutsideWorkHours()
- : MTP_businessAwayMessageScheduleCustom(
- MTP_int(data.customInterval.start),
- MTP_int(data.customInterval.end));
- }
- [[nodiscard]] MTPInputBusinessAwayMessage ToMTP(const AwaySettings &data) {
- using Flag = MTPDinputBusinessAwayMessage::Flag;
- return MTP_inputBusinessAwayMessage(
- MTP_flags(data.offlineOnly ? Flag::f_offline_only : Flag()),
- MTP_int(data.shortcutId),
- ToMTP(data.schedule),
- ForMessagesToMTP(data.recipients));
- }
- [[nodiscard]] MTPInputBusinessGreetingMessage ToMTP(
- const GreetingSettings &data) {
- return MTP_inputBusinessGreetingMessage(
- MTP_int(data.shortcutId),
- ForMessagesToMTP(data.recipients),
- MTP_int(data.noActivityDays));
- }
- } // namespace
- BusinessInfo::BusinessInfo(not_null<Session*> owner)
- : _owner(owner) {
- }
- BusinessInfo::~BusinessInfo() = default;
- void BusinessInfo::saveWorkingHours(
- WorkingHours data,
- Fn<void(QString)> fail) {
- const auto session = &_owner->session();
- auto details = session->user()->businessDetails();
- const auto &was = details.hours;
- if (was == data) {
- return;
- }
- using Flag = MTPaccount_UpdateBusinessWorkHours::Flag;
- session->api().request(MTPaccount_UpdateBusinessWorkHours(
- MTP_flags(data ? Flag::f_business_work_hours : Flag()),
- ToMTP(data)
- )).fail([=](const MTP::Error &error) {
- auto details = session->user()->businessDetails();
- details.hours = was;
- session->user()->setBusinessDetails(std::move(details));
- if (fail) {
- fail(error.type());
- }
- }).send();
- details.hours = std::move(data);
- session->user()->setBusinessDetails(std::move(details));
- }
- void BusinessInfo::saveChatIntro(ChatIntro data, Fn<void(QString)> fail) {
- const auto session = &_owner->session();
- auto details = session->user()->businessDetails();
- const auto &was = details.intro;
- if (was == data) {
- return;
- } else {
- const auto session = &_owner->session();
- using Flag = MTPaccount_UpdateBusinessIntro::Flag;
- session->api().request(MTPaccount_UpdateBusinessIntro(
- MTP_flags(data ? Flag::f_intro : Flag()),
- MTP_inputBusinessIntro(
- MTP_flags(data.sticker
- ? MTPDinputBusinessIntro::Flag::f_sticker
- : MTPDinputBusinessIntro::Flag()),
- MTP_string(data.title),
- MTP_string(data.description),
- (data.sticker
- ? data.sticker->mtpInput()
- : MTP_inputDocumentEmpty()))
- )).fail([=](const MTP::Error &error) {
- auto details = session->user()->businessDetails();
- details.intro = was;
- session->user()->setBusinessDetails(std::move(details));
- if (fail) {
- fail(error.type());
- }
- }).send();
- }
- details.intro = std::move(data);
- session->user()->setBusinessDetails(std::move(details));
- }
- void BusinessInfo::saveLocation(
- BusinessLocation data,
- Fn<void(QString)> fail) {
- const auto session = &_owner->session();
- auto details = session->user()->businessDetails();
- const auto &was = details.location;
- if (was == data) {
- return;
- } else {
- const auto session = &_owner->session();
- using Flag = MTPaccount_UpdateBusinessLocation::Flag;
- session->api().request(MTPaccount_UpdateBusinessLocation(
- MTP_flags((data.point ? Flag::f_geo_point : Flag())
- | (data.address.isEmpty() ? Flag() : Flag::f_address)),
- (data.point
- ? MTP_inputGeoPoint(
- MTP_flags(0),
- MTP_double(data.point->lat()),
- MTP_double(data.point->lon()),
- MTPint()) // accuracy_radius
- : MTP_inputGeoPointEmpty()),
- MTP_string(data.address)
- )).fail([=](const MTP::Error &error) {
- auto details = session->user()->businessDetails();
- details.location = was;
- session->user()->setBusinessDetails(std::move(details));
- if (fail) {
- fail(error.type());
- }
- }).send();
- }
- details.location = std::move(data);
- session->user()->setBusinessDetails(std::move(details));
- }
- void BusinessInfo::applyAwaySettings(AwaySettings data) {
- if (_awaySettings == data) {
- return;
- }
- _awaySettings = data;
- _awaySettingsChanged.fire({});
- }
- void BusinessInfo::saveAwaySettings(
- AwaySettings data,
- Fn<void(QString)> fail) {
- const auto &was = _awaySettings;
- if (was == data) {
- return;
- } else if (!data || data.shortcutId) {
- using Flag = MTPaccount_UpdateBusinessAwayMessage::Flag;
- const auto session = &_owner->session();
- session->api().request(MTPaccount_UpdateBusinessAwayMessage(
- MTP_flags(data ? Flag::f_message : Flag()),
- data ? ToMTP(data) : MTPInputBusinessAwayMessage()
- )).fail([=](const MTP::Error &error) {
- _awaySettings = was;
- _awaySettingsChanged.fire({});
- if (fail) {
- fail(error.type());
- }
- }).send();
- }
- _awaySettings = std::move(data);
- _awaySettingsChanged.fire({});
- }
- bool BusinessInfo::awaySettingsLoaded() const {
- return _awaySettings.has_value();
- }
- AwaySettings BusinessInfo::awaySettings() const {
- return _awaySettings.value_or(AwaySettings());
- }
- rpl::producer<> BusinessInfo::awaySettingsChanged() const {
- return _awaySettingsChanged.events();
- }
- void BusinessInfo::applyGreetingSettings(GreetingSettings data) {
- if (_greetingSettings == data) {
- return;
- }
- _greetingSettings = data;
- _greetingSettingsChanged.fire({});
- }
- void BusinessInfo::saveGreetingSettings(
- GreetingSettings data,
- Fn<void(QString)> fail) {
- const auto &was = _greetingSettings;
- if (was == data) {
- return;
- } else if (!data || data.shortcutId) {
- using Flag = MTPaccount_UpdateBusinessGreetingMessage::Flag;
- _owner->session().api().request(
- MTPaccount_UpdateBusinessGreetingMessage(
- MTP_flags(data ? Flag::f_message : Flag()),
- data ? ToMTP(data) : MTPInputBusinessGreetingMessage())
- ).fail([=](const MTP::Error &error) {
- _greetingSettings = was;
- _greetingSettingsChanged.fire({});
- if (fail) {
- fail(error.type());
- }
- }).send();
- }
- _greetingSettings = std::move(data);
- _greetingSettingsChanged.fire({});
- }
- bool BusinessInfo::greetingSettingsLoaded() const {
- return _greetingSettings.has_value();
- }
- GreetingSettings BusinessInfo::greetingSettings() const {
- return _greetingSettings.value_or(GreetingSettings());
- }
- rpl::producer<> BusinessInfo::greetingSettingsChanged() const {
- return _greetingSettingsChanged.events();
- }
- void BusinessInfo::preload() {
- preloadTimezones();
- }
- void BusinessInfo::preloadTimezones() {
- if (!_timezones.current().list.empty() || _timezonesRequestId) {
- return;
- }
- _timezonesRequestId = _owner->session().api().request(
- MTPhelp_GetTimezonesList(MTP_int(_timezonesHash))
- ).done([=](const MTPhelp_TimezonesList &result) {
- result.match([&](const MTPDhelp_timezonesList &data) {
- _timezonesHash = data.vhash().v;
- const auto proj = [](const MTPtimezone &result) {
- return Timezone{
- .id = qs(result.data().vid()),
- .name = qs(result.data().vname()),
- .utcOffset = result.data().vutc_offset().v,
- };
- };
- _timezones = Timezones{
- .list = ranges::views::all(
- data.vtimezones().v
- ) | ranges::views::transform(
- proj
- ) | ranges::to_vector,
- };
- }, [](const MTPDhelp_timezonesListNotModified &) {
- });
- }).send();
- }
- rpl::producer<Timezones> BusinessInfo::timezonesValue() const {
- const_cast<BusinessInfo*>(this)->preloadTimezones();
- return _timezones.value();
- }
- bool BusinessInfo::timezonesLoaded() const {
- return !_timezones.current().list.empty();
- }
- QString FindClosestTimezoneId(const std::vector<Timezone> &list) {
- const auto local = QDateTime::currentDateTime();
- const auto utc = QDateTime(local.date(), local.time(), Qt::UTC);
- const auto shift = base::unixtime::now() - (TimeId)::time(nullptr);
- const auto delta = int(utc.toSecsSinceEpoch())
- - int(local.toSecsSinceEpoch())
- - shift;
- const auto proj = [&](const Timezone &value) {
- auto distance = value.utcOffset - delta;
- while (distance > 12 * 3600) {
- distance -= 24 * 3600;
- }
- while (distance < -12 * 3600) {
- distance += 24 * 3600;
- }
- return std::abs(distance);
- };
- return ranges::min_element(list, ranges::less(), proj)->id;
- }
- } // namespace Data
|