diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/AppSettings.java b/app/src/main/java/org/nuclearfog/twidda/activity/AppSettings.java index fac1cab0..da9300ec 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/AppSettings.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/AppSettings.java @@ -20,6 +20,7 @@ import android.widget.EditText; import android.widget.NumberPicker; import android.widget.Spinner; import android.widget.TextView; +import android.widget.Toast; import androidx.appcompat.app.AlertDialog.Builder; import androidx.appcompat.app.AppCompatActivity; @@ -34,7 +35,8 @@ import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.adapter.FontAdapter; import org.nuclearfog.twidda.adapter.LocationAdapter; import org.nuclearfog.twidda.backend.LocationListLoader; -import org.nuclearfog.twidda.backend.TwitterEngine; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.items.TrendLocation; import org.nuclearfog.twidda.database.DatabaseAdapter; @@ -45,6 +47,7 @@ import java.util.regex.Matcher; import static android.os.AsyncTask.Status.RUNNING; import static android.view.View.GONE; +import static android.widget.Toast.LENGTH_SHORT; import static org.nuclearfog.twidda.activity.MainActivity.APP_LOGOUT; import static org.nuclearfog.twidda.activity.MainActivity.DB_CLEARED; @@ -347,6 +350,20 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O locationSpinner.setSelection(position); } + public void onError(EngineException err) { + if (err.isErrorDefined()) { + if (err.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += err.getRetryAfter(); + Toast.makeText(this, errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(this, err.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(this, err.getMessage(), LENGTH_SHORT).show(); + } + } + private void setColor(int preColor) { color_dialog_selector = ColorPickerDialogBuilder.with(this) diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/LoginPage.java b/app/src/main/java/org/nuclearfog/twidda/activity/LoginPage.java index 14bec720..4e8e6a0b 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/LoginPage.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/LoginPage.java @@ -1,5 +1,6 @@ package org.nuclearfog.twidda.activity; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -11,11 +12,13 @@ import android.widget.Button; import android.widget.EditText; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.Registration; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.database.GlobalSettings; @@ -87,7 +90,7 @@ public class LoginPage extends AppCompatActivity implements OnClickListener { @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.login_setting) { Intent settings = new Intent(this, AppSettings.class); startActivity(settings); @@ -136,4 +139,19 @@ public class LoginPage extends AppCompatActivity implements OnClickListener { else Toast.makeText(this, R.string.error_connection, LENGTH_SHORT).show(); } + + + public void onSuccess() { + setResult(Activity.RESULT_OK); + finish(); + } + + public void onError(@NonNull EngineException error) { + if (error.isErrorDefined()) { + Toast.makeText(this, error.getMessageResource(), LENGTH_SHORT).show(); + } else { + Toast.makeText(this, error.getMessage(), LENGTH_SHORT).show(); + } + + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/MainActivity.java b/app/src/main/java/org/nuclearfog/twidda/activity/MainActivity.java index f075563d..9200f278 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/MainActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/MainActivity.java @@ -226,5 +226,7 @@ public class MainActivity extends AppCompatActivity implements OnTabSelectedList @Override public void onTabReselected(Tab tab) { + if (adapter != null) + adapter.scrollToTop(tab.getPosition()); } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/MessagePopup.java b/app/src/main/java/org/nuclearfog/twidda/activity/MessagePopup.java index 46fccfee..c9cb57a6 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/MessagePopup.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/MessagePopup.java @@ -18,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.MessageUploader; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.items.MessageHolder; import org.nuclearfog.twidda.database.GlobalSettings; @@ -145,6 +146,33 @@ public class MessagePopup extends AppCompatActivity implements OnClickListener { } } + /** + * called when direct message is sent + */ + public void onSuccess() { + Toast.makeText(this, R.string.info_dm_send, Toast.LENGTH_SHORT).show(); + finish(); + } + + /** + * called when an error occurs + * + * @param error Engine Exception + */ + public void onError(EngineException error) { + if (error.isErrorDefined()) { + if (error.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += error.getRetryAfter(); + Toast.makeText(this, errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(this, error.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(this, error.getMessage(), LENGTH_SHORT).show(); + } + } + private void getMedia() { boolean accessGranted = true; diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/ProfileEditor.java b/app/src/main/java/org/nuclearfog/twidda/activity/ProfileEditor.java index 5c7fe986..c65b0f8d 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/ProfileEditor.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/ProfileEditor.java @@ -27,6 +27,7 @@ import com.squareup.picasso.Picasso; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.ProfileUpdater; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.UserHolder; @@ -39,6 +40,7 @@ import static android.os.AsyncTask.Status.RUNNING; import static android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI; import static android.view.View.INVISIBLE; import static android.widget.Toast.LENGTH_SHORT; +import static org.nuclearfog.twidda.activity.UserProfile.RETURN_PROFILE_CHANGED; public class ProfileEditor extends AppCompatActivity implements OnClickListener { @@ -54,6 +56,7 @@ public class ProfileEditor extends AppCompatActivity implements OnClickListener private EditText name, link, loc, bio; private Button add_banner_btn; private String profileLink, bannerLink; + private boolean userSet = false; @Override protected void onCreate(Bundle savedInstanceState) { @@ -208,6 +211,32 @@ public class ProfileEditor extends AppCompatActivity implements OnClickListener link.setText(user.getLink()); loc.setText(user.getLocation()); bio.setText(user.getBio()); + userSet = true; + } + + /** + * called after user profile was updated successfully + */ + public void setSuccess() { + Toast.makeText(this, R.string.info_profile_updated, Toast.LENGTH_SHORT).show(); + setResult(RETURN_PROFILE_CHANGED); + finish(); + } + + /** + * called after an error occurs + * + * @param err Engine Exception + */ + public void setError(EngineException err) { + if (err.isErrorDefined()) { + Toast.makeText(this, err.getMessageResource(), LENGTH_SHORT).show(); + } else { + Toast.makeText(this, err.getMessage(), LENGTH_SHORT).show(); + } + if (!userSet) { + finish(); + } } diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/SearchPage.java b/app/src/main/java/org/nuclearfog/twidda/activity/SearchPage.java index 8958a094..f73deb3f 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/SearchPage.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/SearchPage.java @@ -132,12 +132,15 @@ public class SearchPage extends AppCompatActivity implements OnTabSelectedListen @Override public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + if (adapter != null) + adapter.scrollToTop(tab.getPosition()); } @Override public void onTabReselected(Tab tab) { + if (adapter != null) + adapter.scrollToTop(tab.getPosition()); } diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java b/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java index cc55184b..4399c010 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java @@ -34,6 +34,7 @@ import org.nuclearfog.twidda.adapter.FragmentAdapter; import org.nuclearfog.twidda.adapter.FragmentAdapter.AdapterType; import org.nuclearfog.twidda.backend.TweetLoader; import org.nuclearfog.twidda.backend.TweetLoader.Action; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.helper.StringTools; import org.nuclearfog.twidda.backend.items.Tweet; @@ -59,6 +60,7 @@ import static org.nuclearfog.twidda.activity.TweetPopup.KEY_TWEETPOPUP_REPLYID; import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_ID; import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_MODE; import static org.nuclearfog.twidda.activity.UserDetail.USERLIST_RETWEETS; +import static org.nuclearfog.twidda.fragment.TweetFragment.RETURN_TWEET_CHANGED; public class TweetDetail extends AppCompatActivity implements OnClickListener, @@ -394,8 +396,58 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener, } } + /** + * called after a tweet action + * + * @param tweet tweet information + * @param action action type + */ + public void onAction(Tweet tweet, Action action) { + switch (action) { + case RETWEET: + if (tweet.retweeted()) + Toast.makeText(this, R.string.info_tweet_retweeted, LENGTH_SHORT).show(); + else + Toast.makeText(this, R.string.info_tweet_unretweeted, LENGTH_SHORT).show(); + break; - public void finishIfEmpty() { + case FAVORITE: + if (tweet.favored()) + Toast.makeText(this, R.string.info_tweet_favored, LENGTH_SHORT).show(); + else + Toast.makeText(this, R.string.info_tweet_unfavored, LENGTH_SHORT).show(); + break; + + case DELETE: + Toast.makeText(this, R.string.info_tweet_removed, LENGTH_SHORT).show(); + setResult(RETURN_TWEET_CHANGED); + finish(); + break; + } + } + + /** + * called when an error occurs + * + * @param error Engine Exception + */ + public void onError(@NonNull EngineException error) { + if (error.isErrorDefined()) { + if (error.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += error.getRetryAfter(); + Toast.makeText(this, errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(this, error.getMessageResource(), LENGTH_SHORT).show(); + } + if (error.isHardFault()) { + if (error.statusNotFound()) + setResult(RETURN_TWEET_CHANGED); + finish(); + } + } else { + Toast.makeText(this, error.getMessage(), LENGTH_SHORT).show(); + } if (tweet == null) { finish(); } diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java b/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java index 1873f978..faedc3e2 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java @@ -24,6 +24,7 @@ import androidx.appcompat.app.AppCompatActivity; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.TweetUploader; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.helper.StringTools; import org.nuclearfog.twidda.backend.helper.StringTools.FileType; @@ -288,15 +289,27 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo locationBtn.setVisibility(VISIBLE); } + /** + * called after sending tweet + */ + public void onSuccess() { + Toast.makeText(this, R.string.info_tweet_sent, LENGTH_LONG).show(); + finish(); + } /** * Show confirmation dialog if an error occurs while sending tweet - * * @param tweet tweet to re-send */ - public void showErrorMsg(final TweetHolder tweet) { + public void onError(final TweetHolder tweet, @Nullable EngineException error) { + int errorRes; + if (error != null && error.isErrorDefined()) { + errorRes = error.getMessageResource(); + } else { + errorRes = R.string.error_sending_tweet; + } AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.ConfirmDialog); - builder.setTitle(R.string.info_error).setMessage(R.string.error_sending_tweet) + builder.setTitle(R.string.info_error).setMessage(errorRes) .setPositiveButton(R.string.confirm_retry, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/UserProfile.java b/app/src/main/java/org/nuclearfog/twidda/activity/UserProfile.java index be275cd6..2902a091 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activity/UserProfile.java +++ b/app/src/main/java/org/nuclearfog/twidda/activity/UserProfile.java @@ -34,6 +34,7 @@ import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.adapter.FragmentAdapter; import org.nuclearfog.twidda.adapter.FragmentAdapter.AdapterType; import org.nuclearfog.twidda.backend.ProfileLoader; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.helper.FontTool; import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.UserProperties; @@ -452,12 +453,15 @@ public class UserProfile extends AppCompatActivity implements OnClickListener, @Override public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + if (adapter != null) + adapter.scrollToTop(tab.getPosition()); } @Override public void onTabReselected(Tab tab) { + if (adapter != null) + adapter.scrollToTop(tab.getPosition()); } @@ -523,14 +527,63 @@ public class UserProfile extends AppCompatActivity implements OnClickListener, } } - /** * Set User Relationship - * * @param properties relationship to the current user */ public void setConnection(UserProperties properties) { this.properties = properties; invalidateOptionsMenu(); } + + /** + * print messages after user action + * + * @param properties connection to an user + * @param action Action on the user profile + */ + public void onAction(UserProperties properties, ProfileLoader.Action action) { + switch (action) { + case ACTION_FOLLOW: + if (properties.isFriend()) + Toast.makeText(this, R.string.info_followed, Toast.LENGTH_SHORT).show(); + break; + + case ACTION_BLOCK: + if (properties.isBlocked()) + Toast.makeText(this, R.string.info_user_blocked, Toast.LENGTH_SHORT).show(); + else + Toast.makeText(this, R.string.info_user_unblocked, Toast.LENGTH_SHORT).show(); + break; + + case ACTION_MUTE: + if (properties.isMuted()) + Toast.makeText(this, R.string.info_user_muted, Toast.LENGTH_SHORT).show(); + else + Toast.makeText(this, R.string.info_user_unmuted, Toast.LENGTH_SHORT).show(); + break; + } + } + + /** + * called if an error occurs + * + * @param err Engine Exception + */ + public void onError(EngineException err) { + if (err.isErrorDefined()) { + if (err.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += err.getRetryAfter(); + Toast.makeText(this, errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(this, err.getMessageResource(), LENGTH_SHORT).show(); + if (err.isHardFault()) { + finish(); + } + } + } else { + Toast.makeText(this, err.getMessage(), LENGTH_SHORT).show(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/adapter/FragmentAdapter.java b/app/src/main/java/org/nuclearfog/twidda/adapter/FragmentAdapter.java index 7e339f6b..7f51891c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/adapter/FragmentAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/adapter/FragmentAdapter.java @@ -234,10 +234,19 @@ public class FragmentAdapter extends FragmentStatePagerAdapter { public interface FragmentChangeObserver { + /** + * called if settings changed to refresh fragments + */ void onSettingsChange(); + /** + * called when the current tab changes + */ void onTabChange(); + /** + * called to clear the lists + */ void onDataClear(); } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/LocationListLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/LocationListLoader.java index 9b0fe4e5..300c6485 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/LocationListLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/LocationListLoader.java @@ -1,18 +1,17 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.Nullable; import org.nuclearfog.twidda.activity.AppSettings; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TrendLocation; import java.lang.ref.WeakReference; import java.util.List; -import static android.widget.Toast.LENGTH_SHORT; - /** * Background task to load location information used by twitter such as location names and world ID's * @see AppSettings @@ -20,7 +19,7 @@ import static android.widget.Toast.LENGTH_SHORT; public class LocationListLoader extends AsyncTask> { @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private TwitterEngine mTwitter; @@ -35,7 +34,7 @@ public class LocationListLoader extends AsyncTask doInBackground(Void[] v) { try { return mTwitter.getLocations(); - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -50,7 +49,7 @@ public class LocationListLoader extends AsyncTask> { @@ -30,12 +27,11 @@ public class MessageListLoader extends AsyncTask> { } @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private Mode mode; private WeakReference ui; private TwitterEngine mTwitter; private AppDatabase db; - private MessageAdapter adapter; private long id; @@ -43,15 +39,15 @@ public class MessageListLoader extends AsyncTask> { ui = new WeakReference<>(fragment); db = new AppDatabase(fragment.getContext()); mTwitter = TwitterEngine.getInstance(fragment.getContext()); - adapter = fragment.getAdapter(); this.mode = mode; } @Override protected void onPreExecute() { - if (ui.get() != null) + if (ui.get() != null) { ui.get().setRefresh(true); + } } @@ -81,7 +77,7 @@ public class MessageListLoader extends AsyncTask> { db.deleteDm(messageId); break; } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; if (twException.statusNotFound()) db.deleteDm(messageId); @@ -95,22 +91,17 @@ public class MessageListLoader extends AsyncTask> { @Override protected void onPostExecute(@Nullable List messages) { if (ui.get() != null) { - if (messages != null) - adapter.replaceAll(messages); - else if (twException != null) { - Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show(); - if (twException.statusNotFound()) - adapter.remove(id); - } else if (mode == Mode.DEL) - adapter.remove(id); + if (messages != null) { + ui.get().setData(messages); + } else if (twException != null) { + ui.get().onError(twException); + if (twException.statusNotFound()) { + ui.get().removeItem(id); + } + } else if (mode == Mode.DEL) { + ui.get().removeItem(id); + } ui.get().setRefresh(false); } } - - - @Override - protected void onCancelled() { - if (ui.get() != null) - ui.get().setRefresh(false); - } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/MessageUploader.java b/app/src/main/java/org/nuclearfog/twidda/backend/MessageUploader.java index 9c59a55a..233b35f9 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/MessageUploader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/MessageUploader.java @@ -12,12 +12,12 @@ import androidx.annotation.Nullable; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.MessagePopup; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.MessageHolder; import java.lang.ref.WeakReference; -import static android.widget.Toast.LENGTH_SHORT; - /** * Background task to send a direct messages to a user * @see MessagePopup @@ -25,7 +25,7 @@ import static android.widget.Toast.LENGTH_SHORT; public class MessageUploader extends AsyncTask { @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private WeakReference popup; private TwitterEngine mTwitter; @@ -34,13 +34,13 @@ public class MessageUploader extends AsyncTask { /** * send direct message * - * @param c Activity context + * @param context Activity context * @param message message to send */ - public MessageUploader(@NonNull MessagePopup c, MessageHolder message) { - ui = new WeakReference<>(c); - popup = new WeakReference<>(new Dialog(c)); - mTwitter = TwitterEngine.getInstance(c); + public MessageUploader(@NonNull MessagePopup context, MessageHolder message) { + ui = new WeakReference<>(context); + popup = new WeakReference<>(new Dialog(context)); + mTwitter = TwitterEngine.getInstance(context); this.message = message; } @@ -81,7 +81,7 @@ public class MessageUploader extends AsyncTask { try { mTwitter.sendMessage(message); return true; - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -93,14 +93,12 @@ public class MessageUploader extends AsyncTask { @Override protected void onPostExecute(Boolean success) { if (ui.get() != null && popup.get() != null) { - if (success) { - Toast.makeText(ui.get(), R.string.info_dm_send, Toast.LENGTH_SHORT).show(); - ui.get().finish(); - } else { - if (twException != null) - Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show(); - } popup.get().dismiss(); + if (success) { + ui.get().onSuccess(); + } else if (twException != null) { + ui.get().onError(twException); + } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/ProfileLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/ProfileLoader.java index 02c4729c..5cf3e96f 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/ProfileLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/ProfileLoader.java @@ -1,21 +1,19 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.UserProfile; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.UserProperties; import org.nuclearfog.twidda.database.AppDatabase; import java.lang.ref.WeakReference; -import static android.widget.Toast.LENGTH_SHORT; - /** * task for loading user profile information and take actions * @see UserProfile @@ -32,7 +30,7 @@ public class ProfileLoader extends AsyncTask private final Action action; private WeakReference ui; private TwitterEngine mTwitter; - private TwitterEngine.EngineException twException; + private EngineException twException; private AppDatabase db; @@ -100,7 +98,7 @@ public class ProfileLoader extends AsyncTask publishProgress(user); return mTwitter.getConnection(userId); } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -123,31 +121,9 @@ public class ProfileLoader extends AsyncTask if (ui.get() != null) { if (properties != null) { ui.get().setConnection(properties); - switch (action) { - case ACTION_FOLLOW: - if (properties.isFriend()) - Toast.makeText(ui.get(), R.string.info_followed, Toast.LENGTH_SHORT).show(); - break; - - case ACTION_BLOCK: - if (properties.isBlocked()) - Toast.makeText(ui.get(), R.string.info_user_blocked, Toast.LENGTH_SHORT).show(); - else - Toast.makeText(ui.get(), R.string.info_user_unblocked, Toast.LENGTH_SHORT).show(); - break; - - case ACTION_MUTE: - if (properties.isMuted()) - Toast.makeText(ui.get(), R.string.info_user_muted, Toast.LENGTH_SHORT).show(); - else - Toast.makeText(ui.get(), R.string.info_user_unmuted, Toast.LENGTH_SHORT).show(); - break; - } - } - if (twException != null) { - Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show(); - if (twException.isHardFault()) - ui.get().finish(); + ui.get().onAction(properties, action); + } else if (twException != null) { + ui.get().onError(twException); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/ProfileUpdater.java b/app/src/main/java/org/nuclearfog/twidda/backend/ProfileUpdater.java index 86d1a87a..e5b46455 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/ProfileUpdater.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/ProfileUpdater.java @@ -5,21 +5,18 @@ import android.content.DialogInterface; import android.os.AsyncTask; import android.view.Window; import android.widget.ProgressBar; -import android.widget.Toast; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.ProfileEditor; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.backend.items.UserHolder; import org.nuclearfog.twidda.database.AppDatabase; import java.lang.ref.WeakReference; -import static android.widget.Toast.LENGTH_SHORT; -import static org.nuclearfog.twidda.activity.UserProfile.RETURN_PROFILE_CHANGED; - /** * Task for editing profile information and updating images @@ -32,7 +29,7 @@ public class ProfileUpdater extends AsyncTask { private WeakReference popup; private UserHolder userHolder; private TwitterEngine mTwitter; - private TwitterEngine.EngineException twException; + private EngineException twException; private AppDatabase db; @@ -82,7 +79,7 @@ public class ProfileUpdater extends AsyncTask { TwitterUser user = mTwitter.updateProfile(userHolder); db.storeUser(user); } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -96,15 +93,11 @@ public class ProfileUpdater extends AsyncTask { if (ui.get() != null && popup.get() != null) { popup.get().dismiss(); if (twException != null) { - Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show(); - if (userHolder == null) - ui.get().finish(); + ui.get().setError(twException); } else if (user != null) { ui.get().setUser(user); } else if (userHolder != null) { - Toast.makeText(ui.get(), R.string.info_profile_updated, Toast.LENGTH_SHORT).show(); - ui.get().setResult(RETURN_PROFILE_CHANGED); - ui.get().finish(); + ui.get().setSuccess(); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/Registration.java b/app/src/main/java/org/nuclearfog/twidda/backend/Registration.java index 4122e367..b84d3581 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/Registration.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/Registration.java @@ -1,18 +1,15 @@ package org.nuclearfog.twidda.backend; -import android.app.Activity; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.LoginPage; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import java.lang.ref.WeakReference; -import static android.widget.Toast.LENGTH_SHORT; - /** * Background task to connect to twitter and initialize keys * @see LoginPage @@ -20,7 +17,7 @@ import static android.widget.Toast.LENGTH_SHORT; public class Registration extends AsyncTask { @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private TwitterEngine mTwitter; @@ -42,7 +39,7 @@ public class Registration extends AsyncTask { return mTwitter.request(); mTwitter.initialize(param[0]); return ""; - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -58,13 +55,10 @@ public class Registration extends AsyncTask { if (!redirectionURL.isEmpty()) { ui.get().connect(redirectionURL); } else { - ui.get().setResult(Activity.RESULT_OK); - ui.get().finish(); + ui.get().onSuccess(); } } else if (twException != null) { - Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show(); - } else { - Toast.makeText(ui.get(), R.string.error_pin_verification, Toast.LENGTH_SHORT).show(); + ui.get().onError(twException); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TrendListLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/TrendListLoader.java index 838eb2f8..22fb9e76 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/TrendListLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/TrendListLoader.java @@ -1,12 +1,12 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.adapter.TrendAdapter; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TwitterTrend; import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.fragment.TrendFragment; @@ -14,8 +14,6 @@ import org.nuclearfog.twidda.fragment.TrendFragment; import java.lang.ref.WeakReference; import java.util.List; -import static android.widget.Toast.LENGTH_SHORT; - /** * Background task to load a list of location specific trends @@ -25,18 +23,18 @@ import static android.widget.Toast.LENGTH_SHORT; public class TrendListLoader extends AsyncTask> { @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private TwitterEngine mTwitter; private AppDatabase db; - private TrendAdapter adapter; + private boolean isEmpty; public TrendListLoader(@NonNull TrendFragment fragment) { ui = new WeakReference<>(fragment); db = new AppDatabase(fragment.getContext()); mTwitter = TwitterEngine.getInstance(fragment.getContext()); - adapter = fragment.getAdapter(); + isEmpty = fragment.isEmpty(); } @@ -52,7 +50,7 @@ public class TrendListLoader extends AsyncTask List trends; int woeId = param[0]; try { - if (adapter.isEmpty()) { + if (isEmpty) { trends = db.getTrends(woeId); if (trends.isEmpty()) { trends = mTwitter.getTrends(woeId); @@ -63,7 +61,7 @@ public class TrendListLoader extends AsyncTask db.storeTrends(trends, woeId); } return trends; - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -75,18 +73,12 @@ public class TrendListLoader extends AsyncTask @Override protected void onPostExecute(@Nullable List trends) { if (ui.get() != null) { - if (trends != null) - adapter.setData(trends); - if (twException != null) - Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show(); ui.get().setRefresh(false); + if (trends != null) { + ui.get().setData(trends); + } else if (twException != null) { + ui.get().onError(twException); + } } } - - - @Override - protected void onCancelled() { - if (ui.get() != null) - ui.get().setRefresh(false); - } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TweetListLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/TweetListLoader.java index 0f37d198..e3babedb 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/TweetListLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/TweetListLoader.java @@ -1,11 +1,11 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.adapter.TweetAdapter; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.Tweet; import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.fragment.TweetFragment; @@ -13,8 +13,6 @@ import org.nuclearfog.twidda.fragment.TweetFragment; import java.lang.ref.WeakReference; import java.util.List; -import static android.widget.Toast.LENGTH_SHORT; - /** * Background task to download a list of tweets from different sources @@ -35,19 +33,19 @@ public class TweetListLoader extends AsyncTask> { } @Nullable - private TwitterEngine.EngineException twException; - private Mode mode; + private EngineException twException; private WeakReference ui; - private TweetAdapter adapter; private TwitterEngine mTwitter; private AppDatabase db; + private Mode mode; + private long sinceId; public TweetListLoader(TweetFragment fragment, Mode mode) { ui = new WeakReference<>(fragment); db = new AppDatabase(fragment.getContext()); mTwitter = TwitterEngine.getInstance(fragment.getContext()); - adapter = fragment.getAdapter(); + sinceId = fragment.getTopId(); this.mode = mode; } @@ -63,19 +61,17 @@ public class TweetListLoader extends AsyncTask> { @Override protected List doInBackground(Object[] param) { List tweets = null; - long sinceId = 1; try { switch (mode) { case TL_HOME: int page = (int) param[0]; - if (adapter.isEmpty()) { + if (sinceId == 0) { tweets = db.getHomeTimeline(); if (tweets.isEmpty()) { tweets = mTwitter.getHome(page, sinceId); db.storeHomeTimeline(tweets); } } else { - sinceId = adapter.getItemId(0); tweets = mTwitter.getHome(page, sinceId); db.storeHomeTimeline(tweets); } @@ -83,14 +79,13 @@ public class TweetListLoader extends AsyncTask> { case TL_MENT: page = (int) param[0]; - if (adapter.isEmpty()) { + if (sinceId == 0) { tweets = db.getMentions(); if (tweets.isEmpty()) { tweets = mTwitter.getMention(page, sinceId); db.storeMentions(tweets); } } else { - sinceId = adapter.getItemId(0); tweets = mTwitter.getMention(page, sinceId); db.storeMentions(tweets); } @@ -99,14 +94,13 @@ public class TweetListLoader extends AsyncTask> { case USR_TWEETS: long id = (long) param[0]; page = (int) param[1]; - if (adapter.isEmpty()) { + if (sinceId == 0) { tweets = db.getUserTweets(id); if (tweets.isEmpty()) { tweets = mTwitter.getUserTweets(id, sinceId, page); db.storeUserTweets(tweets); } } else { - sinceId = adapter.getItemId(0); tweets = mTwitter.getUserTweets(id, sinceId, page); db.storeUserTweets(tweets); } @@ -115,7 +109,7 @@ public class TweetListLoader extends AsyncTask> { case USR_FAVORS: id = (long) param[0]; page = (int) param[1]; - if (adapter.isEmpty()) { + if (sinceId == 0) { tweets = db.getUserFavs(id); if (tweets.isEmpty()) { tweets = mTwitter.getUserFavs(id, page); @@ -135,7 +129,7 @@ public class TweetListLoader extends AsyncTask> { case TWEET_ANS: id = (long) param[0]; String search = (String) param[1]; - if (adapter.isEmpty()) { + if (sinceId == 0) { tweets = db.getAnswers(id); if (tweets.isEmpty()) { tweets = mTwitter.getAnswers(search, id, sinceId); @@ -143,7 +137,6 @@ public class TweetListLoader extends AsyncTask> { db.storeReplies(tweets); } } else { - sinceId = adapter.getItemId(0); tweets = mTwitter.getAnswers(search, id, sinceId); if (!tweets.isEmpty() && db.containStatus(id)) db.storeReplies(tweets); @@ -152,20 +145,16 @@ public class TweetListLoader extends AsyncTask> { case TWEET_SEARCH: search = (String) param[0]; - if (!adapter.isEmpty()) - sinceId = adapter.getItemId(0); tweets = mTwitter.searchTweets(search, sinceId); break; case LIST: - long listId = (long) param[0]; + id = (long) param[0]; page = (int) param[1]; - if (!adapter.isEmpty()) - sinceId = adapter.getItemId(0); - tweets = mTwitter.getListTweets(listId, sinceId, page); + tweets = mTwitter.getListTweets(id, sinceId, page); break; } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -177,23 +166,15 @@ public class TweetListLoader extends AsyncTask> { @Override protected void onPostExecute(@Nullable List tweets) { if (ui.get() != null) { + ui.get().setRefresh(false); if (tweets != null) { if (mode == Mode.USR_FAVORS) - adapter.add(tweets); // replace all items + ui.get().add(tweets); else - adapter.addFirst(tweets); + ui.get().addTop(tweets); + } else if (twException != null) { + ui.get().onError(twException); } - if (twException != null) - Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show(); - ui.get().setRefresh(false); - } - } - - - @Override - protected void onCancelled() { - if (ui.get() != null) { - ui.get().setRefresh(false); } } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java index f4000d61..b4c9a278 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java @@ -1,21 +1,18 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.TweetDetail; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.Tweet; import org.nuclearfog.twidda.database.AppDatabase; import java.lang.ref.WeakReference; -import static android.widget.Toast.LENGTH_SHORT; -import static org.nuclearfog.twidda.fragment.TweetFragment.RETURN_TWEET_CHANGED; - /** * Background task to download tweet informations and to take actions @@ -31,7 +28,7 @@ public class TweetLoader extends AsyncTask { } @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private TwitterEngine mTwitter; private WeakReference ui; private AppDatabase db; @@ -89,7 +86,7 @@ public class TweetLoader extends AsyncTask { db.removeFavorite(tweetId); break; } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; if (twException.statusNotFound()) { db.removeStatus(tweetId); @@ -114,37 +111,9 @@ public class TweetLoader extends AsyncTask { protected void onPostExecute(@Nullable Tweet tweet) { if (ui.get() != null) { if (tweet != null) { - switch (action) { - case RETWEET: - if (tweet.retweeted()) - Toast.makeText(ui.get(), R.string.info_tweet_retweeted, LENGTH_SHORT).show(); - else - Toast.makeText(ui.get(), R.string.info_tweet_unretweeted, LENGTH_SHORT).show(); - break; - - case FAVORITE: - if (tweet.favored()) - Toast.makeText(ui.get(), R.string.info_tweet_favored, LENGTH_SHORT).show(); - else - Toast.makeText(ui.get(), R.string.info_tweet_unfavored, LENGTH_SHORT).show(); - break; - - case DELETE: - Toast.makeText(ui.get(), R.string.info_tweet_removed, LENGTH_SHORT).show(); - ui.get().setResult(RETURN_TWEET_CHANGED); - ui.get().finish(); - break; - } - } - if (twException != null) { - Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show(); - if (twException.isHardFault()) { - if (twException.statusNotFound()) - ui.get().setResult(RETURN_TWEET_CHANGED); - ui.get().finish(); - } else { - ui.get().finishIfEmpty(); - } + ui.get().onAction(tweet, action); + } else if (twException != null) { + ui.get().onError(twException); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TweetUploader.java b/app/src/main/java/org/nuclearfog/twidda/backend/TweetUploader.java index 0ecc5f82..24d0982c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/TweetUploader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/TweetUploader.java @@ -11,14 +11,14 @@ import androidx.annotation.Nullable; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.TweetPopup; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TweetHolder; import java.lang.ref.WeakReference; import static android.os.AsyncTask.Status.RUNNING; import static android.view.Window.FEATURE_NO_TITLE; -import static android.widget.Toast.LENGTH_LONG; -import static android.widget.Toast.LENGTH_SHORT; /** * Background task for uploading tweet @@ -27,7 +27,7 @@ import static android.widget.Toast.LENGTH_SHORT; public class TweetUploader extends AsyncTask { @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private WeakReference popup; private TwitterEngine mTwitter; @@ -83,7 +83,7 @@ public class TweetUploader extends AsyncTask { protected Boolean doInBackground(Void[] v) { try { mTwitter.uploadStatus(tweet); - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; return false; } catch (Exception exception) { @@ -97,23 +97,12 @@ public class TweetUploader extends AsyncTask { @Override protected void onPostExecute(Boolean success) { if (ui.get() != null && popup.get() != null) { + popup.get().dismiss(); if (success) { - Toast.makeText(ui.get(), R.string.info_tweet_sent, LENGTH_LONG).show(); - ui.get().finish(); + ui.get().onSuccess(); } else { - if (twException != null) - Toast.makeText(ui.get(), twException.getMessageResource(), LENGTH_SHORT).show(); - ui.get().showErrorMsg(tweet); + ui.get().onError(tweet, twException); } - popup.get().dismiss(); - } - } - - - @Override - protected void onCancelled() { - if (popup.get() != null) { - popup.get().dismiss(); } } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TwitterListLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/TwitterListLoader.java index 2702cc9a..a9bc07dd 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/TwitterListLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/TwitterListLoader.java @@ -1,12 +1,11 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.R; -import org.nuclearfog.twidda.adapter.ListAdapter; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TwitterList; import org.nuclearfog.twidda.fragment.ListFragment; @@ -14,8 +13,6 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; -import static android.widget.Toast.LENGTH_SHORT; - /** * Background task for downloading twitter lists created by a user @@ -31,23 +28,22 @@ public class TwitterListLoader extends AsyncTask> } @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private TwitterEngine mTwitter; - private ListAdapter adapter; private Action action; public TwitterListLoader(ListFragment frag, Action action) { - ui = new WeakReference<>(frag); mTwitter = TwitterEngine.getInstance(frag.getContext()); - adapter = frag.getAdapter(); + ui = new WeakReference<>(frag); this.action = action; } @Override protected void onPreExecute() { - if (ui.get() != null) + if (ui.get() != null) { ui.get().setRefresh(true); + } } @Override @@ -69,7 +65,7 @@ public class TwitterListLoader extends AsyncTask> result.add(mTwitter.deleteUserList(param[0])); return result; } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } return null; @@ -78,37 +74,26 @@ public class TwitterListLoader extends AsyncTask> @Override protected void onPostExecute(@Nullable List result) { if (ui.get() != null) { + ui.get().setRefresh(false); if (result != null) { switch (action) { case LOAD: - adapter.setData(result); + ui.get().setData(result); break; case FOLLOW: TwitterList list = result.get(0); - adapter.updateItem(list); - if (list.isFollowing()) - Toast.makeText(ui.get().getContext(), R.string.info_followed, LENGTH_SHORT).show(); - else - Toast.makeText(ui.get().getContext(), R.string.info_unfollowed, LENGTH_SHORT).show(); + ui.get().updateItem(list); break; case DELETE: list = result.get(0); - adapter.removeItem(list.getId()); - Toast.makeText(ui.get().getContext(), R.string.info_list_removed, LENGTH_SHORT).show(); + ui.get().removeItem(list.getId()); break; } + } else if (twException != null) { + ui.get().onError(twException); } - if (twException != null) - Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show(); - ui.get().setRefresh(false); } } - - @Override - protected void onCancelled() { - if (ui.get() != null) - ui.get().setRefresh(false); - } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/UserListLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/UserListLoader.java index efdd93be..c168b9ca 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/UserListLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/UserListLoader.java @@ -1,12 +1,11 @@ package org.nuclearfog.twidda.backend; import android.os.AsyncTask; -import android.widget.Toast; import androidx.annotation.Nullable; -import org.nuclearfog.twidda.R; -import org.nuclearfog.twidda.adapter.UserAdapter; +import org.nuclearfog.twidda.backend.engine.EngineException; +import org.nuclearfog.twidda.backend.engine.TwitterEngine; import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.fragment.UserFragment; @@ -14,8 +13,6 @@ import java.lang.ref.WeakReference; import java.util.LinkedList; import java.util.List; -import static android.widget.Toast.LENGTH_SHORT; - /** * download a list of user such as follower, following or searched users * @see UserFragment @@ -33,17 +30,15 @@ public class UserListLoader extends AsyncTask> { } @Nullable - private TwitterEngine.EngineException twException; + private EngineException twException; private WeakReference ui; private TwitterEngine mTwitter; - private UserAdapter adapter; private Mode mode; public UserListLoader(UserFragment fragment, Mode mode) { ui = new WeakReference<>(fragment); mTwitter = TwitterEngine.getInstance(fragment.getContext()); - adapter = fragment.getAdapter(); this.mode = mode; } @@ -81,7 +76,7 @@ public class UserListLoader extends AsyncTask> { return mTwitter.getListMember((long) param[0]); } - } catch (TwitterEngine.EngineException twException) { + } catch (EngineException twException) { this.twException = twException; } catch (Exception exception) { exception.printStackTrace(); @@ -93,30 +88,12 @@ public class UserListLoader extends AsyncTask> { @Override protected void onPostExecute(@Nullable List users) { if (ui.get() != null) { + ui.get().setRefresh(false); if (users != null) { - adapter.replaceAll(users); - if (mode == Mode.FAVORIT) - Toast.makeText(ui.get().getContext(), R.string.info_not_implemented, Toast.LENGTH_SHORT).show(); - } else if (twException != null) - Toast.makeText(ui.get().getContext(), twException.getMessageResource(), LENGTH_SHORT).show(); - ui.get().setRefresh(false); - } - } - - - @Override - protected void onCancelled() { - if (ui.get() != null) - ui.get().setRefresh(false); - } - - - @Override - protected void onCancelled(@Nullable List users) { - if (ui.get() != null) { - if (users != null) - adapter.replaceAll(users); - ui.get().setRefresh(false); + ui.get().setData(users); + } else if (twException != null) { + ui.get().onError(twException); + } } } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java b/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java new file mode 100644 index 00000000..328b823d --- /dev/null +++ b/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java @@ -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; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TwitterEngine.java b/app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java similarity index 81% rename from app/src/main/java/org/nuclearfog/twidda/backend/TwitterEngine.java rename to app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java index 271cd935..70d5d002 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/TwitterEngine.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java @@ -1,12 +1,10 @@ -package org.nuclearfog.twidda.backend; +package org.nuclearfog.twidda.backend.engine; import android.content.Context; import androidx.annotation.Nullable; -import androidx.annotation.StringRes; import org.nuclearfog.twidda.BuildConfig; -import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.items.Message; import org.nuclearfog.twidda.backend.items.MessageHolder; import org.nuclearfog.twidda.backend.items.TrendLocation; @@ -157,7 +155,7 @@ public class TwitterEngine { * @return Link to App Registration * @throws EngineException if internet connection is unavailable */ - String request() throws EngineException { + public String request() throws EngineException { try { if (reqToken == null) reqToken = twitter.getOAuthRequestToken(); @@ -174,7 +172,7 @@ public class TwitterEngine { * @param twitterPin PIN for accessing account * @throws EngineException if pin is false or request token is null */ - void initialize(String twitterPin) throws EngineException { + public void initialize(String twitterPin) throws EngineException { try { if (reqToken != null) { AccessToken accessToken = twitter.getOAuthAccessToken(reqToken, twitterPin); @@ -201,7 +199,7 @@ public class TwitterEngine { * @return List of Tweets * @throws EngineException if access is unavailable */ - List getHome(int page, long lastId) throws EngineException { + public List getHome(int page, long lastId) throws EngineException { try { int load = settings.getRowLimit(); List homeTweets = twitter.getHomeTimeline(new Paging(page, load, lastId)); @@ -220,7 +218,7 @@ public class TwitterEngine { * @return List of Mention Tweets * @throws EngineException if access is unavailable */ - List getMention(int page, long id) throws EngineException { + public List getMention(int page, long id) throws EngineException { try { int load = settings.getRowLimit(); List mentions = twitter.getMentionsTimeline(new Paging(page, load, id)); @@ -239,7 +237,7 @@ public class TwitterEngine { * @return List of Tweets * @throws EngineException if acces is unavailable */ - List searchTweets(String search, long id) throws EngineException { + public List searchTweets(String search, long id) throws EngineException { try { int load = settings.getRowLimit(); Query q = new Query(); @@ -262,7 +260,7 @@ public class TwitterEngine { * @return Trend Resource * @throws EngineException if access is unavailable */ - List getTrends(int woeId) throws EngineException { + public List getTrends(int woeId) throws EngineException { try { int index = 1; List result = new LinkedList<>(); @@ -282,7 +280,7 @@ public class TwitterEngine { * @return list of locations * @throws EngineException if access is unavailable */ - List getLocations() throws EngineException { + public List getLocations() throws EngineException { try { List result = new LinkedList<>(); List locations = twitter.getAvailableTrends(); @@ -302,7 +300,7 @@ public class TwitterEngine { * @return List of Users * @throws EngineException if access is unavailable */ - List searchUsers(String search) throws EngineException { + public List searchUsers(String search) throws EngineException { try { return convertUserList(twitter.searchUsers(search, -1)); } catch (TwitterException err) { @@ -320,7 +318,7 @@ public class TwitterEngine { * @return List of User Tweets * @throws EngineException if access is unavailable */ - List getUserTweets(long userId, long sinceId, int page) throws EngineException { + public List getUserTweets(long userId, long sinceId, int page) throws EngineException { try { int load = settings.getRowLimit(); Paging paging = new Paging(page, load, sinceId); @@ -339,7 +337,7 @@ public class TwitterEngine { * @return List of User Favs * @throws EngineException if access is unavailable */ - List getUserFavs(long userId, int page) throws EngineException { + public List getUserFavs(long userId, int page) throws EngineException { try { int load = settings.getRowLimit(); Paging paging = new Paging(page, load); @@ -358,7 +356,7 @@ public class TwitterEngine { * @return User Object * @throws EngineException if Access is unavailable */ - TwitterUser getUser(long userId) throws EngineException { + public TwitterUser getUser(long userId) throws EngineException { try { return new TwitterUser(twitter.showUser(userId)); } catch (TwitterException err) { @@ -373,7 +371,7 @@ public class TwitterEngine { * @return curent user * @throws EngineException if Access is unavailable */ - TwitterUser getCurrentUser() throws EngineException { + public TwitterUser getCurrentUser() throws EngineException { try { return new TwitterUser(twitter.showUser(twitterID)); } catch (TwitterException err) { @@ -389,7 +387,7 @@ public class TwitterEngine { * @return User Properties * @throws EngineException if Connection is unavailable */ - UserProperties getConnection(long userId) throws EngineException { + public UserProperties getConnection(long userId) throws EngineException { try { return new UserProperties(twitter.showFriendship(twitterID, userId)); } catch (TwitterException err) { @@ -405,7 +403,7 @@ public class TwitterEngine { * @return Twitter User * @throws EngineException if Access is unavailable */ - TwitterUser followUser(long userID) throws EngineException { + public TwitterUser followUser(long userID) throws EngineException { try { return new TwitterUser(twitter.createFriendship(userID)); } catch (TwitterException err) { @@ -421,7 +419,7 @@ public class TwitterEngine { * @return Twitter User * @throws EngineException if Access is unavailable */ - TwitterUser unfollowUser(long userID) throws EngineException { + public TwitterUser unfollowUser(long userID) throws EngineException { try { return new TwitterUser(twitter.destroyFriendship(userID)); } catch (TwitterException err) { @@ -437,7 +435,7 @@ public class TwitterEngine { * @return Twitter User * @throws EngineException if Access is unavailable */ - TwitterUser blockUser(long UserID) throws EngineException { + public TwitterUser blockUser(long UserID) throws EngineException { try { return new TwitterUser(twitter.createBlock(UserID)); } catch (TwitterException err) { @@ -453,7 +451,7 @@ public class TwitterEngine { * @return Twitter User * @throws EngineException if Access is unavailable */ - TwitterUser unblockUser(long UserID) throws EngineException { + public TwitterUser unblockUser(long UserID) throws EngineException { try { return new TwitterUser(twitter.destroyBlock(UserID)); } catch (TwitterException err) { @@ -469,7 +467,7 @@ public class TwitterEngine { * @return Twitter User * @throws EngineException if Access is unavailable */ - TwitterUser muteUser(long UserID) throws EngineException { + public TwitterUser muteUser(long UserID) throws EngineException { try { return new TwitterUser(twitter.createMute(UserID)); } catch (TwitterException err) { @@ -485,7 +483,7 @@ public class TwitterEngine { * @return Twitter User * @throws EngineException if Access is unavailable */ - TwitterUser unmuteUser(long UserID) throws EngineException { + public TwitterUser unmuteUser(long UserID) throws EngineException { try { return new TwitterUser(twitter.destroyMute(UserID)); } catch (TwitterException err) { @@ -501,7 +499,7 @@ public class TwitterEngine { * @return List of Following User * @throws EngineException if Access is unavailable */ - List getFollowing(long userId) throws EngineException { + public List getFollowing(long userId) throws EngineException { try { int load = settings.getRowLimit(); IDs userIDs = twitter.getFriendsIDs(userId, -1, load); @@ -522,7 +520,7 @@ public class TwitterEngine { * @return List of Follower * @throws EngineException if Access is unavailable */ - List getFollower(long userId) throws EngineException { + public List getFollower(long userId) throws EngineException { try { int load = settings.getRowLimit(); IDs userIDs = twitter.getFollowersIDs(userId, -1, load); @@ -542,7 +540,7 @@ public class TwitterEngine { * @param tweet Tweet holder * @throws EngineException if twitter service is unavailable or media was not found */ - void uploadStatus(TweetHolder tweet) throws EngineException { + public void uploadStatus(TweetHolder tweet) throws EngineException { try { StatusUpdate mStatus = new StatusUpdate(tweet.getText()); if (tweet.isReply()) @@ -570,7 +568,7 @@ public class TwitterEngine { * @return Tweet Object * @throws EngineException if Access is unavailable */ - Tweet getStatus(long tweetId) throws EngineException { + public Tweet getStatus(long tweetId) throws EngineException { try { Status tweet = twitter.showStatus(tweetId); return new Tweet(tweet); @@ -589,7 +587,7 @@ public class TwitterEngine { * @return List of Answers * @throws EngineException if Access is unavailable */ - List getAnswers(String name, long tweetId, long sinceId) throws EngineException { + public List getAnswers(String name, long tweetId, long sinceId) throws EngineException { try { int load = settings.getRowLimit(); List answers = new LinkedList<>(); @@ -615,7 +613,7 @@ public class TwitterEngine { * @param tweetId Tweet ID * @throws EngineException if Access is unavailable */ - Tweet retweet(long tweetId) throws EngineException { + public Tweet retweet(long tweetId) throws EngineException { try { Status tweet = twitter.showStatus(tweetId); boolean retweeted = tweet.isRetweeted(); @@ -644,7 +642,7 @@ public class TwitterEngine { * @param tweetId Tweet ID * @throws EngineException if Access is unavailable */ - Tweet favorite(long tweetId) throws EngineException { + public Tweet favorite(long tweetId) throws EngineException { try { Status tweet = twitter.showStatus(tweetId); boolean retweeted = tweet.isRetweeted(); @@ -672,7 +670,7 @@ public class TwitterEngine { * @return dummy tweet * @throws EngineException if Access is unavailable */ - Tweet deleteTweet(long tweetId) throws EngineException { + public Tweet deleteTweet(long tweetId) throws EngineException { try { return new Tweet(twitter.destroyStatus(tweetId)); } catch (TwitterException err) { @@ -688,7 +686,7 @@ public class TwitterEngine { * @return List of users or empty list if no match * @throws EngineException if Access is unavailable */ - List getRetweeter(long tweetID) throws EngineException { + public List getRetweeter(long tweetID) throws EngineException { try { int load = settings.getRowLimit(); Tweet embeddedStat = getStatus(tweetID).getEmbeddedTweet(); @@ -710,7 +708,7 @@ public class TwitterEngine { * @return DM List * @throws EngineException if access is unavailable */ - List getMessages() throws EngineException { + public List getMessages() throws EngineException { try { int load = settings.getRowLimit(); List dmList = twitter.getDirectMessages(load); @@ -731,7 +729,7 @@ public class TwitterEngine { * @param messageHolder message informations * @throws EngineException if access is unavailable */ - void sendMessage(MessageHolder messageHolder) throws EngineException { + public void sendMessage(MessageHolder messageHolder) throws EngineException { try { long id = twitter.showUser(messageHolder.getUsername()).getId(); if (messageHolder.hasMedia()) { @@ -753,7 +751,7 @@ public class TwitterEngine { * @param id Message ID * @throws EngineException if Access is unavailable or message not found */ - void deleteMessage(long id) throws EngineException { + public void deleteMessage(long id) throws EngineException { try { twitter.destroyDirectMessage(id); } catch (TwitterException err) { @@ -769,7 +767,7 @@ public class TwitterEngine { * @return updated user profile * @throws EngineException if Access is unavailable */ - TwitterUser updateProfile(UserHolder userHolder) throws EngineException { + public TwitterUser updateProfile(UserHolder userHolder) throws EngineException { try { if (userHolder.hasProfileImage()) { File profileImage = new File(userHolder.getProfileImage()); @@ -798,7 +796,7 @@ public class TwitterEngine { * @return list information * @throws EngineException if access is unavailable */ - List getUserList(long userId) throws EngineException { + public List getUserList(long userId) throws EngineException { try { List result = new LinkedList<>(); ResponseList lists = twitter.getUserLists(userId); @@ -818,7 +816,7 @@ public class TwitterEngine { * @return List information * @throws EngineException if access is unavailable */ - TwitterList followUserList(long listId) throws EngineException { + public TwitterList followUserList(long listId) throws EngineException { try { UserList list = twitter.showUserList(listId); if (list.isFollowing()) { @@ -840,7 +838,7 @@ public class TwitterEngine { * @return List information * @throws EngineException if access is unavailable */ - TwitterList deleteUserList(long listId) throws EngineException { + public TwitterList deleteUserList(long listId) throws EngineException { try { return new TwitterList(twitter.destroyUserList(listId), twitterID); } catch (TwitterException err) { @@ -855,7 +853,7 @@ public class TwitterEngine { * @return list of users following the list * @throws EngineException if access is unavailable */ - List getListFollower(long listId) throws EngineException { + public List getListFollower(long listId) throws EngineException { try { return convertUserList(twitter.getUserListSubscribers(listId, -1)); } catch (TwitterException err) { @@ -870,7 +868,7 @@ public class TwitterEngine { * @return list of users * @throws EngineException if access is unavailable */ - List getListMember(long listId) throws EngineException { + public List getListMember(long listId) throws EngineException { try { return convertUserList(twitter.getUserListMembers(listId, -1)); } catch (TwitterException err) { @@ -888,7 +886,7 @@ public class TwitterEngine { * @return list of tweets * @throws EngineException if access is unavailable */ - List getListTweets(long listId, long sinceId, int page) throws EngineException { + public List getListTweets(long listId, long sinceId, int page) throws EngineException { try { int load = settings.getRowLimit(); Paging paging = new Paging(page, load, sinceId); @@ -988,140 +986,4 @@ public class TwitterEngine { throw new EngineException(EngineException.FILENOTFOUND); } } - - - /** - * Internal Exception - */ - public static class EngineException extends Exception { - - private static final int FILENOTFOUND = 600; - private static final int TOKENNOTSET = 601; - - @StringRes - private int messageResource; - private boolean hardFault = false; - private boolean statusNotFound = false; - - /** - * Constructor for Twitter4J errors - * - * @param error Twitter4J Exception - */ - private EngineException(TwitterException error) { - super(error); - switch (error.getErrorCode()) { - case 88: - case 420: // - case 429: // Rate limit exceeded! - messageResource = R.string.error_limit_exceeded; - break; - - case 17: - case 50: // USER not found - case 63: // USER suspended - messageResource = R.string.error_user_not_found; - statusNotFound = true; - hardFault = true; - break; - - case 32: - messageResource = R.string.error_request_token; - break; - - case 34: // - case 144: // TWEET not found - messageResource = R.string.error_not_found; - statusNotFound = true; - hardFault = true; - break; - - case 150: - messageResource = R.string.error_send_dm; - break; - - case 136: - case 179: - messageResource = R.string.info_not_authorized; - hardFault = true; - break; - - case 186: - messageResource = R.string.error_status_too_long; - break; - - case 187: - messageResource = R.string.error_duplicate_status; - break; - - case 349: - messageResource = R.string.error_dm_send; - break; - - case 354: - messageResource = R.string.error_dm_length; - break; - - case 89: - messageResource = R.string.error_accesstoken; - break; - - default: - if (error.getStatusCode() == 401) - messageResource = R.string.info_not_authorized; - else - messageResource = R.string.error_connection_failed; - break; - } - } - - /** - * Constructor for non Twitter4J errors - * - * @param errorCode custom error code - */ - private EngineException(int errorCode) { - switch (errorCode) { - case FILENOTFOUND: - messageResource = R.string.error_media_not_found; - break; - - case TOKENNOTSET: - messageResource = R.string.error_token_not_set; - break; - - default: - messageResource = R.string.info_error; - break; - } - } - - /** - * get String resource of error message - * - * @return string recource for - */ - @StringRes - int getMessageResource() { - return messageResource; - } - - /** - * return if activity should closed - * - * @return true if hard fault - */ - boolean isHardFault() { - return hardFault; - } - - /** - * return if tweet or author was not found - * - * @return true if author or tweet not found - */ - boolean statusNotFound() { - return statusNotFound; - } - } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/fragment/ListFragment.java b/app/src/main/java/org/nuclearfog/twidda/fragment/ListFragment.java index fff03ed4..a26b6e36 100644 --- a/app/src/main/java/org/nuclearfog/twidda/fragment/ListFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/fragment/ListFragment.java @@ -7,6 +7,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog.Builder; @@ -23,11 +24,15 @@ import org.nuclearfog.twidda.activity.UserProfile; import org.nuclearfog.twidda.adapter.ListAdapter; import org.nuclearfog.twidda.adapter.ListAdapter.ListClickListener; import org.nuclearfog.twidda.backend.TwitterListLoader; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.items.TwitterList; import org.nuclearfog.twidda.database.GlobalSettings; +import java.util.List; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.RUNNING; +import static android.widget.Toast.LENGTH_SHORT; import static org.nuclearfog.twidda.activity.ListDetail.KEY_LISTDETAIL_ID; import static org.nuclearfog.twidda.activity.ListDetail.KEY_LISTDETAIL_NAME; import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_ID; @@ -159,12 +164,37 @@ public class ListFragment extends Fragment implements OnRefreshListener, ListCli } } - - public ListAdapter getAdapter() { - return adapter; + /** + * set data to list + * + * @param data List of Twitter list data + */ + public void setData(List data) { + adapter.setData(data); } + /** + * update item in list + * + * @param item Twitter list item + */ + public void updateItem(TwitterList item) { + adapter.updateItem(item); + } + /** + * remove item with specific ID + * + * @param id ID of list to remove + */ + public void removeItem(long id) { + adapter.removeItem(id); + } + + /** + * called from {@link TwitterListLoader} to enable or disable RefreshLayout + * @param enable true to enable RefreshLayout with delay + */ public void setRefresh(boolean enable) { if (enable) { reloadLayout.postDelayed(new Runnable() { @@ -179,6 +209,25 @@ public class ListFragment extends Fragment implements OnRefreshListener, ListCli } } + /** + * called from {@link TwitterListLoader} if an error occurs + * + * @param err Twitter exception + */ + public void onError(EngineException err) { + if (err.isErrorDefined()) { + if (err.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += err.getRetryAfter(); + Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show(); + } + } + private void load() { listTask = new TwitterListLoader(this, LOAD); diff --git a/app/src/main/java/org/nuclearfog/twidda/fragment/MessageFragment.java b/app/src/main/java/org/nuclearfog/twidda/fragment/MessageFragment.java index 9fb26f70..5b7eb3b1 100644 --- a/app/src/main/java/org/nuclearfog/twidda/fragment/MessageFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/fragment/MessageFragment.java @@ -27,9 +27,13 @@ import org.nuclearfog.twidda.adapter.MessageAdapter; import org.nuclearfog.twidda.adapter.MessageAdapter.OnItemSelected; import org.nuclearfog.twidda.backend.MessageListLoader; import org.nuclearfog.twidda.backend.MessageListLoader.Mode; +import org.nuclearfog.twidda.backend.TrendListLoader; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.items.Message; import org.nuclearfog.twidda.database.GlobalSettings; +import java.util.List; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.RUNNING; import static android.widget.Toast.LENGTH_SHORT; @@ -149,12 +153,28 @@ public class MessageFragment extends Fragment implements OnRefreshListener, OnIt } } - - public MessageAdapter getAdapter() { - return adapter; + /** + * set data to list + * + * @param data list of direct messages + */ + public void setData(List data) { + adapter.replaceAll(data); } + /** + * remove item from list + * + * @param id ID of the item + */ + public void removeItem(long id) { + adapter.remove(id); + } + /** + * called from {@link TrendListLoader} to enable or disable RefreshLayout + * @param enable true to enable RefreshLayout with delay + */ public void setRefresh(boolean enable) { if (enable) { reload.postDelayed(new Runnable() { @@ -169,6 +189,25 @@ public class MessageFragment extends Fragment implements OnRefreshListener, OnIt } } + /** + * called from {@link MessageListLoader} if an error occurs + * + * @param err Twitter exception + */ + public void onError(EngineException err) { + if (err.isErrorDefined()) { + if (err.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += err.getRetryAfter(); + Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show(); + } + } + private void load(Mode m) { messageTask = new MessageListLoader(this, m); diff --git a/app/src/main/java/org/nuclearfog/twidda/fragment/TrendFragment.java b/app/src/main/java/org/nuclearfog/twidda/fragment/TrendFragment.java index c56b39ac..da78fff3 100644 --- a/app/src/main/java/org/nuclearfog/twidda/fragment/TrendFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/fragment/TrendFragment.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; @@ -14,16 +15,21 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; +import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.SearchPage; import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver; import org.nuclearfog.twidda.adapter.TrendAdapter; import org.nuclearfog.twidda.adapter.TrendAdapter.TrendClickListener; import org.nuclearfog.twidda.backend.TrendListLoader; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.items.TwitterTrend; import org.nuclearfog.twidda.database.GlobalSettings; +import java.util.List; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.RUNNING; +import static android.widget.Toast.LENGTH_SHORT; import static org.nuclearfog.twidda.activity.SearchPage.KEY_SEARCH_QUERY; @@ -115,12 +121,48 @@ public class TrendFragment extends Fragment implements OnRefreshListener, TrendC load(); } + /** + * set trend data to list + * + * @param data Trend data + */ + public void setData(List data) { + adapter.setData(data); + } - public TrendAdapter getAdapter() { - return adapter; + /** + * check if list is empty + * + * @return true if list is empty + */ + public boolean isEmpty() { + return adapter == null || adapter.isEmpty(); } + /** + * called from {@link TrendListLoader} if an error occurs + * + * @param err Twitter exception + */ + public void onError(EngineException err) { + if (err.isErrorDefined()) { + if (err.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += err.getRetryAfter(); + Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show(); + } + } + + /** + * called from {@link TrendListLoader} to enable or disable RefreshLayout + * @param enable true to enable RefreshLayout with delay + */ public void setRefresh(boolean enable) { if (enable) { reload.postDelayed(new Runnable() { diff --git a/app/src/main/java/org/nuclearfog/twidda/fragment/TweetFragment.java b/app/src/main/java/org/nuclearfog/twidda/fragment/TweetFragment.java index 377667c1..20b84731 100644 --- a/app/src/main/java/org/nuclearfog/twidda/fragment/TweetFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/fragment/TweetFragment.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; @@ -14,17 +15,22 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; +import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.TweetDetail; import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver; import org.nuclearfog.twidda.adapter.TweetAdapter; import org.nuclearfog.twidda.adapter.TweetAdapter.TweetClickListener; import org.nuclearfog.twidda.backend.TweetListLoader; import org.nuclearfog.twidda.backend.TweetListLoader.Mode; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.items.Tweet; import org.nuclearfog.twidda.database.GlobalSettings; +import java.util.List; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.RUNNING; +import static android.widget.Toast.LENGTH_SHORT; import static org.nuclearfog.twidda.activity.TweetDetail.KEY_TWEET_ID; import static org.nuclearfog.twidda.activity.TweetDetail.KEY_TWEET_NAME; @@ -154,12 +160,39 @@ public class TweetFragment extends Fragment implements OnRefreshListener, TweetC tweetTask = null; } - - public TweetAdapter getAdapter() { - return adapter; + /** + * get Id of the first Tweet + * + * @return ID of the first tweet or zero if list is empty + */ + public long getTopId() { + if (adapter != null && !adapter.isEmpty()) + return adapter.getItemId(0); + return 0; } + /** + * replace all tweets of the list + * + * @param tweets list of new tweets + */ + public void add(List tweets) { + adapter.add(tweets); + } + /** + * attach new tweets to the top of the list + * + * @param tweets list of new tweets + */ + public void addTop(List tweets) { + adapter.addFirst(tweets); + } + + /** + * called from {@link TweetListLoader} to enable or disable RefreshLayout + * @param enable true to enable RefreshLayout with delay + */ public void setRefresh(boolean enable) { if (enable) { reload.postDelayed(new Runnable() { @@ -174,6 +207,25 @@ public class TweetFragment extends Fragment implements OnRefreshListener, TweetC } } + /** + * called from {@link TweetListLoader} if an error occurs + * + * @param err Twitter exception + */ + public void onError(EngineException err) { + if (err.isErrorDefined()) { + if (err.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += err.getRetryAfter(); + Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(getContext(), err.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), err.getMessage(), LENGTH_SHORT).show(); + } + } + private void load() { switch (mode) { diff --git a/app/src/main/java/org/nuclearfog/twidda/fragment/UserFragment.java b/app/src/main/java/org/nuclearfog/twidda/fragment/UserFragment.java index a57bd797..5896afd1 100644 --- a/app/src/main/java/org/nuclearfog/twidda/fragment/UserFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/fragment/UserFragment.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; @@ -14,17 +15,22 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; +import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.activity.UserProfile; import org.nuclearfog.twidda.adapter.FragmentAdapter.FragmentChangeObserver; import org.nuclearfog.twidda.adapter.UserAdapter; import org.nuclearfog.twidda.adapter.UserAdapter.UserClickListener; import org.nuclearfog.twidda.backend.UserListLoader; import org.nuclearfog.twidda.backend.UserListLoader.Mode; +import org.nuclearfog.twidda.backend.engine.EngineException; import org.nuclearfog.twidda.backend.items.TwitterUser; import org.nuclearfog.twidda.database.GlobalSettings; +import java.util.List; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.RUNNING; +import static android.widget.Toast.LENGTH_SHORT; import static org.nuclearfog.twidda.activity.UserProfile.KEY_PROFILE_ID; @@ -123,12 +129,19 @@ public class UserFragment extends Fragment implements OnRefreshListener, UserCli public void onDataClear() { } - - public UserAdapter getAdapter() { - return adapter; + /** + * set List data + * + * @param data list of twitter users + */ + public void setData(List data) { + adapter.replaceAll(data); } - + /** + * called from {@link UserListLoader} to enable or disable RefreshLayout + * @param enable true to enable RefreshLayout with delay + */ public void setRefresh(boolean enable) { if (enable) { reload.postDelayed(new Runnable() { @@ -143,6 +156,25 @@ public class UserFragment extends Fragment implements OnRefreshListener, UserCli } } + /** + * called when an error occurs + * + * @param error Engine exception + */ + public void onError(EngineException error) { + if (error.isErrorDefined()) { + if (error.isRateLimitExceeded()) { + String errorMsg = getString(R.string.error_limit_exceeded); + errorMsg += error.getRetryAfter(); + Toast.makeText(getContext(), errorMsg, LENGTH_SHORT).show(); + } else { + Toast.makeText(getContext(), error.getMessageResource(), LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), error.getMessage(), LENGTH_SHORT).show(); + } + } + private void load() { switch (mode) { diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 8e46e1d6..c560bf4f 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -22,7 +22,7 @@ Keine Internetverbindung! PIN eingeben! Datenbank löschen? - Anfragelimit erreicht! + "Anfragelimit erreicht! Entsperrt nach: " Fehler beim Senden! Tweet gesendet Fehler! diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3cf023b7..4c778c38 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,7 +30,7 @@ connection failed Enter PIN! delete database? - "Rate limit exceeded!" + "Rate limit exceeded! Retry after: " error while sending tweet sent Error!