#3503 Remove Title/Caption From MediaUploadDetail and only use Caption/Description pairs (#3578)

* #3529 Captions/depictions are not saved to Commons - make copy of list of depictionEntityIds - uncomment editBaseDepictsProperty - refactor upload related classes

* #3529 Captions/depictions are not saved to Commons - fix wrong ArrayList usage

* #3529 Captions/depictions are not saved to Commons - fix test

* #3503 Remove Title/Caption From MediaUploadDetail and only use Caption/Description pairs - replace title with the first MediaDetail

* #3503 Remove Title/Caption From MediaUploadDetail and only use Caption/Description pairs - restore button disabling

* #3503 Remove Title/Caption From MediaUploadDetail and only use Caption/Description pairs - fix nearby place
This commit is contained in:
Seán Mac Gillicuddy 2020-03-26 10:17:05 +00:00 committed by GitHub
parent 23b8c2e659
commit dec68ed922
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 40 additions and 160 deletions

View file

@ -2,6 +2,7 @@ package fr.free.nrw.commons;
import androidx.annotation.NonNull;
import okhttp3.logging.HttpLoggingInterceptor.Level;
import org.wikipedia.dataclient.SharedPreferenceCookieManager;
import org.wikipedia.dataclient.okhttp.HttpStatusException;
@ -40,7 +41,7 @@ public final class OkHttpConnectionFactory {
private static HttpLoggingInterceptor getLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BASIC);
.setLevel(BuildConfig.DEBUG ? Level.BODY: Level.BASIC);
httpLoggingInterceptor.redactHeader("Authorization");
httpLoggingInterceptor.redactHeader("Cookie");

View file

@ -71,7 +71,7 @@ public class NetworkingModule {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(message -> {
Timber.tag("OkHttp").v(message);
});
httpLoggingInterceptor.level(BuildConfig.DEBUG ? Level.BODY: HttpLoggingInterceptor.Level.BASIC);
httpLoggingInterceptor.level(BuildConfig.DEBUG ? Level.BODY: Level.BASIC);
return httpLoggingInterceptor;
}

View file

@ -1,29 +0,0 @@
package fr.free.nrw.commons.upload
import android.text.TextUtils
class Title {
private var titleText: String? = null
var isSet = false
override fun toString(): String {
if (titleText == null) {
return ""
} else {
return titleText!!
}
}
fun setTitleText(titleText: String?) {
this.titleText=titleText?.trim()
if (!TextUtils.isEmpty(titleText)) {
isSet = true
}
}
val isEmpty: Boolean
get() = titleText == null || titleText!!.isEmpty()
fun getTitleText(): String? {
return titleText
}
}

View file

@ -62,7 +62,7 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDe
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.init(position);
holder.bind(position);
}
@Override
@ -102,14 +102,18 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDe
Timber.i("descItemEditText:" + descItemEditText);
}
public void init(int position) {
public void bind(int position) {
UploadMediaDetail uploadMediaDetail = uploadMediaDetails.get(position);
Timber.d("UploadMediaDetail is " + uploadMediaDetail);
captionItemEditText.setText(uploadMediaDetail.getCaptionText());
descItemEditText.setText(uploadMediaDetail.getDescriptionText());
captionItemEditText.addTextChangedListener(new AbstractTextWatcher(
value -> eventListener.onEvent(value.length() != 0)) );
value -> {
if (position == 0) {
eventListener.onPrimaryCaptionTextChange(value.length() != 0);
}
}));
if (position == 0) {
captionItemEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, getInfoIcon(),
@ -231,7 +235,7 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDe
}
public interface EventListener {
void onEvent(Boolean data);
void onPrimaryCaptionTextChange(boolean isNotEmpty);
}
/**

View file

@ -119,7 +119,6 @@ public class UploadModel {
uploadableFile.getMimeType(context), source, imageCoordinates, place, fileCreatedDate,
createdTimestampSource);
if (place != null) {
uploadItem.title.setTitleText(place.name);
uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place));
}
if (!items.contains(uploadItem)) {
@ -207,7 +206,6 @@ public class UploadModel {
public void updateUploadItem(final int index, final UploadItem uploadItem) {
final UploadItem uploadItem1 = items.get(index);
uploadItem1.setMediaDetails(uploadItem.uploadMediaDetails);
uploadItem1.setTitle(uploadItem.title);
}
public void setSelectedDepictions(final List<String> selectedDepictions) {
@ -232,7 +230,6 @@ public class UploadModel {
private final String mimeType;
private final String source;
private ImageCoordinates gpsCoords;
private Title title;
private List<UploadMediaDetail> uploadMediaDetails;
private final Place place;
private final long createdTimestamp;
@ -246,8 +243,6 @@ public class UploadModel {
final String createdTimestampSource) {
this.originalContentUri = originalContentUri;
this.createdTimestampSource = createdTimestampSource;
title = new Title();
uploadMediaDetails = Collections.singletonList(new UploadMediaDetail());
uploadMediaDetails = new ArrayList<>(Arrays.asList(new UploadMediaDetail()));
this.place = place;
this.mediaUri = mediaUri;
@ -278,10 +273,6 @@ public class UploadModel {
return createdTimestamp;
}
public Title getTitle() {
return title;
}
public Uri getMediaUri() {
return mediaUri;
}
@ -298,11 +289,6 @@ public class UploadModel {
return place;
}
public void setTitle(final Title title) {
this.title = title;
}
public void setMediaDetails(final List<UploadMediaDetail> uploadMediaDetails) {
this.uploadMediaDetails = uploadMediaDetails;
}

View file

@ -1,15 +1,9 @@
package fr.free.nrw.commons.upload.categories;
import static fr.free.nrw.commons.di.CommonsApplicationModule.IO_THREAD;
import static fr.free.nrw.commons.di.CommonsApplicationModule.MAIN_THREAD;
import android.text.TextUtils;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.category.CategoryItem;
import fr.free.nrw.commons.repository.UploadRepository;
@ -18,11 +12,14 @@ import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import timber.log.Timber;
import static fr.free.nrw.commons.di.CommonsApplicationModule.IO_THREAD;
import static fr.free.nrw.commons.di.CommonsApplicationModule.MAIN_THREAD;
/**
* The presenter class for UploadCategoriesFragment
*/
@ -86,9 +83,10 @@ public class CategoriesPresenter implements CategoriesContract.UserActionListene
)
.filter(categoryItem -> !repository.containsYear(categoryItem.getName()))
.distinct();
if(!TextUtils.isEmpty(query)) {
distinctCategoriesObservable=distinctCategoriesObservable.sorted(repository.sortBySimilarity(query));
}
if(!TextUtils.isEmpty(query)) {
distinctCategoriesObservable=distinctCategoriesObservable.sorted(repository.sortBySimilarity(query));
}
Disposable searchCategoriesDisposable = distinctCategoriesObservable
.observeOn(mainThreadScheduler)
.subscribe(
@ -114,8 +112,9 @@ public class CategoriesPresenter implements CategoriesContract.UserActionListene
private List<String> getImageTitleList() {
List<String> titleList = new ArrayList<>();
for (UploadItem item : repository.getUploads()) {
if (item.getTitle().isSet()) {
titleList.add(item.getTitle().toString());
final String captionText = item.getUploadMediaDetails().get(0).getCaptionText();
if (!TextUtils.isEmpty(captionText)) {
titleList.add(captionText);
}
}
return titleList;

View file

@ -3,15 +3,10 @@ package fr.free.nrw.commons.upload.mediaDetails;
import static fr.free.nrw.commons.utils.ImageUtils.getErrorMessageForResult;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -24,7 +19,6 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.github.chrisbanes.photoview.PhotoView;
import com.jakewharton.rxbinding2.widget.RxTextView;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.filepicker.UploadableFile;
@ -34,7 +28,6 @@ import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.settings.Prefs;
import fr.free.nrw.commons.upload.ImageCoordinates;
import fr.free.nrw.commons.upload.SimilarImageDialogFragment;
import fr.free.nrw.commons.upload.Title;
import fr.free.nrw.commons.upload.UploadBaseFragment;
import fr.free.nrw.commons.upload.UploadMediaDetail;
import fr.free.nrw.commons.upload.UploadMediaDetailAdapter;
@ -43,7 +36,6 @@ import fr.free.nrw.commons.upload.UploadModel.UploadItem;
import fr.free.nrw.commons.utils.DialogUtil;
import fr.free.nrw.commons.utils.ImageUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.disposables.Disposable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -66,8 +58,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
AppCompatImageButton ibExpandCollapse;
@BindView(R.id.ll_container_media_detail)
LinearLayout llContainerMediaDetail;
@BindView(R.id.et_title)
EditText etTitle;
@BindView(R.id.rv_descriptions)
RecyclerView rvDescriptions;
@BindView(R.id.backgroundImage)
@ -94,7 +84,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
private String source;
private Place place;
private Title title;
private boolean isExpanded = true;
private UploadMediaDetailFragmentCallback callback;
@ -131,24 +120,8 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
private void init() {
tvTitle.setText(getString(R.string.step_count, callback.getIndexInViewFlipper(this) + 1,
callback.getTotalNumberOfSteps()));
title = new Title();
initRecyclerView();
initPresenter();
Disposable disposable = RxTextView.textChanges(etTitle)
.subscribe(text -> {
if (!TextUtils.isEmpty(text)) {
btnNext.setEnabled(true);
btnNext.setClickable(true);
btnNext.setAlpha(1.0f);
title.setTitleText(text.toString());
uploadItem.setTitle(title);
} else {
btnNext.setAlpha(0.5f);
btnNext.setEnabled(false);
btnNext.setClickable(false);
}
});
compositeDisposable.add(disposable);
presenter.receiveImage(uploadableFile, source, place);
if (callback.getIndexInViewFlipper(this) == 0) {
@ -168,36 +141,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
attachImageViewScaleChangeListener();
addEtTitleTouchListener();
}
/**
* Handles the drawable click listener for Edit Text
*/
private void addEtTitleTouchListener() {
etTitle.setOnTouchListener((v, event) -> {
//2 is for drawable right
float twelveDpInPixels = convertDpToPixel(12, getContext());
if (event.getAction() == MotionEvent.ACTION_UP && etTitle.getCompoundDrawables() != null
&& etTitle.getCompoundDrawables().length > 2 && etTitle
.getCompoundDrawables()[2].getBounds()
.contains((int) (etTitle.getWidth() - (event.getX() + twelveDpInPixels)),
(int) (event.getY() - twelveDpInPixels))) {
showInfoAlert(R.string.media_detail_title, R.string.title_info);
return true;
}
return false;
});
}
/**
* converts dp to pixel
* @param dp
* @param context
* @return
*/
private float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
/**
@ -224,7 +167,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
private void initRecyclerView() {
uploadMediaDetailAdapter = new UploadMediaDetailAdapter(defaultKvStore.getString(Prefs.KEY_LANGUAGE_VALUE, ""));
uploadMediaDetailAdapter.setCallback(this::showInfoAlert);
uploadMediaDetailAdapter.setEventListener(this::onEvent);
uploadMediaDetailAdapter.setEventListener(this);
rvDescriptions.setLayoutManager(new LinearLayoutManager(getContext()));
rvDescriptions.setAdapter(uploadMediaDetailAdapter);
}
@ -301,8 +244,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
getString(R.string.upload_nearby_place_found_description),
place.getName()),
() -> {
etTitle.setText(place.getName());
descriptions = new ArrayList<>(Arrays.asList(new UploadMediaDetail()));
descriptions = new ArrayList<>(Arrays.asList(new UploadMediaDetail(place)));
setDescriptionsInAdapter(descriptions);
},
() -> {
@ -368,8 +310,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
}
@Override
public void setTitleAndDescription(String title, List<UploadMediaDetail> uploadMediaDetails) {
etTitle.setText(title);
public void setCaptionsAndDescriptions(List<UploadMediaDetail> uploadMediaDetails) {
setDescriptionsInAdapter(uploadMediaDetails);
}
@ -405,10 +346,10 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
}
@Override
public void onEvent(Boolean data) {
btnNext.setEnabled(data);
btnNext.setClickable(data);
btnNext.setAlpha(data ? 1.0f: 0.5f);
public void onPrimaryCaptionTextChange(boolean isNotEmpty) {
btnNext.setEnabled(isNotEmpty);
btnNext.setClickable(isNotEmpty);
btnNext.setAlpha(isNotEmpty ? 1.0f: 0.5f);
}

View file

@ -36,7 +36,7 @@ public interface UploadMediaDetailsContract {
void showMapWithImageCoordinates(boolean shouldShow);
void setTitleAndDescription(String title, List<UploadMediaDetail> uploadMediaDetails);
void setCaptionsAndDescriptions(List<UploadMediaDetail> uploadMediaDetails);
}
interface UserActionListener extends BasePresenter<View> {

View file

@ -151,7 +151,7 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
public void fetchPreviousTitleAndDescription(int indexInViewFlipper) {
UploadItem previousUploadItem = repository.getPreviousUploadItem(indexInViewFlipper);
if (null != previousUploadItem) {
view.setTitleAndDescription(previousUploadItem.getTitle().getTitleText(), previousUploadItem.getUploadMediaDetails());
view.setCaptionsAndDescriptions(previousUploadItem.getUploadMediaDetails());
} else {
view.showMessage(R.string.previous_image_title_description_not_found, R.color.color_error);
}

View file

@ -82,22 +82,6 @@
android:layout_marginTop="@dimen/standard_gap"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_container_title"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/share_title_hint"
android:imeOptions="actionNext"
android:drawableEnd="@drawable/mapbox_info_icon_default"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<fr.free.nrw.commons.widget.HeightLimitedRecyclerView
android:id="@+id/rv_descriptions"
android:layout_width="match_parent"
@ -137,8 +121,7 @@
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:enabled="false"
android:clickable="false"
android:alpha="0.5"
android:alpha=".5"
android:text="@string/next"
android:textColor="@android:color/white" />

View file

@ -1,6 +1,5 @@
package fr.free.nrw.commons.upload
import androidx.recyclerview.widget.RecyclerView
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.filepicker.UploadableFile
@ -14,11 +13,12 @@ import io.reactivex.Single
import io.reactivex.schedulers.TestScheduler
import org.junit.Before
import org.junit.Test
import org.mockito.*
import org.mockito.ArgumentMatchers
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.*
@ -43,9 +43,6 @@ class UploadMediaPresenterTest {
@Mock
private lateinit var uploadItem: UploadModel.UploadItem
@Mock
private lateinit var title: Title
@Mock
private lateinit var uploadMediaDetails: List<UploadMediaDetail>
@ -171,11 +168,9 @@ class UploadMediaPresenterTest {
whenever(repository.getPreviousUploadItem(ArgumentMatchers.anyInt()))
.thenReturn(uploadItem)
whenever(uploadItem.uploadMediaDetails).thenReturn(uploadMediaDetails)
whenever(uploadItem.title).thenReturn(title)
whenever(title.getTitleText()).thenReturn(ArgumentMatchers.anyString())
uploadMediaPresenter.fetchPreviousTitleAndDescription(0)
verify(view).setTitleAndDescription(ArgumentMatchers.anyString(), ArgumentMatchers.any())
verify(view).setCaptionsAndDescriptions(ArgumentMatchers.any())
}
/**