diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java index ac513816..538368bf 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java @@ -330,10 +330,10 @@ public interface Connection { /** * - * @param name name of the hashtag + * @param id of the featured hashtag * @return updated hashtag information */ - Hashtag unfeatureHashtag(String name) throws ConnectionException; + Hashtag unfeatureHashtag(long id) throws ConnectionException; /** * show current user's home timeline diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java index cf8ec5ed..ee62e1b0 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java @@ -541,13 +541,9 @@ public class Mastodon implements Connection { @Override - public Hashtag unfeatureHashtag(String name) throws ConnectionException { + public Hashtag unfeatureHashtag(long id) throws ConnectionException { try { - if (name.startsWith("#")) - name = name.substring(1); - List params = new ArrayList<>(); - params.add("name=" + StringUtils.encode(name)); - return createTag(delete(ENDPOINT_HASHTAG_FEATURE, params)); + return createTag(delete(ENDPOINT_HASHTAG_FEATURE + "/" + id, new ArrayList<>())); } catch (IOException e) { throw new MastodonException(e); } @@ -1466,7 +1462,9 @@ public class Mastodon implements Connection { long[] cursors = getCursors(response); Trends result = new Trends(cursors[0], cursors[1]); for (int i = 0; i < jsonArray.length(); i++) { - result.add(new MastodonHashtag(jsonArray.getJSONObject(i))); + MastodonHashtag item = new MastodonHashtag(jsonArray.getJSONObject(i)); + item.setRank(i + 1); + result.add(item); } Collections.sort(result); return result; diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonHashtag.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonHashtag.java index 3eded8e9..5213e6e0 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonHashtag.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonHashtag.java @@ -5,8 +5,8 @@ import androidx.annotation.Nullable; import org.json.JSONArray; import org.json.JSONObject; -import org.nuclearfog.twidda.model.Location; import org.nuclearfog.twidda.model.Hashtag; +import org.nuclearfog.twidda.model.Location; /** * Hashtag implementation used by Mastodon API @@ -20,12 +20,15 @@ public class MastodonHashtag implements Hashtag { private int popularity; private String name; private boolean following; + private long id; + private int rank; /** * @param json trend json object */ public MastodonHashtag(JSONObject json) { JSONArray history = json.optJSONArray("history"); + String idStr = json.optString("id", "0"); name = '#' + json.optString("name", ""); following = json.optBoolean("following", false); if (history != null && history.length() > 0) { @@ -36,6 +39,17 @@ public class MastodonHashtag implements Hashtag { } else { popularity = json.optInt("statuses_count", 0); } + try { + id = Long.parseLong(idStr); + } catch (NumberFormatException exception) { + // proceed without ID + } + } + + + @Override + public long getId() { + return id; } @@ -53,7 +67,7 @@ public class MastodonHashtag implements Hashtag { @Override public int getRank() { - return -1; + return rank; } @@ -68,6 +82,13 @@ public class MastodonHashtag implements Hashtag { return following; } + /** + * + */ + public void setRank(int rank) { + this.rank = rank; + } + @Override public boolean equals(@Nullable Object obj) { diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/async/HashtagAction.java b/app/src/main/java/org/nuclearfog/twidda/backend/async/HashtagAction.java index 1eec2b6b..1ab92389 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/async/HashtagAction.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/async/HashtagAction.java @@ -15,7 +15,7 @@ import org.nuclearfog.twidda.model.Hashtag; * * @author nuclearfog */ -public class HashtagAction extends AsyncExecutor { +public class HashtagAction extends AsyncExecutor { private Connection connection; @@ -28,41 +28,41 @@ public class HashtagAction extends AsyncExecutor { +public class HashtagLoader extends AsyncExecutor { private Connection connection; private AppDatabase db; @@ -26,52 +26,52 @@ public class TrendLoader extends AsyncExecutor implements OnHolderClickListener { +public class HashtagAdapter extends Adapter implements OnHolderClickListener { /** * "index" used to replace the whole list with new items @@ -31,15 +31,16 @@ public class TrendAdapter extends Adapter implements OnHolderClickLi private static final int NO_LOADING = -1; - private TrendClickListener itemClickListener; + private OnHashtagClickListener itemClickListener; private Trends items = new Trends(); private int loadingIndex = NO_LOADING; + private boolean enableDelete = false; /** * @param itemClickListener Listener for item click */ - public TrendAdapter(TrendClickListener itemClickListener) { + public HashtagAdapter(OnHashtagClickListener itemClickListener) { this.itemClickListener = itemClickListener; } @@ -62,7 +63,7 @@ public class TrendAdapter extends Adapter implements OnHolderClickLi @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if (viewType == TYPE_TREND) { - return new TrendHolder(parent, this); + return new HashtagHolder(parent, this, enableDelete); } else { return new PlaceHolder(parent, this, false); } @@ -71,8 +72,8 @@ public class TrendAdapter extends Adapter implements OnHolderClickLi @Override public void onBindViewHolder(@NonNull ViewHolder vh, int index) { - if (vh instanceof TrendHolder) { - TrendHolder holder = (TrendHolder) vh; + if (vh instanceof HashtagHolder) { + HashtagHolder holder = (HashtagHolder) vh; Hashtag hashtag = items.get(index); if (hashtag != null) { holder.setContent(hashtag, index); @@ -86,7 +87,11 @@ public class TrendAdapter extends Adapter implements OnHolderClickLi @Override public void onItemClick(int position, int type, int... extras) { - itemClickListener.onTrendClick(items.get(position)); + if (type == HASHTAG_CLICK) { + itemClickListener.onHashtagClick(items.get(position), OnHashtagClickListener.SELECT); + } else if (type == HASHTAG_REMOVE) { + itemClickListener.onHashtagClick(items.get(position), OnHashtagClickListener.REMOVE); + } } @@ -177,18 +182,32 @@ public class TrendAdapter extends Adapter implements OnHolderClickLi } /** - * Listener for trend list + * */ - public interface TrendClickListener { + public void enableDelete() { + enableDelete = true; + } + + /** + * Listener for hashtag list + */ + public interface OnHashtagClickListener { + + int SELECT = 1; + + int REMOVE = 2; /** * called when a trend item is clicked * * @param hashtag trend name + * @param action action to take {@link #SELECT,#REMOVE} */ - void onTrendClick(Hashtag hashtag); - + void onHashtagClick(Hashtag hashtag, int action); + /** + * + */ boolean onPlaceholderClick(long cursor, int index); } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/TrendHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/HashtagHolder.java similarity index 71% rename from app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/TrendHolder.java rename to app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/HashtagHolder.java index f54be2e9..b6abeaf4 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/TrendHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/HashtagHolder.java @@ -17,26 +17,28 @@ import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.StringUtils; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Hashtag; +import org.nuclearfog.twidda.ui.adapter.recyclerview.HashtagAdapter; /** * ViewHolder for a trend item * * @author nuclearfog - * @see org.nuclearfog.twidda.ui.adapter.recyclerview.TrendAdapter + * @see HashtagAdapter */ -public class TrendHolder extends ViewHolder implements OnClickListener { +public class HashtagHolder extends ViewHolder implements OnClickListener { private TextView name, rank, vol; private OnHolderClickListener listener; - public TrendHolder(ViewGroup parent, OnHolderClickListener listener) { - super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_trend, parent, false)); + public HashtagHolder(ViewGroup parent, OnHolderClickListener listener, boolean enableRemove) { + super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_hashtag, parent, false)); this.listener = listener; CardView background = (CardView) itemView; ViewGroup container = itemView.findViewById(R.id.item_trend_container); + View btnRemove = itemView.findViewById(R.id.item_trend_delete_button); rank = itemView.findViewById(R.id.item_trend_rank); name = itemView.findViewById(R.id.item_trend_name); vol = itemView.findViewById(R.id.item_trend_vol); @@ -44,16 +46,26 @@ public class TrendHolder extends ViewHolder implements OnClickListener { GlobalSettings settings = GlobalSettings.get(parent.getContext()); AppStyles.setTheme(container, Color.TRANSPARENT); background.setCardBackgroundColor(settings.getCardColor()); + if (enableRemove) { + btnRemove.setVisibility(View.VISIBLE); + } else { + btnRemove.setVisibility(View.GONE); + } itemView.setOnClickListener(this); + btnRemove.setOnClickListener(this); } @Override public void onClick(View v) { - if (v == itemView) { - int position = getLayoutPosition(); + int position = getLayoutPosition(); + if (v.getId() == R.id.item_trend_delete_button) { if (position != RecyclerView.NO_POSITION) { - listener.onItemClick(position, OnHolderClickListener.NO_TYPE); + listener.onItemClick(position, OnHolderClickListener.HASHTAG_REMOVE); + } + } else if (v == itemView) { + if (position != RecyclerView.NO_POSITION) { + listener.onItemClick(position, OnHolderClickListener.HASHTAG_CLICK); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/OnHolderClickListener.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/OnHolderClickListener.java index a35fc976..174ab0c9 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/OnHolderClickListener.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/OnHolderClickListener.java @@ -45,6 +45,10 @@ public interface OnHolderClickListener { int FILTER_REMOVE = 23; + int HASHTAG_CLICK = 24; + + int HASHTAG_REMOVE = 25; + /** * called when an item was clicked * diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/UserHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/UserHolder.java index f92f90c9..903e8d3f 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/UserHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/UserHolder.java @@ -84,7 +84,7 @@ public class UserHolder extends ViewHolder implements OnClickListener, AsyncCall profileImg = itemView.findViewById(R.id.item_user_profile); verifyIcon = itemView.findViewById(R.id.item_user_verified); lockedIcon = itemView.findViewById(R.id.item_user_private); - delete = itemView.findViewById(R.id.item_user_delete_buton); + delete = itemView.findViewById(R.id.item_user_delete_button); placeholder = new ColorDrawable(EMPTY_COLOR); AppStyles.setTheme(container, Color.TRANSPARENT); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java index e8d1ebf1..3d618c23 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java @@ -134,6 +134,16 @@ public class ConfirmDialog extends Dialog implements OnClickListener { */ public static final int CONTINUE_BROWSER = 627; + /** + * + */ + public static final int UNFOLLOW_HASHTAG = 628; + + /** + * + */ + public static final int UNFEATURE_HASHTAG = 629; + private TextView title, message, remember_label; private Button confirm, cancel; @@ -275,6 +285,14 @@ public class ConfirmDialog extends Dialog implements OnClickListener { titleRes = R.string.confirm_warning; messageRes = R.string.confirm_proxy_bypass; break; + + case UNFOLLOW_HASHTAG: + messageRes = R.string.confirm_hashtag_unfollow; + break; + + case UNFEATURE_HASHTAG: + messageRes = R.string.confirm_hashtag_unfeature; + break; } // setup title title.setVisibility(titleVis); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/HashtagFragment.java b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/HashtagFragment.java index 5f88c279..2096f727 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/HashtagFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/HashtagFragment.java @@ -3,6 +3,7 @@ package org.nuclearfog.twidda.ui.fragments; import android.content.Intent; import android.os.Bundle; import android.view.View; +import android.widget.Toast; import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultCallback; @@ -11,16 +12,21 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback; -import org.nuclearfog.twidda.backend.async.TrendLoader; -import org.nuclearfog.twidda.backend.async.TrendLoader.TrendParameter; -import org.nuclearfog.twidda.backend.async.TrendLoader.TrendResult; +import org.nuclearfog.twidda.backend.async.HashtagAction; +import org.nuclearfog.twidda.backend.async.HashtagAction.HashtagActionParam; +import org.nuclearfog.twidda.backend.async.HashtagAction.HashtagActionResult; +import org.nuclearfog.twidda.backend.async.HashtagLoader; +import org.nuclearfog.twidda.backend.async.HashtagLoader.HashtagLoaderParam; +import org.nuclearfog.twidda.backend.async.HashtagLoader.HashtagLoaderResult; import org.nuclearfog.twidda.backend.utils.ErrorUtils; import org.nuclearfog.twidda.model.Hashtag; import org.nuclearfog.twidda.model.lists.Trends; import org.nuclearfog.twidda.ui.activities.SearchActivity; -import org.nuclearfog.twidda.ui.adapter.recyclerview.TrendAdapter; -import org.nuclearfog.twidda.ui.adapter.recyclerview.TrendAdapter.TrendClickListener; +import org.nuclearfog.twidda.ui.adapter.recyclerview.HashtagAdapter; +import org.nuclearfog.twidda.ui.adapter.recyclerview.HashtagAdapter.OnHashtagClickListener; +import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog; import java.io.Serializable; @@ -29,7 +35,7 @@ import java.io.Serializable; * * @author nuclearfog */ -public class HashtagFragment extends ListFragment implements TrendClickListener, AsyncCallback, ActivityResultCallback { +public class HashtagFragment extends ListFragment implements OnHashtagClickListener, ActivityResultCallback, ConfirmDialog.OnConfirmListener { /** * setup fragment to show popular trends of an instance/location @@ -72,18 +78,26 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, private ActivityResultLauncher activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this); - private TrendLoader trendLoader; - private TrendAdapter adapter; + private AsyncCallback hashtagActionCallback = this::onHashtagActionResult; + private AsyncCallback hashtagLoaderCallback = this::onHashtagLoaderResult; + + private HashtagLoader hashtagLoader; + private HashtagAction hashtagAction; + private HashtagAdapter adapter; + private ConfirmDialog confirmDialog; private int mode = 0; private String search = ""; + private Hashtag selection; @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - adapter = new TrendAdapter(this); - trendLoader = new TrendLoader(requireContext()); + adapter = new HashtagAdapter(this); + hashtagLoader = new HashtagLoader(requireContext()); + hashtagAction = new HashtagAction(requireContext()); + confirmDialog = new ConfirmDialog(requireActivity(), this); setAdapter(adapter); Bundle args = getArguments(); @@ -91,15 +105,18 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, search = args.getString(KEY_SEARCH, ""); mode = args.getInt(KEY_MODE, 0); } + if (mode == MODE_FOLLOW || mode == MODE_FEATURE) { + adapter.enableDelete(); + } if (savedInstanceState != null) { Serializable data = savedInstanceState.getSerializable(KEY_DATA); if (data instanceof Trends) { - adapter.addItems((Trends) data, TrendAdapter.CLEAR_LIST); + adapter.addItems((Trends) data, HashtagAdapter.CLEAR_LIST); return; } } setRefresh(true); - load(TrendParameter.NO_CURSOR, TrendAdapter.CLEAR_LIST); + load(HashtagLoaderParam.NO_CURSOR, HashtagAdapter.CLEAR_LIST); } @@ -112,7 +129,7 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, @Override public void onDestroy() { - trendLoader.cancel(); + hashtagLoader.cancel(); super.onDestroy(); } @@ -120,15 +137,15 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, @Override protected void onReset() { adapter.clear(); - trendLoader = new TrendLoader(requireContext()); - load(TrendParameter.NO_CURSOR, TrendAdapter.CLEAR_LIST); + hashtagLoader = new HashtagLoader(requireContext()); + load(HashtagLoaderParam.NO_CURSOR, HashtagAdapter.CLEAR_LIST); setRefresh(true); } @Override protected void onReload() { - load(TrendParameter.NO_CURSOR, TrendAdapter.CLEAR_LIST); + load(HashtagLoaderParam.NO_CURSOR, HashtagAdapter.CLEAR_LIST); } @@ -150,24 +167,35 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, @Override - public void onTrendClick(Hashtag hashtag) { - if (!isRefreshing()) { - Intent intent = new Intent(requireContext(), SearchActivity.class); - String name = hashtag.getName(); - if (!name.startsWith("#") && !name.startsWith("\"") && !name.endsWith("\"")) { - name = "\"" + name + "\""; - intent.putExtra(SearchActivity.KEY_QUERY, name); - } else { - intent.putExtra(SearchActivity.KEY_DATA, hashtag); + public void onHashtagClick(Hashtag hashtag, int action) { + if (action == OnHashtagClickListener.SELECT) { + if (!isRefreshing()) { + Intent intent = new Intent(requireContext(), SearchActivity.class); + String name = hashtag.getName(); + if (!name.startsWith("#") && !name.startsWith("\"") && !name.endsWith("\"")) { + name = "\"" + name + "\""; + intent.putExtra(SearchActivity.KEY_QUERY, name); + } else { + intent.putExtra(SearchActivity.KEY_DATA, hashtag); + } + activityResultLauncher.launch(intent); + } + } else if (action == OnHashtagClickListener.REMOVE) { + if (!confirmDialog.isShowing()) { + selection = hashtag; + if (mode == MODE_FEATURE) { + confirmDialog.show(ConfirmDialog.UNFEATURE_HASHTAG); + } else if (mode == MODE_FOLLOW) { + confirmDialog.show(ConfirmDialog.UNFOLLOW_HASHTAG); + } } - activityResultLauncher.launch(intent); } } @Override public boolean onPlaceholderClick(long cursor, int index) { - if (trendLoader.isIdle()) { + if (hashtagLoader.isIdle()) { load(cursor, index); return true; } @@ -176,8 +204,36 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, @Override - public void onResult(@NonNull TrendResult result) { - if (result.mode == TrendResult.ERROR) { + public void onConfirm(int type, boolean remember) { + if (selection != null) { + if (type == ConfirmDialog.UNFOLLOW_HASHTAG) { + HashtagActionParam param = new HashtagActionParam(HashtagActionParam.UNFOLLOW, selection.getName(), selection.getId()); + hashtagAction.execute(param, hashtagActionCallback); + } else if (type == ConfirmDialog.UNFEATURE_HASHTAG) { + HashtagActionParam param = new HashtagActionParam(HashtagActionParam.UNFEATURE, selection.getName(), selection.getId()); + hashtagAction.execute(param, hashtagActionCallback); + } + } + } + + /** + * callback for {@link HashtagAction} + */ + private void onHashtagActionResult(@NonNull HashtagActionResult result) { + if (result.mode == HashtagActionResult.UNFEATURE) { + Toast.makeText(requireContext(), R.string.info_hashtag_unfeatured, Toast.LENGTH_SHORT).show(); + adapter.removeItem(result.hashtag); + } else if (result.mode == HashtagActionResult.UNFOLLOW) { + Toast.makeText(requireContext(), R.string.info_hashtag_unfollowed, Toast.LENGTH_SHORT).show(); + adapter.removeItem(result.hashtag); + } + } + + /** + * callback for {@link HashtagLoader} + */ + private void onHashtagLoaderResult(@NonNull HashtagLoaderResult result) { + if (result.mode == HashtagLoaderResult.ERROR) { if (getContext() != null) { ErrorUtils.showErrorMessage(getContext(), result.exception); } @@ -192,30 +248,30 @@ public class HashtagFragment extends ListFragment implements TrendClickListener, * load content into the list */ private void load(long cursor, int index) { - TrendParameter param; + HashtagLoaderParam param; switch (mode) { case MODE_POPULAR: if (adapter.isEmpty()) { - param = new TrendParameter(TrendParameter.POPULAR_OFFLINE, index, search, cursor); + param = new HashtagLoaderParam(HashtagLoaderParam.POPULAR_OFFLINE, index, search, cursor); } else { - param = new TrendParameter(TrendParameter.POPULAR_ONLINE, index, search, cursor); + param = new HashtagLoaderParam(HashtagLoaderParam.POPULAR_ONLINE, index, search, cursor); } - trendLoader.execute(param, this); + hashtagLoader.execute(param, hashtagLoaderCallback); break; case MODE_FOLLOW: - param = new TrendParameter(TrendParameter.FOLLOWING, index, search, cursor); - trendLoader.execute(param, this); + param = new HashtagLoaderParam(HashtagLoaderParam.FOLLOWING, index, search, cursor); + hashtagLoader.execute(param, hashtagLoaderCallback); break; case MODE_FEATURE: - param = new TrendParameter(TrendParameter.FEATURING, index, search, cursor); - trendLoader.execute(param, this); + param = new HashtagLoaderParam(HashtagLoaderParam.FEATURING, index, search, cursor); + hashtagLoader.execute(param, hashtagLoaderCallback); break; case MODE_SEARCH: - param = new TrendParameter(TrendParameter.SEARCH, index, search, cursor); - trendLoader.execute(param, this); + param = new HashtagLoaderParam(HashtagLoaderParam.SEARCH, index, search, cursor); + hashtagLoader.execute(param, hashtagLoaderCallback); break; } } diff --git a/app/src/main/res/layout/item_trend.xml b/app/src/main/res/layout/item_hashtag.xml similarity index 60% rename from app/src/main/res/layout/item_trend.xml rename to app/src/main/res/layout/item_hashtag.xml index 2cc9ad03..6e2f4048 100644 --- a/app/src/main/res/layout/item_trend.xml +++ b/app/src/main/res/layout/item_hashtag.xml @@ -9,16 +9,16 @@ android:id="@+id/item_trend_container" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="@dimen/trenditem_layout_padding"> + android:padding="@dimen/item_hashtag_layout_padding"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_user.xml b/app/src/main/res/layout/item_user.xml index 2e0adfd2..05686110 100644 --- a/app/src/main/res/layout/item_user.xml +++ b/app/src/main/res/layout/item_user.xml @@ -80,7 +80,7 @@ app:layout_constraintStart_toEndOf="@id/item_user_verified" app:layout_constraintTop_toTopOf="@id/item_user_profile" app:layout_constraintBottom_toTopOf="@id/item_user_screenname" - app:layout_constraintEnd_toStartOf="@id/item_user_delete_buton" /> + app:layout_constraintEnd_toStartOf="@id/item_user_delete_button" /> + app:layout_constraintEnd_toStartOf="@id/item_user_delete_button" /> + app:layout_constraintEnd_toStartOf="@id/item_user_delete_button" /> \@name stummschalten \@name blockieren Nutzer ausschließen + Hashtag hinzufügen Ergebnisse filtern domain.namen eingeben Lizenzen @@ -296,11 +297,13 @@ Dauer der Umfrage ist zu kurz! Dauer der Umfrage ist zu lang! Umfrageoption darf nicht leer sein! + Hashtags folge Hashtag entfolge Hashtag Hashtag entfolgt Domain von der Liste entfernt Hashtag gefolgt + Veröffentlichung planen bei Reposts bei Favorisierung bei beendeten Umfragen @@ -354,4 +357,6 @@ Filterbezeichnung darf nicht leer sein es muss mindestens ein Filter aktiviert sein Medienbeschreibung + Hashtag von der Liste entfernen + Hashtag entfolgen? \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 02335b7d..dedf9bdb 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -92,13 +92,15 @@ 6sp 26sp - - 5dp - 5dp - 20sp - 20sp - 14sp - 40sp + + 5dp + 5dp + 20sp + 1dp + 20sp + 20sp + 14sp + 40sp 56sp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0087279b..2c44292e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -78,6 +78,7 @@ Hashtag featured Hashtag followed Hashtag unfollowed + Hashtag unfeatured Status reported Error @@ -289,6 +290,7 @@ update list remove user from list? remove user from list + remove hashtag from list remove domain from list unknown error! following list @@ -307,6 +309,8 @@ remember choice Warning Opening an external link would bypass proxy connection. Proceed? + unfollow hashtag? + unfeature hashtag? remove account from list? delete filter? \'unnamed\'