From c87311a68e5a9cc741dfa98e52f6baf045eda06e Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 1 Sep 2020 13:37:00 -0400 Subject: [PATCH] address #74, fix #76, fix #90, fix #104, fix #106 --- .../java/awais/instagrabber/MainHelper.java | 12 +- .../activities/DirectMessagesActivity.java | 16 ++- .../awais/instagrabber/activities/Main.java | 2 +- .../instagrabber/activities/PostViewer.java | 15 +-- .../activities/ProfilePicViewer.java | 5 +- .../adapters/DirectMessageMembersAdapter.java | 10 +- .../DirectMessageInboxItemViewHolder.java | 1 + .../viewholder/FollowsViewHolder.java | 3 +- .../instagrabber/asyncs/PostsFetcher.java | 2 +- .../asyncs/ProfilePictureFetcher.java | 1 + .../DirectThreadBroadcaster.java | 4 +- .../instagrabber/dialogs/SettingsDialog.java | 10 ++ .../DirectMessageSettingsFragment.java | 84 ++++++++++-- .../DirectMessageThreadFragment.java | 43 ++++-- .../direct_messages/InboxThreadModel.java | 20 +-- .../awais/instagrabber/utils/Constants.java | 6 +- .../instagrabber/utils/SettingsHelper.java | 8 +- .../java/awais/instagrabber/utils/Utils.java | 16 ++- app/src/main/res/drawable-anydpi/ic_star.xml | 10 ++ app/src/main/res/drawable-hdpi/ic_star.png | Bin 0 -> 375 bytes app/src/main/res/drawable-mdpi/ic_star.png | Bin 0 -> 258 bytes app/src/main/res/drawable-xhdpi/ic_star.png | Bin 0 -> 464 bytes app/src/main/res/drawable-xxhdpi/ic_star.png | Bin 0 -> 943 bytes app/src/main/res/drawable/circle.xml | 12 ++ .../res/layout/activity_direct_messages.xml | 16 +++ .../main/res/layout/dialog_main_settings.xml | 122 ++++++++++++------ .../fragment_direct_messages_settings.xml | 32 ++++- app/src/main/res/layout/item_follow.xml | 10 ++ .../res/layout/layout_include_simple_item.xml | 47 ++++--- app/src/main/res/values/strings.xml | 5 + 30 files changed, 392 insertions(+), 120 deletions(-) create mode 100644 app/src/main/res/drawable-anydpi/ic_star.xml create mode 100644 app/src/main/res/drawable-hdpi/ic_star.png create mode 100644 app/src/main/res/drawable-mdpi/ic_star.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_star.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_star.png create mode 100644 app/src/main/res/drawable/circle.xml diff --git a/app/src/main/java/awais/instagrabber/MainHelper.java b/app/src/main/java/awais/instagrabber/MainHelper.java index 088b3350..c727d78b 100755 --- a/app/src/main/java/awais/instagrabber/MainHelper.java +++ b/app/src/main/java/awais/instagrabber/MainHelper.java @@ -1234,7 +1234,17 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { main.locationModel != null ? main.locationModel.getName() : main.userQuery.replaceAll("^@", ""))); onRefresh(); } else if (v == main.mainBinding.profileView.btnFollow) { - new ProfileAction().execute("follow"); + if (main.profileModel.isPrivate()) { + new AlertDialog.Builder(main) + .setTitle(R.string.priv_acc) + .setMessage(R.string.priv_acc_confirm) + .setNegativeButton(R.string.no, null) + .setPositiveButton(R.string.yes, (dialog, which) -> new ProfileAction().execute("follow")) + .show(); + } + else { + new ProfileAction().execute("follow"); + } } else if (v == main.mainBinding.profileView.btnRestrict && isLoggedIn) { new ProfileAction().execute("restrict"); } else if (v == main.mainBinding.profileView.btnSaved && !iamme) { diff --git a/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java b/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java index 80483316..d8043469 100644 --- a/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java +++ b/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java @@ -18,11 +18,13 @@ import androidx.navigation.ui.NavigationUI; import awais.instagrabber.R; import awais.instagrabber.databinding.ActivityDirectMessagesBinding; import awais.instagrabber.fragments.directmessages.DirectMessageThreadFragmentArgs; +import awais.instagrabber.utils.Constants; +import static awais.instagrabber.utils.Utils.settingsHelper; public class DirectMessagesActivity extends BaseLanguageActivity implements NavController.OnDestinationChangedListener { private TextView toolbarTitle; - private AppCompatImageView infoButton; + private AppCompatImageView dmInfo, dmSeen; @Override protected void onCreate(Bundle savedInstanceState) { @@ -36,7 +38,8 @@ public class DirectMessagesActivity extends BaseLanguageActivity implements NavC final Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); - infoButton = binding.dmInfo; + dmInfo = binding.dmInfo; + dmSeen = binding.dmSeen; final NavController navController = Navigation.findNavController(this, R.id.direct_messages_nav_host_fragment); navController.addOnDestinationChangedListener(this); @@ -51,7 +54,8 @@ public class DirectMessagesActivity extends BaseLanguageActivity implements NavC switch (destination.getId()) { case R.id.directMessagesInboxFragment: setToolbarTitle(R.string.action_dms); - infoButton.setVisibility(View.GONE); + dmInfo.setVisibility(View.GONE); + dmSeen.setVisibility(View.GONE); return; case R.id.directMessagesThreadFragment: if (arguments == null) { @@ -59,14 +63,16 @@ public class DirectMessagesActivity extends BaseLanguageActivity implements NavC } final String title = DirectMessageThreadFragmentArgs.fromBundle(arguments).getTitle(); setToolbarTitle(title); - infoButton.setVisibility(View.VISIBLE); + dmInfo.setVisibility(View.VISIBLE); + dmSeen.setVisibility(settingsHelper.getBoolean(Constants.DM_MARK_AS_SEEN) ? View.GONE : View.VISIBLE); return; case R.id.directMessagesSettingsFragment: if (arguments == null) { return; } setToolbarTitle(R.string.action_settings); - infoButton.setVisibility(View.GONE); + dmInfo.setVisibility(View.GONE); + dmSeen.setVisibility(View.GONE); return; } } diff --git a/app/src/main/java/awais/instagrabber/activities/Main.java b/app/src/main/java/awais/instagrabber/activities/Main.java index 57c24244..f3c19720 100755 --- a/app/src/main/java/awais/instagrabber/activities/Main.java +++ b/app/src/main/java/awais/instagrabber/activities/Main.java @@ -127,7 +127,7 @@ public final class Main extends BaseLanguageActivity { mainBinding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(mainBinding.getRoot()); - FlavorTown.updateCheck(this); + if (settingsHelper.getBoolean(Constants.CHECK_UPDATES)) FlavorTown.updateCheck(this); FlavorTown.changelogCheck(this); cookie = settingsHelper.getString(Constants.COOKIE); diff --git a/app/src/main/java/awais/instagrabber/activities/PostViewer.java b/app/src/main/java/awais/instagrabber/activities/PostViewer.java index b46c765b..6322d539 100755 --- a/app/src/main/java/awais/instagrabber/activities/PostViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/PostViewer.java @@ -652,19 +652,12 @@ public final class PostViewer extends BaseLanguageActivity { postUserId = result.getId(); final boolean hdPicEmpty = Utils.isEmpty(hdProfilePic); - glideRequestManager.load(hdPicEmpty ? sdProfilePic : hdProfilePic).listener(new RequestListener() { - private boolean loaded = true; - + RequestListener profilePicListener = new RequestListener() { @Override public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) { viewerBinding.topPanel.ivProfilePic.setEnabled(false); viewerBinding.topPanel.ivProfilePic.setOnClickListener(null); - if (loaded) { - loaded = false; - if (!Utils.isEmpty(sdProfilePic)) glideRequestManager.load(sdProfilePic).listener(this) - .into(viewerBinding.topPanel.ivProfilePic); - } - return false; + return true; } @Override @@ -673,7 +666,9 @@ public final class PostViewer extends BaseLanguageActivity { viewerBinding.topPanel.ivProfilePic.setOnClickListener(onClickListener); return false; } - }).into(viewerBinding.topPanel.ivProfilePic); + }; + glideRequestManager.load(hdPicEmpty ? sdProfilePic : hdProfilePic).listener(profilePicListener) + .error(glideRequestManager.load(sdProfilePic).listener(profilePicListener)).into(viewerBinding.topPanel.ivProfilePic); final View viewStoryPost = findViewById(R.id.viewStoryPost); if (viewStoryPost != null) { diff --git a/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java b/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java index dbf3fbee..afdcaab5 100755 --- a/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java @@ -103,9 +103,6 @@ public final class ProfilePicViewer extends BaseLanguageActivity { errorHandled = true; new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null)) .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else { - glideRequestManager.load(profilePicUrl).into(profileBinding.imageViewer); - showImageInfo(); } profileBinding.progressView.setVisibility(View.GONE); return false; @@ -153,7 +150,7 @@ public final class ProfilePicViewer extends BaseLanguageActivity { profileBinding.imageInfo.setVisibility(View.VISIBLE); } } - }).into(profileBinding.imageViewer); + }).error(glideRequestManager.load(profilePicUrl)).into(profileBinding.imageViewer); }; new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null)) diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectMessageMembersAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectMessageMembersAdapter.java index 971275f1..6920596b 100755 --- a/app/src/main/java/awais/instagrabber/adapters/DirectMessageMembersAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectMessageMembersAdapter.java @@ -10,17 +10,22 @@ import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; +import java.util.List; + import awais.instagrabber.R; import awais.instagrabber.adapters.viewholder.FollowsViewHolder; import awais.instagrabber.models.ProfileModel; public final class DirectMessageMembersAdapter extends RecyclerView.Adapter { private final ProfileModel[] profileModels; + private final List admins; private final View.OnClickListener onClickListener; private final LayoutInflater layoutInflater; - public DirectMessageMembersAdapter(final ProfileModel[] profileModels, final Context context, final View.OnClickListener onClickListener) { + public DirectMessageMembersAdapter(final ProfileModel[] profileModels, final List admins, + final Context context, final View.OnClickListener onClickListener) { this.profileModels = profileModels; + this.admins = admins; this.layoutInflater = LayoutInflater.from(context); this.onClickListener = onClickListener; } @@ -44,6 +49,9 @@ public final class DirectMessageMembersAdapter extends RecyclerView.Adapter 0L ? View.VISIBLE : View.GONE); } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java index fb52eac1..4f3b9b58 100755 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java @@ -10,7 +10,7 @@ import androidx.recyclerview.widget.RecyclerView; import awais.instagrabber.R; public final class FollowsViewHolder extends RecyclerView.ViewHolder { - public final ImageView profileImage; + public final ImageView profileImage, isAdmin; public final TextView tvFullName, tvUsername; public FollowsViewHolder(@NonNull final View itemView) { @@ -18,5 +18,6 @@ public final class FollowsViewHolder extends RecyclerView.ViewHolder { profileImage = itemView.findViewById(R.id.ivProfilePic); tvFullName = itemView.findViewById(R.id.tvFullName); tvUsername = itemView.findViewById(R.id.tvUsername); + isAdmin = itemView.findViewById(R.id.isAdmin); } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java index 204323d6..6dbd4c88 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java @@ -56,7 +56,7 @@ public final class PostsFetcher extends AsyncTask { final String url; if (isHashTag) - url = "https://www.instagram.com/graphql/query/?query_hash=ded47faa9a1aaded10161a2ff32abb6b&variables=" + + url = "https://www.instagram.com/graphql/query/?query_hash=9b498c08113f1e09617a1703c22b2f32&variables=" + "{\"tag_name\":\"" + id.substring(1).toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}"; else if (isLocation) url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" + diff --git a/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java index 39cb4cfa..46d93041 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java @@ -86,6 +86,7 @@ public final class ProfilePictureFetcher extends AsyncTask { } } } + if (Utils.isEmpty(out)) out = picUrl; } catch (final Exception e) { if (logCollector != null) logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground"); diff --git a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectThreadBroadcaster.java b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectThreadBroadcaster.java index 561bb1ba..1994a2fc 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectThreadBroadcaster.java +++ b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectThreadBroadcaster.java @@ -161,7 +161,7 @@ public class DirectThreadBroadcaster extends AsyncTask currentlyRunning; - private DirectMessageMembersAdapter memberAdapter; - private View.OnClickListener clickListener; + private DirectMessageMembersAdapter memberAdapter, leftAdapter; + private View.OnClickListener clickListener, basicClickListener; private final FetchListener fetchListener = new FetchListener() { @Override @@ -63,8 +68,15 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr @Override public void onResult(final InboxThreadModel threadModel) { - memberAdapter = new DirectMessageMembersAdapter(threadModel.getUsers(), requireContext(), clickListener); + final List adminList = Arrays.asList(threadModel.getAdmins()); + amAdmin = adminList.contains(Long.parseLong(Utils.getUserIdFromCookie(cookie))); + memberAdapter = new DirectMessageMembersAdapter(threadModel.getUsers(), adminList, requireContext(), amAdmin ? clickListener : basicClickListener); userList.setAdapter(memberAdapter); + if (threadModel.getLeftUsers() != null && threadModel.getLeftUsers().length > 0) { + leftTitle.setVisibility(View.VISIBLE); + leftAdapter = new DirectMessageMembersAdapter(threadModel.getLeftUsers(), null, requireContext(), basicClickListener); + leftUserList.setAdapter(leftAdapter); + } } }; @@ -73,10 +85,9 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr super.onCreate(savedInstanceState); fragmentActivity = requireActivity(); - clickListener = v -> { + basicClickListener = v -> { final Object tag = v.getTag(); if (tag instanceof ProfileModel) { - // TODO: kick dialog ProfileModel model = (ProfileModel) tag; startActivity( new Intent(requireContext(), ProfileViewer.class) @@ -84,6 +95,37 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr ); } }; + + clickListener = v -> { + final Object tag = v.getTag(); + if (tag instanceof ProfileModel) { + ProfileModel model = (ProfileModel) tag; + if (!amAdmin || model.getId().equals(Utils.getUserIdFromCookie(cookie))) { + startActivity( + new Intent(requireContext(), ProfileViewer.class) + .putExtra(Constants.EXTRAS_USERNAME, model.getUsername()) + ); + } + else { + new AlertDialog.Builder(requireContext()).setAdapter( + new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, new String[]{ + getString(R.string.open_profile), + getString(R.string.dms_action_kick), + }), + (d,w) -> { + if (w == 0) + startActivity( + new Intent(requireContext(), ProfileViewer.class) + .putExtra(Constants.EXTRAS_USERNAME, model.getUsername()) + ); + else if (w == 1) { + new ChangeSettings().execute("remove_users", model.getId()); + onRefresh(); + } + }).show(); + } + } + }; } @Override @@ -92,7 +134,18 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr final Bundle savedInstanceState) { final FragmentDirectMessagesSettingsBinding binding = FragmentDirectMessagesSettingsBinding.inflate(inflater, container, false); final LinearLayout root = binding.getRoot(); - layoutManager = new LinearLayoutManager(requireContext()); + layoutManager = new LinearLayoutManager(requireContext()) { + @Override + public boolean canScrollVertically() { + return false; + } + }; + layoutManagerDos = new LinearLayoutManager(requireContext()) { + @Override + public boolean canScrollVertically() { + return false; + } + }; threadId = DirectMessageSettingsFragmentArgs.fromBundle(getArguments()).getThreadId(); threadTitle = DirectMessageSettingsFragmentArgs.fromBundle(getArguments()).getTitle(); @@ -102,6 +155,12 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr userList.setHasFixedSize(true); userList.setLayoutManager(layoutManager); + leftUserList = binding.leftUserList; + leftUserList.setHasFixedSize(true); + leftUserList.setLayoutManager(layoutManagerDos); + + leftTitle = binding.leftTitle; + titleText = binding.titleText; titleText.setText(threadTitle); @@ -154,11 +213,12 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr } class ChangeSettings extends AsyncTask { - String action; + String action, argument; boolean ok = false; protected Void doInBackground(String... rawAction) { action = rawAction[0]; + if (rawAction.length == 2) argument = rawAction[1]; final String url = "https://i.instagram.com/api/v1/direct_v2/threads/"+threadId+"/"+action+"/"; try { String urlParameters = "_csrftoken=" + cookie.split("csrftoken=")[1].split(";")[0] @@ -167,6 +227,8 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr urlParameters += "&title=" + URLEncoder.encode(titleText.getText().toString(), "UTF-8") .replaceAll("\\+", "%20").replaceAll("%21", "!").replaceAll("%27", "'") .replaceAll("%28", "(").replaceAll("%29", ")").replaceAll("%7E", "~"); + else if (action.startsWith("remove_users")) + urlParameters += ("&user_ids=[" + argument + "]"); final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); urlConnection.setRequestMethod("POST"); urlConnection.setUseCaches(false); @@ -197,11 +259,15 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr threadTitle = titleText.getText().toString(); titleSend.setVisibility(View.GONE); titleText.clearFocus(); + DirectMessageThreadFragment.hasSentSomething = true; } else if (action.equals("leave")) { DirectMessageInboxFragment.refreshPlease = true; NavHostFragment.findNavController(DirectMessageSettingsFragment.this).popBackStack(R.id.directMessagesInboxFragment, false); } + else { + DirectMessageThreadFragment.hasSentSomething = true; + } } else Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); } diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index ed5be0ea..bab07098 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -77,17 +77,17 @@ public class DirectMessageThreadFragment extends Fragment { private static final int PICK_IMAGE = 100; private FragmentActivity fragmentActivity; - private String threadId, threadTitle; - private String cursor; + private String threadId, threadTitle, cursor, lastMessage; private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); private final String myId = Utils.getUserIdFromCookie(cookie); private FragmentDirectMessagesThreadBinding binding; private DirectItemModelListViewModel listViewModel; private DirectItemModel directItemModel; private RecyclerView messageList; - private AppCompatImageView dmInfo; - private boolean hasSentSomething, hasDeletedSomething; + private AppCompatImageView dmInfo, dmSeen; + private boolean hasDeletedSomething; private boolean hasOlder = true; + public static boolean hasSentSomething; private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel(); private final List users = new ArrayList<>(); @@ -151,6 +151,10 @@ public class DirectMessageThreadFragment extends Fragment { list.addAll(newList); } listViewModel.getList().postValue(list); + + lastMessage = result.getNewestCursor(); + + if (Utils.settingsHelper.getBoolean(Constants.DM_MARK_AS_SEEN)) new ThreadAction().execute("seen", lastMessage); } binding.swipeRefreshLayout.setRefreshing(false); } @@ -162,6 +166,14 @@ public class DirectMessageThreadFragment extends Fragment { fragmentActivity = requireActivity(); } + @Override + public void onResume() { + super.onResume(); + if (hasSentSomething) { + new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + @Override public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container, @@ -169,6 +181,7 @@ public class DirectMessageThreadFragment extends Fragment { binding = FragmentDirectMessagesThreadBinding.inflate(inflater, container, false); CoordinatorLayout containerTwo = (CoordinatorLayout) container.getParent(); dmInfo = containerTwo.findViewById(R.id.dmInfo); + dmSeen = containerTwo.findViewById(R.id.dmSeen); final LinearLayout root = binding.getRoot(); listViewModel = new ViewModelProvider(fragmentActivity).get(DirectItemModelListViewModel.class); if (getArguments() == null) { @@ -200,6 +213,11 @@ public class DirectMessageThreadFragment extends Fragment { NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); }); + dmSeen.setOnClickListener(v -> { + new ThreadAction().execute("seen", lastMessage); + dmSeen.setVisibility(View.GONE); + }); + final DialogInterface.OnClickListener onDialogListener = (dialogInterface, which) -> { if (which == 0) { final DirectItemType itemType = directItemModel.getItemType(); @@ -266,7 +284,7 @@ public class DirectMessageThreadFragment extends Fragment { sendText(null, directItemModel.getItemId(), directItemModel.isLiked()); } else if (which == 2) { - if (String.valueOf(directItemModel.getUserId()).equals(myId)) new Unsend().execute(); + if (String.valueOf(directItemModel.getUserId()).equals(myId)) new ThreadAction().execute("delete", directItemModel.getItemId()); else searchUsername(getUser(directItemModel.getUserId()).getUsername()); } }; @@ -462,9 +480,13 @@ public class DirectMessageThreadFragment extends Fragment { } } - class Unsend extends AsyncTask { - protected Void doInBackground(Void... lmao) { - final String url = "https://i.instagram.com/api/v1/direct_v2/threads/"+threadId+"/items/"+directItemModel.getItemId()+"/delete/"; + class ThreadAction extends AsyncTask { + String action, argument; + + protected Void doInBackground(String... rawAction) { + action = rawAction[0]; + argument = rawAction[1]; + final String url = "https://i.instagram.com/api/v1/direct_v2/threads/"+threadId+"/items/"+argument+"/"+action+"/"; try { String urlParameters = "_csrftoken=" + cookie.split("csrftoken=")[1].split(";")[0] +"&_uuid=" + Utils.settingsHelper.getString(Constants.DEVICE_UUID); @@ -481,11 +503,12 @@ public class DirectMessageThreadFragment extends Fragment { wr.close(); urlConnection.connect(); if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { - hasDeletedSomething = true; + if (action == "delete") hasDeletedSomething = true; + else if (action == "seen") DirectMessageInboxFragment.refreshPlease = true; } urlConnection.disconnect(); } catch (Throwable ex) { - Log.e("austin_debug", "unsend: " + ex); + Log.e("austin_debug", action + ": " + ex); } return null; } diff --git a/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java b/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java index 2eec3549..18513511 100755 --- a/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java +++ b/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java @@ -12,16 +12,17 @@ public final class InboxThreadModel implements Serializable { private final String threadId, threadV2Id, threadType, threadTitle, newestCursor, oldestCursor, nextCursor, prevCursor; private final ProfileModel inviter; private final ProfileModel[] users, leftUsers; + private final Long[] admins; private final DirectItemModel[] items; - private final boolean muted, isPin, isSpam, isGroup, named, pending, archived, canonical, hasOlder, hasNewer; - private final long lastActivityAt; + private final boolean muted, isPin, isSpam, isGroup, named, pending, archived, canonical, hasOlder; + private final long unreadCount, lastActivityAt; public InboxThreadModel(final InboxReadState readState, final String threadId, final String threadV2Id, final String threadType, final String threadTitle, final String newestCursor, final String oldestCursor, final String nextCursor, final String prevCursor, - final ProfileModel inviter, final ProfileModel[] users, - final ProfileModel[] leftUsers, final DirectItemModel[] items, final boolean muted, + final ProfileModel inviter, final ProfileModel[] users, final ProfileModel[] leftUsers, + final Long[] admins, final DirectItemModel[] items, final boolean muted, final boolean isPin, final boolean named, final boolean canonical, final boolean pending, - final boolean hasOlder, final boolean hasNewer, final boolean isSpam, final boolean isGroup, + final boolean hasOlder, final long unreadCount, final boolean isSpam, final boolean isGroup, final boolean archived, final long lastActivityAt) { this.readState = readState; this.threadId = threadId; @@ -35,6 +36,7 @@ public final class InboxThreadModel implements Serializable { this.inviter = inviter; this.users = users; this.leftUsers = leftUsers; + this.admins = admins; this.items = items; // todo this.muted = muted; this.isPin = isPin; @@ -42,7 +44,7 @@ public final class InboxThreadModel implements Serializable { this.canonical = canonical; this.pending = pending; this.hasOlder = hasOlder; - this.hasNewer = hasNewer; + this.unreadCount = unreadCount; this.isSpam = isSpam; this.isGroup = isGroup; this.archived = archived; @@ -97,6 +99,8 @@ public final class InboxThreadModel implements Serializable { return leftUsers; } + public Long[] getAdmins() { return admins; } + public DirectItemModel[] getItems() { return items; } @@ -129,9 +133,7 @@ public final class InboxThreadModel implements Serializable { return hasOlder; } - public boolean isHasNewer() { - return hasNewer; - } + public long getUnreadCount() { return unreadCount; } public boolean isSpam() { return isSpam; diff --git a/app/src/main/java/awais/instagrabber/utils/Constants.java b/app/src/main/java/awais/instagrabber/utils/Constants.java index 692342d9..4a23b792 100755 --- a/app/src/main/java/awais/instagrabber/utils/Constants.java +++ b/app/src/main/java/awais/instagrabber/utils/Constants.java @@ -20,10 +20,12 @@ public final class Constants { public static final String SHOW_FEED = "show_feed"; public static final String CUSTOM_DATE_TIME_FORMAT_ENABLED = "data_time_custom_enabled"; public static final String MARK_AS_SEEN = "mark_as_seen"; + public static final String DM_MARK_AS_SEEN = "dm_mark_as_seen"; public static final String INSTADP = "instadp"; public static final String STORIESIG = "storiesig"; public static final String AMOLED_THEME = "amoled_theme"; public static final String CHECK_ACTIVITY = "check_activity"; + public static final String CHECK_UPDATES = "check_updates"; // never Export public static final String COOKIE = "cookie"; public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg"; @@ -50,9 +52,9 @@ public final class Constants { // spoof public static final String USER_AGENT = "Mozilla/5.0 (Linux; Android 8.1.0; motorola one Build/OPKS28.63-18-3; wv) " + "AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36 " + - "Instagram 154.0.0.32.123 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 238093938)"; + "Instagram 156.0.0.26.109 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 240726452)"; public static final String I_USER_AGENT = - "Instagram 154.0.0.32.123 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 238093938)"; + "Instagram 156.0.0.26.109 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 240726452)"; public static final String A_USER_AGENT = "https://InstaGrabber.AustinHuang.me / mailto:InstaGrabber@AustinHuang.me"; // see https://github.com/dilame/instagram-private-api/blob/master/src/core/constants.ts public static final String SUPPORTED_CAPABILITIES = "[ { \"name\": \"SUPPORTED_SDK_VERSIONS\", \"value\":" + diff --git a/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java b/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java index d6b22b5b..2fb969fe 100755 --- a/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java +++ b/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java @@ -15,12 +15,14 @@ import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS; import static awais.instagrabber.utils.Constants.AUTOPLAY_VIDEOS; import static awais.instagrabber.utils.Constants.BOTTOM_TOOLBAR; import static awais.instagrabber.utils.Constants.CHECK_ACTIVITY; +import static awais.instagrabber.utils.Constants.CHECK_UPDATES; import static awais.instagrabber.utils.Constants.COOKIE; import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT; import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED; import static awais.instagrabber.utils.Constants.DATE_TIME_FORMAT; import static awais.instagrabber.utils.Constants.DATE_TIME_SELECTION; import static awais.instagrabber.utils.Constants.DEVICE_UUID; +import static awais.instagrabber.utils.Constants.DM_MARK_AS_SEEN; import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER; import static awais.instagrabber.utils.Constants.FOLDER_PATH; import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; @@ -76,7 +78,8 @@ public final class SettingsHelper { return BOTTOM_TOOLBAR.equals(key) || AUTOPLAY_VIDEOS.equals(key) || SHOW_QUICK_ACCESS_DIALOG.equals(key) || - MUTED_VIDEOS.equals(key); + MUTED_VIDEOS.equals(key) || + CHECK_UPDATES.equals(key); } public int getThemeCode(final boolean fromHelper) { @@ -111,7 +114,8 @@ public final class SettingsHelper { public @interface StringSettings {} @StringDef({DOWNLOAD_USER_FOLDER, BOTTOM_TOOLBAR, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS, - AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, INSTADP, STORIESIG, AMOLED_THEME, CHECK_ACTIVITY}) + AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, DM_MARK_AS_SEEN, + INSTADP, STORIESIG, AMOLED_THEME, CHECK_ACTIVITY, CHECK_UPDATES}) public @interface BooleanSettings {} @StringDef({APP_THEME, APP_LANGUAGE, PREV_INSTALL_VERSION}) diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java index d1d8492d..07856309 100755 --- a/app/src/main/java/awais/instagrabber/utils/Utils.java +++ b/app/src/main/java/awais/instagrabber/utils/Utils.java @@ -474,7 +474,7 @@ public final class Utils { @NonNull public static InboxThreadModel createInboxThreadModel(@NonNull final JSONObject data, final boolean inThreadView) throws Exception { final InboxReadState readState = data.getInt("read_state") == 0 ? InboxReadState.STATE_READ : InboxReadState.STATE_UNREAD; - final String threadType = data.getString("thread_type");// private = dms, [??] = group + final String threadType = data.getString("thread_type"); // they're all "private", group is identified by boolean "is_group" final String threadId = data.getString("thread_id"); final String threadV2Id = data.getString("thread_v2_id"); @@ -486,7 +486,7 @@ public final class Utils { final String threadPrevCursor = data.has("prev_cursor") ? data.getString("prev_cursor") : null; final boolean threadHasOlder = data.getBoolean("has_older"); - final boolean threadHasNewer = data.getBoolean("has_newer"); + final long unreadCount = data.optLong("read_state", 0); final long lastActivityAt = data.optLong("last_activity_at"); final boolean named = data.optBoolean("named"); @@ -502,6 +502,8 @@ public final class Utils { final int usersLen = users.length(); final JSONArray leftusers = data.getJSONArray("left_users"); final int leftusersLen = leftusers.length(); + final JSONArray admins = data.getJSONArray("admin_user_ids"); + final int adminsLen = admins.length(); final ProfileModel[] userModels = new ProfileModel[usersLen]; for (int j = 0; j < usersLen; ++j) { @@ -531,6 +533,11 @@ public final class Utils { null, 0, 0, 0, false, false, false, false); } + final Long[] adminIDs = new Long[adminsLen]; + for (int j = 0; j < adminsLen; ++j) { + adminIDs[j] = admins.getLong(j); + } + final JSONArray items = data.getJSONArray("items"); final int itemsLen = items.length(); @@ -707,7 +714,6 @@ public final class Utils { break; case CLIP: - Log.d("austin_debug", "clip: "+itemObject.getJSONObject("clip").getJSONObject("clip")); directMedia = getDirectMediaModel(itemObject.getJSONObject("clip").getJSONObject("clip")); break; @@ -776,10 +782,10 @@ public final class Utils { return new InboxThreadModel(readState, threadId, threadV2Id, threadType, threadTitle, threadNewestCursor, threadOldestCursor, threadNextCursor, threadPrevCursor, null, // todo - userModels, leftuserModels, + userModels, leftuserModels, adminIDs, itemModels.toArray(new DirectItemModel[0]), muted, isPin, named, canonical, - pending, threadHasOlder, threadHasNewer, isSpam, isGroup, archived, lastActivityAt); + pending, threadHasOlder, unreadCount, isSpam, isGroup, archived, lastActivityAt); } private static RavenExpiringMediaType getExpiringMediaType(final String type) { diff --git a/app/src/main/res/drawable-anydpi/ic_star.xml b/app/src/main/res/drawable-anydpi/ic_star.xml new file mode 100644 index 00000000..a7415e89 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_star.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-hdpi/ic_star.png b/app/src/main/res/drawable-hdpi/ic_star.png new file mode 100644 index 0000000000000000000000000000000000000000..1f122fa86380c7e6e7d00071416ea6b415487b65 GIT binary patch literal 375 zcmV--0f_#IP){5OwbC>S|ZPkHOWoUE8()!BtmRyY}BU4BJe<3du2q`GLzfJxn1XCyR0O)qNZa&4{} z7n`Uhp|_e7Ci%xVHRoW1Gh{stkIj5V&US3mp)Nc&k^viR3C%H%${#y^_`lZa)*qej Vv1|FC^dA5K002ovPDHLkV1fY>q^1A> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_star.png b/app/src/main/res/drawable-mdpi/ic_star.png new file mode 100644 index 0000000000000000000000000000000000000000..22ba83c5b5fd5a39381581a86be761361f171513 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjCp}#pLn>}1CrAVyxN;>#tR*wk zk%{B-k%HvpWIbWw$ukvrk}eM@iH``JlXT|HnJW$w zFCHb8a62R!R4xhvhqocorZJ+~G0U;a zqc0^%r%_7JJJ0Ksl2XK`6_a*;__3fj=CG?r2eV+-(|ZLuo-^0P@M=w)Sgc#*;w0=~ zcrjDnUEr!yaEGW}eA5+%Lf(_9_9sG*O!>WJg)D0XBSW~xF0WbcEP);5PU1ep()qiWxw8@27pwM1>v6o!ZNIc$s^xd@_4pE{+ zaVBM1rl6c1xPh_+pXd3pD2g{ItT{%%RSv+KV+ID4fq`4}YXu%B z_;&A}s6B$WGXM%>nW(=PVZFnEI-tSa*1rS;^KkKwSn&4*TLI*B|B5Zm`o%%L;6hUfjxZ zN%qh&E-R7?V3Tq&JTQIB%K6Q+%dah9oApP*C{d#Pp?m=D2JrC(VZp@!0000e9vJ3 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_star.png b/app/src/main/res/drawable-xxhdpi/ic_star.png new file mode 100644 index 0000000000000000000000000000000000000000..71791fd50e9bc1a4864b2f4d648d43a820d35d37 GIT binary patch literal 943 zcmV;g15o^lP)mym7q^*vbmYSq7sOe7PWb(50!$NYC&nmq97O{g-A7C(l+|n z#_x+03?T`d-DGzrdk!2X3E7!5znwjEX6Ed~goucUh=_>D5F{Rt&nA<}OG2WDSeCUy z6%t(}m&+ZCMx(n_eikAf5{t$1&_7D^LZnR^jmADesk8yA@HZi&1dr9NHaJa%FS;RQ z{sY?R1O#0dGXLOAcY)K?Y&LsF07auudI5qig&K}++eZMQ)(23nP$(Pi8mox%Ey@zguPEzY0kIBM*C$nXQMEPCwrK-xL7a7gw$a8>`HBeI zN~7@{%10=ls@P?d(Jj9J971P(QDtjc*}lfUs6Mf8X~4Yd=5e@)%D$Td!GnHdU)}nQ z)2Lu;jNxphQmIp39qUo(`*DNAKCy2@bH=D_b&TMwj>LJ>v6&8seHisNMRLG}rY>5i z?SAg%)C__{TO+;(iSYjC@hoo};BU5RYfvlmDMrZ}11izRK$jc&eEu*Dd8gsX*`RIO ztjS=|GmU1dl~Sp+U&mvd2O5l=Io;2?VlZ+q05E%O+lXxt%oIJRvc_waZ;M+Z+(@%@F{ zdbEDe0|wr7(W!E`?NI*aFo)5c41L`F!XV27zO>RW=SSrd-5+q-vZ(V6_QBy@el^I6 zCjaX+r;!JOx{jVn2iY4Ho``rnO{qA@{+QI!|3v!S)m@Ye!!TUkhy_(=FGvv`N6=ia zy_!+Hl)^fD?Kx?=?Fzs0ro+%LcqF2JZ1J+K4nVK9+aPNT@aTsY{d@_9FU6=CwB8Ch zwc0>a$yS83$@jkkv}0Ojk#VM+(ds0_x5NNv_N0tC;SdoK5fKp)5fL#{{sQ<-o!g@a R4Qc=Y002ovPDHLkV1lbJys!WO literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/circle.xml b/app/src/main/res/drawable/circle.xml new file mode 100644 index 00000000..15e02794 --- /dev/null +++ b/app/src/main/res/drawable/circle.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_direct_messages.xml b/app/src/main/res/layout/activity_direct_messages.xml index 459fadaa..a41d2190 100644 --- a/app/src/main/res/layout/activity_direct_messages.xml +++ b/app/src/main/res/layout/activity_direct_messages.xml @@ -49,6 +49,22 @@ android:gravity="center_vertical" android:text="@string/app_name" /> + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + android:layout_height="match_parent"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_follow.xml b/app/src/main/res/layout/item_follow.xml index bb962674..646200df 100755 --- a/app/src/main/res/layout/item_follow.xml +++ b/app/src/main/res/layout/item_follow.xml @@ -20,6 +20,7 @@ android:layout_height="60dp" android:layout_marginStart="66dp" android:layout_marginLeft="66dp" + android:layout_marginEnd="26dp" android:orientation="vertical"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_include_simple_item.xml b/app/src/main/res/layout/layout_include_simple_item.xml index 27956961..df81d467 100755 --- a/app/src/main/res/layout/layout_include_simple_item.xml +++ b/app/src/main/res/layout/layout_include_simple_item.xml @@ -51,22 +51,35 @@ android:layout_height="wrap_content" android:orientation="vertical"> - + android:orientation="horizontal"> + + + + + android:layout_height="wrap_content"> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 05fbc373..dcbf1242 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -34,9 +34,11 @@ User Story Changelog Show toolbar at bottom + Check for new updates on GitHub at startup Download posts to username folder in Downloads Auto-load all posts from user Mark stories as seen after viewing\n(Story author will know you viewed it) + Automatically mark DM as seen after viewing\n(Other members will know you viewed it) Enable activity notifications Error loading profile!\nTry logging in and search again. Error creating Download folder(s). @@ -84,6 +86,7 @@ You have already answered! Mentions This Account is Private + You won\'t be able to access posts after unfollowing! Are you sure? You can log in via Settings on the bottom-right corner. Or, you can view public accounts without login! You can swipe left/right for explore/feed, or search something below! This Account has No Posts @@ -173,6 +176,8 @@ Great success! Leave Leave this chat? + Kick + Left users Download directly Downloads posts directly to the phone! Fetching post(s)