63 changed files with 3548 additions and 1995 deletions
-
6app/build.gradle
-
7app/src/main/java/awais/instagrabber/activities/MainActivity.java
-
2app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java
-
4app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java
-
16app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectInboxItemViewHolder.java
-
7app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java
-
33app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.java
-
94app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java
-
184app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
-
32app/src/main/java/awais/instagrabber/fragments/directmessages/DirectPendingInboxFragment.java
-
81app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.java
-
358app/src/main/java/awais/instagrabber/managers/InboxManager.java
-
1780app/src/main/java/awais/instagrabber/managers/ThreadManager.java
-
17app/src/main/java/awais/instagrabber/models/Resource.java
-
19app/src/main/java/awais/instagrabber/repositories/responses/AnimatedMediaFixedHeight.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/AnimatedMediaImages.java
-
18app/src/main/java/awais/instagrabber/repositories/responses/Audio.java
-
16app/src/main/java/awais/instagrabber/repositories/responses/Caption.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/EndOfFeedDemarcator.java
-
17app/src/main/java/awais/instagrabber/repositories/responses/EndOfFeedGroup.java
-
19app/src/main/java/awais/instagrabber/repositories/responses/EndOfFeedGroupSet.java
-
24app/src/main/java/awais/instagrabber/repositories/responses/FriendshipStatus.java
-
14app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.java
-
20app/src/main/java/awais/instagrabber/repositories/responses/Location.java
-
49app/src/main/java/awais/instagrabber/repositories/responses/Media.java
-
16app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.java
-
31app/src/main/java/awais/instagrabber/repositories/responses/User.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/UsertagIn.java
-
14app/src/main/java/awais/instagrabber/repositories/responses/Usertags.java
-
18app/src/main/java/awais/instagrabber/repositories/responses/VideoVersion.java
-
16app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectInbox.java
-
61app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItem.java
-
32app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemActionLog.java
-
18app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemAnimatedMedia.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemClip.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemFelixShare.java
-
18app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemLink.java
-
18app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemLinkContext.java
-
17app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemPlaceholder.java
-
22app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemReelShare.java
-
16app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemReelShareReactionInfo.java
-
21app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemStoryShare.java
-
18app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemVideoCallEvent.java
-
22app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemVisualMedia.java
-
17app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemVoiceMedia.java
-
75app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThread.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThreadDirectStory.java
-
16app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThreadLastSeenAt.java
-
6app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThreadParticipantRequestsResponse.java
-
17app/src/main/java/awais/instagrabber/repositories/responses/directmessages/RavenExpiringMediaActionSummary.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/directmessages/ThreadContext.java
-
2app/src/main/java/awais/instagrabber/utils/BitmapUtils.java
-
47app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java
-
8app/src/main/java/awais/instagrabber/viewmodels/AppStateViewModel.java
-
166app/src/main/java/awais/instagrabber/viewmodels/DirectInboxViewModel.java
-
119app/src/main/java/awais/instagrabber/viewmodels/DirectPendingInboxViewModel.java
-
650app/src/main/java/awais/instagrabber/viewmodels/DirectSettingsViewModel.java
-
1057app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
-
35app/src/main/java/awais/instagrabber/viewmodels/factories/DirectSettingsViewModelFactory.java
-
35app/src/main/java/awais/instagrabber/viewmodels/factories/DirectThreadViewModelFactory.java
-
10app/src/main/res/layout/fragment_direct_pending_inbox.xml
-
1app/src/main/res/values/strings.xml
-
2build.gradle
@ -0,0 +1,81 @@ |
|||||
|
package awais.instagrabber.managers; |
||||
|
|
||||
|
import android.content.ContentResolver; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
|
||||
|
import com.google.common.collect.Iterables; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
import awais.instagrabber.repositories.responses.User; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectItem; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
||||
|
|
||||
|
public final class DirectMessagesManager { |
||||
|
private static final String TAG = DirectMessagesManager.class.getSimpleName(); |
||||
|
private static final Object LOCK = new Object(); |
||||
|
|
||||
|
private static DirectMessagesManager instance; |
||||
|
|
||||
|
private final InboxManager inboxManager; |
||||
|
private final InboxManager pendingInboxManager; |
||||
|
|
||||
|
public static DirectMessagesManager getInstance() { |
||||
|
if (instance == null) { |
||||
|
synchronized (LOCK) { |
||||
|
if (instance == null) { |
||||
|
instance = new DirectMessagesManager(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return instance; |
||||
|
} |
||||
|
|
||||
|
private DirectMessagesManager() { |
||||
|
inboxManager = InboxManager.getInstance(false); |
||||
|
pendingInboxManager = InboxManager.getInstance(true); |
||||
|
} |
||||
|
|
||||
|
public void moveThreadFromPending(@NonNull final String threadId) { |
||||
|
final List<DirectThread> pendingThreads = pendingInboxManager.getThreads().getValue(); |
||||
|
if (pendingThreads == null) return; |
||||
|
final int index = Iterables.indexOf(pendingThreads, t -> t.getThreadId().equals(threadId)); |
||||
|
if (index < 0) return; |
||||
|
final DirectThread thread = pendingThreads.get(index); |
||||
|
final DirectItem threadFirstDirectItem = thread.getFirstDirectItem(); |
||||
|
if (threadFirstDirectItem == null) return; |
||||
|
final List<DirectThread> threads = inboxManager.getThreads().getValue(); |
||||
|
int insertIndex = 0; |
||||
|
for (final DirectThread tempThread : threads) { |
||||
|
final DirectItem firstDirectItem = tempThread.getFirstDirectItem(); |
||||
|
if (firstDirectItem == null) continue; |
||||
|
final long timestamp = firstDirectItem.getTimestamp(); |
||||
|
if (timestamp < threadFirstDirectItem.getTimestamp()) { |
||||
|
break; |
||||
|
} |
||||
|
insertIndex++; |
||||
|
} |
||||
|
thread.setPending(false); |
||||
|
inboxManager.addThread(thread, insertIndex); |
||||
|
pendingInboxManager.removeThread(threadId); |
||||
|
final Integer currentTotal = inboxManager.getPendingRequestsTotal().getValue(); |
||||
|
if (currentTotal == null) return; |
||||
|
inboxManager.setPendingRequestsTotal(currentTotal - 1); |
||||
|
} |
||||
|
|
||||
|
public InboxManager getInboxManager() { |
||||
|
return inboxManager; |
||||
|
} |
||||
|
|
||||
|
public InboxManager getPendingInboxManager() { |
||||
|
return pendingInboxManager; |
||||
|
} |
||||
|
|
||||
|
public ThreadManager getThreadManager(@NonNull final String threadId, |
||||
|
final boolean pending, |
||||
|
@NonNull final User currentUser, |
||||
|
@NonNull final ContentResolver contentResolver) { |
||||
|
return ThreadManager.getInstance(threadId, pending, currentUser, contentResolver); |
||||
|
} |
||||
|
} |
@ -0,0 +1,358 @@ |
|||||
|
package awais.instagrabber.managers; |
||||
|
|
||||
|
import android.util.Log; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.lifecycle.LiveData; |
||||
|
import androidx.lifecycle.MutableLiveData; |
||||
|
import androidx.lifecycle.Transformations; |
||||
|
|
||||
|
import com.google.common.cache.CacheBuilder; |
||||
|
import com.google.common.cache.CacheLoader; |
||||
|
import com.google.common.cache.LoadingCache; |
||||
|
import com.google.common.collect.ImmutableList; |
||||
|
import com.google.common.collect.Iterables; |
||||
|
|
||||
|
import java.util.Collection; |
||||
|
import java.util.Collections; |
||||
|
import java.util.Comparator; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
import awais.instagrabber.models.Resource; |
||||
|
import awais.instagrabber.repositories.responses.User; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectInbox; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectItem; |
||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
||||
|
import awais.instagrabber.utils.Constants; |
||||
|
import awais.instagrabber.utils.CookieUtils; |
||||
|
import awais.instagrabber.utils.TextUtils; |
||||
|
import awais.instagrabber.webservices.DirectMessagesService; |
||||
|
import retrofit2.Call; |
||||
|
import retrofit2.Callback; |
||||
|
import retrofit2.Response; |
||||
|
|
||||
|
import static androidx.lifecycle.Transformations.distinctUntilChanged; |
||||
|
import static awais.instagrabber.utils.Utils.settingsHelper; |
||||
|
|
||||
|
public final class InboxManager { |
||||
|
private static final String TAG = InboxManager.class.getSimpleName(); |
||||
|
private static final LoadingCache<String, Object> THREAD_LOCKS = CacheBuilder |
||||
|
.newBuilder() |
||||
|
.expireAfterAccess(1, TimeUnit.MINUTES) // max lock time ever expected |
||||
|
.build(CacheLoader.from(Object::new)); |
||||
|
private static final Comparator<DirectThread> THREAD_COMPARATOR = (t1, t2) -> { |
||||
|
final DirectItem t1FirstDirectItem = t1.getFirstDirectItem(); |
||||
|
final DirectItem t2FirstDirectItem = t2.getFirstDirectItem(); |
||||
|
if (t1FirstDirectItem == null && t2FirstDirectItem == null) return 0; |
||||
|
if (t1FirstDirectItem == null) return 1; |
||||
|
if (t2FirstDirectItem == null) return -1; |
||||
|
return Long.compare(t2FirstDirectItem.getTimestamp(), t1FirstDirectItem.getTimestamp()); |
||||
|
}; |
||||
|
|
||||
|
private final MutableLiveData<Resource<DirectInbox>> inbox = new MutableLiveData<>(); |
||||
|
private final MutableLiveData<Resource<Integer>> unseenCount = new MutableLiveData<>(); |
||||
|
private final MutableLiveData<Integer> pendingRequestsTotal = new MutableLiveData<>(0); |
||||
|
|
||||
|
private final LiveData<List<DirectThread>> threads; |
||||
|
private final DirectMessagesService service; |
||||
|
private final boolean pending; |
||||
|
|
||||
|
private Call<DirectInboxResponse> inboxRequest; |
||||
|
private Call<DirectBadgeCount> unseenCountRequest; |
||||
|
private long seqId; |
||||
|
private String cursor; |
||||
|
private boolean hasOlder = true; |
||||
|
private User viewer; |
||||
|
|
||||
|
@NonNull |
||||
|
public static InboxManager getInstance(final boolean pending) { |
||||
|
return new InboxManager(pending); |
||||
|
} |
||||
|
|
||||
|
private InboxManager(final boolean pending) { |
||||
|
this.pending = pending; |
||||
|
final String cookie = settingsHelper.getString(Constants.COOKIE); |
||||
|
final long userId = CookieUtils.getUserIdFromCookie(cookie); |
||||
|
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID); |
||||
|
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie); |
||||
|
if (TextUtils.isEmpty(csrfToken) || userId <= 0 || TextUtils.isEmpty(deviceUuid)) { |
||||
|
throw new IllegalArgumentException("User is not logged in!"); |
||||
|
} |
||||
|
service = DirectMessagesService.getInstance(csrfToken, userId, deviceUuid); |
||||
|
|
||||
|
// Transformations |
||||
|
threads = distinctUntilChanged(Transformations.map(inbox, inboxResource -> { |
||||
|
if (inboxResource == null) { |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
final DirectInbox inbox = inboxResource.data; |
||||
|
if (inbox == null) { |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
return ImmutableList.sortedCopyOf(THREAD_COMPARATOR, inbox.getThreads()); |
||||
|
})); |
||||
|
|
||||
|
fetchInbox(); |
||||
|
if (!pending) { |
||||
|
fetchUnseenCount(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public LiveData<Resource<DirectInbox>> getInbox() { |
||||
|
return distinctUntilChanged(inbox); |
||||
|
} |
||||
|
|
||||
|
public LiveData<List<DirectThread>> getThreads() { |
||||
|
return threads; |
||||
|
} |
||||
|
|
||||
|
public LiveData<Resource<Integer>> getUnseenCount() { |
||||
|
return distinctUntilChanged(unseenCount); |
||||
|
} |
||||
|
|
||||
|
public LiveData<Integer> getPendingRequestsTotal() { |
||||
|
return distinctUntilChanged(pendingRequestsTotal); |
||||
|
} |
||||
|
|
||||
|
public User getViewer() { |
||||
|
return viewer; |
||||
|
} |
||||
|
|
||||
|
public void fetchInbox() { |
||||
|
final Resource<DirectInbox> inboxResource = inbox.getValue(); |
||||
|
if ((inboxResource != null && inboxResource.status == Resource.Status.LOADING) || !hasOlder) return; |
||||
|
stopCurrentInboxRequest(); |
||||
|
inbox.postValue(Resource.loading(getCurrentDirectInbox())); |
||||
|
inboxRequest = pending ? service.fetchPendingInbox(cursor, seqId) : service.fetchInbox(cursor, seqId); |
||||
|
inboxRequest.enqueue(new Callback<DirectInboxResponse>() { |
||||
|
@Override |
||||
|
public void onResponse(@NonNull final Call<DirectInboxResponse> call, @NonNull final Response<DirectInboxResponse> response) { |
||||
|
parseInboxResponse(response.body()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onFailure(@NonNull final Call<DirectInboxResponse> call, @NonNull final Throwable t) { |
||||
|
Log.e(TAG, "Failed fetching dm inbox", t); |
||||
|
inbox.postValue(Resource.error(t.getMessage(), getCurrentDirectInbox())); |
||||
|
hasOlder = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public void fetchUnseenCount() { |
||||
|
final Resource<Integer> unseenCountResource = unseenCount.getValue(); |
||||
|
if ((unseenCountResource != null && unseenCountResource.status == Resource.Status.LOADING)) return; |
||||
|
stopCurrentUnseenCountRequest(); |
||||
|
unseenCount.postValue(Resource.loading(getCurrentUnseenCount())); |
||||
|
unseenCountRequest = service.fetchUnseenCount(); |
||||
|
unseenCountRequest.enqueue(new Callback<DirectBadgeCount>() { |
||||
|
@Override |
||||
|
public void onResponse(@NonNull final Call<DirectBadgeCount> call, @NonNull final Response<DirectBadgeCount> response) { |
||||
|
final DirectBadgeCount directBadgeCount = response.body(); |
||||
|
if (directBadgeCount == null) { |
||||
|
Log.e(TAG, "onResponse: directBadgeCount Response is null"); |
||||
|
unseenCount.postValue(Resource.error("Unseen count response is null", getCurrentUnseenCount())); |
||||
|
return; |
||||
|
} |
||||
|
unseenCount.postValue(Resource.success(directBadgeCount.getBadgeCount())); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onFailure(@NonNull final Call<DirectBadgeCount> call, @NonNull final Throwable t) { |
||||
|
Log.e(TAG, "Failed fetching unseen count", t); |
||||
|
unseenCount.postValue(Resource.error(t.getMessage(), getCurrentUnseenCount())); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public void refresh() { |
||||
|
cursor = null; |
||||
|
seqId = 0; |
||||
|
hasOlder = true; |
||||
|
fetchInbox(); |
||||
|
if (!pending) { |
||||
|
fetchUnseenCount(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private DirectInbox getCurrentDirectInbox() { |
||||
|
final Resource<DirectInbox> inboxResource = inbox.getValue(); |
||||
|
return inboxResource != null ? inboxResource.data : null; |
||||
|
} |
||||
|
|
||||
|
private void parseInboxResponse(final DirectInboxResponse response) { |
||||
|
if (response == null) { |
||||
|
Log.e(TAG, "parseInboxResponse: Response is null"); |
||||
|
inbox.postValue(Resource.error("Response is null", getCurrentDirectInbox())); |
||||
|
hasOlder = false; |
||||
|
return; |
||||
|
} |
||||
|
if (!response.getStatus().equals("ok")) { |
||||
|
final String msg = "DM inbox fetch response: status not ok"; |
||||
|
Log.e(TAG, msg); |
||||
|
inbox.postValue(Resource.error(msg, getCurrentDirectInbox())); |
||||
|
hasOlder = false; |
||||
|
return; |
||||
|
} |
||||
|
seqId = response.getSeqId(); |
||||
|
if (viewer == null) { |
||||
|
viewer = response.getViewer(); |
||||
|
} |
||||
|
final DirectInbox inbox = response.getInbox(); |
||||
|
if (!TextUtils.isEmpty(cursor)) { |
||||
|
final DirectInbox currentDirectInbox = getCurrentDirectInbox(); |
||||
|
if (currentDirectInbox != null) { |
||||
|
List<DirectThread> threads = currentDirectInbox.getThreads(); |
||||
|
threads = threads == null ? new LinkedList<>() : new LinkedList<>(threads); |
||||
|
threads.addAll(inbox.getThreads()); |
||||
|
inbox.setThreads(threads); |
||||
|
} |
||||
|
} |
||||
|
this.inbox.postValue(Resource.success(inbox)); |
||||
|
cursor = inbox.getOldestCursor(); |
||||
|
hasOlder = inbox.hasOlder(); |
||||
|
pendingRequestsTotal.postValue(response.getPendingRequestsTotal()); |
||||
|
} |
||||
|
|
||||
|
public void setThread(@NonNull final String threadId, |
||||
|
@NonNull final DirectThread thread) { |
||||
|
final DirectInbox inbox = getCurrentDirectInbox(); |
||||
|
if (inbox == null) return; |
||||
|
final int index = getThreadIndex(threadId, inbox); |
||||
|
setThread(inbox, index, thread); |
||||
|
} |
||||
|
|
||||
|
private void setThread(@NonNull final DirectInbox inbox, |
||||
|
final int index, |
||||
|
@NonNull final DirectThread thread) { |
||||
|
if (index < 0) return; |
||||
|
synchronized (this.inbox) { |
||||
|
final List<DirectThread> threadsCopy = new LinkedList<>(inbox.getThreads()); |
||||
|
threadsCopy.set(index, thread); |
||||
|
try { |
||||
|
final DirectInbox clone = (DirectInbox) inbox.clone(); |
||||
|
clone.setThreads(threadsCopy); |
||||
|
this.inbox.postValue(Resource.success(clone)); |
||||
|
} catch (CloneNotSupportedException e) { |
||||
|
Log.e(TAG, "setThread: ", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void addItemsToThread(@NonNull final String threadId, |
||||
|
final int insertIndex, |
||||
|
@NonNull final Collection<DirectItem> items) { |
||||
|
final DirectInbox inbox = getCurrentDirectInbox(); |
||||
|
if (inbox == null) return; |
||||
|
synchronized (THREAD_LOCKS.getUnchecked(threadId)) { |
||||
|
final int index = getThreadIndex(threadId, inbox); |
||||
|
if (index < 0) return; |
||||
|
final List<DirectThread> threads = inbox.getThreads(); |
||||
|
final DirectThread thread = threads.get(index); |
||||
|
List<DirectItem> list = thread.getItems(); |
||||
|
list = list == null ? new LinkedList<>() : new LinkedList<>(list); |
||||
|
if (insertIndex >= 0) { |
||||
|
list.addAll(insertIndex, items); |
||||
|
} else { |
||||
|
list.addAll(items); |
||||
|
} |
||||
|
try { |
||||
|
final DirectThread threadClone = (DirectThread) thread.clone(); |
||||
|
threadClone.setItems(list); |
||||
|
setThread(inbox, index, threadClone); |
||||
|
} catch (Exception e) { |
||||
|
Log.e(TAG, "addItemsToThread: ", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void setItemsToThread(@NonNull final String threadId, |
||||
|
@NonNull final List<DirectItem> updatedItems) { |
||||
|
final DirectInbox inbox = getCurrentDirectInbox(); |
||||
|
if (inbox == null) return; |
||||
|
synchronized (THREAD_LOCKS.getUnchecked(threadId)) { |
||||
|
final int index = getThreadIndex(threadId, inbox); |
||||
|
if (index < 0) return; |
||||
|
final List<DirectThread> threads = inbox.getThreads(); |
||||
|
final DirectThread thread = threads.get(index); |
||||
|
thread.setItems(updatedItems); |
||||
|
setThread(inbox, index, thread); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private int getThreadIndex(@NonNull final String threadId, |
||||
|
@NonNull final DirectInbox inbox) { |
||||
|
final List<DirectThread> threads = inbox.getThreads(); |
||||
|
if (threads == null || threads.isEmpty()) { |
||||
|
return -1; |
||||
|
} |
||||
|
return Iterables.indexOf(threads, t -> { |
||||
|
if (t == null) return false; |
||||
|
return t.getThreadId().equals(threadId); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private Integer getCurrentUnseenCount() { |
||||
|
final Resource<Integer> unseenCountResource = unseenCount.getValue(); |
||||
|
return unseenCountResource != null ? unseenCountResource.data : null; |
||||
|
} |
||||
|
|
||||
|
private void stopCurrentInboxRequest() { |
||||
|
if (inboxRequest == null || inboxRequest.isCanceled() || inboxRequest.isExecuted()) return; |
||||
|
inboxRequest.cancel(); |
||||
|
inboxRequest = null; |
||||
|
} |
||||
|
|
||||
|
private void stopCurrentUnseenCountRequest() { |
||||
|
if (unseenCountRequest == null || unseenCountRequest.isCanceled() || unseenCountRequest.isExecuted()) return; |
||||
|
unseenCountRequest.cancel(); |
||||
|
unseenCountRequest = null; |
||||
|
} |
||||
|
|
||||
|
public void onDestroy() { |
||||
|
stopCurrentInboxRequest(); |
||||
|
stopCurrentUnseenCountRequest(); |
||||
|
} |
||||
|
|
||||
|
public void addThread(@NonNull final DirectThread thread, final int insertIndex) { |
||||
|
if (insertIndex < 0) return; |
||||
|
synchronized (this.inbox) { |
||||
|
final DirectInbox currentDirectInbox = getCurrentDirectInbox(); |
||||
|
final List<DirectThread> threadsCopy = new LinkedList<>(currentDirectInbox.getThreads()); |
||||
|
threadsCopy.add(insertIndex, thread); |
||||
|
try { |
||||
|
final DirectInbox clone = (DirectInbox) currentDirectInbox.clone(); |
||||
|
clone.setThreads(threadsCopy); |
||||
|
this.inbox.setValue(Resource.success(clone)); |
||||
|
} catch (CloneNotSupportedException e) { |
||||
|
Log.e(TAG, "setThread: ", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void removeThread(@NonNull final String threadId) { |
||||
|
synchronized (this.inbox) { |
||||
|
final DirectInbox currentDirectInbox = getCurrentDirectInbox(); |
||||
|
final List<DirectThread> threadsCopy = currentDirectInbox.getThreads() |
||||
|
.stream() |
||||
|
.filter(t -> !t.getThreadId().equals(threadId)) |
||||
|
.collect(Collectors.toList()); |
||||
|
try { |
||||
|
final DirectInbox clone = (DirectInbox) currentDirectInbox.clone(); |
||||
|
clone.setThreads(threadsCopy); |
||||
|
this.inbox.postValue(Resource.success(clone)); |
||||
|
} catch (CloneNotSupportedException e) { |
||||
|
Log.e(TAG, "setThread: ", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void setPendingRequestsTotal(final int total) { |
||||
|
pendingRequestsTotal.postValue(total); |
||||
|
} |
||||
|
} |
1780
app/src/main/java/awais/instagrabber/managers/ThreadManager.java
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,188 +1,56 @@ |
|||||
package awais.instagrabber.viewmodels; |
package awais.instagrabber.viewmodels; |
||||
|
|
||||
import android.util.Log; |
|
||||
|
|
||||
import androidx.annotation.NonNull; |
|
||||
import androidx.lifecycle.LiveData; |
import androidx.lifecycle.LiveData; |
||||
import androidx.lifecycle.MutableLiveData; |
|
||||
import androidx.lifecycle.ViewModel; |
import androidx.lifecycle.ViewModel; |
||||
|
|
||||
import java.util.Collection; |
|
||||
import java.util.LinkedList; |
|
||||
import java.util.List; |
import java.util.List; |
||||
|
|
||||
|
import awais.instagrabber.managers.DirectMessagesManager; |
||||
|
import awais.instagrabber.managers.InboxManager; |
||||
|
import awais.instagrabber.models.Resource; |
||||
import awais.instagrabber.repositories.responses.User; |
import awais.instagrabber.repositories.responses.User; |
||||
import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; |
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectInbox; |
import awais.instagrabber.repositories.responses.directmessages.DirectInbox; |
||||
import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; |
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
||||
import awais.instagrabber.utils.Constants; |
|
||||
import awais.instagrabber.utils.CookieUtils; |
|
||||
import awais.instagrabber.utils.TextUtils; |
|
||||
import awais.instagrabber.webservices.DirectMessagesService; |
|
||||
import retrofit2.Call; |
|
||||
import retrofit2.Callback; |
|
||||
import retrofit2.Response; |
|
||||
|
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper; |
|
||||
|
|
||||
public class DirectInboxViewModel extends ViewModel { |
public class DirectInboxViewModel extends ViewModel { |
||||
private static final String TAG = DirectInboxViewModel.class.getSimpleName(); |
private static final String TAG = DirectInboxViewModel.class.getSimpleName(); |
||||
|
|
||||
private final DirectMessagesService service; |
|
||||
private final MutableLiveData<Boolean> fetchingInbox = new MutableLiveData<>(false); |
|
||||
private final MutableLiveData<List<DirectThread>> threads = new MutableLiveData<>(); |
|
||||
private final MutableLiveData<Boolean> fetchingUnseenCount = new MutableLiveData<>(false); |
|
||||
private final MutableLiveData<Integer> unseenCount = new MutableLiveData<>(0); |
|
||||
private final MutableLiveData<Integer> pendingRequestsTotal = new MutableLiveData<>(0); |
|
||||
|
|
||||
private Call<DirectInboxResponse> inboxRequest; |
|
||||
private Call<DirectBadgeCount> unseenCountRequest; |
|
||||
private long seqId; |
|
||||
private String cursor; |
|
||||
private boolean hasOlder = true; |
|
||||
private User viewer; |
|
||||
|
private final InboxManager inboxManager; |
||||
|
|
||||
public DirectInboxViewModel() { |
public DirectInboxViewModel() { |
||||
final String cookie = settingsHelper.getString(Constants.COOKIE); |
|
||||
final long userId = CookieUtils.getUserIdFromCookie(cookie); |
|
||||
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID); |
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie); |
|
||||
if (TextUtils.isEmpty(csrfToken) || userId <= 0 || TextUtils.isEmpty(deviceUuid)) { |
|
||||
throw new IllegalArgumentException("User is not logged in!"); |
|
||||
} |
|
||||
service = DirectMessagesService.getInstance(csrfToken, userId, deviceUuid); |
|
||||
fetchInbox(); |
|
||||
fetchUnseenCount(); |
|
||||
} |
|
||||
|
|
||||
public LiveData<List<DirectThread>> getThreads() { |
|
||||
return threads; |
|
||||
|
final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance(); |
||||
|
inboxManager = messagesManager.getInboxManager(); |
||||
} |
} |
||||
|
|
||||
public void setThreads(final List<DirectThread> threads) { |
|
||||
this.threads.postValue(threads); |
|
||||
|
public LiveData<Resource<DirectInbox>> getInbox() { |
||||
|
return inboxManager.getInbox(); |
||||
} |
} |
||||
|
|
||||
public void addThreads(final Collection<DirectThread> threads) { |
|
||||
if (threads == null) return; |
|
||||
List<DirectThread> list = getThreads().getValue(); |
|
||||
list = list == null ? new LinkedList<>() : new LinkedList<>(list); |
|
||||
list.addAll(threads); |
|
||||
this.threads.postValue(list); |
|
||||
} |
|
||||
|
|
||||
public LiveData<Integer> getUnseenCount() { |
|
||||
return unseenCount; |
|
||||
|
public LiveData<List<DirectThread>> getThreads() { |
||||
|
return inboxManager.getThreads(); |
||||
} |
} |
||||
|
|
||||
public LiveData<Boolean> getFetchingInbox() { |
|
||||
return fetchingInbox; |
|
||||
|
public LiveData<Resource<Integer>> getUnseenCount() { |
||||
|
return inboxManager.getUnseenCount(); |
||||
} |
} |
||||
|
|
||||
public LiveData<Integer> getPendingRequestsTotal() { |
public LiveData<Integer> getPendingRequestsTotal() { |
||||
return pendingRequestsTotal; |
|
||||
|
return inboxManager.getPendingRequestsTotal(); |
||||
} |
} |
||||
|
|
||||
public User getViewer() { |
public User getViewer() { |
||||
return viewer; |
|
||||
|
return inboxManager.getViewer(); |
||||
} |
} |
||||
|
|
||||
public void fetchInbox() { |
public void fetchInbox() { |
||||
if ((fetchingInbox.getValue() != null && fetchingInbox.getValue()) || !hasOlder) return; |
|
||||
stopCurrentInboxRequest(); |
|
||||
fetchingInbox.postValue(true); |
|
||||
inboxRequest = service.fetchInbox(cursor, seqId); |
|
||||
inboxRequest.enqueue(new Callback<DirectInboxResponse>() { |
|
||||
@Override |
|
||||
public void onResponse(@NonNull final Call<DirectInboxResponse> call, @NonNull final Response<DirectInboxResponse> response) { |
|
||||
parseInboxResponse(response.body()); |
|
||||
fetchingInbox.postValue(false); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<DirectInboxResponse> call, @NonNull final Throwable t) { |
|
||||
Log.e(TAG, "Failed fetching dm inbox", t); |
|
||||
fetchingInbox.postValue(false); |
|
||||
hasOlder = false; |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void parseInboxResponse(final DirectInboxResponse response) { |
|
||||
if (response == null) { |
|
||||
hasOlder = false; |
|
||||
return; |
|
||||
} |
|
||||
if (!response.getStatus().equals("ok")) { |
|
||||
Log.e(TAG, "DM inbox fetch response: status not ok"); |
|
||||
hasOlder = false; |
|
||||
return; |
|
||||
} |
|
||||
seqId = response.getSeqId(); |
|
||||
if (viewer == null) { |
|
||||
viewer = response.getViewer(); |
|
||||
} |
|
||||
final DirectInbox inbox = response.getInbox(); |
|
||||
final List<DirectThread> threads = inbox.getThreads(); |
|
||||
if (!TextUtils.isEmpty(cursor)) { |
|
||||
addThreads(threads); |
|
||||
} else { |
|
||||
setThreads(threads); |
|
||||
} |
|
||||
cursor = inbox.getOldestCursor(); |
|
||||
hasOlder = inbox.hasOlder(); |
|
||||
pendingRequestsTotal.postValue(response.getPendingRequestsTotal()); |
|
||||
// unseenCount.postValue(inbox.getUnseenCount()); |
|
||||
} |
|
||||
|
|
||||
private void stopCurrentInboxRequest() { |
|
||||
if (inboxRequest == null || inboxRequest.isCanceled() || inboxRequest.isExecuted()) return; |
|
||||
inboxRequest.cancel(); |
|
||||
inboxRequest = null; |
|
||||
} |
|
||||
|
|
||||
public void fetchUnseenCount() { |
|
||||
if ((fetchingUnseenCount.getValue() != null && fetchingUnseenCount.getValue())) return; |
|
||||
stopCurrentUnseenCountRequest(); |
|
||||
fetchingUnseenCount.postValue(true); |
|
||||
unseenCountRequest = service.fetchUnseenCount(); |
|
||||
unseenCountRequest.enqueue(new Callback<DirectBadgeCount>() { |
|
||||
@Override |
|
||||
public void onResponse(@NonNull final Call<DirectBadgeCount> call, @NonNull final Response<DirectBadgeCount> response) { |
|
||||
parseUnseenCountResponse(response.body()); |
|
||||
fetchingUnseenCount.postValue(false); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<DirectBadgeCount> call, @NonNull final Throwable t) { |
|
||||
Log.e(TAG, "Failed fetching unseen count", t); |
|
||||
fetchingUnseenCount.postValue(false); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void parseUnseenCountResponse(final DirectBadgeCount directBadgeCount) { |
|
||||
if (directBadgeCount == null) return; |
|
||||
unseenCount.postValue(directBadgeCount.getBadgeCount()); |
|
||||
} |
|
||||
|
|
||||
private void stopCurrentUnseenCountRequest() { |
|
||||
if (unseenCountRequest == null || unseenCountRequest.isCanceled() || unseenCountRequest.isExecuted()) return; |
|
||||
unseenCountRequest.cancel(); |
|
||||
unseenCountRequest = null; |
|
||||
|
inboxManager.fetchInbox(); |
||||
} |
} |
||||
|
|
||||
public void refresh() { |
public void refresh() { |
||||
cursor = null; |
|
||||
seqId = 0; |
|
||||
hasOlder = true; |
|
||||
fetchInbox(); |
|
||||
fetchUnseenCount(); |
|
||||
|
inboxManager.refresh(); |
||||
} |
} |
||||
|
|
||||
public void onDestroy() { |
public void onDestroy() { |
||||
stopCurrentInboxRequest(); |
|
||||
// getThreads().postValue(Collections.emptyList()); |
|
||||
|
inboxManager.onDestroy(); |
||||
} |
} |
||||
} |
} |
@ -1,141 +1,48 @@ |
|||||
package awais.instagrabber.viewmodels; |
package awais.instagrabber.viewmodels; |
||||
|
|
||||
import android.util.Log; |
|
||||
|
|
||||
import androidx.annotation.NonNull; |
|
||||
import androidx.lifecycle.LiveData; |
import androidx.lifecycle.LiveData; |
||||
import androidx.lifecycle.MutableLiveData; |
|
||||
import androidx.lifecycle.ViewModel; |
import androidx.lifecycle.ViewModel; |
||||
|
|
||||
import java.util.Collection; |
|
||||
import java.util.LinkedList; |
|
||||
import java.util.List; |
import java.util.List; |
||||
|
|
||||
|
import awais.instagrabber.managers.DirectMessagesManager; |
||||
|
import awais.instagrabber.managers.InboxManager; |
||||
|
import awais.instagrabber.models.Resource; |
||||
import awais.instagrabber.repositories.responses.User; |
import awais.instagrabber.repositories.responses.User; |
||||
import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; |
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectInbox; |
import awais.instagrabber.repositories.responses.directmessages.DirectInbox; |
||||
import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; |
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
||||
import awais.instagrabber.utils.Constants; |
|
||||
import awais.instagrabber.utils.CookieUtils; |
|
||||
import awais.instagrabber.utils.TextUtils; |
|
||||
import awais.instagrabber.webservices.DirectMessagesService; |
|
||||
import retrofit2.Call; |
|
||||
import retrofit2.Callback; |
|
||||
import retrofit2.Response; |
|
||||
|
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper; |
|
||||
|
|
||||
public class DirectPendingInboxViewModel extends ViewModel { |
public class DirectPendingInboxViewModel extends ViewModel { |
||||
private static final String TAG = DirectPendingInboxViewModel.class.getSimpleName(); |
private static final String TAG = DirectPendingInboxViewModel.class.getSimpleName(); |
||||
|
|
||||
private final DirectMessagesService service; |
|
||||
private final MutableLiveData<Boolean> fetchingInbox = new MutableLiveData<>(false); |
|
||||
private final MutableLiveData<List<DirectThread>> threads = new MutableLiveData<>(); |
|
||||
|
|
||||
private Call<DirectInboxResponse> inboxRequest; |
|
||||
private Call<DirectBadgeCount> unseenCountRequest; |
|
||||
private long seqId; |
|
||||
private String cursor; |
|
||||
private boolean hasOlder = true; |
|
||||
private User viewer; |
|
||||
|
private final InboxManager inboxManager; |
||||
|
|
||||
public DirectPendingInboxViewModel() { |
public DirectPendingInboxViewModel() { |
||||
final String cookie = settingsHelper.getString(Constants.COOKIE); |
|
||||
final long userId = CookieUtils.getUserIdFromCookie(cookie); |
|
||||
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID); |
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie); |
|
||||
if (TextUtils.isEmpty(csrfToken) || userId <= 0 || TextUtils.isEmpty(deviceUuid)) { |
|
||||
throw new IllegalArgumentException("User is not logged in!"); |
|
||||
} |
|
||||
service = DirectMessagesService.getInstance(csrfToken, userId, deviceUuid); |
|
||||
fetchInbox(); |
|
||||
|
inboxManager = DirectMessagesManager.getInstance().getPendingInboxManager(); |
||||
|
inboxManager.fetchInbox(); |
||||
} |
} |
||||
|
|
||||
public LiveData<List<DirectThread>> getThreads() { |
public LiveData<List<DirectThread>> getThreads() { |
||||
return threads; |
|
||||
} |
|
||||
|
|
||||
public void setThreads(final List<DirectThread> threads) { |
|
||||
this.threads.postValue(threads); |
|
||||
} |
|
||||
|
|
||||
public void addThreads(final Collection<DirectThread> threads) { |
|
||||
if (threads == null) return; |
|
||||
List<DirectThread> list = getThreads().getValue(); |
|
||||
list = list == null ? new LinkedList<>() : new LinkedList<>(list); |
|
||||
list.addAll(threads); |
|
||||
this.threads.postValue(list); |
|
||||
|
return inboxManager.getThreads(); |
||||
} |
} |
||||
|
|
||||
public LiveData<Boolean> getFetchingInbox() { |
|
||||
return fetchingInbox; |
|
||||
|
public LiveData<Resource<DirectInbox>> getInbox() { |
||||
|
return inboxManager.getInbox(); |
||||
} |
} |
||||
|
|
||||
public User getViewer() { |
public User getViewer() { |
||||
return viewer; |
|
||||
|
return inboxManager.getViewer(); |
||||
} |
} |
||||
|
|
||||
public void fetchInbox() { |
public void fetchInbox() { |
||||
if ((fetchingInbox.getValue() != null && fetchingInbox.getValue()) || !hasOlder) return; |
|
||||
stopCurrentInboxRequest(); |
|
||||
fetchingInbox.postValue(true); |
|
||||
inboxRequest = service.fetchPendingInbox(cursor, seqId); |
|
||||
inboxRequest.enqueue(new Callback<DirectInboxResponse>() { |
|
||||
@Override |
|
||||
public void onResponse(@NonNull final Call<DirectInboxResponse> call, @NonNull final Response<DirectInboxResponse> response) { |
|
||||
parseInboxResponse(response.body()); |
|
||||
fetchingInbox.postValue(false); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<DirectInboxResponse> call, @NonNull final Throwable t) { |
|
||||
Log.e(TAG, "Failed fetching pending inbox", t); |
|
||||
fetchingInbox.postValue(false); |
|
||||
hasOlder = false; |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void parseInboxResponse(final DirectInboxResponse response) { |
|
||||
if (response == null) { |
|
||||
hasOlder = false; |
|
||||
return; |
|
||||
} |
|
||||
if (!response.getStatus().equals("ok")) { |
|
||||
Log.e(TAG, "DM pending inbox fetch response: status not ok"); |
|
||||
hasOlder = false; |
|
||||
return; |
|
||||
} |
|
||||
seqId = response.getSeqId(); |
|
||||
if (viewer == null) { |
|
||||
viewer = response.getViewer(); |
|
||||
} |
|
||||
final DirectInbox inbox = response.getInbox(); |
|
||||
final List<DirectThread> threads = inbox.getThreads(); |
|
||||
if (!TextUtils.isEmpty(cursor)) { |
|
||||
addThreads(threads); |
|
||||
} else { |
|
||||
setThreads(threads); |
|
||||
} |
|
||||
cursor = inbox.getOldestCursor(); |
|
||||
hasOlder = inbox.hasOlder(); |
|
||||
} |
|
||||
|
|
||||
private void stopCurrentInboxRequest() { |
|
||||
if (inboxRequest == null || inboxRequest.isCanceled() || inboxRequest.isExecuted()) return; |
|
||||
inboxRequest.cancel(); |
|
||||
inboxRequest = null; |
|
||||
|
inboxManager.fetchInbox(); |
||||
} |
} |
||||
|
|
||||
public void refresh() { |
public void refresh() { |
||||
cursor = null; |
|
||||
seqId = 0; |
|
||||
hasOlder = true; |
|
||||
fetchInbox(); |
|
||||
|
inboxManager.refresh(); |
||||
} |
} |
||||
|
|
||||
public void onDestroy() { |
public void onDestroy() { |
||||
stopCurrentInboxRequest(); |
|
||||
|
inboxManager.onDestroy(); |
||||
} |
} |
||||
} |
} |
1057
app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,35 @@ |
|||||
|
package awais.instagrabber.viewmodels.factories; |
||||
|
|
||||
|
import android.app.Application; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.lifecycle.ViewModel; |
||||
|
import androidx.lifecycle.ViewModelProvider; |
||||
|
|
||||
|
import awais.instagrabber.repositories.responses.User; |
||||
|
import awais.instagrabber.viewmodels.DirectSettingsViewModel; |
||||
|
|
||||
|
public class DirectSettingsViewModelFactory implements ViewModelProvider.Factory { |
||||
|
|
||||
|
private final Application application; |
||||
|
private final String threadId; |
||||
|
private final boolean pending; |
||||
|
private final User currentUser; |
||||
|
|
||||
|
public DirectSettingsViewModelFactory(@NonNull final Application application, |
||||
|
@NonNull final String threadId, |
||||
|
final boolean pending, |
||||
|
@NonNull final User currentUser) { |
||||
|
this.application = application; |
||||
|
this.threadId = threadId; |
||||
|
this.pending = pending; |
||||
|
this.currentUser = currentUser; |
||||
|
} |
||||
|
|
||||
|
@NonNull |
||||
|
@Override |
||||
|
public <T extends ViewModel> T create(@NonNull final Class<T> modelClass) { |
||||
|
//noinspection unchecked |
||||
|
return (T) new DirectSettingsViewModel(application, threadId, pending, currentUser); |
||||
|
} |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
package awais.instagrabber.viewmodels.factories; |
||||
|
|
||||
|
import android.app.Application; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.lifecycle.ViewModel; |
||||
|
import androidx.lifecycle.ViewModelProvider; |
||||
|
|
||||
|
import awais.instagrabber.repositories.responses.User; |
||||
|
import awais.instagrabber.viewmodels.DirectThreadViewModel; |
||||
|
|
||||
|
public class DirectThreadViewModelFactory implements ViewModelProvider.Factory { |
||||
|
|
||||
|
private final Application application; |
||||
|
private final String threadId; |
||||
|
private final boolean pending; |
||||
|
private final User currentUser; |
||||
|
|
||||
|
public DirectThreadViewModelFactory(@NonNull final Application application, |
||||
|
@NonNull final String threadId, |
||||
|
final boolean pending, |
||||
|
@NonNull final User currentUser) { |
||||
|
this.application = application; |
||||
|
this.threadId = threadId; |
||||
|
this.pending = pending; |
||||
|
this.currentUser = currentUser; |
||||
|
} |
||||
|
|
||||
|
@NonNull |
||||
|
@Override |
||||
|
public <T extends ViewModel> T create(@NonNull final Class<T> modelClass) { |
||||
|
//noinspection unchecked |
||||
|
return (T) new DirectThreadViewModel(application, threadId, pending, currentUser); |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue