rearranged code

This commit is contained in:
nuclearfog 2020-05-23 20:36:12 +02:00
parent 7126042490
commit 94dd7b64b5
No known key found for this signature in database
GPG Key ID: ED35E22099354A64
31 changed files with 800 additions and 481 deletions

View File

@ -20,6 +20,7 @@ import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.app.AppCompatActivity;
@ -34,7 +35,8 @@ import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.adapter.FontAdapter;
import org.nuclearfog.twidda.adapter.LocationAdapter;
import org.nuclearfog.twidda.backend.LocationListLoader;
import org.nuclearfog.twidda.backend.TwitterEngine;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.backend.items.TrendLocation;
import org.nuclearfog.twidda.database.DatabaseAdapter;
@ -45,6 +47,7 @@ import java.util.regex.Matcher;
import static android.os.AsyncTask.Status.RUNNING;
import static android.view.View.GONE;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.MainActivity.APP_LOGOUT;
import static org.nuclearfog.twidda.activity.MainActivity.DB_CLEARED;
@ -347,6 +350,20 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
locationSpinner.setSelection(position);
}
public void onError(EngineException err) {
if (err.isErrorDefined()) {
if (err.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += err.getRetryAfter();
Toast.makeText(this, errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(this, err.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, err.getMessage(), LENGTH_SHORT).show();
}
}
private void setColor(int preColor) {
color_dialog_selector = ColorPickerDialogBuilder.with(this)

View File

@ -1,5 +1,6 @@
package org.nuclearfog.twidda.activity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@ -11,11 +12,13 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.Registration;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.database.GlobalSettings;
@ -87,7 +90,7 @@ public class LoginPage extends AppCompatActivity implements OnClickListener {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.login_setting) {
Intent settings = new Intent(this, AppSettings.class);
startActivity(settings);
@ -136,4 +139,19 @@ public class LoginPage extends AppCompatActivity implements OnClickListener {
else
Toast.makeText(this, R.string.error_connection, LENGTH_SHORT).show();
}
public void onSuccess() {
setResult(Activity.RESULT_OK);
finish();
}
public void onError(@NonNull EngineException error) {
if (error.isErrorDefined()) {
Toast.makeText(this, error.getMessageResource(), LENGTH_SHORT).show();
} else {
Toast.makeText(this, error.getMessage(), LENGTH_SHORT).show();
}
}
}

View File

@ -226,5 +226,7 @@ public class MainActivity extends AppCompatActivity implements OnTabSelectedList
@Override
public void onTabReselected(Tab tab) {
if (adapter != null)
adapter.scrollToTop(tab.getPosition());
}
}

View File

@ -18,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.MessageUploader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.backend.items.MessageHolder;
import org.nuclearfog.twidda.database.GlobalSettings;
@ -145,6 +146,33 @@ public class MessagePopup extends AppCompatActivity implements OnClickListener {
}
}
/**
* called when direct message is sent
*/
public void onSuccess() {
Toast.makeText(this, R.string.info_dm_send, Toast.LENGTH_SHORT).show();
finish();
}
/**
* called when an error occurs
*
* @param error Engine Exception
*/
public void onError(EngineException error) {
if (error.isErrorDefined()) {
if (error.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += error.getRetryAfter();
Toast.makeText(this, errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(this, error.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, error.getMessage(), LENGTH_SHORT).show();
}
}
private void getMedia() {
boolean accessGranted = true;

View File

@ -27,6 +27,7 @@ import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.ProfileUpdater;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserHolder;
@ -39,6 +40,7 @@ import static android.os.AsyncTask.Status.RUNNING;
import static android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
import static android.view.View.INVISIBLE;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.UserProfile.RETURN_PROFILE_CHANGED;
public class ProfileEditor extends AppCompatActivity implements OnClickListener {
@ -54,6 +56,7 @@ public class ProfileEditor extends AppCompatActivity implements OnClickListener
private EditText name, link, loc, bio;
private Button add_banner_btn;
private String profileLink, bannerLink;
private boolean userSet = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -208,6 +211,32 @@ public class ProfileEditor extends AppCompatActivity implements OnClickListener
link.setText(user.getLink());
loc.setText(user.getLocation());
bio.setText(user.getBio());
userSet = true;
}
/**
* called after user profile was updated successfully
*/
public void setSuccess() {
Toast.makeText(this, R.string.info_profile_updated, Toast.LENGTH_SHORT).show();
setResult(RETURN_PROFILE_CHANGED);
finish();
}
/**
* called after an error occurs
*
* @param err Engine Exception
*/
public void setError(EngineException err) {
if (err.isErrorDefined()) {
Toast.makeText(this, err.getMessageResource(), LENGTH_SHORT).show();
} else {
Toast.makeText(this, err.getMessage(), LENGTH_SHORT).show();
}
if (!userSet) {
finish();
}
}

View File

@ -132,12 +132,15 @@ public class SearchPage extends AppCompatActivity implements OnTabSelectedListen
@Override
public void onTabUnselected(Tab tab) {
adapter.scrollToTop(tab.getPosition());
if (adapter != null)
adapter.scrollToTop(tab.getPosition());
}
@Override
public void onTabReselected(Tab tab) {
if (adapter != null)
adapter.scrollToTop(tab.getPosition());
}

View File

@ -34,6 +34,7 @@ import org.nuclearfog.twidda.adapter.FragmentAdapter;
import org.nuclearfog.twidda.adapter.FragmentAdapter.AdapterType;
import org.nuclearfog.twidda.backend.TweetLoader;
import org.nuclearfog.twidda.backend.TweetLoader.Action;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.items.Tweet;
@ -59,6 +60,7 @@ import static org.nuclearfog.twidda.activity.TweetPopup.KEY_TWEETPOPUP_REPLYID;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_ID;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_MODE;
import static org.nuclearfog.twidda.activity.UserDetail.USERLIST_RETWEETS;
import static org.nuclearfog.twidda.fragment.TweetFragment.RETURN_TWEET_CHANGED;
public class TweetDetail extends AppCompatActivity implements OnClickListener,
@ -394,8 +396,58 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
}
}
/**
* called after a tweet action
*
* @param tweet tweet information
* @param action action type
*/
public void onAction(Tweet tweet, Action action) {
switch (action) {
case RETWEET:
if (tweet.retweeted())
Toast.makeText(this, R.string.info_tweet_retweeted, LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.info_tweet_unretweeted, LENGTH_SHORT).show();
break;
public void finishIfEmpty() {
case FAVORITE:
if (tweet.favored())
Toast.makeText(this, R.string.info_tweet_favored, LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.info_tweet_unfavored, LENGTH_SHORT).show();
break;
case DELETE:
Toast.makeText(this, R.string.info_tweet_removed, LENGTH_SHORT).show();
setResult(RETURN_TWEET_CHANGED);
finish();
break;
}
}
/**
* called when an error occurs
*
* @param error Engine Exception
*/
public void onError(@NonNull EngineException error) {
if (error.isErrorDefined()) {
if (error.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += error.getRetryAfter();
Toast.makeText(this, errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(this, error.getMessageResource(), LENGTH_SHORT).show();
}
if (error.isHardFault()) {
if (error.statusNotFound())
setResult(RETURN_TWEET_CHANGED);
finish();
}
} else {
Toast.makeText(this, error.getMessage(), LENGTH_SHORT).show();
}
if (tweet == null) {
finish();
}

View File

@ -24,6 +24,7 @@ import androidx.appcompat.app.AppCompatActivity;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.TweetUploader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.helper.StringTools.FileType;
@ -288,15 +289,27 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
locationBtn.setVisibility(VISIBLE);
}
/**
* called after sending tweet
*/
public void onSuccess() {
Toast.makeText(this, R.string.info_tweet_sent, LENGTH_LONG).show();
finish();
}
/**
* Show confirmation dialog if an error occurs while sending tweet
*
* @param tweet tweet to re-send
*/
public void showErrorMsg(final TweetHolder tweet) {
public void onError(final TweetHolder tweet, @Nullable EngineException error) {
int errorRes;
if (error != null && error.isErrorDefined()) {
errorRes = error.getMessageResource();
} else {
errorRes = R.string.error_sending_tweet;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.ConfirmDialog);
builder.setTitle(R.string.info_error).setMessage(R.string.error_sending_tweet)
builder.setTitle(R.string.info_error).setMessage(errorRes)
.setPositiveButton(R.string.confirm_retry, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

View File

@ -34,6 +34,7 @@ import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.adapter.FragmentAdapter;
import org.nuclearfog.twidda.adapter.FragmentAdapter.AdapterType;
import org.nuclearfog.twidda.backend.ProfileLoader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserProperties;
@ -452,12 +453,15 @@ public class UserProfile extends AppCompatActivity implements OnClickListener,
@Override
public void onTabUnselected(Tab tab) {
adapter.scrollToTop(tab.getPosition());
if (adapter != null)
adapter.scrollToTop(tab.getPosition());
}
@Override
public void onTabReselected(Tab tab) {
if (adapter != null)
adapter.scrollToTop(tab.getPosition());
}
@ -523,14 +527,63 @@ public class UserProfile extends AppCompatActivity implements OnClickListener,
}
}
/**
* Set User Relationship
*
* @param properties relationship to the current user
*/
public void setConnection(UserProperties properties) {
this.properties = properties;
invalidateOptionsMenu();
}
/**
* print messages after user action
*
* @param properties connection to an user
* @param action Action on the user profile
*/
public void onAction(UserProperties properties, ProfileLoader.Action action) {
switch (action) {
case ACTION_FOLLOW:
if (properties.isFriend())
Toast.makeText(this, R.string.info_followed, Toast.LENGTH_SHORT).show();
break;
case ACTION_BLOCK:
if (properties.isBlocked())
Toast.makeText(this, R.string.info_user_blocked, Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.info_user_unblocked, Toast.LENGTH_SHORT).show();
break;
case ACTION_MUTE:
if (properties.isMuted())
Toast.makeText(this, R.string.info_user_muted, Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.info_user_unmuted, Toast.LENGTH_SHORT).show();
break;
}
}
/**
* called if an error occurs
*
* @param err Engine Exception
*/
public void onError(EngineException err) {
if (err.isErrorDefined()) {
if (err.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += err.getRetryAfter();
Toast.makeText(this, errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(this, err.getMessageResource(), LENGTH_SHORT).show();
if (err.isHardFault()) {
finish();
}
}
} else {
Toast.makeText(this, err.getMessage(), LENGTH_SHORT).show();
}
}
}

View File

@ -234,10 +234,19 @@ public class FragmentAdapter extends FragmentStatePagerAdapter {
public interface FragmentChangeObserver {
/**
* called if settings changed to refresh fragments
*/
void onSettingsChange();
/**
* called when the current tab changes
*/
void onTabChange();
/**
* called to clear the lists
*/
void onDataClear();
}
}

View File

@ -1,18 +1,17 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.activity.AppSettings;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TrendLocation;
import java.lang.ref.WeakReference;
import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task to load location information used by twitter such as location names and world ID's
* @see AppSettings
@ -20,7 +19,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation>> {
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<AppSettings> ui;
private TwitterEngine mTwitter;
@ -35,7 +34,7 @@ public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation
protected List<TrendLocation> doInBackground(Void[] v) {
try {
return mTwitter.getLocations();
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -50,7 +49,7 @@ public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation
if (locations != null && !locations.isEmpty()) {
ui.get().setLocationData(locations);
} else if (twException != null) {
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().onError(twException);
}
}
}

View File

@ -1,11 +1,11 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.adapter.MessageAdapter;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.Message;
import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.fragment.MessageFragment;
@ -13,12 +13,9 @@ import org.nuclearfog.twidda.fragment.MessageFragment;
import java.lang.ref.WeakReference;
import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/**
* task to download a direct message list from twitter and handle message actions
*
* @see MessageFragment
*/
public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
@ -30,12 +27,11 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
}
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private Mode mode;
private WeakReference<MessageFragment> ui;
private TwitterEngine mTwitter;
private AppDatabase db;
private MessageAdapter adapter;
private long id;
@ -43,15 +39,15 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
ui = new WeakReference<>(fragment);
db = new AppDatabase(fragment.getContext());
mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter();
this.mode = mode;
}
@Override
protected void onPreExecute() {
if (ui.get() != null)
if (ui.get() != null) {
ui.get().setRefresh(true);
}
}
@ -81,7 +77,7 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
db.deleteDm(messageId);
break;
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
if (twException.statusNotFound())
db.deleteDm(messageId);
@ -95,22 +91,17 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
@Override
protected void onPostExecute(@Nullable List<Message> messages) {
if (ui.get() != null) {
if (messages != null)
adapter.replaceAll(messages);
else if (twException != null) {
Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show();
if (twException.statusNotFound())
adapter.remove(id);
} else if (mode == Mode.DEL)
adapter.remove(id);
if (messages != null) {
ui.get().setData(messages);
} else if (twException != null) {
ui.get().onError(twException);
if (twException.statusNotFound()) {
ui.get().removeItem(id);
}
} else if (mode == Mode.DEL) {
ui.get().removeItem(id);
}
ui.get().setRefresh(false);
}
}
@Override
protected void onCancelled() {
if (ui.get() != null)
ui.get().setRefresh(false);
}
}

View File

@ -12,12 +12,12 @@ import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.MessagePopup;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.MessageHolder;
import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task to send a direct messages to a user
* @see MessagePopup
@ -25,7 +25,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<MessagePopup> ui;
private WeakReference<Dialog> popup;
private TwitterEngine mTwitter;
@ -34,13 +34,13 @@ public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
/**
* send direct message
*
* @param c Activity context
* @param context Activity context
* @param message message to send
*/
public MessageUploader(@NonNull MessagePopup c, MessageHolder message) {
ui = new WeakReference<>(c);
popup = new WeakReference<>(new Dialog(c));
mTwitter = TwitterEngine.getInstance(c);
public MessageUploader(@NonNull MessagePopup context, MessageHolder message) {
ui = new WeakReference<>(context);
popup = new WeakReference<>(new Dialog(context));
mTwitter = TwitterEngine.getInstance(context);
this.message = message;
}
@ -81,7 +81,7 @@ public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
try {
mTwitter.sendMessage(message);
return true;
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -93,14 +93,12 @@ public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPostExecute(Boolean success) {
if (ui.get() != null && popup.get() != null) {
if (success) {
Toast.makeText(ui.get(), R.string.info_dm_send, Toast.LENGTH_SHORT).show();
ui.get().finish();
} else {
if (twException != null)
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
}
popup.get().dismiss();
if (success) {
ui.get().onSuccess();
} else if (twException != null) {
ui.get().onError(twException);
}
}
}

View File

@ -1,21 +1,19 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.UserProfile;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserProperties;
import org.nuclearfog.twidda.database.AppDatabase;
import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
/**
* task for loading user profile information and take actions
* @see UserProfile
@ -32,7 +30,7 @@ public class ProfileLoader extends AsyncTask<Long, TwitterUser, UserProperties>
private final Action action;
private WeakReference<UserProfile> ui;
private TwitterEngine mTwitter;
private TwitterEngine.EngineException twException;
private EngineException twException;
private AppDatabase db;
@ -100,7 +98,7 @@ public class ProfileLoader extends AsyncTask<Long, TwitterUser, UserProperties>
publishProgress(user);
return mTwitter.getConnection(userId);
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -123,31 +121,9 @@ public class ProfileLoader extends AsyncTask<Long, TwitterUser, UserProperties>
if (ui.get() != null) {
if (properties != null) {
ui.get().setConnection(properties);
switch (action) {
case ACTION_FOLLOW:
if (properties.isFriend())
Toast.makeText(ui.get(), R.string.info_followed, Toast.LENGTH_SHORT).show();
break;
case ACTION_BLOCK:
if (properties.isBlocked())
Toast.makeText(ui.get(), R.string.info_user_blocked, Toast.LENGTH_SHORT).show();
else
Toast.makeText(ui.get(), R.string.info_user_unblocked, Toast.LENGTH_SHORT).show();
break;
case ACTION_MUTE:
if (properties.isMuted())
Toast.makeText(ui.get(), R.string.info_user_muted, Toast.LENGTH_SHORT).show();
else
Toast.makeText(ui.get(), R.string.info_user_unmuted, Toast.LENGTH_SHORT).show();
break;
}
}
if (twException != null) {
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
if (twException.isHardFault())
ui.get().finish();
ui.get().onAction(properties, action);
} else if (twException != null) {
ui.get().onError(twException);
}
}
}

View File

@ -5,21 +5,18 @@ import android.content.DialogInterface;
import android.os.AsyncTask;
import android.view.Window;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.ProfileEditor;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserHolder;
import org.nuclearfog.twidda.database.AppDatabase;
import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.UserProfile.RETURN_PROFILE_CHANGED;
/**
* Task for editing profile information and updating images
@ -32,7 +29,7 @@ public class ProfileUpdater extends AsyncTask<Void, Void, TwitterUser> {
private WeakReference<Dialog> popup;
private UserHolder userHolder;
private TwitterEngine mTwitter;
private TwitterEngine.EngineException twException;
private EngineException twException;
private AppDatabase db;
@ -82,7 +79,7 @@ public class ProfileUpdater extends AsyncTask<Void, Void, TwitterUser> {
TwitterUser user = mTwitter.updateProfile(userHolder);
db.storeUser(user);
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -96,15 +93,11 @@ public class ProfileUpdater extends AsyncTask<Void, Void, TwitterUser> {
if (ui.get() != null && popup.get() != null) {
popup.get().dismiss();
if (twException != null) {
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
if (userHolder == null)
ui.get().finish();
ui.get().setError(twException);
} else if (user != null) {
ui.get().setUser(user);
} else if (userHolder != null) {
Toast.makeText(ui.get(), R.string.info_profile_updated, Toast.LENGTH_SHORT).show();
ui.get().setResult(RETURN_PROFILE_CHANGED);
ui.get().finish();
ui.get().setSuccess();
}
}
}

View File

@ -1,18 +1,15 @@
package org.nuclearfog.twidda.backend;
import android.app.Activity;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.LoginPage;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task to connect to twitter and initialize keys
* @see LoginPage
@ -20,7 +17,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class Registration extends AsyncTask<String, Void, String> {
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<LoginPage> ui;
private TwitterEngine mTwitter;
@ -42,7 +39,7 @@ public class Registration extends AsyncTask<String, Void, String> {
return mTwitter.request();
mTwitter.initialize(param[0]);
return "";
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -58,13 +55,10 @@ public class Registration extends AsyncTask<String, Void, String> {
if (!redirectionURL.isEmpty()) {
ui.get().connect(redirectionURL);
} else {
ui.get().setResult(Activity.RESULT_OK);
ui.get().finish();
ui.get().onSuccess();
}
} else if (twException != null) {
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
} else {
Toast.makeText(ui.get(), R.string.error_pin_verification, Toast.LENGTH_SHORT).show();
ui.get().onError(twException);
}
}
}

View File

@ -1,12 +1,12 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.adapter.TrendAdapter;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterTrend;
import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.fragment.TrendFragment;
@ -14,8 +14,6 @@ import org.nuclearfog.twidda.fragment.TrendFragment;
import java.lang.ref.WeakReference;
import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task to load a list of location specific trends
@ -25,18 +23,18 @@ import static android.widget.Toast.LENGTH_SHORT;
public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>> {
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<TrendFragment> ui;
private TwitterEngine mTwitter;
private AppDatabase db;
private TrendAdapter adapter;
private boolean isEmpty;
public TrendListLoader(@NonNull TrendFragment fragment) {
ui = new WeakReference<>(fragment);
db = new AppDatabase(fragment.getContext());
mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter();
isEmpty = fragment.isEmpty();
}
@ -52,7 +50,7 @@ public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>
List<TwitterTrend> trends;
int woeId = param[0];
try {
if (adapter.isEmpty()) {
if (isEmpty) {
trends = db.getTrends(woeId);
if (trends.isEmpty()) {
trends = mTwitter.getTrends(woeId);
@ -63,7 +61,7 @@ public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>
db.storeTrends(trends, woeId);
}
return trends;
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -75,18 +73,12 @@ public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>
@Override
protected void onPostExecute(@Nullable List<TwitterTrend> trends) {
if (ui.get() != null) {
if (trends != null)
adapter.setData(trends);
if (twException != null)
Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().setRefresh(false);
if (trends != null) {
ui.get().setData(trends);
} else if (twException != null) {
ui.get().onError(twException);
}
}
}
@Override
protected void onCancelled() {
if (ui.get() != null)
ui.get().setRefresh(false);
}
}

View File

@ -1,11 +1,11 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.adapter.TweetAdapter;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.Tweet;
import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.fragment.TweetFragment;
@ -13,8 +13,6 @@ import org.nuclearfog.twidda.fragment.TweetFragment;
import java.lang.ref.WeakReference;
import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task to download a list of tweets from different sources
@ -35,19 +33,19 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
}
@Nullable
private TwitterEngine.EngineException twException;
private Mode mode;
private EngineException twException;
private WeakReference<TweetFragment> ui;
private TweetAdapter adapter;
private TwitterEngine mTwitter;
private AppDatabase db;
private Mode mode;
private long sinceId;
public TweetListLoader(TweetFragment fragment, Mode mode) {
ui = new WeakReference<>(fragment);
db = new AppDatabase(fragment.getContext());
mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter();
sinceId = fragment.getTopId();
this.mode = mode;
}
@ -63,19 +61,17 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
@Override
protected List<Tweet> doInBackground(Object[] param) {
List<Tweet> tweets = null;
long sinceId = 1;
try {
switch (mode) {
case TL_HOME:
int page = (int) param[0];
if (adapter.isEmpty()) {
if (sinceId == 0) {
tweets = db.getHomeTimeline();
if (tweets.isEmpty()) {
tweets = mTwitter.getHome(page, sinceId);
db.storeHomeTimeline(tweets);
}
} else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getHome(page, sinceId);
db.storeHomeTimeline(tweets);
}
@ -83,14 +79,13 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case TL_MENT:
page = (int) param[0];
if (adapter.isEmpty()) {
if (sinceId == 0) {
tweets = db.getMentions();
if (tweets.isEmpty()) {
tweets = mTwitter.getMention(page, sinceId);
db.storeMentions(tweets);
}
} else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getMention(page, sinceId);
db.storeMentions(tweets);
}
@ -99,14 +94,13 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case USR_TWEETS:
long id = (long) param[0];
page = (int) param[1];
if (adapter.isEmpty()) {
if (sinceId == 0) {
tweets = db.getUserTweets(id);
if (tweets.isEmpty()) {
tweets = mTwitter.getUserTweets(id, sinceId, page);
db.storeUserTweets(tweets);
}
} else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getUserTweets(id, sinceId, page);
db.storeUserTweets(tweets);
}
@ -115,7 +109,7 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case USR_FAVORS:
id = (long) param[0];
page = (int) param[1];
if (adapter.isEmpty()) {
if (sinceId == 0) {
tweets = db.getUserFavs(id);
if (tweets.isEmpty()) {
tweets = mTwitter.getUserFavs(id, page);
@ -135,7 +129,7 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case TWEET_ANS:
id = (long) param[0];
String search = (String) param[1];
if (adapter.isEmpty()) {
if (sinceId == 0) {
tweets = db.getAnswers(id);
if (tweets.isEmpty()) {
tweets = mTwitter.getAnswers(search, id, sinceId);
@ -143,7 +137,6 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
db.storeReplies(tweets);
}
} else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getAnswers(search, id, sinceId);
if (!tweets.isEmpty() && db.containStatus(id))
db.storeReplies(tweets);
@ -152,20 +145,16 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case TWEET_SEARCH:
search = (String) param[0];
if (!adapter.isEmpty())
sinceId = adapter.getItemId(0);
tweets = mTwitter.searchTweets(search, sinceId);
break;
case LIST:
long listId = (long) param[0];
id = (long) param[0];
page = (int) param[1];
if (!adapter.isEmpty())
sinceId = adapter.getItemId(0);
tweets = mTwitter.getListTweets(listId, sinceId, page);
tweets = mTwitter.getListTweets(id, sinceId, page);
break;
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -177,23 +166,15 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
@Override
protected void onPostExecute(@Nullable List<Tweet> tweets) {
if (ui.get() != null) {
ui.get().setRefresh(false);
if (tweets != null) {
if (mode == Mode.USR_FAVORS)
adapter.add(tweets); // replace all items
ui.get().add(tweets);
else
adapter.addFirst(tweets);
ui.get().addTop(tweets);
} else if (twException != null) {
ui.get().onError(twException);
}
if (twException != null)
Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().setRefresh(false);
}
}
@Override
protected void onCancelled() {
if (ui.get() != null) {
ui.get().setRefresh(false);
}
}
}

View File

@ -1,21 +1,18 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.TweetDetail;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.Tweet;
import org.nuclearfog.twidda.database.AppDatabase;
import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.fragment.TweetFragment.RETURN_TWEET_CHANGED;
/**
* Background task to download tweet informations and to take actions
@ -31,7 +28,7 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
}
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private TwitterEngine mTwitter;
private WeakReference<TweetDetail> ui;
private AppDatabase db;
@ -89,7 +86,7 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
db.removeFavorite(tweetId);
break;
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
if (twException.statusNotFound()) {
db.removeStatus(tweetId);
@ -114,37 +111,9 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
protected void onPostExecute(@Nullable Tweet tweet) {
if (ui.get() != null) {
if (tweet != null) {
switch (action) {
case RETWEET:
if (tweet.retweeted())
Toast.makeText(ui.get(), R.string.info_tweet_retweeted, LENGTH_SHORT).show();
else
Toast.makeText(ui.get(), R.string.info_tweet_unretweeted, LENGTH_SHORT).show();
break;
case FAVORITE:
if (tweet.favored())
Toast.makeText(ui.get(), R.string.info_tweet_favored, LENGTH_SHORT).show();
else
Toast.makeText(ui.get(), R.string.info_tweet_unfavored, LENGTH_SHORT).show();
break;
case DELETE:
Toast.makeText(ui.get(), R.string.info_tweet_removed, LENGTH_SHORT).show();
ui.get().setResult(RETURN_TWEET_CHANGED);
ui.get().finish();
break;
}
}
if (twException != null) {
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
if (twException.isHardFault()) {
if (twException.statusNotFound())
ui.get().setResult(RETURN_TWEET_CHANGED);
ui.get().finish();
} else {
ui.get().finishIfEmpty();
}
ui.get().onAction(tweet, action);
} else if (twException != null) {
ui.get().onError(twException);
}
}
}

View File

@ -11,14 +11,14 @@ import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.TweetPopup;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TweetHolder;
import java.lang.ref.WeakReference;
import static android.os.AsyncTask.Status.RUNNING;
import static android.view.Window.FEATURE_NO_TITLE;
import static android.widget.Toast.LENGTH_LONG;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task for uploading tweet
@ -27,7 +27,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class TweetUploader extends AsyncTask<Void, Void, Boolean> {
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<TweetPopup> ui;
private WeakReference<Dialog> popup;
private TwitterEngine mTwitter;
@ -83,7 +83,7 @@ public class TweetUploader extends AsyncTask<Void, Void, Boolean> {
protected Boolean doInBackground(Void[] v) {
try {
mTwitter.uploadStatus(tweet);
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
return false;
} catch (Exception exception) {
@ -97,23 +97,12 @@ public class TweetUploader extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPostExecute(Boolean success) {
if (ui.get() != null && popup.get() != null) {
popup.get().dismiss();
if (success) {
Toast.makeText(ui.get(), R.string.info_tweet_sent, LENGTH_LONG).show();
ui.get().finish();
ui.get().onSuccess();
} else {
if (twException != null)
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().showErrorMsg(tweet);
ui.get().onError(tweet, twException);
}
popup.get().dismiss();
}
}
@Override
protected void onCancelled() {
if (popup.get() != null) {
popup.get().dismiss();
}
}
}

View File

@ -1,12 +1,11 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.adapter.ListAdapter;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterList;
import org.nuclearfog.twidda.fragment.ListFragment;
@ -14,8 +13,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/**
* Background task for downloading twitter lists created by a user
@ -31,23 +28,22 @@ public class TwitterListLoader extends AsyncTask<Long, Void, List<TwitterList>>
}
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<ListFragment> ui;
private TwitterEngine mTwitter;
private ListAdapter adapter;
private Action action;
public TwitterListLoader(ListFragment frag, Action action) {
ui = new WeakReference<>(frag);
mTwitter = TwitterEngine.getInstance(frag.getContext());
adapter = frag.getAdapter();
ui = new WeakReference<>(frag);
this.action = action;
}
@Override
protected void onPreExecute() {
if (ui.get() != null)
if (ui.get() != null) {
ui.get().setRefresh(true);
}
}
@Override
@ -69,7 +65,7 @@ public class TwitterListLoader extends AsyncTask<Long, Void, List<TwitterList>>
result.add(mTwitter.deleteUserList(param[0]));
return result;
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
}
return null;
@ -78,37 +74,26 @@ public class TwitterListLoader extends AsyncTask<Long, Void, List<TwitterList>>
@Override
protected void onPostExecute(@Nullable List<TwitterList> result) {
if (ui.get() != null) {
ui.get().setRefresh(false);
if (result != null) {
switch (action) {
case LOAD:
adapter.setData(result);
ui.get().setData(result);
break;
case FOLLOW:
TwitterList list = result.get(0);
adapter.updateItem(list);
if (list.isFollowing())
Toast.makeText(ui.get().getContext(), R.string.info_followed, LENGTH_SHORT).show();
else
Toast.makeText(ui.get().getContext(), R.string.info_unfollowed, LENGTH_SHORT).show();
ui.get().updateItem(list);
break;
case DELETE:
list = result.get(0);
adapter.removeItem(list.getId());
Toast.makeText(ui.get().getContext(), R.string.info_list_removed, LENGTH_SHORT).show();
ui.get().removeItem(list.getId());
break;
}
} else if (twException != null) {
ui.get().onError(twException);
}
if (twException != null)
Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().setRefresh(false);
}
}
@Override
protected void onCancelled() {
if (ui.get() != null)
ui.get().setRefresh(false);
}
}

View File

@ -1,12 +1,11 @@
package org.nuclearfog.twidda.backend;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.adapter.UserAdapter;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.fragment.UserFragment;
@ -14,8 +13,6 @@ import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/**
* download a list of user such as follower, following or searched users
* @see UserFragment
@ -33,17 +30,15 @@ public class UserListLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
}
@Nullable
private TwitterEngine.EngineException twException;
private EngineException twException;
private WeakReference<UserFragment> ui;
private TwitterEngine mTwitter;
private UserAdapter adapter;
private Mode mode;
public UserListLoader(UserFragment fragment, Mode mode) {
ui = new WeakReference<>(fragment);
mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter();
this.mode = mode;
}
@ -81,7 +76,7 @@ public class UserListLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
return mTwitter.getListMember((long) param[0]);
}
} catch (TwitterEngine.EngineException twException) {
} catch (EngineException twException) {
this.twException = twException;
} catch (Exception exception) {
exception.printStackTrace();
@ -93,30 +88,12 @@ public class UserListLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
@Override
protected void onPostExecute(@Nullable List<TwitterUser> users) {
if (ui.get() != null) {
ui.get().setRefresh(false);
if (users != null) {
adapter.replaceAll(users);
if (mode == Mode.FAVORIT)
Toast.makeText(ui.get().getContext(), R.string.info_not_implemented, Toast.LENGTH_SHORT).show();
} else if (twException != null)
Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().setRefresh(false);
}
}
@Override
protected void onCancelled() {
if (ui.get() != null)
ui.get().setRefresh(false);
}
@Override
protected void onCancelled(@Nullable List<TwitterUser> users) {
if (ui.get() != null) {
if (users != null)
adapter.replaceAll(users);
ui.get().setRefresh(false);
ui.get().setData(users);
} else if (twException != null) {
ui.get().onError(twException);
}
}
}
}

View File

@ -0,0 +1,175 @@
package org.nuclearfog.twidda.backend.engine;
import androidx.annotation.StringRes;
import org.nuclearfog.twidda.R;
import twitter4j.TwitterException;
public class EngineException extends Exception {
static final int FILENOTFOUND = 600;
static final int TOKENNOTSET = 601;
@StringRes
private int messageResource = 0;
private boolean errorDefined = true;
private boolean hardFault = false;
private boolean statusNotFound = false;
private boolean rateLimitExceeded = false;
private String retryAfterString = "";
/**
* Constructor for Twitter4J errors
*
* @param error Twitter4J Exception
*/
EngineException(TwitterException error) {
super(error);
switch (error.getErrorCode()) {
case 88:
case 420: //
case 429: // Rate limit exceeded!
rateLimitExceeded = true;
int retryAfter = error.getRetryAfter();
if (retryAfter >= 60)
retryAfterString = retryAfter / 60 + "m ";
retryAfterString += retryAfter % 60 + "s";
break;
case 17:
case 50: // USER not found
case 63: // USER suspended
messageResource = R.string.error_user_not_found;
statusNotFound = true;
hardFault = true;
break;
case 32:
messageResource = R.string.error_request_token;
break;
case 34: //
case 144: // TWEET not found
messageResource = R.string.error_not_found;
statusNotFound = true;
hardFault = true;
break;
case 150:
messageResource = R.string.error_send_dm;
break;
case 136:
case 179:
messageResource = R.string.info_not_authorized;
hardFault = true;
break;
case 186:
messageResource = R.string.error_status_too_long;
break;
case 187:
messageResource = R.string.error_duplicate_status;
break;
case 349:
messageResource = R.string.error_dm_send;
break;
case 354:
messageResource = R.string.error_dm_length;
break;
case 89:
messageResource = R.string.error_accesstoken;
break;
default:
errorDefined = false;
if (error.getStatusCode() == 401)
messageResource = R.string.info_not_authorized;
else
messageResource = R.string.error_connection_failed;
break;
}
}
/**
* Constructor for non Twitter4J errors
*
* @param errorCode custom error code
*/
EngineException(int errorCode) {
switch (errorCode) {
case FILENOTFOUND:
messageResource = R.string.error_media_not_found;
break;
case TOKENNOTSET:
messageResource = R.string.error_token_not_set;
break;
default:
messageResource = R.string.info_error;
break;
}
}
/**
* get String resource of error message
*
* @return string recource for
*/
@StringRes
public int getMessageResource() {
return messageResource;
}
/**
* check if error is defined by twitter exception
*
* @return true if error is defined
*/
public boolean isErrorDefined() {
return errorDefined;
}
/**
* return if activity should closed
*
* @return true if hard fault
*/
public boolean isHardFault() {
return hardFault;
}
/**
* return if tweet or author was not found
*
* @return true if author or tweet not found
*/
public boolean statusNotFound() {
return statusNotFound;
}
/**
* Check if rate limit of twitter is exceeded
*
* @return true if exceeded
*/
public boolean isRateLimitExceeded() {
return rateLimitExceeded;
}
/**
* get time to wait for new access
*
* @return time in seconds
*/
public String getRetryAfter() {
return retryAfterString;
}
}

View File

@ -1,12 +1,10 @@
package org.nuclearfog.twidda.backend;
package org.nuclearfog.twidda.backend.engine;
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import org.nuclearfog.twidda.BuildConfig;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.items.Message;
import org.nuclearfog.twidda.backend.items.MessageHolder;
import org.nuclearfog.twidda.backend.items.TrendLocation;
@ -157,7 +155,7 @@ public class TwitterEngine {
* @return Link to App Registration
* @throws EngineException if internet connection is unavailable
*/
String request() throws EngineException {
public String request() throws EngineException {
try {
if (reqToken == null)
reqToken = twitter.getOAuthRequestToken();
@ -174,7 +172,7 @@ public class TwitterEngine {
* @param twitterPin PIN for accessing account
* @throws EngineException if pin is false or request token is null
*/
void initialize(String twitterPin) throws EngineException {
public void initialize(String twitterPin) throws EngineException {
try {
if (reqToken != null) {
AccessToken accessToken = twitter.getOAuthAccessToken(reqToken, twitterPin);
@ -201,7 +199,7 @@ public class TwitterEngine {
* @return List of Tweets
* @throws EngineException if access is unavailable
*/
List<Tweet> getHome(int page, long lastId) throws EngineException {
public List<Tweet> getHome(int page, long lastId) throws EngineException {
try {
int load = settings.getRowLimit();
List<Status> homeTweets = twitter.getHomeTimeline(new Paging(page, load, lastId));
@ -220,7 +218,7 @@ public class TwitterEngine {
* @return List of Mention Tweets
* @throws EngineException if access is unavailable
*/
List<Tweet> getMention(int page, long id) throws EngineException {
public List<Tweet> getMention(int page, long id) throws EngineException {
try {
int load = settings.getRowLimit();
List<Status> mentions = twitter.getMentionsTimeline(new Paging(page, load, id));
@ -239,7 +237,7 @@ public class TwitterEngine {
* @return List of Tweets
* @throws EngineException if acces is unavailable
*/
List<Tweet> searchTweets(String search, long id) throws EngineException {
public List<Tweet> searchTweets(String search, long id) throws EngineException {
try {
int load = settings.getRowLimit();
Query q = new Query();
@ -262,7 +260,7 @@ public class TwitterEngine {
* @return Trend Resource
* @throws EngineException if access is unavailable
*/
List<TwitterTrend> getTrends(int woeId) throws EngineException {
public List<TwitterTrend> getTrends(int woeId) throws EngineException {
try {
int index = 1;
List<TwitterTrend> result = new LinkedList<>();
@ -282,7 +280,7 @@ public class TwitterEngine {
* @return list of locations
* @throws EngineException if access is unavailable
*/
List<TrendLocation> getLocations() throws EngineException {
public List<TrendLocation> getLocations() throws EngineException {
try {
List<TrendLocation> result = new LinkedList<>();
List<Location> locations = twitter.getAvailableTrends();
@ -302,7 +300,7 @@ public class TwitterEngine {
* @return List of Users
* @throws EngineException if access is unavailable
*/
List<TwitterUser> searchUsers(String search) throws EngineException {
public List<TwitterUser> searchUsers(String search) throws EngineException {
try {
return convertUserList(twitter.searchUsers(search, -1));
} catch (TwitterException err) {
@ -320,7 +318,7 @@ public class TwitterEngine {
* @return List of User Tweets
* @throws EngineException if access is unavailable
*/
List<Tweet> getUserTweets(long userId, long sinceId, int page) throws EngineException {
public List<Tweet> getUserTweets(long userId, long sinceId, int page) throws EngineException {
try {
int load = settings.getRowLimit();
Paging paging = new Paging(page, load, sinceId);
@ -339,7 +337,7 @@ public class TwitterEngine {
* @return List of User Favs
* @throws EngineException if access is unavailable
*/
List<Tweet> getUserFavs(long userId, int page) throws EngineException {
public List<Tweet> getUserFavs(long userId, int page) throws EngineException {
try {
int load = settings.getRowLimit();
Paging paging = new Paging(page, load);
@ -358,7 +356,7 @@ public class TwitterEngine {
* @return User Object
* @throws EngineException if Access is unavailable
*/
TwitterUser getUser(long userId) throws EngineException {
public TwitterUser getUser(long userId) throws EngineException {
try {
return new TwitterUser(twitter.showUser(userId));
} catch (TwitterException err) {
@ -373,7 +371,7 @@ public class TwitterEngine {
* @return curent user
* @throws EngineException if Access is unavailable
*/
TwitterUser getCurrentUser() throws EngineException {
public TwitterUser getCurrentUser() throws EngineException {
try {
return new TwitterUser(twitter.showUser(twitterID));
} catch (TwitterException err) {
@ -389,7 +387,7 @@ public class TwitterEngine {
* @return User Properties
* @throws EngineException if Connection is unavailable
*/
UserProperties getConnection(long userId) throws EngineException {
public UserProperties getConnection(long userId) throws EngineException {
try {
return new UserProperties(twitter.showFriendship(twitterID, userId));
} catch (TwitterException err) {
@ -405,7 +403,7 @@ public class TwitterEngine {
* @return Twitter User
* @throws EngineException if Access is unavailable
*/
TwitterUser followUser(long userID) throws EngineException {
public TwitterUser followUser(long userID) throws EngineException {
try {
return new TwitterUser(twitter.createFriendship(userID));
} catch (TwitterException err) {
@ -421,7 +419,7 @@ public class TwitterEngine {
* @return Twitter User
* @throws EngineException if Access is unavailable
*/
TwitterUser unfollowUser(long userID) throws EngineException {
public TwitterUser unfollowUser(long userID) throws EngineException {
try {
return new TwitterUser(twitter.destroyFriendship(userID));
} catch (TwitterException err) {
@ -437,7 +435,7 @@ public class TwitterEngine {
* @return Twitter User
* @throws EngineException if Access is unavailable
*/
TwitterUser blockUser(long UserID) throws EngineException {
public TwitterUser blockUser(long UserID) throws EngineException {
try {
return new TwitterUser(twitter.createBlock(UserID));
} catch (TwitterException err) {
@ -453,7 +451,7 @@ public class TwitterEngine {
* @return Twitter User
* @throws EngineException if Access is unavailable
*/
TwitterUser unblockUser(long UserID) throws EngineException {
public TwitterUser unblockUser(long UserID) throws EngineException {
try {
return new TwitterUser(twitter.destroyBlock(UserID));
} catch (TwitterException err) {
@ -469,7 +467,7 @@ public class TwitterEngine {
* @return Twitter User
* @throws EngineException if Access is unavailable
*/
TwitterUser muteUser(long UserID) throws EngineException {
public TwitterUser muteUser(long UserID) throws EngineException {
try {
return new TwitterUser(twitter.createMute(UserID));
} catch (TwitterException err) {
@ -485,7 +483,7 @@ public class TwitterEngine {
* @return Twitter User
* @throws EngineException if Access is unavailable
*/
TwitterUser unmuteUser(long UserID) throws EngineException {
public TwitterUser unmuteUser(long UserID) throws EngineException {
try {
return new TwitterUser(twitter.destroyMute(UserID));
} catch (TwitterException err) {
@ -501,7 +499,7 @@ public class TwitterEngine {
* @return List of Following User
* @throws EngineException if Access is unavailable
*/
List<TwitterUser> getFollowing(long userId) throws EngineException {
public List<TwitterUser> getFollowing(long userId) throws EngineException {
try {
int load = settings.getRowLimit();
IDs userIDs = twitter.getFriendsIDs(userId, -1, load);
@ -522,7 +520,7 @@ public class TwitterEngine {
* @return List of Follower
* @throws EngineException if Access is unavailable
*/
List<TwitterUser> getFollower(long userId) throws EngineException {
public List<TwitterUser> getFollower(long userId) throws EngineException {
try {
int load = settings.getRowLimit();
IDs userIDs = twitter.getFollowersIDs(userId, -1, load);
@ -542,7 +540,7 @@ public class TwitterEngine {
* @param tweet Tweet holder
* @throws EngineException if twitter service is unavailable or media was not found
*/
void uploadStatus(TweetHolder tweet) throws EngineException {
public void uploadStatus(TweetHolder tweet) throws EngineException {
try {
StatusUpdate mStatus = new StatusUpdate(tweet.getText());
if (tweet.isReply())
@ -570,7 +568,7 @@ public class TwitterEngine {
* @return Tweet Object
* @throws EngineException if Access is unavailable
*/
Tweet getStatus(long tweetId) throws EngineException {
public Tweet getStatus(long tweetId) throws EngineException {
try {
Status tweet = twitter.showStatus(tweetId);
return new Tweet(tweet);
@ -589,7 +587,7 @@ public class TwitterEngine {
* @return List of Answers
* @throws EngineException if Access is unavailable
*/
List<Tweet> getAnswers(String name, long tweetId, long sinceId) throws EngineException {
public List<Tweet> getAnswers(String name, long tweetId, long sinceId) throws EngineException {
try {
int load = settings.getRowLimit();
List<Status> answers = new LinkedList<>();
@ -615,7 +613,7 @@ public class TwitterEngine {
* @param tweetId Tweet ID
* @throws EngineException if Access is unavailable
*/
Tweet retweet(long tweetId) throws EngineException {
public Tweet retweet(long tweetId) throws EngineException {
try {
Status tweet = twitter.showStatus(tweetId);
boolean retweeted = tweet.isRetweeted();
@ -644,7 +642,7 @@ public class TwitterEngine {
* @param tweetId Tweet ID
* @throws EngineException if Access is unavailable
*/
Tweet favorite(long tweetId) throws EngineException {
public Tweet favorite(long tweetId) throws EngineException {
try {
Status tweet = twitter.showStatus(tweetId);
boolean retweeted = tweet.isRetweeted();
@ -672,7 +670,7 @@ public class TwitterEngine {
* @return dummy tweet
* @throws EngineException if Access is unavailable
*/
Tweet deleteTweet(long tweetId) throws EngineException {
public Tweet deleteTweet(long tweetId) throws EngineException {
try {
return new Tweet(twitter.destroyStatus(tweetId));
} catch (TwitterException err) {
@ -688,7 +686,7 @@ public class TwitterEngine {
* @return List of users or empty list if no match
* @throws EngineException if Access is unavailable
*/
List<TwitterUser> getRetweeter(long tweetID) throws EngineException {
public List<TwitterUser> getRetweeter(long tweetID) throws EngineException {
try {
int load = settings.getRowLimit();
Tweet embeddedStat = getStatus(tweetID).getEmbeddedTweet();
@ -710,7 +708,7 @@ public class TwitterEngine {
* @return DM List
* @throws EngineException if access is unavailable
*/
List<Message> getMessages() throws EngineException {
public List<Message> getMessages() throws EngineException {
try {
int load = settings.getRowLimit();
List<DirectMessage> dmList = twitter.getDirectMessages(load);
@ -731,7 +729,7 @@ public class TwitterEngine {
* @param messageHolder message informations
* @throws EngineException if access is unavailable
*/
void sendMessage(MessageHolder messageHolder) throws EngineException {
public void sendMessage(MessageHolder messageHolder) throws EngineException {
try {
long id = twitter.showUser(messageHolder.getUsername()).getId();
if (messageHolder.hasMedia()) {
@ -753,7 +751,7 @@ public class TwitterEngine {
* @param id Message ID
* @throws EngineException if Access is unavailable or message not found
*/
void deleteMessage(long id) throws EngineException {
public void deleteMessage(long id) throws EngineException {
try {
twitter.destroyDirectMessage(id);
} catch (TwitterException err) {
@ -769,7 +767,7 @@ public class TwitterEngine {
* @return updated user profile
* @throws EngineException if Access is unavailable
*/
TwitterUser updateProfile(UserHolder userHolder) throws EngineException {
public TwitterUser updateProfile(UserHolder userHolder) throws EngineException {
try {
if (userHolder.hasProfileImage()) {
File profileImage = new File(userHolder.getProfileImage());
@ -798,7 +796,7 @@ public class TwitterEngine {
* @return list information
* @throws EngineException if access is unavailable
*/
List<TwitterList> getUserList(long userId) throws EngineException {
public List<TwitterList> getUserList(long userId) throws EngineException {
try {
List<TwitterList> result = new LinkedList<>();
ResponseList<UserList> lists = twitter.getUserLists(userId);
@ -818,7 +816,7 @@ public class TwitterEngine {
* @return List information
* @throws EngineException if access is unavailable
*/
TwitterList followUserList(long listId) throws EngineException {
public TwitterList followUserList(long listId) throws EngineException {
try {
UserList list = twitter.showUserList(listId);
if (list.isFollowing()) {
@ -840,7 +838,7 @@ public class TwitterEngine {
* @return List information
* @throws EngineException if access is unavailable
*/
TwitterList deleteUserList(long listId) throws EngineException {
public TwitterList deleteUserList(long listId) throws EngineException {
try {
return new TwitterList(twitter.destroyUserList(listId), twitterID);
} catch (TwitterException err) {
@ -855,7 +853,7 @@ public class TwitterEngine {
* @return list of users following the list
* @throws EngineException if access is unavailable
*/
List<TwitterUser> getListFollower(long listId) throws EngineException {
public List<TwitterUser> getListFollower(long listId) throws EngineException {
try {
return convertUserList(twitter.getUserListSubscribers(listId, -1));
} catch (TwitterException err) {
@ -870,7 +868,7 @@ public class TwitterEngine {
* @return list of users
* @throws EngineException if access is unavailable
*/
List<TwitterUser> getListMember(long listId) throws EngineException {
public List<TwitterUser> getListMember(long listId) throws EngineException {
try {
return convertUserList(twitter.getUserListMembers(listId, -1));
} catch (TwitterException err) {
@ -888,7 +886,7 @@ public class TwitterEngine {
* @return list of tweets
* @throws EngineException if access is unavailable
*/
List<Tweet> getListTweets(long listId, long sinceId, int page) throws EngineException {
public List<Tweet> getListTweets(long listId, long sinceId, int page) throws EngineException {
try {
int load = settings.getRowLimit();
Paging paging = new Paging(page, load, sinceId);
@ -988,140 +986,4 @@ public class TwitterEngine {
throw new EngineException(EngineException.FILENOTFOUND);
}
}
/**
* Internal Exception
*/
public static class EngineException extends Exception {
private static final int FILENOTFOUND = 600;
private static final int TOKENNOTSET = 601;
@StringRes
private int messageResource;
private boolean hardFault = false;
private boolean statusNotFound = false;
/**
* Constructor for Twitter4J errors
*
* @param error Twitter4J Exception
*/
private EngineException(TwitterException error) {
super(error);
switch (error.getErrorCode()) {
case 88:
case 420: //
case 429: // Rate limit exceeded!
messageResource = R.string.error_limit_exceeded;
break;
case 17:
case 50: // USER not found
case 63: // USER suspended
messageResource = R.string.error_user_not_found;
statusNotFound = true;
hardFault = true;
break;
case 32:
messageResource = R.string.error_request_token;
break;
case 34: //
case 144: // TWEET not found
messageResource = R.string.error_not_found;
statusNotFound = true;
hardFault = true;
break;
case 150:
messageResource = R.string.error_send_dm;
break;
case 136:
case 179:
messageResource = R.string.info_not_authorized;
hardFault = true;
break;
case 186:
messageResource = R.string.error_status_too_long;
break;
case 187:
messageResource = R.string.error_duplicate_status;
break;
case 349:
messageResource = R.string.error_dm_send;
break;
case 354:
messageResource = R.string.error_dm_length;
break;
case 89:
messageResource = R.string.error_accesstoken;
break;
default:
if (error.getStatusCode() == 401)
messageResource = R.string.info_not_authorized;
else
messageResource = R.string.error_connection_failed;
break;
}
}
/**
* Constructor for non Twitter4J errors
*
* @param errorCode custom error code
*/
private EngineException(int errorCode) {
switch (errorCode) {
case FILENOTFOUND:
messageResource = R.string.error_media_not_found;
break;
case TOKENNOTSET:
messageResource = R.string.error_token_not_set;
break;
default:
messageResource = R.string.info_error;
break;
}
}
/**
* get String resource of error message
*
* @return string recource for
*/
@StringRes
int getMessageResource() {
return messageResource;
}
/**
* return if activity should closed
*
* @return true if hard fault
*/
boolean isHardFault() {
return hardFault;
}
/**
* return if tweet or author was not found
*
* @return true if author or tweet not found
*/
boolean statusNotFound() {
return statusNotFound;
}
}
}

View File

@ -7,6 +7,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog.Builder;
@ -23,11 +24,15 @@ import org.nuclearfog.twidda.activity.UserProfile;
import org.nuclearfog.twidda.adapter.ListAdapter;
import org.nuclearfog.twidda.adapter.ListAdapter.ListClickListener;
import org.nuclearfog.twidda.backend.TwitterListLoader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.TwitterList;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.ListDetail.KEY_LISTDETAIL_ID;
import static org.nuclearfog.twidda.activity.ListDetail.KEY_LISTDETAIL_NAME;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_ID;
@ -159,12 +164,37 @@ public class ListFragment extends Fragment implements OnRefreshListener, ListCli
}
}
public ListAdapter getAdapter() {
return adapter;
/**
* set data to list
*
* @param data List of Twitter list data
*/
public void setData(List<TwitterList> data) {
adapter.setData(data);
}
/**
* update item in list
*
* @param item Twitter list item
*/
public void updateItem(TwitterList item) {
adapter.updateItem(item);
}
/**
* remove item with specific ID
*
* @param id ID of list to remove
*/
public void removeItem(long id) {
adapter.removeItem(id);
}
/**
* called from {@link TwitterListLoader} to enable or disable RefreshLayout
* @param enable true to enable RefreshLayout with delay
*/
public void setRefresh(boolean enable) {
if (enable) {
reloadLayout.postDelayed(new Runnable() {
@ -179,6 +209,25 @@ public class ListFragment extends Fragment implements OnRefreshListener, ListCli
}
}
/**
* called from {@link TwitterListLoader} if an error occurs
*
* @param err Twitter exception
*/
public void onError(EngineException err) {
if (err.isErrorDefined()) {
if (err.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += err.getRetryAfter();
Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show();
}
}
private void load() {
listTask = new TwitterListLoader(this, LOAD);

View File

@ -27,9 +27,13 @@ import org.nuclearfog.twidda.adapter.MessageAdapter;
import org.nuclearfog.twidda.adapter.MessageAdapter.OnItemSelected;
import org.nuclearfog.twidda.backend.MessageListLoader;
import org.nuclearfog.twidda.backend.MessageListLoader.Mode;
import org.nuclearfog.twidda.backend.TrendListLoader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.Message;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
@ -149,12 +153,28 @@ public class MessageFragment extends Fragment implements OnRefreshListener, OnIt
}
}
public MessageAdapter getAdapter() {
return adapter;
/**
* set data to list
*
* @param data list of direct messages
*/
public void setData(List<Message> data) {
adapter.replaceAll(data);
}
/**
* remove item from list
*
* @param id ID of the item
*/
public void removeItem(long id) {
adapter.remove(id);
}
/**
* called from {@link TrendListLoader} to enable or disable RefreshLayout
* @param enable true to enable RefreshLayout with delay
*/
public void setRefresh(boolean enable) {
if (enable) {
reload.postDelayed(new Runnable() {
@ -169,6 +189,25 @@ public class MessageFragment extends Fragment implements OnRefreshListener, OnIt
}
}
/**
* called from {@link MessageListLoader} if an error occurs
*
* @param err Twitter exception
*/
public void onError(EngineException err) {
if (err.isErrorDefined()) {
if (err.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += err.getRetryAfter();
Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show();
}
}
private void load(Mode m) {
messageTask = new MessageListLoader(this, m);

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
@ -14,16 +15,21 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.SearchPage;
import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver;
import org.nuclearfog.twidda.adapter.TrendAdapter;
import org.nuclearfog.twidda.adapter.TrendAdapter.TrendClickListener;
import org.nuclearfog.twidda.backend.TrendListLoader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.TwitterTrend;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.SearchPage.KEY_SEARCH_QUERY;
@ -115,12 +121,48 @@ public class TrendFragment extends Fragment implements OnRefreshListener, TrendC
load();
}
/**
* set trend data to list
*
* @param data Trend data
*/
public void setData(List<TwitterTrend> data) {
adapter.setData(data);
}
public TrendAdapter getAdapter() {
return adapter;
/**
* check if list is empty
*
* @return true if list is empty
*/
public boolean isEmpty() {
return adapter == null || adapter.isEmpty();
}
/**
* called from {@link TrendListLoader} if an error occurs
*
* @param err Twitter exception
*/
public void onError(EngineException err) {
if (err.isErrorDefined()) {
if (err.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += err.getRetryAfter();
Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show();
}
}
/**
* called from {@link TrendListLoader} to enable or disable RefreshLayout
* @param enable true to enable RefreshLayout with delay
*/
public void setRefresh(boolean enable) {
if (enable) {
reload.postDelayed(new Runnable() {

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
@ -14,17 +15,22 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.TweetDetail;
import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver;
import org.nuclearfog.twidda.adapter.TweetAdapter;
import org.nuclearfog.twidda.adapter.TweetAdapter.TweetClickListener;
import org.nuclearfog.twidda.backend.TweetListLoader;
import org.nuclearfog.twidda.backend.TweetListLoader.Mode;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.Tweet;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.TweetDetail.KEY_TWEET_ID;
import static org.nuclearfog.twidda.activity.TweetDetail.KEY_TWEET_NAME;
@ -154,12 +160,39 @@ public class TweetFragment extends Fragment implements OnRefreshListener, TweetC
tweetTask = null;
}
public TweetAdapter getAdapter() {
return adapter;
/**
* get Id of the first Tweet
*
* @return ID of the first tweet or zero if list is empty
*/
public long getTopId() {
if (adapter != null && !adapter.isEmpty())
return adapter.getItemId(0);
return 0;
}
/**
* replace all tweets of the list
*
* @param tweets list of new tweets
*/
public void add(List<Tweet> tweets) {
adapter.add(tweets);
}
/**
* attach new tweets to the top of the list
*
* @param tweets list of new tweets
*/
public void addTop(List<Tweet> tweets) {
adapter.addFirst(tweets);
}
/**
* called from {@link TweetListLoader} to enable or disable RefreshLayout
* @param enable true to enable RefreshLayout with delay
*/
public void setRefresh(boolean enable) {
if (enable) {
reload.postDelayed(new Runnable() {
@ -174,6 +207,25 @@ public class TweetFragment extends Fragment implements OnRefreshListener, TweetC
}
}
/**
* called from {@link TweetListLoader} if an error occurs
*
* @param err Twitter exception
*/
public void onError(EngineException err) {
if (err.isErrorDefined()) {
if (err.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += err.getRetryAfter();
Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show();
}
}
private void load() {
switch (mode) {

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
@ -14,17 +15,22 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.UserProfile;
import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver;
import org.nuclearfog.twidda.adapter.UserAdapter;
import org.nuclearfog.twidda.adapter.UserAdapter.UserClickListener;
import org.nuclearfog.twidda.backend.UserListLoader;
import org.nuclearfog.twidda.backend.UserListLoader.Mode;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.UserProfile.KEY_PROFILE_ID;
@ -123,12 +129,19 @@ public class UserFragment extends Fragment implements OnRefreshListener, UserCli
public void onDataClear() {
}
public UserAdapter getAdapter() {
return adapter;
/**
* set List data
*
* @param data list of twitter users
*/
public void setData(List<TwitterUser> data) {
adapter.replaceAll(data);
}
/**
* called from {@link UserListLoader} to enable or disable RefreshLayout
* @param enable true to enable RefreshLayout with delay
*/
public void setRefresh(boolean enable) {
if (enable) {
reload.postDelayed(new Runnable() {
@ -143,6 +156,25 @@ public class UserFragment extends Fragment implements OnRefreshListener, UserCli
}
}
/**
* called when an error occurs
*
* @param error Engine exception
*/
public void onError(EngineException error) {
if (error.isErrorDefined()) {
if (error.isRateLimitExceeded()) {
String errorMsg = getString(R.string.error_limit_exceeded);
errorMsg += error.getRetryAfter();
Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), error.getMessageResource(), LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), error.getMessage(), LENGTH_SHORT).show();
}
}
private void load() {
switch (mode) {

View File

@ -22,7 +22,7 @@
<string name="error_connection">Keine Internetverbindung!</string>
<string name="error_enter_pin">PIN eingeben!</string>
<string name="confirm_delete_database">Datenbank löschen?</string>
<string name="error_limit_exceeded">Anfragelimit erreicht!</string>
<string name="error_limit_exceeded">"Anfragelimit erreicht! Entsperrt nach: "</string>
<string name="error_sending_tweet">Fehler beim Senden!</string>
<string name="info_tweet_sent">Tweet gesendet</string>
<string name="info_error">Fehler!</string>

View File

@ -30,7 +30,7 @@
<string name="error_connection">connection failed</string>
<string name="error_enter_pin">Enter PIN!</string>
<string name="confirm_delete_database">delete database?</string>
<string name="error_limit_exceeded">"Rate limit exceeded!"</string>
<string name="error_limit_exceeded">"Rate limit exceeded! Retry after: "</string>
<string name="error_sending_tweet">error while sending</string>
<string name="info_tweet_sent">tweet sent</string>
<string name="info_error">Error!</string>