mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 14:47:29 +00:00
Add activity/notification view fragment
This commit is contained in:
parent
73a9e627d9
commit
37912854d0
@ -120,13 +120,6 @@
|
|||||||
<data android:scheme="https" />
|
<data android:scheme="https" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".activities.NotificationsViewer"
|
|
||||||
android:parentActivityName=".activities.MainActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".activities.MainActivity" />
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.Login"
|
android:name=".activities.Login"
|
||||||
android:label="@string/login"
|
android:label="@string/login"
|
||||||
|
@ -78,7 +78,8 @@ public class MainActivity extends BaseLanguageActivity {
|
|||||||
R.id.savedViewerFragment,
|
R.id.savedViewerFragment,
|
||||||
R.id.commentsViewerFragment,
|
R.id.commentsViewerFragment,
|
||||||
R.id.followViewerFragment,
|
R.id.followViewerFragment,
|
||||||
R.id.directMessagesSettingsFragment);
|
R.id.directMessagesSettingsFragment,
|
||||||
|
R.id.notificationsViewer);
|
||||||
private static final Map<Integer, Integer> NAV_TO_MENU_ID_MAP = new HashMap<>();
|
private static final Map<Integer, Integer> NAV_TO_MENU_ID_MAP = new HashMap<>();
|
||||||
private static final List<Integer> REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = Collections.singletonList(R.id.commentsViewerFragment);
|
private static final List<Integer> REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = Collections.singletonList(R.id.commentsViewerFragment);
|
||||||
private static final String FIRST_FRAGMENT_GRAPH_INDEX_KEY = "firstFragmentGraphIndex";
|
private static final String FIRST_FRAGMENT_GRAPH_INDEX_KEY = "firstFragmentGraphIndex";
|
||||||
|
@ -1,189 +0,0 @@
|
|||||||
package awais.instagrabber.activities;
|
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.style.RelativeSizeSpan;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
|
||||||
import awais.instagrabber.adapters.NotificationsAdapter;
|
|
||||||
import awais.instagrabber.asyncs.NotificationsFetcher;
|
|
||||||
import awais.instagrabber.databinding.ActivityNotificationBinding;
|
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
|
||||||
import awais.instagrabber.interfaces.MentionClickListener;
|
|
||||||
import awais.instagrabber.models.NotificationModel;
|
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
|
||||||
import awais.instagrabber.utils.Constants;
|
|
||||||
import awais.instagrabber.utils.TextUtils;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.notificationManager;
|
|
||||||
|
|
||||||
public final class NotificationsViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
|
|
||||||
private NotificationModel notificationModel;
|
|
||||||
private ActivityNotificationBinding notificationsBinding;
|
|
||||||
private ArrayAdapter<String> commmentDialogAdapter;
|
|
||||||
private String shortCode, postId, userId;
|
|
||||||
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
|
||||||
private Resources resources;
|
|
||||||
String[] commentDialogList;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
|
||||||
notificationManager.cancel(1800000000);
|
|
||||||
if (TextUtils.isEmpty(cookie)) {
|
|
||||||
Toast.makeText(this, R.string.activity_notloggedin, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
notificationsBinding = ActivityNotificationBinding.inflate(getLayoutInflater());
|
|
||||||
setContentView(notificationsBinding.getRoot());
|
|
||||||
notificationsBinding.swipeRefreshLayout.setOnRefreshListener(this);
|
|
||||||
resources = getResources();
|
|
||||||
setSupportActionBar(notificationsBinding.toolbar.toolbar);
|
|
||||||
notificationsBinding.toolbar.toolbar.setTitle(R.string.action_notif);
|
|
||||||
onRefresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRefresh() {
|
|
||||||
notificationsBinding.swipeRefreshLayout.setRefreshing(true);
|
|
||||||
new NotificationsFetcher(new FetchListener<NotificationModel[]>() {
|
|
||||||
@Override
|
|
||||||
public void onResult(final NotificationModel[] notificationModels) {
|
|
||||||
notificationsBinding.rvComments.setAdapter(new NotificationsAdapter(notificationModels, clickListener, mentionClickListener));
|
|
||||||
notificationsBinding.swipeRefreshLayout.setRefreshing(false);
|
|
||||||
new SeenAction().execute();
|
|
||||||
}
|
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
|
|
||||||
if (which == 0)
|
|
||||||
searchUsername(notificationModel.getUsername());
|
|
||||||
else if (which == 1 && commentDialogList.length == 2) {
|
|
||||||
// startActivity(new Intent(getApplicationContext(), PostViewer.class)
|
|
||||||
// .putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode(), false)));
|
|
||||||
}
|
|
||||||
else if (which == 1) new ProfileAction().execute("/approve/");
|
|
||||||
else if (which == 2) new ProfileAction().execute("/ignore/");
|
|
||||||
};
|
|
||||||
|
|
||||||
private final View.OnClickListener clickListener = v -> {
|
|
||||||
final Object tag = v.getTag();
|
|
||||||
if (tag instanceof NotificationModel) {
|
|
||||||
notificationModel = (NotificationModel) tag;
|
|
||||||
|
|
||||||
final String username = notificationModel.getUsername();
|
|
||||||
final SpannableString title = new SpannableString(username + ":\n" + notificationModel.getText());
|
|
||||||
title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
|
||||||
|
|
||||||
if (notificationModel.getShortcode() != null) commentDialogList = new String[]{
|
|
||||||
resources.getString(R.string.open_profile),
|
|
||||||
resources.getString(R.string.view_post)
|
|
||||||
};
|
|
||||||
else if (notificationModel.getType() == NotificationType.REQUEST)
|
|
||||||
commentDialogList = new String[]{
|
|
||||||
resources.getString(R.string.open_profile),
|
|
||||||
resources.getString(R.string.request_approve),
|
|
||||||
resources.getString(R.string.request_reject)
|
|
||||||
};
|
|
||||||
else commentDialogList = new String[]{
|
|
||||||
resources.getString(R.string.open_profile)
|
|
||||||
};
|
|
||||||
|
|
||||||
commmentDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, commentDialogList);
|
|
||||||
|
|
||||||
new AlertDialog.Builder(this).setTitle(title)
|
|
||||||
.setAdapter(commmentDialogAdapter, profileDialogListener)
|
|
||||||
.setNeutralButton(R.string.cancel, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) ->
|
|
||||||
new AlertDialog.Builder(this).setTitle(text)
|
|
||||||
.setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
|
|
||||||
.setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
|
|
||||||
(dialog, which) -> searchUsername(text)).show();
|
|
||||||
|
|
||||||
|
|
||||||
private void searchUsername(final String text) {
|
|
||||||
// startActivity(new Intent(getApplicationContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProfileAction extends AsyncTask<String, Void, Void> {
|
|
||||||
boolean ok = false;
|
|
||||||
String action;
|
|
||||||
|
|
||||||
protected Void doInBackground(String... rawAction) {
|
|
||||||
action = rawAction[0];
|
|
||||||
final String url = "https://www.instagram.com/web/friendships/"+notificationModel.getId()+action;
|
|
||||||
try {
|
|
||||||
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
|
||||||
urlConnection.setRequestMethod("POST");
|
|
||||||
urlConnection.setUseCaches(false);
|
|
||||||
urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
|
||||||
urlConnection.setRequestProperty("x-csrftoken",
|
|
||||||
Utils.settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]);
|
|
||||||
urlConnection.connect();
|
|
||||||
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
urlConnection.disconnect();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
Log.e("austin_debug", action+": " + ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void result) {
|
|
||||||
if (ok == true) {
|
|
||||||
onRefresh();
|
|
||||||
}
|
|
||||||
else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SeenAction extends AsyncTask<Void, Void, Void> {
|
|
||||||
protected Void doInBackground(Void... lmao) {
|
|
||||||
try {
|
|
||||||
final HttpURLConnection urlConnection =
|
|
||||||
(HttpURLConnection) new URL("https://www.instagram.com/web/activity/mark_checked/").openConnection();
|
|
||||||
urlConnection.setRequestMethod("POST");
|
|
||||||
urlConnection.setUseCaches(false);
|
|
||||||
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();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
Log.e("austin_debug", "seen: " + ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
90
app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
Executable file → Normal file
90
app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
Executable file → Normal file
@ -1,91 +1,55 @@
|
|||||||
package awais.instagrabber.adapters;
|
package awais.instagrabber.adapters;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
|
import androidx.recyclerview.widget.ListAdapter;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.RequestManager;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
|
||||||
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
|
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
|
||||||
|
import awais.instagrabber.databinding.ItemNotificationBinding;
|
||||||
import awais.instagrabber.interfaces.MentionClickListener;
|
import awais.instagrabber.interfaces.MentionClickListener;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
import awais.instagrabber.models.NotificationModel;
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
|
||||||
|
|
||||||
public final class NotificationsAdapter extends RecyclerView.Adapter<NotificationViewHolder> {
|
public final class NotificationsAdapter extends ListAdapter<NotificationModel, NotificationViewHolder> {
|
||||||
private final View.OnClickListener onClickListener;
|
private final OnNotificationClickListener notificationClickListener;
|
||||||
private final MentionClickListener mentionClickListener;
|
private final MentionClickListener mentionClickListener;
|
||||||
private final NotificationModel[] notificationModels;
|
|
||||||
private LayoutInflater layoutInflater;
|
|
||||||
|
|
||||||
public NotificationsAdapter(final NotificationModel[] notificationModels, final View.OnClickListener onClickListener,
|
private static final DiffUtil.ItemCallback<NotificationModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<NotificationModel>() {
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
|
||||||
|
return oldItem.getId().equals(newItem.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
|
||||||
|
return oldItem.getId().equals(newItem.getId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public NotificationsAdapter(final OnNotificationClickListener notificationClickListener,
|
||||||
final MentionClickListener mentionClickListener) {
|
final MentionClickListener mentionClickListener) {
|
||||||
this.notificationModels = notificationModels;
|
super(DIFF_CALLBACK);
|
||||||
this.onClickListener = onClickListener;
|
this.notificationClickListener = notificationClickListener;
|
||||||
this.mentionClickListener = mentionClickListener;
|
this.mentionClickListener = mentionClickListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public NotificationViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
|
public NotificationViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
|
||||||
final Context context = parent.getContext();
|
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
||||||
if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
|
final ItemNotificationBinding binding = ItemNotificationBinding.inflate(layoutInflater, parent, false);
|
||||||
return new NotificationViewHolder(layoutInflater.inflate(R.layout.item_notification,
|
return new NotificationViewHolder(binding);
|
||||||
parent, false), onClickListener, mentionClickListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
|
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
|
||||||
final NotificationModel notificationModel = notificationModels[position];
|
final NotificationModel notificationModel = getItem(position);
|
||||||
if (notificationModel != null) {
|
holder.bind(notificationModel, notificationClickListener);
|
||||||
holder.setNotificationModel(notificationModel);
|
|
||||||
|
|
||||||
int text = -1;
|
|
||||||
CharSequence subtext = null;
|
|
||||||
switch (notificationModel.getType()) {
|
|
||||||
case LIKE:
|
|
||||||
text = R.string.liked_notif;
|
|
||||||
break;
|
|
||||||
case COMMENT:
|
|
||||||
text = R.string.comment_notif;
|
|
||||||
subtext = notificationModel.getText();
|
|
||||||
break;
|
|
||||||
case MENTION:
|
|
||||||
text = R.string.mention_notif;
|
|
||||||
subtext = notificationModel.getText();
|
|
||||||
break;
|
|
||||||
case FOLLOW:
|
|
||||||
text = R.string.follow_notif;
|
|
||||||
break;
|
|
||||||
case REQUEST:
|
|
||||||
text = R.string.request_notif;
|
|
||||||
subtext = notificationModel.getText();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.setCommment(text);
|
public interface OnNotificationClickListener {
|
||||||
holder.setSubCommment(subtext);
|
void onNotificationClick(final NotificationModel model);
|
||||||
if (notificationModel.getType() != NotificationType.REQUEST)
|
|
||||||
holder.setDate(notificationModel.getDateTime());
|
|
||||||
|
|
||||||
holder.setUsername(notificationModel.getUsername());
|
|
||||||
|
|
||||||
final RequestManager rm = Glide.with(layoutInflater.getContext())
|
|
||||||
.applyDefaultRequestOptions(new RequestOptions().skipMemoryCache(true));
|
|
||||||
|
|
||||||
rm.load(notificationModel.getProfilePic()).into(holder.getProfilePicView());
|
|
||||||
rm.load(notificationModel.getPreviewPic()).into(holder.getPreviewPicView());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return notificationModels == null ? 0 : notificationModels.length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
103
app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java
Executable file → Normal file
103
app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java
Executable file → Normal file
@ -1,75 +1,68 @@
|
|||||||
package awais.instagrabber.adapters.viewholder;
|
package awais.instagrabber.adapters.viewholder;
|
||||||
|
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
import awais.instagrabber.customviews.RamboTextView;
|
import awais.instagrabber.adapters.NotificationsAdapter.OnNotificationClickListener;
|
||||||
import awais.instagrabber.interfaces.MentionClickListener;
|
import awais.instagrabber.databinding.ItemNotificationBinding;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
import awais.instagrabber.models.NotificationModel;
|
||||||
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
|
|
||||||
public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final MentionClickListener mentionClickListener;
|
private final ItemNotificationBinding binding;
|
||||||
private final ImageView ivProfilePic, ivPreviewPic;
|
|
||||||
private final TextView tvUsername, tvDate, tvComment, tvSubComment;
|
|
||||||
private final View container, rightContainer;
|
|
||||||
|
|
||||||
public NotificationViewHolder(@NonNull final View itemView, final View.OnClickListener onClickListener, final MentionClickListener mentionClickListener) {
|
public NotificationViewHolder(final ItemNotificationBinding binding) {
|
||||||
super(itemView);
|
super(binding.getRoot());
|
||||||
|
this.binding = binding;
|
||||||
container = itemView.findViewById(R.id.container);
|
|
||||||
rightContainer = itemView.findViewById(R.id.rightContainer);
|
|
||||||
if (onClickListener != null) container.setOnClickListener(onClickListener);
|
|
||||||
|
|
||||||
this.mentionClickListener = mentionClickListener;
|
|
||||||
|
|
||||||
ivProfilePic = itemView.findViewById(R.id.ivProfilePic);
|
|
||||||
ivPreviewPic = itemView.findViewById(R.id.ivPreviewPic);
|
|
||||||
tvUsername = itemView.findViewById(R.id.tvUsername);
|
|
||||||
tvDate = itemView.findViewById(R.id.tvDate);
|
|
||||||
tvComment = itemView.findViewById(R.id.tvComment);
|
|
||||||
tvSubComment = itemView.findViewById(R.id.tvSubComment);
|
|
||||||
|
|
||||||
tvUsername.setSelected(true);
|
|
||||||
tvDate.setSelected(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ImageView getProfilePicView() {
|
public void bind(final NotificationModel model,
|
||||||
return ivProfilePic;
|
final OnNotificationClickListener notificationClickListener) {
|
||||||
|
if (model == null) return;
|
||||||
|
itemView.setOnClickListener(v -> {
|
||||||
|
if (notificationClickListener == null) return;
|
||||||
|
notificationClickListener.onNotificationClick(model);
|
||||||
|
});
|
||||||
|
int text = -1;
|
||||||
|
CharSequence subtext = null;
|
||||||
|
switch (model.getType()) {
|
||||||
|
case LIKE:
|
||||||
|
text = R.string.liked_notif;
|
||||||
|
break;
|
||||||
|
case COMMENT:
|
||||||
|
text = R.string.comment_notif;
|
||||||
|
subtext = model.getText();
|
||||||
|
break;
|
||||||
|
case MENTION:
|
||||||
|
text = R.string.mention_notif;
|
||||||
|
subtext = model.getText();
|
||||||
|
break;
|
||||||
|
case FOLLOW:
|
||||||
|
text = R.string.follow_notif;
|
||||||
|
break;
|
||||||
|
case REQUEST:
|
||||||
|
text = R.string.request_notif;
|
||||||
|
subtext = model.getText();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
binding.tvUsername.setText(model.getUsername());
|
||||||
public final ImageView getPreviewPicView() {
|
binding.tvComment.setText(text);
|
||||||
return ivPreviewPic;
|
binding.tvSubComment.setText(subtext, subtext instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
|
||||||
|
// binding.tvSubComment.setMentionClickListener(mentionClickListener);
|
||||||
|
if (model.getType() != NotificationType.REQUEST) {
|
||||||
|
binding.tvDate.setText(model.getDateTime());
|
||||||
}
|
}
|
||||||
|
binding.ivProfilePic.setImageURI(model.getProfilePic());
|
||||||
public final void setNotificationModel(final NotificationModel notificationModel) {
|
if (TextUtils.isEmpty(model.getPreviewPic())) {
|
||||||
if (container != null) container.setTag(notificationModel);
|
binding.ivPreviewPic.setVisibility(View.GONE);
|
||||||
if (rightContainer != null) rightContainer.setTag(notificationModel);
|
} else {
|
||||||
}
|
binding.ivPreviewPic.setVisibility(View.VISIBLE);
|
||||||
|
binding.ivPreviewPic.setImageURI(model.getPreviewPic());
|
||||||
public final void setUsername(final String username) {
|
|
||||||
if (tvUsername != null) tvUsername.setText(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setDate(final String date) {
|
|
||||||
if (tvDate != null) tvDate.setText(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setCommment(final int commment) {
|
|
||||||
if (tvComment != null) {
|
|
||||||
tvComment.setText(commment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setSubCommment(final CharSequence commment) {
|
|
||||||
if (tvSubComment != null) {
|
|
||||||
tvSubComment.setText(commment, commment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
|
|
||||||
((RamboTextView) tvSubComment).setMentionClickListener(mentionClickListener);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
71
app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
Executable file → Normal file
71
app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
Executable file → Normal file
@ -8,6 +8,8 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
import awais.instagrabber.BuildConfig;
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
@ -22,16 +24,18 @@ import awaisomereport.LogCollector;
|
|||||||
import static awais.instagrabber.utils.Utils.logCollector;
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
|
|
||||||
public final class NotificationsFetcher extends AsyncTask<Void, Void, NotificationModel[]> {
|
public final class NotificationsFetcher extends AsyncTask<Void, Void, List<NotificationModel>> {
|
||||||
private final FetchListener<NotificationModel[]> fetchListener;
|
private static final String TAG = "NotificationsFetcher";
|
||||||
|
|
||||||
public NotificationsFetcher(final FetchListener<NotificationModel[]> fetchListener) {
|
private final FetchListener<List<NotificationModel>> fetchListener;
|
||||||
|
|
||||||
|
public NotificationsFetcher(final FetchListener<List<NotificationModel>> fetchListener) {
|
||||||
this.fetchListener = fetchListener;
|
this.fetchListener = fetchListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NotificationModel[] doInBackground(final Void... voids) {
|
protected List<NotificationModel> doInBackground(final Void... voids) {
|
||||||
NotificationModel[] result = null;
|
List<NotificationModel> result = new ArrayList<>();
|
||||||
final String url = "https://www.instagram.com/accounts/activity/?__a=1";
|
final String url = "https://www.instagram.com/accounts/activity/?__a=1";
|
||||||
CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE));
|
CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE));
|
||||||
|
|
||||||
@ -43,37 +47,34 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, Notificati
|
|||||||
conn.connect();
|
conn.connect();
|
||||||
|
|
||||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
JSONObject page = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject("user"),
|
final JSONObject page = new JSONObject(NetworkUtils.readFromConnection(conn))
|
||||||
ewaf = page.getJSONObject("activity_feed").optJSONObject("edge_web_activity_feed"),
|
.getJSONObject("graphql")
|
||||||
efr = page.optJSONObject("edge_follow_requests"),
|
.getJSONObject("user");
|
||||||
data;
|
final JSONObject ewaf = page.getJSONObject("activity_feed")
|
||||||
|
.optJSONObject("edge_web_activity_feed");
|
||||||
|
final JSONObject efr = page.optJSONObject("edge_follow_requests");
|
||||||
|
JSONObject data;
|
||||||
JSONArray media;
|
JSONArray media;
|
||||||
// int totalLength = 0;
|
|
||||||
int mediaLen = 0;
|
|
||||||
int reqLen = 0;
|
|
||||||
NotificationModel[] models = null, req = null;
|
|
||||||
|
|
||||||
if (ewaf != null
|
if (ewaf != null
|
||||||
&& (media = ewaf.optJSONArray("edges")) != null
|
&& (media = ewaf.optJSONArray("edges")) != null
|
||||||
&& media.length() > 0
|
&& media.length() > 0
|
||||||
&& media.optJSONObject(0).optJSONObject("node") != null) {
|
&& media.optJSONObject(0).optJSONObject("node") != null) {
|
||||||
mediaLen = media.length();
|
for (int i = 0; i < media.length(); ++i) {
|
||||||
models = new NotificationModel[mediaLen];
|
|
||||||
for (int i = 0; i < mediaLen; ++i) {
|
|
||||||
data = media.optJSONObject(i).optJSONObject("node");
|
data = media.optJSONObject(i).optJSONObject("node");
|
||||||
if (data == null) continue;
|
if (data == null) continue;
|
||||||
final String type = data.getString("__typename");
|
final String type = data.getString("__typename");
|
||||||
final NotificationType notificationType = NotificationType.valueOfType(type);
|
final NotificationType notificationType = NotificationType.valueOfType(type);
|
||||||
if (notificationType == null) continue;
|
if (notificationType == null) continue;
|
||||||
models[i] = new NotificationModel(
|
final JSONObject user = data.getJSONObject("user");
|
||||||
|
result.add(new NotificationModel(
|
||||||
data.getString(Constants.EXTRAS_ID),
|
data.getString(Constants.EXTRAS_ID),
|
||||||
data.optString("text"), // comments or mentions
|
data.optString("text"), // comments or mentions
|
||||||
data.getLong("timestamp"),
|
data.getLong("timestamp"),
|
||||||
data.getJSONObject("user").getString("username"),
|
user.getString("id"),
|
||||||
data.getJSONObject("user").getString("profile_pic_url"),
|
user.getString("username"),
|
||||||
|
user.getString("profile_pic_url"),
|
||||||
!data.isNull("media") ? data.getJSONObject("media").getString("shortcode") : null,
|
!data.isNull("media") ? data.getJSONObject("media").getString("shortcode") : null,
|
||||||
!data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
|
!data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null, notificationType));
|
||||||
notificationType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,29 +82,27 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, Notificati
|
|||||||
&& (media = efr.optJSONArray("edges")) != null
|
&& (media = efr.optJSONArray("edges")) != null
|
||||||
&& media.length() > 0
|
&& media.length() > 0
|
||||||
&& media.optJSONObject(0).optJSONObject("node") != null) {
|
&& media.optJSONObject(0).optJSONObject("node") != null) {
|
||||||
reqLen = media.length();
|
for (int i = 0; i < media.length(); ++i) {
|
||||||
req = new NotificationModel[reqLen];
|
|
||||||
for (int i = 0; i < reqLen; ++i) {
|
|
||||||
data = media.optJSONObject(i).optJSONObject("node");
|
data = media.optJSONObject(i).optJSONObject("node");
|
||||||
if (data == null) continue;
|
if (data == null) continue;
|
||||||
req[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID),
|
result.add(new NotificationModel(
|
||||||
data.optString("full_name"), 0L, data.getString("username"),
|
data.getString(Constants.EXTRAS_ID),
|
||||||
data.getString("profile_pic_url"), null, null, NotificationType.REQUEST);
|
data.optString("full_name"),
|
||||||
|
0L,
|
||||||
|
data.getString(Constants.EXTRAS_ID),
|
||||||
|
data.getString("username"),
|
||||||
|
data.getString("profile_pic_url"),
|
||||||
|
null,
|
||||||
|
null, NotificationType.REQUEST));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = new NotificationModel[mediaLen + reqLen];
|
|
||||||
if (req != null) System.arraycopy(req, 0, result, 0, reqLen);
|
|
||||||
if (models != null) System.arraycopy(models, 0, result, reqLen, mediaLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
if (logCollector != null)
|
if (logCollector != null)
|
||||||
logCollector.appendException(e, LogCollector.LogFile.ASYNC_NOTIFICATION_FETCHER, "doInBackground");
|
logCollector.appendException(e, LogCollector.LogFile.ASYNC_NOTIFICATION_FETCHER, "doInBackground");
|
||||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +112,7 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, Notificati
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(final NotificationModel[] result) {
|
protected void onPostExecute(final List<NotificationModel> result) {
|
||||||
if (fetchListener != null) fetchListener.onResult(result);
|
if (fetchListener != null) fetchListener.onResult(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,215 @@
|
|||||||
|
package awais.instagrabber.fragments;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.Spanned;
|
||||||
|
import android.text.style.RelativeSizeSpan;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
|
import awais.instagrabber.R;
|
||||||
|
import awais.instagrabber.adapters.NotificationsAdapter;
|
||||||
|
import awais.instagrabber.adapters.NotificationsAdapter.OnNotificationClickListener;
|
||||||
|
import awais.instagrabber.asyncs.NotificationsFetcher;
|
||||||
|
import awais.instagrabber.databinding.FragmentNotificationsViewerBinding;
|
||||||
|
import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections;
|
||||||
|
import awais.instagrabber.interfaces.MentionClickListener;
|
||||||
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
|
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
|
||||||
|
import awais.instagrabber.services.FriendshipService;
|
||||||
|
import awais.instagrabber.services.NewsService;
|
||||||
|
import awais.instagrabber.services.ServiceCallback;
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
|
import awais.instagrabber.utils.TextUtils;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
import awais.instagrabber.viewmodels.NotificationViewModel;
|
||||||
|
|
||||||
|
import static awais.instagrabber.utils.Utils.notificationManager;
|
||||||
|
|
||||||
|
public final class NotificationsViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||||
|
private static final String TAG = "NotificationsViewer";
|
||||||
|
|
||||||
|
private FragmentNotificationsViewerBinding binding;
|
||||||
|
private SwipeRefreshLayout root;
|
||||||
|
private boolean shouldRefresh = true;
|
||||||
|
private NotificationViewModel notificationViewModel;
|
||||||
|
private FriendshipService friendshipService;
|
||||||
|
private String userId;
|
||||||
|
private String csrfToken;
|
||||||
|
private NewsService newsService;
|
||||||
|
|
||||||
|
private final OnNotificationClickListener clickListener = model -> {
|
||||||
|
if (model == null) return;
|
||||||
|
final String username = model.getUsername();
|
||||||
|
final SpannableString title = new SpannableString(username + (TextUtils.isEmpty(model.getText()) ? "" : (":\n" + model.getText())));
|
||||||
|
title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
|
|
||||||
|
String[] commentDialogList;
|
||||||
|
if (model.getShortCode() != null) {
|
||||||
|
commentDialogList = new String[]{
|
||||||
|
getString(R.string.open_profile),
|
||||||
|
getString(R.string.view_post)
|
||||||
|
};
|
||||||
|
} else if (model.getType() == NotificationType.REQUEST) {
|
||||||
|
commentDialogList = new String[]{
|
||||||
|
getString(R.string.open_profile),
|
||||||
|
getString(R.string.request_approve),
|
||||||
|
getString(R.string.request_reject)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
commentDialogList = new String[]{getString(R.string.open_profile)};
|
||||||
|
}
|
||||||
|
if (getContext() == null) return;
|
||||||
|
final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
|
||||||
|
switch (which) {
|
||||||
|
case 0:
|
||||||
|
openProfile(model.getUsername());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (model.getType() == NotificationType.REQUEST) {
|
||||||
|
friendshipService.approve(userId, model.getUserId(), csrfToken, new ServiceCallback<FriendshipRepoChangeRootResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final FriendshipRepoChangeRootResponse result) {
|
||||||
|
// Log.d(TAG, "onSuccess: " + result);
|
||||||
|
if (result.getStatus().equals("ok")) {
|
||||||
|
onRefresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.e(TAG, "approve: status was not ok!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Throwable t) {
|
||||||
|
Log.e(TAG, "approve: onFailure: ", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final NavDirections action = MorePreferencesFragmentDirections
|
||||||
|
.actionGlobalPostViewFragment(0, new String[]{model.getShortCode()}, false);
|
||||||
|
NavHostFragment.findNavController(this).navigate(action);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
friendshipService.ignore(userId, model.getUserId(), csrfToken, new ServiceCallback<FriendshipRepoChangeRootResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final FriendshipRepoChangeRootResponse result) {
|
||||||
|
// Log.d(TAG, "onSuccess: " + result);
|
||||||
|
if (result.getStatus().equals("ok")) {
|
||||||
|
onRefresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.e(TAG, "ignore: status was not ok!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Throwable t) {
|
||||||
|
Log.e(TAG, "ignore: onFailure: ", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle(title)
|
||||||
|
.setItems(commentDialogList, profileDialogListener)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
};
|
||||||
|
private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
|
||||||
|
if (getContext() == null) return;
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle(text)
|
||||||
|
.setMessage(isHashtag ? R.string.comment_view_mention_hash_search
|
||||||
|
: R.string.comment_view_mention_user_search)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.ok, (dialog, which) -> openProfile(text))
|
||||||
|
.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
notificationManager.cancel(Constants.ACTIVITY_NOTIFICATION_ID);
|
||||||
|
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||||
|
if (TextUtils.isEmpty(cookie)) {
|
||||||
|
Toast.makeText(getContext(), R.string.activity_notloggedin, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
friendshipService = FriendshipService.getInstance();
|
||||||
|
newsService = NewsService.getInstance();
|
||||||
|
userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||||
|
csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
|
||||||
|
if (root != null) {
|
||||||
|
shouldRefresh = false;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
binding = FragmentNotificationsViewerBinding.inflate(getLayoutInflater());
|
||||||
|
root = binding.getRoot();
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||||
|
if (!shouldRefresh) return;
|
||||||
|
init();
|
||||||
|
shouldRefresh = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
binding.swipeRefreshLayout.setOnRefreshListener(this);
|
||||||
|
notificationViewModel = new ViewModelProvider(this).get(NotificationViewModel.class);
|
||||||
|
final NotificationsAdapter adapter = new NotificationsAdapter(clickListener, mentionClickListener);
|
||||||
|
binding.rvComments.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.rvComments.setAdapter(adapter);
|
||||||
|
notificationViewModel.getList().observe(getViewLifecycleOwner(), adapter::submitList);
|
||||||
|
onRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
binding.swipeRefreshLayout.setRefreshing(true);
|
||||||
|
new NotificationsFetcher(notificationModels -> {
|
||||||
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
|
notificationViewModel.getList().postValue(notificationModels);
|
||||||
|
final String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
||||||
|
newsService.markChecked(timestamp, csrfToken, new ServiceCallback<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(@NonNull final Boolean result) {
|
||||||
|
// Log.d(TAG, "onResponse: body: " + result);
|
||||||
|
if (!result) Log.e(TAG, "onSuccess: Error marking activity checked, response is false");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Throwable t) {
|
||||||
|
Log.e(TAG, "onFailure: Error marking activity checked", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openProfile(final String username) {
|
||||||
|
final NavDirections action = MorePreferencesFragmentDirections
|
||||||
|
.actionGlobalProfileFragment("@" + username);
|
||||||
|
NavHostFragment.findNavController(this).navigate(action);
|
||||||
|
}
|
||||||
|
}
|
@ -291,6 +291,7 @@ public class PostViewFragment extends Fragment {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (currentPostIndex >= idOrCodeList.size() || currentPostIndex < 0) return;
|
||||||
final String idOrShortCode = idOrCodeList.get(currentPostIndex);
|
final String idOrShortCode = idOrCodeList.get(currentPostIndex);
|
||||||
if (isId) {
|
if (isId) {
|
||||||
new iPostFetcher(idOrShortCode, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
new iPostFetcher(idOrShortCode, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
@ -100,7 +100,11 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
|
|||||||
generalCategory.setTitle("General");
|
generalCategory.setTitle("General");
|
||||||
generalCategory.setIconSpaceReserved(false);
|
generalCategory.setIconSpaceReserved(false);
|
||||||
screen.addPreference(generalCategory);
|
screen.addPreference(generalCategory);
|
||||||
generalCategory.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> false));
|
generalCategory.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> {
|
||||||
|
final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToNotificationsViewer();
|
||||||
|
NavHostFragment.findNavController(this).navigate(navDirections);
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
generalCategory.addPreference(getPreference(R.string.action_settings, R.drawable.ic_outline_settings_24, preference -> {
|
generalCategory.addPreference(getPreference(R.string.action_settings, R.drawable.ic_outline_settings_24, preference -> {
|
||||||
final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToSettingsPreferencesFragment();
|
final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToSettingsPreferencesFragment();
|
||||||
NavHostFragment.findNavController(this).navigate(navDirections);
|
NavHostFragment.findNavController(this).navigate(navDirections);
|
||||||
|
@ -9,19 +9,32 @@ import awais.instagrabber.utils.TextUtils;
|
|||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
public final class NotificationModel {
|
public final class NotificationModel {
|
||||||
private final String id, username, profilePicUrl, shortcode, previewUrl;
|
private final String id;
|
||||||
|
private final String userId;
|
||||||
|
private final String username;
|
||||||
|
private final String profilePicUrl;
|
||||||
|
private final String shortCode;
|
||||||
|
private final String previewUrl;
|
||||||
private final NotificationType type;
|
private final NotificationType type;
|
||||||
private final CharSequence text;
|
private final CharSequence text;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
|
||||||
public NotificationModel(final String id, final String text, final long timestamp, final String username,
|
public NotificationModel(final String id,
|
||||||
final String profilePicUrl, final String shortcode, final String previewUrl, final NotificationType type) {
|
final String text,
|
||||||
|
final long timestamp,
|
||||||
|
final String userId,
|
||||||
|
final String username,
|
||||||
|
final String profilePicUrl,
|
||||||
|
final String shortCode,
|
||||||
|
final String previewUrl,
|
||||||
|
final NotificationType type) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.text = TextUtils.hasMentions(text) ? TextUtils.getMentionText(text) : text;
|
this.text = TextUtils.hasMentions(text) ? TextUtils.getMentionText(text) : text;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
|
this.userId = userId;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.profilePicUrl = profilePicUrl;
|
this.profilePicUrl = profilePicUrl;
|
||||||
this.shortcode = shortcode;
|
this.shortCode = shortCode;
|
||||||
this.previewUrl = previewUrl;
|
this.previewUrl = previewUrl;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
@ -39,6 +52,10 @@ public final class NotificationModel {
|
|||||||
return Utils.datetimeParser.format(new Date(timestamp * 1000L));
|
return Utils.datetimeParser.format(new Date(timestamp * 1000L));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
@ -47,8 +64,8 @@ public final class NotificationModel {
|
|||||||
return profilePicUrl;
|
return profilePicUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getShortcode() {
|
public String getShortCode() {
|
||||||
return shortcode;
|
return shortCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPreviewPic() {
|
public String getPreviewPic() {
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package awais.instagrabber.repositories;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.FieldMap;
|
||||||
|
import retrofit2.http.FormUrlEncoded;
|
||||||
|
import retrofit2.http.Header;
|
||||||
|
import retrofit2.http.Headers;
|
||||||
|
import retrofit2.http.POST;
|
||||||
|
|
||||||
|
public interface NewsRepository {
|
||||||
|
|
||||||
|
Call<String> inbox();
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@Headers("User-Agent: " + Constants.USER_AGENT)
|
||||||
|
@POST("https://www.instagram.com/web/activity/mark_checked/")
|
||||||
|
Call<String> markChecked(@Header("x-csrftoken") String csrfToken, @FieldMap Map<String, String> map);
|
||||||
|
}
|
@ -17,8 +17,11 @@ public class AddCookiesInterceptor implements Interceptor {
|
|||||||
final Request request = chain.request();
|
final Request request = chain.request();
|
||||||
final Request.Builder builder = request.newBuilder();
|
final Request.Builder builder = request.newBuilder();
|
||||||
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||||
builder.addHeader("Cookie", cookie)
|
builder.addHeader("Cookie", cookie);
|
||||||
.addHeader("User-Agent", Constants.I_USER_AGENT);
|
final String userAgentHeader = "User-Agent";
|
||||||
|
if (request.header(userAgentHeader) == null) {
|
||||||
|
builder.addHeader(userAgentHeader, Constants.I_USER_AGENT);
|
||||||
|
}
|
||||||
final Request updatedRequest = builder.build();
|
final Request updatedRequest = builder.build();
|
||||||
return chain.proceed(updatedRequest);
|
return chain.proceed(updatedRequest);
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ public abstract class BaseService {
|
|||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
final OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
|
final OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
|
||||||
.addInterceptor(new AddCookiesInterceptor())
|
.addInterceptor(new AddCookiesInterceptor())
|
||||||
.followRedirects(true)
|
.followRedirects(false)
|
||||||
.followSslRedirects(true);
|
.followSslRedirects(false);
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
// clientBuilder.addInterceptor(new LoggingInterceptor());
|
// clientBuilder.addInterceptor(new LoggingInterceptor());
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,20 @@ public class FriendshipService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void approve(final String userId,
|
||||||
|
final String targetUserId,
|
||||||
|
final String crsfToken,
|
||||||
|
final ServiceCallback<FriendshipRepoChangeRootResponse> callback) {
|
||||||
|
change("approve", userId, targetUserId, crsfToken, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ignore(final String userId,
|
||||||
|
final String targetUserId,
|
||||||
|
final String crsfToken,
|
||||||
|
final ServiceCallback<FriendshipRepoChangeRootResponse> callback) {
|
||||||
|
change("ignore", userId, targetUserId, crsfToken, callback);
|
||||||
|
}
|
||||||
|
|
||||||
private void change(final String action,
|
private void change(final String action,
|
||||||
final String userId,
|
final String userId,
|
||||||
final String targetUserId,
|
final String targetUserId,
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
package awais.instagrabber.services;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.NewsRepository;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
import retrofit2.Retrofit;
|
||||||
|
|
||||||
|
public class NewsService extends BaseService {
|
||||||
|
private static final String TAG = "NewsService";
|
||||||
|
|
||||||
|
private final NewsRepository repository;
|
||||||
|
|
||||||
|
private static NewsService instance;
|
||||||
|
|
||||||
|
private NewsService() {
|
||||||
|
final Retrofit retrofit = getRetrofitBuilder()
|
||||||
|
.baseUrl("https://i.instagram.com")
|
||||||
|
.build();
|
||||||
|
repository = retrofit.create(NewsRepository.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NewsService getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new NewsService();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markChecked(final String timestamp,
|
||||||
|
final String csrfToken,
|
||||||
|
final ServiceCallback<Boolean> callback) {
|
||||||
|
final Map<String, String> map = new HashMap<>();
|
||||||
|
map.put("timestamp", timestamp);
|
||||||
|
final Call<String> request = repository.markChecked(csrfToken, map);
|
||||||
|
request.enqueue(new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
|
final String body = response.body();
|
||||||
|
if (body == null) {
|
||||||
|
callback.onSuccess(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final JSONObject jsonObject = new JSONObject(body);
|
||||||
|
final String status = jsonObject.optString("status");
|
||||||
|
callback.onSuccess(status.equals("ok"));
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
callback.onFailure(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
// Log.e(TAG, "onFailure: ", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
1
app/src/main/java/awais/instagrabber/utils/Constants.java
Executable file → Normal file
1
app/src/main/java/awais/instagrabber/utils/Constants.java
Executable file → Normal file
@ -74,4 +74,5 @@ public final class Constants {
|
|||||||
public static final String CHANNEL_ID = "InstaGrabber";
|
public static final String CHANNEL_ID = "InstaGrabber";
|
||||||
public static final String CHANNEL_NAME = "Instagrabber";
|
public static final String CHANNEL_NAME = "Instagrabber";
|
||||||
public static final String NOTIF_GROUP_NAME = "awais.instagrabber.InstaNotif";
|
public static final String NOTIF_GROUP_NAME = "awais.instagrabber.InstaNotif";
|
||||||
|
public static final int ACTIVITY_NOTIFICATION_ID = 1800000000;
|
||||||
}
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package awais.instagrabber.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import awais.instagrabber.models.NotificationModel;
|
||||||
|
|
||||||
|
public class NotificationViewModel extends ViewModel {
|
||||||
|
private MutableLiveData<List<NotificationModel>> list;
|
||||||
|
|
||||||
|
public MutableLiveData<List<NotificationModel>> getList() {
|
||||||
|
if (list == null) {
|
||||||
|
list = new MutableLiveData<>();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
<?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"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:context=".activities.NotificationsViewer">
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
layout="@layout/layout_include_toolbar" />
|
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/swipeRefreshLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/rvComments"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
app:layoutManager="LinearLayoutManager"
|
|
||||||
tools:listitem="@layout/item_notification" />
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
</LinearLayout>
|
|
15
app/src/main/res/layout/fragment_notifications_viewer.xml
Normal file
15
app/src/main/res/layout/fragment_notifications_viewer.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.NotificationsViewerFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvComments"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
tools:listitem="@layout/item_notification" />
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
199
app/src/main/res/layout/item_notification.xml
Executable file → Normal file
199
app/src/main/res/layout/item_notification.xml
Executable file → Normal file
@ -1,19 +1,192 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:background="?android:selectableItemBackground"
|
||||||
tools:viewBindingIgnore="true">
|
android:baselineAligned="false"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
<include
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/container"
|
android:id="@+id/ivProfilePic"
|
||||||
layout="@layout/layout_include_notif_item" />
|
android:layout_width="@dimen/notification_image_size"
|
||||||
|
android:layout_height="@dimen/notification_image_size"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:actualImageScaleType="centerCrop"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/barrier"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:roundAsCircle="true"
|
||||||
|
tools:placeholderImage="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
<!--<com.facebook.drawee.view.SimpleDraweeView-->
|
||||||
android:layout_height="1dp"
|
<!-- android:id="@+id/multi_pic1"-->
|
||||||
android:layout_gravity="bottom"
|
<!-- android:layout_width="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
android:layout_marginBottom="4dp"
|
<!-- android:layout_height="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
android:background="#80888888" />
|
<!-- app:actualImageScaleType="centerCrop"-->
|
||||||
</LinearLayout>
|
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||||
|
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||||
|
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||||
|
<!-- app:placeholderImage="@mipmap/ic_launcher" />-->
|
||||||
|
|
||||||
|
<!--<com.facebook.drawee.view.SimpleDraweeView-->
|
||||||
|
<!-- android:id="@+id/multi_pic2"-->
|
||||||
|
<!-- android:layout_width="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- android:layout_height="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- app:layout_constraintBottom_toTopOf="@+id/multi_pic3"-->
|
||||||
|
<!-- app:layout_constraintEnd_toStartOf="@id/barrier"-->
|
||||||
|
<!-- app:layout_constraintStart_toEndOf="@id/multi_pic1"-->
|
||||||
|
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||||
|
<!-- app:placeholderImage="@mipmap/ic_launcher" />-->
|
||||||
|
|
||||||
|
<!--<com.facebook.drawee.view.SimpleDraweeView-->
|
||||||
|
<!-- android:id="@+id/multi_pic3"-->
|
||||||
|
<!-- android:layout_width="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- android:layout_height="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||||
|
<!-- app:layout_constraintEnd_toStartOf="@id/barrier"-->
|
||||||
|
<!-- app:layout_constraintStart_toEndOf="@id/multi_pic1"-->
|
||||||
|
<!-- app:layout_constraintTop_toBottomOf="@+id/multi_pic2"-->
|
||||||
|
<!-- app:placeholderImage="@mipmap/ic_launcher" />-->
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Barrier
|
||||||
|
android:id="@+id/barrier"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:barrierDirection="end"
|
||||||
|
app:constraint_referenced_ids="ivProfilePic" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/tvUsername"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/tvComment"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/ivPreviewPic"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/barrier"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="username" />
|
||||||
|
|
||||||
|
<awais.instagrabber.customviews.RamboTextView
|
||||||
|
android:id="@+id/tvComment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:linksClickable="true"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat"
|
||||||
|
android:textStyle="italic"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/tvSubComment"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/ivPreviewPic"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/tvUsername"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvUsername"
|
||||||
|
tools:text="comment comment comment comment comment comment comment comment comment comment comment comment comment " />
|
||||||
|
|
||||||
|
<awais.instagrabber.customviews.RamboTextView
|
||||||
|
android:id="@+id/tvSubComment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autoLink="web|email"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:linksClickable="true"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/tvDate"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/tvUsername"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvComment"
|
||||||
|
tools:text="sub-comment" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/tvDate"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:gravity="end"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:textStyle="italic"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/ivPreviewPic"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/tvSubComment"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvComment"
|
||||||
|
tools:text="date" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Barrier
|
||||||
|
android:id="@+id/preview_barrier"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:barrierDirection="start"
|
||||||
|
app:constraint_referenced_ids="ivPreviewPic" />
|
||||||
|
|
||||||
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
|
android:id="@+id/ivPreviewPic"
|
||||||
|
android:layout_width="@dimen/notification_image_size"
|
||||||
|
android:layout_height="@dimen/notification_image_size"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/preview_barrier"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:placeholderImage="@mipmap/ic_launcher"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<!--<com.facebook.drawee.view.SimpleDraweeView-->
|
||||||
|
<!-- android:id="@+id/preview_pic1"-->
|
||||||
|
<!-- android:layout_width="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- android:layout_height="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||||
|
<!-- app:layout_constraintEnd_toStartOf="@id/preview_pic2"-->
|
||||||
|
<!-- app:layout_constraintStart_toEndOf="@id/preview_barrier"-->
|
||||||
|
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||||
|
<!-- app:placeholderImage="@mipmap/ic_launcher" />-->
|
||||||
|
|
||||||
|
<!--<com.facebook.drawee.view.SimpleDraweeView-->
|
||||||
|
<!-- android:id="@+id/preview_pic2"-->
|
||||||
|
<!-- android:layout_width="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- android:layout_height="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||||
|
<!-- app:layout_constraintStart_toEndOf="@id/preview_pic1"-->
|
||||||
|
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||||
|
<!-- app:placeholderImage="@mipmap/ic_launcher" />-->
|
||||||
|
|
||||||
|
<!--<com.facebook.drawee.view.SimpleDraweeView-->
|
||||||
|
<!-- android:id="@+id/preview_pic3"-->
|
||||||
|
<!-- android:layout_width="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- android:layout_height="@dimen/simple_item_picture_size_exact_half"-->
|
||||||
|
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||||
|
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||||
|
<!-- app:layout_constraintStart_toEndOf="@id/preview_pic1"-->
|
||||||
|
<!-- app:layout_constraintTop_toBottomOf="@id/preview_pic2"-->
|
||||||
|
<!-- app:placeholderImage="@mipmap/ic_launcher" />-->
|
||||||
|
|
||||||
|
<!--<androidx.constraintlayout.widget.Group-->
|
||||||
|
<!-- android:id="@+id/multi_pic_group"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:visibility="visible"-->
|
||||||
|
<!-- app:constraint_referenced_ids="multi_pic1, multi_pic2, multi_pic3" />-->
|
||||||
|
|
||||||
|
<!--<androidx.constraintlayout.widget.Group-->
|
||||||
|
<!-- android:id="@+id/preview_pic_group"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:visibility="gone"-->
|
||||||
|
<!-- app:constraint_referenced_ids="preview_pic1, preview_pic2, preview_pic3" />-->
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,152 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?android:selectableItemBackground"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingLeft="0dp"
|
|
||||||
android:paddingEnd="4dp"
|
|
||||||
android:paddingRight="4dp">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size"
|
|
||||||
android:layout_height="@dimen/simple_item_picture_size"
|
|
||||||
android:gravity="center">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/ivProfilePic"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="@dimen/simple_item_picture_size_half" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="@dimen/simple_item_picture_size_half" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/tvUsername"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingEnd="4dp"
|
|
||||||
android:paddingRight="4dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
|
||||||
android:textColor="?android:textColorPrimary"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingRight="8dp">
|
|
||||||
|
|
||||||
<awais.instagrabber.customviews.RamboTextView
|
|
||||||
android:id="@+id/tvComment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:linksClickable="true"
|
|
||||||
android:textStyle="italic"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat" />
|
|
||||||
|
|
||||||
<awais.instagrabber.customviews.RamboTextView
|
|
||||||
android:id="@+id/tvSubComment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:autoLink="web|email"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:linksClickable="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/tvDate"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:gravity="right"
|
|
||||||
android:paddingStart="4dp"
|
|
||||||
android:paddingLeft="4dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textStyle="italic" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size"
|
|
||||||
android:layout_height="@dimen/simple_item_picture_size"
|
|
||||||
android:gravity="center">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/ivPreviewPic"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/rightContainer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="@dimen/simple_item_picture_size_half" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
|
||||||
android:layout_height="@dimen/simple_item_picture_size_half" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</FrameLayout>
|
|
||||||
</LinearLayout>
|
|
@ -1,9 +1,39 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/more_nav_graph"
|
android:id="@+id/more_nav_graph"
|
||||||
app:startDestination="@id/morePreferencesFragment">
|
app:startDestination="@id/morePreferencesFragment">
|
||||||
|
|
||||||
|
<include app:graph="@navigation/post_view_nav_graph" />
|
||||||
|
<include app:graph="@navigation/profile_nav_graph" />
|
||||||
|
<include app:graph="@navigation/hashtag_nav_graph" />
|
||||||
|
<include app:graph="@navigation/location_nav_graph" />
|
||||||
|
<include app:graph="@navigation/comments_nav_graph" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_postViewFragment"
|
||||||
|
app:destination="@id/post_view_nav_graph">
|
||||||
|
<argument
|
||||||
|
android:name="index"
|
||||||
|
app:argType="integer" />
|
||||||
|
<argument
|
||||||
|
android:name="idOrCodeArray"
|
||||||
|
app:argType="string[]" />
|
||||||
|
<argument
|
||||||
|
android:name="isId"
|
||||||
|
app:argType="boolean" />
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_profileFragment"
|
||||||
|
app:destination="@id/profile_nav_graph">
|
||||||
|
<argument
|
||||||
|
android:name="username"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="true" />
|
||||||
|
</action>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/morePreferencesFragment"
|
android:id="@+id/morePreferencesFragment"
|
||||||
android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment"
|
android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment"
|
||||||
@ -14,6 +44,9 @@
|
|||||||
<action
|
<action
|
||||||
android:id="@+id/action_morePreferencesFragment_to_aboutFragment"
|
android:id="@+id/action_morePreferencesFragment_to_aboutFragment"
|
||||||
app:destination="@id/aboutFragment" />
|
app:destination="@id/aboutFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_morePreferencesFragment_to_notificationsViewer"
|
||||||
|
app:destination="@id/notificationsViewer" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/settingsPreferencesFragment"
|
android:id="@+id/settingsPreferencesFragment"
|
||||||
@ -23,4 +56,9 @@
|
|||||||
android:id="@+id/aboutFragment"
|
android:id="@+id/aboutFragment"
|
||||||
android:name="awais.instagrabber.fragments.settings.AboutFragment"
|
android:name="awais.instagrabber.fragments.settings.AboutFragment"
|
||||||
android:label="@string/action_about" />
|
android:label="@string/action_about" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/notificationsViewer"
|
||||||
|
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
|
||||||
|
android:label="@string/title_notifications"
|
||||||
|
tools:layout="@layout/fragment_notifications_viewer" />
|
||||||
</navigation>
|
</navigation>
|
2
app/src/main/res/values/dimens.xml
Executable file → Normal file
2
app/src/main/res/values/dimens.xml
Executable file → Normal file
@ -15,7 +15,9 @@
|
|||||||
|
|
||||||
<dimen name="simple_item_picture_size">80dp</dimen>
|
<dimen name="simple_item_picture_size">80dp</dimen>
|
||||||
<dimen name="simple_item_picture_size_half">35dp</dimen>
|
<dimen name="simple_item_picture_size_half">35dp</dimen>
|
||||||
|
<dimen name="simple_item_picture_size_exact_half">40dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="notification_image_size">56dp</dimen>
|
||||||
<dimen name="message_item_size">@dimen/simple_item_picture_size</dimen>
|
<dimen name="message_item_size">@dimen/simple_item_picture_size</dimen>
|
||||||
<dimen name="message_item_profile_size">@dimen/feed_profile_size</dimen>
|
<dimen name="message_item_profile_size">@dimen/feed_profile_size</dimen>
|
||||||
<dimen name="dm_media_img_max_height">500dp</dimen>
|
<dimen name="dm_media_img_max_height">500dp</dimen>
|
||||||
|
Loading…
Reference in New Issue
Block a user