diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 0d4ae4220a..07bb95fe02 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -757,9 +757,10 @@ void Framework::RequestUGC(FeatureID const & fid, ugc::Api::UGCCallback const & m_work.GetUGC(fid, ugcCallback); } -void Framework::SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc) +void Framework::SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc, + ugc::Api::OnResultCallback const & callback /* = nullptr */) { - m_work.GetUGCApi()->SetUGCUpdate(fid, ugc); + m_work.GetUGCApi()->SetUGCUpdate(fid, ugc, callback); } void Framework::UploadUGC() diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index bd313352bf..e1dbb774f2 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -209,7 +209,8 @@ namespace android std::string const & productId, ms::LatLon const & from, ms::LatLon const & to); void RequestUGC(FeatureID const & fid, ugc::Api::UGCCallback const & ugcCallback); - void SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc); + void SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc, + ugc::Api::OnResultCallback const & callback = nullptr); void UploadUGC(); int ToDoAfterUpdate() const; diff --git a/android/jni/com/mapswithme/maps/ugc/UGC.cpp b/android/jni/com/mapswithme/maps/ugc/UGC.cpp index 4f4be3944f..8f7041df64 100644 --- a/android/jni/com/mapswithme/maps/ugc/UGC.cpp +++ b/android/jni/com/mapswithme/maps/ugc/UGC.cpp @@ -63,7 +63,7 @@ private: class JavaBridge { public: - void OnResult(JNIEnv * env, ugc::UGC const & ugc, ugc::UGCUpdate const & ugcUpdate) + void OnUGCReceived(JNIEnv * env, ugc::UGC const & ugc, ugc::UGCUpdate const & ugcUpdate) { Init(env); jni::TScopedLocalRef ugcResult(env, ToJavaUGC(env, ugc)); @@ -72,10 +72,16 @@ public: std::string formattedRating = place_page::rating::GetRatingFormatted(ugc.m_totalRating); jni::TScopedLocalRef jrating(env, jni::ToJavaString(env, formattedRating)); - env->CallStaticVoidMethod(m_ugcClass, m_onResult, ugcResult.get(), ugcUpdateResult.get(), + env->CallStaticVoidMethod(m_ugcClass, m_ugcReceived, ugcResult.get(), ugcUpdateResult.get(), ToImpress(ugc.m_totalRating), jrating.get()); } + void OnUGCSaved(JNIEnv * env, ugc::Storage::SettingResult const & saveResult) + { + auto const result = static_cast(saveResult == ugc::Storage::SettingResult::Success); + env->CallStaticVoidMethod(m_ugcClass, m_ugcSaved, result); + } + static int ToImpress(float const rating) { return static_cast(place_page::rating::GetImpress(rating)); @@ -210,8 +216,9 @@ private: m_ugcCtor = jni::GetConstructorID( env, m_ugcClass, "([Lcom/mapswithme/maps/ugc/UGC$Rating;F[Lcom/mapswithme/maps/ugc/UGC$Review;I)V"); - m_onResult = jni::GetStaticMethodID(env, m_ugcClass, "onUGCReceived", - "(Lcom/mapswithme/maps/ugc/UGC;Lcom/mapswithme/maps/ugc/UGCUpdate;ILjava/lang/String;)V"); + m_ugcReceived = jni::GetStaticMethodID( + env, m_ugcClass, "onUGCReceived", + "(Lcom/mapswithme/maps/ugc/UGC;Lcom/mapswithme/maps/ugc/UGCUpdate;ILjava/lang/String;)V"); m_ratingCtor = jni::GetConstructorID(env, g_ratingClazz, "(Ljava/lang/String;F)V"); @@ -230,6 +237,8 @@ private: m_keyboardLocaleFieldId = env->GetFieldID(m_ugcUpdateClass, "mKeyboardLocale", "Ljava/lang/String;"); m_ratingNameFieldId = env->GetFieldID(g_ratingClazz, "mName", "Ljava/lang/String;"); m_ratingValueFieldId = env->GetFieldID(g_ratingClazz, "mValue", "F"); + m_ugcSaved = jni::GetStaticMethodID(env, m_ugcClass, "onUGCSaved", "(Z)V"); + m_initialized = true; } @@ -248,7 +257,8 @@ private: jfieldID m_ratingNameFieldId; jfieldID m_ratingValueFieldId; - jmethodID m_onResult; + jmethodID m_ugcReceived; + jmethodID m_ugcSaved; jmethodID m_ratingCtor; @@ -259,23 +269,25 @@ private: extern "C" { JNIEXPORT -void JNICALL Java_com_mapswithme_maps_ugc_UGC_requestUGC(JNIEnv * env, jclass /* clazz */, - jobject featureId) +void JNICALL Java_com_mapswithme_maps_ugc_UGC_nativeRequestUGC(JNIEnv * env, jclass /* clazz */, + jobject featureId) { auto const fid = g_builder.Build(env, featureId); - g_framework->RequestUGC(fid, [&](ugc::UGC const & ugc, ugc::UGCUpdate const & update) { - JNIEnv * e = jni::GetEnv(); - g_bridge.OnResult(e, ugc, update); + g_framework->RequestUGC(fid, [](ugc::UGC const & ugc, ugc::UGCUpdate const & update) { + g_bridge.OnUGCReceived(jni::GetEnv(), ugc, update); }); } JNIEXPORT -void JNICALL Java_com_mapswithme_maps_ugc_UGC_setUGCUpdate(JNIEnv * env, jclass /* clazz */, - jobject featureId, jobject ugcUpdate) +void JNICALL Java_com_mapswithme_maps_ugc_UGC_nativeSetUGCUpdate(JNIEnv * env, jclass /* clazz */, + jobject featureId, + jobject ugcUpdate) { auto const fid = g_builder.Build(env, featureId); ugc::UGCUpdate update = g_bridge.ToNativeUGCUpdate(env, ugcUpdate); - g_framework->SetUGCUpdate(fid, update); + g_framework->SetUGCUpdate(fid, update, [](ugc::Storage::SettingResult const & result) { + g_bridge.OnUGCSaved(jni::GetEnv(), result); + }); } JNIEXPORT diff --git a/android/src/com/mapswithme/maps/ugc/UGC.java b/android/src/com/mapswithme/maps/ugc/UGC.java index 53c034ff53..10f5361984 100644 --- a/android/src/com/mapswithme/maps/ugc/UGC.java +++ b/android/src/com/mapswithme/maps/ugc/UGC.java @@ -41,12 +41,14 @@ public class UGC private final int mBasedOnCount; private final float mAverageRating; @Nullable - private static UGCListener mListener; + private static ReceiveUGCListener mReceiveListener; + @Nullable + private static SaveUGCListener mSaveListener; public static void init(final @NonNull Context context) { final AppBackgroundTracker.OnTransitionListener listener = new UploadUgcTransitionListener(context); - MwmApplication.backgroundTracker().addListener(listener); + MwmApplication.backgroundTracker(context).addListener(listener); } private UGC(@NonNull Rating[] ratings, float averageRating, @Nullable Review[] reviews, @@ -78,14 +80,24 @@ public class UGC return Arrays.asList(mReviews); } - public static void setListener(@Nullable UGCListener listener) + public static void setReceiveListener(@Nullable ReceiveUGCListener listener) { - mListener = listener; + mReceiveListener = listener; } - public static native void requestUGC(@NonNull FeatureId fid); + public static void setSaveListener(@Nullable SaveUGCListener listener) + { + mSaveListener = listener; + } - public static native void setUGCUpdate(@NonNull FeatureId fid, UGCUpdate update); + public static void setUGCUpdate(@NonNull FeatureId fid, UGCUpdate update) + { + nativeSetUGCUpdate(fid, update); + } + + public static native void nativeRequestUGC(@NonNull FeatureId fid); + + public static native void nativeSetUGCUpdate(@NonNull FeatureId fid, UGCUpdate update); public static native void nativeUploadUGC(); @@ -94,15 +106,27 @@ public class UGC @NonNull public static native String nativeFormatRating(float rating); + // Called from JNI. + @SuppressWarnings("unused") public static void onUGCReceived(@Nullable UGC ugc, @Nullable UGCUpdate ugcUpdate, @Impress int impress, @NonNull String rating) { - if (mListener != null) - { - if (ugc == null && ugcUpdate != null) - impress = UGC.RATING_COMING_SOON; - mListener.onUGCReceived(ugc, ugcUpdate, impress, rating); - } + if (mReceiveListener == null) + return; + + if (ugc == null && ugcUpdate != null) + impress = UGC.RATING_COMING_SOON; + mReceiveListener.onUGCReceived(ugc, ugcUpdate, impress, rating); + } + + // Called from JNI. + @SuppressWarnings("unused") + public static void onUGCSaved(boolean result) + { + if (mSaveListener == null) + return; + + mSaveListener.onUGCSaved(result); } public static class Rating implements Parcelable @@ -258,12 +282,17 @@ public class UGC } } - interface UGCListener + interface ReceiveUGCListener { void onUGCReceived(@Nullable UGC ugc, @Nullable UGCUpdate ugcUpdate, @Impress int impress, @NonNull String rating); } + interface SaveUGCListener + { + void onUGCSaved(boolean result); + } + private static class UploadUgcTransitionListener implements AppBackgroundTracker.OnTransitionListener { @NonNull diff --git a/android/src/com/mapswithme/maps/ugc/UGCController.java b/android/src/com/mapswithme/maps/ugc/UGCController.java index 5e8827cf6f..6ca2673ae7 100644 --- a/android/src/com/mapswithme/maps/ugc/UGCController.java +++ b/android/src/com/mapswithme/maps/ugc/UGCController.java @@ -24,7 +24,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; -public class UGCController implements View.OnClickListener, UGC.UGCListener +public class UGCController implements View.OnClickListener, UGC.ReceiveUGCListener { @NonNull private final View mUgcRootView; @@ -142,7 +142,7 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener mReviewListDivider = mPlacePage.findViewById(R.id.ugc_review_list_divider); mUserReviewDivider = mPlacePage.findViewById(R.id.user_review_divider); - UGC.setListener(this); + UGC.setReceiveListener(this); } public void clearViewsFor(@NonNull MapObject mapObject) @@ -186,7 +186,7 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener return; mMapObject = mapObject; - UGC.requestUGC(mMapObject.getFeatureId()); + UGC.nativeRequestUGC(mMapObject.getFeatureId()); } @Override diff --git a/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java b/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java index d171d3aec6..c0d7440753 100644 --- a/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java +++ b/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java @@ -1,6 +1,7 @@ package com.mapswithme.maps.ugc; import android.os.Bundle; +import android.support.annotation.CallSuper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; @@ -80,26 +81,7 @@ public class UGCEditorFragment extends BaseToolbarAuthFragment super.onViewCreated(view, savedInstanceState); getToolbarController().setTitle(getArguments().getString(ARG_TITLE)); View submitButton = getToolbarController().findViewById(R.id.submit); - submitButton.setOnClickListener(v -> - { - onSubmitButtonClick(); - if (!ConnectionState.isConnected()) - { - if (isAuthorized()) - { - Utils.toastShortcut(getContext(), - R.string.ugc_thanks_message_auth); - } - else - { - Utils.toastShortcut(getContext(), - R.string.ugc_thanks_message_not_auth); - } - finishActivity(); - return; - } - authorize(); - }); + submitButton.setOnClickListener(v -> onSubmitButtonClick()); } @NonNull @@ -117,6 +99,48 @@ public class UGCEditorFragment extends BaseToolbarAuthFragment }; } + @Override + @CallSuper + public void onStart() + { + super.onStart(); + + UGC.setSaveListener((boolean result) -> + { + if (!result) + { + finishActivity(); + return; + } + + UserActionsLogger.logUgcSaved(); + Statistics.INSTANCE.trackEvent(Statistics.EventName.UGC_REVIEW_SUCCESS); + + if (!ConnectionState.isConnected()) + { + if (isAuthorized()) + { + Utils.toastShortcut(getContext(), R.string.ugc_thanks_message_auth); + } + else + { + Utils.toastShortcut(getContext(), R.string.ugc_thanks_message_not_auth); + } + finishActivity(); + return; + } + authorize(); + }); + } + + @Override + @CallSuper + public void onStop() + { + super.onStop(); + UGC.setSaveListener(null); + } + @Override public void onAuthorizationFinish(boolean success) { @@ -180,8 +204,7 @@ public class UGCEditorFragment extends BaseToolbarAuthFragment "; lat = " + getArguments().getDouble(ARG_LAT) + "; lon = " + getArguments().getDouble(ARG_LON)); } + UGC.setUGCUpdate(featureId, update); - UserActionsLogger.logUgcSaved(); - Statistics.INSTANCE.trackEvent(Statistics.EventName.UGC_REVIEW_SUCCESS); } }