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.NumberPicker;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog.Builder; import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.app.AppCompatActivity; 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.FontAdapter;
import org.nuclearfog.twidda.adapter.LocationAdapter; import org.nuclearfog.twidda.adapter.LocationAdapter;
import org.nuclearfog.twidda.backend.LocationListLoader; 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.helper.FontTool;
import org.nuclearfog.twidda.backend.items.TrendLocation; import org.nuclearfog.twidda.backend.items.TrendLocation;
import org.nuclearfog.twidda.database.DatabaseAdapter; 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.os.AsyncTask.Status.RUNNING;
import static android.view.View.GONE; 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.APP_LOGOUT;
import static org.nuclearfog.twidda.activity.MainActivity.DB_CLEARED; import static org.nuclearfog.twidda.activity.MainActivity.DB_CLEARED;
@ -347,6 +350,20 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
locationSpinner.setSelection(position); 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) { private void setColor(int preColor) {
color_dialog_selector = ColorPickerDialogBuilder.with(this) color_dialog_selector = ColorPickerDialogBuilder.with(this)

View File

@ -1,5 +1,6 @@
package org.nuclearfog.twidda.activity; package org.nuclearfog.twidda.activity;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -11,11 +12,13 @@ import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.Registration; import org.nuclearfog.twidda.backend.Registration;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.helper.FontTool;
import org.nuclearfog.twidda.database.GlobalSettings; import org.nuclearfog.twidda.database.GlobalSettings;
@ -87,7 +90,7 @@ public class LoginPage extends AppCompatActivity implements OnClickListener {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.login_setting) { if (item.getItemId() == R.id.login_setting) {
Intent settings = new Intent(this, AppSettings.class); Intent settings = new Intent(this, AppSettings.class);
startActivity(settings); startActivity(settings);
@ -136,4 +139,19 @@ public class LoginPage extends AppCompatActivity implements OnClickListener {
else else
Toast.makeText(this, R.string.error_connection, LENGTH_SHORT).show(); 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 @Override
public void onTabReselected(Tab tab) { 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.R;
import org.nuclearfog.twidda.backend.MessageUploader; 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.helper.FontTool;
import org.nuclearfog.twidda.backend.items.MessageHolder; import org.nuclearfog.twidda.backend.items.MessageHolder;
import org.nuclearfog.twidda.database.GlobalSettings; 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() { private void getMedia() {
boolean accessGranted = true; boolean accessGranted = true;

View File

@ -27,6 +27,7 @@ import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.ProfileUpdater; 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.helper.FontTool;
import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserHolder; 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.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
import static android.view.View.INVISIBLE; import static android.view.View.INVISIBLE;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.UserProfile.RETURN_PROFILE_CHANGED;
public class ProfileEditor extends AppCompatActivity implements OnClickListener { 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 EditText name, link, loc, bio;
private Button add_banner_btn; private Button add_banner_btn;
private String profileLink, bannerLink; private String profileLink, bannerLink;
private boolean userSet = false;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -208,6 +211,32 @@ public class ProfileEditor extends AppCompatActivity implements OnClickListener
link.setText(user.getLink()); link.setText(user.getLink());
loc.setText(user.getLocation()); loc.setText(user.getLocation());
bio.setText(user.getBio()); 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 @Override
public void onTabUnselected(Tab tab) { public void onTabUnselected(Tab tab) {
if (adapter != null)
adapter.scrollToTop(tab.getPosition()); adapter.scrollToTop(tab.getPosition());
} }
@Override @Override
public void onTabReselected(Tab tab) { 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.adapter.FragmentAdapter.AdapterType;
import org.nuclearfog.twidda.backend.TweetLoader; import org.nuclearfog.twidda.backend.TweetLoader;
import org.nuclearfog.twidda.backend.TweetLoader.Action; 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.FontTool;
import org.nuclearfog.twidda.backend.helper.StringTools; import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.items.Tweet; 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_ID;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_MODE; import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_MODE;
import static org.nuclearfog.twidda.activity.UserDetail.USERLIST_RETWEETS; 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, 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) { if (tweet == null) {
finish(); finish();
} }

View File

@ -24,6 +24,7 @@ import androidx.appcompat.app.AppCompatActivity;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.TweetUploader; 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.FontTool;
import org.nuclearfog.twidda.backend.helper.StringTools; import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.helper.StringTools.FileType; import org.nuclearfog.twidda.backend.helper.StringTools.FileType;
@ -288,15 +289,27 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
locationBtn.setVisibility(VISIBLE); 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 * Show confirmation dialog if an error occurs while sending tweet
*
* @param tweet tweet to re-send * @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); 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() { .setPositiveButton(R.string.confirm_retry, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { 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;
import org.nuclearfog.twidda.adapter.FragmentAdapter.AdapterType; import org.nuclearfog.twidda.adapter.FragmentAdapter.AdapterType;
import org.nuclearfog.twidda.backend.ProfileLoader; 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.helper.FontTool;
import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserProperties; import org.nuclearfog.twidda.backend.items.UserProperties;
@ -452,12 +453,15 @@ public class UserProfile extends AppCompatActivity implements OnClickListener,
@Override @Override
public void onTabUnselected(Tab tab) { public void onTabUnselected(Tab tab) {
if (adapter != null)
adapter.scrollToTop(tab.getPosition()); adapter.scrollToTop(tab.getPosition());
} }
@Override @Override
public void onTabReselected(Tab tab) { 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 * Set User Relationship
*
* @param properties relationship to the current user * @param properties relationship to the current user
*/ */
public void setConnection(UserProperties properties) { public void setConnection(UserProperties properties) {
this.properties = properties; this.properties = properties;
invalidateOptionsMenu(); 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 { public interface FragmentChangeObserver {
/**
* called if settings changed to refresh fragments
*/
void onSettingsChange(); void onSettingsChange();
/**
* called when the current tab changes
*/
void onTabChange(); void onTabChange();
/**
* called to clear the lists
*/
void onDataClear(); void onDataClear();
} }
} }

View File

@ -1,18 +1,17 @@
package org.nuclearfog.twidda.backend; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.nuclearfog.twidda.activity.AppSettings; 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 org.nuclearfog.twidda.backend.items.TrendLocation;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; 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 * Background task to load location information used by twitter such as location names and world ID's
* @see AppSettings * @see AppSettings
@ -20,7 +19,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation>> { public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation>> {
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private WeakReference<AppSettings> ui; private WeakReference<AppSettings> ui;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
@ -35,7 +34,7 @@ public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation
protected List<TrendLocation> doInBackground(Void[] v) { protected List<TrendLocation> doInBackground(Void[] v) {
try { try {
return mTwitter.getLocations(); return mTwitter.getLocations();
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} catch (Exception exception) { } catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
@ -50,7 +49,7 @@ public class LocationListLoader extends AsyncTask<Void, Void, List<TrendLocation
if (locations != null && !locations.isEmpty()) { if (locations != null && !locations.isEmpty()) {
ui.get().setLocationData(locations); ui.get().setLocationData(locations);
} else if (twException != null) { } 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; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable; 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.backend.items.Message;
import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.fragment.MessageFragment; import org.nuclearfog.twidda.fragment.MessageFragment;
@ -13,12 +13,9 @@ import org.nuclearfog.twidda.fragment.MessageFragment;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* task to download a direct message list from twitter and handle message actions * task to download a direct message list from twitter and handle message actions
*
* @see MessageFragment * @see MessageFragment
*/ */
public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> { public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
@ -30,12 +27,11 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
} }
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private Mode mode; private Mode mode;
private WeakReference<MessageFragment> ui; private WeakReference<MessageFragment> ui;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private AppDatabase db; private AppDatabase db;
private MessageAdapter adapter;
private long id; private long id;
@ -43,16 +39,16 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
ui = new WeakReference<>(fragment); ui = new WeakReference<>(fragment);
db = new AppDatabase(fragment.getContext()); db = new AppDatabase(fragment.getContext());
mTwitter = TwitterEngine.getInstance(fragment.getContext()); mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter();
this.mode = mode; this.mode = mode;
} }
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
if (ui.get() != null) if (ui.get() != null) {
ui.get().setRefresh(true); ui.get().setRefresh(true);
} }
}
@Override @Override
@ -81,7 +77,7 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
db.deleteDm(messageId); db.deleteDm(messageId);
break; break;
} }
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
if (twException.statusNotFound()) if (twException.statusNotFound())
db.deleteDm(messageId); db.deleteDm(messageId);
@ -95,22 +91,17 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
@Override @Override
protected void onPostExecute(@Nullable List<Message> messages) { protected void onPostExecute(@Nullable List<Message> messages) {
if (ui.get() != null) { if (ui.get() != null) {
if (messages != null) if (messages != null) {
adapter.replaceAll(messages); ui.get().setData(messages);
else if (twException != null) { } else if (twException != null) {
Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show(); ui.get().onError(twException);
if (twException.statusNotFound()) if (twException.statusNotFound()) {
adapter.remove(id); ui.get().removeItem(id);
} else if (mode == Mode.DEL) }
adapter.remove(id); } else if (mode == Mode.DEL) {
ui.get().removeItem(id);
}
ui.get().setRefresh(false); 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.R;
import org.nuclearfog.twidda.activity.MessagePopup; 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 org.nuclearfog.twidda.backend.items.MessageHolder;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* Background task to send a direct messages to a user * Background task to send a direct messages to a user
* @see MessagePopup * @see MessagePopup
@ -25,7 +25,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class MessageUploader extends AsyncTask<Void, Void, Boolean> { public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private WeakReference<MessagePopup> ui; private WeakReference<MessagePopup> ui;
private WeakReference<Dialog> popup; private WeakReference<Dialog> popup;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
@ -34,13 +34,13 @@ public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
/** /**
* send direct message * send direct message
* *
* @param c Activity context * @param context Activity context
* @param message message to send * @param message message to send
*/ */
public MessageUploader(@NonNull MessagePopup c, MessageHolder message) { public MessageUploader(@NonNull MessagePopup context, MessageHolder message) {
ui = new WeakReference<>(c); ui = new WeakReference<>(context);
popup = new WeakReference<>(new Dialog(c)); popup = new WeakReference<>(new Dialog(context));
mTwitter = TwitterEngine.getInstance(c); mTwitter = TwitterEngine.getInstance(context);
this.message = message; this.message = message;
} }
@ -81,7 +81,7 @@ public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
try { try {
mTwitter.sendMessage(message); mTwitter.sendMessage(message);
return true; return true;
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} catch (Exception exception) { } catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
@ -93,14 +93,12 @@ public class MessageUploader extends AsyncTask<Void, Void, Boolean> {
@Override @Override
protected void onPostExecute(Boolean success) { protected void onPostExecute(Boolean success) {
if (ui.get() != null && popup.get() != null) { 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(); 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; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.UserProfile; 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.TwitterUser;
import org.nuclearfog.twidda.backend.items.UserProperties; import org.nuclearfog.twidda.backend.items.UserProperties;
import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.database.AppDatabase;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* task for loading user profile information and take actions * task for loading user profile information and take actions
* @see UserProfile * @see UserProfile
@ -32,7 +30,7 @@ public class ProfileLoader extends AsyncTask<Long, TwitterUser, UserProperties>
private final Action action; private final Action action;
private WeakReference<UserProfile> ui; private WeakReference<UserProfile> ui;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private TwitterEngine.EngineException twException; private EngineException twException;
private AppDatabase db; private AppDatabase db;
@ -100,7 +98,7 @@ public class ProfileLoader extends AsyncTask<Long, TwitterUser, UserProperties>
publishProgress(user); publishProgress(user);
return mTwitter.getConnection(userId); return mTwitter.getConnection(userId);
} }
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} catch (Exception exception) { } catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
@ -123,31 +121,9 @@ public class ProfileLoader extends AsyncTask<Long, TwitterUser, UserProperties>
if (ui.get() != null) { if (ui.get() != null) {
if (properties != null) { if (properties != null) {
ui.get().setConnection(properties); ui.get().setConnection(properties);
switch (action) { ui.get().onAction(properties, action);
case ACTION_FOLLOW: } else if (twException != null) {
if (properties.isFriend()) ui.get().onError(twException);
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();
} }
} }
} }

View File

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

View File

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

View File

@ -1,12 +1,12 @@
package org.nuclearfog.twidda.backend; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; 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.backend.items.TwitterTrend;
import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.fragment.TrendFragment; import org.nuclearfog.twidda.fragment.TrendFragment;
@ -14,8 +14,6 @@ import org.nuclearfog.twidda.fragment.TrendFragment;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* Background task to load a list of location specific trends * 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>> { public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>> {
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private WeakReference<TrendFragment> ui; private WeakReference<TrendFragment> ui;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private AppDatabase db; private AppDatabase db;
private TrendAdapter adapter; private boolean isEmpty;
public TrendListLoader(@NonNull TrendFragment fragment) { public TrendListLoader(@NonNull TrendFragment fragment) {
ui = new WeakReference<>(fragment); ui = new WeakReference<>(fragment);
db = new AppDatabase(fragment.getContext()); db = new AppDatabase(fragment.getContext());
mTwitter = TwitterEngine.getInstance(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; List<TwitterTrend> trends;
int woeId = param[0]; int woeId = param[0];
try { try {
if (adapter.isEmpty()) { if (isEmpty) {
trends = db.getTrends(woeId); trends = db.getTrends(woeId);
if (trends.isEmpty()) { if (trends.isEmpty()) {
trends = mTwitter.getTrends(woeId); trends = mTwitter.getTrends(woeId);
@ -63,7 +61,7 @@ public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>
db.storeTrends(trends, woeId); db.storeTrends(trends, woeId);
} }
return trends; return trends;
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} catch (Exception exception) { } catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
@ -75,18 +73,12 @@ public class TrendListLoader extends AsyncTask<Integer, Void, List<TwitterTrend>
@Override @Override
protected void onPostExecute(@Nullable List<TwitterTrend> trends) { protected void onPostExecute(@Nullable List<TwitterTrend> trends) {
if (ui.get() != null) { 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); 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; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable; 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.backend.items.Tweet;
import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.database.AppDatabase;
import org.nuclearfog.twidda.fragment.TweetFragment; import org.nuclearfog.twidda.fragment.TweetFragment;
@ -13,8 +13,6 @@ import org.nuclearfog.twidda.fragment.TweetFragment;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* Background task to download a list of tweets from different sources * 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 @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private Mode mode;
private WeakReference<TweetFragment> ui; private WeakReference<TweetFragment> ui;
private TweetAdapter adapter;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private AppDatabase db; private AppDatabase db;
private Mode mode;
private long sinceId;
public TweetListLoader(TweetFragment fragment, Mode mode) { public TweetListLoader(TweetFragment fragment, Mode mode) {
ui = new WeakReference<>(fragment); ui = new WeakReference<>(fragment);
db = new AppDatabase(fragment.getContext()); db = new AppDatabase(fragment.getContext());
mTwitter = TwitterEngine.getInstance(fragment.getContext()); mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter(); sinceId = fragment.getTopId();
this.mode = mode; this.mode = mode;
} }
@ -63,19 +61,17 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
@Override @Override
protected List<Tweet> doInBackground(Object[] param) { protected List<Tweet> doInBackground(Object[] param) {
List<Tweet> tweets = null; List<Tweet> tweets = null;
long sinceId = 1;
try { try {
switch (mode) { switch (mode) {
case TL_HOME: case TL_HOME:
int page = (int) param[0]; int page = (int) param[0];
if (adapter.isEmpty()) { if (sinceId == 0) {
tweets = db.getHomeTimeline(); tweets = db.getHomeTimeline();
if (tweets.isEmpty()) { if (tweets.isEmpty()) {
tweets = mTwitter.getHome(page, sinceId); tweets = mTwitter.getHome(page, sinceId);
db.storeHomeTimeline(tweets); db.storeHomeTimeline(tweets);
} }
} else { } else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getHome(page, sinceId); tweets = mTwitter.getHome(page, sinceId);
db.storeHomeTimeline(tweets); db.storeHomeTimeline(tweets);
} }
@ -83,14 +79,13 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case TL_MENT: case TL_MENT:
page = (int) param[0]; page = (int) param[0];
if (adapter.isEmpty()) { if (sinceId == 0) {
tweets = db.getMentions(); tweets = db.getMentions();
if (tweets.isEmpty()) { if (tweets.isEmpty()) {
tweets = mTwitter.getMention(page, sinceId); tweets = mTwitter.getMention(page, sinceId);
db.storeMentions(tweets); db.storeMentions(tweets);
} }
} else { } else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getMention(page, sinceId); tweets = mTwitter.getMention(page, sinceId);
db.storeMentions(tweets); db.storeMentions(tweets);
} }
@ -99,14 +94,13 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case USR_TWEETS: case USR_TWEETS:
long id = (long) param[0]; long id = (long) param[0];
page = (int) param[1]; page = (int) param[1];
if (adapter.isEmpty()) { if (sinceId == 0) {
tweets = db.getUserTweets(id); tweets = db.getUserTweets(id);
if (tweets.isEmpty()) { if (tweets.isEmpty()) {
tweets = mTwitter.getUserTweets(id, sinceId, page); tweets = mTwitter.getUserTweets(id, sinceId, page);
db.storeUserTweets(tweets); db.storeUserTweets(tweets);
} }
} else { } else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getUserTweets(id, sinceId, page); tweets = mTwitter.getUserTweets(id, sinceId, page);
db.storeUserTweets(tweets); db.storeUserTweets(tweets);
} }
@ -115,7 +109,7 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case USR_FAVORS: case USR_FAVORS:
id = (long) param[0]; id = (long) param[0];
page = (int) param[1]; page = (int) param[1];
if (adapter.isEmpty()) { if (sinceId == 0) {
tweets = db.getUserFavs(id); tweets = db.getUserFavs(id);
if (tweets.isEmpty()) { if (tweets.isEmpty()) {
tweets = mTwitter.getUserFavs(id, page); tweets = mTwitter.getUserFavs(id, page);
@ -135,7 +129,7 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case TWEET_ANS: case TWEET_ANS:
id = (long) param[0]; id = (long) param[0];
String search = (String) param[1]; String search = (String) param[1];
if (adapter.isEmpty()) { if (sinceId == 0) {
tweets = db.getAnswers(id); tweets = db.getAnswers(id);
if (tweets.isEmpty()) { if (tweets.isEmpty()) {
tweets = mTwitter.getAnswers(search, id, sinceId); tweets = mTwitter.getAnswers(search, id, sinceId);
@ -143,7 +137,6 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
db.storeReplies(tweets); db.storeReplies(tweets);
} }
} else { } else {
sinceId = adapter.getItemId(0);
tweets = mTwitter.getAnswers(search, id, sinceId); tweets = mTwitter.getAnswers(search, id, sinceId);
if (!tweets.isEmpty() && db.containStatus(id)) if (!tweets.isEmpty() && db.containStatus(id))
db.storeReplies(tweets); db.storeReplies(tweets);
@ -152,20 +145,16 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
case TWEET_SEARCH: case TWEET_SEARCH:
search = (String) param[0]; search = (String) param[0];
if (!adapter.isEmpty())
sinceId = adapter.getItemId(0);
tweets = mTwitter.searchTweets(search, sinceId); tweets = mTwitter.searchTweets(search, sinceId);
break; break;
case LIST: case LIST:
long listId = (long) param[0]; id = (long) param[0];
page = (int) param[1]; page = (int) param[1];
if (!adapter.isEmpty()) tweets = mTwitter.getListTweets(id, sinceId, page);
sinceId = adapter.getItemId(0);
tweets = mTwitter.getListTweets(listId, sinceId, page);
break; break;
} }
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} catch (Exception exception) { } catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
@ -177,23 +166,15 @@ public class TweetListLoader extends AsyncTask<Object, Void, List<Tweet>> {
@Override @Override
protected void onPostExecute(@Nullable List<Tweet> tweets) { protected void onPostExecute(@Nullable List<Tweet> tweets) {
if (ui.get() != null) { if (ui.get() != null) {
ui.get().setRefresh(false);
if (tweets != null) { if (tweets != null) {
if (mode == Mode.USR_FAVORS) if (mode == Mode.USR_FAVORS)
adapter.add(tweets); // replace all items ui.get().add(tweets);
else 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; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.TweetDetail; 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.backend.items.Tweet;
import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.database.AppDatabase;
import java.lang.ref.WeakReference; 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 * Background task to download tweet informations and to take actions
@ -31,7 +28,7 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
} }
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private WeakReference<TweetDetail> ui; private WeakReference<TweetDetail> ui;
private AppDatabase db; private AppDatabase db;
@ -89,7 +86,7 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
db.removeFavorite(tweetId); db.removeFavorite(tweetId);
break; break;
} }
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
if (twException.statusNotFound()) { if (twException.statusNotFound()) {
db.removeStatus(tweetId); db.removeStatus(tweetId);
@ -114,37 +111,9 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
protected void onPostExecute(@Nullable Tweet tweet) { protected void onPostExecute(@Nullable Tweet tweet) {
if (ui.get() != null) { if (ui.get() != null) {
if (tweet != null) { if (tweet != null) {
switch (action) { ui.get().onAction(tweet, action);
case RETWEET: } else if (twException != null) {
if (tweet.retweeted()) ui.get().onError(twException);
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();
}
} }
} }
} }

View File

@ -11,14 +11,14 @@ import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.TweetPopup; 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 org.nuclearfog.twidda.backend.items.TweetHolder;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import static android.os.AsyncTask.Status.RUNNING; import static android.os.AsyncTask.Status.RUNNING;
import static android.view.Window.FEATURE_NO_TITLE; 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 * Background task for uploading tweet
@ -27,7 +27,7 @@ import static android.widget.Toast.LENGTH_SHORT;
public class TweetUploader extends AsyncTask<Void, Void, Boolean> { public class TweetUploader extends AsyncTask<Void, Void, Boolean> {
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private WeakReference<TweetPopup> ui; private WeakReference<TweetPopup> ui;
private WeakReference<Dialog> popup; private WeakReference<Dialog> popup;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
@ -83,7 +83,7 @@ public class TweetUploader extends AsyncTask<Void, Void, Boolean> {
protected Boolean doInBackground(Void[] v) { protected Boolean doInBackground(Void[] v) {
try { try {
mTwitter.uploadStatus(tweet); mTwitter.uploadStatus(tweet);
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
return false; return false;
} catch (Exception exception) { } catch (Exception exception) {
@ -97,23 +97,12 @@ public class TweetUploader extends AsyncTask<Void, Void, Boolean> {
@Override @Override
protected void onPostExecute(Boolean success) { protected void onPostExecute(Boolean success) {
if (ui.get() != null && popup.get() != null) { if (ui.get() != null && popup.get() != null) {
popup.get().dismiss();
if (success) { if (success) {
Toast.makeText(ui.get(), R.string.info_tweet_sent, LENGTH_LONG).show(); ui.get().onSuccess();
ui.get().finish();
} else { } else {
if (twException != null) ui.get().onError(tweet, twException);
Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show();
ui.get().showErrorMsg(tweet);
} }
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; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.adapter.ListAdapter; import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterList; import org.nuclearfog.twidda.backend.items.TwitterList;
import org.nuclearfog.twidda.fragment.ListFragment; import org.nuclearfog.twidda.fragment.ListFragment;
@ -14,8 +13,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* Background task for downloading twitter lists created by a user * Background task for downloading twitter lists created by a user
@ -31,24 +28,23 @@ public class TwitterListLoader extends AsyncTask<Long, Void, List<TwitterList>>
} }
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private WeakReference<ListFragment> ui; private WeakReference<ListFragment> ui;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private ListAdapter adapter;
private Action action; private Action action;
public TwitterListLoader(ListFragment frag, Action action) { public TwitterListLoader(ListFragment frag, Action action) {
ui = new WeakReference<>(frag);
mTwitter = TwitterEngine.getInstance(frag.getContext()); mTwitter = TwitterEngine.getInstance(frag.getContext());
adapter = frag.getAdapter(); ui = new WeakReference<>(frag);
this.action = action; this.action = action;
} }
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
if (ui.get() != null) if (ui.get() != null) {
ui.get().setRefresh(true); ui.get().setRefresh(true);
} }
}
@Override @Override
protected List<TwitterList> doInBackground(Long[] param) { protected List<TwitterList> doInBackground(Long[] param) {
@ -69,7 +65,7 @@ public class TwitterListLoader extends AsyncTask<Long, Void, List<TwitterList>>
result.add(mTwitter.deleteUserList(param[0])); result.add(mTwitter.deleteUserList(param[0]));
return result; return result;
} }
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} }
return null; return null;
@ -78,37 +74,26 @@ public class TwitterListLoader extends AsyncTask<Long, Void, List<TwitterList>>
@Override @Override
protected void onPostExecute(@Nullable List<TwitterList> result) { protected void onPostExecute(@Nullable List<TwitterList> result) {
if (ui.get() != null) { if (ui.get() != null) {
ui.get().setRefresh(false);
if (result != null) { if (result != null) {
switch (action) { switch (action) {
case LOAD: case LOAD:
adapter.setData(result); ui.get().setData(result);
break; break;
case FOLLOW: case FOLLOW:
TwitterList list = result.get(0); TwitterList list = result.get(0);
adapter.updateItem(list); ui.get().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();
break; break;
case DELETE: case DELETE:
list = result.get(0); list = result.get(0);
adapter.removeItem(list.getId()); ui.get().removeItem(list.getId());
Toast.makeText(ui.get().getContext(), R.string.info_list_removed, LENGTH_SHORT).show();
break; break;
} }
} } else if (twException != null) {
if (twException != null) ui.get().onError(twException);
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; package org.nuclearfog.twidda.backend;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.adapter.UserAdapter; import org.nuclearfog.twidda.backend.engine.TwitterEngine;
import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.fragment.UserFragment; import org.nuclearfog.twidda.fragment.UserFragment;
@ -14,8 +13,6 @@ import java.lang.ref.WeakReference;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import static android.widget.Toast.LENGTH_SHORT;
/** /**
* download a list of user such as follower, following or searched users * download a list of user such as follower, following or searched users
* @see UserFragment * @see UserFragment
@ -33,17 +30,15 @@ public class UserListLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
} }
@Nullable @Nullable
private TwitterEngine.EngineException twException; private EngineException twException;
private WeakReference<UserFragment> ui; private WeakReference<UserFragment> ui;
private TwitterEngine mTwitter; private TwitterEngine mTwitter;
private UserAdapter adapter;
private Mode mode; private Mode mode;
public UserListLoader(UserFragment fragment, Mode mode) { public UserListLoader(UserFragment fragment, Mode mode) {
ui = new WeakReference<>(fragment); ui = new WeakReference<>(fragment);
mTwitter = TwitterEngine.getInstance(fragment.getContext()); mTwitter = TwitterEngine.getInstance(fragment.getContext());
adapter = fragment.getAdapter();
this.mode = mode; this.mode = mode;
} }
@ -81,7 +76,7 @@ public class UserListLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
return mTwitter.getListMember((long) param[0]); return mTwitter.getListMember((long) param[0]);
} }
} catch (TwitterEngine.EngineException twException) { } catch (EngineException twException) {
this.twException = twException; this.twException = twException;
} catch (Exception exception) { } catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
@ -93,30 +88,12 @@ public class UserListLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
@Override @Override
protected void onPostExecute(@Nullable List<TwitterUser> users) { protected void onPostExecute(@Nullable List<TwitterUser> users) {
if (ui.get() != null) { if (ui.get() != null) {
ui.get().setRefresh(false);
if (users != null) { if (users != null) {
adapter.replaceAll(users); ui.get().setData(users);
if (mode == Mode.FAVORIT) } else if (twException != null) {
Toast.makeText(ui.get().getContext(), R.string.info_not_implemented, Toast.LENGTH_SHORT).show(); ui.get().onError(twException);
} 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);
}
} }
} }

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 android.content.Context;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import org.nuclearfog.twidda.BuildConfig; import org.nuclearfog.twidda.BuildConfig;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.items.Message; import org.nuclearfog.twidda.backend.items.Message;
import org.nuclearfog.twidda.backend.items.MessageHolder; import org.nuclearfog.twidda.backend.items.MessageHolder;
import org.nuclearfog.twidda.backend.items.TrendLocation; import org.nuclearfog.twidda.backend.items.TrendLocation;
@ -157,7 +155,7 @@ public class TwitterEngine {
* @return Link to App Registration * @return Link to App Registration
* @throws EngineException if internet connection is unavailable * @throws EngineException if internet connection is unavailable
*/ */
String request() throws EngineException { public String request() throws EngineException {
try { try {
if (reqToken == null) if (reqToken == null)
reqToken = twitter.getOAuthRequestToken(); reqToken = twitter.getOAuthRequestToken();
@ -174,7 +172,7 @@ public class TwitterEngine {
* @param twitterPin PIN for accessing account * @param twitterPin PIN for accessing account
* @throws EngineException if pin is false or request token is null * @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 { try {
if (reqToken != null) { if (reqToken != null) {
AccessToken accessToken = twitter.getOAuthAccessToken(reqToken, twitterPin); AccessToken accessToken = twitter.getOAuthAccessToken(reqToken, twitterPin);
@ -201,7 +199,7 @@ public class TwitterEngine {
* @return List of Tweets * @return List of Tweets
* @throws EngineException if access is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
List<Status> homeTweets = twitter.getHomeTimeline(new Paging(page, load, lastId)); List<Status> homeTweets = twitter.getHomeTimeline(new Paging(page, load, lastId));
@ -220,7 +218,7 @@ public class TwitterEngine {
* @return List of Mention Tweets * @return List of Mention Tweets
* @throws EngineException if access is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
List<Status> mentions = twitter.getMentionsTimeline(new Paging(page, load, id)); List<Status> mentions = twitter.getMentionsTimeline(new Paging(page, load, id));
@ -239,7 +237,7 @@ public class TwitterEngine {
* @return List of Tweets * @return List of Tweets
* @throws EngineException if acces is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
Query q = new Query(); Query q = new Query();
@ -262,7 +260,7 @@ public class TwitterEngine {
* @return Trend Resource * @return Trend Resource
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<TwitterTrend> getTrends(int woeId) throws EngineException { public List<TwitterTrend> getTrends(int woeId) throws EngineException {
try { try {
int index = 1; int index = 1;
List<TwitterTrend> result = new LinkedList<>(); List<TwitterTrend> result = new LinkedList<>();
@ -282,7 +280,7 @@ public class TwitterEngine {
* @return list of locations * @return list of locations
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<TrendLocation> getLocations() throws EngineException { public List<TrendLocation> getLocations() throws EngineException {
try { try {
List<TrendLocation> result = new LinkedList<>(); List<TrendLocation> result = new LinkedList<>();
List<Location> locations = twitter.getAvailableTrends(); List<Location> locations = twitter.getAvailableTrends();
@ -302,7 +300,7 @@ public class TwitterEngine {
* @return List of Users * @return List of Users
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<TwitterUser> searchUsers(String search) throws EngineException { public List<TwitterUser> searchUsers(String search) throws EngineException {
try { try {
return convertUserList(twitter.searchUsers(search, -1)); return convertUserList(twitter.searchUsers(search, -1));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -320,7 +318,7 @@ public class TwitterEngine {
* @return List of User Tweets * @return List of User Tweets
* @throws EngineException if access is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
Paging paging = new Paging(page, load, sinceId); Paging paging = new Paging(page, load, sinceId);
@ -339,7 +337,7 @@ public class TwitterEngine {
* @return List of User Favs * @return List of User Favs
* @throws EngineException if access is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
Paging paging = new Paging(page, load); Paging paging = new Paging(page, load);
@ -358,7 +356,7 @@ public class TwitterEngine {
* @return User Object * @return User Object
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser getUser(long userId) throws EngineException { public TwitterUser getUser(long userId) throws EngineException {
try { try {
return new TwitterUser(twitter.showUser(userId)); return new TwitterUser(twitter.showUser(userId));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -373,7 +371,7 @@ public class TwitterEngine {
* @return curent user * @return curent user
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser getCurrentUser() throws EngineException { public TwitterUser getCurrentUser() throws EngineException {
try { try {
return new TwitterUser(twitter.showUser(twitterID)); return new TwitterUser(twitter.showUser(twitterID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -389,7 +387,7 @@ public class TwitterEngine {
* @return User Properties * @return User Properties
* @throws EngineException if Connection is unavailable * @throws EngineException if Connection is unavailable
*/ */
UserProperties getConnection(long userId) throws EngineException { public UserProperties getConnection(long userId) throws EngineException {
try { try {
return new UserProperties(twitter.showFriendship(twitterID, userId)); return new UserProperties(twitter.showFriendship(twitterID, userId));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -405,7 +403,7 @@ public class TwitterEngine {
* @return Twitter User * @return Twitter User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser followUser(long userID) throws EngineException { public TwitterUser followUser(long userID) throws EngineException {
try { try {
return new TwitterUser(twitter.createFriendship(userID)); return new TwitterUser(twitter.createFriendship(userID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -421,7 +419,7 @@ public class TwitterEngine {
* @return Twitter User * @return Twitter User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser unfollowUser(long userID) throws EngineException { public TwitterUser unfollowUser(long userID) throws EngineException {
try { try {
return new TwitterUser(twitter.destroyFriendship(userID)); return new TwitterUser(twitter.destroyFriendship(userID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -437,7 +435,7 @@ public class TwitterEngine {
* @return Twitter User * @return Twitter User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser blockUser(long UserID) throws EngineException { public TwitterUser blockUser(long UserID) throws EngineException {
try { try {
return new TwitterUser(twitter.createBlock(UserID)); return new TwitterUser(twitter.createBlock(UserID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -453,7 +451,7 @@ public class TwitterEngine {
* @return Twitter User * @return Twitter User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser unblockUser(long UserID) throws EngineException { public TwitterUser unblockUser(long UserID) throws EngineException {
try { try {
return new TwitterUser(twitter.destroyBlock(UserID)); return new TwitterUser(twitter.destroyBlock(UserID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -469,7 +467,7 @@ public class TwitterEngine {
* @return Twitter User * @return Twitter User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser muteUser(long UserID) throws EngineException { public TwitterUser muteUser(long UserID) throws EngineException {
try { try {
return new TwitterUser(twitter.createMute(UserID)); return new TwitterUser(twitter.createMute(UserID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -485,7 +483,7 @@ public class TwitterEngine {
* @return Twitter User * @return Twitter User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser unmuteUser(long UserID) throws EngineException { public TwitterUser unmuteUser(long UserID) throws EngineException {
try { try {
return new TwitterUser(twitter.destroyMute(UserID)); return new TwitterUser(twitter.destroyMute(UserID));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -501,7 +499,7 @@ public class TwitterEngine {
* @return List of Following User * @return List of Following User
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
List<TwitterUser> getFollowing(long userId) throws EngineException { public List<TwitterUser> getFollowing(long userId) throws EngineException {
try { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
IDs userIDs = twitter.getFriendsIDs(userId, -1, load); IDs userIDs = twitter.getFriendsIDs(userId, -1, load);
@ -522,7 +520,7 @@ public class TwitterEngine {
* @return List of Follower * @return List of Follower
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
List<TwitterUser> getFollower(long userId) throws EngineException { public List<TwitterUser> getFollower(long userId) throws EngineException {
try { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
IDs userIDs = twitter.getFollowersIDs(userId, -1, load); IDs userIDs = twitter.getFollowersIDs(userId, -1, load);
@ -542,7 +540,7 @@ public class TwitterEngine {
* @param tweet Tweet holder * @param tweet Tweet holder
* @throws EngineException if twitter service is unavailable or media was not found * @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 { try {
StatusUpdate mStatus = new StatusUpdate(tweet.getText()); StatusUpdate mStatus = new StatusUpdate(tweet.getText());
if (tweet.isReply()) if (tweet.isReply())
@ -570,7 +568,7 @@ public class TwitterEngine {
* @return Tweet Object * @return Tweet Object
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
Tweet getStatus(long tweetId) throws EngineException { public Tweet getStatus(long tweetId) throws EngineException {
try { try {
Status tweet = twitter.showStatus(tweetId); Status tweet = twitter.showStatus(tweetId);
return new Tweet(tweet); return new Tweet(tweet);
@ -589,7 +587,7 @@ public class TwitterEngine {
* @return List of Answers * @return List of Answers
* @throws EngineException if Access is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
List<Status> answers = new LinkedList<>(); List<Status> answers = new LinkedList<>();
@ -615,7 +613,7 @@ public class TwitterEngine {
* @param tweetId Tweet ID * @param tweetId Tweet ID
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
Tweet retweet(long tweetId) throws EngineException { public Tweet retweet(long tweetId) throws EngineException {
try { try {
Status tweet = twitter.showStatus(tweetId); Status tweet = twitter.showStatus(tweetId);
boolean retweeted = tweet.isRetweeted(); boolean retweeted = tweet.isRetweeted();
@ -644,7 +642,7 @@ public class TwitterEngine {
* @param tweetId Tweet ID * @param tweetId Tweet ID
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
Tweet favorite(long tweetId) throws EngineException { public Tweet favorite(long tweetId) throws EngineException {
try { try {
Status tweet = twitter.showStatus(tweetId); Status tweet = twitter.showStatus(tweetId);
boolean retweeted = tweet.isRetweeted(); boolean retweeted = tweet.isRetweeted();
@ -672,7 +670,7 @@ public class TwitterEngine {
* @return dummy tweet * @return dummy tweet
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
Tweet deleteTweet(long tweetId) throws EngineException { public Tweet deleteTweet(long tweetId) throws EngineException {
try { try {
return new Tweet(twitter.destroyStatus(tweetId)); return new Tweet(twitter.destroyStatus(tweetId));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -688,7 +686,7 @@ public class TwitterEngine {
* @return List of users or empty list if no match * @return List of users or empty list if no match
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
List<TwitterUser> getRetweeter(long tweetID) throws EngineException { public List<TwitterUser> getRetweeter(long tweetID) throws EngineException {
try { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
Tweet embeddedStat = getStatus(tweetID).getEmbeddedTweet(); Tweet embeddedStat = getStatus(tweetID).getEmbeddedTweet();
@ -710,7 +708,7 @@ public class TwitterEngine {
* @return DM List * @return DM List
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<Message> getMessages() throws EngineException { public List<Message> getMessages() throws EngineException {
try { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
List<DirectMessage> dmList = twitter.getDirectMessages(load); List<DirectMessage> dmList = twitter.getDirectMessages(load);
@ -731,7 +729,7 @@ public class TwitterEngine {
* @param messageHolder message informations * @param messageHolder message informations
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
void sendMessage(MessageHolder messageHolder) throws EngineException { public void sendMessage(MessageHolder messageHolder) throws EngineException {
try { try {
long id = twitter.showUser(messageHolder.getUsername()).getId(); long id = twitter.showUser(messageHolder.getUsername()).getId();
if (messageHolder.hasMedia()) { if (messageHolder.hasMedia()) {
@ -753,7 +751,7 @@ public class TwitterEngine {
* @param id Message ID * @param id Message ID
* @throws EngineException if Access is unavailable or message not found * @throws EngineException if Access is unavailable or message not found
*/ */
void deleteMessage(long id) throws EngineException { public void deleteMessage(long id) throws EngineException {
try { try {
twitter.destroyDirectMessage(id); twitter.destroyDirectMessage(id);
} catch (TwitterException err) { } catch (TwitterException err) {
@ -769,7 +767,7 @@ public class TwitterEngine {
* @return updated user profile * @return updated user profile
* @throws EngineException if Access is unavailable * @throws EngineException if Access is unavailable
*/ */
TwitterUser updateProfile(UserHolder userHolder) throws EngineException { public TwitterUser updateProfile(UserHolder userHolder) throws EngineException {
try { try {
if (userHolder.hasProfileImage()) { if (userHolder.hasProfileImage()) {
File profileImage = new File(userHolder.getProfileImage()); File profileImage = new File(userHolder.getProfileImage());
@ -798,7 +796,7 @@ public class TwitterEngine {
* @return list information * @return list information
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<TwitterList> getUserList(long userId) throws EngineException { public List<TwitterList> getUserList(long userId) throws EngineException {
try { try {
List<TwitterList> result = new LinkedList<>(); List<TwitterList> result = new LinkedList<>();
ResponseList<UserList> lists = twitter.getUserLists(userId); ResponseList<UserList> lists = twitter.getUserLists(userId);
@ -818,7 +816,7 @@ public class TwitterEngine {
* @return List information * @return List information
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
TwitterList followUserList(long listId) throws EngineException { public TwitterList followUserList(long listId) throws EngineException {
try { try {
UserList list = twitter.showUserList(listId); UserList list = twitter.showUserList(listId);
if (list.isFollowing()) { if (list.isFollowing()) {
@ -840,7 +838,7 @@ public class TwitterEngine {
* @return List information * @return List information
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
TwitterList deleteUserList(long listId) throws EngineException { public TwitterList deleteUserList(long listId) throws EngineException {
try { try {
return new TwitterList(twitter.destroyUserList(listId), twitterID); return new TwitterList(twitter.destroyUserList(listId), twitterID);
} catch (TwitterException err) { } catch (TwitterException err) {
@ -855,7 +853,7 @@ public class TwitterEngine {
* @return list of users following the list * @return list of users following the list
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<TwitterUser> getListFollower(long listId) throws EngineException { public List<TwitterUser> getListFollower(long listId) throws EngineException {
try { try {
return convertUserList(twitter.getUserListSubscribers(listId, -1)); return convertUserList(twitter.getUserListSubscribers(listId, -1));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -870,7 +868,7 @@ public class TwitterEngine {
* @return list of users * @return list of users
* @throws EngineException if access is unavailable * @throws EngineException if access is unavailable
*/ */
List<TwitterUser> getListMember(long listId) throws EngineException { public List<TwitterUser> getListMember(long listId) throws EngineException {
try { try {
return convertUserList(twitter.getUserListMembers(listId, -1)); return convertUserList(twitter.getUserListMembers(listId, -1));
} catch (TwitterException err) { } catch (TwitterException err) {
@ -888,7 +886,7 @@ public class TwitterEngine {
* @return list of tweets * @return list of tweets
* @throws EngineException if access is unavailable * @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 { try {
int load = settings.getRowLimit(); int load = settings.getRowLimit();
Paging paging = new Paging(page, load, sinceId); Paging paging = new Paging(page, load, sinceId);
@ -988,140 +986,4 @@ public class TwitterEngine {
throw new EngineException(EngineException.FILENOTFOUND); 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.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog.Builder; 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;
import org.nuclearfog.twidda.adapter.ListAdapter.ListClickListener; import org.nuclearfog.twidda.adapter.ListAdapter.ListClickListener;
import org.nuclearfog.twidda.backend.TwitterListLoader; import org.nuclearfog.twidda.backend.TwitterListLoader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.TwitterList; import org.nuclearfog.twidda.backend.items.TwitterList;
import org.nuclearfog.twidda.database.GlobalSettings; import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING; 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_ID;
import static org.nuclearfog.twidda.activity.ListDetail.KEY_LISTDETAIL_NAME; import static org.nuclearfog.twidda.activity.ListDetail.KEY_LISTDETAIL_NAME;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_ID; 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() { * set data to list
return adapter; *
* @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) { public void setRefresh(boolean enable) {
if (enable) { if (enable) {
reloadLayout.postDelayed(new Runnable() { 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() { private void load() {
listTask = new TwitterListLoader(this, 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.adapter.MessageAdapter.OnItemSelected;
import org.nuclearfog.twidda.backend.MessageListLoader; import org.nuclearfog.twidda.backend.MessageListLoader;
import org.nuclearfog.twidda.backend.MessageListLoader.Mode; 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.backend.items.Message;
import org.nuclearfog.twidda.database.GlobalSettings; import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING; import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
@ -149,12 +153,28 @@ public class MessageFragment extends Fragment implements OnRefreshListener, OnIt
} }
} }
/**
public MessageAdapter getAdapter() { * set data to list
return adapter; *
* @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) { public void setRefresh(boolean enable) {
if (enable) { if (enable) {
reload.postDelayed(new Runnable() { 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) { private void load(Mode m) {
messageTask = new MessageListLoader(this, m); messageTask = new MessageListLoader(this, m);

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -14,16 +15,21 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.SearchPage; import org.nuclearfog.twidda.activity.SearchPage;
import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver; import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver;
import org.nuclearfog.twidda.adapter.TrendAdapter; import org.nuclearfog.twidda.adapter.TrendAdapter;
import org.nuclearfog.twidda.adapter.TrendAdapter.TrendClickListener; import org.nuclearfog.twidda.adapter.TrendAdapter.TrendClickListener;
import org.nuclearfog.twidda.backend.TrendListLoader; import org.nuclearfog.twidda.backend.TrendListLoader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.items.TwitterTrend; import org.nuclearfog.twidda.backend.items.TwitterTrend;
import org.nuclearfog.twidda.database.GlobalSettings; import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING; import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.SearchPage.KEY_SEARCH_QUERY; import static org.nuclearfog.twidda.activity.SearchPage.KEY_SEARCH_QUERY;
@ -115,12 +121,48 @@ public class TrendFragment extends Fragment implements OnRefreshListener, TrendC
load(); 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) { public void setRefresh(boolean enable) {
if (enable) { if (enable) {
reload.postDelayed(new Runnable() { reload.postDelayed(new Runnable() {

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -14,17 +15,22 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.TweetDetail; import org.nuclearfog.twidda.activity.TweetDetail;
import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver; import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver;
import org.nuclearfog.twidda.adapter.TweetAdapter; import org.nuclearfog.twidda.adapter.TweetAdapter;
import org.nuclearfog.twidda.adapter.TweetAdapter.TweetClickListener; import org.nuclearfog.twidda.adapter.TweetAdapter.TweetClickListener;
import org.nuclearfog.twidda.backend.TweetListLoader; import org.nuclearfog.twidda.backend.TweetListLoader;
import org.nuclearfog.twidda.backend.TweetListLoader.Mode; 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.backend.items.Tweet;
import org.nuclearfog.twidda.database.GlobalSettings; import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING; 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_ID;
import static org.nuclearfog.twidda.activity.TweetDetail.KEY_TWEET_NAME; import static org.nuclearfog.twidda.activity.TweetDetail.KEY_TWEET_NAME;
@ -154,12 +160,39 @@ public class TweetFragment extends Fragment implements OnRefreshListener, TweetC
tweetTask = null; tweetTask = null;
} }
/**
public TweetAdapter getAdapter() { * get Id of the first Tweet
return adapter; *
* @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) { public void setRefresh(boolean enable) {
if (enable) { if (enable) {
reload.postDelayed(new Runnable() { 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() { private void load() {
switch (mode) { switch (mode) {

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -14,17 +15,22 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.activity.UserProfile; import org.nuclearfog.twidda.activity.UserProfile;
import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver; import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver;
import org.nuclearfog.twidda.adapter.UserAdapter; import org.nuclearfog.twidda.adapter.UserAdapter;
import org.nuclearfog.twidda.adapter.UserAdapter.UserClickListener; import org.nuclearfog.twidda.adapter.UserAdapter.UserClickListener;
import org.nuclearfog.twidda.backend.UserListLoader; import org.nuclearfog.twidda.backend.UserListLoader;
import org.nuclearfog.twidda.backend.UserListLoader.Mode; 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.backend.items.TwitterUser;
import org.nuclearfog.twidda.database.GlobalSettings; import org.nuclearfog.twidda.database.GlobalSettings;
import java.util.List;
import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.RUNNING; import static android.os.AsyncTask.Status.RUNNING;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.UserProfile.KEY_PROFILE_ID; 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 void onDataClear() {
} }
/**
public UserAdapter getAdapter() { * set List data
return adapter; *
* @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) { public void setRefresh(boolean enable) {
if (enable) { if (enable) {
reload.postDelayed(new Runnable() { 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() { private void load() {
switch (mode) { switch (mode) {

View File

@ -22,7 +22,7 @@
<string name="error_connection">Keine Internetverbindung!</string> <string name="error_connection">Keine Internetverbindung!</string>
<string name="error_enter_pin">PIN eingeben!</string> <string name="error_enter_pin">PIN eingeben!</string>
<string name="confirm_delete_database">Datenbank löschen?</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="error_sending_tweet">Fehler beim Senden!</string>
<string name="info_tweet_sent">Tweet gesendet</string> <string name="info_tweet_sent">Tweet gesendet</string>
<string name="info_error">Fehler!</string> <string name="info_error">Fehler!</string>

View File

@ -30,7 +30,7 @@
<string name="error_connection">connection failed</string> <string name="error_connection">connection failed</string>
<string name="error_enter_pin">Enter PIN!</string> <string name="error_enter_pin">Enter PIN!</string>
<string name="confirm_delete_database">delete database?</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="error_sending_tweet">error while sending</string>
<string name="info_tweet_sent">tweet sent</string> <string name="info_tweet_sent">tweet sent</string>
<string name="info_error">Error!</string> <string name="info_error">Error!</string>