diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java index 1cf53b9b4..c94977604 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java @@ -700,22 +700,27 @@ public class PlacePageView extends Fragment if (shouldEnableEditPlace) { + mTvEditPlace.setEnabled(true); + mTvAddPlace.setEnabled(true); mTvEditPlace.setOnClickListener(this); mTvAddPlace.setOnClickListener(this); } else { - mTvEditPlace.setOnClickListener((v) -> { - Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); - }); - mTvAddPlace.setOnClickListener((v) -> { - Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); - }); - String countryId = MapManager.nativeGetSelectedCountry(); - if (countryId != null) + if (countryId != null && MapManager.nativeIsMapTooOldToEdit(countryId)) { + // map editing is disabled because the map is too old + mTvEditPlace.setEnabled(true); + mTvAddPlace.setEnabled(true); + mTvEditPlace.setOnClickListener((v) -> { + Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); + }); + mTvAddPlace.setOnClickListener((v) -> { + Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); + }); + CountryItem map = CountryItem.fill(countryId); if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE @@ -740,6 +745,12 @@ public class PlacePageView extends Fragment mapTooOldDescription.setText(R.string.place_page_app_too_old_description); } } + else + { + // map editing is disabled for other reasons + mTvEditPlace.setEnabled(false); + mTvAddPlace.setEnabled(false); + } } final int editButtonColor = diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/MapManager.cpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/MapManager.cpp index b8f1e2fe5..6d18e55ef 100644 --- a/android/sdk/src/main/cpp/app/organicmaps/sdk/MapManager.cpp +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/MapManager.cpp @@ -587,4 +587,11 @@ JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeG storage::CountryId const & res = g_framework->GetPlacePageInfo().GetCountryId(); return (res == storage::kInvalidCountryId ? nullptr : jni::ToJavaString(env, res)); } + +// static native boolean nativeIsMapTooOldToEdit(String countryId); +JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsMapTooOldToEdit(JNIEnv *env, jclass clazz, + jstring country_id) +{ + return GetStorage().IsMapTooOldToEdit(jni::ToNativeString(env, country_id)); +} } // extern "C" diff --git a/android/sdk/src/main/java/app/organicmaps/sdk/downloader/MapManager.java b/android/sdk/src/main/java/app/organicmaps/sdk/downloader/MapManager.java index e879d1f26..6784cdef6 100644 --- a/android/sdk/src/main/java/app/organicmaps/sdk/downloader/MapManager.java +++ b/android/sdk/src/main/java/app/organicmaps/sdk/downloader/MapManager.java @@ -261,4 +261,9 @@ public final class MapManager * Returns country ID which the current PP object points to, or {@code null}. */ public static native @Nullable String nativeGetSelectedCountry(); + + /** + * Returns true when the map exists and is too old for map editing. + */ + public static native boolean nativeIsMapTooOldToEdit(String countryId); } diff --git a/libs/storage/storage.cpp b/libs/storage/storage.cpp index 665d3df53..3a42039c9 100644 --- a/libs/storage/storage.cpp +++ b/libs/storage/storage.cpp @@ -1252,16 +1252,33 @@ bool Storage::IsAllowedToEditVersion(CountryId const & countryId) const case Status::OnDiskOutOfDate: { auto const localFile = GetLatestLocalFile(countryId); - ASSERT(localFile, ("Local file shouldn't be nullptr.")); - auto const currentVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast(m_currentVersion)); - auto const localVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast(localFile->GetVersion())); - return currentVersionTime - localVersionTime < kMaxSecondsTillLastVersionUpdate && - base::SecondsSinceEpoch() - localVersionTime < kMaxSecondsTillNoEdits; + return IsAllowedToEditFile(localFile); } default: return false; } } +bool Storage::IsMapTooOldToEdit(CountryId const & countryId) const +{ + auto const status = CountryStatusEx(countryId); + if (status == Status::OnDiskOutOfDate) + { + LocalFilePtr const localFile = GetLatestLocalFile(countryId); + return !IsAllowedToEditFile(localFile); + } + + return false; +} + +bool Storage::IsAllowedToEditFile(LocalFilePtr const & localFile) const +{ + ASSERT(localFile, ("Local file shouldn't be nullptr.")); + auto const currentVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast(m_currentVersion)); + auto const localVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast(localFile->GetVersion())); + return currentVersionTime - localVersionTime < kMaxSecondsTillLastVersionUpdate && + base::SecondsSinceEpoch() - localVersionTime < kMaxSecondsTillNoEdits; +} + int64_t Storage::GetVersion(CountryId const & countryId) const { CHECK_THREAD_CHECKER(m_threadChecker, ()); diff --git a/libs/storage/storage.hpp b/libs/storage/storage.hpp index fc3fa7a60..98117be89 100644 --- a/libs/storage/storage.hpp +++ b/libs/storage/storage.hpp @@ -383,6 +383,9 @@ public: /// \brief Returns true if the version of countryId can be used to update maps. bool IsAllowedToEditVersion(CountryId const & countryId) const; + /// \brief Returns true when the map exists and is too old for map editing. + bool IsMapTooOldToEdit(CountryId const & countryId) const; + /// Returns version of downloaded mwm or zero. int64_t GetVersion(CountryId const & countryId) const; @@ -625,6 +628,8 @@ private: // Returns a path to a place on disk downloader can use for downloaded files. std::string GetFileDownloadPath(CountryId const & countryId, MapFileType file) const; + bool IsAllowedToEditFile(LocalFilePtr const & localFile) const; + /// Fast version, doesn't check if country is out of date Status CountryStatus(CountryId const & countryId) const;