diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index f70bd4a492..6fa086389e 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -588,6 +588,11 @@ void Framework::RequestUGC(FeatureID const & fid, ugc::Api::UGCCallback const & m_work.GetUGCApi()->GetUGC(fid, ugcCallback); } +void Framework::SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc) +{ + m_work.GetUGCApi()->SetUGCUpdate(fid, ugc); +} + uint64_t Framework::GetRentNearby(JNIEnv * env, jobject policy, ms::LatLon const & latlon, cian::Api::RentNearbyCallback const & onSuccess, cian::Api::ErrorCallback const & onError) diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index 03f25a4e16..952eed8d9e 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -201,6 +201,7 @@ namespace android viator::GetTop5ProductsCallback const & callback); void RequestUGC(FeatureID const & fid, ugc::Api::UGCCallback const & ugcCallback); + void SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc); uint64_t GetRentNearby(JNIEnv * env, jobject policy, ms::LatLon const & latlon, cian::Api::RentNearbyCallback const & onSuccess, diff --git a/android/jni/com/mapswithme/maps/ugc/UGC.cpp b/android/jni/com/mapswithme/maps/ugc/UGC.cpp index 4cb4fa78c7..7fdb78abe2 100644 --- a/android/jni/com/mapswithme/maps/ugc/UGC.cpp +++ b/android/jni/com/mapswithme/maps/ugc/UGC.cpp @@ -57,11 +57,38 @@ private: class JavaBridge { public: - void OnResult(JNIEnv * env, ugc::UGC const & ugc) + void OnResult(JNIEnv * env, ugc::UGC const & ugc, ugc::UGCUpdate const & ugcUpdate) { Init(env); - jni::TScopedLocalRef result(env, ToJavaUGC(env, ugc)); - env->CallStaticVoidMethod(m_ugcClass, m_onResult, result.get()); + jni::TScopedLocalRef ugcResult(env, ToJavaUGC(env, ugc)); + jni::TScopedLocalRef ugcUpdateResult(env, ToJavaUGCUpdate(env, ugcUpdate)); + env->CallStaticVoidMethod(m_ugcClass, m_onResult, ugcResult.get(), ugcUpdateResult.get()); + } + + ugc::UGCUpdate ToNativeUGCUpdate(JNIEnv * env, jobject ugcUpdate) + { + Init(env); + + jobjectArray jratings = static_cast(env->GetObjectField(ugcUpdate, m_ratingArrayFieldId)); + int const length = env->GetArrayLength(jratings); + std::vector records(length); + for (int i = 0; i < length; i++) + { + jobject jrating = env->GetObjectArrayElement(jratings, i); + + jstring name = static_cast(env->GetObjectField(jrating, m_ratingNameFieldId)); + ugc::TranslationKey key(jni::ToNativeString(env, name)); + + jfloat value = env->GetFloatField(jrating, m_ratingValueFieldId); + auto const ratingValue = static_cast(value); + + ugc::RatingRecord record(key, ratingValue); + records.push_back(record); + } + jstring jtext = static_cast(env->GetObjectField(ugcUpdate, m_ratingTextFieldId)); + // TODO: use lang parameter correctly. + ugc::Text text(jni::ToNativeString(env, jtext), 1); + return ugc::UGCUpdate(records, text, std::chrono::system_clock::now()); } private: @@ -76,6 +103,16 @@ private: return result; } + jobject ToJavaUGCUpdate(JNIEnv * env, ugc::UGCUpdate const & ugcUpdate) + { + jni::TScopedLocalObjectArrayRef ratings(env, ToJavaRatings(env, ugcUpdate.m_ratings)); + jni::TScopedLocalRef text(env, jni::ToJavaString(env, ugcUpdate.m_text.m_text)); + + jobject result = env->NewObject(m_ugcUpdateClass, m_ugcUpdateCtor, ratings.get(), text.get()); + ASSERT(result, ()); + return result; + } + jobjectArray ToJavaRatings(JNIEnv * env, std::vector const & ratings) { size_t const n = ratings.size(); @@ -128,7 +165,7 @@ private: env, m_ugcClass, "([Lcom/mapswithme/maps/ugc/UGC$Rating;F[Lcom/mapswithme/maps/ugc/UGC$Review;)V"); m_onResult = jni::GetStaticMethodID(env, m_ugcClass, "onUGCReceived", - "(Lcom/mapswithme/maps/ugc/UGC;)V"); + "(Lcom/mapswithme/maps/ugc/UGC;Lcom/mapswithme/maps/ugc/UGCUpdate;)V"); m_ratingClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/ugc/UGC$Rating"); m_ratingCtor = jni::GetConstructorID(env, m_ratingClass, "(Ljava/lang/String;F)V"); @@ -137,6 +174,13 @@ private: m_reviewCtor = jni::GetConstructorID(env, m_reviewClass, "(Ljava/lang/String;Ljava/lang/String;J)V"); + m_ugcUpdateClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/ugc/UGCUpdate"); + m_ugcUpdateCtor = jni::GetConstructorID( + env, m_ugcUpdateClass, "([Lcom/mapswithme/maps/ugc/UGC$Rating;Ljava/lang/String;)V"); + m_ratingArrayFieldId = env->GetFieldID(m_ugcUpdateClass, "mRatings", "[Lcom/mapswithme/maps/ugc/UGC$Rating;"); + m_ratingTextFieldId = env->GetFieldID(m_ugcUpdateClass, "mText", "Ljava/lang/String;"); + m_ratingNameFieldId = env->GetFieldID(m_ratingClass, "mName", "Ljava/lang/String;"); + m_ratingValueFieldId = env->GetFieldID(m_ratingClass, "mValue", "F"); m_initialized = true; } @@ -144,6 +188,14 @@ private: jclass m_ugcClass; jmethodID m_ugcCtor; + + jclass m_ugcUpdateClass; + jmethodID m_ugcUpdateCtor; + jfieldID m_ratingArrayFieldId; + jfieldID m_ratingTextFieldId; + jfieldID m_ratingNameFieldId; + jfieldID m_ratingValueFieldId; + jmethodID m_onResult; jclass m_ratingClass; @@ -155,13 +207,23 @@ private: } // namespace extern "C" { -JNIEXPORT void JNICALL Java_com_mapswithme_maps_ugc_UGC_requestUGC(JNIEnv * env, jclass /* clazz */, +JNIEXPORT +void JNICALL Java_com_mapswithme_maps_ugc_UGC_requestUGC(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); + g_bridge.OnResult(e, ugc, update); }); } + +JNIEXPORT +void JNICALL Java_com_mapswithme_maps_ugc_UGC_setUGCUpdate(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); +} } diff --git a/android/src/com/mapswithme/maps/ugc/UGC.java b/android/src/com/mapswithme/maps/ugc/UGC.java index 745014c8ab..f165009dbe 100644 --- a/android/src/com/mapswithme/maps/ugc/UGC.java +++ b/android/src/com/mapswithme/maps/ugc/UGC.java @@ -79,12 +79,14 @@ public class UGC implements Serializable mListener = listener; } - public static native void requestUGC(FeatureId fid); + public static native void requestUGC(@NonNull FeatureId fid); - public static void onUGCReceived(@NonNull UGC ugc) + public static native void setUGCUpdate(@NonNull FeatureId fid, UGCUpdate update); + + public static void onUGCReceived(@NonNull UGC ugc, @NonNull UGCUpdate ugcUpdate) { if (mListener != null) - mListener.onUGCReceived(ugc); + mListener.onUGCReceived(ugc, ugcUpdate); } public static class Rating implements Serializable @@ -151,6 +153,6 @@ public class UGC implements Serializable public interface UGCListener { - void onUGCReceived(@NonNull UGC ugc); + void onUGCReceived(@NonNull UGC ugc, @NonNull UGCUpdate ugcUpdate); } } diff --git a/android/src/com/mapswithme/maps/ugc/UGCController.java b/android/src/com/mapswithme/maps/ugc/UGCController.java index 5a2cfcce0a..e644abdf1a 100644 --- a/android/src/com/mapswithme/maps/ugc/UGCController.java +++ b/android/src/com/mapswithme/maps/ugc/UGCController.java @@ -49,7 +49,7 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener return; UGCEditorActivity.start((Activity) mPlacePage.getContext(), mMapObject.getTitle(), - mMapObject.getFeatureId().getFeatureIndex(), + mMapObject.getFeatureId(), mUgc, UGC.RATING_HORRIBLE); } }; @@ -58,6 +58,8 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener private MapObject mMapObject; @Nullable private UGC mUgc; + @Nullable + private UGCUpdate mUGCUpdate; public UGCController(@NonNull final PlacePageView placePage) { @@ -167,9 +169,10 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener } @Override - public void onUGCReceived(@NonNull UGC ugc) + public void onUGCReceived(@NonNull UGC ugc, @NonNull UGCUpdate ugcUpdate) { mUgc = ugc; + mUGCUpdate = ugcUpdate; if (ugc.getReviews() != null) mUGCReviewAdapter.setItems(ugc.getReviews()); mUGCRatingRecordsAdapter.setItems(ugc.getRatings()); @@ -184,7 +187,7 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener return; UGCEditorActivity.start((Activity) mPlacePage.getContext(), mMapObject.getTitle(), - mMapObject.getFeatureId().getFeatureIndex(), + mMapObject.getFeatureId(), mUgc, rating); } } diff --git a/android/src/com/mapswithme/maps/ugc/UGCEditorActivity.java b/android/src/com/mapswithme/maps/ugc/UGCEditorActivity.java index 42cdea2d90..527c4893c6 100644 --- a/android/src/com/mapswithme/maps/ugc/UGCEditorActivity.java +++ b/android/src/com/mapswithme/maps/ugc/UGCEditorActivity.java @@ -7,20 +7,21 @@ import android.support.annotation.StyleRes; import android.support.v4.app.Fragment; import com.mapswithme.maps.base.BaseMwmFragmentActivity; +import com.mapswithme.maps.bookmarks.data.FeatureId; import com.mapswithme.util.ThemeUtils; public class UGCEditorActivity extends BaseMwmFragmentActivity { - private static final String EXTRA_FEATURE_INDEX = "extra_feature_index"; + static final String EXTRA_FEATURE_ID = "extra_feautre_id"; static final String EXTRA_UGC = "extra_ugc"; static final String EXTRA_TITLE = "extra_title"; static final String EXTRA_AVG_RATING = "extra_avg_rating"; public static void start(@NonNull Activity activity, @NonNull String title, - int featureIndex, @NonNull UGC ugc, @UGC.UGCRating int rating) + @NonNull FeatureId featureId, @NonNull UGC ugc, @UGC.UGCRating int rating) { final Intent i = new Intent(activity, UGCEditorActivity.class); - i.putExtra(EXTRA_FEATURE_INDEX, featureIndex); + i.putExtra(EXTRA_FEATURE_ID, featureId); i.putExtra(EXTRA_UGC, ugc); i.putExtra(EXTRA_TITLE, title); i.putExtra(EXTRA_AVG_RATING, rating); diff --git a/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java b/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java index 7fd16a32ed..b78d5a7002 100644 --- a/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java +++ b/android/src/com/mapswithme/maps/ugc/UGCEditorFragment.java @@ -12,6 +12,7 @@ import android.view.ViewGroup; import com.mapswithme.maps.R; import com.mapswithme.maps.auth.BaseMwmAuthorizationFragment; +import com.mapswithme.maps.bookmarks.data.FeatureId; import com.mapswithme.util.log.Logger; import com.mapswithme.util.log.LoggerFactory; @@ -24,6 +25,8 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment private static final String TAG = UGCEditorFragment.class.getSimpleName(); @NonNull private final UGCRatingAdapter mUGCRatingAdapter = new UGCRatingAdapter(); + //TODO: field just for testing. + private List mRatings; @Nullable @Override @@ -40,10 +43,10 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment //TODO: use parcelable instead of serializable Intent intent = getActivity().getIntent(); UGC ugc = (UGC) intent.getSerializableExtra(UGCEditorActivity.EXTRA_UGC); - List avgRatings = new ArrayList<>(ugc.getRatings()); - for (UGC.Rating rating: avgRatings) + mRatings = new ArrayList<>(ugc.getRatings()); + for (UGC.Rating rating: mRatings) rating.setValue(getActivity().getIntent().getIntExtra(UGCEditorActivity.EXTRA_AVG_RATING, 3)); - mUGCRatingAdapter.setItems(avgRatings); + mUGCRatingAdapter.setItems(mRatings); return root; } @@ -56,6 +59,18 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment mToolbarController.setTitle(intent.getStringExtra(UGCEditorActivity.EXTRA_TITLE)); } + @Override + protected void onSubmitButtonClick() + { + super.onSubmitButtonClick(); + UGC.Rating[] ratings = new UGC.Rating[mRatings.size()]; + for (int i = 0; i < ratings.length; i++) + ratings[i] = mRatings.get(i); + //TODO: just for testing + UGCUpdate update = new UGCUpdate(ratings, "Test text"); + UGC.setUGCUpdate((FeatureId) getActivity().getIntent().getParcelableExtra(UGCEditorActivity.EXTRA_FEATURE_ID), update); + } + @Override protected void onPreSocialAuthentication() { diff --git a/android/src/com/mapswithme/maps/ugc/UGCUpdate.java b/android/src/com/mapswithme/maps/ugc/UGCUpdate.java new file mode 100644 index 0000000000..dd90df64e1 --- /dev/null +++ b/android/src/com/mapswithme/maps/ugc/UGCUpdate.java @@ -0,0 +1,43 @@ +package com.mapswithme.maps.ugc; + +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.Nullable; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class UGCUpdate +{ + @Nullable + private final UGC.Rating[] mRatings; + @Nullable + private String mText; + + public UGCUpdate(@Nullable UGC.Rating[] ratings, @Nullable String text) + { + mRatings = ratings; + mText = text; + } + + public void setText(@Nullable String text) + { + mText = text; + } + + @Nullable + public String getText() + { + return mText; + } + + @Nullable + public List getRatings() + { + if (mRatings == null) + return null; + + return Collections.synchronizedList(Arrays.asList(mRatings)); + } +}