Browse Source
Merge branch 'master' into task/separate-feed-item-views
renovate/org.robolectric-robolectric-4.x
Merge branch 'master' into task/separate-feed-item-views
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
47 changed files with 512 additions and 102 deletions
-
4app/build.gradle
-
4app/src/main/java/awais/instagrabber/activities/CommentsViewer.java
-
14app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java
-
3app/src/main/java/awais/instagrabber/activities/FollowViewer.java
-
1app/src/main/java/awais/instagrabber/activities/Login.java
-
26app/src/main/java/awais/instagrabber/activities/MainActivity.java
-
5app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java
-
21app/src/main/java/awais/instagrabber/activities/StoryViewer.java
-
55app/src/main/java/awais/instagrabber/adapters/DirectMessageMembersAdapter.java
-
8app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
-
7app/src/main/java/awais/instagrabber/adapters/PostsAdapter.java
-
1app/src/main/java/awais/instagrabber/adapters/SuggestionsAdapter.java
-
1app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java
-
1app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageActionLogViewHolder.java
-
1app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessagePlaceholderViewHolder.java
-
2app/src/main/java/awais/instagrabber/asyncs/FeedFetcher.java
-
2app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java
-
2app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
-
1app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java
-
2app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java
-
6app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java
-
2app/src/main/java/awais/instagrabber/asyncs/i/iTopicFetcher.java
-
5app/src/main/java/awais/instagrabber/dialogs/SettingsDialog.java
-
2app/src/main/java/awais/instagrabber/directdownload/MultiDirectDialog.java
-
10app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.java
-
209app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java
-
47app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
-
2app/src/main/java/awais/instagrabber/models/NotificationModel.java
-
1app/src/main/java/awais/instagrabber/models/ViewerPostModel.java
-
1app/src/main/java/awais/instagrabber/utils/Constants.java
-
9app/src/main/java/awais/instagrabber/utils/FlavorTown.java
-
3app/src/main/java/awais/instagrabber/utils/SettingsHelper.java
-
10app/src/main/res/drawable-anydpi/ic_submit.xml
-
BINapp/src/main/res/drawable-hdpi/ic_submit.png
-
BINapp/src/main/res/drawable-mdpi/ic_submit.png
-
BINapp/src/main/res/drawable-xhdpi/ic_submit.png
-
BINapp/src/main/res/drawable-xxhdpi/ic_submit.png
-
18app/src/main/res/layout/activity_direct_messages.xml
-
1app/src/main/res/layout/activity_saved.xml
-
25app/src/main/res/layout/dialog_main_settings.xml
-
68app/src/main/res/layout/fragment_direct_messages_settings.xml
-
10app/src/main/res/layout/item_follow.xml
-
1app/src/main/res/layout/item_notification.xml
-
2app/src/main/res/layout/layout_include_notif_item.xml
-
14app/src/main/res/navigation/direct_messages_nav_graph.xml
-
4app/src/main/res/values/strings.xml
-
3fastlane/metadata/android/en-US/changelogs/47.txt
@ -0,0 +1,55 @@ |
|||
package awais.instagrabber.adapters; |
|||
|
|||
import android.content.Context; |
|||
import android.view.LayoutInflater; |
|||
import android.view.View; |
|||
import android.view.ViewGroup; |
|||
|
|||
import androidx.annotation.NonNull; |
|||
import androidx.recyclerview.widget.RecyclerView; |
|||
|
|||
import com.bumptech.glide.Glide; |
|||
|
|||
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 View.OnClickListener onClickListener; |
|||
private final LayoutInflater layoutInflater; |
|||
|
|||
public DirectMessageMembersAdapter(final ProfileModel[] profileModels, final Context context, final View.OnClickListener onClickListener) { |
|||
this.profileModels = profileModels; |
|||
this.layoutInflater = LayoutInflater.from(context); |
|||
this.onClickListener = onClickListener; |
|||
} |
|||
|
|||
@NonNull |
|||
@Override |
|||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) { |
|||
final View view = layoutInflater.inflate(R.layout.item_follow, parent, false); |
|||
return new FollowsViewHolder(view); |
|||
} |
|||
|
|||
@Override |
|||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { |
|||
final ProfileModel model = profileModels[position]; |
|||
|
|||
final FollowsViewHolder followHolder = (FollowsViewHolder) holder; |
|||
if (model != null) { |
|||
followHolder.itemView.setTag(model); |
|||
followHolder.itemView.setOnClickListener(onClickListener); |
|||
|
|||
followHolder.tvUsername.setText(model.getUsername()); |
|||
followHolder.tvFullName.setText(model.getName()); |
|||
|
|||
Glide.with(layoutInflater.getContext()).load(model.getSdProfilePic()).into(followHolder.profileImage); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public int getItemCount() { |
|||
return profileModels.length; |
|||
} |
|||
} |
@ -0,0 +1,209 @@ |
|||
package awais.instagrabber.fragments.directmessages; |
|||
|
|||
import android.content.Intent; |
|||
import android.os.AsyncTask; |
|||
import android.os.Bundle; |
|||
import android.text.Editable; |
|||
import android.text.TextWatcher; |
|||
import android.util.Log; |
|||
import android.view.LayoutInflater; |
|||
import android.view.View; |
|||
import android.view.ViewGroup; |
|||
import android.widget.EditText; |
|||
import android.widget.LinearLayout; |
|||
import android.widget.Toast; |
|||
|
|||
import androidx.annotation.NonNull; |
|||
import androidx.annotation.Nullable; |
|||
import androidx.appcompat.app.AlertDialog; |
|||
import androidx.appcompat.widget.AppCompatButton; |
|||
import androidx.appcompat.widget.AppCompatImageView; |
|||
import androidx.fragment.app.Fragment; |
|||
import androidx.fragment.app.FragmentActivity; |
|||
import androidx.navigation.fragment.NavHostFragment; |
|||
import androidx.recyclerview.widget.LinearLayoutManager; |
|||
import androidx.recyclerview.widget.RecyclerView; |
|||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; |
|||
|
|||
import java.io.DataOutputStream; |
|||
import java.net.HttpURLConnection; |
|||
import java.net.URL; |
|||
import java.net.URLEncoder; |
|||
|
|||
import awais.instagrabber.BuildConfig; |
|||
import awais.instagrabber.R; |
|||
import awais.instagrabber.activities.ProfileViewer; |
|||
import awais.instagrabber.adapters.DirectMessageMembersAdapter; |
|||
import awais.instagrabber.asyncs.direct_messages.DirectMessageInboxThreadFetcher; |
|||
import awais.instagrabber.databinding.FragmentDirectMessagesSettingsBinding; |
|||
import awais.instagrabber.interfaces.FetchListener; |
|||
import awais.instagrabber.models.ProfileModel; |
|||
import awais.instagrabber.models.direct_messages.InboxThreadModel; |
|||
import awais.instagrabber.utils.Constants; |
|||
import awais.instagrabber.utils.Utils; |
|||
|
|||
public class DirectMessageSettingsFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { |
|||
private static final String TAG = "DirectMessagesSettingsFrag"; |
|||
|
|||
private FragmentActivity fragmentActivity; |
|||
private RecyclerView userList; |
|||
private EditText titleText; |
|||
private AppCompatImageView titleSend; |
|||
private AppCompatButton btnLeave; |
|||
private LinearLayoutManager layoutManager; |
|||
private String threadId, threadTitle; |
|||
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); |
|||
private AsyncTask<Void, Void, InboxThreadModel> currentlyRunning; |
|||
private DirectMessageMembersAdapter memberAdapter; |
|||
private View.OnClickListener clickListener; |
|||
|
|||
private final FetchListener<InboxThreadModel> fetchListener = new FetchListener<InboxThreadModel>() { |
|||
@Override |
|||
public void doBefore() {} |
|||
|
|||
@Override |
|||
public void onResult(final InboxThreadModel threadModel) { |
|||
memberAdapter = new DirectMessageMembersAdapter(threadModel.getUsers(), requireContext(), clickListener); |
|||
userList.setAdapter(memberAdapter); |
|||
} |
|||
}; |
|||
|
|||
@Override |
|||
public void onCreate(@Nullable final Bundle savedInstanceState) { |
|||
super.onCreate(savedInstanceState); |
|||
fragmentActivity = requireActivity(); |
|||
|
|||
clickListener = v -> { |
|||
final Object tag = v.getTag(); |
|||
if (tag instanceof ProfileModel) { |
|||
// TODO: kick dialog |
|||
ProfileModel model = (ProfileModel) tag; |
|||
startActivity( |
|||
new Intent(requireContext(), ProfileViewer.class) |
|||
.putExtra(Constants.EXTRAS_USERNAME, model.getUsername()) |
|||
); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
@Override |
|||
public View onCreateView(@NonNull final LayoutInflater inflater, |
|||
final ViewGroup container, |
|||
final Bundle savedInstanceState) { |
|||
final FragmentDirectMessagesSettingsBinding binding = FragmentDirectMessagesSettingsBinding.inflate(inflater, container, false); |
|||
final LinearLayout root = binding.getRoot(); |
|||
layoutManager = new LinearLayoutManager(requireContext()); |
|||
|
|||
threadId = DirectMessageSettingsFragmentArgs.fromBundle(getArguments()).getThreadId(); |
|||
threadTitle = DirectMessageSettingsFragmentArgs.fromBundle(getArguments()).getTitle(); |
|||
binding.swipeRefreshLayout.setEnabled(false); |
|||
|
|||
userList = binding.userList; |
|||
userList.setHasFixedSize(true); |
|||
userList.setLayoutManager(layoutManager); |
|||
|
|||
titleText = binding.titleText; |
|||
titleText.setText(threadTitle); |
|||
|
|||
titleSend = binding.titleSend; |
|||
titleSend.setOnClickListener(v -> { |
|||
new ChangeSettings().execute("update_title"); |
|||
}); |
|||
|
|||
titleText.addTextChangedListener(new TextWatcher() { |
|||
@Override |
|||
public void afterTextChanged(Editable s) {} |
|||
|
|||
@Override |
|||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} |
|||
|
|||
@Override |
|||
public void onTextChanged(CharSequence s, int start, int before, int count) { |
|||
titleSend.setVisibility(s.toString().equals(threadTitle) ? View.GONE : View.VISIBLE); |
|||
} |
|||
}); |
|||
|
|||
btnLeave = binding.btnLeave; |
|||
btnLeave.setOnClickListener(v -> { |
|||
new AlertDialog.Builder(requireContext()).setTitle(R.string.dms_action_leave_question) |
|||
.setPositiveButton(R.string.yes, (x,y) -> { |
|||
new ChangeSettings().execute("leave"); |
|||
}) |
|||
.setNegativeButton(R.string.no, null) |
|||
.show(); |
|||
}); |
|||
|
|||
currentlyRunning = new DirectMessageInboxThreadFetcher(threadId, null, null, fetchListener).execute(); |
|||
return root; |
|||
} |
|||
|
|||
@Override |
|||
public void onRefresh() { |
|||
stopCurrentExecutor(); |
|||
currentlyRunning = new DirectMessageInboxThreadFetcher(threadId, null, null, fetchListener).execute(); |
|||
} |
|||
|
|||
private void stopCurrentExecutor() { |
|||
if (currentlyRunning != null) { |
|||
try { |
|||
currentlyRunning.cancel(true); |
|||
} catch (final Exception e) { |
|||
if (BuildConfig.DEBUG) Log.e(TAG, "", e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
class ChangeSettings extends AsyncTask<String, Void, Void> { |
|||
String action; |
|||
boolean ok = false; |
|||
|
|||
protected Void doInBackground(String... rawAction) { |
|||
action = rawAction[0]; |
|||
final String url = "https://i.instagram.com/api/v1/direct_v2/threads/"+threadId+"/"+action+"/"; |
|||
try { |
|||
String urlParameters = "_csrftoken=" + cookie.split("csrftoken=")[1].split(";")[0] |
|||
+"&_uuid=" + Utils.settingsHelper.getString(Constants.DEVICE_UUID); |
|||
if (action.equals("update_title")) |
|||
urlParameters += "&title=" + URLEncoder.encode(titleText.getText().toString(), "UTF-8") |
|||
.replaceAll("\\+", "%20").replaceAll("%21", "!").replaceAll("%27", "'") |
|||
.replaceAll("%28", "(").replaceAll("%29", ")").replaceAll("%7E", "~"); |
|||
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); |
|||
urlConnection.setRequestMethod("POST"); |
|||
urlConnection.setUseCaches(false); |
|||
urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT); |
|||
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
|||
urlConnection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length)); |
|||
urlConnection.setDoOutput(true); |
|||
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); |
|||
wr.writeBytes(urlParameters); |
|||
wr.flush(); |
|||
wr.close(); |
|||
urlConnection.connect(); |
|||
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { |
|||
ok = true; |
|||
} |
|||
urlConnection.disconnect(); |
|||
} catch (Throwable ex) { |
|||
Log.e("austin_debug", "unsend: " + ex); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
protected void onPostExecute(Void result) { |
|||
if (ok) { |
|||
Toast.makeText(requireContext(), R.string.dms_action_success, Toast.LENGTH_SHORT).show(); |
|||
if (action.equals("update_title")) { |
|||
threadTitle = titleText.getText().toString(); |
|||
titleSend.setVisibility(View.GONE); |
|||
titleText.clearFocus(); |
|||
} |
|||
else if (action.equals("leave")) { |
|||
DirectMessageInboxFragment.afterLeave = true; |
|||
NavHostFragment.findNavController(DirectMessageSettingsFragment.this).popBackStack(R.id.directMessagesInboxFragment, false); |
|||
} |
|||
} |
|||
else Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:width="24dp" |
|||
android:height="24dp" |
|||
android:viewportWidth="24" |
|||
android:viewportHeight="24" |
|||
android:tint="?attr/colorControlNormal"> |
|||
<path |
|||
android:fillColor="@android:color/white" |
|||
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/> |
|||
</vector> |
After Width: 36 | Height: 36 | Size: 186 B |
After Width: 24 | Height: 24 | Size: 139 B |
After Width: 48 | Height: 48 | Size: 323 B |
After Width: 72 | Height: 72 | Size: 337 B |
@ -0,0 +1,68 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:app="http://schemas.android.com/apk/res-auto" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="match_parent" |
|||
android:orientation="vertical"> |
|||
|
|||
<LinearLayout |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content"> |
|||
|
|||
<EditText |
|||
android:id="@+id/titleText" |
|||
android:layout_width="0dp" |
|||
android:layout_height="wrap_content" |
|||
android:layout_weight="1" |
|||
android:gravity="bottom" |
|||
android:importantForAutofill="no" |
|||
android:inputType="textMultiLine" |
|||
android:maxLength="2200" |
|||
android:maxLines="10" |
|||
android:paddingStart="8dp" |
|||
android:paddingLeft="8dp" |
|||
android:paddingEnd="4dp" |
|||
android:paddingRight="4dp" |
|||
android:scrollHorizontally="false" /> |
|||
|
|||
<androidx.appcompat.widget.AppCompatImageView |
|||
android:id="@+id/titleSend" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
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" |
|||
android:visibility="gone" |
|||
app:srcCompat="@drawable/ic_submit" /> |
|||
</LinearLayout> |
|||
|
|||
<androidx.appcompat.widget.AppCompatButton |
|||
android:id="@+id/btnLeave" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginLeft="8dp" |
|||
android:layout_marginStart="6dp" |
|||
android:layout_marginRight="8dp" |
|||
android:text="@string/dms_action_leave" |
|||
android:textColor="@color/btn_red_text_color" |
|||
android:textSize="18sp" |
|||
app:backgroundTint="@color/btn_red_background" /> |
|||
|
|||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
|||
android:id="@+id/swipeRefreshLayout" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="0dp" |
|||
android:layout_weight="1"> |
|||
<androidx.recyclerview.widget.RecyclerView |
|||
android:id="@+id/userList" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="match_parent" /> |
|||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
|||
</LinearLayout> |
@ -0,0 +1,3 @@ |
|||
* You can now change the topic or leave a room, as well as see members |
|||
* More optimizations on activity check (You can now disable it) and DM |
|||
* Fix the inconsistent autoplay setting bug |
Write
Preview
Loading…
Cancel
Save
Reference in new issue