added hashtag suggestion, renamed list

This commit is contained in:
nuclearfog 2023-10-01 21:02:48 +02:00
parent 2b6f15296c
commit 4b7c037a37
No known key found for this signature in database
GPG Key ID: 03488A185C476379
11 changed files with 107 additions and 68 deletions

View File

@ -30,7 +30,7 @@ import org.nuclearfog.twidda.model.lists.Filters;
import org.nuclearfog.twidda.model.lists.Notifications;
import org.nuclearfog.twidda.model.lists.ScheduledStatuses;
import org.nuclearfog.twidda.model.lists.Statuses;
import org.nuclearfog.twidda.model.lists.Trends;
import org.nuclearfog.twidda.model.lists.Hashtags;
import org.nuclearfog.twidda.model.lists.UserLists;
import org.nuclearfog.twidda.model.lists.Users;
@ -272,7 +272,7 @@ public interface Connection {
*
* @return trend list
*/
Trends getTrends() throws ConnectionException;
Hashtags getTrends() throws ConnectionException;
/**
* search hashtags matching search string
@ -280,7 +280,7 @@ public interface Connection {
* @param search text to search hashtags
* @return list of trends (Hashtags)
*/
Trends searchHashtags(String search) throws ConnectionException;
Hashtags searchHashtags(String search) throws ConnectionException;
/**
* show hashtags the current user follows them
@ -288,14 +288,21 @@ public interface Connection {
* @param cursor cursor to parse the results
* @return hashtag list
*/
Trends showHashtagFollowing(long cursor) throws ConnectionException;
Hashtags showHashtagFollowing(long cursor) throws ConnectionException;
/**
* show featured hashtags by current user
*
* @return hashtag list
*/
Trends showHashtagFeaturing() throws ConnectionException;
Hashtags showHashtagFeaturing() throws ConnectionException;
/**
* show suggestions to feature hashtags
*
* @return hashtag list
*/
Hashtags showHashtagSuggestions() throws ConnectionException;
/**
* show information of a single hashtag

View File

@ -60,7 +60,7 @@ import org.nuclearfog.twidda.model.lists.Filters;
import org.nuclearfog.twidda.model.lists.Notifications;
import org.nuclearfog.twidda.model.lists.ScheduledStatuses;
import org.nuclearfog.twidda.model.lists.Statuses;
import org.nuclearfog.twidda.model.lists.Trends;
import org.nuclearfog.twidda.model.lists.Hashtags;
import org.nuclearfog.twidda.model.lists.UserLists;
import org.nuclearfog.twidda.model.lists.Users;
@ -457,26 +457,26 @@ public class Mastodon implements Connection {
@Override
public Trends getTrends() throws MastodonException {
Trends result = getTrends(ENDPOINT_TRENDS, new ArrayList<>());
public Hashtags getTrends() throws MastodonException {
Hashtags result = getTrends(ENDPOINT_TRENDS, new ArrayList<>());
Collections.sort(result);
return result;
}
@Override
public Trends searchHashtags(String search) throws MastodonException {
public Hashtags searchHashtags(String search) throws MastodonException {
List<String> params = new ArrayList<>();
params.add("q=" + StringUtils.encode(search));
params.add("type=hashtags");
Trends result = getTrends(ENDPOINT_SEARCH_TIMELINE, params);
Hashtags result = getTrends(ENDPOINT_SEARCH_TIMELINE, params);
Collections.sort(result);
return result;
}
@Override
public Trends showHashtagFollowing(long cursor) throws ConnectionException {
public Hashtags showHashtagFollowing(long cursor) throws ConnectionException {
List<String> params = new ArrayList<>();
if (cursor != 0L)
params.add("max_id=" + cursor);
@ -485,11 +485,17 @@ public class Mastodon implements Connection {
@Override
public Trends showHashtagFeaturing() throws ConnectionException {
public Hashtags showHashtagFeaturing() throws ConnectionException {
return getTrends(ENDPOINT_HASHTAG_FEATURE, new ArrayList<>());
}
@Override
public Hashtags showHashtagSuggestions() throws ConnectionException {
return getTrends(ENDPOINT_HASHTAG_FEATURE + "/suggestions", new ArrayList<>());
}
@Override
public Hashtag showHashtag(String name) throws ConnectionException {
try {
@ -1434,7 +1440,7 @@ public class Mastodon implements Connection {
* @param params additional parameters
* @return trend list
*/
private Trends getTrends(String endpoint, List<String> params) throws MastodonException {
private Hashtags getTrends(String endpoint, List<String> params) throws MastodonException {
try {
params.add("limit=" + settings.getListSize());
Response response = get(endpoint, params);
@ -1448,7 +1454,7 @@ public class Mastodon implements Connection {
jsonArray = new JSONObject(jsonStr).getJSONArray("hashtags");
}
long[] cursors = getCursors(response);
Trends result = new Trends(cursors[0], cursors[1]);
Hashtags result = new Hashtags(cursors[0], cursors[1]);
for (int i = 0; i < jsonArray.length(); i++) {
MastodonHashtag item = new MastodonHashtag(jsonArray.getJSONObject(i));
item.setRank(i + 1);

View File

@ -9,7 +9,7 @@ import org.nuclearfog.twidda.backend.api.Connection;
import org.nuclearfog.twidda.backend.api.ConnectionException;
import org.nuclearfog.twidda.backend.api.ConnectionManager;
import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.model.lists.Trends;
import org.nuclearfog.twidda.model.lists.Hashtags;
import org.nuclearfog.twidda.ui.fragments.HashtagFragment;
/**
@ -37,28 +37,32 @@ public class HashtagLoader extends AsyncExecutor<HashtagLoader.Param, HashtagLoa
try {
switch (param.mode) {
case Param.POPULAR_OFFLINE:
Trends trends = db.getTrends();
if (!trends.isEmpty()) {
return new Result(Result.POPULAR, trends, param.index, null);
Hashtags hashtags = db.getTrends();
if (!hashtags.isEmpty()) {
return new Result(Result.POPULAR, hashtags, param.index, null);
}
// fall through
case Param.POPULAR_ONLINE:
trends = connection.getTrends();
db.saveTrends(trends);
return new Result(Result.POPULAR, trends, param.index, null);
hashtags = connection.getTrends();
db.saveTrends(hashtags);
return new Result(Result.POPULAR, hashtags, param.index, null);
case Param.SEARCH:
trends = connection.searchHashtags(param.trend);
return new Result(Result.SEARCH, trends, param.index, null);
hashtags = connection.searchHashtags(param.trend);
return new Result(Result.SEARCH, hashtags, param.index, null);
case Param.FOLLOWING:
trends = connection.showHashtagFollowing(param.cursor);
return new Result(Result.FOLLOWING, trends, param.index, null);
hashtags = connection.showHashtagFollowing(param.cursor);
return new Result(Result.FOLLOWING, hashtags, param.index, null);
case Param.FEATURING:
trends = connection.showHashtagFeaturing();
return new Result(Result.FEATURING, trends, param.index, null);
hashtags = connection.showHashtagFeaturing();
return new Result(Result.FEATURING, hashtags, param.index, null);
case Param.SUGGESTIONS:
hashtags = connection.showHashtagSuggestions();
return new Result(Result.SUGGESTIONS, hashtags, param.index, null);
default:
return null;
@ -78,6 +82,7 @@ public class HashtagLoader extends AsyncExecutor<HashtagLoader.Param, HashtagLoa
public static final int SEARCH = 3;
public static final int FOLLOWING = 4;
public static final int FEATURING = 5;
public static final int SUGGESTIONS = 6;
public static final long NO_CURSOR = 0L;
@ -104,16 +109,17 @@ public class HashtagLoader extends AsyncExecutor<HashtagLoader.Param, HashtagLoa
public static final int SEARCH = 21;
public static final int FOLLOWING = 22;
public static final int FEATURING = 23;
public static final int SUGGESTIONS = 24;
public final int mode;
public final int index;
@Nullable
public final Trends trends;
public final Hashtags hashtags;
@Nullable
public final ConnectionException exception;
Result(int mode, @Nullable Trends trends, int index, @Nullable ConnectionException exception) {
this.trends = trends;
Result(int mode, @Nullable Hashtags hashtags, int index, @Nullable ConnectionException exception) {
this.hashtags = hashtags;
this.exception = exception;
this.index = index;
this.mode = mode;

View File

@ -45,7 +45,7 @@ import org.nuclearfog.twidda.model.User;
import org.nuclearfog.twidda.model.lists.Accounts;
import org.nuclearfog.twidda.model.lists.Notifications;
import org.nuclearfog.twidda.model.lists.Statuses;
import org.nuclearfog.twidda.model.lists.Trends;
import org.nuclearfog.twidda.model.lists.Hashtags;
import java.util.ArrayList;
import java.util.Collections;
@ -776,20 +776,20 @@ public class AppDatabase {
*
* @return list of trends
*/
public Trends getTrends() {
public Hashtags getTrends() {
synchronized (LOCK) {
String[] args = {Long.toString(settings.getTrendLocation().getId())};
SQLiteDatabase db = adapter.getDbRead();
Cursor cursor = db.query(HashtagTable.NAME, DatabaseHashtag.COLUMNS, TREND_SELECT, args, null, null, null);
Trends trends = new Trends();
Hashtags hashtags = new Hashtags();
if (cursor.moveToFirst()) {
do {
trends.add(new DatabaseHashtag(cursor));
hashtags.add(new DatabaseHashtag(cursor));
} while (cursor.moveToNext());
}
cursor.close();
Collections.sort(trends);
return trends;
Collections.sort(hashtags);
return hashtags;
}
}

View File

@ -8,11 +8,11 @@ import org.nuclearfog.twidda.model.Hashtag;
import java.util.LinkedList;
/**
* Trend list implementation with addtitional paging IDs
* Hashtag list implementation with addtitional paging cursors
*
* @author nuclearfog
*/
public class Trends extends LinkedList<Hashtag> {
public class Hashtags extends LinkedList<Hashtag> {
private static final long serialVersionUID = 7646437787602696292L;
@ -21,7 +21,7 @@ public class Trends extends LinkedList<Hashtag> {
/**
*
*/
public Trends() {
public Hashtags() {
this(0L, 0L);
}
@ -29,19 +29,19 @@ public class Trends extends LinkedList<Hashtag> {
* @param prevCursor minimum ID of an item
* @param nextCursor maximum ID of an item
*/
public Trends(long prevCursor, long nextCursor) {
public Hashtags(long prevCursor, long nextCursor) {
super();
this.nextCursor = nextCursor;
this.prevCursor = prevCursor;
}
/**
* @param trends trend list to clone
* @param hashtags trend list to clone
*/
public Trends(Trends trends) {
super(trends);
prevCursor = trends.prevCursor;
nextCursor = trends.nextCursor;
public Hashtags(Hashtags hashtags) {
super(hashtags);
prevCursor = hashtags.prevCursor;
nextCursor = hashtags.nextCursor;
}
/**
@ -70,31 +70,31 @@ public class Trends extends LinkedList<Hashtag> {
/**
* add a sublist at specific position
*
* @param trends sublist to add
* @param hashtags sublist to add
* @param index index where to insert the sublist
*/
public void addAll(int index, Trends trends) {
public void addAll(int index, Hashtags hashtags) {
if (isEmpty()) {
prevCursor = trends.getPreviousCursor();
nextCursor = trends.getNextCursor();
prevCursor = hashtags.getPreviousCursor();
nextCursor = hashtags.getNextCursor();
} else if (index == 0) {
prevCursor = trends.getPreviousCursor();
prevCursor = hashtags.getPreviousCursor();
} else if (index == size() - 1) {
nextCursor = trends.getNextCursor();
nextCursor = hashtags.getNextCursor();
}
super.addAll(index, trends);
super.addAll(index, hashtags);
}
/**
* replace all items with new ones
*
* @param trends new items to insert
* @param hashtags new items to insert
*/
public void replaceAll(Trends trends) {
public void replaceAll(Hashtags hashtags) {
clear();
addAll(trends);
prevCursor = trends.getPreviousCursor();
nextCursor = trends.getNextCursor();
addAll(hashtags);
prevCursor = hashtags.getPreviousCursor();
nextCursor = hashtags.getNextCursor();
}

View File

@ -52,7 +52,7 @@ public class HashtagActivity extends AppCompatActivity implements SearchView.OnQ
settings = GlobalSettings.get(this);
adapter = new HashtagAdapter(this);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(2);
viewPager.setOffscreenPageLimit(3);
tabSelector.addTabIcons(R.array.userlist_hashtag_icons);
tabSelector.addTabLabels(R.array.hashtag_labels);

View File

@ -7,7 +7,7 @@ import androidx.recyclerview.widget.RecyclerView.Adapter;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import org.nuclearfog.twidda.model.Hashtag;
import org.nuclearfog.twidda.model.lists.Trends;
import org.nuclearfog.twidda.model.lists.Hashtags;
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.HashtagHolder;
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.OnHolderClickListener;
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.PlaceHolder;
@ -33,7 +33,7 @@ public class HashtagAdapter extends Adapter<ViewHolder> implements OnHolderClick
private OnHashtagClickListener itemClickListener;
private Trends items = new Trends();
private Hashtags items = new Hashtags();
private int loadingIndex = NO_LOADING;
private boolean enableDelete = false;
@ -109,8 +109,8 @@ public class HashtagAdapter extends Adapter<ViewHolder> implements OnHolderClick
*
* @return a copy of the items
*/
public Trends getItems() {
return new Trends(items);
public Hashtags getItems() {
return new Hashtags(items);
}
/**
@ -118,7 +118,7 @@ public class HashtagAdapter extends Adapter<ViewHolder> implements OnHolderClick
*
* @param newItems array of trend items
*/
public void addItems(Trends newItems, int index) {
public void addItems(Hashtags newItems, int index) {
disableLoading();
if (index < 0) {
this.items.replaceAll(newItems);

View File

@ -30,7 +30,13 @@ public class HashtagAdapter extends ViewPagerAdapter {
paramFeaturedTags.putInt(HashtagFragment.KEY_MODE, HashtagFragment.MODE_FEATURE);
featuredTags.setArguments(paramFeaturedTags);
HashtagFragment suggestedTags = new HashtagFragment();
Bundle paramSuggestedTags = new Bundle();
paramSuggestedTags.putInt(HashtagFragment.KEY_MODE, HashtagFragment.MODE_SUGGESTIONS);
suggestedTags.setArguments(paramSuggestedTags);
fragments.add(followedTags);
fragments.add(featuredTags);
fragments.add(suggestedTags);
}
}

View File

@ -18,7 +18,7 @@ import org.nuclearfog.twidda.backend.async.HashtagAction;
import org.nuclearfog.twidda.backend.async.HashtagLoader;
import org.nuclearfog.twidda.backend.utils.ErrorUtils;
import org.nuclearfog.twidda.model.Hashtag;
import org.nuclearfog.twidda.model.lists.Trends;
import org.nuclearfog.twidda.model.lists.Hashtags;
import org.nuclearfog.twidda.ui.activities.SearchActivity;
import org.nuclearfog.twidda.ui.adapter.recyclerview.HashtagAdapter;
import org.nuclearfog.twidda.ui.adapter.recyclerview.HashtagAdapter.OnHashtagClickListener;
@ -54,6 +54,11 @@ public class HashtagFragment extends ListFragment implements OnHashtagClickListe
*/
public static final int MODE_FEATURE = 0x16347583;
/**
* setup fragment to view suggestions for hashtag features
*/
public static final int MODE_SUGGESTIONS = 0x4422755;
/**
* key used to define what type of trends should be shown, see {@link #MODE_FOLLOW ,#MODE_POPULAR ,#KEY_FRAGMENT_TREND_SEARCH}
* value type is Integer
@ -68,7 +73,7 @@ public class HashtagFragment extends ListFragment implements OnHashtagClickListe
/**
* bundle key to add adapter items
* value type is {@link Trends}
* value type is {@link Hashtags}
*/
private static final String KEY_DATA = "fragment_trend_data";
@ -106,8 +111,8 @@ public class HashtagFragment extends ListFragment implements OnHashtagClickListe
}
if (savedInstanceState != null) {
Serializable data = savedInstanceState.getSerializable(KEY_DATA);
if (data instanceof Trends) {
adapter.addItems((Trends) data, HashtagAdapter.CLEAR_LIST);
if (data instanceof Hashtags) {
adapter.addItems((Hashtags) data, HashtagAdapter.CLEAR_LIST);
return;
}
}
@ -237,7 +242,7 @@ public class HashtagFragment extends ListFragment implements OnHashtagClickListe
}
adapter.disableLoading();
} else {
adapter.addItems(result.trends, result.index);
adapter.addItems(result.hashtags, result.index);
}
setRefresh(false);
}
@ -271,6 +276,12 @@ public class HashtagFragment extends ListFragment implements OnHashtagClickListe
param = new HashtagLoader.Param(HashtagLoader.Param.SEARCH, index, search, cursor);
hashtagLoader.execute(param, hashtagLoaderCallback);
break;
case MODE_SUGGESTIONS:
param = new HashtagLoader.Param(HashtagLoader.Param.SUGGESTIONS, index, search, cursor);
hashtagLoader.execute(param, hashtagLoaderCallback);
break;
}
}
}

View File

@ -38,6 +38,7 @@
<string-array name="hashtag_labels">
<item>gefolgt</item>
<item>vorgestellt</item>
<item>voegeschlagen</item>
</string-array>
<string-array name="userlist_policy">

View File

@ -72,6 +72,7 @@
<integer-array name="userlist_hashtag_icons">
<item>@drawable/hash</item>
<item>@drawable/hash</item>
<item>@drawable/hash</item>
</integer-array>
<string-array name="networks">
@ -115,6 +116,7 @@
<string-array name="hashtag_labels">
<item>followed</item>
<item>featured</item>
<item>suggested</item>
</string-array>
<string-array name="userlist_policy">