diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java index 931e92ef2..c8281ebd6 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java @@ -162,7 +162,7 @@ public abstract class BaseMainActivity extends BaseActivity private DisplayNotificationsFragment notificationsFragment; private static final int ERROR_DIALOG_REQUEST_CODE = 97; private static BroadcastReceiver receive_data, receive_federated_data, receive_local_data; - private boolean display_local, display_global; + private boolean display_direct, display_local, display_global; public static int countNewStatus = 0; public static int countNewNotifications = 0; private String userIdService; @@ -200,6 +200,7 @@ public abstract class BaseMainActivity extends BaseActivity } setContentView(R.layout.activity_main); + display_direct = sharedpreferences.getBoolean(Helper.SET_DISPLAY_DIRECT, true); display_local = sharedpreferences.getBoolean(Helper.SET_DISPLAY_LOCAL, true); display_global = sharedpreferences.getBoolean(Helper.SET_DISPLAY_GLOBAL, true); @@ -228,10 +229,13 @@ public abstract class BaseMainActivity extends BaseActivity tabLayout = findViewById(R.id.tabLayout); TabLayout.Tab tabHome = tabLayout.newTab(); TabLayout.Tab tabNotif = tabLayout.newTab(); + TabLayout.Tab tabDirect = tabLayout.newTab(); TabLayout.Tab tabLocal = tabLayout.newTab(); TabLayout.Tab tabPublic = tabLayout.newTab(); + tabHome.setCustomView(R.layout.tab_badge); tabNotif.setCustomView(R.layout.tab_badge); + tabDirect.setCustomView(R.layout.tab_badge); tabLocal.setCustomView(R.layout.tab_badge); tabPublic.setCustomView(R.layout.tab_badge); @@ -252,6 +256,11 @@ public abstract class BaseMainActivity extends BaseActivity iconNotif.setImageResource(R.drawable.ic_notifications); + @SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId") + ImageView iconDirect = tabDirect.getCustomView().findViewById(R.id.tab_icon); + iconDirect.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); + iconDirect.setImageResource(R.drawable.ic_direct_messages); + @SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId") ImageView iconLocal = tabLocal.getCustomView().findViewById(R.id.tab_icon); iconLocal.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); @@ -278,8 +287,10 @@ public abstract class BaseMainActivity extends BaseActivity changeDrawableColor(getApplicationContext(), R.drawable.ic_home,R.color.dark_text); changeDrawableColor(getApplicationContext(), R.drawable.ic_notifications,R.color.dark_text); + changeDrawableColor(getApplicationContext(), R.drawable.ic_direct_messages,R.color.dark_text); changeDrawableColor(getApplicationContext(), R.drawable.ic_people,R.color.dark_text); changeDrawableColor(getApplicationContext(), R.drawable.ic_public,R.color.dark_text); + startSreaming(); tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); tabLayout.setTabMode(TabLayout.MODE_FIXED); @@ -287,6 +298,8 @@ public abstract class BaseMainActivity extends BaseActivity tabLayout.addTab(tabHome); tabLayout.addTab(tabNotif); + if( display_direct) + tabLayout.addTab(tabDirect); if( display_local) tabLayout.addTab(tabLocal); if( display_global) @@ -385,15 +398,22 @@ public abstract class BaseMainActivity extends BaseActivity } }); - if( tabStrip.getChildCount() > 2) - tabStrip.getChildAt(2).setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - return manageFilters(tabStrip, sharedpreferences); - } - }); - if( tabStrip.getChildCount() == 4) - tabStrip.getChildAt(3).setOnLongClickListener(new View.OnLongClickListener() { + if( tabStrip.getChildCount() > 2 && !display_direct) + tabStrip.getChildAt(2).setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + return manageFilters(tabStrip, sharedpreferences); + } + }); + else if ( tabStrip.getChildCount() > 3 && display_direct) + tabStrip.getChildAt(3).setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + return manageFilters(tabStrip, sharedpreferences); + } + }); + if( tabStrip.getChildCount() == 5) + tabStrip.getChildAt(4).setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { return manageFilters(tabStrip, sharedpreferences); @@ -403,6 +423,8 @@ public abstract class BaseMainActivity extends BaseActivity viewPager = findViewById(R.id.viewpager); countPage = 2; + if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_DIRECT, true)) + countPage++; if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_LOCAL, true)) countPage++; if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_GLOBAL, true)) @@ -477,7 +499,9 @@ public abstract class BaseMainActivity extends BaseActivity displayStatusFragment.scrollToTop(); break; case 2: - if (display_local) + if (display_direct) + updateTimeLine(RetrieveFeedsAsyncTask.Type.DIRECT, 0); + else if (display_local) updateTimeLine(RetrieveFeedsAsyncTask.Type.LOCAL, 0); else if (display_global) updateTimeLine(RetrieveFeedsAsyncTask.Type.PUBLIC, 0); @@ -485,6 +509,14 @@ public abstract class BaseMainActivity extends BaseActivity displayStatusFragment.scrollToTop(); break; case 3: + if (display_direct && display_local) + updateTimeLine(RetrieveFeedsAsyncTask.Type.LOCAL, 0); + else + updateTimeLine(RetrieveFeedsAsyncTask.Type.PUBLIC, 0); + displayStatusFragment = ((DisplayStatusFragment) fragment); + displayStatusFragment.scrollToTop(); + break; + case 4: displayStatusFragment = ((DisplayStatusFragment) fragment); displayStatusFragment.scrollToTop(); updateTimeLine(RetrieveFeedsAsyncTask.Type.PUBLIC, 0); @@ -541,6 +573,7 @@ public abstract class BaseMainActivity extends BaseActivity case 0: case 2: case 3: + case 4: DisplayStatusFragment displayStatusFragment = ((DisplayStatusFragment) fragment); displayStatusFragment.scrollToTop(); break; @@ -1853,8 +1886,22 @@ public abstract class BaseMainActivity extends BaseActivity @SuppressWarnings("ConstantConditions") public void updateTimeLine(RetrieveFeedsAsyncTask.Type type, int value){ - if( type == RetrieveFeedsAsyncTask.Type.LOCAL){ - if( tabLayout.getTabAt(2) != null && display_local){ + + + if( type == RetrieveFeedsAsyncTask.Type.DIRECT && display_direct){ + if( tabLayout.getTabAt(2) != null ){ + View tabDirect = tabLayout.getTabAt(2).getCustomView(); + assert tabDirect != null; + TextView tabCounterDirect = tabDirect.findViewById(R.id.tab_counter); + tabCounterDirect.setText(String.valueOf(value)); + if( value > 0){ + tabCounterDirect.setVisibility(View.VISIBLE); + }else { + tabCounterDirect.setVisibility(View.GONE); + } + } + }else if( type == RetrieveFeedsAsyncTask.Type.LOCAL && display_local){ + if( tabLayout.getTabAt(2) != null && !display_direct){ View tabLocal = tabLayout.getTabAt(2).getCustomView(); assert tabLocal != null; TextView tabCounterLocal = tabLocal.findViewById(R.id.tab_counter); @@ -1864,10 +1911,20 @@ public abstract class BaseMainActivity extends BaseActivity }else { tabCounterLocal.setVisibility(View.GONE); } + }else if( tabLayout.getTabAt(3) != null && display_direct){ + View tabLocal = tabLayout.getTabAt(3).getCustomView(); + assert tabLocal != null; + TextView tabCounterLocal = tabLocal.findViewById(R.id.tab_counter); + tabCounterLocal.setText(String.valueOf(value)); + if( value > 0){ + tabCounterLocal.setVisibility(View.VISIBLE); + }else { + tabCounterLocal.setVisibility(View.GONE); + } } - }else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC){ - if( tabLayout.getTabAt(3) != null && display_local){ - View tabPublic = tabLayout.getTabAt(3).getCustomView(); + }else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC && display_global){ + if( tabLayout.getTabAt(4) != null && display_local && display_direct){ + View tabPublic = tabLayout.getTabAt(4).getCustomView(); assert tabPublic != null; TextView tabCounterPublic = tabPublic.findViewById(R.id.tab_counter); tabCounterPublic.setText(String.valueOf(value)); @@ -1876,7 +1933,17 @@ public abstract class BaseMainActivity extends BaseActivity }else { tabCounterPublic.setVisibility(View.GONE); } - }else if( tabLayout.getTabAt(2) != null && !display_local && display_global){ + }else if( tabLayout.getTabAt(2) != null && !display_local && !display_direct){ + View tabPublic = tabLayout.getTabAt(2).getCustomView(); + assert tabPublic != null; + TextView tabCounterPublic = tabPublic.findViewById(R.id.tab_counter); + tabCounterPublic.setText(String.valueOf(value)); + if( value > 0){ + tabCounterPublic.setVisibility(View.VISIBLE); + }else { + tabCounterPublic.setVisibility(View.GONE); + } + }else if( tabLayout.getTabAt(3) != null && ((!display_local && display_direct) || (display_local && !display_direct) )){ View tabPublic = tabLayout.getTabAt(2).getCustomView(); assert tabPublic != null; TextView tabCounterPublic = tabPublic.findViewById(R.id.tab_counter); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java index feb5915ba..4c8ff65e0 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java @@ -58,6 +58,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { public enum Type{ HOME, LOCAL, + DIRECT, PUBLIC, HASHTAG, LIST, @@ -137,6 +138,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { case PUBLIC: apiResponse = api.getPublicTimeline(false, max_id); break; + case DIRECT: + apiResponse = api.getDirectTimeline(max_id); + break; case REMOTE_INSTANCE: SQLiteDatabase db = Sqlite.getInstance(this.contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); List remoteInstanceObj = new InstancesDAO(this.contextReference.get(), db).getInstanceByName(this.instanceName); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java index 4f4e1eb86..1aa469793 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java @@ -489,6 +489,55 @@ public class API { } + /** + * Retrieves direct timeline for the account *synchronously* + * @param max_id String id max + * @return APIResponse + */ + public APIResponse getDirectTimeline( String max_id) { + return getDirectTimeline(max_id, null, tootPerPage); + } + + + /** + * Retrieves direct timeline for the account *synchronously* + * @param max_id String id max + * @param since_id String since the id + * @param limit int limit - max value 40 + * @return APIResponse + */ + private APIResponse getDirectTimeline(String max_id, String since_id, int limit) { + + HashMap params = new HashMap<>(); + if (max_id != null) + params.put("max_id", max_id); + if (since_id != null) + params.put("since_id", since_id); + if (0 > limit || limit > 80) + limit = 80; + params.put("limit",String.valueOf(limit)); + statuses = new ArrayList<>(); + try { + HttpsConnection httpsConnection = new HttpsConnection(context); + String response = httpsConnection.get(getAbsoluteUrl("/timelines/direct"), 60, params, prefKeyOauthTokenT); + apiResponse.setSince_id(httpsConnection.getSince_id()); + apiResponse.setMax_id(httpsConnection.getMax_id()); + statuses = parseStatuses(new JSONArray(response)); + } catch (HttpsConnection.HttpsConnectionException e) { + setError(e.getStatusCode(), e); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + apiResponse.setStatuses(statuses); + return apiResponse; + } + /** * Retrieves home timeline for the account *synchronously* @@ -728,6 +777,8 @@ public class API { limit = 40; params.put("limit",String.valueOf(limit)); statuses = new ArrayList<>(); + if( tag == null) + return null; try { HttpsConnection httpsConnection = new HttpsConnection(context); String response = httpsConnection.get(getAbsoluteUrl(String.format("/timelines/tag/%s",tag.trim())), 60, params, prefKeyOauthTokenT); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java index ad052bf35..2d707cfd5 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java @@ -321,8 +321,11 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn mainLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE); //Discards 404 - error which can often happen due to toots which have been deleted - if( apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 ){ - Toast.makeText(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show(); + if( apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){ + if( apiResponse == null) + Toast.makeText(context, R.string.toast_error,Toast.LENGTH_LONG).show(); + else + Toast.makeText(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show(); swipeRefreshLayout.setRefreshing(false); flag_loading = false; return; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index c1a8f84ff..706d08e6a 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -316,6 +316,7 @@ public class Helper { public static final String SET_COOKIES = "set_cookies"; public static final String SET_FOLDER_RECORD = "set_folder_record"; public static final String SET_TOOT_VISIBILITY = "set_toot_visibility"; + public static final String SET_DISPLAY_DIRECT = "set_display_direct"; public static final String SET_DISPLAY_LOCAL = "set_display_local"; public static final String SET_DISPLAY_GLOBAL = "set_display_global"; public static final String SET_AUTOMATICALLY_SPLIT_TOOTS = "set_automatically_split_toots"; diff --git a/app/src/main/res/drawable-hdpi/ic_direct_messages.png b/app/src/main/res/drawable-hdpi/ic_direct_messages.png new file mode 100644 index 000000000..8e8bbc834 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_direct_messages.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_direct_messages.png b/app/src/main/res/drawable-ldpi/ic_direct_messages.png new file mode 100644 index 000000000..1c802780c Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_direct_messages.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_direct_messages.png b/app/src/main/res/drawable-mdpi/ic_direct_messages.png new file mode 100644 index 000000000..45b848113 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_direct_messages.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_direct_messages.png b/app/src/main/res/drawable-xhdpi/ic_direct_messages.png new file mode 100644 index 000000000..9c456f0ca Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_direct_messages.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_direct_messages.png b/app/src/main/res/drawable-xxhdpi/ic_direct_messages.png new file mode 100644 index 000000000..f2801ad5f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_direct_messages.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_direct_messages.png b/app/src/main/res/drawable-xxxhdpi/ic_direct_messages.png new file mode 100644 index 000000000..8922e17aa Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_direct_messages.png differ