Skip to content

Fixes #2810 Option to Remove a new language description while uploading #4206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ImageView;
import android.widget.Spinner;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.utils.AbstractTextWatcher;
Expand All @@ -21,195 +22,212 @@
import java.util.List;
import timber.log.Timber;

public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDetailAdapter.ViewHolder> {
public class UploadMediaDetailAdapter extends
RecyclerView.Adapter<UploadMediaDetailAdapter.ViewHolder> {

private List<UploadMediaDetail> uploadMediaDetails;
private Callback callback;
private EventListener eventListener;
private List<UploadMediaDetail> uploadMediaDetails;
private Callback callback;
private EventListener eventListener;

private HashMap<AdapterView, String> selectedLanguages;
private final String savedLanguageValue;
private HashMap<AdapterView, String> selectedLanguages;
private final String savedLanguageValue;

public UploadMediaDetailAdapter(String savedLanguageValue) {
uploadMediaDetails = new ArrayList<>();
selectedLanguages = new HashMap<>();
this.savedLanguageValue = savedLanguageValue;
}
public UploadMediaDetailAdapter(String savedLanguageValue) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines shouldn't be edited for this PR. Kindly please revert them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your review. I auto indent with android studio and that the result. Should i modify anyway ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please :/ Otherwise it wont be similar with other files.

uploadMediaDetails = new ArrayList<>();
selectedLanguages = new HashMap<>();
this.savedLanguageValue = savedLanguageValue;
}

public void setCallback(Callback callback) {
this.callback = callback;
}
public void setCallback(Callback callback) {
this.callback = callback;
}

public void setEventListener(EventListener eventListener) {
this.eventListener = eventListener;
}
public void setEventListener(EventListener eventListener) {
this.eventListener = eventListener;
}

public void setItems(List<UploadMediaDetail> uploadMediaDetails) {
this.uploadMediaDetails = uploadMediaDetails;
selectedLanguages = new HashMap<>();
notifyDataSetChanged();
}
public void setItems(List<UploadMediaDetail> uploadMediaDetails) {
this.uploadMediaDetails = uploadMediaDetails;
selectedLanguages = new HashMap<>();
notifyDataSetChanged();
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_item_description, parent, false));
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_item_description, parent, false));
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(position);
}

@Override
public int getItemCount() {
return uploadMediaDetails.size();
}
@Override
public int getItemCount() {
return uploadMediaDetails.size();
}

public void addDescription(UploadMediaDetail uploadMediaDetail) {
this.uploadMediaDetails.add(uploadMediaDetail);
notifyItemInserted(uploadMediaDetails.size());
}

public class ViewHolder extends RecyclerView.ViewHolder {
public void addDescription(final UploadMediaDetail uploadMediaDetail) {
this.uploadMediaDetails.add(uploadMediaDetail);
notifyItemInserted(uploadMediaDetails.size());
}

@Nullable
@BindView(R.id.spinner_description_languages)
AppCompatSpinner spinnerDescriptionLanguages;
private void removeDescription(final UploadMediaDetail uploadMediaDetail, final int pos) {
this.uploadMediaDetails.remove(uploadMediaDetail);
notifyItemRemoved(pos);
}

@BindView(R.id.description_item_edit_text)
AppCompatEditText descItemEditText;
public class ViewHolder extends RecyclerView.ViewHolder {

@BindView(R.id.description_item_edit_text_input_layout)
TextInputLayout descInputLayout;
@Nullable
@BindView(R.id.spinner_description_languages)
Spinner spinnerDescriptionLanguages;

@BindView(R.id.caption_item_edit_text)
AppCompatEditText captionItemEditText;
@BindView(R.id.description_item_edit_text)
TextInputEditText descItemEditText;

@BindView(R.id.caption_item_edit_text_input_layout)
TextInputLayout captionInputLayout;
@BindView(R.id.description_item_edit_text_input_layout)
TextInputLayout descInputLayout;

public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
Timber.i("descItemEditText:" + descItemEditText);
}
@BindView(R.id.caption_item_edit_text)
TextInputEditText captionItemEditText;

public void bind(int position) {
UploadMediaDetail uploadMediaDetail = uploadMediaDetails.get(position);
Timber.d("UploadMediaDetail is " + uploadMediaDetail);
@BindView(R.id.caption_item_edit_text_input_layout)
TextInputLayout captionInputLayout;

captionItemEditText.addTextChangedListener(new AbstractTextWatcher(
value -> {
if (position == 0) {
eventListener.onPrimaryCaptionTextChange(value.length() != 0);
}
}));
captionItemEditText.setText(uploadMediaDetail.getCaptionText());
descItemEditText.setText(uploadMediaDetail.getDescriptionText());
@BindView(R.id.btn_remove)
ImageView removeButton;

if (position == 0) {
captionInputLayout.setEndIconMode(TextInputLayout.END_ICON_CUSTOM);
captionInputLayout.setEndIconDrawable(R.drawable.mapbox_info_icon_default);
captionInputLayout.setEndIconOnClickListener(v ->
callback.showAlert(R.string.media_detail_caption, R.string.caption_info));
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
Timber.i("descItemEditText:" + descItemEditText);
}

descInputLayout.setEndIconMode(TextInputLayout.END_ICON_CUSTOM);
descInputLayout.setEndIconDrawable(R.drawable.mapbox_info_icon_default);
descInputLayout.setEndIconOnClickListener(v ->
callback.showAlert(R.string.media_detail_description, R.string.description_info));
public void bind(int position) {
UploadMediaDetail uploadMediaDetail = uploadMediaDetails.get(position);
Timber.d("UploadMediaDetail is " + uploadMediaDetail);

} else {
captionInputLayout.setEndIconDrawable(null);
descInputLayout.setEndIconDrawable(null);
captionItemEditText.addTextChangedListener(new AbstractTextWatcher(
value -> {
if (position == 0) {
eventListener.onPrimaryCaptionTextChange(value.length() != 0);
}
}));
captionItemEditText.setText(uploadMediaDetail.getCaptionText());
descItemEditText.setText(uploadMediaDetail.getDescriptionText());

if (position == 0) {
removeButton.setVisibility(View.GONE);
captionInputLayout.setEndIconMode(TextInputLayout.END_ICON_CUSTOM);
captionInputLayout.setEndIconDrawable(R.drawable.mapbox_info_icon_default);
captionInputLayout.setEndIconOnClickListener(v ->
callback.showAlert(R.string.media_detail_caption, R.string.caption_info));

descInputLayout.setEndIconMode(TextInputLayout.END_ICON_CUSTOM);
descInputLayout.setEndIconDrawable(R.drawable.mapbox_info_icon_default);
descInputLayout.setEndIconOnClickListener(v ->
callback.showAlert(R.string.media_detail_description, R.string.description_info));

} else {
removeButton.setVisibility(View.VISIBLE);
captionInputLayout.setEndIconDrawable(null);
descInputLayout.setEndIconDrawable(null);
}

removeButton.setOnClickListener(v -> removeDescription(uploadMediaDetail, position));

captionItemEditText.addTextChangedListener(new AbstractTextWatcher(
captionText -> uploadMediaDetails.get(position).setCaptionText(captionText)));
initLanguageSpinner(position, uploadMediaDetail);

descItemEditText.addTextChangedListener(new AbstractTextWatcher(
descriptionText -> uploadMediaDetails.get(position).setDescriptionText(descriptionText)));
initLanguageSpinner(position, uploadMediaDetail);

//If the description was manually added by the user, it deserves focus, if not, let the user decide
if (uploadMediaDetail.isManuallyAdded()) {
captionItemEditText.requestFocus();
} else {
captionItemEditText.clearFocus();
}
}

captionItemEditText.addTextChangedListener(new AbstractTextWatcher(
captionText -> uploadMediaDetails.get(position).setCaptionText(captionText)));
initLanguageSpinner(position, uploadMediaDetail);

descItemEditText.addTextChangedListener(new AbstractTextWatcher(
descriptionText -> uploadMediaDetails.get(position).setDescriptionText(descriptionText)));
initLanguageSpinner(position, uploadMediaDetail);

//If the description was manually added by the user, it deserves focus, if not, let the user decide
if (uploadMediaDetail.isManuallyAdded()) {
captionItemEditText.requestFocus();
} else {
captionItemEditText.clearFocus();
}
/**
* Extracted out the function to init the language spinner with different system supported
* languages
*
* @param position
* @param description
*/
private void initLanguageSpinner(int position, UploadMediaDetail description) {
SpinnerLanguagesAdapter languagesAdapter = new SpinnerLanguagesAdapter(
spinnerDescriptionLanguages.getContext(),
selectedLanguages
);
spinnerDescriptionLanguages.setAdapter(languagesAdapter);

spinnerDescriptionLanguages.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position,
long l) {
description.setSelectedLanguageIndex(position);
String languageCode = ((SpinnerLanguagesAdapter) adapterView.getAdapter())
.getLanguageCode(position);
description.setLanguageCode(languageCode);
selectedLanguages.remove(adapterView);
selectedLanguages.put(adapterView, languageCode);
((SpinnerLanguagesAdapter) adapterView
.getAdapter()).setSelectedLangCode(languageCode);
spinnerDescriptionLanguages.setSelection(position);
Timber.d("Description language code is: " + languageCode);
}

/**
* Extracted out the function to init the language spinner with different system supported languages
* @param position
* @param description
*/
private void initLanguageSpinner(int position, UploadMediaDetail description) {
SpinnerLanguagesAdapter languagesAdapter = new SpinnerLanguagesAdapter(
spinnerDescriptionLanguages.getContext(),
selectedLanguages
);
spinnerDescriptionLanguages.setAdapter(languagesAdapter);

spinnerDescriptionLanguages.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position,
long l) {
description.setSelectedLanguageIndex(position);
String languageCode = ((SpinnerLanguagesAdapter) adapterView.getAdapter())
.getLanguageCode(position);
description.setLanguageCode(languageCode);
selectedLanguages.remove(adapterView);
selectedLanguages.put(adapterView, languageCode);
((SpinnerLanguagesAdapter) adapterView
.getAdapter()).setSelectedLangCode(languageCode);
spinnerDescriptionLanguages.setSelection(position);
Timber.d("Description language code is: "+languageCode);
}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});

if (description.getSelectedLanguageIndex() == -1) {
if (!TextUtils.isEmpty(savedLanguageValue)) {
// If user has chosen a default language from settings activity savedLanguageValue is not null
spinnerDescriptionLanguages.setSelection(languagesAdapter.getIndexOfLanguageCode(savedLanguageValue));
} else {
//Checking whether Language Code attribute is null or not.
if(uploadMediaDetails.get(position).getLanguageCode() != null){
//If it is not null that means it is fetching details from the previous upload (i.e. when user has pressed copy previous caption & description)
//hence providing same language code for the current upload.
spinnerDescriptionLanguages.setSelection(languagesAdapter
.getIndexOfLanguageCode(uploadMediaDetails.get(position).getLanguageCode()), true);
} else {
if (position == 0) {
int defaultLocaleIndex = languagesAdapter
.getIndexOfUserDefaultLocale(spinnerDescriptionLanguages.getContext());
spinnerDescriptionLanguages.setSelection(defaultLocaleIndex, true);
} else {
spinnerDescriptionLanguages.setSelection(0,true);
}
}
}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});

if (description.getSelectedLanguageIndex() == -1) {
if (!TextUtils.isEmpty(savedLanguageValue)) {
// If user has chosen a default language from settings activity savedLanguageValue is not null
spinnerDescriptionLanguages
.setSelection(languagesAdapter.getIndexOfLanguageCode(savedLanguageValue));
} else {
//Checking whether Language Code attribute is null or not.
if (uploadMediaDetails.get(position).getLanguageCode() != null) {
//If it is not null that means it is fetching details from the previous upload (i.e. when user has pressed copy previous caption & description)
//hence providing same language code for the current upload.
spinnerDescriptionLanguages.setSelection(languagesAdapter
.getIndexOfLanguageCode(uploadMediaDetails.get(position).getLanguageCode()), true);
} else {
if (position == 0) {
int defaultLocaleIndex = languagesAdapter
.getIndexOfUserDefaultLocale(spinnerDescriptionLanguages.getContext());
spinnerDescriptionLanguages.setSelection(defaultLocaleIndex, true);
} else {
spinnerDescriptionLanguages.setSelection(description.getSelectedLanguageIndex());
selectedLanguages.put(spinnerDescriptionLanguages, description.getLanguageCode());
spinnerDescriptionLanguages.setSelection(0, true);
}
}
}

} else {
spinnerDescriptionLanguages.setSelection(description.getSelectedLanguageIndex());
selectedLanguages.put(spinnerDescriptionLanguages, description.getLanguageCode());
}
}
}

public interface Callback {
public interface Callback {

void showAlert(int mediaDetailDescription, int descriptionInfo);
}
void showAlert(int mediaDetailDescription, int descriptionInfo);
}

public interface EventListener {
void onPrimaryCaptionTextChange(boolean isNotEmpty);
}
public interface EventListener {

void onPrimaryCaptionTextChange(boolean isNotEmpty);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public void onButtonAddDescriptionClicked() {
UploadMediaDetail uploadMediaDetail = new UploadMediaDetail();
uploadMediaDetail.setManuallyAdded(true);//This was manually added by the user
uploadMediaDetailAdapter.addDescription(uploadMediaDetail);
rvDescriptions.scrollToPosition(uploadMediaDetailAdapter.getItemCount()-1);
rvDescriptions.smoothScrollToPosition(uploadMediaDetailAdapter.getItemCount()-1);
}

@Override
Expand Down
Loading