added hashtag search for Mastodon, bug fix

This commit is contained in:
nuclearfog 2023-01-15 20:12:28 +01:00
parent 6fbea96223
commit b81792eee3
No known key found for this signature in database
GPG Key ID: 03488A185C476379
26 changed files with 173 additions and 104 deletions

View File

@ -57,7 +57,7 @@ proguardDictionaries {
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

View File

@ -9,6 +9,7 @@ import static org.nuclearfog.twidda.ui.fragments.StatusFragment.STATUS_FRAGMENT_
import static org.nuclearfog.twidda.ui.fragments.StatusFragment.STATUS_FRAGMENT_SEARCH;
import static org.nuclearfog.twidda.ui.fragments.StatusFragment.STATUS_FRAGMENT_USER;
import static org.nuclearfog.twidda.ui.fragments.StatusFragment.STATUS_FRAGMENT_USERLIST;
import static org.nuclearfog.twidda.ui.fragments.TrendFragment.KEY_HASHTAG_SEARCH;
import static org.nuclearfog.twidda.ui.fragments.UserFragment.KEY_FRAG_DEL_USER;
import static org.nuclearfog.twidda.ui.fragments.UserFragment.KEY_FRAG_USER_ID;
import static org.nuclearfog.twidda.ui.fragments.UserFragment.KEY_FRAG_USER_MODE;
@ -147,16 +148,25 @@ public class FragmentAdapter extends FragmentStatePagerAdapter {
/**
* setup adapter for search for status and user search
*
* @param search Search string
* @param search Search string
* @param includeHashtag add hashtag search fragment
*/
public void setupSearchPage(String search) {
public void setupSearchPage(String search, boolean includeHashtag) {
Bundle paramStatuses = new Bundle();
Bundle paramUsers = new Bundle();
Bundle paramTrend = new Bundle();
paramStatuses.putString(KEY_STATUS_FRAGMENT_SEARCH, search);
paramUsers.putString(KEY_FRAG_USER_SEARCH, search);
paramStatuses.putInt(KEY_STATUS_FRAGMENT_MODE, STATUS_FRAGMENT_SEARCH);
paramUsers.putInt(KEY_FRAG_USER_MODE, USER_FRAG_SEARCH);
fragments = new ListFragment[2];
paramTrend.putString(KEY_HASHTAG_SEARCH, search);
if (includeHashtag) {
fragments = new ListFragment[3];
fragments[2] = new TrendFragment();
fragments[2].setArguments(paramTrend);
} else {
fragments = new ListFragment[2];
}
fragments[0] = new StatusFragment();
fragments[1] = new UserFragment();
fragments[0].setArguments(paramStatuses);

View File

@ -238,6 +238,14 @@ public interface Connection {
*/
List<Trend> getTrends() throws ConnectionException;
/**
* search hashtags matching search string
*
* @param search text to search hashtags
* @return list of trends (Hashtags)
*/
List<Trend> searchHashtags(String search) throws ConnectionException;
/**
* get available locations for trends
*

View File

@ -201,6 +201,7 @@ public class Mastodon implements Connection {
List<String> params = new ArrayList<>();
params.add("q=" + StringTools.encode(search));
params.add("limit=" + settings.getListSize());
params.add("type=accounts");
return getUsers(ENDPOINT_SEARCH_ACCOUNTS, params);
}
@ -351,6 +352,7 @@ public class Mastodon implements Connection {
public List<Status> searchStatuses(String search, long minId, long maxId) throws MastodonException {
List<String> params = new ArrayList<>();
params.add("q=" + StringTools.encode(search));
params.add("limit=" + settings.getListSize());
params.add("type=statuses");
return getStatuses(SEARCH_TIMELINE, params, minId, maxId);
}
@ -385,6 +387,30 @@ public class Mastodon implements Connection {
}
@Override
public List<Trend> searchHashtags(String search) throws MastodonException {
try {
List<String> params = new ArrayList<>();
params.add("q=" + StringTools.encode(search));
params.add("limit=" + settings.getListSize());
params.add("type=hashtags");
Response response = get(SEARCH_TIMELINE, params);
ResponseBody body = response.body();
if (response.code() == 200 && body != null) {
JSONArray array = new JSONObject(body.string()).getJSONArray("hashtags");
List<Trend> result = new ArrayList<>(array.length());
for (int i = 0; i < array.length(); i++) {
result.add(new MastodonTrend(array.getJSONObject(i), i));
}
return result;
}
throw new MastodonException(response);
} catch (IOException | JSONException e) {
throw new MastodonException(e);
}
}
@Override
public List<Location> getLocations() {
return new ArrayList<>(0); // not supported yet

View File

@ -25,7 +25,7 @@ public class MastodonTrend implements Trend {
*/
public MastodonTrend(JSONObject json, int pos) {
JSONArray history = json.optJSONArray("history");
name = json.optString("name", "");
name = '#' + json.optString("name", "");
rank = pos + 1;
if (history != null && history.length() > 0) {
JSONObject latest = history.optJSONObject(0);

View File

@ -534,6 +534,12 @@ public class Twitter implements Connection {
}
@Override
public List<Trend> searchHashtags(String search) throws TwitterException {
throw new TwitterException("not implemented!");
}
@Override
public List<Location> getLocations() throws TwitterException {
try {

View File

@ -65,10 +65,11 @@ public class MessageLoader extends AsyncTask<Void, Void, Messages> {
@Override
protected Messages doInBackground(Void... v) {
Messages messages = null;
try {
switch (action) {
case DB:
Messages messages = db.getMessages();
messages = db.getMessages();
if (messages.isEmpty()) {
messages = connection.getDirectmessages("");
// merge online messages with offline messages
@ -95,8 +96,9 @@ public class MessageLoader extends AsyncTask<Void, Void, Messages> {
}
} catch (Exception e) {
e.printStackTrace();
messageId = -1L; // remove ID of the message
}
return null;
return messages;
}
@ -109,16 +111,17 @@ public class MessageLoader extends AsyncTask<Void, Void, Messages> {
case LOAD:
if (messages != null) {
fragment.setData(messages);
} else {
}
if (messages == null || exception != null) {
fragment.onError(exception, messageId);
}
break;
case DEL:
if (exception == null) {
fragment.removeItem(messageId);
} else {
if (exception != null || messageId != -1L) {
fragment.onError(exception, messageId);
} else {
fragment.removeItem(messageId);
}
break;
}

View File

@ -208,7 +208,7 @@ public class StatusLoader extends AsyncTask<Long, Void, List<Status>> {
if (statuses != null) {
fragment.setData(statuses, pos);
}
if (exception != null) {
if (statuses == null || exception != null) {
fragment.onError(exception);
}
}

View File

@ -20,7 +20,7 @@ import java.util.List;
* @author nuclearfog
* @see TrendFragment
*/
public class TrendLoader extends AsyncTask<Void, Void, List<Trend>> {
public class TrendLoader extends AsyncTask<String, Void, List<Trend>> {
private WeakReference<TrendFragment> weakRef;
private Connection connection;
@ -43,10 +43,12 @@ public class TrendLoader extends AsyncTask<Void, Void, List<Trend>> {
@Override
protected List<Trend> doInBackground(Void... v) {
List<Trend> trends;
protected List<Trend> doInBackground(String... params) {
List<Trend> trends = null;
try {
if (isEmpty) {
if (params.length == 1 && params[0] != null && !params[0].trim().isEmpty()) {
trends = connection.searchHashtags(params[0]);
} else if (isEmpty) {
trends = db.getTrends();
if (trends.isEmpty()) {
trends = connection.getTrends();
@ -56,13 +58,12 @@ public class TrendLoader extends AsyncTask<Void, Void, List<Trend>> {
trends = connection.getTrends();
db.saveTrends(trends);
}
return trends;
} catch (ConnectionException exception) {
this.exception = exception;
} catch (Exception e) {
e.printStackTrace();
}
return null;
return trends;
}
@ -73,7 +74,7 @@ public class TrendLoader extends AsyncTask<Void, Void, List<Trend>> {
if (trends != null) {
fragment.setData(trends);
}
if (exception != null) {
if (trends == null || exception != null) {
fragment.onError(exception);
}
}

View File

@ -208,14 +208,14 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener,
else {
String apiTxt1 = apiKey1.getText().toString();
String apiTxt2 = apiKey2.getText().toString();
Toast.makeText(this, R.string.info_open_twitter_login, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_open_twitter_login, LENGTH_LONG).show();
loginAsync = new LoginAction(this, LoginAction.LOGIN_TWITTER, LoginAction.MODE_REQUEST);
loginAsync.execute(apiTxt1, apiTxt2);
}
}
// use system tokens
else if (Tokens.USE_DEFAULT_KEYS) {
Toast.makeText(this, R.string.info_open_twitter_login, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_open_twitter_login, LENGTH_LONG).show();
loginAsync = new LoginAction(this, LoginAction.LOGIN_TWITTER, LoginAction.MODE_REQUEST);
loginAsync.execute();
}
@ -223,9 +223,9 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener,
// generate Mastodon login
else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_MASTODON) {
if (apiHost.length() > 0 && !Patterns.WEB_URL.matcher(apiHost.getText()).matches()) {
Toast.makeText(this, R.string.error_invalid_url, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.error_invalid_url, LENGTH_LONG).show();
} else {
Toast.makeText(this, R.string.info_open_mastodon_login, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_open_mastodon_login, LENGTH_LONG).show();
loginAsync = new LoginAction(this, LoginAction.LOGIN_MASTODON, LoginAction.MODE_REQUEST);
if (apiHost.length() > 0) {
String link = apiHost.getText().toString();
@ -245,7 +245,7 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener,
String code = pinInput.getText().toString();
// check if user clicked on PIN button
if (loginLink == null) {
Toast.makeText(this, R.string.info_get_link, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_get_link, LENGTH_LONG).show();
} else if (code.isEmpty()) {
pinInput.setError(getString(R.string.error_enter_code));
}
@ -259,21 +259,21 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener,
else {
String apiTxt1 = apiKey1.getText().toString();
String apiTxt2 = apiKey2.getText().toString();
Toast.makeText(this, R.string.info_login_to_twitter, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_login_to_twitter, LENGTH_LONG).show();
loginAsync = new LoginAction(this, LoginAction.LOGIN_TWITTER, LoginAction.MODE_LOGIN);
loginAsync.execute(loginLink, code, apiTxt1, apiTxt2);
}
}
// use system tokens
else if (Tokens.USE_DEFAULT_KEYS) {
Toast.makeText(this, R.string.info_login_to_twitter, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_login_to_twitter, LENGTH_LONG).show();
loginAsync = new LoginAction(this, LoginAction.LOGIN_TWITTER, LoginAction.MODE_LOGIN);
loginAsync.execute(loginLink, code);
}
}
// login to mastodon
else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_MASTODON) {
Toast.makeText(this, R.string.info_login_to_mastodon, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_login_to_mastodon, LENGTH_LONG).show();
loginAsync = new LoginAction(this, LoginAction.LOGIN_MASTODON, LoginAction.MODE_LOGIN);
loginAsync.execute(loginLink, code);
}
@ -358,7 +358,7 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener,
try {
startActivity(loginIntent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_open_link, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_open_link, LENGTH_SHORT).show();
}
}

View File

@ -250,7 +250,7 @@ public class MainActivity extends AppCompatActivity implements OnTabSelectedList
search.putExtra(KEY_SEARCH_QUERY, s);
startActivity(search);
} else {
Toast.makeText(this, R.string.error_twitter_search, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_twitter_search, Toast.LENGTH_SHORT).show();
}
return false;
}
@ -302,7 +302,7 @@ public class MainActivity extends AppCompatActivity implements OnTabSelectedList
if (error != null) {
ErrorHandler.handleFailure(this, error);
} else {
Toast.makeText(this, R.string.error_open_link, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_open_link, Toast.LENGTH_SHORT).show();
}
loadingCircle.dismiss();
}

View File

@ -247,7 +247,7 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
* called when an image was successfully saved to external storage
*/
public void onImageSaved() {
Toast.makeText(this, R.string.info_image_saved, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_image_saved, LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
// start media scanner to scan for new image
MediaScannerConnection.scanFile(this, new String[]{imageName}, null, null);
@ -258,7 +258,7 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
* called when an error occurs while storing image
*/
public void onError() {
Toast.makeText(this, R.string.error_image_save, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_image_save, Toast.LENGTH_SHORT).show();
}
/**
@ -269,7 +269,7 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
startLocating();
} else {
if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
Toast.makeText(this, R.string.info_permission_location, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_permission_location, LENGTH_LONG).show();
}
requestPermissions(PERMISSION_LOCATION, REQUEST_LOCATION);
}
@ -297,7 +297,7 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
if (requiresPermission) {
for (String permission : PERMISSIONS_READ) {
if (shouldShowRequestPermissionRationale(permission)) {
Toast.makeText(this, R.string.info_permission_read, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_permission_read, LENGTH_LONG).show();
break;
}
}
@ -321,7 +321,7 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
saveImage();
} else {
if (shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE))
Toast.makeText(this, R.string.info_permission_write, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_permission_write, LENGTH_LONG).show();
requestPermissions(PERMISSION_WRITE, REQUEST_STORE_IMG);
}
}
@ -371,7 +371,7 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
try {
startActivityForResult(mediaSelect, requestCode);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_no_media_app, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_no_media_app, LENGTH_SHORT).show();
}
}

View File

@ -124,7 +124,7 @@ public class MessageEditor extends MediaActivity implements OnClickListener, OnC
preview.setVisibility(VISIBLE);
media.setVisibility(GONE);
} else {
Toast.makeText(this, R.string.error_adding_media, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_adding_media, LENGTH_SHORT).show();
}
}
}
@ -177,7 +177,7 @@ public class MessageEditor extends MediaActivity implements OnClickListener, OnC
* called when direct message is sent
*/
public void onSuccess() {
Toast.makeText(this, R.string.info_dm_send, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_dm_send, Toast.LENGTH_SHORT).show();
finish();
}
@ -206,10 +206,10 @@ public class MessageEditor extends MediaActivity implements OnClickListener, OnC
messageAsync.execute();
loadingCircle.show();
} else {
Toast.makeText(this, R.string.error_media_init, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_media_init, LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, R.string.error_dm, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_dm, LENGTH_SHORT).show();
}
}
}

View File

@ -478,7 +478,7 @@ public class ProfileActivity extends AppCompatActivity implements OnClickListene
try {
startActivity(intent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
}
}
@ -519,7 +519,7 @@ public class ProfileActivity extends AppCompatActivity implements OnClickListene
try {
startActivity(browserIntent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
}
}
@ -694,25 +694,25 @@ public class ProfileActivity extends AppCompatActivity implements OnClickListene
// check if block status changed
if (relation.isBlocked() != this.relation.isBlocked()) {
if (relation.isBlocked()) {
Toast.makeText(this, R.string.info_user_blocked, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_user_blocked, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.info_user_unblocked, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_user_unblocked, Toast.LENGTH_SHORT).show();
}
}
// check if following status changed
else if (relation.isFollowing() != this.relation.isFollowing()) {
if (relation.isFollowing()) {
Toast.makeText(this, R.string.info_followed, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_followed, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.info_unfollowed, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_unfollowed, Toast.LENGTH_SHORT).show();
}
}
// check if mute status changed
else if (relation.isMuted() != this.relation.isMuted()) {
if (relation.isMuted()) {
Toast.makeText(this, R.string.info_user_muted, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_user_muted, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.info_user_unmuted, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_user_unmuted, Toast.LENGTH_SHORT).show();
}
}
}

View File

@ -205,7 +205,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
if (holder.setImage(this, uri)) {
profile_image.setImageURI(uri);
} else {
Toast.makeText(this, R.string.error_adding_media, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_adding_media, Toast.LENGTH_SHORT).show();
}
}
// Add image as banner image
@ -217,7 +217,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
addBannerBtn.setVisibility(INVISIBLE);
changeBannerBtn.setVisibility(VISIBLE);
} else {
Toast.makeText(this, R.string.error_adding_media, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_adding_media, Toast.LENGTH_SHORT).show();
}
}
}
@ -276,7 +276,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
public void onSuccess(@NonNull User user) {
Intent data = new Intent();
data.putExtra(KEY_UPDATED_PROFILE, user);
Toast.makeText(this, R.string.info_profile_updated, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_profile_updated, Toast.LENGTH_SHORT).show();
setResult(RETURN_PROFILE_CHANGED, data);
finish();
}
@ -314,7 +314,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
editorAsync.execute();
loadingCircle.show();
} else {
Toast.makeText(this, R.string.error_media_init, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_media_init, Toast.LENGTH_SHORT).show();
}
}
}

View File

@ -78,9 +78,12 @@ public class SearchActivity extends AppCompatActivity implements OnTabSelectedLi
pager.setAdapter(adapter);
pager.setOffscreenPageLimit(2);
search = getIntent().getStringExtra(KEY_SEARCH_QUERY);
adapter.setupSearchPage(search);
AppStyles.setTabIcons(tabLayout, settings, R.array.search_tab_icons);
String search = getIntent().getStringExtra(KEY_SEARCH_QUERY);
if (search != null) {
this.search = search;
adapter.setupSearchPage(search, !search.startsWith("#") && settings.getLogin().getApiType() == Account.API_MASTODON);
AppStyles.setTabIcons(tabLayout, settings, R.array.search_tab_icons);
}
AppStyles.setTheme(root);
}
@ -146,7 +149,7 @@ public class SearchActivity extends AppCompatActivity implements OnTabSelectedLi
search.putExtra(KEY_SEARCH_QUERY, s);
startActivity(search);
} else {
Toast.makeText(this, R.string.error_twitter_search, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_twitter_search, Toast.LENGTH_SHORT).show();
}
return true;
}

View File

@ -534,7 +534,7 @@ public class SettingsActivity extends AppCompatActivity implements OnClickListen
else if (parent.getId() == R.id.spinner_scale) {
settings.setScaleIndex(position);
AppStyles.setFontStyle(root);
Toast.makeText(this, R.string.info_restart_app_on_change, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_restart_app_on_change, Toast.LENGTH_SHORT).show();
}
}

View File

@ -365,7 +365,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
try {
startActivity(intent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
}
// copy status link to clipboard
@ -373,7 +373,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
if (clip != null) {
ClipData linkClip = ClipData.newPlainText("status text", status.getText());
clip.setPrimaryClip(linkClip);
Toast.makeText(this, R.string.info_tweet_text_copied, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_text_copied, LENGTH_SHORT).show();
}
}
// copy status link to clipboard
@ -381,7 +381,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
if (clip != null) {
ClipData linkClip = ClipData.newPlainText("status link", status.getUrl());
clip.setPrimaryClip(linkClip);
Toast.makeText(this, R.string.info_tweet_link_copied, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_link_copied, LENGTH_SHORT).show();
}
}
// open status metrics page
@ -398,7 +398,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
if (clip != null) {
ClipData linkClip = ClipData.newPlainText("status media link", medias[index].getUrl());
clip.setPrimaryClip(linkClip);
Toast.makeText(this, R.string.info_tweet_medialink_copied, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_medialink_copied, LENGTH_SHORT).show();
}
}
}
@ -485,7 +485,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
} else {
statusAsync.execute(status.getId());
}
Toast.makeText(this, R.string.info_loading, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_loading, LENGTH_SHORT).show();
return true;
}
// favorite this status
@ -496,7 +496,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
statusAsync = new StatusAction(this, StatusAction.FAVORITE);
}
statusAsync.execute(status.getId());
Toast.makeText(this, R.string.info_loading, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_loading, LENGTH_SHORT).show();
return true;
}
// go to original status
@ -519,7 +519,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
if (clip != null && location != null) {
ClipData linkClip = ClipData.newPlainText("Status location coordinates", location.getCoordinates());
clip.setPrimaryClip(linkClip);
Toast.makeText(this, R.string.info_tweet_location_copied, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_location_copied, LENGTH_SHORT).show();
}
}
}
@ -563,7 +563,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
try {
startActivity(intent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
} else if (type == OnCardClickListener.TYPE_IMAGE) {
String imageUrl = card.getImageUrl();
@ -635,7 +635,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
try {
startActivity(intent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
}
}
@ -767,43 +767,43 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
public void OnSuccess(int action) {
switch (action) {
case StatusAction.REPOST:
Toast.makeText(this, R.string.info_tweet_retweeted, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_retweeted, LENGTH_SHORT).show();
break;
case StatusAction.REMOVE_REPOST:
Toast.makeText(this, R.string.info_tweet_unretweeted, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_unretweeted, LENGTH_SHORT).show();
// todo remove old retweet from list fragment
break;
case StatusAction.FAVORITE:
if (settings.likeEnabled())
Toast.makeText(this, R.string.info_tweet_liked, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_liked, LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.info_tweet_favored, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_favored, LENGTH_SHORT).show();
break;
case StatusAction.UNFAVORITE:
if (settings.likeEnabled())
Toast.makeText(this, R.string.info_tweet_unliked, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_unliked, LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.info_tweet_unfavored, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_unfavored, LENGTH_SHORT).show();
break;
case StatusAction.HIDE:
hidden = true;
invalidateOptionsMenu();
Toast.makeText(this, R.string.info_reply_hidden, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_reply_hidden, LENGTH_SHORT).show();
break;
case StatusAction.UNHIDE:
hidden = false;
invalidateOptionsMenu();
Toast.makeText(this, R.string.info_reply_unhidden, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_reply_unhidden, LENGTH_SHORT).show();
break;
case StatusAction.DELETE:
if (status != null) {
Toast.makeText(this, R.string.info_tweet_removed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_removed, LENGTH_SHORT).show();
Intent returnData = new Intent();
if (status.getEmbeddedStatus() != null)
returnData.putExtra(INTENT_STATUS_REMOVED_ID, status.getEmbeddedStatus().getId());

View File

@ -160,15 +160,15 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
String statusText = this.statusText.getText().toString();
// check if status is empty
if (statusText.trim().isEmpty() && statusUpdate.mediaCount() == 0) {
Toast.makeText(this, R.string.error_empty_tweet, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_empty_tweet, LENGTH_SHORT).show();
}
// check if mentions exceed the limit
else if (StringTools.countMentions(statusText) > MAX_MENTIONS) {
Toast.makeText(this, R.string.error_mention_exceed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_mention_exceed, LENGTH_SHORT).show();
}
// check if GPS location is pending
else if (isLocating()) {
Toast.makeText(this, R.string.info_location_pending, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_location_pending, LENGTH_SHORT).show();
}
// check if gps locating is not pending
else if (uploaderAsync == null || uploaderAsync.getStatus() != RUNNING) {
@ -202,9 +202,9 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
protected void onAttachLocation(@Nullable Location location) {
if (location != null) {
statusUpdate.setLocation(location);
Toast.makeText(this, R.string.info_gps_attached, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_gps_attached, LENGTH_LONG).show();
} else {
Toast.makeText(this, R.string.error_gps, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.error_gps, LENGTH_LONG).show();
}
locationPending.setVisibility(INVISIBLE);
locationBtn.setVisibility(VISIBLE);
@ -228,7 +228,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
break;
case StatusUpdate.MEDIA_ERROR:
Toast.makeText(this, R.string.error_adding_media, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_adding_media, LENGTH_SHORT).show();
break;
}
if (statusUpdate.mediaLimitReached()) {
@ -282,7 +282,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
* called if status was updated successfully
*/
public void onSuccess() {
Toast.makeText(this, R.string.info_tweet_sent, LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), R.string.info_tweet_sent, LENGTH_LONG).show();
finish();
}
@ -321,7 +321,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
// show progress dialog
loadingCircle.show();
} else {
Toast.makeText(this, R.string.error_media_init, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_media_init, LENGTH_SHORT).show();
}
}
}

View File

@ -329,13 +329,13 @@ public class UserlistActivity extends AppCompatActivity implements OnTabSelected
return false;
if (USERNAME_PATTERN.matcher(query).matches()) {
if (listManagerAsync == null || listManagerAsync.getStatus() != RUNNING) {
Toast.makeText(this, R.string.info_adding_user_to_list, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_adding_user_to_list, Toast.LENGTH_SHORT).show();
listManagerAsync = new ListManager(this, userList.getId(), ListManager.ADD_USER, query, this);
listManagerAsync.execute();
return true;
}
} else {
Toast.makeText(this, R.string.error_username_format, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_username_format, Toast.LENGTH_SHORT).show();
}
return false;
}
@ -352,14 +352,14 @@ public class UserlistActivity extends AppCompatActivity implements OnTabSelected
if (!name.startsWith("@"))
name = '@' + name;
String info = getString(R.string.info_user_added_to_list, name);
Toast.makeText(this, info, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
break;
case ListManager.DEL_USER:
if (user != null) {
info = getString(R.string.info_user_removed, user.getScreenname());
Toast.makeText(this, info, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show();
// remove user from list member page
Fragment fragment = adapter.getItem(1);
if (fragment instanceof UserFragment) {
@ -405,12 +405,12 @@ public class UserlistActivity extends AppCompatActivity implements OnTabSelected
break;
case ListAction.FOLLOW:
Toast.makeText(this, R.string.info_list_followed, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_list_followed, Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
break;
case ListAction.UNFOLLOW:
Toast.makeText(this, R.string.info_list_unfollowed, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_list_unfollowed, Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
break;
@ -418,7 +418,7 @@ public class UserlistActivity extends AppCompatActivity implements OnTabSelected
Intent result = new Intent();
result.putExtra(RESULT_REMOVED_LIST_ID, userList.getId());
setResult(RETURN_LIST_REMOVED, result);
Toast.makeText(this, R.string.info_list_removed, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_list_removed, Toast.LENGTH_SHORT).show();
finish();
break;
}

View File

@ -165,8 +165,8 @@ public class UserlistEditor extends AppCompatActivity implements OnClickListener
/**
* called when a list was created successfully
*
* @param result new created list
* @param updated true if an existing list was updated
* @param result new created list
* @param updated true if an existing list was updated
*/
public void onSuccess(@NonNull UserList result, boolean updated) {
if (updated) {
@ -197,7 +197,7 @@ public class UserlistEditor extends AppCompatActivity implements OnClickListener
String descrStr = subTitleInput.getText().toString();
boolean isPublic = visibility.isChecked();
if (titleStr.trim().isEmpty()) {
Toast.makeText(this, R.string.error_list_title_empty, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_list_title_empty, Toast.LENGTH_SHORT).show();
} else {
UserListUpdate mHolder;
if (userList != null) {

View File

@ -235,7 +235,7 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.menu_exclude_refresh) {
if (userExclTask == null || userExclTask.getStatus() != RUNNING) {
Toast.makeText(this, R.string.info_refreshing_exclude_list, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_refreshing_exclude_list, Toast.LENGTH_SHORT).show();
userExclTask = new FilterLoader(this, REFRESH);
userExclTask.execute();
}
@ -279,7 +279,7 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis
}
}
} else {
Toast.makeText(this, R.string.error_username_format, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_username_format, Toast.LENGTH_SHORT).show();
}
return false;
}
@ -296,17 +296,17 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis
public void onSuccess(int mode) {
switch (mode) {
case MUTE_USER:
Toast.makeText(this, R.string.info_user_muted, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_user_muted, Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
break;
case BLOCK_USER:
Toast.makeText(this, R.string.info_user_blocked, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_user_blocked, Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
break;
case REFRESH:
Toast.makeText(this, R.string.info_exclude_list_updated, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.info_exclude_list_updated, Toast.LENGTH_SHORT).show();
break;
}
}

View File

@ -228,7 +228,7 @@ public class VideoViewer extends MediaActivity implements OnSeekBarChangeListene
try {
startActivity(intent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
}
}
@ -350,7 +350,7 @@ public class VideoViewer extends MediaActivity implements OnSeekBarChangeListene
if (link.getScheme().startsWith("http")) {
confirmDialog.show(ConfirmDialog.VIDEO_ERROR);
} else {
Toast.makeText(this, R.string.error_cant_load_video, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_cant_load_video, LENGTH_SHORT).show();
finish();
}
return true;
@ -398,7 +398,7 @@ public class VideoViewer extends MediaActivity implements OnSeekBarChangeListene
try {
startActivity(intent);
} catch (ActivityNotFoundException err) {
Toast.makeText(this, R.string.error_connection_failed, LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
}
}
}

View File

@ -219,7 +219,7 @@ public class StatusFragment extends ListFragment implements StatusSelectListener
/**
* called from {@link StatusLoader} if an error occurs
*/
public void onError(ConnectionException error) {
public void onError(@Nullable ConnectionException error) {
ErrorHandler.handleFailure(requireContext(), error);
adapter.disableLoading();
setRefresh(false);

View File

@ -27,15 +27,26 @@ import java.util.List;
*/
public class TrendFragment extends ListFragment implements TrendClickListener {
/**
* additional bundle key to set search string for hashtags
*/
public static final String KEY_HASHTAG_SEARCH = "trend_search_hashtags";
private TrendLoader trendTask;
private TrendAdapter adapter;
private String search = "";
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
adapter = new TrendAdapter(settings, this);
setAdapter(adapter);
Bundle args = getArguments();
if (args != null) {
search = args.getString(KEY_HASHTAG_SEARCH, "");
}
}
@ -106,7 +117,7 @@ public class TrendFragment extends ListFragment implements TrendClickListener {
/**
* called from {@link TrendLoader} if an error occurs
*/
public void onError(ConnectionException error) {
public void onError(@Nullable ConnectionException error) {
ErrorHandler.handleFailure(requireContext(), error);
setRefresh(false);
}
@ -116,6 +127,6 @@ public class TrendFragment extends ListFragment implements TrendClickListener {
*/
private void load() {
trendTask = new TrendLoader(this);
trendTask.execute();
trendTask.execute(search);
}
}

View File

@ -18,6 +18,7 @@
<integer-array name="search_tab_icons">
<item>@drawable/search</item>
<item>@drawable/user</item>
<item>@drawable/hash</item>
</integer-array>
<integer-array name="list_tab_icons">