[android] Added custom props selection

This commit is contained in:
Dmitry Donskoy 2018-11-13 16:42:55 +03:00 committed by Aleksandr Zatsepin
parent 74b540b5b4
commit 7810f081c5
10 changed files with 319 additions and 46 deletions

View file

@ -450,7 +450,8 @@
<activity android:name="com.mapswithme.maps.ugc.routes.UgcRouteEditSettingsActivity"/>
<activity android:name=".purchase.BookmarkPaymentActivity"/>
<activity android:name="com.mapswithme.maps.ugc.route.SendLinkPlaceholderActivity"/>
<activity android:name="com.mapswithme.maps.ugc.routes.UgcRoutePropertiesActivity"/>
<activity android:name="com.mapswithme.maps.ugc.routes.UgcRoutePropertiesActivity"
android:label="@string/select_properties"/>
<service
android:name="com.mapswithme.maps.background.WorkerService"
android:permission="android.permission.BIND_JOB_SERVICE"

View file

@ -1,7 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress"
android:minWidth="@dimen/search_progress_size"
android:minHeight="@dimen/search_progress_size"
android:paddingTop="@dimen/direction_frame_min_height"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
<LinearLayout
android:id="@+id/properties_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="@string/custom_props_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/margin_base"
android:paddingBottom="@dimen/margin_base"
android:paddingRight="@dimen/margin_half_double_plus"
android:paddingEnd="@dimen/margin_half_double_plus"
android:paddingLeft="@dimen/margin_half_double_plus"
android:paddingStart="@dimen/margin_half_double_plus"/>
<include layout="@layout/list_divider"/>
<TextView
android:text="@string/custom_props_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center"
android:background="?cardBackground"
android:paddingTop="@dimen/margin_base"
android:paddingBottom="@dimen/margin_base"
android:paddingLeft="@dimen/margin_base"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
android:paddingRight="@dimen/margin_base"/>
<LinearLayout
android:id="@+id/btn_container"
android:paddingTop="@dimen/margin_base"
android:paddingBottom="@dimen/margin_base"
android:background="?cardBackground"
android:weightSum="2"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/left_btn"
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/local"
style="@style/MwmWidget.Button.Primary"
android:layout_marginEnd="@dimen/margin_half"
android:layout_marginStart="@dimen/margin_base"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_half"/>
<Button
android:id="@+id/right_btn"
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/traveller"
style="@style/MwmWidget.Button.Primary"
android:layout_marginEnd="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginStart="@dimen/margin_half"
android:layout_marginLeft="@dimen/margin_half"/>
</LinearLayout>
<include layout="@layout/list_divider"/>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
app:showAsAction="always"
android:id="@+id/done"
android:visible="false"
android:title="@string/done"
android:icon="@drawable/ic_done"/>
</menu>

View file

@ -119,6 +119,16 @@ public class TagsCompositeAdapter extends RecyclerView.Adapter<TagsCompositeAdap
return Collections.unmodifiableList(tags);
}
public boolean hasSelectedItems()
{
for (ComponentHolder each : mComponentHolders)
{
if (!each.mAdapter.getSelectedTags().isEmpty())
return true;
}
return false;
}
private static class ComponentHolder
{
@NonNull

View file

@ -282,8 +282,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
private boolean isCategorySharingRestricted()
{
BookmarkCategory category = mCategoryDataSource.getData();
return category.getType() == BookmarkCategory.Type.DOWNLOADED
|| category.getAccessRules() != BookmarkCategory.AccessRules.ACCESS_RULES_LOCAL;
return !category.isSharingOptionsAllowed();
}
@Override

View file

@ -2,18 +2,10 @@ package com.mapswithme.maps.ugc.routes;
import android.support.v4.app.Fragment;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.maps.base.BaseToolbarActivity;
public class UgcRoutePropertiesActivity extends BaseMwmFragmentActivity
public class UgcRoutePropertiesActivity extends BaseToolbarActivity
{
@Override
protected int getContentLayoutResId()
{
return R.layout.fragment_container_layout;
}
@Override
protected Class<? extends Fragment> getFragmentClass()
{

View file

@ -13,17 +13,44 @@ import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.maps.bookmarks.data.CatalogCustomProperty;
import com.mapswithme.maps.bookmarks.data.CatalogCustomPropertyOption;
import com.mapswithme.maps.bookmarks.data.CatalogPropertyOptionAndKey;
import com.mapswithme.maps.bookmarks.data.CatalogTagsGroup;
import com.mapswithme.maps.dialog.AlertDialog;
import com.mapswithme.maps.dialog.AlertDialogCallback;
import com.mapswithme.util.UiUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class UgcRoutePropertiesFragment extends BaseMwmFragment implements BookmarkManager.BookmarksCatalogListener
public class UgcRoutePropertiesFragment extends BaseMwmFragment implements BookmarkManager.BookmarksCatalogListener, AlertDialogCallback
{
public static final String EXTRA_TAGS_ACTIVITY_RESULT = "tags_activity_result";
public static final String EXTRA_CATEGORY_OPTIONS = "category_options";
private static final String BUNDLE_SELECTED_OPTION = "selected_property";
private static final String BUNDLE_CUSTOM_PROPS = "custom_props";
private static final String ERROR_LOADING_DIALOG_TAG = "error_loading_dialog";
private static final int REQ_CODE_LOAD_FAILED = 101;
private static final int MAGIC_MAX_PROPS_COUNT = 1;
private static final int MAGIC_MAX_OPTIONS_COUNT = 2;
private static final int FIRST_OPTION_INDEX = 0;
private static final int SECOND_OPTION_INDEX = 1;
@NonNull
private List<CatalogCustomProperty> mProps = Collections.emptyList();
@Nullable
private CatalogPropertyOptionAndKey mSelectedOption;
@SuppressWarnings("NullableProblems")
@NonNull
private View mProgress;
@SuppressWarnings("NullableProblems")
@NonNull
private View mPropsContainer;
@Nullable
@Override
@ -31,10 +58,71 @@ public class UgcRoutePropertiesFragment extends BaseMwmFragment implements Bookm
@Nullable Bundle savedInstanceState)
{
View root = inflater.inflate(R.layout.fragment_ugc_routes_properties, container, false);
BookmarkManager.INSTANCE.requestCustomProperties();
mSelectedOption = getSelectedOption(savedInstanceState);
mProps = getCustomProps(savedInstanceState);
initViews(root);
if (mProps.isEmpty())
BookmarkManager.INSTANCE.requestCustomProperties();
return root;
}
private void initViews(View root)
{
View leftBtn = root.findViewById(R.id.left_btn);
leftBtn.setOnClickListener(v -> onLeftBtnClicked());
View rightBtn = root.findViewById(R.id.right_btn);
rightBtn.setOnClickListener(v -> onRightBtnClicked());
mPropsContainer = root.findViewById(R.id.properties_container);
UiUtils.hideIf(mProps.isEmpty(), mPropsContainer);
mProgress = root.findViewById(R.id.progress);
UiUtils.showIf(mProps.isEmpty(), mProgress);
}
@Nullable
private static CatalogPropertyOptionAndKey getSelectedOption(@Nullable Bundle savedInstanceState)
{
if (savedInstanceState == null)
return null;
return savedInstanceState.getParcelable(BUNDLE_SELECTED_OPTION);
}
@NonNull
private static List<CatalogCustomProperty> getCustomProps(@Nullable Bundle savedInstanceState)
{
if (savedInstanceState == null)
return Collections.emptyList();
return Objects.requireNonNull(savedInstanceState.getParcelableArrayList(BUNDLE_CUSTOM_PROPS));
}
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
if (mSelectedOption != null)
outState.putParcelable(BUNDLE_SELECTED_OPTION, mSelectedOption);
outState.putParcelableArrayList(BUNDLE_CUSTOM_PROPS, new ArrayList<>(mProps));
}
private void onBtnClicked(int index)
{
checkPropsSize(mProps);
CatalogCustomProperty property = mProps.get(0);
CatalogCustomPropertyOption option = property.getOptions().get(index);
mSelectedOption = new CatalogPropertyOptionAndKey(property.getKey(), option);
Intent intent = new Intent(getContext(), UgcRouteTagsActivity.class);
startActivityForResult(intent, UgcSharingOptionsFragment.REQ_CODE_TAGS_ACTIVITY);
}
private void onRightBtnClicked()
{
onBtnClicked(SECOND_OPTION_INDEX);
}
private void onLeftBtnClicked()
{
onBtnClicked(FIRST_OPTION_INDEX);
}
@Override
public void onStart()
{
@ -52,32 +140,86 @@ public class UgcRoutePropertiesFragment extends BaseMwmFragment implements Bookm
@Override
public void onImportStarted(@NonNull String serverId)
{
/* Do noting by default */
}
@Override
public void onImportFinished(@NonNull String serverId, long catId, boolean successful)
{
/* Do noting by default */
}
@Override
public void onTagsReceived(boolean successful, @NonNull List<CatalogTagsGroup> tagsGroups)
{
/* Do noting by default */
}
@Override
public void onCustomPropertiesReceived(boolean successful,
@NonNull List<CatalogCustomProperty> properties)
{
if (successful)
onLoadSuccess(properties);
else
onLoadFailed();
}
private void onLoadFailed()
{
showLoadFailedDialog();
mProgress.setVisibility(View.GONE);
mPropsContainer.setVisibility(View.GONE);
}
private void showLoadFailedDialog()
{
AlertDialog dialog = new AlertDialog.Builder()
.setTitleId(R.string.discovery_button_viator_error_title)
.setMessageId(R.string.properties_loading_error_subtitle)
.setPositiveBtnId(R.string.try_again)
.setNegativeBtnId(R.string.cancel)
.setReqCode(REQ_CODE_LOAD_FAILED)
.setFragManagerStrategy(new AlertDialog.ActivityFragmentManagerStrategy())
.build();
dialog.setTargetFragment(this, REQ_CODE_LOAD_FAILED);
dialog.show(this, ERROR_LOADING_DIALOG_TAG);
}
private void onLoadSuccess(@NonNull List<CatalogCustomProperty> properties)
{
checkPropsSize(properties);
mProps = properties;
mPropsContainer.setVisibility(View.VISIBLE);
mProgress.setVisibility(View.GONE);
}
private static void checkPropsSize(@NonNull List<CatalogCustomProperty> properties)
{
if ((properties.size() > MAGIC_MAX_PROPS_COUNT
|| properties.get(0).getOptions().size() != MAGIC_MAX_OPTIONS_COUNT))
{
throw makeException(properties);
}
}
@NonNull
private static IllegalArgumentException makeException(@NonNull List<CatalogCustomProperty> properties)
{
return new IllegalArgumentException("Workaround - multiple selection restricted, because " +
"interface doesn't supported that, " +
"and backend and core can not return single POJO " +
"instance. " +
"Props.size() = " + properties.size() +
(properties.isEmpty() ? ""
: " Options.size() = "
+ properties.get(0).getOptions()));
}
@Override
public void onUploadStarted(long originCategoryId)
{
/* Do noting by default */
}
@Override
@ -85,27 +227,58 @@ public class UgcRoutePropertiesFragment extends BaseMwmFragment implements Bookm
@NonNull String description, long originCategoryId,
long resultCategoryId)
{
/* Do noting by default */
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == UgcSharingOptionsFragment.REQ_CODE_TAGS_ACTIVITY && resultCode == Activity.RESULT_OK)
if (requestCode == UgcSharingOptionsFragment.REQ_CODE_TAGS_ACTIVITY)
{
Intent intent = new Intent().putExtra(EXTRA_TAGS_ACTIVITY_RESULT, data);
ArrayList<CatalogPropertyOptionAndKey> options = new ArrayList<>(getSelectedOptions());
intent.putParcelableArrayListExtra(EXTRA_CATEGORY_OPTIONS, options);
getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();
if (resultCode == Activity.RESULT_OK)
{
Intent intent = new Intent();
ArrayList<CatalogPropertyOptionAndKey> options = new ArrayList<>(prepareSelectedOptions());
intent.putParcelableArrayListExtra(EXTRA_CATEGORY_OPTIONS, options);
intent.putExtra(EXTRA_TAGS_ACTIVITY_RESULT, data.getExtras());
getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();
}
else if (resultCode == Activity.RESULT_CANCELED)
{
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
}
}
@NonNull
private List<CatalogPropertyOptionAndKey> getSelectedOptions()
private List<CatalogPropertyOptionAndKey> prepareSelectedOptions()
{
/* FIXME later */
return Collections.emptyList();
return mSelectedOption == null ? Collections.emptyList()
: Collections.singletonList(mSelectedOption);
}
@Override
public void onAlertDialogPositiveClick(int requestCode, int which)
{
mProgress.setVisibility(View.VISIBLE);
mPropsContainer.setVisibility(View.GONE);
BookmarkManager.INSTANCE.requestCustomProperties();
}
@Override
public void onAlertDialogNegativeClick(int requestCode, int which)
{
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
@Override
public void onAlertDialogCancel(int requestCode)
{
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
}

View file

@ -5,8 +5,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
@ -117,7 +116,20 @@ public class UgcRouteTagsFragment extends BaseMwmFragment implements BookmarkMan
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.menu_done, menu);
inflater.inflate(R.menu.menu_tags_done, menu);
}
@Override
public void onPrepareOptionsMenu(Menu menu)
{
super.onPrepareOptionsMenu(menu);
MenuItem item = menu.findItem(R.id.done);
item.setVisible(hasSelectedItems());
}
private boolean hasSelectedItems()
{
return mTagsAdapter != null && mTagsAdapter.hasSelectedItems();
}
@Override
@ -248,6 +260,7 @@ public class UgcRouteTagsFragment extends BaseMwmFragment implements BookmarkMan
public void onItemClick(@NonNull View v,
@NonNull Pair<TagsAdapter, TagsAdapter.TagViewHolder> item)
{
ActivityCompat.invalidateOptionsMenu(getActivity());
TagsAdapter adapter = item.first;
int position = item.second.getAdapterPosition();
adapter.notifyItemChanged(position);
@ -262,12 +275,14 @@ public class UgcRouteTagsFragment extends BaseMwmFragment implements BookmarkMan
@Override
public void onAlertDialogNegativeClick(int requestCode, int which)
{
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
@Override
public void onAlertDialogCancel(int requestCode)
{
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
}

View file

@ -243,8 +243,8 @@ public class UgcSharingOptionsFragment extends BaseMwmAuthorizationFragment impl
private void openTagsScreen()
{
Intent intent = new Intent(getContext(), UgcRouteTagsActivity.class);
startActivityForResult(intent, REQ_CODE_TAGS_ACTIVITY);
Intent intent = new Intent(getContext(), UgcRoutePropertiesActivity.class);
startActivityForResult(intent, REQ_CODE_CUSTOM_PROPERTIES);
}
private void onUploadAndPublishBtnClicked()
@ -332,11 +332,11 @@ public class UgcSharingOptionsFragment extends BaseMwmAuthorizationFragment impl
private void requestPublishing(@NonNull Intent data)
{
showProgress();
Intent tagsActivityResult = data.getParcelableExtra(UgcRoutePropertiesFragment.EXTRA_TAGS_ACTIVITY_RESULT);
Bundle tagsActivityResult = data.getParcelableExtra(UgcRoutePropertiesFragment.EXTRA_TAGS_ACTIVITY_RESULT);
List<CatalogTag> tags = tagsActivityResult.getParcelableArrayListExtra(UgcRouteTagsActivity.EXTRA_TAGS);
List<CatalogTag> tags = tagsActivityResult.getParcelableArrayList(UgcRouteTagsActivity.EXTRA_TAGS);
List<CatalogPropertyOptionAndKey> options = data.getParcelableArrayListExtra(UgcRoutePropertiesFragment.EXTRA_CATEGORY_OPTIONS);
BookmarkManager.INSTANCE.setCategoryTags(mCategory, tags);
BookmarkManager.INSTANCE.setCategoryTags(mCategory, Objects.requireNonNull(tags));
BookmarkManager.INSTANCE.setCategoryProperties(mCategory, options);
BookmarkManager.INSTANCE.uploadToCatalog(BookmarkCategory.AccessRules.ACCESS_RULES_PUBLIC, mCategory);
}
@ -425,7 +425,6 @@ public class UgcSharingOptionsFragment extends BaseMwmAuthorizationFragment impl
private void onUploadError(@NonNull BookmarkManager.UploadResult uploadResult)
{
/* FIXME later */
if (uploadResult == BookmarkManager.UploadResult.UPLOAD_RESULT_MALFORMED_DATA_ERROR)
{
showErrorBrokenFileDialog();

View file

@ -398,8 +398,7 @@ void BookmarkCatalog::RequestCustomProperties(std::string const & language,
}
else
{
LOG(LWARNING, ("Custom properties request error. Code =", resultCode,
"Response =", request.ServerResponse()));
LOG(LWARNING, ("Custom properties request error. Code =", resultCode));
}
}
if (callback)