mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-12-23 05:16:58 +00:00
Share posts via DM. Resolves part of austinhuang0131/barinsta#537
This commit is contained in:
parent
0dfdc4bb41
commit
742b696d17
@ -14,6 +14,7 @@ import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -68,8 +69,10 @@ import com.skydoves.balloon.overlay.BalloonOverlayCircle;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.UserSearchNavGraphDirections;
|
||||
import awais.instagrabber.activities.MainActivity;
|
||||
import awais.instagrabber.adapters.SliderCallbackAdapter;
|
||||
import awais.instagrabber.adapters.SliderItemsAdapter;
|
||||
@ -93,6 +96,7 @@ import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.repositories.responses.VideoVersion;
|
||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.NullSafePair;
|
||||
import awais.instagrabber.utils.NumberUtils;
|
||||
@ -124,6 +128,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
private PopupMenu optionsPopup;
|
||||
private EditTextDialogFragment editTextDialogFragment;
|
||||
private boolean wasDeleted;
|
||||
private MutableLiveData<Object> backStackSavedStateCollectionLiveData;
|
||||
private MutableLiveData<Object> backStackSavedStateResultLiveData;
|
||||
private OnDeleteListener onDeleteListener;
|
||||
@Nullable
|
||||
@ -131,7 +136,6 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
private LayoutPostViewBottomBinding bottom;
|
||||
private View postView;
|
||||
private int originalHeight;
|
||||
private int originalSystemUi;
|
||||
private boolean isInFullScreenMode;
|
||||
private StyledPlayerView playerView;
|
||||
private int playerViewOriginalHeight;
|
||||
@ -145,8 +149,28 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (result instanceof String) {
|
||||
final String collection = (String) result;
|
||||
handleSaveUnsaveResourceLiveData(viewModel.toggleSave(collection, viewModel.getMedia().getHasViewerSaved()));
|
||||
} else if ((result instanceof RankedRecipient)) {
|
||||
// Log.d(TAG, "result: " + result);
|
||||
final Context context = getContext();
|
||||
if (context != null) {
|
||||
Toast.makeText(context, R.string.sending, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
viewModel.shareDm((RankedRecipient) result);
|
||||
} else if ((result instanceof Set)) {
|
||||
try {
|
||||
// Log.d(TAG, "result: " + result);
|
||||
final Context context = getContext();
|
||||
if (context != null) {
|
||||
Toast.makeText(context, R.string.sending, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
//noinspection unchecked
|
||||
viewModel.shareDm((Set<RankedRecipient>) result);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "share: ", e);
|
||||
}
|
||||
}
|
||||
// clear result
|
||||
backStackSavedStateCollectionLiveData.postValue(null);
|
||||
backStackSavedStateResultLiveData.postValue(null);
|
||||
};
|
||||
|
||||
@ -193,7 +217,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
// wasPaused = true;
|
||||
if (settingsHelper.getBoolean(PreferenceKeys.PLAY_IN_BACKGROUND)) return;
|
||||
final Media media = viewModel.getMedia();
|
||||
if (media == null) return;
|
||||
if (media == null || media.getMediaType() == null) return;
|
||||
switch (media.getMediaType()) {
|
||||
case MEDIA_TYPE_VIDEO:
|
||||
if (videoPlayerViewHelper != null) {
|
||||
@ -214,7 +238,9 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
final NavController navController = NavHostFragment.findNavController(this);
|
||||
final NavBackStackEntry backStackEntry = navController.getCurrentBackStackEntry();
|
||||
if (backStackEntry != null) {
|
||||
backStackSavedStateResultLiveData = backStackEntry.getSavedStateHandle().getLiveData("collection");
|
||||
backStackSavedStateCollectionLiveData = backStackEntry.getSavedStateHandle().getLiveData("collection");
|
||||
backStackSavedStateCollectionLiveData.observe(getViewLifecycleOwner(), backStackSavedStateObserver);
|
||||
backStackSavedStateResultLiveData = backStackEntry.getSavedStateHandle().getLiveData("result");
|
||||
backStackSavedStateResultLiveData.observe(getViewLifecycleOwner(), backStackSavedStateObserver);
|
||||
}
|
||||
}
|
||||
@ -224,7 +250,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
super.onDestroyView();
|
||||
showSystemUI();
|
||||
final Media media = viewModel.getMedia();
|
||||
if (media == null) return;
|
||||
if (media == null || media.getMediaType() == null) return;
|
||||
switch (media.getMediaType()) {
|
||||
case MEDIA_TYPE_VIDEO:
|
||||
if (videoPlayerViewHelper != null) {
|
||||
@ -740,14 +766,55 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
// is this necessary?
|
||||
Toast.makeText(context, R.string.share_private_post, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
final Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
sharingIntent.setType("text/plain");
|
||||
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "https://instagram.com/p/" + media.getCode());
|
||||
startActivity(Intent.createChooser(sharingIntent,
|
||||
isPrivate ? getString(R.string.share_private_post) : getString(R.string.share_public_post)));
|
||||
if (viewModel.isLoggedIn()) {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(context, R.style.popupMenuStyle);
|
||||
final PopupMenu popupMenu = new PopupMenu(themeWrapper, bottom.share);
|
||||
final Menu menu = popupMenu.getMenu();
|
||||
menu.add(0, R.id.share_dm, 0, R.string.share_via_dm);
|
||||
menu.add(0, R.id.share, 1, R.string.share_link);
|
||||
popupMenu.setOnMenuItemClickListener(item -> {
|
||||
final int itemId = item.getItemId();
|
||||
if (itemId == R.id.share_dm) {
|
||||
final UserSearchNavGraphDirections.ActionGlobalUserSearch actionGlobalUserSearch = UserSearchFragmentDirections
|
||||
.actionGlobalUserSearch()
|
||||
.setTitle(getString(R.string.share))
|
||||
.setActionLabel(getString(R.string.send))
|
||||
.setShowGroups(true)
|
||||
.setMultiple(true)
|
||||
.setSearchMode(UserSearchFragment.SearchMode.RAVEN);
|
||||
final NavController navController = NavHostFragment.findNavController(PostViewV2Fragment.this);
|
||||
try {
|
||||
navController.navigate(actionGlobalUserSearch);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "setupShare: ", e);
|
||||
}
|
||||
return true;
|
||||
} else if (itemId == R.id.share) {
|
||||
shareLink(media, isPrivate);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
popupMenu.show();
|
||||
return;
|
||||
}
|
||||
shareLink(media, isPrivate);
|
||||
});
|
||||
}
|
||||
|
||||
private void shareLink(@NonNull final Media media, final boolean isPrivate) {
|
||||
final Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
sharingIntent.setType("text/plain");
|
||||
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "https://instagram.com/p/" + media.getCode());
|
||||
startActivity(Intent.createChooser(
|
||||
sharingIntent,
|
||||
isPrivate ? getString(R.string.share_private_post)
|
||||
: getString(R.string.share_public_post)
|
||||
));
|
||||
}
|
||||
|
||||
private void setupPostTypeLayout(final MediaItemType type) {
|
||||
if (type == null) return;
|
||||
switch (type) {
|
||||
@ -1246,7 +1313,9 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
}
|
||||
|
||||
private void toggleDetails() {
|
||||
final boolean hasBeenToggled = true;
|
||||
// final boolean hasBeenToggled = true;
|
||||
final MainActivity activity = (MainActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
final Media media = viewModel.getMedia();
|
||||
binding.getRoot().post(() -> {
|
||||
TransitionManager.beginDelayedTransition(binding.getRoot());
|
||||
@ -1268,8 +1337,9 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
playerView.getLayoutParams().height = fullHeight;
|
||||
}
|
||||
}
|
||||
final BottomNavigationView bottomNavView = activity.getBottomNavView();
|
||||
bottomNavView.setVisibility(View.GONE);
|
||||
detailsVisible = false;
|
||||
|
||||
if (media.getUser() != null) {
|
||||
binding.profilePic.setVisibility(View.GONE);
|
||||
binding.title.setVisibility(View.GONE);
|
||||
@ -1310,6 +1380,8 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
playerView = null;
|
||||
}
|
||||
}
|
||||
final BottomNavigationView bottomNavView = activity.getBottomNavView();
|
||||
bottomNavView.setVisibility(View.VISIBLE);
|
||||
if (media.getUser() != null) {
|
||||
binding.profilePic.setVisibility(View.VISIBLE);
|
||||
binding.title.setVisibility(View.VISIBLE);
|
||||
@ -1375,8 +1447,6 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (toolbar != null) {
|
||||
toolbar.setVisibility(View.GONE);
|
||||
}
|
||||
final BottomNavigationView bottomNavView = activity.getBottomNavView();
|
||||
bottomNavView.setVisibility(View.GONE);
|
||||
binding.getRoot().setPadding(binding.getRoot().getPaddingLeft(),
|
||||
binding.getRoot().getPaddingTop(),
|
||||
binding.getRoot().getPaddingRight(),
|
||||
@ -1404,8 +1474,6 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (toolbar != null) {
|
||||
toolbar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
final BottomNavigationView bottomNavView = activity.getBottomNavView();
|
||||
bottomNavView.setVisibility(View.VISIBLE);
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
binding.getRoot().setPadding(binding.getRoot().getPaddingLeft(),
|
||||
|
@ -1,16 +1,38 @@
|
||||
package awais.instagrabber.managers;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import awais.instagrabber.models.Resource;
|
||||
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
|
||||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadBroadcastResponse;
|
||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.webservices.DirectMessagesService;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public final class DirectMessagesManager {
|
||||
private static final String TAG = DirectMessagesManager.class.getSimpleName();
|
||||
@ -21,6 +43,8 @@ public final class DirectMessagesManager {
|
||||
private final InboxManager inboxManager;
|
||||
private final InboxManager pendingInboxManager;
|
||||
|
||||
private DirectMessagesService service;
|
||||
|
||||
public static DirectMessagesManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (LOCK) {
|
||||
@ -35,26 +59,34 @@ public final class DirectMessagesManager {
|
||||
private DirectMessagesManager() {
|
||||
inboxManager = InboxManager.getInstance(false);
|
||||
pendingInboxManager = InboxManager.getInstance(true);
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
final long viewerId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
if (csrfToken == null) return;
|
||||
service = DirectMessagesService.getInstance(csrfToken, viewerId, deviceUuid);
|
||||
}
|
||||
|
||||
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));
|
||||
final int index = Iterables.indexOf(pendingThreads, t -> t != null && 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;
|
||||
if (threads != null) {
|
||||
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++;
|
||||
}
|
||||
insertIndex++;
|
||||
}
|
||||
thread.setPending(false);
|
||||
inboxManager.addThread(thread, insertIndex);
|
||||
@ -78,4 +110,166 @@ public final class DirectMessagesManager {
|
||||
@NonNull final ContentResolver contentResolver) {
|
||||
return ThreadManager.getInstance(threadId, pending, currentUser, contentResolver);
|
||||
}
|
||||
|
||||
public void createThread(final long userPk,
|
||||
@Nullable final Function<DirectThread, Void> callback) {
|
||||
if (service == null) return;
|
||||
final Call<DirectThread> createThreadRequest = service.createThread(Collections.singletonList(userPk), null);
|
||||
createThreadRequest.enqueue(new Callback<DirectThread>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<DirectThread> call, @NonNull final Response<DirectThread> response) {
|
||||
if (!response.isSuccessful()) {
|
||||
if (response.errorBody() != null) {
|
||||
try {
|
||||
final String string = response.errorBody().string();
|
||||
final String msg = String.format(Locale.US,
|
||||
"onResponse: url: %s, responseCode: %d, errorBody: %s",
|
||||
call.request().url().toString(),
|
||||
response.code(),
|
||||
string);
|
||||
Log.e(TAG, msg);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "onResponse: ", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "onResponse: request was not successful and response error body was null");
|
||||
return;
|
||||
}
|
||||
final DirectThread thread = response.body();
|
||||
if (thread == null) {
|
||||
Log.e(TAG, "onResponse: thread is null");
|
||||
return;
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.apply(thread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<DirectThread> call, @NonNull final Throwable t) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void sendMedia(@NonNull final Set<RankedRecipient> recipients, final String mediaId) {
|
||||
final int[] resultsCount = {0};
|
||||
final Function<Void, Void> callback = unused -> {
|
||||
resultsCount[0]++;
|
||||
if (resultsCount[0] == recipients.size()) {
|
||||
inboxManager.refresh();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
for (final RankedRecipient recipient : recipients) {
|
||||
if (recipient == null) continue;
|
||||
sendMedia(recipient, mediaId, false, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMedia(@NonNull final RankedRecipient recipient, final String mediaId) {
|
||||
sendMedia(recipient, mediaId, true, null);
|
||||
}
|
||||
|
||||
private void sendMedia(@NonNull final RankedRecipient recipient,
|
||||
@NonNull final String mediaId,
|
||||
final boolean refreshInbox,
|
||||
@Nullable final Function<Void, Void> callback) {
|
||||
if (recipient.getThread() == null && recipient.getUser() != null) {
|
||||
// create thread and forward
|
||||
createThread(recipient.getUser().getPk(), directThread -> {
|
||||
sendMedia(directThread, mediaId, unused -> {
|
||||
if (refreshInbox) {
|
||||
inboxManager.refresh();
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.apply(null);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if (recipient.getThread() == null) return;
|
||||
// just forward
|
||||
final DirectThread thread = recipient.getThread();
|
||||
sendMedia(thread, mediaId, unused -> {
|
||||
if (refreshInbox) {
|
||||
inboxManager.refresh();
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.apply(null);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public LiveData<Resource<Object>> sendMedia(@NonNull final DirectThread thread,
|
||||
@NonNull final String mediaId,
|
||||
@Nullable final Function<Void, Void> callback) {
|
||||
return sendMedia(thread.getThreadId(), mediaId, callback);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public LiveData<Resource<Object>> sendMedia(@NonNull final String threadId,
|
||||
@NonNull final String mediaId,
|
||||
@Nullable final Function<Void, Void> callback) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
data.postValue(Resource.loading(null));
|
||||
final Call<DirectThreadBroadcastResponse> request = service.broadcastMediaShare(
|
||||
UUID.randomUUID().toString(),
|
||||
BroadcastOptions.ThreadIdOrUserIds.of(threadId),
|
||||
mediaId
|
||||
);
|
||||
request.enqueue(new Callback<DirectThreadBroadcastResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<DirectThreadBroadcastResponse> call,
|
||||
@NonNull final Response<DirectThreadBroadcastResponse> response) {
|
||||
if (response.isSuccessful()) {
|
||||
data.postValue(Resource.success(new Object()));
|
||||
if (callback != null) {
|
||||
callback.apply(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (response.errorBody() != null) {
|
||||
try {
|
||||
final String string = response.errorBody().string();
|
||||
final String msg = String.format(Locale.US,
|
||||
"onResponse: url: %s, responseCode: %d, errorBody: %s",
|
||||
call.request().url().toString(),
|
||||
response.code(),
|
||||
string);
|
||||
Log.e(TAG, msg);
|
||||
data.postValue(Resource.error(msg, null));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "onResponse: ", e);
|
||||
data.postValue(Resource.error(e.getMessage(), null));
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.apply(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final String msg = "onResponse: request was not successful and response error body was null";
|
||||
Log.e(TAG, msg);
|
||||
data.postValue(Resource.error(msg, null));
|
||||
if (callback != null) {
|
||||
callback.apply(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<DirectThreadBroadcastResponse> call, @NonNull final Throwable t) {
|
||||
Log.e(TAG, "onFailure: ", t);
|
||||
data.postValue(Resource.error(t.getMessage(), null));
|
||||
if (callback != null) {
|
||||
callback.apply(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ public final class ThreadManager {
|
||||
private final ThreadIdOrUserIds threadIdOrUserIds;
|
||||
private final User currentUser;
|
||||
private final ContentResolver contentResolver;
|
||||
private final DirectMessagesManager messagesManager;
|
||||
|
||||
private DirectMessagesService service;
|
||||
private MediaService mediaService;
|
||||
@ -147,7 +148,7 @@ public final class ThreadManager {
|
||||
final boolean pending,
|
||||
@NonNull final User currentUser,
|
||||
@NonNull final ContentResolver contentResolver) {
|
||||
final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance();
|
||||
messagesManager = DirectMessagesManager.getInstance();
|
||||
this.inboxManager = pending ? messagesManager.getPendingInboxManager() : messagesManager.getInboxManager();
|
||||
this.threadId = threadId;
|
||||
this.threadIdOrUserIds = ThreadIdOrUserIds.of(threadId);
|
||||
@ -821,42 +822,10 @@ public final class ThreadManager {
|
||||
if (recipient == null || itemToForward == null) return;
|
||||
if (recipient.getThread() == null && recipient.getUser() != null) {
|
||||
// create thread and forward
|
||||
final Call<DirectThread> createThreadRequest = service.createThread(Collections.singletonList(recipient.getUser().getPk()), null);
|
||||
createThreadRequest.enqueue(new Callback<DirectThread>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<DirectThread> call, @NonNull final Response<DirectThread> response) {
|
||||
if (!response.isSuccessful()) {
|
||||
if (response.errorBody() != null) {
|
||||
try {
|
||||
final String string = response.errorBody().string();
|
||||
final String msg = String.format(Locale.US,
|
||||
"onResponse: url: %s, responseCode: %d, errorBody: %s",
|
||||
call.request().url().toString(),
|
||||
response.code(),
|
||||
string);
|
||||
Log.e(TAG, msg);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "onResponse: ", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "onResponse: request was not successful and response error body was null");
|
||||
return;
|
||||
}
|
||||
final DirectThread thread = response.body();
|
||||
if (thread == null) {
|
||||
Log.e(TAG, "onResponse: thread is null");
|
||||
return;
|
||||
}
|
||||
forward(thread, itemToForward);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<DirectThread> call, @NonNull final Throwable t) {
|
||||
|
||||
}
|
||||
messagesManager.createThread(recipient.getUser().getPk(), directThread -> {
|
||||
forward(directThread, itemToForward);
|
||||
return null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (recipient.getThread() != null) {
|
||||
// just forward
|
||||
@ -870,13 +839,25 @@ public final class ThreadManager {
|
||||
replyToItem.postValue(item);
|
||||
}
|
||||
|
||||
private void forward(@NonNull final DirectThread thread, @NonNull final DirectItem itemToForward) {
|
||||
@NonNull
|
||||
private LiveData<Resource<Object>> forward(@NonNull final DirectThread thread, @NonNull final DirectItem itemToForward) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
if (itemToForward.getItemId() == null) {
|
||||
data.postValue(Resource.error("item id is null", null));
|
||||
return data;
|
||||
}
|
||||
final DirectItemType itemType = itemToForward.getItemType();
|
||||
if (itemType == null) {
|
||||
data.postValue(Resource.error("item type is null", null));
|
||||
return data;
|
||||
}
|
||||
final String itemTypeName = itemType.getName();
|
||||
if (itemTypeName == null) {
|
||||
Log.e(TAG, "forward: itemTypeName was null!");
|
||||
return;
|
||||
data.postValue(Resource.error("itemTypeName is null", null));
|
||||
return data;
|
||||
}
|
||||
data.postValue(Resource.loading(null));
|
||||
final Call<DirectThreadBroadcastResponse> request = service.forward(thread.getThreadId(),
|
||||
itemTypeName,
|
||||
threadId,
|
||||
@ -885,7 +866,10 @@ public final class ThreadManager {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<DirectThreadBroadcastResponse> call,
|
||||
@NonNull final Response<DirectThreadBroadcastResponse> response) {
|
||||
if (response.isSuccessful()) return;
|
||||
if (response.isSuccessful()) {
|
||||
data.postValue(Resource.success(new Object()));
|
||||
return;
|
||||
}
|
||||
if (response.errorBody() != null) {
|
||||
try {
|
||||
final String string = response.errorBody().string();
|
||||
@ -895,19 +879,25 @@ public final class ThreadManager {
|
||||
response.code(),
|
||||
string);
|
||||
Log.e(TAG, msg);
|
||||
data.postValue(Resource.error(msg, null));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "onResponse: ", e);
|
||||
data.postValue(Resource.error(e.getMessage(), null));
|
||||
}
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "onResponse: request was not successful and response error body was null");
|
||||
final String msg = "onResponse: request was not successful and response error body was null";
|
||||
Log.e(TAG, msg);
|
||||
data.postValue(Resource.error(msg, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<DirectThreadBroadcastResponse> call, @NonNull final Throwable t) {
|
||||
Log.e(TAG, "onFailure: ", t);
|
||||
data.postValue(Resource.error(t.getMessage(), null));
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
public LiveData<Resource<Object>> acceptRequest() {
|
||||
|
@ -8,7 +8,8 @@ public enum BroadcastItemType {
|
||||
LINK("link"),
|
||||
VIDEO("configure_video"),
|
||||
VOICE("share_voice"),
|
||||
ANIMATED_MEDIA("animated_media");
|
||||
ANIMATED_MEDIA("animated_media"),
|
||||
MEDIA_SHARE("media_share");
|
||||
|
||||
private final String value;
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package awais.instagrabber.repositories.requests.directmessages
|
||||
|
||||
import awais.instagrabber.models.enums.BroadcastItemType
|
||||
|
||||
class MediaShareBroadcastOptions(
|
||||
clientContext: String?,
|
||||
threadIdOrUserIds: ThreadIdOrUserIds,
|
||||
val mediaId: String
|
||||
) : BroadcastOptions(
|
||||
clientContext,
|
||||
threadIdOrUserIds,
|
||||
BroadcastItemType.MEDIA_SHARE
|
||||
) {
|
||||
|
||||
override fun getFormMap(): Map<String, String> {
|
||||
return mapOf("media_id" to mediaId)
|
||||
}
|
||||
}
|
@ -11,14 +11,17 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.managers.DirectMessagesManager;
|
||||
import awais.instagrabber.models.Resource;
|
||||
import awais.instagrabber.models.enums.MediaItemType;
|
||||
import awais.instagrabber.repositories.responses.Caption;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
@ -49,6 +52,7 @@ public class PostViewV2ViewModel extends ViewModel {
|
||||
private final boolean isLoggedIn;
|
||||
|
||||
private Media media;
|
||||
private DirectMessagesManager messageManager;
|
||||
|
||||
public PostViewV2ViewModel() {
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
@ -326,4 +330,18 @@ public class PostViewV2ViewModel extends ViewModel {
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
public void shareDm(@NonNull final RankedRecipient result) {
|
||||
if (messageManager == null) {
|
||||
messageManager = DirectMessagesManager.getInstance();
|
||||
}
|
||||
messageManager.sendMedia(result, media.getId());
|
||||
}
|
||||
|
||||
public void shareDm(@NonNull final Set<RankedRecipient> recipients) {
|
||||
if (messageManager == null) {
|
||||
messageManager = DirectMessagesManager.getInstance();
|
||||
}
|
||||
messageManager.sendMedia(recipients, media.getId());
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import awais.instagrabber.repositories.requests.directmessages.AnimatedMediaBroa
|
||||
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions;
|
||||
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions.ThreadIdOrUserIds;
|
||||
import awais.instagrabber.repositories.requests.directmessages.LinkBroadcastOptions;
|
||||
import awais.instagrabber.repositories.requests.directmessages.MediaShareBroadcastOptions;
|
||||
import awais.instagrabber.repositories.requests.directmessages.PhotoBroadcastOptions;
|
||||
import awais.instagrabber.repositories.requests.directmessages.ReactionBroadcastOptions;
|
||||
import awais.instagrabber.repositories.requests.directmessages.StoryReplyBroadcastOptions;
|
||||
@ -190,6 +191,12 @@ public class DirectMessagesService extends BaseService {
|
||||
return broadcast(new AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif));
|
||||
}
|
||||
|
||||
public Call<DirectThreadBroadcastResponse> broadcastMediaShare(@NonNull final String clientContext,
|
||||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds,
|
||||
@NonNull final String mediaId) {
|
||||
return broadcast(new MediaShareBroadcastOptions(clientContext, threadIdOrUserIds, mediaId));
|
||||
}
|
||||
|
||||
private Call<DirectThreadBroadcastResponse> broadcast(@NonNull final BroadcastOptions broadcastOptions) {
|
||||
if (TextUtils.isEmpty(broadcastOptions.getClientContext())) {
|
||||
throw new IllegalArgumentException("Broadcast requires a valid client context value");
|
||||
|
@ -111,6 +111,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/discoverFragment"
|
||||
android:name="awais.instagrabber.fragments.main.DiscoverFragment"
|
||||
|
@ -122,6 +122,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/feedFragment"
|
||||
android:name="awais.instagrabber.fragments.main.FeedFragment"
|
||||
|
@ -81,6 +81,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/hashTagFragment"
|
||||
android:name="awais.instagrabber.fragments.HashTagFragment"
|
||||
|
@ -82,6 +82,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/locationFragment"
|
||||
android:name="awais.instagrabber.fragments.LocationFragment"
|
||||
|
@ -73,6 +73,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/morePreferencesFragment"
|
||||
android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment"
|
||||
|
@ -84,6 +84,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/storyViewerFragment"
|
||||
android:name="awais.instagrabber.fragments.StoryViewerFragment"
|
||||
|
@ -98,6 +98,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/notificationsViewer"
|
||||
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
|
||||
|
@ -76,6 +76,12 @@
|
||||
app:argType="integer" />
|
||||
</action>
|
||||
|
||||
<include app:graph="@navigation/user_search_nav_graph" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_user_search"
|
||||
app:destination="@id/user_search_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/savedCollectionsFragment"
|
||||
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
|
||||
|
@ -5,4 +5,5 @@
|
||||
<item name="forward" type="id" />
|
||||
<item name="detail" type="id" />
|
||||
<item name="copy" type="id" />
|
||||
<item name="share_dm" type="id" />
|
||||
</resources>
|
@ -508,4 +508,7 @@
|
||||
<string name="click_to_show_full">Click to show full like count</string>
|
||||
<string name="no_profile_pic_found">No profile pic found!</string>
|
||||
<string name="swipe_up_confirmation">Are you sure you want to open this link?</string>
|
||||
<string name="sending">Sending...</string>
|
||||
<string name="share_via_dm">Share via DM</string>
|
||||
<string name="share_link">Share link…</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user