Browse Source
Allow forwarding messages (need to check types which cannot be forwarded)
renovate/org.robolectric-robolectric-4.x
Allow forwarding messages (need to check types which cannot be forwarded)
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
28 changed files with 1170 additions and 159 deletions
-
120app/src/main/java/awais/instagrabber/adapters/UserSearchResultsAdapter.java
-
5app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemLikeViewHolder.java
-
5app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java
-
5app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java
-
5app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemStoryShareViewHolder.java
-
15app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java
-
5app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVoiceMediaViewHolder.java
-
89app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/RecipientThreadViewHolder.java
-
139app/src/main/java/awais/instagrabber/fragments/UserSearchFragment.java
-
60app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java
-
60app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
-
44app/src/main/java/awais/instagrabber/models/enums/DirectItemType.java
-
13app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.java
-
9app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItem.java
-
3app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThread.java
-
46app/src/main/java/awais/instagrabber/repositories/responses/directmessages/RankedRecipient.java
-
50app/src/main/java/awais/instagrabber/repositories/responses/directmessages/RankedRecipientsResponse.java
-
12app/src/main/java/awais/instagrabber/utils/DirectItemFactory.java
-
69app/src/main/java/awais/instagrabber/utils/RankedRecipientsCache.java
-
93app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
-
331app/src/main/java/awais/instagrabber/viewmodels/UserSearchViewModel.java
-
56app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.java
-
6app/src/main/res/layout/layout_dm_base.xml
-
19app/src/main/res/layout/layout_dm_user_item.xml
-
34app/src/main/res/navigation/direct_messages_nav_graph.xml
-
32app/src/main/res/navigation/user_search_nav_graph.xml
-
1app/src/main/res/values/ids.xml
-
3app/src/main/res/values/strings.xml
@ -0,0 +1,89 @@ |
|||||
|
package awais.instagrabber.adapters.viewholder.directmessages; |
||||
|
|
||||
|
import android.content.res.Resources; |
||||
|
import android.view.View; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
import awais.instagrabber.R; |
||||
|
import awais.instagrabber.adapters.UserSearchResultsAdapter.OnRecipientClickListener; |
||||
|
import awais.instagrabber.databinding.LayoutDmUserItemBinding; |
||||
|
import awais.instagrabber.repositories.responses.User; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient; |
||||
|
|
||||
|
public class RecipientThreadViewHolder extends RecyclerView.ViewHolder { |
||||
|
private static final String TAG = RecipientThreadViewHolder.class.getSimpleName(); |
||||
|
|
||||
|
private final LayoutDmUserItemBinding binding; |
||||
|
private final OnRecipientClickListener onThreadClickListener; |
||||
|
private final float translateAmount; |
||||
|
|
||||
|
public RecipientThreadViewHolder(@NonNull final LayoutDmUserItemBinding binding, |
||||
|
final OnRecipientClickListener onThreadClickListener) { |
||||
|
super(binding.getRoot()); |
||||
|
this.binding = binding; |
||||
|
this.onThreadClickListener = onThreadClickListener; |
||||
|
binding.info.setVisibility(View.GONE); |
||||
|
final Resources resources = itemView.getResources(); |
||||
|
final int avatarSize = resources.getDimensionPixelSize(R.dimen.dm_inbox_avatar_size); |
||||
|
translateAmount = ((float) avatarSize) / 7; |
||||
|
} |
||||
|
|
||||
|
public void bind(final int position, |
||||
|
final DirectThread thread, |
||||
|
final boolean showSelection, |
||||
|
final boolean isSelected) { |
||||
|
if (thread == null) return; |
||||
|
binding.getRoot().setOnClickListener(v -> { |
||||
|
if (onThreadClickListener == null) return; |
||||
|
onThreadClickListener.onClick(position, RankedRecipient.of(thread), isSelected); |
||||
|
}); |
||||
|
binding.fullName.setText(thread.getThreadTitle()); |
||||
|
setUsername(thread); |
||||
|
setProfilePic(thread); |
||||
|
setSelection(showSelection, isSelected); |
||||
|
} |
||||
|
|
||||
|
private void setProfilePic(final DirectThread thread) { |
||||
|
final List<User> users = thread.getUsers(); |
||||
|
binding.profilePic.setImageURI(users.get(0).getProfilePicUrl()); |
||||
|
binding.profilePic.setScaleX(1); |
||||
|
binding.profilePic.setScaleY(1); |
||||
|
binding.profilePic.setTranslationX(0); |
||||
|
binding.profilePic.setTranslationY(0); |
||||
|
if (users.size() > 1) { |
||||
|
binding.profilePic2.setVisibility(View.VISIBLE); |
||||
|
binding.profilePic2.setImageURI(users.get(1).getProfilePicUrl()); |
||||
|
binding.profilePic2.setTranslationX(translateAmount); |
||||
|
binding.profilePic2.setTranslationY(translateAmount); |
||||
|
final float scaleAmount = 0.75f; |
||||
|
binding.profilePic2.setScaleX(scaleAmount); |
||||
|
binding.profilePic2.setScaleY(scaleAmount); |
||||
|
binding.profilePic.setScaleX(scaleAmount); |
||||
|
binding.profilePic.setScaleY(scaleAmount); |
||||
|
binding.profilePic.setTranslationX(-translateAmount); |
||||
|
binding.profilePic.setTranslationY(-translateAmount); |
||||
|
return; |
||||
|
} |
||||
|
binding.profilePic2.setVisibility(View.GONE); |
||||
|
} |
||||
|
|
||||
|
private void setUsername(final DirectThread thread) { |
||||
|
if (thread.isGroup()) { |
||||
|
binding.username.setVisibility(View.GONE); |
||||
|
return; |
||||
|
} |
||||
|
binding.username.setVisibility(View.VISIBLE); |
||||
|
// for a non-group thread, the thread title is the username so set the full name in the username text view |
||||
|
binding.username.setText(thread.getUsers().get(0).getFullName()); |
||||
|
} |
||||
|
|
||||
|
private void setSelection(final boolean showSelection, final boolean isSelected) { |
||||
|
binding.select.setVisibility(showSelection ? View.VISIBLE : View.GONE); |
||||
|
binding.getRoot().setSelected(isSelected); |
||||
|
} |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
package awais.instagrabber.repositories.responses.directmessages; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
import awais.instagrabber.repositories.responses.User; |
||||
|
|
||||
|
public class RankedRecipient implements Serializable { |
||||
|
private final User user; |
||||
|
private final DirectThread thread; |
||||
|
|
||||
|
public RankedRecipient(final User user, final DirectThread thread) { |
||||
|
this.user = user; |
||||
|
this.thread = thread; |
||||
|
} |
||||
|
|
||||
|
public User getUser() { |
||||
|
return user; |
||||
|
} |
||||
|
|
||||
|
public DirectThread getThread() { |
||||
|
return thread; |
||||
|
} |
||||
|
|
||||
|
public static RankedRecipient of(final User user) { |
||||
|
return new RankedRecipient(user, null); |
||||
|
} |
||||
|
|
||||
|
public static RankedRecipient of(final DirectThread thread) { |
||||
|
return new RankedRecipient(null, thread); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean equals(final Object o) { |
||||
|
if (this == o) return true; |
||||
|
if (o == null || getClass() != o.getClass()) return false; |
||||
|
final RankedRecipient that = (RankedRecipient) o; |
||||
|
return Objects.equals(user, that.user) && |
||||
|
Objects.equals(thread, that.thread); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int hashCode() { |
||||
|
return Objects.hash(user, thread); |
||||
|
} |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
package awais.instagrabber.repositories.responses.directmessages; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public class RankedRecipientsResponse { |
||||
|
private final List<RankedRecipient> rankedRecipients; |
||||
|
private final long expires; |
||||
|
private final boolean filtered; |
||||
|
private final String requestId; |
||||
|
private final String rankToken; |
||||
|
private final String status; |
||||
|
|
||||
|
public RankedRecipientsResponse(final List<RankedRecipient> rankedRecipients, |
||||
|
final long expires, |
||||
|
final boolean filtered, |
||||
|
final String requestId, |
||||
|
final String rankToken, |
||||
|
final String status) { |
||||
|
this.rankedRecipients = rankedRecipients; |
||||
|
this.expires = expires; |
||||
|
this.filtered = filtered; |
||||
|
this.requestId = requestId; |
||||
|
this.rankToken = rankToken; |
||||
|
this.status = status; |
||||
|
} |
||||
|
|
||||
|
public List<RankedRecipient> getRankedRecipients() { |
||||
|
return rankedRecipients; |
||||
|
} |
||||
|
|
||||
|
public long getExpires() { |
||||
|
return expires; |
||||
|
} |
||||
|
|
||||
|
public boolean isFiltered() { |
||||
|
return filtered; |
||||
|
} |
||||
|
|
||||
|
public String getRequestId() { |
||||
|
return requestId; |
||||
|
} |
||||
|
|
||||
|
public String getRankToken() { |
||||
|
return rankToken; |
||||
|
} |
||||
|
|
||||
|
public String getStatus() { |
||||
|
return status; |
||||
|
} |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
package awais.instagrabber.utils; |
||||
|
|
||||
|
import java.time.LocalDateTime; |
||||
|
import java.time.temporal.ChronoUnit; |
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
|
||||
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse; |
||||
|
|
||||
|
public class RankedRecipientsCache { |
||||
|
private static final Object LOCK = new Object(); |
||||
|
|
||||
|
private static RankedRecipientsCache instance; |
||||
|
|
||||
|
public static RankedRecipientsCache getInstance() { |
||||
|
if (instance == null) { |
||||
|
synchronized (LOCK) { |
||||
|
if (instance == null) { |
||||
|
instance = new RankedRecipientsCache(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return instance; |
||||
|
} |
||||
|
|
||||
|
private LocalDateTime lastUpdatedOn; |
||||
|
private RankedRecipientsResponse response; |
||||
|
private boolean updateInitiated = false; |
||||
|
private boolean failed = false; |
||||
|
|
||||
|
private RankedRecipientsCache() {} |
||||
|
|
||||
|
public List<RankedRecipient> getRankedRecipients() { |
||||
|
if (response != null) { |
||||
|
return response.getRankedRecipients(); |
||||
|
} |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
|
||||
|
public void setRankedRecipientsResponse(final RankedRecipientsResponse response) { |
||||
|
this.response = response; |
||||
|
lastUpdatedOn = LocalDateTime.now(); |
||||
|
} |
||||
|
|
||||
|
public boolean isExpired() { |
||||
|
if (lastUpdatedOn == null || response == null) { |
||||
|
return true; |
||||
|
} |
||||
|
final long expiresInSecs = response.getExpires(); |
||||
|
return LocalDateTime.now().isAfter(lastUpdatedOn.plus(expiresInSecs, ChronoUnit.SECONDS)); |
||||
|
} |
||||
|
|
||||
|
public boolean isUpdateInitiated() { |
||||
|
return updateInitiated; |
||||
|
} |
||||
|
|
||||
|
public void setUpdateInitiated(final boolean updateInitiated) { |
||||
|
this.updateInitiated = updateInitiated; |
||||
|
} |
||||
|
|
||||
|
public boolean isFailed() { |
||||
|
return failed; |
||||
|
} |
||||
|
|
||||
|
public void setFailed(final boolean failed) { |
||||
|
this.failed = failed; |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue