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 f39568543..8df5e0032 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 @@ -180,11 +180,11 @@ public abstract class BaseMainActivity extends BaseActivity private RelativeLayout main_app_container; private Stack stackBack = new Stack<>(); public static List filters = new ArrayList<>(); - private DisplayStatusFragment homeFragment, federatedFragment, localFragment; + private DisplayStatusFragment homeFragment, federatedFragment, localFragment, artFragment; 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_direct, display_local, display_global; + private boolean display_direct, display_local, display_global, display_art; public static int countNewStatus = 0; public static int countNewNotifications = 0; private String userIdService; @@ -232,7 +232,7 @@ public abstract class BaseMainActivity extends BaseActivity 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); - + display_art = sharedpreferences.getBoolean(Helper.SET_DISPLAY_ART, true); //Test if user is still log in if( ! Helper.isLoggedIn(getApplicationContext())) { //It is not, the user is redirected to the login page @@ -274,13 +274,14 @@ public abstract class BaseMainActivity extends BaseActivity TabLayout.Tab tabDirect = tabLayout.newTab(); TabLayout.Tab tabLocal = tabLayout.newTab(); TabLayout.Tab tabPublic = tabLayout.newTab(); - + TabLayout.Tab tabArt = 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); + tabArt.setCustomView(R.layout.tab_badge); @SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId") ImageView iconHome = tabHome.getCustomView().findViewById(R.id.tab_icon); @@ -310,18 +311,25 @@ public abstract class BaseMainActivity extends BaseActivity ImageView iconGlobal = tabPublic.getCustomView().findViewById(R.id.tab_icon); iconGlobal.setImageResource(R.drawable.ic_public); + + @SuppressWarnings("ConstantConditions") @SuppressLint("CutPasteId") + ImageView iconArt = tabPublic.getCustomView().findViewById(R.id.tab_icon); + iconArt.setImageResource(R.drawable.ic_color_lens); + if( theme == THEME_LIGHT){ iconHome.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.action_light_header), PorterDuff.Mode.SRC_IN); iconNotif.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.action_light_header), PorterDuff.Mode.SRC_IN); iconDirect.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.action_light_header), PorterDuff.Mode.SRC_IN); iconLocal.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.action_light_header), PorterDuff.Mode.SRC_IN); iconGlobal.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.action_light_header), PorterDuff.Mode.SRC_IN); + iconArt.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.action_light_header), PorterDuff.Mode.SRC_IN); }else { iconHome.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); iconNotif.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); iconDirect.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); iconLocal.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); iconGlobal.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); + iconArt.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.dark_text), PorterDuff.Mode.SRC_IN); } if (theme == Helper.THEME_DARK) { @@ -669,12 +677,14 @@ public abstract class BaseMainActivity extends BaseActivity changeDrawableColor(getApplicationContext(), R.drawable.ic_direct_messages,R.color.dark_icon); changeDrawableColor(getApplicationContext(), R.drawable.ic_people,R.color.dark_icon); changeDrawableColor(getApplicationContext(), R.drawable.ic_public,R.color.dark_icon); + changeDrawableColor(getApplicationContext(), R.drawable.ic_color_lens,R.color.dark_icon); }else { 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); + changeDrawableColor(getApplicationContext(), R.drawable.ic_color_lens,R.color.dark_text); } @@ -691,7 +701,8 @@ public abstract class BaseMainActivity extends BaseActivity tabLayout.addTab(tabLocal); if( display_global) tabLayout.addTab(tabPublic); - + if( display_art) + tabLayout.addTab(tabArt); //Display filter for notification when long pressing the tab final LinearLayout tabStrip = (LinearLayout) tabLayout.getChildAt(0); @@ -816,6 +827,8 @@ public abstract class BaseMainActivity extends BaseActivity countPage++; if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_GLOBAL, true)) countPage++; + if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_ART, true)) + countPage++; viewPager.setOffscreenPageLimit(countPage<=4?countPage:4); main_app_container = findViewById(R.id.main_app_container); @@ -2343,7 +2356,12 @@ public abstract class BaseMainActivity extends BaseActivity bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.PUBLIC); statusFragment.setArguments(bundle); return statusFragment; - }else if (position == 3 && display_local && display_direct){ + }else if(position == 2 && display_art ){ + statusFragment = new DisplayStatusFragment(); + bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.ART); + statusFragment.setArguments(bundle); + return statusFragment; + } else if (position == 3 && display_local && display_direct){ statusFragment = new DisplayStatusFragment(); bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.LOCAL); statusFragment.setArguments(bundle); @@ -2358,12 +2376,29 @@ public abstract class BaseMainActivity extends BaseActivity bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.PUBLIC); statusFragment.setArguments(bundle); return statusFragment; - }else if (position == 4 && display_global && countPage == 5){ + }else if (position == 3 ){ + statusFragment = new DisplayStatusFragment(); + bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.ART); + statusFragment.setArguments(bundle); + return statusFragment; + } + else if (position == 4 && display_global && countPage == 5){ statusFragment = new DisplayStatusFragment(); bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.PUBLIC); statusFragment.setArguments(bundle); return statusFragment; - } else{ //Here it's a search fragment + } else if (position == 4 && !display_global && countPage == 5){ + statusFragment = new DisplayStatusFragment(); + bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.ART); + statusFragment.setArguments(bundle); + return statusFragment; + } else if (position == 5 && countPage == 6){ + statusFragment = new DisplayStatusFragment(); + bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.ART); + statusFragment.setArguments(bundle); + return statusFragment; + } + else{ //Here it's a search fragment statusFragment = new DisplayStatusFragment(); bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.TAG); if( tabLayout.getTabAt(position) != null && tabLayout.getTabAt(position).getText() != null) @@ -2391,18 +2426,26 @@ public abstract class BaseMainActivity extends BaseActivity else if ( !display_direct && display_global) federatedFragment = (DisplayStatusFragment) createdFragment; else - federatedFragment = (DisplayStatusFragment) createdFragment; + artFragment = (DisplayStatusFragment) createdFragment; case 3: if( display_direct && display_local) localFragment = (DisplayStatusFragment) createdFragment; else if( !display_direct && display_local && display_global) federatedFragment = (DisplayStatusFragment) createdFragment; - else + else if( display_direct && display_global) federatedFragment = (DisplayStatusFragment) createdFragment; + else + artFragment = (DisplayStatusFragment) createdFragment; break; case 4: if( display_direct && display_local && display_global) federatedFragment = (DisplayStatusFragment) createdFragment; + else + artFragment = (DisplayStatusFragment) createdFragment; + break; + case 5: + if( display_direct && display_local && display_global && display_art) + artFragment = (DisplayStatusFragment) createdFragment; break; } return createdFragment; @@ -2563,6 +2606,58 @@ public abstract class BaseMainActivity extends BaseActivity } } } + }else if( type == RetrieveFeedsAsyncTask.Type.ART ){ + if( display_art){ + if( tabLayout.getTabAt(2) != null && !display_local && !display_direct && !display_global){ + View tabArt = tabLayout.getTabAt(2).getCustomView(); + assert tabArt != null; + TextView tabCounterArt = tabArt.findViewById(R.id.tab_counter); + tabCounterArt.setText(String.valueOf(value)); + if( value > 0){ + tabCounterArt.setVisibility(View.VISIBLE); + }else { + tabCounterArt.setVisibility(View.GONE); + } + }else if( tabLayout.getTabAt(3) != null && ( + (!display_local && !display_direct && display_global) || + (!display_global && !display_direct && display_local) || + (!display_global && !display_local && display_direct) + )){ + View tabArt = tabLayout.getTabAt(3).getCustomView(); + assert tabArt != null; + TextView tabCounterArt = tabArt.findViewById(R.id.tab_counter); + tabCounterArt.setText(String.valueOf(value)); + if( value > 0){ + tabCounterArt.setVisibility(View.VISIBLE); + }else { + tabCounterArt.setVisibility(View.GONE); + } + }else if( tabLayout.getTabAt(4) != null && ( + (!display_direct && display_local && display_global) || + (!display_local && display_direct && display_global) || + (!display_global && display_local && display_direct) + )){ + View tabArt = tabLayout.getTabAt(4).getCustomView(); + assert tabArt != null; + TextView tabCounterArt = tabArt.findViewById(R.id.tab_counter); + tabCounterArt.setText(String.valueOf(value)); + if( value > 0){ + tabCounterArt.setVisibility(View.VISIBLE); + }else { + tabCounterArt.setVisibility(View.GONE); + } + }else if( tabLayout.getTabAt(5) != null && display_local && display_direct && display_global){ + View tabArt = tabLayout.getTabAt(5).getCustomView(); + assert tabArt != null; + TextView tabCounterArt = tabArt.findViewById(R.id.tab_counter); + tabCounterArt.setText(String.valueOf(value)); + if( value > 0){ + tabCounterArt.setVisibility(View.VISIBLE); + }else { + tabCounterArt.setVisibility(View.GONE); + } + } + } } } 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 3a86e6bb5..a21c29b81 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 @@ -71,7 +71,8 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { CACHE_BOOKMARKS, CACHE_BOOKMARKS_PEERTUBE, CACHE_STATUS, - REMOTE_INSTANCE + REMOTE_INSTANCE, + ART } @@ -190,6 +191,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { case TAG: apiResponse = api.getPublicTimelineTag(tag, false, max_id); break; + case ART: + apiResponse = api.getArtTimeline(false, max_id); + break; case CACHE_BOOKMARKS: apiResponse = new APIResponse(); db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); 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 d3bcd8b98..ce5970706 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 @@ -1084,6 +1084,41 @@ public class API { return apiResponse; } + + + + /** + * Retrieves art timeline + * @param local boolean only local timeline + * @param max_id String id max + * @return APIResponse + */ + @SuppressWarnings("SameParameterValue") + public APIResponse getArtTimeline(boolean local, String max_id){ + APIResponse apiResponse = getPublicTimelineTag("mastoart", local, true, max_id, null, tootPerPage); + APIResponse apiResponseReply = new APIResponse(); + if( apiResponse != null){ + apiResponseReply.setMax_id(apiResponse.getMax_id()); + apiResponseReply.setSince_id(apiResponse.getSince_id()); + apiResponseReply.setStatuses(new ArrayList<>()); + if( apiResponse.getStatuses() != null && apiResponse.getStatuses().size() > 0){ + for( Status status: apiResponse.getStatuses()){ + if( status.getMedia_attachments().size() > 1){ + for(Attachment attachment: status.getMedia_attachments()){ + ArrayList attachments = new ArrayList<>(); + attachments.add(attachment); + status.setMedia_attachments(attachments); + apiResponseReply.getStatuses().add(status); + } + }else { + apiResponseReply.getStatuses().add(status); + } + } + } + } + return apiResponseReply; + } + /** * Retrieves public tag timeline *synchronously* * @param tag String @@ -1093,7 +1128,7 @@ public class API { */ @SuppressWarnings("SameParameterValue") public APIResponse getPublicTimelineTag(String tag, boolean local, String max_id){ - return getPublicTimelineTag(tag, local, max_id, null, tootPerPage); + return getPublicTimelineTag(tag, local, false, max_id, null, tootPerPage); } /** * Retrieves public tag timeline *synchronously* @@ -1105,7 +1140,7 @@ public class API { * @return APIResponse */ @SuppressWarnings("SameParameterValue") - private APIResponse getPublicTimelineTag(String tag, boolean local, String max_id, String since_id, int limit){ + private APIResponse getPublicTimelineTag(String tag, boolean local, boolean onlymedia, String max_id, String since_id, int limit){ HashMap params = new HashMap<>(); if( local) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java index be41b103e..7b09c2722 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java @@ -219,7 +219,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct @Override public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); - if( holder.getItemViewType() == DISPLAYED_STATUS || holder.getItemViewType() == COMPACT_STATUS) { + if( type != RetrieveFeedsAsyncTask.Type.ART && (holder.getItemViewType() == DISPLAYED_STATUS || holder.getItemViewType() == COMPACT_STATUS)) { final ViewHolder viewHolder = (ViewHolder) holder; // Bug workaround for losing text selection ability, see: // https://code.google.com/p/android/issues/detail?id=208169 @@ -228,6 +228,20 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct viewHolder.status_spoiler.setEnabled(false); viewHolder.status_spoiler.setEnabled(true); } + + } + + + private class ViewHolderArt extends RecyclerView.ViewHolder{ + ImageView art_media, art_pp; + TextView art_username, art_acct; + ViewHolderArt(View itemView) { + super(itemView); + art_media = itemView.findViewById(R.id.art_media); + art_pp = itemView.findViewById(R.id.art_pp); + art_username = itemView.findViewById(R.id.art_username); + art_acct = itemView.findViewById(R.id.art_acct); + } } @@ -405,7 +419,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if( viewType == DISPLAYED_STATUS) + if( type == RetrieveFeedsAsyncTask.Type.ART) + return new ViewHolderArt(layoutInflater.inflate(R.layout.drawer_art, parent, false)); + else if( viewType == DISPLAYED_STATUS) return new ViewHolder(layoutInflater.inflate(R.layout.drawer_status, parent, false)); else if(viewType == COMPACT_STATUS) return new ViewHolder(layoutInflater.inflate(R.layout.drawer_status_compact, parent, false)); @@ -420,15 +436,27 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct @SuppressLint("SetJavaScriptEnabled") @Override public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) { - - if( viewHolder.getItemViewType() == DISPLAYED_STATUS || viewHolder.getItemViewType() == FOCUSED_STATUS || viewHolder.getItemViewType() == COMPACT_STATUS){ + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + final String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); + if( type == RetrieveFeedsAsyncTask.Type.ART) { + final ViewHolderArt holder = (ViewHolderArt) viewHolder; + final Status status = statuses.get(position); + Glide.with(context) + .load(status.getMedia_attachments().get(0).getPreview_url()) + .into(holder.art_media); + Glide.with(context) + .load(status.getAccount().getAvatar()) + .apply(new RequestOptions().transforms(new FitCenter(), new RoundedCorners(10))) + .into(holder.art_pp); + holder.art_username.setText( status.getDisplayNameSpan(), TextView.BufferType.SPANNABLE); + holder.art_acct.setText(String.format("@%s", status.getAccount().getAcct())); + }else if( viewHolder.getItemViewType() == DISPLAYED_STATUS || viewHolder.getItemViewType() == FOCUSED_STATUS || viewHolder.getItemViewType() == COMPACT_STATUS){ final ViewHolder holder = (ViewHolder) viewHolder; final Status status = statuses.get(position); - final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + status.setItemViewType(viewHolder.getItemViewType()); - final String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); boolean displayBookmarkButton = sharedpreferences.getBoolean(Helper.SET_SHOW_BOOKMARK, false); boolean fullAttachement = sharedpreferences.getBoolean(Helper.SET_FULL_PREVIEW, false); boolean isCompactMode = sharedpreferences.getBoolean(Helper.SET_COMPACT_MODE, false); 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 1f3ff8c8e..53b1a7192 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 @@ -336,6 +336,7 @@ public class Helper { 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_DISPLAY_ART = "set_display_art"; public static final String SET_AUTOMATICALLY_SPLIT_TOOTS = "set_automatically_split_toots"; public static final String SET_AUTOMATICALLY_SPLIT_TOOTS_SIZE = "set_automatically_split_toots_size"; public static final String SET_TRUNCATE_TOOTS_SIZE = "set_truncate_toots_size"; diff --git a/app/src/main/res/drawable-anydpi/ic_color_lens.xml b/app/src/main/res/drawable-anydpi/ic_color_lens.xml new file mode 100644 index 000000000..f75e2fbe3 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_color_lens.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/drawer_art.xml b/app/src/main/res/layout/drawer_art.xml new file mode 100644 index 000000000..607164852 --- /dev/null +++ b/app/src/main/res/layout/drawer_art.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + \ No newline at end of file