Comment #467 #464 - fix api calls

This commit is contained in:
Thomas 2022-11-18 15:52:25 +01:00
parent d886693c75
commit b09e21a589
9 changed files with 246 additions and 106 deletions

View file

@ -28,8 +28,6 @@ import android.widget.Button;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatCheckBox;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -37,7 +35,6 @@ import androidx.lifecycle.ViewModelStoreOwner;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -45,11 +42,11 @@ import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R; import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Filter; import app.fedilab.android.client.entities.api.Filter;
import app.fedilab.android.databinding.ActivityFiltersBinding; import app.fedilab.android.databinding.ActivityFiltersBinding;
import app.fedilab.android.databinding.KeywordsLayoutBinding;
import app.fedilab.android.databinding.PopupAddFilterBinding; import app.fedilab.android.databinding.PopupAddFilterBinding;
import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.ui.drawer.FilterAdapter; import app.fedilab.android.ui.drawer.FilterAdapter;
import app.fedilab.android.ui.drawer.KeywordAdapter;
import app.fedilab.android.viewmodel.mastodon.FiltersVM; import app.fedilab.android.viewmodel.mastodon.FiltersVM;
public class FilterActivity extends BaseActivity implements FilterAdapter.Delete { public class FilterActivity extends BaseActivity implements FilterAdapter.Delete {
@ -74,6 +71,7 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
R.array.filter_expire, android.R.layout.simple_spinner_dropdown_item); R.array.filter_expire, android.R.layout.simple_spinner_dropdown_item);
popupAddFilterBinding.filterExpire.setAdapter(adapterResize); popupAddFilterBinding.filterExpire.setAdapter(adapterResize);
final int[] expire = {-1}; final int[] expire = {-1};
Filter.FilterParams filterParams = new Filter.FilterParams();
popupAddFilterBinding.filterExpire.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { popupAddFilterBinding.filterExpire.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent1, View view, int position1, long id) { public void onItemSelected(AdapterView<?> parent1, View view, int position1, long id) {
@ -107,16 +105,29 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
} }
}); });
popupAddFilterBinding.addKeyword.setOnClickListener(v -> {
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v2 -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
});
if (filter != null) { if (filter != null) {
filterParams.filter_action = filter.filter_action;
filterParams.title = filter.title;
// filterParams.expires_in = filter.expires_at;
filterParams.context = filter.context;
filterParams.id = filter.id;
if (filter.keywords != null && filter.keywords.size() > 0) {
filterParams.keywords = new ArrayList<>();
for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) {
Filter.KeywordsParams keywordsParams = new Filter.KeywordsParams();
keywordsParams._destroy = null;
keywordsParams.id = keywordsAttributes.id;
keywordsParams.keyword = keywordsAttributes.keyword;
keywordsParams.whole_word = keywordsAttributes.whole_word;
filterParams.keywords.add(keywordsParams);
}
}
popupAddFilterBinding.addTitle.setText(filter.title); popupAddFilterBinding.addTitle.setText(filter.title);
if (filter.context != null) if (filter.context != null) {
for (String val : filter.context) { for (String val : filter.context) {
switch (val) { switch (val) {
case "home": case "home":
@ -136,29 +147,25 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
break; break;
} }
} }
if (filter.keywords != null && filter.keywords.size() > 0) {
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
keywordsLayoutBinding.keywordPhrase.setText(filterKeyword.keyword);
keywordsLayoutBinding.wholeWord.setChecked(filterKeyword.whole_word);
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
}
}
if (popupAddFilterBinding.keywordsContainer.getChildCount() == 0) {
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
} }
if (filter.filter_action.equalsIgnoreCase("warn")) {
popupAddFilterBinding.actionHide.setChecked(true);
popupAddFilterBinding.actionRemove.setChecked(false);
} else { } else {
//Add at least a view popupAddFilterBinding.actionHide.setChecked(false);
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context)); popupAddFilterBinding.actionRemove.setChecked(true);
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
} }
}
KeywordAdapter keywordAdapter = new KeywordAdapter(filterParams.keywords);
popupAddFilterBinding.lvKeywords.setAdapter(keywordAdapter);
popupAddFilterBinding.lvKeywords.setLayoutManager(new LinearLayoutManager(context));
popupAddFilterBinding.addKeyword.setOnClickListener(v -> {
filterParams.keywords.add(new Filter.KeywordsParams());
keywordAdapter.notifyItemInserted(filterParams.keywords.size() - 1);
});
popupAddFilterBinding.actionRemove.setOnClickListener(v -> { popupAddFilterBinding.actionRemove.setOnClickListener(v -> {
popupAddFilterBinding.actionHide.setChecked(false); popupAddFilterBinding.actionHide.setChecked(false);
popupAddFilterBinding.actionRemove.setChecked(true); popupAddFilterBinding.actionRemove.setChecked(true);
@ -170,30 +177,17 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
AlertDialog alertDialog = dialogBuilder.setPositiveButton(R.string.validate, null) AlertDialog alertDialog = dialogBuilder.setPositiveButton(R.string.validate, null)
.setNegativeButton(R.string.cancel, null).create(); .setNegativeButton(R.string.cancel, null).create();
alertDialog.setOnShowListener(dialogInterface -> { alertDialog.setOnShowListener(dialogInterface -> {
Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(view -> { button.setOnClickListener(view -> {
int keywordsItem = popupAddFilterBinding.keywordsContainer.getChildCount();
List<Filter.KeywordsAttributes> keywordsAttributes = null;
boolean canBeSent = true; boolean canBeSent = true;
for (int i = 0; i < filterParams.keywords.size(); i++) {
for (int i = 0; i < keywordsItem; i++) { if (filterParams.keywords.get(i).keyword.trim().isEmpty() && !filterParams.keywords.get(i)._destroy) {
View itemView = popupAddFilterBinding.keywordsContainer.getChildAt(i);
AppCompatEditText keyword = itemView.findViewById(R.id.keyword_phrase);
AppCompatCheckBox whole_word = itemView.findViewById(R.id.whole_word);
keywordsAttributes = new ArrayList<>();
if (keyword != null && whole_word != null) {
Filter.KeywordsAttributes keywordsAttr = new Filter.KeywordsAttributes();
keywordsAttr.keyword = keyword.getText().toString();
keywordsAttr.whole_word = whole_word.isChecked();
if (keywordsAttr.keyword.trim().isEmpty()) {
keyword.setError(context.getString(R.string.cannot_be_empty));
canBeSent = false; canBeSent = false;
} }
keywordsAttributes.add(keywordsAttr);
}
} }
if (popupAddFilterBinding.addTitle.getText().toString().trim().isEmpty()) { if (popupAddFilterBinding.addTitle.getText().toString().trim().isEmpty()) {
popupAddFilterBinding.addTitle.setError(context.getString(R.string.cannot_be_empty)); popupAddFilterBinding.addTitle.setError(context.getString(R.string.cannot_be_empty));
@ -204,33 +198,29 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
canBeSent = false; canBeSent = false;
} }
if (canBeSent) { if (canBeSent) {
Filter filterSent = new Filter(); filterParams.context = new ArrayList<>();
ArrayList<String> contextFilter = new ArrayList<>();
if (popupAddFilterBinding.contextHome.isChecked()) if (popupAddFilterBinding.contextHome.isChecked())
contextFilter.add("home"); filterParams.context.add("home");
if (popupAddFilterBinding.contextPublic.isChecked()) if (popupAddFilterBinding.contextPublic.isChecked())
contextFilter.add("public"); filterParams.context.add("public");
if (popupAddFilterBinding.contextNotification.isChecked()) if (popupAddFilterBinding.contextNotification.isChecked())
contextFilter.add("notifications"); filterParams.context.add("notifications");
if (popupAddFilterBinding.contextConversation.isChecked()) if (popupAddFilterBinding.contextConversation.isChecked())
contextFilter.add("thread"); filterParams.context.add("thread");
if (popupAddFilterBinding.contextProfiles.isChecked()) if (popupAddFilterBinding.contextProfiles.isChecked())
contextFilter.add("account"); filterParams.context.add("account");
filterSent.context = contextFilter;
if (expire[0] != -1) { if (expire[0] != -1) {
Calendar calendar = Calendar.getInstance(); filterParams.expires_in = (long) expire[0];
calendar.add(Calendar.SECOND, expire[0]);
filterSent.expires_at = calendar.getTime();
} else { } else {
filterSent.expires_at = null; filterParams.expires_in = null;
} }
filterSent.title = popupAddFilterBinding.addTitle.getText().toString().trim(); filterParams.title = popupAddFilterBinding.addTitle.getText().toString().trim();
filterSent.filter_action = popupAddFilterBinding.actionHide.isChecked() ? "hide" : "warn"; filterParams.filter_action = popupAddFilterBinding.actionRemove.isChecked() ? "hide" : "warn";
if (filter != null) { if (filterParams.id != null) {
filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filter.id, filterSent.title, filterSent.expires_at, filterSent.context, filterSent.filter_action, keywordsAttributes) filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
.observe((LifecycleOwner) context, listener::callback); .observe((LifecycleOwner) context, listener::callback);
} else { } else {
filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterSent.title, filterSent.expires_at, filterSent.context, filterSent.filter_action, keywordsAttributes) filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
.observe((LifecycleOwner) context, listener::callback); .observe((LifecycleOwner) context, listener::callback);
} }
alertDialog.dismiss(); alertDialog.dismiss();

View file

@ -15,16 +15,17 @@ package app.fedilab.android.client.endpoints;
* see <http://www.gnu.org/licenses>. */ * see <http://www.gnu.org/licenses>. */
import java.util.Date;
import java.util.List; import java.util.List;
import app.fedilab.android.client.entities.api.Filter; import app.fedilab.android.client.entities.api.Filter;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE; import retrofit2.http.DELETE;
import retrofit2.http.Field; import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded; import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET; import retrofit2.http.GET;
import retrofit2.http.Header; import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST; import retrofit2.http.POST;
import retrofit2.http.PUT; import retrofit2.http.PUT;
import retrofit2.http.Path; import retrofit2.http.Path;
@ -50,23 +51,28 @@ public interface MastodonFiltersService {
Call<Filter> addFilter( Call<Filter> addFilter(
@Header("Authorization") String token, @Header("Authorization") String token,
@Field("title") String title, @Field("title") String title,
@Field("expires_at") Date expires_at, @Field("expires_in") Long expires_in,
@Field("filter_action") String filter_action, @Field("filter_action") String filter_action,
@Field("context[]") List<String> context, @Field("context[]") List<String> context,
@Field("keywords_attributes[]") List<Filter.KeywordsAttributes> keywordsAttributes @Field("keywords_attributes[]") List<Filter.KeywordsParams> keywordsAttributes
); );
//Edit a filter //Edit a filter
@FormUrlEncoded @Headers({"Accept: application/json"})
@PUT("filters/{id}") @PUT("filters/{id}")
Call<Filter> editFilter( Call<Filter> editFilter(
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("id") String id, @Path("id") String id,
@Body Filter.FilterParams filter
/*@Path("id") String id,
@Field("title") String title, @Field("title") String title,
@Field("expires_at") Date expires_at, @Field("expires_in") Date expires_in,
@Field("filter_action") String filter_action, @Field("filter_action") String filter_action,
@Field("context[]") List<String> context, @Field("context[]") List<String> context,
@Field("keywords_attributes[]") List<Filter.KeywordsAttributes> keywordsAttributes @Field("keywords_attributes[]") List<Filter.KeywordsAttributes> keywords
@Field("keywords_attributes[][id]") List<String> keywordId,
@Field("keywords_attributes[][keyword]") List<String> keywords,
@Field("keywords_attributes[][whole_word]") List<Boolean> wholeWords*/
); );
//Remove a filter //Remove a filter
@ -77,7 +83,7 @@ public interface MastodonFiltersService {
); );
//Get a filter with its id //Get a keywords for a filter
@GET("filters/{id}/keywords") @GET("filters/{id}/keywords")
Call<List<Filter.KeywordsAttributes>> getKeywordFilter( Call<List<Filter.KeywordsAttributes>> getKeywordFilter(
@Header("Authorization") String token, @Header("Authorization") String token,
@ -90,21 +96,20 @@ public interface MastodonFiltersService {
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("filter_id") String filter_id, @Path("filter_id") String filter_id,
@Path("id") String id, @Path("id") String id,
@Field("keyword") Filter.Keyword keyword @Field("keyword") Filter.KeywordsAttributes keyword
); );
//Edit a keyword for a filter //Edit a keyword for a filter
@FormUrlEncoded @FormUrlEncoded
@PUT("filters/{filter_id}/keywords/{id}") @PUT("filter_keywords/{id}")
Call<Filter.KeywordsAttributes> editKeywordFilter( Call<Filter.KeywordsAttributes> editKeywordFilter(
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("filter_id") String filter_id,
@Path("id") String id, @Path("id") String id,
@Field("keyword") Filter.Keyword keyword @Field("keyword") Filter.KeywordsAttributes keyword
); );
//Remove a keyword for a filter //Remove a keyword for a filter
@DELETE("filters/keywords/{id}") @DELETE("filter_keywords/{id}")
Call<Void> removeKeywordFilter( Call<Void> removeKeywordFilter(
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("id") String id @Path("id") String id

View file

@ -1,5 +1,6 @@
package app.fedilab.android.client.entities.api; package app.fedilab.android.client.entities.api;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.io.Serializable; import java.io.Serializable;
@ -33,15 +34,26 @@ public class Filter implements Serializable {
@SerializedName("filter_action") @SerializedName("filter_action")
public String filter_action; public String filter_action;
@SerializedName("keywords") @SerializedName("keywords")
public List<FilterKeyword> keywords; public List<KeywordsAttributes> keywords;
public static class FilterKeyword implements Serializable { public static String getValueOf(FilterParams filterParams) {
Gson gson = new Gson();
try {
return gson.toJson(filterParams);
} catch (Exception e) {
return null;
}
}
public static class KeywordsAttributes implements Serializable {
@SerializedName("id") @SerializedName("id")
public String id; public String id;
@SerializedName("keyword") @SerializedName("keyword")
public String keyword; public String keyword;
@SerializedName("whole_word") @SerializedName("whole_word")
public boolean whole_word; public Boolean whole_word;
@SerializedName("_destroy")
public Boolean _destroy;
} }
public static class FilterResult implements Serializable { public static class FilterResult implements Serializable {
@ -53,27 +65,35 @@ public class Filter implements Serializable {
public List<String> context; public List<String> context;
@SerializedName("whole_word") @SerializedName("whole_word")
public boolean whole_word; public boolean whole_word;
@SerializedName("expires_at") @SerializedName("expires_in")
public Date expires_at; public Date expires_at;
@SerializedName("filter_action") @SerializedName("filter_action")
public String filter_action; public String filter_action;
} }
public static class Keyword implements Serializable { public static class FilterParams implements Serializable {
@SerializedName("keyword") @SerializedName("id")
public String keyword; public String id;
@SerializedName("whole_word") @SerializedName("title")
public boolean whole_word; public String title;
@SerializedName("context")
public List<String> context;
@SerializedName("expires_in")
public Long expires_in;
@SerializedName("filter_action")
public String filter_action;
@SerializedName("keywords_attributes")
public List<KeywordsParams> keywords;
} }
public static class KeywordsAttributes implements Serializable { public static class KeywordsParams implements Serializable {
@SerializedName("id") @SerializedName("id")
public String id; public String id;
@SerializedName("keyword") @SerializedName("keyword")
public String keyword; public String keyword;
@SerializedName("whole_word") @SerializedName("whole_word")
public boolean whole_word; public Boolean whole_word;
@SerializedName("_destroy") @SerializedName("_destroy")
public boolean _destroy; public Boolean _destroy;
} }
} }

View file

@ -92,8 +92,8 @@ public class Status implements Serializable, Cloneable {
public Card card; public Card card;
@SerializedName("poll") @SerializedName("poll")
public Poll poll; public Poll poll;
@SerializedName("filtered") /* @SerializedName("filtered")
public Filter.FilterResult filtered; public Filter.FilterResult filtered;*/
@SerializedName("pleroma") @SerializedName("pleroma")
public Pleroma pleroma; public Pleroma pleroma;
@SerializedName("cached") @SerializedName("cached")

View file

@ -112,7 +112,7 @@ public class TimelineHelper {
if (!filter.context.contains("public")) continue; if (!filter.context.contains("public")) continue;
} }
if (filter.keywords != null && filter.keywords.size() > 0) { if (filter.keywords != null && filter.keywords.size() > 0) {
for (Filter.FilterKeyword filterKeyword : filter.keywords) { for (Filter.KeywordsAttributes filterKeyword : filter.keywords) {
if (filterKeyword.whole_word) { if (filterKeyword.whole_word) {
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE); Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
for (Status status : statuses) { for (Status status : statuses) {
@ -206,7 +206,7 @@ public class TimelineHelper {
if (!filter.context.contains("notification")) continue; if (!filter.context.contains("notification")) continue;
if (filter.keywords != null && filter.keywords.size() > 0) { if (filter.keywords != null && filter.keywords.size() > 0) {
for (Filter.FilterKeyword filterKeyword : filter.keywords) { for (Filter.KeywordsAttributes filterKeyword : filter.keywords) {
if (filterKeyword.whole_word) { if (filterKeyword.whole_word) {
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE); Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
for (Notification notification : notifications) { for (Notification notification : notifications) {

View file

@ -0,0 +1,119 @@
package app.fedilab.android.ui.drawer;
/* Copyright 2022 Thomas Schneider
*
* This file is a part of Fedilab
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Filter;
import app.fedilab.android.databinding.DrawerKeywordBinding;
public class KeywordAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<Filter.KeywordsParams> keywordsParamsList;
private Context context;
public KeywordAdapter(List<Filter.KeywordsParams> keywordsParamsList) {
this.keywordsParamsList = keywordsParamsList;
}
public int getCount() {
return keywordsParamsList.size();
}
public Filter.KeywordsParams getItem(int position) {
return keywordsParamsList.get(position);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
DrawerKeywordBinding itemBinding = DrawerKeywordBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new KeywordViewHolder(itemBinding);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
Filter.KeywordsParams keywordsParams = keywordsParamsList.get(position);
KeywordViewHolder holder = (KeywordViewHolder) viewHolder;
holder.binding.keywordPhrase.setText(keywordsParams.keyword);
holder.binding.keywordPhrase.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
keywordsParams.keyword = charSequence.toString().trim();
if (charSequence.toString().length() == 0) {
holder.binding.wholeWord.setError(context.getString(R.string.cannot_be_empty));
} else {
holder.binding.wholeWord.setError(null);
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
if (keywordsParams._destroy != null) {
holder.binding.mainContainer.setVisibility(View.GONE);
} else {
holder.binding.mainContainer.setVisibility(View.VISIBLE);
}
holder.binding.wholeWord.setOnCheckedChangeListener((compoundButton, checked) -> keywordsParams.whole_word = checked);
holder.binding.wholeWord.setChecked(keywordsParams.whole_word != null && keywordsParams.whole_word);
holder.binding.deleteKeyword.setOnClickListener(v -> {
//The keyword exists
if (keywordsParams.id != null) {
keywordsParams._destroy = true;
notifyItemChanged(position);
} else { //It is currently only the app
if (keywordsParamsList.size() > position) {
keywordsParamsList.remove(position);
notifyItemRemoved(position);
}
}
});
}
@Override
public int getItemCount() {
return keywordsParamsList.size();
}
public static class KeywordViewHolder extends RecyclerView.ViewHolder {
DrawerKeywordBinding binding;
KeywordViewHolder(DrawerKeywordBinding itemView) {
super(itemView.getRoot());
binding = itemView;
}
}
}

View file

@ -18,14 +18,12 @@ package app.fedilab.android.viewmodel.mastodon;
import android.app.Application; import android.app.Application;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -60,7 +58,8 @@ public class FiltersVM extends AndroidViewModel {
private MastodonFiltersService initV2(String instance) { private MastodonFiltersService initV2(String instance) {
Retrofit retrofit = new Retrofit.Builder() Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://" + instance + "/api/v2/") .baseUrl("https://" + instance + "/api/v2/")
.addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder())) // .addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient) .client(okHttpClient)
.build(); .build();
return retrofit.create(MastodonFiltersService.class); return retrofit.create(MastodonFiltersService.class);
@ -132,13 +131,12 @@ public class FiltersVM extends AndroidViewModel {
* *
* @return {@link LiveData} containing a {@link Filter} * @return {@link LiveData} containing a {@link Filter}
*/ */
public LiveData<Filter> addFilter(@NonNull String instance, String token, public LiveData<Filter> addFilter(@NonNull String instance, String token, @NonNull Filter.FilterParams filterParams) {
@NonNull String title, Date expires_at, @NonNull List<String> filterContext, String filter_action, List<Filter.KeywordsAttributes> keywordsAttributes) {
filterMutableLiveData = new MutableLiveData<>(); filterMutableLiveData = new MutableLiveData<>();
MastodonFiltersService mastodonFiltersService = initV2(instance); MastodonFiltersService mastodonFiltersService = initV2(instance);
new Thread(() -> { new Thread(() -> {
Filter filter = null; Filter filter = null;
Call<Filter> addFilterCall = mastodonFiltersService.addFilter(token, title, expires_at, filter_action, filterContext, keywordsAttributes); Call<Filter> addFilterCall = mastodonFiltersService.addFilter(token, filterParams.title, filterParams.expires_in, filterParams.filter_action, filterParams.context, filterParams.keywords);
if (addFilterCall != null) { if (addFilterCall != null) {
try { try {
Response<Filter> addFiltersResponse = addFilterCall.execute(); Response<Filter> addFiltersResponse = addFilterCall.execute();
@ -162,14 +160,22 @@ public class FiltersVM extends AndroidViewModel {
* *
* @return {@link LiveData} containing a {@link Filter} * @return {@link LiveData} containing a {@link Filter}
*/ */
public LiveData<Filter> editFilter(@NonNull String instance, String token, @NonNull String id, @NonNull String title, Date expires_at, @NonNull List<String> filterContext, String filter_action, List<Filter.KeywordsAttributes> keywordsAttributes) { public LiveData<Filter> editFilter(@NonNull String instance, String token, @NonNull Filter.FilterParams filterParams) {
filterMutableLiveData = new MutableLiveData<>(); filterMutableLiveData = new MutableLiveData<>();
MastodonFiltersService mastodonFiltersService = initV2(instance); MastodonFiltersService mastodonFiltersService = initV2(instance);
new Thread(() -> { new Thread(() -> {
Filter filter = null; Filter filter = null;
Call<Filter> editFilterCall = mastodonFiltersService.editFilter(token, id, title, expires_at, filter_action, filterContext, keywordsAttributes); /* List<String> keywordsId = new ArrayList<>();
List<String> keywords = new ArrayList<>();
List<Boolean> whole_words = new ArrayList<>();
for(Filter.KeywordsAttributes attributes: keywordsAttributes) {
keywordsId.add(attributes.id);
keywords.add(attributes.keyword);
whole_words.add(attributes.whole_word);
}*/
Call<Filter> editFilterCall = mastodonFiltersService.editFilter(token, filterParams.id, filterParams);
if (editFilterCall != null) { if (editFilterCall != null) {
Log.v(Helper.TAG, "request: " + editFilterCall.request());
try { try {
Response<Filter> editFiltersResponse = editFilterCall.execute(); Response<Filter> editFiltersResponse = editFilterCall.execute();
if (editFiltersResponse.isSuccessful()) { if (editFiltersResponse.isSuccessful()) {

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" <androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"

View file

@ -218,11 +218,10 @@
android:hint="@string/context_whole_word" /> android:hint="@string/context_whole_word" />
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat <androidx.recyclerview.widget.RecyclerView
android:id="@+id/keywords_container" android:id="@+id/lv_keywords"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:orientation="vertical" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/add_keyword" android:id="@+id/add_keyword"