mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 14:47:29 +00:00
notification viewer + hd avatar
This commit is contained in:
parent
ca8e2d58de
commit
8726a924a0
@ -186,6 +186,15 @@
|
|||||||
android:value=".activities.Main" />
|
android:value=".activities.Main" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activities.NotificationsViewer"
|
||||||
|
android:parentActivityName=".activities.Main">
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".activities.Main" />
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.Login"
|
android:name=".activities.Login"
|
||||||
android:label="@string/login"
|
android:label="@string/login"
|
||||||
|
@ -87,7 +87,7 @@ public final class Main extends BaseLanguageActivity {
|
|||||||
private MenuItem searchAction;
|
private MenuItem searchAction;
|
||||||
public ActivityMainBinding mainBinding;
|
public ActivityMainBinding mainBinding;
|
||||||
public SearchView searchView;
|
public SearchView searchView;
|
||||||
public MenuItem downloadAction, settingsAction, dmsAction;
|
public MenuItem downloadAction, settingsAction, dmsAction, notifAction;
|
||||||
public StoryModel[] storyModels;
|
public StoryModel[] storyModels;
|
||||||
public String userQuery = null;
|
public String userQuery = null;
|
||||||
public MainHelper mainHelper;
|
public MainHelper mainHelper;
|
||||||
@ -118,9 +118,6 @@ public final class Main extends BaseLanguageActivity {
|
|||||||
final String uid = Utils.getUserIdFromCookie(cookie);
|
final String uid = Utils.getUserIdFromCookie(cookie);
|
||||||
Utils.setupCookies(cookie);
|
Utils.setupCookies(cookie);
|
||||||
|
|
||||||
if (settingsHelper.getInteger(Constants.PROFILE_FETCH_MODE) == 2)
|
|
||||||
settingsHelper.putInteger(Constants.PROFILE_FETCH_MODE, 1);
|
|
||||||
|
|
||||||
MainHelper.stopCurrentExecutor();
|
MainHelper.stopCurrentExecutor();
|
||||||
mainHelper = new MainHelper(this);
|
mainHelper = new MainHelper(this);
|
||||||
if (bundle == null) {
|
if (bundle == null) {
|
||||||
@ -292,10 +289,12 @@ public final class Main extends BaseLanguageActivity {
|
|||||||
final MenuItem quickAccessAction = menu.findItem(R.id.action_quickaccess).setVisible(true);
|
final MenuItem quickAccessAction = menu.findItem(R.id.action_quickaccess).setVisible(true);
|
||||||
|
|
||||||
final MenuItem.OnMenuItemClickListener clickListener = item -> {
|
final MenuItem.OnMenuItemClickListener clickListener = item -> {
|
||||||
if (item == downloadAction) {
|
if (item == downloadAction)
|
||||||
downloadSelectedItems();
|
downloadSelectedItems();
|
||||||
} else if (item == dmsAction)
|
else if (item == dmsAction)
|
||||||
startActivity(new Intent(this, DirectMessages.class));
|
startActivity(new Intent(this, DirectMessages.class));
|
||||||
|
else if (item == notifAction)
|
||||||
|
startActivity(new Intent(this, NotificationsViewer.class));
|
||||||
else if (item == settingsAction)
|
else if (item == settingsAction)
|
||||||
new SettingsDialog().show(fragmentManager, "settings");
|
new SettingsDialog().show(fragmentManager, "settings");
|
||||||
else if (item == quickAccessAction)
|
else if (item == quickAccessAction)
|
||||||
@ -310,11 +309,12 @@ public final class Main extends BaseLanguageActivity {
|
|||||||
quickAccessAction.setOnMenuItemClickListener(clickListener);
|
quickAccessAction.setOnMenuItemClickListener(clickListener);
|
||||||
menu.findItem(R.id.action_about).setVisible(true).setOnMenuItemClickListener(clickListener);
|
menu.findItem(R.id.action_about).setVisible(true).setOnMenuItemClickListener(clickListener);
|
||||||
dmsAction = menu.findItem(R.id.action_dms).setOnMenuItemClickListener(clickListener);
|
dmsAction = menu.findItem(R.id.action_dms).setOnMenuItemClickListener(clickListener);
|
||||||
|
notifAction = menu.findItem(R.id.action_notif).setOnMenuItemClickListener(clickListener);
|
||||||
settingsAction = menu.findItem(R.id.action_settings).setVisible(true).setOnMenuItemClickListener(clickListener);
|
settingsAction = menu.findItem(R.id.action_settings).setVisible(true).setOnMenuItemClickListener(clickListener);
|
||||||
downloadAction = menu.findItem(R.id.action_download).setOnMenuItemClickListener(clickListener);
|
downloadAction = menu.findItem(R.id.action_download).setOnMenuItemClickListener(clickListener);
|
||||||
|
|
||||||
if (!Utils.isEmpty(Utils.settingsHelper.getString(Constants.COOKIE))) {
|
if (!Utils.isEmpty(Utils.settingsHelper.getString(Constants.COOKIE))) {
|
||||||
//settingsAction.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
notifAction.setVisible(true);
|
||||||
dmsAction.setVisible(true).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
dmsAction.setVisible(true).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
140
app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java
Executable file
140
app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
package awais.instagrabber.activities;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
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.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.widget.SearchView;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
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.PostModel;
|
||||||
|
import awais.instagrabber.models.ProfileModel;
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
|
public final class NotificationsViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
|
||||||
|
private NotificationsAdapter notificationsAdapter;
|
||||||
|
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;
|
||||||
|
private InputMethodManager imm;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
notificationsBinding = ActivityNotificationBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(notificationsBinding.getRoot());
|
||||||
|
notificationsBinding.swipeRefreshLayout.setOnRefreshListener(this);
|
||||||
|
|
||||||
|
notificationsBinding.swipeRefreshLayout.setRefreshing(true);
|
||||||
|
setSupportActionBar(notificationsBinding.toolbar.toolbar);
|
||||||
|
notificationsBinding.toolbar.toolbar.setTitle(R.string.title_notifications);
|
||||||
|
|
||||||
|
resources = getResources();
|
||||||
|
|
||||||
|
new NotificationsFetcher(new FetchListener<NotificationModel[]>() {
|
||||||
|
@Override
|
||||||
|
public void onResult(final NotificationModel[] notificationModels) {
|
||||||
|
notificationsAdapter = new NotificationsAdapter(notificationModels, clickListener, mentionClickListener);
|
||||||
|
|
||||||
|
notificationsBinding.rvComments.setAdapter(notificationsAdapter);
|
||||||
|
notificationsBinding.swipeRefreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
notificationsBinding.swipeRefreshLayout.setRefreshing(true);
|
||||||
|
new NotificationsFetcher(new FetchListener<NotificationModel[]>() {
|
||||||
|
@Override
|
||||||
|
public void onResult(final NotificationModel[] notificationModels) {
|
||||||
|
notificationsBinding.swipeRefreshLayout.setRefreshing(false);
|
||||||
|
|
||||||
|
notificationsAdapter = new NotificationsAdapter(notificationModels, clickListener, mentionClickListener);
|
||||||
|
|
||||||
|
notificationsBinding.rvComments.setAdapter(notificationsAdapter);
|
||||||
|
}
|
||||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
|
||||||
|
if (which == 0)
|
||||||
|
searchUsername(notificationModel.getUsername());
|
||||||
|
else if (which == 1)
|
||||||
|
startActivity(new Intent(getApplicationContext(), PostViewer.class)
|
||||||
|
.putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode())));
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
String[] commentDialogList;
|
||||||
|
|
||||||
|
if (notificationModel.getShortcode() != null) commentDialogList = new String[]{
|
||||||
|
resources.getString(R.string.open_profile),
|
||||||
|
resources.getString(R.string.view_post)
|
||||||
|
};
|
||||||
|
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) ->
|
||||||
|
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) {
|
||||||
|
if (Main.scanHack != null) {
|
||||||
|
Main.scanHack.onResult(text);
|
||||||
|
setResult(6969);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -29,22 +28,14 @@ import awais.instagrabber.R;
|
|||||||
import awais.instagrabber.asyncs.DownloadAsync;
|
import awais.instagrabber.asyncs.DownloadAsync;
|
||||||
import awais.instagrabber.asyncs.ProfilePictureFetcher;
|
import awais.instagrabber.asyncs.ProfilePictureFetcher;
|
||||||
import awais.instagrabber.databinding.ActivityProfileBinding;
|
import awais.instagrabber.databinding.ActivityProfileBinding;
|
||||||
import awais.instagrabber.dialogs.ProfileSettingsDialog;
|
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.HashtagModel;
|
import awais.instagrabber.models.HashtagModel;
|
||||||
import awais.instagrabber.models.LocationModel;
|
import awais.instagrabber.models.LocationModel;
|
||||||
import awais.instagrabber.models.ProfileModel;
|
import awais.instagrabber.models.ProfileModel;
|
||||||
import awais.instagrabber.models.enums.ProfilePictureFetchMode;
|
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Constants.PROFILE_FETCH_MODE;
|
|
||||||
|
|
||||||
public final class ProfileViewer extends BaseLanguageActivity {
|
public final class ProfileViewer extends BaseLanguageActivity {
|
||||||
private final ProfilePictureFetchMode[] fetchModes = {
|
|
||||||
ProfilePictureFetchMode.INSTADP,
|
|
||||||
ProfilePictureFetchMode.INSTAFULLSIZE
|
|
||||||
};
|
|
||||||
private ActivityProfileBinding profileBinding;
|
private ActivityProfileBinding profileBinding;
|
||||||
private ProfileModel profileModel;
|
private ProfileModel profileModel;
|
||||||
private HashtagModel hashtagModel;
|
private HashtagModel hashtagModel;
|
||||||
@ -88,15 +79,12 @@ public final class ProfileViewer extends BaseLanguageActivity {
|
|||||||
profileBinding.imageViewer.setZoomTransitionDuration(420);
|
profileBinding.imageViewer.setZoomTransitionDuration(420);
|
||||||
profileBinding.imageViewer.setMaximumScale(7.2f);
|
profileBinding.imageViewer.setMaximumScale(7.2f);
|
||||||
|
|
||||||
final int fetchIndex = Math.min(2, Math.max(0, Utils.settingsHelper.getInteger(PROFILE_FETCH_MODE)));
|
|
||||||
final ProfilePictureFetchMode fetchMode = fetchModes[fetchIndex];
|
|
||||||
|
|
||||||
fetchListener = profileUrl -> {
|
fetchListener = profileUrl -> {
|
||||||
profilePicUrl = profileUrl;
|
profilePicUrl = profileUrl;
|
||||||
|
|
||||||
if (!fallbackToProfile && Utils.isEmpty(profilePicUrl)) {
|
if (!fallbackToProfile && Utils.isEmpty(profilePicUrl)) {
|
||||||
fallbackToProfile = true;
|
fallbackToProfile = true;
|
||||||
new ProfilePictureFetcher(username, id, fetchListener, fetchMode, profilePicUrl, (hashtagModel != null || locationModel != null)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +101,7 @@ public final class ProfileViewer extends BaseLanguageActivity {
|
|||||||
fallbackToProfile = true;
|
fallbackToProfile = true;
|
||||||
if (!errorHandled) {
|
if (!errorHandled) {
|
||||||
errorHandled = true;
|
errorHandled = true;
|
||||||
new ProfilePictureFetcher(username, id, fetchListener, fetchModes[Math.min(2, Math.max(0, fetchIndex + 1))], profilePicUrl, (hashtagModel != null || locationModel != null))
|
new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null))
|
||||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
} else {
|
} else {
|
||||||
glideRequestManager.load(profilePicUrl).into(profileBinding.imageViewer);
|
glideRequestManager.load(profilePicUrl).into(profileBinding.imageViewer);
|
||||||
@ -168,7 +156,7 @@ public final class ProfileViewer extends BaseLanguageActivity {
|
|||||||
}).into(profileBinding.imageViewer);
|
}).into(profileBinding.imageViewer);
|
||||||
};
|
};
|
||||||
|
|
||||||
new ProfilePictureFetcher(username, id, fetchListener, fetchMode, profilePicUrl, (hashtagModel != null || locationModel != null))
|
new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null))
|
||||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,8 +199,6 @@ public final class ProfileViewer extends BaseLanguageActivity {
|
|||||||
final MenuItem.OnMenuItemClickListener menuItemClickListener = item -> {
|
final MenuItem.OnMenuItemClickListener menuItemClickListener = item -> {
|
||||||
if (item == menuItemDownload) {
|
if (item == menuItemDownload) {
|
||||||
downloadProfilePicture();
|
downloadProfilePicture();
|
||||||
} else {
|
|
||||||
new ProfileSettingsDialog().show(fragmentManager, "settings");
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -223,10 +209,6 @@ public final class ProfileViewer extends BaseLanguageActivity {
|
|||||||
menuItemDownload.setEnabled(false);
|
menuItemDownload.setEnabled(false);
|
||||||
menuItemDownload.setOnMenuItemClickListener(menuItemClickListener);
|
menuItemDownload.setOnMenuItemClickListener(menuItemClickListener);
|
||||||
|
|
||||||
final MenuItem menuItemSettings = menu.findItem(R.id.action_settings);
|
|
||||||
menuItemSettings.setVisible(true);
|
|
||||||
menuItemSettings.setOnMenuItemClickListener(menuItemClickListener);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
90
app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
Executable file
90
app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
Executable file
@ -0,0 +1,90 @@
|
|||||||
|
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.core.text.HtmlCompat;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.RequestManager;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import awais.instagrabber.R;
|
||||||
|
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
|
||||||
|
import awais.instagrabber.interfaces.MentionClickListener;
|
||||||
|
import awais.instagrabber.models.NotificationModel;
|
||||||
|
import awais.instagrabber.utils.LocaleUtils;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
|
public final class NotificationsAdapter extends RecyclerView.Adapter<NotificationViewHolder> {
|
||||||
|
private final View.OnClickListener onClickListener;
|
||||||
|
private final MentionClickListener mentionClickListener;
|
||||||
|
private final NotificationModel[] notificationModels;
|
||||||
|
private LayoutInflater layoutInflater;
|
||||||
|
|
||||||
|
public NotificationsAdapter(final NotificationModel[] notificationModels, final View.OnClickListener onClickListener,
|
||||||
|
final MentionClickListener mentionClickListener) {
|
||||||
|
this.notificationModels = notificationModels;
|
||||||
|
this.onClickListener = onClickListener;
|
||||||
|
this.mentionClickListener = mentionClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public NotificationViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
|
||||||
|
final Context context = parent.getContext();
|
||||||
|
if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
|
||||||
|
return new NotificationViewHolder(layoutInflater.inflate(R.layout.item_notification,
|
||||||
|
parent, false), onClickListener, mentionClickListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
|
||||||
|
final NotificationModel notificationModel = notificationModels[position];
|
||||||
|
if (notificationModel != null) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.setCommment(text);
|
||||||
|
holder.setSubCommment(subtext);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package awais.instagrabber.adapters.viewholder;
|
||||||
|
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import awais.instagrabber.R;
|
||||||
|
import awais.instagrabber.adapters.CommentsAdapter;
|
||||||
|
import awais.instagrabber.customviews.RamboTextView;
|
||||||
|
import awais.instagrabber.interfaces.MentionClickListener;
|
||||||
|
import awais.instagrabber.models.NotificationModel;
|
||||||
|
|
||||||
|
public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final MentionClickListener mentionClickListener;
|
||||||
|
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) {
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
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() {
|
||||||
|
return ivProfilePic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ImageView getPreviewPicView() {
|
||||||
|
return ivPreviewPic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setNotificationModel(final NotificationModel notificationModel) {
|
||||||
|
if (container != null) container.setTag(notificationModel);
|
||||||
|
if (rightContainer != null) rightContainer.setTag(notificationModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
Executable file
85
app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
Executable file
@ -0,0 +1,85 @@
|
|||||||
|
package awais.instagrabber.asyncs;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import awais.instagrabber.BuildConfig;
|
||||||
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
|
import awais.instagrabber.models.NotificationModel;
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
import awaisomereport.LogCollector;
|
||||||
|
|
||||||
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
|
|
||||||
|
public final class NotificationsFetcher extends AsyncTask<Void, Void, NotificationModel[]> {
|
||||||
|
private final FetchListener<NotificationModel[]> fetchListener;
|
||||||
|
|
||||||
|
public NotificationsFetcher(final FetchListener<NotificationModel[]> fetchListener) {
|
||||||
|
this.fetchListener = fetchListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NotificationModel[] doInBackground(final Void... voids) {
|
||||||
|
NotificationModel[] result = null;
|
||||||
|
final String url = "https://www.instagram.com/accounts/activity/?__a=1";
|
||||||
|
|
||||||
|
try {
|
||||||
|
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
conn.setInstanceFollowRedirects(false);
|
||||||
|
conn.setUseCaches(false);
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
|
JSONObject data = new JSONObject(Utils.readFromConnection(conn))
|
||||||
|
.getJSONObject("graphql").getJSONObject("user").getJSONObject("activity_feed").getJSONObject("edge_web_activity_feed");
|
||||||
|
|
||||||
|
JSONArray media;
|
||||||
|
if ((media = data.optJSONArray("edges")) != null && media.length() > 0 &&
|
||||||
|
(data = media.optJSONObject(0).optJSONObject("node")) != null) {
|
||||||
|
|
||||||
|
final int mediaLen = media.length();
|
||||||
|
|
||||||
|
final NotificationModel[] models = new NotificationModel[mediaLen];
|
||||||
|
for (int i = 0; i < mediaLen; ++i) {
|
||||||
|
data = media.optJSONObject(i).optJSONObject("node");
|
||||||
|
if (Utils.getNotifType(data.getString("__typename")) == null) continue;
|
||||||
|
models[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID),
|
||||||
|
data.optString("text"), // comments or mentions
|
||||||
|
data.getLong("timestamp"),
|
||||||
|
data.getJSONObject("user").getString("username"),
|
||||||
|
data.getJSONObject("user").getString("profile_pic_url"),
|
||||||
|
!data.isNull("media") ? data.getJSONObject("media").getString("shortcode") : null,
|
||||||
|
!data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
|
||||||
|
Utils.getNotifType(data.getString("__typename")));
|
||||||
|
}
|
||||||
|
result = models;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.disconnect();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
if (logCollector != null)
|
||||||
|
logCollector.appendException(e, LogCollector.LogFile.ASYNC_NOTIFICATION_FETCHER, "doInBackground");
|
||||||
|
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
if (fetchListener != null) fetchListener.doBefore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(final NotificationModel[] result) {
|
||||||
|
if (fetchListener != null) fetchListener.onResult(result);
|
||||||
|
}
|
||||||
|
}
|
@ -5,31 +5,26 @@ import android.util.Log;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.jsoup.nodes.Element;
|
|
||||||
import org.jsoup.select.Elements;
|
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
import awais.instagrabber.BuildConfig;
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import awaisomereport.LogCollector;
|
import awaisomereport.LogCollector;
|
||||||
import awais.instagrabber.models.enums.ProfilePictureFetchMode;
|
|
||||||
import static awais.instagrabber.utils.Utils.logCollector;
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
|
|
||||||
public final class ProfilePictureFetcher extends AsyncTask<Void, Void, String> {
|
public final class ProfilePictureFetcher extends AsyncTask<Void, Void, String> {
|
||||||
private final FetchListener<String> fetchListener;
|
private final FetchListener<String> fetchListener;
|
||||||
private final String userName, userId, picUrl;
|
private final String userName, userId, picUrl;
|
||||||
private final boolean isHashtag;
|
private final boolean isHashtag;
|
||||||
private ProfilePictureFetchMode fetchMode;
|
|
||||||
|
|
||||||
public ProfilePictureFetcher(final String userName, final String userId, final FetchListener<String> fetchListener,
|
public ProfilePictureFetcher(final String userName, final String userId, final FetchListener<String> fetchListener,
|
||||||
final ProfilePictureFetchMode fetchMode, final String picUrl, final boolean isHashtag) {
|
final String picUrl, final boolean isHashtag) {
|
||||||
this.fetchListener = fetchListener;
|
this.fetchListener = fetchListener;
|
||||||
this.fetchMode = fetchMode;
|
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.picUrl = picUrl;
|
this.picUrl = picUrl;
|
||||||
@ -40,69 +35,28 @@ public final class ProfilePictureFetcher extends AsyncTask<Void, Void, String> {
|
|||||||
protected String doInBackground(final Void... voids) {
|
protected String doInBackground(final Void... voids) {
|
||||||
String out = picUrl;
|
String out = picUrl;
|
||||||
if (!isHashtag) try {
|
if (!isHashtag) try {
|
||||||
if (fetchMode == ProfilePictureFetchMode.INSTA_STALKER) fetchMode = ProfilePictureFetchMode.INSTADP;
|
final String url = "https://i.instagram.com/api/v1/users/"+userId+"/info/";
|
||||||
final String url;
|
|
||||||
|
|
||||||
if (fetchMode == ProfilePictureFetchMode.INSTADP)
|
|
||||||
url = "https://instadp.com/fullsize/" + userName;
|
|
||||||
else // select from s1, s2, s3 but s1 works fine
|
|
||||||
url = "https://instafullsize.com/ifsapi/ig/photo/s1/" + userName + "?igid=" + userId;
|
|
||||||
|
|
||||||
// prolly http://167.99.85.4/instagram/userid?profile-url=the.badak
|
|
||||||
|
|
||||||
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
conn.setUseCaches(false);
|
conn.setUseCaches(false);
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
if (fetchMode == ProfilePictureFetchMode.INSTAFULLSIZE) {
|
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
conn.setRequestProperty("Authorization", "fjgt842ff582a");
|
|
||||||
}
|
|
||||||
|
|
||||||
final String result = conn.getResponseCode() == HttpURLConnection.HTTP_OK ? Utils.readFromConnection(conn) : null;
|
final String result = conn.getResponseCode() == HttpURLConnection.HTTP_OK ? Utils.readFromConnection(conn) : null;
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
|
|
||||||
if (!Utils.isEmpty(result)) {
|
if (!Utils.isEmpty(result)) {
|
||||||
final Document doc = Jsoup.parse(result);
|
JSONObject data = new JSONObject(result).getJSONObject("user");
|
||||||
boolean fallback = false;
|
if (data.has("hd_profile_pic_url_info"))
|
||||||
|
out = data.getJSONObject("hd_profile_pic_url_info").optString("url");
|
||||||
if (fetchMode == ProfilePictureFetchMode.INSTADP) {
|
|
||||||
final int imgIndex = result.indexOf("preloadImg('"), lastIndex;
|
|
||||||
|
|
||||||
Element element = doc.selectFirst(".instadp");
|
|
||||||
if (element != null && (element = element.selectFirst(".picture")) != null)
|
|
||||||
out = element.attr("src");
|
|
||||||
else if ((element = doc.selectFirst(".download-btn")) != null)
|
|
||||||
out = element.attr("href");
|
|
||||||
else if (imgIndex != -1 && (lastIndex = result.indexOf("')", imgIndex)) != -1)
|
|
||||||
out = result.substring(imgIndex + 12, lastIndex);
|
|
||||||
else fallback = true;
|
|
||||||
|
|
||||||
} else if (fetchMode == ProfilePictureFetchMode.INSTAFULLSIZE) {
|
|
||||||
try {
|
|
||||||
final JSONObject object = new JSONObject(result);
|
|
||||||
out = object.getString("result");
|
|
||||||
} catch (final Exception e) {
|
|
||||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
|
||||||
fallback = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fallback) {
|
|
||||||
final Elements imgs = doc.getElementsByTag("img");
|
|
||||||
for (final Element img : imgs) {
|
|
||||||
final String imgStr = img.toString();
|
|
||||||
if (imgStr.contains("cdninstagram.com")) return img.attr("src");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
if (logCollector != null)
|
if (logCollector != null)
|
||||||
logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground",
|
logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground");
|
||||||
new Pair<>("fetchMode", fetchMode));
|
|
||||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (out == null) out = picUrl;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
package awais.instagrabber.dialogs;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Constants.PROFILE_FETCH_MODE;
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
|
||||||
|
|
||||||
public final class ProfileSettingsDialog extends BottomSheetDialogFragment implements AdapterView.OnItemSelectedListener {
|
|
||||||
private int fetchIndex;
|
|
||||||
private Activity activity;
|
|
||||||
private Spinner spProfileFetchMode;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
|
||||||
final Dialog dialog = super.onCreateDialog(savedInstanceState);
|
|
||||||
|
|
||||||
final Context context = getContext();
|
|
||||||
activity = context instanceof Activity ? (Activity) context : getActivity();
|
|
||||||
|
|
||||||
final View contentView = View.inflate(activity, R.layout.dialog_profile_settings, null);
|
|
||||||
|
|
||||||
spProfileFetchMode = contentView.findViewById(R.id.spProfileFetchMode);
|
|
||||||
|
|
||||||
fetchIndex = Math.min(2, Math.max(0, settingsHelper.getInteger(PROFILE_FETCH_MODE)));
|
|
||||||
spProfileFetchMode.setSelection(fetchIndex);
|
|
||||||
spProfileFetchMode.setOnItemSelectedListener(this);
|
|
||||||
|
|
||||||
dialog.setContentView(contentView);
|
|
||||||
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDismiss(@NonNull final DialogInterface dialog) {
|
|
||||||
super.onDismiss(dialog);
|
|
||||||
if (activity != null && (spProfileFetchMode == null || fetchIndex != spProfileFetchMode.getSelectedItemPosition()))
|
|
||||||
activity.recreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(final AdapterView<?> parent, final View view, final int position, final long id) {
|
|
||||||
settingsHelper.putInteger(PROFILE_FETCH_MODE, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(final AdapterView<?> parent) { }
|
|
||||||
}
|
|
58
app/src/main/java/awais/instagrabber/models/NotificationModel.java
Executable file
58
app/src/main/java/awais/instagrabber/models/NotificationModel.java
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
package awais.instagrabber.models;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
|
|
||||||
|
public final class NotificationModel {
|
||||||
|
private final String id, username, profilePicUrl, shortcode, previewUrl;
|
||||||
|
private final NotificationType type;
|
||||||
|
private final CharSequence text;
|
||||||
|
private final long timestamp;
|
||||||
|
|
||||||
|
public NotificationModel(final String id, final String text, final long timestamp, final String username,
|
||||||
|
final String profilePicUrl, final String shortcode, final String previewUrl, final NotificationType type) {
|
||||||
|
this.id = id;
|
||||||
|
this.text = Utils.hasMentions(text) ? Utils.getMentionText(text) : text;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.username = username;
|
||||||
|
this.profilePicUrl = profilePicUrl;
|
||||||
|
this.shortcode = shortcode;
|
||||||
|
this.previewUrl = previewUrl;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getDateTime() {
|
||||||
|
return Utils.datetimeParser.format(new Date(timestamp * 1000L));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfilePic() {
|
||||||
|
return profilePicUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShortcode() {
|
||||||
|
return shortcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPreviewPic() {
|
||||||
|
return previewUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotificationType getType() { return type; }
|
||||||
|
}
|
10
app/src/main/java/awais/instagrabber/models/enums/NotificationType.java
Executable file
10
app/src/main/java/awais/instagrabber/models/enums/NotificationType.java
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
package awais.instagrabber.models.enums;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public enum NotificationType implements Serializable {
|
||||||
|
LIKE,
|
||||||
|
FOLLOW,
|
||||||
|
COMMENT,
|
||||||
|
MENTION
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package awais.instagrabber.models.enums;
|
|
||||||
|
|
||||||
public enum ProfilePictureFetchMode {
|
|
||||||
INSTADP,
|
|
||||||
INSTAFULLSIZE,
|
|
||||||
INSTA_STALKER,
|
|
||||||
}
|
|
@ -10,7 +10,6 @@ public final class Constants {
|
|||||||
public static final String APP_THEME = "app_theme";
|
public static final String APP_THEME = "app_theme";
|
||||||
public static final String APP_LANGUAGE = "app_language";
|
public static final String APP_LANGUAGE = "app_language";
|
||||||
public static final String PREV_INSTALL_VERSION = "prevVersion";
|
public static final String PREV_INSTALL_VERSION = "prevVersion";
|
||||||
public static final String PROFILE_FETCH_MODE = "profile_fetch_mode";
|
|
||||||
// boolean prefs
|
// boolean prefs
|
||||||
public static final String DOWNLOAD_USER_FOLDER = "download_user_folder";
|
public static final String DOWNLOAD_USER_FOLDER = "download_user_folder";
|
||||||
public static final String BOTTOM_TOOLBAR = "bottom_toolbar";
|
public static final String BOTTOM_TOOLBAR = "bottom_toolbar";
|
||||||
|
@ -219,7 +219,6 @@ public final class ExportImportUtils {
|
|||||||
final JSONObject json = new JSONObject();
|
final JSONObject json = new JSONObject();
|
||||||
json.put(Constants.APP_THEME, settingsHelper.getInteger(Constants.APP_THEME));
|
json.put(Constants.APP_THEME, settingsHelper.getInteger(Constants.APP_THEME));
|
||||||
json.put(Constants.APP_LANGUAGE, settingsHelper.getInteger(Constants.APP_LANGUAGE));
|
json.put(Constants.APP_LANGUAGE, settingsHelper.getInteger(Constants.APP_LANGUAGE));
|
||||||
json.put(Constants.PROFILE_FETCH_MODE, settingsHelper.getInteger(Constants.PROFILE_FETCH_MODE));
|
|
||||||
|
|
||||||
String str = settingsHelper.getString(Constants.FOLDER_PATH);
|
String str = settingsHelper.getString(Constants.FOLDER_PATH);
|
||||||
if (!Utils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str);
|
if (!Utils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str);
|
||||||
|
@ -23,7 +23,6 @@ import static awais.instagrabber.utils.Constants.FOLDER_PATH;
|
|||||||
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
|
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
|
||||||
import static awais.instagrabber.utils.Constants.MUTED_VIDEOS;
|
import static awais.instagrabber.utils.Constants.MUTED_VIDEOS;
|
||||||
import static awais.instagrabber.utils.Constants.PREV_INSTALL_VERSION;
|
import static awais.instagrabber.utils.Constants.PREV_INSTALL_VERSION;
|
||||||
import static awais.instagrabber.utils.Constants.PROFILE_FETCH_MODE;
|
|
||||||
import static awais.instagrabber.utils.Constants.SHOW_QUICK_ACCESS_DIALOG;
|
import static awais.instagrabber.utils.Constants.SHOW_QUICK_ACCESS_DIALOG;
|
||||||
|
|
||||||
public final class SettingsHelper {
|
public final class SettingsHelper {
|
||||||
@ -109,6 +108,6 @@ public final class SettingsHelper {
|
|||||||
AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED})
|
AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED})
|
||||||
public @interface BooleanSettings {}
|
public @interface BooleanSettings {}
|
||||||
|
|
||||||
@StringDef({APP_THEME, APP_LANGUAGE, PROFILE_FETCH_MODE, PREV_INSTALL_VERSION})
|
@StringDef({APP_THEME, APP_LANGUAGE, PREV_INSTALL_VERSION})
|
||||||
public @interface IntegerSettings {}
|
public @interface IntegerSettings {}
|
||||||
}
|
}
|
@ -82,6 +82,7 @@ import awais.instagrabber.models.enums.DownloadMethod;
|
|||||||
import awais.instagrabber.models.enums.InboxReadState;
|
import awais.instagrabber.models.enums.InboxReadState;
|
||||||
import awais.instagrabber.models.enums.IntentModelType;
|
import awais.instagrabber.models.enums.IntentModelType;
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
import awais.instagrabber.models.enums.RavenExpiringMediaType;
|
import awais.instagrabber.models.enums.RavenExpiringMediaType;
|
||||||
import awais.instagrabber.models.enums.RavenMediaViewType;
|
import awais.instagrabber.models.enums.RavenMediaViewType;
|
||||||
import awaisomereport.LogCollector;
|
import awaisomereport.LogCollector;
|
||||||
@ -128,6 +129,7 @@ public final class Utils {
|
|||||||
try {
|
try {
|
||||||
final URI uri1 = new URI("https://instagram.com");
|
final URI uri1 = new URI("https://instagram.com");
|
||||||
final URI uri2 = new URI("https://instagram.com/");
|
final URI uri2 = new URI("https://instagram.com/");
|
||||||
|
final URI uri3 = new URI("https://i.instagram.com/");
|
||||||
for (final String cookie : cookieRaw.split(";")) {
|
for (final String cookie : cookieRaw.split(";")) {
|
||||||
final String[] strings = cookie.split("=", 2);
|
final String[] strings = cookie.split("=", 2);
|
||||||
final HttpCookie httpCookie = new HttpCookie(strings[0].trim(), strings[1].trim());
|
final HttpCookie httpCookie = new HttpCookie(strings[0].trim(), strings[1].trim());
|
||||||
@ -136,6 +138,7 @@ public final class Utils {
|
|||||||
httpCookie.setVersion(0);
|
httpCookie.setVersion(0);
|
||||||
cookieStore.add(uri1, httpCookie);
|
cookieStore.add(uri1, httpCookie);
|
||||||
cookieStore.add(uri2, httpCookie);
|
cookieStore.add(uri2, httpCookie);
|
||||||
|
cookieStore.add(uri3, httpCookie);
|
||||||
}
|
}
|
||||||
} catch (final URISyntaxException e) {
|
} catch (final URISyntaxException e) {
|
||||||
if (logCollector != null)
|
if (logCollector != null)
|
||||||
@ -732,6 +735,14 @@ public final class Utils {
|
|||||||
return RavenExpiringMediaType.RAVEN_UNKNOWN;
|
return RavenExpiringMediaType.RAVEN_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NotificationType getNotifType(final String itemType) {
|
||||||
|
if ("GraphLikeAggregatedStory".equals(itemType)) return NotificationType.LIKE;
|
||||||
|
if ("GraphFollowAggregatedStory".equals(itemType)) return NotificationType.FOLLOW;
|
||||||
|
if ("GraphCommentMediaStory".equals(itemType)) return NotificationType.COMMENT;
|
||||||
|
if ("GraphMentionStory".equals(itemType)) return NotificationType.MENTION;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static int convertDpToPx(final float dp) {
|
public static int convertDpToPx(final float dp) {
|
||||||
if (displayMetrics == null)
|
if (displayMetrics == null)
|
||||||
displayMetrics = Resources.getSystem().getDisplayMetrics();
|
displayMetrics = Resources.getSystem().getDisplayMetrics();
|
||||||
@ -1189,7 +1200,7 @@ public final class Utils {
|
|||||||
if (jsonObject.getString("__typename").equals("GraphTappableFeedMedia") && jsonObject.has("media")) {
|
if (jsonObject.getString("__typename").equals("GraphTappableFeedMedia") && jsonObject.has("media")) {
|
||||||
storyModels[j].setTappableShortCode(jsonObject.getJSONObject("media").getString(Constants.EXTRAS_SHORTCODE));
|
storyModels[j].setTappableShortCode(jsonObject.getJSONObject("media").getString(Constants.EXTRAS_SHORTCODE));
|
||||||
}
|
}
|
||||||
else if (jsonObject.optString("__typename").equals("GraphTappableStoryPoll")) {
|
else if (jsonObject.optString("__typename").equals("GraphTappableStoryPoll") && !jsonObject.isNull("id")) {
|
||||||
storyModels[j].setPoll(new PollModel(
|
storyModels[j].setPoll(new PollModel(
|
||||||
jsonObject.getString("id"),
|
jsonObject.getString("id"),
|
||||||
jsonObject.getString("question"),
|
jsonObject.getString("question"),
|
||||||
|
@ -108,6 +108,7 @@ public final class LogCollector {
|
|||||||
ASYNC_FEED_FETCHER("async-feed-fetcher.txt"),
|
ASYNC_FEED_FETCHER("async-feed-fetcher.txt"),
|
||||||
ASYNC_HASHTAG_FETCHER("async-hashtag-fetcher.txt"),
|
ASYNC_HASHTAG_FETCHER("async-hashtag-fetcher.txt"),
|
||||||
ASYNC_LOCATION_FETCHER("async-location-fetcher.txt"),
|
ASYNC_LOCATION_FETCHER("async-location-fetcher.txt"),
|
||||||
|
ASYNC_NOTIFICATION_FETCHER("async-notification-fetcher.txt"),
|
||||||
ASYNC_PROFILE_FETCHER("async-profile-fetcher.txt"),
|
ASYNC_PROFILE_FETCHER("async-profile-fetcher.txt"),
|
||||||
ASYNC_PROFILE_PICTURE_FETCHER("async-pfp-fetcher.txt"),
|
ASYNC_PROFILE_PICTURE_FETCHER("async-pfp-fetcher.txt"),
|
||||||
ASYNC_SAVED_FETCHER("async-saved-fetcher.txt"),
|
ASYNC_SAVED_FETCHER("async-saved-fetcher.txt"),
|
||||||
|
11
app/src/main/res/drawable-anydpi/ic_notif.xml
Normal file
11
app/src/main/res/drawable-anydpi/ic_notif.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#333333"
|
||||||
|
android:alpha="0.6">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
|
||||||
|
</vector>
|
BIN
app/src/main/res/drawable-hdpi/ic_notif.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_notif.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 269 B |
BIN
app/src/main/res/drawable-mdpi/ic_notif.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_notif.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 193 B |
BIN
app/src/main/res/drawable-xhdpi/ic_notif.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_notif.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 321 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_notif.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_notif.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 433 B |
30
app/src/main/res/layout/activity_notification.xml
Executable file
30
app/src/main/res/layout/activity_notification.xml
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
<?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>
|
@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="10dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
style="@style/TextAppearance.AppCompat.Headline"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:paddingStart="?attr/dialogPreferredPadding"
|
|
||||||
android:paddingLeft="?attr/dialogPreferredPadding"
|
|
||||||
android:paddingTop="10dp"
|
|
||||||
android:paddingEnd="?attr/dialogPreferredPadding"
|
|
||||||
android:paddingRight="?attr/dialogPreferredPadding"
|
|
||||||
android:paddingBottom="6dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@string/action_settings" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="5dp"
|
|
||||||
android:layout_marginLeft="5dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_marginBottom="24dp"
|
|
||||||
android:padding="5dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:text="@string/profile_endpoint"
|
|
||||||
android:textColor="?android:textColorPrimary"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/spProfileFetchMode"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:entries="@array/profile_fetch_modes"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingBottom="4dp" />
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
20
app/src/main/res/layout/item_notification.xml
Executable file
20
app/src/main/res/layout/item_notification.xml
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
<?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="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:viewBindingIgnore="true">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/container"
|
||||||
|
layout="@layout/layout_include_notif_item" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:background="#80888888" />
|
||||||
|
</LinearLayout>
|
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipChildren="false"
|
|
||||||
android:clipToPadding="false">
|
|
||||||
|
|
||||||
<awais.instagrabber.customviews.RamboTextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="10dp"
|
|
||||||
android:paddingLeft="10dp"
|
|
||||||
android:paddingEnd="10dp"
|
|
||||||
android:paddingRight="10dp"
|
|
||||||
android:paddingBottom="24dp"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
</ScrollView>
|
|
154
app/src/main/res/layout/layout_include_notif_item.xml
Executable file
154
app/src/main/res/layout/layout_include_notif_item.xml
Executable file
@ -0,0 +1,154 @@
|
|||||||
|
<?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="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>
|
@ -12,6 +12,14 @@
|
|||||||
android:visible="false"
|
android:visible="false"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="always" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_notif"
|
||||||
|
android:icon="@drawable/ic_notif"
|
||||||
|
android:title="@string/action_notif"
|
||||||
|
android:titleCondensed="@string/action_notif"
|
||||||
|
android:visible="false"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_about"
|
android:id="@+id/action_about"
|
||||||
android:icon="@android:drawable/ic_menu_info_details"
|
android:icon="@android:drawable/ic_menu_info_details"
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>tanggal</item>
|
<item>tanggal</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
<item>\|</item>
|
<item>\|</item>
|
||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -28,11 +28,6 @@
|
|||||||
<item>-</item>
|
<item>-</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="profile_fetch_modes">
|
|
||||||
<item>Instadp</item>
|
|
||||||
<item>Instafullsize</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="date_presets">
|
<string-array name="date_presets">
|
||||||
<item>dd-MM-yyyy</item>
|
<item>dd-MM-yyyy</item>
|
||||||
<item>dd/MM/yyyy</item>
|
<item>dd/MM/yyyy</item>
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<string name="description">The original maintainer, AWAiS, made InstaGrabber as a small and basic little personal app with intentions of [steali-]downloading posts off Instagram. Very unfortunately, this was abandoned and me, Austin Huang, took over the ship. [Let\'s hope that\'s at least a lil\' bit cash money.] After all, this app is fully open source, ad-less, and tracking-less [aside from what Instagram knows]. Even if you don\'t care about downloading stuff [like me], it\'s still a great Instagram client to use!\n\nGot questions [or just wanna talk]? Contact instagrabber@austinhuang.me or click one of the buttons below.</string>
|
<string name="description">The original maintainer, AWAiS, made InstaGrabber as a small and basic little personal app with intentions of [steali-]downloading posts off Instagram. Very unfortunately, this was abandoned and me, Austin Huang, took over the ship. [Let\'s hope that\'s at least a lil\' bit cash money.] After all, this app is fully open source, ad-less, and tracking-less [aside from what Instagram knows]. Even if you don\'t care about downloading stuff [like me], it\'s still a great Instagram client to use!\n\nGot questions [or just wanna talk]? Contact instagrabber@austinhuang.me or click one of the buttons below.</string>
|
||||||
<string name="action_quickaccess">Quick Access</string>
|
<string name="action_quickaccess">Quick Access</string>
|
||||||
<string name="action_about">About</string>
|
<string name="action_about">About</string>
|
||||||
|
<string name="action_notif">Notifications</string>
|
||||||
<string name="action_dms">Direct Messages</string>
|
<string name="action_dms">Direct Messages</string>
|
||||||
<string name="action_setting">Settings (v%s)</string>
|
<string name="action_setting">Settings (v%s)</string>
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
@ -29,6 +30,7 @@
|
|||||||
<string name="title_favorites">Favorites</string>
|
<string name="title_favorites">Favorites</string>
|
||||||
<string name="title_discover">Discover</string>
|
<string name="title_discover">Discover</string>
|
||||||
<string name="title_comments">Comments</string>
|
<string name="title_comments">Comments</string>
|
||||||
|
<string name="title_notifications">Notifications</string>
|
||||||
<string name="title_highlight">Highlight: %s</string>
|
<string name="title_highlight">Highlight: %s</string>
|
||||||
<string name="title_user_story">User Story</string>
|
<string name="title_user_story">User Story</string>
|
||||||
<string name="title_changelog">Changelog</string>
|
<string name="title_changelog">Changelog</string>
|
||||||
@ -60,6 +62,7 @@
|
|||||||
<string name="show_stories">Show stories</string>
|
<string name="show_stories">Show stories</string>
|
||||||
<string name="no_more_stories">No more stories!</string>
|
<string name="no_more_stories">No more stories!</string>
|
||||||
<string name="view_story_post">View Story Post</string>
|
<string name="view_story_post">View Story Post</string>
|
||||||
|
<string name="view_post">View Post</string>
|
||||||
<string name="spotify">Spotify</string>
|
<string name="spotify">Spotify</string>
|
||||||
<string name="vote_story_poll">Vote</string>
|
<string name="vote_story_poll">Vote</string>
|
||||||
<string name="votef_story_poll">Vote successful!</string>
|
<string name="votef_story_poll">Vote successful!</string>
|
||||||
@ -180,6 +183,11 @@
|
|||||||
|
|
||||||
<string name="comment_hint">Write a new comment...</string>
|
<string name="comment_hint">Write a new comment...</string>
|
||||||
|
|
||||||
|
<string name="liked_notif">Liked your post</string>
|
||||||
|
<string name="comment_notif">Commented on your post:</string>
|
||||||
|
<string name="follow_notif">Started following you</string>
|
||||||
|
<string name="mention_notif">Mentioned you:</string>
|
||||||
|
|
||||||
<string name="share_public_post">Share this public post to...</string>
|
<string name="share_public_post">Share this public post to...</string>
|
||||||
<string name="share_private_post">This is a private post! Share to those who can view them!</string>
|
<string name="share_private_post">This is a private post! Share to those who can view them!</string>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user