mirror of
				https://github.com/KokaKiwi/BarInsta
				synced 2025-10-31 11:35:34 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/austinhuang0131/instagrabber into pr/77
This commit is contained in:
		
						commit
						b62dc66032
					
				| @ -10,8 +10,8 @@ android { | ||||
|         minSdkVersion 16 | ||||
|         targetSdkVersion 29 | ||||
| 
 | ||||
|         versionCode 47 | ||||
|         versionName '18.1' | ||||
|         versionCode 48 | ||||
|         versionName '18.2' | ||||
| 
 | ||||
|         multiDexEnabled true | ||||
| 
 | ||||
|  | ||||
| @ -1414,6 +1414,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | ||||
|                                                                     ? mainActivity.locationModel.getName() | ||||
|                                                                     : mainActivity.userQuery.replaceAll("^@", ""))); | ||||
|                 onRefresh(); | ||||
| <<<<<<< HEAD | ||||
|             } else if (v == mainActivity.mainBinding.profileView.btnFollow) { | ||||
|                 if (mainActivity.profileModel.isPrivate() && mainActivity.profileModel.getFollowing()) { | ||||
|                     new AlertDialog.Builder(main) | ||||
| @ -1425,6 +1426,25 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | ||||
|                 } | ||||
|                 else new ProfileAction().execute("follow"); | ||||
|             } else if (v == mainActivity.mainBinding.profileView.btnRestrict && isLoggedIn) { | ||||
| ||||||| merged common ancestors | ||||
|             } else if (v == main.mainBinding.profileView.btnFollow) { | ||||
|                 new ProfileAction().execute("follow"); | ||||
|             } else if (v == main.mainBinding.profileView.btnRestrict && isLoggedIn) { | ||||
| ======= | ||||
|             } else if (v == main.mainBinding.profileView.btnFollow) { | ||||
|                 if (main.profileModel.isPrivate() && main.profileModel.getFollowing()) { | ||||
|                     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) { | ||||
| >>>>>>> 44db2db57f4461bbffa160e26cd734fb07f3b930 | ||||
|                 new ProfileAction().execute("restrict"); | ||||
|             } else if (v == mainActivity.mainBinding.profileView.btnSaved && !isSelf) { | ||||
|                 new ProfileAction().execute("block"); | ||||
| @ -1455,6 +1475,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | ||||
| 
 | ||||
|         protected Void doInBackground(String... rawAction) { | ||||
|             action = rawAction[0]; | ||||
| <<<<<<< HEAD | ||||
|             final String url = "https://www.instagram.com/web/" + (action.equals("followtag") && mainActivity.hashtagModel != null | ||||
|                                                                    ? "tags/" + (mainActivity.hashtagModel.getFollowing() | ||||
|                                                                                 ? "unfollow/" | ||||
| @ -1480,6 +1501,31 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | ||||
|                                                                                                                                              .getBlocked() | ||||
|                                                                                                                                      ? "unblock/" | ||||
|                                                                                                                                      : "block/")); | ||||
| ||||||| merged common ancestors | ||||
|             final String url = "https://www.instagram.com/web/"+ | ||||
|                     ((action == "followtag" && main.hashtagModel != null) ? ("tags/"+ | ||||
|                             (main.hashtagModel.getFollowing() == true ? "unfollow/" : "follow/")+main.hashtagModel.getName()+"/") : ( | ||||
|                     ((action == "restrict" && main.profileModel != null) ? "restrict_action" : ("friendships/"+main.profileModel.getId()))+"/"+ | ||||
|                     ((action == "follow" && main.profileModel != null) ? | ||||
|                     ((main.profileModel.getFollowing() == true || | ||||
|                             (main.profileModel.getFollowing() == false && main.profileModel.getRequested() == true)) | ||||
|                             ? "unfollow/" : "follow/") : | ||||
|                     ((action == "restrict" && main.profileModel != null) ? | ||||
|                             (main.profileModel.getRestricted() == true ? "unrestrict/" : "restrict/") : | ||||
|                             (main.profileModel.getBlocked() == true ? "unblock/" : "block/"))))); | ||||
| ======= | ||||
|             final String url = "https://www.instagram.com/web/"+ | ||||
|                     ((action == "followtag" && main.hashtagModel != null) ? ("tags/"+ | ||||
|                             (main.hashtagModel.getFollowing() ? "unfollow/" : "follow/")+main.hashtagModel.getName()+"/") : ( | ||||
|                     ((action == "restrict" && main.profileModel != null) ? "restrict_action" : ("friendships/"+main.profileModel.getId()))+"/"+ | ||||
|                     ((action == "follow" && main.profileModel != null) ? | ||||
|                     ((main.profileModel.getFollowing() || | ||||
|                             (main.profileModel.getFollowing() == false && main.profileModel.getRequested() == true)) | ||||
|                             ? "unfollow/" : "follow/") : | ||||
|                     ((action == "restrict" && main.profileModel != null) ? | ||||
|                             (main.profileModel.getRestricted() ? "unrestrict/" : "restrict/") : | ||||
|                             (main.profileModel.getBlocked() ? "unblock/" : "block/"))))); | ||||
| >>>>>>> 44db2db57f4461bbffa160e26cd734fb07f3b930 | ||||
|             try { | ||||
|                 final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); | ||||
|                 urlConnection.setRequestMethod("POST"); | ||||
| @ -1515,4 +1561,4 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -129,7 +129,7 @@ public final class MainActivityBackup extends BaseLanguageActivity { | ||||
|         mainBinding = ActivityMainbackupBinding.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); | ||||
|  | ||||
| @ -17,6 +17,7 @@ import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; | ||||
| 
 | ||||
| import java.io.DataOutputStream; | ||||
| import java.net.HttpURLConnection; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| @ -169,8 +170,16 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S | ||||
|                 urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT); | ||||
|                 urlConnection.setRequestProperty("x-csrftoken", | ||||
|                         Utils.settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]); | ||||
|                 final String urlParameters = "timestamp="+(System.currentTimeMillis()/1000); | ||||
|                 urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); | ||||
|                 urlConnection.setRequestProperty("Content-Length", "" + | ||||
|                         urlParameters.getBytes().length); | ||||
|                 urlConnection.setDoOutput(true); | ||||
|                 DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); | ||||
|                 wr.writeBytes(urlParameters); | ||||
|                 wr.flush(); | ||||
|                 wr.close(); | ||||
|                 urlConnection.connect(); | ||||
|                 urlConnection.disconnect(); | ||||
|             } catch (Throwable ex) { | ||||
|                 Log.e("austin_debug", "seen: " + ex); | ||||
|             } | ||||
|  | ||||
| @ -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)) | ||||
|  | ||||
| @ -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<RecyclerView.ViewHolder> { | ||||
|     private final ProfileModel[] profileModels; | ||||
|     private final List<Long> 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<Long> 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<Recy | ||||
|             followHolder.tvUsername.setText(model.getUsername()); | ||||
|             followHolder.tvFullName.setText(model.getName()); | ||||
| 
 | ||||
|             if (admins != null && admins.contains(Long.parseLong(model.getId()))) | ||||
|                 followHolder.isAdmin.setVisibility(View.VISIBLE); | ||||
| 
 | ||||
|             Glide.with(layoutInflater.getContext()).load(model.getSdProfilePic()).into(followHolder.profileImage); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -101,5 +101,6 @@ public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHol | ||||
|         } | ||||
|         binding.tvComment.setText(HtmlCompat.fromHtml(messageText.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT)); | ||||
|         binding.tvDate.setText(lastItemModel.getDateTime()); | ||||
|         binding.unread.setVisibility(model.getUnreadCount() > 0L ? View.VISIBLE : View.GONE); | ||||
|     } | ||||
| } | ||||
| @ -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); | ||||
|     } | ||||
| } | ||||
| @ -86,6 +86,7 @@ public final class ProfilePictureFetcher extends AsyncTask<Void, Void, String> { | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (Utils.isEmpty(out)) out = picUrl; | ||||
|         } catch (final Exception e) { | ||||
|             if (logCollector != null) | ||||
|                 logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground"); | ||||
|  | ||||
| @ -161,7 +161,7 @@ public class DirectThreadBroadcaster extends AsyncTask<DirectThreadBroadcaster.B | ||||
|             super(ItemType.TEXT); | ||||
|             this.text = URLEncoder.encode(text, "UTF-8") | ||||
|                     .replaceAll("\\+", "%20").replaceAll("%21", "!").replaceAll("%27", "'") | ||||
|                     .replaceAll("%28", "(").replaceAll("%29", ")").replaceAll("%7E", "~"); | ||||
|                     .replaceAll("%28", "(").replaceAll("%29", ")").replaceAll("%7E", "~").replaceAll("%0A", "\n"); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
| @ -197,7 +197,7 @@ public class DirectThreadBroadcaster extends AsyncTask<DirectThreadBroadcaster.B | ||||
|             super(ItemType.REELSHARE); | ||||
|             this.text = URLEncoder.encode(text, "UTF-8") | ||||
|                     .replaceAll("\\+", "%20").replaceAll("%21", "!").replaceAll("%27", "'") | ||||
|                     .replaceAll("%28", "(").replaceAll("%29", ")").replaceAll("%7E", "~"); | ||||
|                     .replaceAll("%28", "(").replaceAll("%29", ")").replaceAll("%7E", "~").replaceAll("%0A", "\n"); | ||||
|             this.mediaId = mediaId; | ||||
|             this.reelId = reelId; // or user id, usually same | ||||
|         } | ||||
|  | ||||
| @ -42,7 +42,9 @@ 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.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; | ||||
| @ -137,22 +139,26 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | ||||
|         final AppCompatCheckBox cbAutoplayVideos = contentView.findViewById(R.id.cbAutoplayVideos); | ||||
|         final AppCompatCheckBox cbDownloadUsername = contentView.findViewById(R.id.cbDownloadUsername); | ||||
|         final AppCompatCheckBox cbMarkAsSeen = contentView.findViewById(R.id.cbMarkAsSeen); | ||||
|         final AppCompatCheckBox cbMarkDmAsSeen = contentView.findViewById(R.id.cbMarkDmAsSeen); | ||||
|         final AppCompatCheckBox cbActivity = contentView.findViewById(R.id.cbActivity); | ||||
|         final AppCompatCheckBox cbInstadp = contentView.findViewById(R.id.cbInstadp); | ||||
|         final AppCompatCheckBox cbStoriesig = contentView.findViewById(R.id.cbStoriesig); | ||||
|         final AppCompatCheckBox cbAmoledTheme = contentView.findViewById(R.id.cbAmoledTheme); | ||||
|         final AppCompatCheckBox cbUpdates = contentView.findViewById(R.id.cbUpdates); | ||||
| 
 | ||||
|         cbSaveTo.setChecked(settingsHelper.getBoolean(FOLDER_SAVE_TO)); | ||||
|         cbMuteVideos.setChecked(settingsHelper.getBoolean(MUTED_VIDEOS)); | ||||
|         cbBottomToolbar.setChecked(settingsHelper.getBoolean(BOTTOM_TOOLBAR)); | ||||
|         cbAutoplayVideos.setChecked(settingsHelper.getBoolean(AUTOPLAY_VIDEOS)); | ||||
|         cbMarkAsSeen.setChecked(settingsHelper.getBoolean(MARK_AS_SEEN)); | ||||
|         cbMarkDmAsSeen.setChecked(settingsHelper.getBoolean(DM_MARK_AS_SEEN)); | ||||
|         cbInstadp.setChecked(settingsHelper.getBoolean(INSTADP)); | ||||
|         cbStoriesig.setChecked(settingsHelper.getBoolean(STORIESIG)); | ||||
|         cbAmoledTheme.setChecked(settingsHelper.getBoolean(AMOLED_THEME)); | ||||
|         cbActivity.setChecked(settingsHelper.getBoolean(CHECK_ACTIVITY)); | ||||
|         cbAutoloadPosts.setChecked(settingsHelper.getBoolean(AUTOLOAD_POSTS)); | ||||
|         cbDownloadUsername.setChecked(settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER)); | ||||
|         cbUpdates.setChecked(settingsHelper.getBoolean(CHECK_UPDATES)); | ||||
| 
 | ||||
|         setupListener(cbSaveTo); | ||||
|         setupListener(cbMuteVideos); | ||||
| @ -161,10 +167,12 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | ||||
|         setupListener(cbAutoplayVideos); | ||||
|         setupListener(cbDownloadUsername); | ||||
|         setupListener(cbMarkAsSeen); | ||||
|         setupListener(cbMarkDmAsSeen); | ||||
|         setupListener(cbInstadp); | ||||
|         setupListener(cbStoriesig); | ||||
|         setupListener(cbAmoledTheme); | ||||
|         setupListener(cbActivity); | ||||
|         setupListener(cbUpdates); | ||||
| 
 | ||||
|         btnSaveTo.setEnabled(cbSaveTo.isChecked()); | ||||
| 
 | ||||
| @ -254,10 +262,12 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | ||||
|         else if (id == R.id.cbMuteVideos) settingsHelper.putBoolean(MUTED_VIDEOS, checked); | ||||
|         else if (id == R.id.cbAutoloadPosts) settingsHelper.putBoolean(AUTOLOAD_POSTS, checked); | ||||
|         else if (id == R.id.cbMarkAsSeen) settingsHelper.putBoolean(MARK_AS_SEEN, checked); | ||||
|         else if (id == R.id.cbMarkDmAsSeen) settingsHelper.putBoolean(DM_MARK_AS_SEEN, checked); | ||||
|         else if (id == R.id.cbInstadp) settingsHelper.putBoolean(INSTADP, checked); | ||||
|         else if (id == R.id.cbStoriesig) settingsHelper.putBoolean(STORIESIG, checked); | ||||
|         else if (id == R.id.cbAmoledTheme) settingsHelper.putBoolean(AMOLED_THEME, checked); | ||||
|         else if (id == R.id.cbActivity) settingsHelper.putBoolean(CHECK_ACTIVITY, checked); | ||||
|         else if (id == R.id.cbUpdates) settingsHelper.putBoolean(CHECK_UPDATES, checked); | ||||
|         else if (id == R.id.cbSaveTo) { | ||||
|             settingsHelper.putBoolean(FOLDER_SAVE_TO, checked); | ||||
|             btnSaveTo.setEnabled(checked); | ||||
|  | ||||
| @ -9,6 +9,7 @@ import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.ArrayAdapter; | ||||
| import android.widget.EditText; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.Toast; | ||||
| @ -29,6 +30,8 @@ import java.io.DataOutputStream; | ||||
| import java.net.HttpURLConnection; | ||||
| import java.net.URL; | ||||
| import java.net.URLEncoder; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import awais.instagrabber.BuildConfig; | ||||
| import awais.instagrabber.R; | ||||
| @ -46,16 +49,18 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr | ||||
|     private static final String TAG = "DirectMessagesSettingsFrag"; | ||||
| 
 | ||||
|     private FragmentActivity fragmentActivity; | ||||
|     private RecyclerView userList; | ||||
|     private RecyclerView userList, leftUserList; | ||||
|     private EditText titleText; | ||||
|     private View leftTitle; | ||||
|     private AppCompatImageView titleSend; | ||||
|     private AppCompatButton btnLeave; | ||||
|     private LinearLayoutManager layoutManager; | ||||
|     private LinearLayoutManager layoutManager, layoutManagerDos; | ||||
|     private String threadId, threadTitle; | ||||
|     private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); | ||||
|     private boolean amAdmin; | ||||
|     private AsyncTask<Void, Void, InboxThreadModel> currentlyRunning; | ||||
|     private DirectMessageMembersAdapter memberAdapter; | ||||
|     private View.OnClickListener clickListener; | ||||
|     private DirectMessageMembersAdapter memberAdapter, leftAdapter; | ||||
|     private View.OnClickListener clickListener, basicClickListener; | ||||
| 
 | ||||
|     private final FetchListener<InboxThreadModel> fetchListener = new FetchListener<InboxThreadModel>() { | ||||
|         @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<Long> 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, Void, Void> { | ||||
|         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(); | ||||
|         } | ||||
|  | ||||
| @ -76,17 +76,17 @@ public class DirectMessageThreadFragment extends Fragment { | ||||
|     private static final int PICK_IMAGE = 100; | ||||
| 
 | ||||
|     private AppCompatActivity 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 AppCompatImageView dmInfo, dmSeen; | ||||
|     private boolean hasSentSomething, hasDeletedSomething; | ||||
|     private boolean hasOlder = true; | ||||
|     public static boolean hasSentSomething; | ||||
| 
 | ||||
|     private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel(); | ||||
|     private final List<ProfileModel> users = new ArrayList<>(); | ||||
| @ -150,6 +150,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 { | ||||
|         setHasOptionsMenu(true); | ||||
|     } | ||||
| 
 | ||||
|     @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); | ||||
|         final FragmentContainerView containerTwo = (FragmentContainerView) 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) { | ||||
| @ -204,6 +217,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(); | ||||
| @ -271,7 +289,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(); | ||||
|                     new ThreadAction().execute("delete", directItemModel.getItemId()); | ||||
|                 else searchUsername(getUser(directItemModel.getUserId()).getUsername()); | ||||
|             } | ||||
|         }; | ||||
| @ -474,9 +492,13 @@ public class DirectMessageThreadFragment extends Fragment { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     class Unsend extends AsyncTask<Void, Void, Void> { | ||||
|         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, Void, Void> { | ||||
|         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); | ||||
| @ -493,11 +515,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; | ||||
|         } | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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\":" + | ||||
|  | ||||
| @ -16,12 +16,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; | ||||
| @ -77,7 +79,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) { | ||||
| @ -120,7 +123,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({PREV_INSTALL_VERSION}) | ||||
|  | ||||
| @ -475,7 +475,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"); | ||||
| @ -487,7 +487,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"); | ||||
| @ -503,6 +503,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) { | ||||
| @ -532,6 +534,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(); | ||||
| 
 | ||||
| @ -710,7 +717,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; | ||||
| 
 | ||||
| @ -779,10 +785,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) { | ||||
|  | ||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable-anydpi/ic_star.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable-anydpi/ic_star.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:viewportHeight="24"> | ||||
|   <path | ||||
|       android:fillColor="@android:color/white" | ||||
|       android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/> | ||||
| </vector> | ||||
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable-hdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable-hdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 375 B | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable-mdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable-mdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 258 B | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable-xhdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable-xhdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 464 B | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable-xxhdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable-xxhdpi/ic_star.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 943 B | 
							
								
								
									
										12
									
								
								app/src/main/res/drawable/circle.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/src/main/res/drawable/circle.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <shape | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:shape="oval"> | ||||
| 
 | ||||
|     <solid | ||||
|         android:color="#ff0000"/> | ||||
| 
 | ||||
|     <size | ||||
|         android:width="120dp" | ||||
|         android:height="120dp"/> | ||||
| </shape> | ||||
| @ -44,11 +44,27 @@ | ||||
|                 <TextView | ||||
|                     android:id="@+id/toolbar_title" | ||||
|                     style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_width="200dp" | ||||
|                     android:layout_height="match_parent" | ||||
|                     android:gravity="center_vertical" | ||||
|                     android:text="@string/app_name" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatImageView | ||||
|                     android:id="@+id/dmSeen" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="match_parent" | ||||
|                     android:layout_gravity="center" | ||||
|                     android:background="?selectableItemBackgroundBorderless" | ||||
|                     android:clickable="true" | ||||
|                     android:focusable="true" | ||||
|                     android:paddingStart="4dp" | ||||
|                     android:paddingLeft="4dp" | ||||
|                     android:paddingTop="4dp" | ||||
|                     android:paddingEnd="8dp" | ||||
|                     android:paddingRight="8dp" | ||||
|                     android:paddingBottom="4dp" | ||||
|                     app:srcCompat="@android:drawable/ic_menu_view" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatImageView | ||||
|                     android:id="@+id/dmInfo" | ||||
|                     android:layout_width="wrap_content" | ||||
|  | ||||
| @ -46,6 +46,42 @@ | ||||
|             android:layout_height="match_parent" | ||||
|             android:orientation="vertical"> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_marginStart="8dp" | ||||
|                 android:layout_marginLeft="8dp" | ||||
|                 android:background="?android:selectableItemBackground" | ||||
|                 android:orientation="horizontal" | ||||
|                 android:weightSum="2"> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatButton | ||||
|                     android:id="@+id/btnLogin" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginLeft="8dp" | ||||
|                     android:layout_marginEnd="8dp" | ||||
|                     android:layout_marginRight="8dp" | ||||
|                     android:layout_weight="1" | ||||
|                     android:text="@string/login" | ||||
|                     android:textColor="@color/btn_green_text_color" | ||||
|                     android:textSize="20sp" | ||||
|                     app:backgroundTint="@color/btn_green_background" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatButton | ||||
|                     android:id="@+id/btnLogout" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginLeft="8dp" | ||||
|                     android:layout_marginEnd="8dp" | ||||
|                     android:layout_marginRight="8dp" | ||||
|                     android:layout_weight="1" | ||||
|                     android:text="@string/logout" | ||||
|                     android:textColor="@color/btn_red_text_color" | ||||
|                     android:textSize="20sp" | ||||
|                     app:backgroundTint="@color/btn_red_background" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
| @ -209,6 +245,31 @@ | ||||
|                     android:textSize="16sp" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_marginStart="5dp" | ||||
|                 android:layout_marginLeft="5dp" | ||||
|                 android:background="?android:selectableItemBackground" | ||||
|                 android:orientation="horizontal" | ||||
|                 android:padding="5dp"> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatCheckBox | ||||
|                     android:id="@+id/cbUpdates" | ||||
|                     android:layout_width="30dp" | ||||
|                     android:layout_height="30dp" | ||||
|                     android:contentDescription="@string/bottom_toolbar" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatTextView | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:gravity="center_vertical" | ||||
|                     android:padding="5dp" | ||||
|                     android:text="@string/update_check" | ||||
|                     android:textColor="?android:textColorPrimary" | ||||
|                     android:textSize="16sp" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
| @ -320,6 +381,31 @@ | ||||
|                     android:textSize="16sp" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_marginStart="5dp" | ||||
|                 android:layout_marginLeft="5dp" | ||||
|                 android:background="?android:selectableItemBackground" | ||||
|                 android:orientation="horizontal" | ||||
|                 android:padding="5dp"> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatCheckBox | ||||
|                     android:id="@+id/cbMarkDmAsSeen" | ||||
|                     android:layout_width="30dp" | ||||
|                     android:layout_height="30dp" | ||||
|                     android:contentDescription="@string/dm_mark_as_seen_setting" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatTextView | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:gravity="center_vertical" | ||||
|                     android:padding="5dp" | ||||
|                     android:text="@string/dm_mark_as_seen_setting" | ||||
|                     android:textColor="?android:textColorPrimary" | ||||
|                     android:textSize="16sp" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
| @ -419,42 +505,6 @@ | ||||
|                     android:textSize="16sp" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.LinearLayoutCompat | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_marginStart="8dp" | ||||
|                 android:layout_marginLeft="8dp" | ||||
|                 android:background="?android:selectableItemBackground" | ||||
|                 android:orientation="horizontal" | ||||
|                 android:weightSum="2"> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatButton | ||||
|                     android:id="@+id/btnLogin" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginLeft="8dp" | ||||
|                     android:layout_marginEnd="8dp" | ||||
|                     android:layout_marginRight="8dp" | ||||
|                     android:layout_weight="1" | ||||
|                     android:text="@string/login" | ||||
|                     android:textColor="@color/btn_green_text_color" | ||||
|                     android:textSize="20sp" | ||||
|                     app:backgroundTint="@color/btn_green_background" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatButton | ||||
|                     android:id="@+id/btnLogout" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginLeft="8dp" | ||||
|                     android:layout_marginEnd="8dp" | ||||
|                     android:layout_marginRight="8dp" | ||||
|                     android:layout_weight="1" | ||||
|                     android:text="@string/logout" | ||||
|                     android:textColor="@color/btn_red_text_color" | ||||
|                     android:textSize="20sp" | ||||
|                     app:backgroundTint="@color/btn_red_background" /> | ||||
|             </androidx.appcompat.widget.LinearLayoutCompat> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.AppCompatButton | ||||
|                 android:id="@+id/btnTimeSettings" | ||||
|                 android:layout_width="match_parent" | ||||
|  | ||||
| @ -60,9 +60,35 @@ | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="0dp" | ||||
|         android:layout_weight="1"> | ||||
|         <androidx.recyclerview.widget.RecyclerView | ||||
|             android:id="@+id/userList" | ||||
| 
 | ||||
|         <androidx.core.widget.NestedScrollView | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" /> | ||||
|             android:layout_height="match_parent"> | ||||
|             <LinearLayout | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="match_parent" | ||||
|                 android:orientation="vertical"> | ||||
|                 <androidx.recyclerview.widget.RecyclerView | ||||
|                     android:id="@+id/userList" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="match_parent" | ||||
|                     android:nestedScrollingEnabled="false"/> | ||||
|                 <androidx.appcompat.widget.AppCompatTextView | ||||
|                     android:id="@+id/leftTitle" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:visibility="gone" | ||||
|                     android:gravity="center_vertical" | ||||
|                     android:padding="5dp" | ||||
|                     android:text="@string/dms_left_users" | ||||
|                     android:textColor="?android:textColorPrimary" | ||||
|                     android:textSize="24sp"/> | ||||
|                 <androidx.recyclerview.widget.RecyclerView | ||||
|                     android:id="@+id/leftUserList" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="match_parent" | ||||
|                     android:nestedScrollingEnabled="false"/> | ||||
|             </LinearLayout> | ||||
|         </androidx.core.widget.NestedScrollView> | ||||
|     </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> | ||||
| </LinearLayout> | ||||
| @ -20,6 +20,7 @@ | ||||
|         android:layout_height="60dp" | ||||
|         android:layout_marginStart="66dp" | ||||
|         android:layout_marginLeft="66dp" | ||||
|         android:layout_marginEnd="26dp" | ||||
|         android:orientation="vertical"> | ||||
| 
 | ||||
|         <androidx.appcompat.widget.AppCompatTextView | ||||
| @ -41,4 +42,13 @@ | ||||
|             android:gravity="center_vertical" | ||||
|             android:textAppearance="@style/TextAppearance.AppCompat.Medium" /> | ||||
|     </LinearLayout> | ||||
| 
 | ||||
|     <androidx.appcompat.widget.AppCompatImageView | ||||
|         android:id="@+id/isAdmin" | ||||
|         android:layout_width="20dp" | ||||
|         android:layout_height="60dp" | ||||
|         android:layout_gravity="right" | ||||
|         android:scaleType="fitCenter" | ||||
|         app:srcCompat="@drawable/ic_star" | ||||
|         android:visibility="gone"/> | ||||
| </FrameLayout> | ||||
							
								
								
									
										9
									
								
								fastlane/metadata/android/en-US/changelogs/48.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								fastlane/metadata/android/en-US/changelogs/48.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| * Proper login support for those under Android 8 | ||||
| * You are alerted before unfollowing a private account | ||||
| * Update checker can now be toggled | ||||
| * "Swipe up" story sticker type is now supported | ||||
| * Unread DM are now indicated | ||||
| * You can now mark DMs as seen, either automatically (settings) or manually | ||||
| * You can now kick DM members | ||||
| * "Clip" message type (basically sharing reels) is now supported | ||||
| * Bug fixes, see GitHub | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user