Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/map
diff options
context:
space:
mode:
authorArsentiy Milchakov <milcars@mapswithme.com>2018-08-28 13:26:51 +0300
committerTatiana Yan <tatiana.kondakova@gmail.com>2018-08-30 13:09:25 +0300
commit856f90dd0ca941b586264ad2f5cda9e046979c39 (patch)
tree68667d2ce550027e0124b135aa909d17049b5856 /map
parent6e77783f85d79d2b5e554f6eee10e54c1396e1a0 (diff)
[tips] Tips are added
Diffstat (limited to 'map')
-rw-r--r--map/CMakeLists.txt2
-rw-r--r--map/framework.cpp18
-rw-r--r--map/framework.hpp15
-rw-r--r--map/tips_api.cpp144
-rw-r--r--map/tips_api.hpp44
5 files changed, 221 insertions, 2 deletions
diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt
index 667095dc12..98bb3e228d 100644
--- a/map/CMakeLists.txt
+++ b/map/CMakeLists.txt
@@ -94,6 +94,8 @@ set(
subscription.hpp
taxi_delegate.cpp
taxi_delegate.hpp
+ tips_api.cpp
+ tips_api.hpp
track.cpp
track.hpp
traffic_manager.cpp
diff --git a/map/framework.cpp b/map/framework.cpp
index 6aa632eacd..44b35bd789 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -3660,3 +3660,21 @@ booking::AvailabilityParams Framework::GetLastBookingAvailabilityParams() const
{
return m_bookingAvailabilityParams;
}
+
+TipsApi const & Framework::GetTipsApi() const
+{
+ return m_tipsApi;
+}
+
+bool Framework::HaveTransit(m2::PointD const & pt) const
+{
+ auto const & dataSource = m_model.GetDataSource();
+ MwmSet::MwmId const mwmId =
+ dataSource.GetMwmIdByCountryFile(platform::CountryFile(m_infoGetter->GetRegionCountryId(pt)));
+
+ MwmSet::MwmHandle handle = m_model.GetDataSource().GetMwmHandleById(mwmId);
+ if (!handle.IsAlive())
+ return false;
+
+ return handle.GetValue<MwmValue>()->m_cont.IsExist(TRANSIT_FILE_TAG);
+}
diff --git a/map/framework.hpp b/map/framework.hpp
index 1e7c740cfe..6e403a64dd 100644
--- a/map/framework.hpp
+++ b/map/framework.hpp
@@ -16,6 +16,7 @@
#include "map/search_api.hpp"
#include "map/search_mark.hpp"
#include "map/subscription.hpp"
+#include "map/tips_api.hpp"
#include "map/track.hpp"
#include "map/traffic_manager.hpp"
#include "map/transit/transit_reader.hpp"
@@ -57,6 +58,8 @@
#include "partners_api/taxi_engine.hpp"
#include "partners_api/viator_api.hpp"
+#include "eye/eye_info.hpp"
+
#include "platform/country_defines.hpp"
#include "platform/location.hpp"
#include "platform/platform.hpp"
@@ -129,7 +132,9 @@ struct FrameworkParams
{}
};
-class Framework : public SearchAPI::Delegate, public RoutingManager::Delegate
+class Framework : public SearchAPI::Delegate,
+ public RoutingManager::Delegate,
+ public TipsApi::Delegate
{
DISALLOW_COPY(Framework);
@@ -283,7 +288,7 @@ public:
void ShowNode(storage::TCountryId const & countryId);
/// Checks, whether the country which contains the specified point is loaded.
- bool IsCountryLoaded(m2::PointD const & pt) const;
+ bool IsCountryLoaded(m2::PointD const & pt) const override;
/// Checks, whether the country is loaded.
bool IsCountryLoadedByName(string const & name) const;
//@}
@@ -876,4 +881,10 @@ public:
private:
std::unique_ptr<Subscription> m_subscription;
+ TipsApi m_tipsApi;
+
+public:
+ TipsApi const & GetTipsApi() const;
+
+ bool HaveTransit(m2::PointD const & pt) const override;
};
diff --git a/map/tips_api.cpp b/map/tips_api.cpp
new file mode 100644
index 0000000000..6d0bd8fed0
--- /dev/null
+++ b/map/tips_api.cpp
@@ -0,0 +1,144 @@
+#include "map/tips_api.hpp"
+
+#include "eye/eye.hpp"
+
+#include "platform/platform.hpp"
+
+#include <array>
+#include <utility>
+
+using namespace eye;
+
+namespace
+{
+// The app shouldn't show any screen at all more frequently than once in 3 days.
+auto const kShowAnyTipPeriod = std::chrono::hours(24) * 3;
+// The app shouldn't show the same screen more frequently than 1 month.
+auto const kShowSameTipPeriod = std::chrono::hours(24) * 30;
+// If a user clicks on the action areas (highlighted or blue button)
+// the appropriate screen will never be shown again.
+size_t const kActionClicksCountToDisable = 1;
+// If a user clicks 3 times on the button GOT IT the appropriate screen will never be shown again.
+size_t const kGotitClicksCountToDisable = 3;
+
+size_t ToIndex(Tips::Type type)
+{
+ return static_cast<size_t>(type);
+}
+
+TipsApi::Tip GetTipImpl(TipsApi::Duration showAnyTipPeriod, TipsApi::Duration showSameTipPeriod,
+ TipsApi::Conditions const & triggers)
+{
+ auto const info = Eye::Instance().GetInfo();
+ auto const & tips = info->m_tips;
+ auto const totalTipsCount = static_cast<size_t>(Tips::Type::Count);
+
+ if (Clock::now() - tips.m_lastShown <= showAnyTipPeriod)
+ return {};
+
+ // If some tips are never shown.
+ if (tips.m_shownTips.size() < totalTipsCount)
+ {
+ using Candidate = std::pair<Tips::Type, bool>;
+ std::array<Candidate, totalTipsCount> candidates;
+ for (size_t i = 0; i < totalTipsCount; ++i)
+ {
+ candidates[i] = {static_cast<Tips::Type>(i), true};
+ }
+
+ for (auto const & shownTip : tips.m_shownTips)
+ {
+ candidates[ToIndex(shownTip.m_type)].second = false;
+ }
+
+ for (auto const & c : candidates)
+ {
+ if (c.second && triggers[ToIndex(c.first)]())
+ return c.first;
+ }
+ }
+
+ for (auto const & shownTip : tips.m_shownTips)
+ {
+ if (shownTip.m_eventCounters.Get(Tips::Event::ActionClicked) < kActionClicksCountToDisable &&
+ shownTip.m_eventCounters.Get(Tips::Event::GotitClicked) < kGotitClicksCountToDisable &&
+ Clock::now() - shownTip.m_lastShown > showSameTipPeriod &&
+ triggers[ToIndex(shownTip.m_type)]())
+ {
+ return shownTip.m_type;
+ }
+ }
+
+ return {};
+}
+} // namespace
+
+// static
+TipsApi::Duration TipsApi::GetShowAnyTipPeriod()
+{
+ return kShowAnyTipPeriod;
+}
+
+// static
+TipsApi::Duration TipsApi::GetShowSameTipPeriod()
+{
+ return kShowSameTipPeriod;
+}
+
+// static
+size_t TipsApi::GetActionClicksCountToDisable()
+{
+ return kActionClicksCountToDisable;
+}
+
+// static
+size_t TipsApi::GetGotitClicksCountToDisable()
+{
+ return kGotitClicksCountToDisable;
+}
+
+TipsApi::TipsApi()
+{
+ m_conditions =
+ {{
+ // Condition for Tips::Type::BookmarksCatalog type.
+ [] { return GetPlatform().ConnectionStatus() != Platform::EConnectionType::CONNECTION_NONE; },
+ // Condition for Tips::Type::BookingHotels type.
+ [] { return true; },
+ // Condition for Tips::Type::DiscoverButton type.
+ [this]
+ {
+ auto const pos = m_delegate->GetCurrentPosition();
+ if (!pos.is_initialized())
+ return false;
+
+ return m_delegate->IsCountryLoaded(pos.get());
+ },
+ // Condition for Tips::Type::MapsLayers type.
+ [this]
+ {
+ auto const pos = m_delegate->GetCurrentPosition();
+ if (!pos.is_initialized())
+ return false;
+
+ return m_delegate->HaveTransit(pos.get());
+ }
+ }};
+}
+
+void TipsApi::SetDelegate(std::unique_ptr<Delegate> delegate)
+{
+ m_delegate = std::move(delegate);
+}
+
+TipsApi::Tip TipsApi::GetTip() const
+{
+ return GetTipImpl(GetShowAnyTipPeriod(), GetShowSameTipPeriod(), m_conditions);
+}
+
+// static
+TipsApi::Tip TipsApi::GetTipForTesting(Duration showAnyTipPeriod, Duration showSameTipPeriod,
+ Conditions const & triggers)
+{
+ return GetTipImpl(showAnyTipPeriod, showSameTipPeriod, triggers);
+}
diff --git a/map/tips_api.hpp b/map/tips_api.hpp
new file mode 100644
index 0000000000..a9ed04799d
--- /dev/null
+++ b/map/tips_api.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "eye/eye_info.hpp"
+
+#include <array>
+#include <chrono>
+#include <functional>
+#include <memory>
+
+#include <boost/optional.hpp>
+
+class TipsApi
+{
+public:
+ using Tip = boost::optional<eye::Tips::Type>;
+ using Duration = std::chrono::duration<uint64_t>;
+ using Condition = std::function<bool()>;
+ using Conditions = std::array<Condition, static_cast<size_t>(eye::Tips::Type::Count)>;
+
+ class Delegate
+ {
+ public:
+ virtual boost::optional<m2::PointD> GetCurrentPosition() const = 0;
+ virtual bool IsCountryLoaded(m2::PointD const & pt) const = 0;
+ virtual bool HaveTransit(m2::PointD const & pt) const = 0;
+ };
+
+ static Duration GetShowAnyTipPeriod();
+ static Duration GetShowSameTipPeriod();
+ static size_t GetActionClicksCountToDisable();
+ static size_t GetGotitClicksCountToDisable();
+
+ TipsApi();
+
+ void SetDelegate(std::unique_ptr<Delegate> delegate);
+ Tip GetTip() const;
+
+ static Tip GetTipForTesting(Duration showAnyTipPeriod, Duration showSameTipPeriod,
+ Conditions const & triggers);
+
+private:
+ std::unique_ptr<Delegate> m_delegate;
+ Conditions m_conditions;
+};