1
0
Fork 0
mirror of https://github.com/KokaKiwi/BarInsta synced 2026-03-14 16:31:36 +00:00

Merge pull request #1 from austinhuang0131/master

Upstream from Master
This commit is contained in:
Zerrium 2021-03-19 10:11:24 +07:00 committed by GitHub
commit 4853c1572d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 498 additions and 1414 deletions

View file

@ -18,14 +18,14 @@ import awais.instagrabber.utils.LocaleUtils;
import awais.instagrabber.utils.SettingsHelper;
import awais.instagrabber.utils.TextUtils;
import awaisomereport.CrashReporter;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static awais.instagrabber.utils.CookieUtils.NET_COOKIE_MANAGER;
import static awais.instagrabber.utils.Utils.applicationHandler;
import static awais.instagrabber.utils.Utils.cacheDir;
import static awais.instagrabber.utils.Utils.clipboardManager;
import static awais.instagrabber.utils.Utils.datetimeParser;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public final class InstaGrabberApplication extends Application {
@ -56,7 +56,7 @@ public final class InstaGrabberApplication extends Application {
}
if (!BuildConfig.DEBUG) CrashReporter.get(this).start();
logCollector = new LogCollector(this);
// logCollector = new LogCollector(this);
CookieHandler.setDefault(NET_COOKIE_MANAGER);

View file

@ -21,6 +21,7 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.AutoCompleteTextView;
import android.widget.Toast;
@ -143,6 +144,8 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
final String cookie = settingsHelper.getString(Constants.COOKIE);
CookieUtils.setupCookies(cookie);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != 0;
if (settingsHelper.getBoolean(Constants.FLAG_SECURE))
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
setContentView(binding.getRoot());
final Toolbar toolbar = binding.toolbar;
setSupportActionBar(toolbar);

View file

@ -2,23 +2,46 @@ package awais.instagrabber.adapters;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import awais.instagrabber.adapters.viewholder.StoryListViewHolder;
import awais.instagrabber.databinding.ItemNotificationBinding;
import awais.instagrabber.models.FeedStoryModel;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.utils.TextUtils;
public final class FeedStoriesListAdapter extends ListAdapter<FeedStoryModel, StoryListViewHolder> {
public final class FeedStoriesListAdapter extends ListAdapter<FeedStoryModel, StoryListViewHolder> implements Filterable {
private final OnFeedStoryClickListener listener;
private List<FeedStoryModel> list;
private final Filter filter = new Filter() {
@Nullable
@Override
protected FilterResults performFiltering(final CharSequence filter) {
final boolean isFilterEmpty = TextUtils.isEmpty(filter);
final String query = isFilterEmpty ? null : filter.toString().toLowerCase();
for (FeedStoryModel item : list) {
if (isFilterEmpty) item.setShown(true);
else item.setShown(item.getProfileModel().getUsername().toLowerCase().contains(query));
}
return null;
}
@Override
protected void publishResults(final CharSequence constraint, final FilterResults results) {
submitList(list);
notifyDataSetChanged();
}
};
private static final DiffUtil.ItemCallback<FeedStoryModel> diffCallback = new DiffUtil.ItemCallback<FeedStoryModel>() {
@Override
@ -37,6 +60,17 @@ public final class FeedStoriesListAdapter extends ListAdapter<FeedStoryModel, St
this.listener = listener;
}
@Override
public Filter getFilter() {
return filter;
}
@Override
public void submitList(final List<FeedStoryModel> list) {
super.submitList(list.stream().filter(i -> i.isShown()).collect(Collectors.toList()));
this.list = list;
}
@NonNull
@Override
public StoryListViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {

View file

@ -89,7 +89,7 @@ public class DirectItemMediaShareViewHolder extends DirectItemViewHolder {
private void setupPreview(@NonNull final Media media,
final MessageDirection messageDirection) {
final String url = ResponseBodyUtils.getThumbUrl(media.getImageVersions2());
final String url = ResponseBodyUtils.getThumbUrl(media);
if (Objects.equals(url, binding.mediaPreview.getTag())) {
return;
}

View file

@ -66,9 +66,7 @@ public class DirectItemMediaViewHolder extends DirectItemViewHolder {
binding.mediaPreview.requestLayout();
binding.bgTime.getLayoutParams().width = width;
binding.bgTime.requestLayout();
final ImageVersions2 imageVersions2 = media.getImageVersions2();
if (imageVersions2 == null) return;
final String thumbUrl = ResponseBodyUtils.getThumbUrl(imageVersions2);
final String thumbUrl = ResponseBodyUtils.getThumbUrl(media);
binding.mediaPreview.setImageURI(thumbUrl);
}

View file

@ -86,8 +86,7 @@ public class DirectItemProfileViewHolder extends DirectItemViewHolder {
for (int i = 0; i < previewMedias.size(); i++) {
final Media previewMedia = previewMedias.get(i);
if (previewMedia == null) continue;
final ImageVersions2 imageVersions2 = previewMedia.getImageVersions2();
final String url = ResponseBodyUtils.getThumbUrl(imageVersions2);
final String url = ResponseBodyUtils.getThumbUrl(previewMedia);
if (url == null) continue;
previewViews.get(i).setImageURI(url);
}

View file

@ -180,9 +180,7 @@ public class DirectItemRavenMediaViewHolder extends DirectItemViewHolder {
layoutParams.width = widthHeight.first != null ? widthHeight.first : 0;
layoutParams.height = widthHeight.second != null ? widthHeight.second : 0;
binding.preview.requestLayout();
final ImageVersions2 imageVersions2 = media.getImageVersions2();
if (imageVersions2 == null) return;
final String thumbUrl = ResponseBodyUtils.getThumbUrl(imageVersions2);
final String thumbUrl = ResponseBodyUtils.getThumbUrl(media);
binding.preview.setImageURI(thumbUrl);
}

View file

@ -162,9 +162,7 @@ public class DirectItemReelShareViewHolder extends DirectItemViewHolder {
binding.preview.setHierarchy(new GenericDraweeHierarchyBuilder(itemView.getResources())
.setRoundingParams(roundingParams)
.build());
final ImageVersions2 imageVersions2 = media.getImageVersions2();
if (imageVersions2 == null) return;
final String thumbUrl = ResponseBodyUtils.getThumbUrl(imageVersions2);
final String thumbUrl = ResponseBodyUtils.getThumbUrl(media);
binding.preview.setImageURI(thumbUrl);
}

View file

@ -86,9 +86,7 @@ public class DirectItemStoryShareViewHolder extends DirectItemViewHolder {
layoutParams.width = widthHeight.first != null ? widthHeight.first : 0;
layoutParams.height = widthHeight.second != null ? widthHeight.second : 0;
binding.ivMediaPreview.requestLayout();
final ImageVersions2 imageVersions2 = storyShareMedia.getImageVersions2();
if (imageVersions2 == null) return;
final String thumbUrl = ResponseBodyUtils.getThumbUrl(imageVersions2);
final String thumbUrl = ResponseBodyUtils.getThumbUrl(storyShareMedia);
binding.ivMediaPreview.setImageURI(thumbUrl);
}

View file

@ -242,10 +242,10 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
text = replied.getPlaceholder().getMessage();
break;
case MEDIA:
url = ResponseBodyUtils.getThumbUrl(replied.getMedia().getImageVersions2());
url = ResponseBodyUtils.getThumbUrl(replied.getMedia());
break;
case RAVEN_MEDIA:
url = ResponseBodyUtils.getThumbUrl(replied.getVisualMedia().getMedia().getImageVersions2());
url = ResponseBodyUtils.getThumbUrl(replied.getVisualMedia().getMedia());
break;
case VOICE_MEDIA:
text = resources.getString(R.string.voice_message);
@ -255,7 +255,7 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
if (mediaShare.getMediaType() == MediaItemType.MEDIA_TYPE_SLIDER) {
mediaShare = mediaShare.getCarouselMedia().get(0);
}
url = ResponseBodyUtils.getThumbUrl(mediaShare.getImageVersions2());
url = ResponseBodyUtils.getThumbUrl(mediaShare);
break;
case REEL_SHARE:
text = replied.getReelShare().getText();

View file

@ -22,9 +22,9 @@ import awais.instagrabber.repositories.responses.User;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NetworkUtils;
import awais.instagrabber.utils.TextUtils;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentModel>> {
private static final String TAG = "CommentsFetcher";
@ -130,11 +130,11 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
}
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e,
LogCollector.LogFile.ASYNC_COMMENTS_FETCHER,
"getChildComments",
new Pair<>("commentModels.size", commentModels.size()));
// if (logCollector != null)
// logCollector.appendException(e,
// LogCollector.LogFile.ASYNC_COMMENTS_FETCHER,
// "getChildComments",
// new Pair<>("commentModels.size", commentModels.size()));
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
if (fetchListener != null) fetchListener.onFailure(e);
break;
@ -256,9 +256,9 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_COMMENTS_FETCHER, "getParentComments",
new Pair<>("commentModelsList.size", commentModels.size()));
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_COMMENTS_FETCHER, "getParentComments",
// new Pair<>("commentModelsList.size", commentModels.size()));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
if (fetchListener != null) fetchListener.onFailure(e);
return null;

View file

@ -20,9 +20,9 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NetworkUtils;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public final class HashtagFetcher extends AsyncTask<Void, Void, HashtagModel> {
private static final String TAG = "HashtagFetcher";
@ -86,8 +86,8 @@ public final class HashtagFetcher extends AsyncTask<Void, Void, HashtagModel> {
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_HASHTAG_FETCHER, "doInBackground");
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_HASHTAG_FETCHER, "doInBackground");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
if (fetchListener != null) fetchListener.onFailure(e);
}

View file

@ -16,9 +16,9 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NetworkUtils;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel> {
private static final String TAG = "LocationFetcher";
@ -65,8 +65,8 @@ public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel>
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_LOCATION_FETCHER, "doInBackground");
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_LOCATION_FETCHER, "doInBackground");
if (BuildConfig.DEBUG) {
Log.e(TAG, "", e);
}

View file

@ -12,9 +12,9 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.utils.NetworkUtils;
import awais.instagrabber.utils.ResponseBodyUtils;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public final class PostFetcher extends AsyncTask<Void, Void, Media> {
private static final String TAG = "PostFetcher";
@ -136,9 +136,9 @@ public final class PostFetcher extends AsyncTask<Void, Void, Media> {
return ResponseBodyUtils.parseGraphQLItem(media);
}
} catch (Exception e) {
if (logCollector != null) {
logCollector.appendException(e, LogCollector.LogFile.ASYNC_POST_FETCHER, "doInBackground");
}
// if (logCollector != null) {
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_POST_FETCHER, "doInBackground");
// }
Log.e(TAG, "Error fetching post", e);
} finally {
if (conn != null) {

View file

@ -18,13 +18,16 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, Void> {
private final GraphQLService graphQLService;
private final FetchListener<User> fetchListener;
private final long myId;
private final boolean isLoggedIn;
private final String userName;
public ProfileFetcher(final String userName,
final long myId,
final boolean isLoggedIn,
final FetchListener<User> fetchListener) {
this.userName = userName;
this.myId = myId;
this.isLoggedIn = isLoggedIn;
this.fetchListener = fetchListener;
userService = isLoggedIn ? UserService.getInstance() : null;
@ -34,7 +37,7 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, Void> {
@Nullable
@Override
protected Void doInBackground(final Void... voids) {
if (isLoggedIn) {
if (isLoggedIn && userName != null) {
userService.getUsernameInfo(userName, new ServiceCallback<User>() {
@Override
public void onSuccess(final User user) {
@ -60,6 +63,20 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, Void> {
}
});
}
else if (isLoggedIn) {
userService.getUserInfo(myId, new ServiceCallback<User>() {
@Override
public void onSuccess(final User user) {
fetchListener.onResult(user);
}
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "Error", t);
fetchListener.onFailure(t);
}
});
}
else {
graphQLService.fetchUser(userName, new ServiceCallback<User>() {
@Override

View file

@ -1,55 +0,0 @@
package awais.instagrabber.asyncs;
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.Nullable;
import org.json.JSONObject;
import java.net.HttpURLConnection;
import java.net.URL;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NetworkUtils;
import awais.instagrabber.utils.Utils;
public final class UsernameFetcher extends AsyncTask<Void, Void, String> {
private final FetchListener<String> fetchListener;
private final long uid;
public UsernameFetcher(final long uid, final FetchListener<String> fetchListener) {
this.uid = uid;
this.fetchListener = fetchListener;
}
@Nullable
@Override
protected String doInBackground(final Void... voids) {
String result = null;
try {
final HttpURLConnection conn = (HttpURLConnection) new URL("https://i.instagram.com/api/v1/users/" + uid + "/info/").openConnection();
conn.setRequestProperty("User-Agent", Utils.settingsHelper.getString(Constants.BROWSER_UA));
conn.setUseCaches(true);
final JSONObject user;
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK &&
(user = new JSONObject(NetworkUtils.readFromConnection(conn)).optJSONObject(Constants.EXTRAS_USER)) != null)
result = user.getString(Constants.EXTRAS_USERNAME);
conn.disconnect();
} catch (final Exception e) {
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return result;
}
@Override
protected void onPostExecute(final String result) {
if (fetchListener != null) fetchListener.onResult(result);
}
}

View file

@ -70,11 +70,11 @@ import awais.instagrabber.utils.Utils;
import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.StoriesService;
import awais.instagrabber.webservices.TagsService;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
@ -607,8 +607,8 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
try {
currentlyExecuting.cancel(true);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
Log.e(TAG, "", e);
}
}

View file

@ -69,12 +69,12 @@ import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.StoriesService;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
@ -586,8 +586,8 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
try {
currentlyExecuting.cancel(true);
} catch (final Exception e) {
if (logCollector != null) logCollector.appendException(
e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
// if (logCollector != null) logCollector.appendException(
// e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
Log.e(TAG, "", e);
}
}

View file

@ -103,17 +103,24 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
model.getArgs().getUsername()));
NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action);
} else {
final AlertDialog alertDialog = new AlertDialog.Builder(context)
.setCancelable(false)
.setView(R.layout.dialog_opening_post)
.create();
alertDialog.show();
mediaService.fetch(mediaId, new ServiceCallback<Media>() {
@Override
public void onSuccess(final Media feedModel) {
final PostViewV2Fragment fragment = PostViewV2Fragment
.builder(feedModel)
.build();
fragment.setOnShowListener(dialog -> alertDialog.dismiss());
fragment.show(getChildFragmentManager(), "post_view");
}
@Override
public void onFailure(final Throwable t) {
alertDialog.dismiss();
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
}
});

View file

@ -647,7 +647,6 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
navController.navigate(R.id.action_global_likesViewerFragment, bundle);
return true;
}
Utils.displayToastAboveView(context, v, getString(R.string.like_without_count));
return true;
});
}

View file

@ -4,6 +4,9 @@ import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
@ -12,6 +15,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
@ -51,8 +55,9 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
private ArchivesViewModel archivesViewModel;
private StoriesService storiesService;
private Context context;
private String type, endCursor = null;
private String type, currentQuery, endCursor = null;
private FeedStoriesListAdapter adapter;
private MenuItem menuSearch;
private final OnFeedStoryClickListener clickListener = new OnFeedStoryClickListener() {
@Override
@ -119,6 +124,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
fragmentActivity = (AppCompatActivity) requireActivity();
context = getContext();
if (context == null) return;
setHasOptionsMenu(true);
storiesService = StoriesService.getInstance(null, 0L, null);
}
@ -141,6 +147,30 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
shouldRefresh = false;
}
@Override
public void onCreateOptionsMenu(@NonNull final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.search, menu);
menuSearch = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) menuSearch.getActionView();
searchView.setQueryHint(getResources().getString(R.string.action_search));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(final String query) {
return false;
}
@Override
public boolean onQueryTextChange(final String query) {
if (adapter != null) {
currentQuery = query;
adapter.getFilter().filter(query);
}
return true;
}
});
}
@Override
public void onResume() {
super.onResume();

View file

@ -87,6 +87,7 @@ import awais.instagrabber.models.stickers.SwipeUpModel;
import awais.instagrabber.repositories.requests.StoryViewerOptions;
import awais.instagrabber.repositories.requests.StoryViewerOptions.Type;
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions;
import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.StoryStickerResponse;
import awais.instagrabber.repositories.responses.directmessages.DirectThreadBroadcastResponse;
import awais.instagrabber.utils.Constants;
@ -99,9 +100,10 @@ import awais.instagrabber.viewmodels.FeedStoriesViewModel;
import awais.instagrabber.viewmodels.HighlightsViewModel;
import awais.instagrabber.viewmodels.StoriesViewModel;
import awais.instagrabber.webservices.DirectMessagesService;
import awais.instagrabber.webservices.MediaService;
import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.StoriesService;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@ -109,7 +111,7 @@ import retrofit2.Response;
import static awais.instagrabber.customviews.helpers.SwipeGestureListener.SWIPE_THRESHOLD;
import static awais.instagrabber.customviews.helpers.SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD;
import static awais.instagrabber.utils.Constants.MARK_AS_SEEN;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class StoryViewerFragment extends Fragment {
@ -123,6 +125,7 @@ public class StoryViewerFragment extends Fragment {
private SwipeEvent swipeEvent;
private GestureDetectorCompat gestureDetector;
private StoriesService storiesService;
private MediaService mediaService;
private StoryModel currentStory;
private int slidePos;
private int lastSlidePos;
@ -161,6 +164,7 @@ public class StoryViewerFragment extends Fragment {
final String deviceId = settingsHelper.getString(Constants.DEVICE_UUID);
fragmentActivity = (AppCompatActivity) requireActivity();
storiesService = StoriesService.getInstance(csrfToken, userIdFromCookie, deviceId);
mediaService = MediaService.getInstance(null, null, 0);
directMessagesService = DirectMessagesService.getInstance(csrfToken, userIdFromCookie, deviceId);
setHasOptionsMenu(true);
}
@ -396,10 +400,10 @@ public class StoryViewerFragment extends Fragment {
return true;
}
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ACTIVITY_STORY_VIEWER, "setupListeners",
new Pair<>("swipeEvent", swipeEvent),
new Pair<>("diffX", diffX));
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ACTIVITY_STORY_VIEWER, "setupListeners",
// new Pair<>("swipeEvent", swipeEvent),
// new Pair<>("diffX", diffX));
if (BuildConfig.DEBUG) Log.e(TAG, "Error", e);
}
return false;
@ -422,35 +426,40 @@ public class StoryViewerFragment extends Fragment {
binding.spotify.setOnClickListener(v -> {
final Object tag = v.getTag();
if (tag instanceof CharSequence) {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(tag.toString()));
startActivity(intent);
Utils.openURL(context, tag.toString());
}
});
binding.swipeUp.setOnClickListener(v -> {
final Object tag = v.getTag();
if (tag instanceof CharSequence) {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(tag.toString()));
startActivity(intent);
Utils.openURL(context, tag.toString());
}
});
binding.viewStoryPost.setOnClickListener(v -> {
final Object tag = v.getTag();
if (!(tag instanceof CharSequence)) return;
final String shortCode = tag.toString();
final String mediaId = tag.toString();
final AlertDialog alertDialog = new AlertDialog.Builder(context)
.setCancelable(false)
.setView(R.layout.dialog_opening_post)
.create();
alertDialog.show();
new PostFetcher(shortCode, feedModel -> {
final PostViewV2Fragment fragment = PostViewV2Fragment
.builder(feedModel)
.build();
fragment.setOnShowListener(dialog -> alertDialog.dismiss());
fragment.show(getChildFragmentManager(), "post_view");
}).execute();
mediaService.fetch(Long.valueOf(mediaId), new ServiceCallback<Media>() {
@Override
public void onSuccess(final Media feedModel) {
final PostViewV2Fragment fragment = PostViewV2Fragment
.builder(feedModel)
.build();
fragment.setOnShowListener(dialog -> alertDialog.dismiss());
fragment.show(getChildFragmentManager(), "post_view");
}
@Override
public void onFailure(final Throwable t) {
alertDialog.dismiss();
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
}
});
});
final View.OnClickListener storyActionListener = v -> {
final Object tag = v.getTag();
@ -684,47 +693,45 @@ public class StoryViewerFragment extends Fragment {
String currentStoryMediaId = null;
final Type type = options.getType();
StoryViewerOptions fetchOptions = null;
if (currentFeedStoryIndex >= 0) {
switch (type) {
case HIGHLIGHT: {
final HighlightsViewModel highlightsViewModel = (HighlightsViewModel) viewModel;
final List<HighlightModel> models = highlightsViewModel.getList().getValue();
if (models == null || models.isEmpty() || currentFeedStoryIndex >= models.size()) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
final HighlightModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getId();
fetchOptions = StoryViewerOptions.forHighlight(model.getId());
currentStoryUsername = model.getTitle();
break;
switch (type) {
case HIGHLIGHT: {
final HighlightsViewModel highlightsViewModel = (HighlightsViewModel) viewModel;
final List<HighlightModel> models = highlightsViewModel.getList().getValue();
if (models == null || models.isEmpty() || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
case FEED_STORY_POSITION: {
final FeedStoriesViewModel feedStoriesViewModel = (FeedStoriesViewModel) viewModel;
final List<FeedStoryModel> models = feedStoriesViewModel.getList().getValue();
if (models == null) return;
final FeedStoryModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getStoryMediaId();
currentStoryUsername = model.getProfileModel().getUsername();
fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername);
if (model.isLive()) {
live = model.getFirstStoryModel();
}
break;
final HighlightModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getId();
fetchOptions = StoryViewerOptions.forHighlight(model.getId());
currentStoryUsername = model.getTitle();
break;
}
case FEED_STORY_POSITION: {
final FeedStoriesViewModel feedStoriesViewModel = (FeedStoriesViewModel) viewModel;
final List<FeedStoryModel> models = feedStoriesViewModel.getList().getValue();
if (models == null || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0) return;
final FeedStoryModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getStoryMediaId();
currentStoryUsername = model.getProfileModel().getUsername();
fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername);
if (model.isLive()) {
live = model.getFirstStoryModel();
}
case STORY_ARCHIVE: {
final ArchivesViewModel archivesViewModel = (ArchivesViewModel) viewModel;
final List<HighlightModel> models = archivesViewModel.getList().getValue();
if (models == null || models.isEmpty() || currentFeedStoryIndex >= models.size()) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
final HighlightModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getId();
currentStoryUsername = model.getTitle();
fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername);
break;
break;
}
case STORY_ARCHIVE: {
final ArchivesViewModel archivesViewModel = (ArchivesViewModel) viewModel;
final List<HighlightModel> models = archivesViewModel.getList().getValue();
if (models == null || models.isEmpty() || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
final HighlightModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getId();
currentStoryUsername = model.getTitle();
fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername);
break;
}
}
if (type == Type.USER) {
@ -885,7 +892,11 @@ public class StoryViewerFragment extends Fragment {
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
if (actionBar != null) {
actionBar.setSubtitle(Utils.datetimeParser.format(new Date(currentStory.getTimestamp() * 1000L)));
try {
actionBar.setSubtitle(Utils.datetimeParser.format(new Date(currentStory.getTimestamp() * 1000L)));
} catch (Exception e) {
Log.e(TAG, "refreshStory: ", e);
}
}
if (settingsHelper.getBoolean(MARK_AS_SEEN))

View file

@ -59,7 +59,6 @@ import awais.instagrabber.adapters.HighlightsAdapter;
import awais.instagrabber.asyncs.CreateThreadAction;
import awais.instagrabber.asyncs.ProfileFetcher;
import awais.instagrabber.asyncs.ProfilePostFetchService;
import awais.instagrabber.asyncs.UsernameFetcher;
import awais.instagrabber.customviews.PrimaryActionModeCallback;
import awais.instagrabber.customviews.PrimaryActionModeCallback.CallbacksHelper;
import awais.instagrabber.databinding.FragmentProfileBinding;
@ -125,11 +124,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
private HighlightsViewModel highlightsViewModel;
private MenuItem blockMenuItem, restrictMenuItem, chainingMenuItem;
private MenuItem muteStoriesMenuItem, mutePostsMenuItem;
private boolean highlightsFetching;
private boolean accountIsUpdated = false;
private boolean postsSetupDone = false;
private Set<Media> selectedFeedModels;
private Media downloadFeedModel;
private int downloadChildPosition = -1;
private long myId;
private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_PROFILE_POSTS_LAYOUT);
private final Runnable usernameSettingRunnable = () -> {
@ -303,11 +303,11 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
super.onCreate(savedInstanceState);
cookie = Utils.settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
final long userId = CookieUtils.getUserIdFromCookie(cookie);
myId = CookieUtils.getUserIdFromCookie(cookie);
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
fragmentActivity = (MainActivity) requireActivity();
friendshipService = isLoggedIn ? FriendshipService.getInstance(deviceUuid, csrfToken, userId) : null;
friendshipService = isLoggedIn ? FriendshipService.getInstance(deviceUuid, csrfToken, myId) : null;
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
mediaService = isLoggedIn ? MediaService.getInstance(null, null, 0) : null;
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
@ -363,9 +363,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
inflater.inflate(R.menu.profile_menu, menu);
blockMenuItem = menu.findItem(R.id.block);
final boolean isNotMe = profileModel != null && !Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie));
if (blockMenuItem != null) {
if (profileModel != null) {
blockMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
if (isNotMe) {
blockMenuItem.setVisible(true);
blockMenuItem.setTitle(profileModel.getFriendshipStatus().isBlocking() ? R.string.unblock : R.string.block);
} else {
blockMenuItem.setVisible(false);
@ -373,8 +374,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
restrictMenuItem = menu.findItem(R.id.restrict);
if (restrictMenuItem != null) {
if (profileModel != null) {
restrictMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
if (isNotMe) {
restrictMenuItem.setVisible(true);
restrictMenuItem.setTitle(profileModel.getFriendshipStatus().isRestricted() ? R.string.unrestrict : R.string.restrict);
} else {
restrictMenuItem.setVisible(false);
@ -382,8 +383,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
muteStoriesMenuItem = menu.findItem(R.id.mute_stories);
if (muteStoriesMenuItem != null) {
if (profileModel != null) {
muteStoriesMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
if (isNotMe) {
muteStoriesMenuItem.setVisible(true);
muteStoriesMenuItem.setTitle(profileModel.getFriendshipStatus().isMutingReel() ? R.string.mute_stories : R.string.unmute_stories);
} else {
muteStoriesMenuItem.setVisible(false);
@ -391,8 +392,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
mutePostsMenuItem = menu.findItem(R.id.mute_posts);
if (mutePostsMenuItem != null) {
if (profileModel != null) {
mutePostsMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
if (isNotMe) {
mutePostsMenuItem.setVisible(true);
mutePostsMenuItem.setTitle(profileModel.getFriendshipStatus().isMuting() ? R.string.mute_posts : R.string.unmute_posts);
} else {
mutePostsMenuItem.setVisible(false);
@ -400,11 +401,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
chainingMenuItem = menu.findItem(R.id.chaining);
if (chainingMenuItem != null) {
if (profileModel != null) {
chainingMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
} else {
chainingMenuItem.setVisible(false);
}
chainingMenuItem.setVisible(isNotMe);
}
}
@ -588,49 +585,20 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
binding.swipeRefreshLayout.setEnabled(true);
setupHighlights();
setupCommonListeners();
fetchUsername();
}
private void fetchUsername() {
final long uid = CookieUtils.getUserIdFromCookie(cookie);
if (TextUtils.isEmpty(username) && uid > 0) {
final FetchListener<String> fetchListener = username -> {
if (TextUtils.isEmpty(username)) return;
this.username = username;
setUsernameDelayed();
fetchProfileDetails();
};
accountRepository.getAccount(uid, new RepositoryCallback<Account>() {
@Override
public void onSuccess(final Account account) {
boolean found = false;
if (account != null) {
final String username = account.getUsername();
if (!TextUtils.isEmpty(username)) {
found = true;
fetchListener.onResult("@" + username);
}
}
if (!found) {
// if not in database, fetch info from instagram
new UsernameFetcher(uid, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@Override
public void onDataNotAvailable() {}
});
return;
}
fetchProfileDetails();
}
private void fetchProfileDetails() {
if (TextUtils.isEmpty(username)) return;
new ProfileFetcher(username.trim().substring(1), isLoggedIn, new FetchListener<User>() {
accountIsUpdated = false;
new ProfileFetcher(TextUtils.isEmpty(username) ? null : username.trim().substring(1),
myId, isLoggedIn, new FetchListener<User>() {
@Override
public void onResult(final User user) {
if (getContext() == null) return;
if (TextUtils.isEmpty(username)) {
username = user.getUsername();
setUsernameDelayed();
}
profileModel = user;
setProfileDetails();
}
@ -665,11 +633,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
profileDetailsBinding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
final long profileId = profileModel.getPk();
final long myId = CookieUtils.getUserIdFromCookie(cookie);
if (isLoggedIn) {
fetchStoryAndHighlights(profileId);
}
setupButtons(profileId, myId);
setupButtons(profileId);
profileDetailsBinding.favChip.setVisibility(View.VISIBLE);
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
favoriteRepository.getFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback<Favorite>() {
@ -895,13 +862,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
profileDetailsBinding.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
profileDetailsBinding.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
}
binding.swipeRefreshLayout.setRefreshing(true);
binding.postsRecyclerView.setVisibility(View.VISIBLE);
fetchPosts();
} else {
profileDetailsBinding.mainFollowers.setClickable(false);
profileDetailsBinding.mainFollowing.setClickable(false);
binding.swipeRefreshLayout.setRefreshing(false);
// error
binding.privatePage1.setImageResource(R.drawable.lock);
binding.privatePage2.setText(R.string.priv_acc);
@ -910,7 +874,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
}
private void setupButtons(final long profileId, final long myId) {
private void setupButtons(final long profileId) {
profileDetailsBinding.btnTagged.setVisibility(isReallyPrivate() ? View.GONE : View.VISIBLE);
if (isLoggedIn) {
if (Objects.equals(profileId, myId)) {
@ -919,6 +883,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
profileDetailsBinding.btnLiked.setVisibility(View.VISIBLE);
profileDetailsBinding.btnDM.setVisibility(View.GONE);
profileDetailsBinding.btnSaved.setText(R.string.saved);
if (!accountIsUpdated) updateAccountInfo();
return;
}
profileDetailsBinding.btnSaved.setVisibility(View.GONE);
@ -973,6 +938,26 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
}
private void updateAccountInfo() {
accountRepository.insertOrUpdateAccount(
profileModel.getPk(),
profileModel.getUsername(),
cookie,
profileModel.getFullName(),
profileModel.getProfilePicUrl(),
new RepositoryCallback<Account>() {
@Override
public void onSuccess(final Account result) {
accountIsUpdated = true;
}
@Override
public void onDataNotAvailable() {
Log.e(TAG, "onDataNotAvailable: insert failed");
}
});
}
private void fetchStoryAndHighlights(final long profileId) {
storiesService.getUserStory(
StoryViewerOptions.forUser(profileId, profileModel.getFullName()),
@ -994,7 +979,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
new ServiceCallback<List<HighlightModel>>() {
@Override
public void onSuccess(final List<HighlightModel> result) {
highlightsFetching = false;
if (result != null) {
profileDetailsBinding.highlightsList.setVisibility(View.VISIBLE);
highlightsViewModel.getList().postValue(result);
@ -1166,7 +1150,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
private void updateSwipeRefreshState() {
binding.swipeRefreshLayout.setRefreshing(binding.postsRecyclerView.isFetching() || highlightsFetching);
Log.d("austin_debug", "usrs: "+binding.postsRecyclerView.isFetching());
binding.swipeRefreshLayout.setRefreshing(binding.postsRecyclerView.isFetching());
}
private void setupHighlights() {
@ -1185,14 +1170,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
highlightsViewModel.getList().observe(getViewLifecycleOwner(), highlightModels -> highlightsAdapter.submitList(highlightModels));
}
private void fetchPosts() {
// stopCurrentExecutor();
binding.swipeRefreshLayout.setRefreshing(true);
// currentlyExecuting = new PostsFetcher(profileModel.getId(), PostItemType.MAIN, endCursor, postsFetchListener)
// .setUsername(profileModel.getUsername())
// .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void navigateToProfile(final String username) {
final NavController navController = NavHostFragment.findNavController(this);
final Bundle bundle = new Bundle();
@ -1211,8 +1188,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
private boolean isReallyPrivate() {
final long myId = CookieUtils.getUserIdFromCookie(cookie);
if (profileModel.getPk() == myId) return false;
final FriendshipStatus friendshipStatus = profileModel.getFriendshipStatus();
return !friendshipStatus.isFollowing() && (profileModel.getPk() != myId) && profileModel.isPrivate();
return !friendshipStatus.isFollowing() && profileModel.isPrivate();
}
}

View file

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@ -36,15 +37,56 @@ public class AboutFragment extends BasePreferencesFragment {
final PreferenceCategory thirdPartyCategory = new PreferenceCategory(context);
screen.addPreference(thirdPartyCategory);
thirdPartyCategory.setTitle(R.string.about_category_3pt);
//thirdPartyCategory.setSummary(R.string.about_category_3pt_summary);
thirdPartyCategory.setIconSpaceReserved(false);
// alphabetical order!!!
thirdPartyCategory.addPreference(getACIPreference());
thirdPartyCategory.addPreference(getAutolinkPreference());
thirdPartyCategory.addPreference(getExoPlayerPreference());
thirdPartyCategory.addPreference(getFrescoPreference());
thirdPartyCategory.addPreference(getMDIPreference());
thirdPartyCategory.addPreference(getRetrofitPreference());
thirdPartyCategory.addPreference(get3ptPreference(
context,
"Apache Commons Imaging",
"Copyright 2007-2020 The Apache Software Foundation. Apache 2.0. This product includes software developed at The Apache Software Foundation (http://www.apache.org/).",
"https://commons.apache.org/proper/commons-imaging/"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"AutoLinkTextViewV2",
"Copyright (C) 2019 Arman Chatikyan. Apache 2.0.",
"https://github.com/armcha/AutoLinkTextViewV2"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"ExoPlayer",
"Copyright (C) 2016 The Android Open Source Project. Apache 2.0.",
"https://exoplayer.dev"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"Fresco",
"Copyright (c) Facebook, Inc. and its affiliates. MIT License.",
"https://frescolib.org"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"GPUImage",
"Copyright 2018 CyberAgent, Inc. Apache 2.0.",
"https://github.com/cats-oss/android-gpuimage"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"Material Design Icons",
"Copyright (C) 2014 Austin Andrews & Google LLC. Apache 2.0.",
"https://materialdesignicons.com"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"Retrofit",
"Copyright 2013 Square, Inc. Apache 2.0.",
"https://square.github.io/retrofit/"
));
thirdPartyCategory.addPreference(get3ptPreference(
context,
"uCrop",
"Copyright 2017 Yalantis. Apache 2.0.",
"https://github.com/Yalantis/uCrop"
));
}
private Preference getDocsPreference() {
@ -97,102 +139,6 @@ public class AboutFragment extends BasePreferencesFragment {
return preference;
}
private Preference getRetrofitPreference() {
final Context context = getContext();
if (context == null) return null;
final Preference preference = new Preference(context);
preference.setTitle("Retrofit");
preference.setSummary("Copyright 2013 Square, Inc. Apache 2.0.");
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://square.github.io/retrofit/"));
startActivity(intent);
return true;
});
return preference;
}
private Preference getFrescoPreference() {
final Context context = getContext();
if (context == null) return null;
final Preference preference = new Preference(context);
preference.setTitle("Fresco");
preference.setSummary("Copyright (c) Facebook, Inc. and its affiliates. MIT License.");
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://frescolib.org/"));
startActivity(intent);
return true;
});
return preference;
}
private Preference getExoPlayerPreference() {
final Context context = getContext();
if (context == null) return null;
final Preference preference = new Preference(context);
preference.setTitle("ExoPlayer");
preference.setSummary("Copyright (C) 2016 The Android Open Source Project. Apache 2.0.");
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://exoplayer.dev/"));
startActivity(intent);
return true;
});
return preference;
}
private Preference getMDIPreference() {
final Context context = getContext();
if (context == null) return null;
final Preference preference = new Preference(context);
preference.setTitle("Material Design Icons");
preference.setSummary("Copyright (C) 2014 Austin Andrews & Google LLC. Apache 2.0.");
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://materialdesignicons.com/"));
startActivity(intent);
return true;
});
return preference;
}
private Preference getAutolinkPreference() {
final Context context = getContext();
if (context == null) return null;
final Preference preference = new Preference(context);
preference.setTitle("AutoLinkTextViewV2");
preference.setSummary("Copyright (C) 2019 Arman Chatikyan. Apache 2.0.");
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://github.com/armcha/AutoLinkTextViewV2"));
startActivity(intent);
return true;
});
return preference;
}
private Preference getACIPreference() {
final Context context = getContext();
if (context == null) return null;
final Preference preference = new Preference(context);
preference.setTitle("Apache Commons Imaging");
preference.setSummary("Copyright 2007-2020 The Apache Software Foundation. Apache 2.0.");
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://commons.apache.org/proper/commons-imaging/"));
startActivity(intent);
return true;
});
return preference;
}
private Preference getLicensePreference() {
final Context context = getContext();
if (context == null) return null;
@ -214,4 +160,21 @@ public class AboutFragment extends BasePreferencesFragment {
preference.setIconSpaceReserved(true);
return preference;
}
private Preference get3ptPreference(@NonNull final Context context,
final String title,
final String summary,
final String url) {
final Preference preference = new Preference(context);
preference.setTitle(title);
preference.setSummary(summary);
preference.setIconSpaceReserved(false);
preference.setOnPreferenceClickListener(p -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
});
return preference;
}
}

View file

@ -28,6 +28,7 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment {
screen.addPreference(getDefaultTabPreference(context));
}
screen.addPreference(getUpdateCheckPreference(context));
screen.addPreference(getFlagSecurePreference(context));
}
private Preference getDefaultTabPreference(@NonNull final Context context) {
@ -58,4 +59,17 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment {
preference.setIconSpaceReserved(false);
return preference;
}
private Preference getFlagSecurePreference(@NonNull final Context context) {
return PreferenceHelper.getSwitchPreference(
context,
Constants.FLAG_SECURE,
R.string.flag_secure,
-1,
false,
(preference, newValue) -> {
shouldRecreate();
return true;
});
}
}

View file

@ -16,6 +16,7 @@ public final class FeedStoryModel implements Serializable {
private final boolean isLive, isBestie;
private final long timestamp;
private final int mediaCount;
private boolean isShown = true;
public FeedStoryModel(final String storyMediaId, final User profileModel, final boolean fullyRead,
final long timestamp, final StoryModel firstStoryModel, final int mediaCount,
@ -74,4 +75,12 @@ public final class FeedStoryModel implements Serializable {
public boolean isBestie() {
return isBestie;
}
public boolean isShown() {
return isShown;
}
public void setShown(final boolean shown) {
isShown = shown;
}
}

View file

@ -30,6 +30,7 @@ public final class Constants {
// deprecated: public static final String AMOLED_THEME = "amoled_theme";
public static final String CHECK_ACTIVITY = "check_activity";
public static final String CHECK_UPDATES = "check_updates";
public static final String FLAG_SECURE = "flag_secure";
// never Export
public static final String COOKIE = "cookie";
public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg";

View file

@ -21,7 +21,7 @@ import awais.instagrabber.BuildConfig;
import awais.instagrabber.db.datasources.AccountDataSource;
import awais.instagrabber.db.repositories.AccountRepository;
import awais.instagrabber.db.repositories.RepositoryCallback;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
public final class CookieUtils {
private static final String TAG = CookieUtils.class.getSimpleName();
@ -52,8 +52,8 @@ public final class CookieUtils {
cookieStore.add(uri3, httpCookie);
}
} catch (final URISyntaxException e) {
if (Utils.logCollector != null)
Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "setupCookies");
// if (Utils.logCollector != null)
// Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "setupCookies");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
}

View file

@ -41,9 +41,9 @@ import awais.instagrabber.db.repositories.RepositoryCallback;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.enums.FavoriteType;
import awais.instagrabber.utils.PasswordUtils.IncorrectPasswordException;
import awaisomereport.LogCollector.LogFile;
//import awaisomereport.LogCollector.LogFile;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public final class ExportImportUtils {
@ -80,8 +80,8 @@ public final class ExportImportUtils {
throw e;
} catch (final Exception e) {
if (fetchListener != null) fetchListener.onResult(false);
if (logCollector != null)
logCollector.appendException(e, LogFile.UTILS_IMPORT, "Import::pass");
// if (logCollector != null)
// logCollector.appendException(e, LogFile.UTILS_IMPORT, "Import::pass");
if (BuildConfig.DEBUG) Log.e(TAG, "Error importing backup", e);
}
} else if (configType == 'Z') {
@ -99,7 +99,7 @@ public final class ExportImportUtils {
throw e;
} catch (final Exception e) {
if (fetchListener != null) fetchListener.onResult(false);
if (logCollector != null) logCollector.appendException(e, LogFile.UTILS_IMPORT, "Import");
// if (logCollector != null) logCollector.appendException(e, LogFile.UTILS_IMPORT, "Import");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
}
@ -122,7 +122,7 @@ public final class ExportImportUtils {
if (fetchListener != null) fetchListener.onResult(true);
} catch (final Exception e) {
if (fetchListener != null) fetchListener.onResult(false);
if (logCollector != null) logCollector.appendException(e, LogFile.UTILS_IMPORT, "importJson");
// if (logCollector != null) logCollector.appendException(e, LogFile.UTILS_IMPORT, "importJson");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
}
@ -241,8 +241,8 @@ public final class ExportImportUtils {
exportBytes = PasswordUtils.enc(exportString, bytes);
} catch (final Exception e) {
if (fetchListener != null) fetchListener.onResult(false);
if (logCollector != null)
logCollector.appendException(e, LogFile.UTILS_EXPORT, "Export::isPass");
// if (logCollector != null)
// logCollector.appendException(e, LogFile.UTILS_EXPORT, "Export::isPass");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
} else {
@ -255,8 +255,8 @@ public final class ExportImportUtils {
if (fetchListener != null) fetchListener.onResult(true);
} catch (final Exception e) {
if (fetchListener != null) fetchListener.onResult(false);
if (logCollector != null)
logCollector.appendException(e, LogFile.UTILS_EXPORT, "Export::notPass");
// if (logCollector != null)
// logCollector.appendException(e, LogFile.UTILS_EXPORT, "Export::notPass");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
} else if (fetchListener != null) fetchListener.onResult(false);
@ -324,7 +324,7 @@ public final class ExportImportUtils {
}, AppExecutors.getInstance().tasksThread());
return;
} catch (final Exception e) {
if (logCollector != null) logCollector.appendException(e, LogFile.UTILS_EXPORT, "getExportString");
// if (logCollector != null) logCollector.appendException(e, LogFile.UTILS_EXPORT, "getExportString");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
callback.onCreated(null);
@ -373,9 +373,9 @@ public final class ExportImportUtils {
jsonArray.put(jsonObject);
}
} catch (Exception e) {
if (logCollector != null) {
logCollector.appendException(e, LogFile.UTILS_EXPORT, "getFavorites");
}
// if (logCollector != null) {
// logCollector.appendException(e, LogFile.UTILS_EXPORT, "getFavorites");
// }
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error exporting favorites", e);
}
@ -409,9 +409,9 @@ public final class ExportImportUtils {
jsonArray.put(jsonObject);
}
} catch (Exception e) {
if (logCollector != null) {
logCollector.appendException(e, LogFile.UTILS_EXPORT, "getCookies");
}
// if (logCollector != null) {
// logCollector.appendException(e, LogFile.UTILS_EXPORT, "getCookies");
// }
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error exporting accounts", e);
}

View file

@ -13,6 +13,7 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.models.StoryModel;
@ -30,7 +31,7 @@ import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.MediaCandidate;
import awais.instagrabber.repositories.responses.User;
import awais.instagrabber.repositories.responses.VideoVersion;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
public final class ResponseBodyUtils {
private static final String TAG = "ResponseBodyUtils";
@ -75,10 +76,10 @@ public final class ResponseBodyUtils {
if (lastIndexMain >= 0) return sources[lastIndexMain];
else if (lastIndexBase >= 0) return sources[lastIndexBase];
} catch (final Exception e) {
if (Utils.logCollector != null)
Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityPost",
new Pair<>("resourcesNull", resources == null),
new Pair<>("isVideo", isVideo));
// if (Utils.logCollector != null)
// Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityPost",
// new Pair<>("resourcesNull", resources == null),
// new Pair<>("isVideo", isVideo));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return null;
@ -93,9 +94,9 @@ public final class ResponseBodyUtils {
src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, false);
if (src == null) return resources.getString("display_url");
} catch (final Exception e) {
if (Utils.logCollector != null)
Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityImage",
new Pair<>("resourcesNull", resources == null));
// if (Utils.logCollector != null)
// Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityImage",
// new Pair<>("resourcesNull", resources == null));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return src;
@ -986,7 +987,7 @@ public final class ResponseBodyUtils {
model.setVideoUrl(ResponseBodyUtils.getHighQualityPost(videoResources, true, true, false));
if (data.has("story_feed_media")) {
model.setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_code"));
model.setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id"));
}
// TODO: this may not be limited to spotify
@ -1094,29 +1095,24 @@ public final class ResponseBodyUtils {
}
public static String getThumbUrl(final Media media) {
if (media == null) {
return null;
}
final ImageVersions2 imageVersions2 = media.getImageVersions2();
return getThumbUrl(imageVersions2);
}
public static String getThumbUrl(final ImageVersions2 imageVersions2) {
if (imageVersions2 == null) return null;
final List<MediaCandidate> candidates = imageVersions2.getCandidates();
if (candidates == null || candidates.isEmpty()) return null;
final MediaCandidate mediaCandidate = candidates.get(candidates.size() - 1);
if (mediaCandidate == null) return null;
return mediaCandidate.getUrl();
return getImageCandidate(media, CandidateType.THUMBNAIL);
}
public static String getImageUrl(final Media media) {
return getImageCandidate(media, CandidateType.DOWNLOAD);
}
private static String getImageCandidate(final Media media, final CandidateType type) {
if (media == null) return null;
final ImageVersions2 imageVersions2 = media.getImageVersions2();
if (imageVersions2 == null) return null;
final List<MediaCandidate> candidates = imageVersions2.getCandidates();
if (candidates == null || candidates.isEmpty()) return null;
final MediaCandidate candidate = candidates.get(0);
final List<MediaCandidate> sortedCandidates = candidates.stream()
.sorted((c1, c2) -> Integer.compare(c2.getWidth(), c1.getWidth()))
.filter(c -> c.getWidth() < type.getValue())
.collect(Collectors.toList());
final MediaCandidate candidate = sortedCandidates.get(0);
if (candidate == null) return null;
return candidate.getUrl();
}
@ -1133,4 +1129,19 @@ public final class ResponseBodyUtils {
model.setVideoUrl(data.getString("dash_playback_url"));
return model;
}
private enum CandidateType {
THUMBNAIL(1000),
DOWNLOAD(10000);
private final int value;
CandidateType(final int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
}

View file

@ -30,6 +30,7 @@ import static awais.instagrabber.utils.Constants.DEFAULT_TAB;
import static awais.instagrabber.utils.Constants.DEVICE_UUID;
import static awais.instagrabber.utils.Constants.DM_MARK_AS_SEEN;
import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER;
import static awais.instagrabber.utils.Constants.FLAG_SECURE;
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
import static awais.instagrabber.utils.Constants.MARK_AS_SEEN;
@ -139,7 +140,8 @@ public final class SettingsHelper {
@StringDef({DOWNLOAD_USER_FOLDER, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
SHOW_CAPTIONS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, DM_MARK_AS_SEEN, CHECK_ACTIVITY,
CHECK_UPDATES, SWAP_DATE_TIME_FORMAT_ENABLED, PREF_ENABLE_DM_NOTIFICATIONS, PREF_ENABLE_DM_AUTO_REFRESH})
CHECK_UPDATES, SWAP_DATE_TIME_FORMAT_ENABLED, PREF_ENABLE_DM_NOTIFICATIONS, PREF_ENABLE_DM_AUTO_REFRESH,
FLAG_SECURE})
public @interface BooleanSettings {}
@StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER})

View file

@ -75,7 +75,7 @@ public class UserAgentUtils {
@NonNull
public static String generateBrowserUA(final int code) {
return browsers[code - 1];
return browsers[code];
}
@NonNull

View file

@ -56,13 +56,13 @@ import java.util.Map;
import awais.instagrabber.R;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.models.enums.FavoriteType;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
public final class Utils {
private static final String TAG = "Utils";
private static final int VIDEO_CACHE_MAX_BYTES = 10 * 1024 * 1024;
public static LogCollector logCollector;
// public static LogCollector logCollector;
public static SettingsHelper settingsHelper;
public static boolean sessionVolumeFull = false;
public static final MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();

View file

@ -7,7 +7,6 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import awais.instagrabber.asyncs.ProfileFetcher;
import awais.instagrabber.asyncs.UsernameFetcher;
import awais.instagrabber.db.datasources.AccountDataSource;
import awais.instagrabber.db.entities.Account;
import awais.instagrabber.db.repositories.AccountRepository;
@ -28,7 +27,6 @@ public class AppStateViewModel extends AndroidViewModel {
private User currentUser;
private AccountRepository accountRepository;
private String username;
public AppStateViewModel(@NonNull final Application application) {
super(application);
@ -37,52 +35,15 @@ public class AppStateViewModel extends AndroidViewModel {
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
if (!isLoggedIn) return;
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(application));
setCurrentUser();
}
private void setCurrentUser() {
if (!isLoggedIn) return;
final FetchListener<String> usernameListener = username -> {
if (TextUtils.isEmpty(username)) return;
this.username = username;
fetchProfileDetails();
};
fetchUsername(usernameListener);
fetchProfileDetails();
}
public User getCurrentUser() {
return currentUser;
}
private void fetchUsername(final FetchListener<String> usernameListener) {
if (!TextUtils.isEmpty(username)) {
usernameListener.onResult(username);
return;
}
final long uid = CookieUtils.getUserIdFromCookie(cookie);
if (uid <= 0) return;
accountRepository.getAccount(uid, new RepositoryCallback<Account>() {
@Override
public void onSuccess(@NonNull final Account account) {
final String username = account.getUsername();
if (TextUtils.isEmpty(username)) return;
usernameListener.onResult("@" + username);
}
@Override
public void onDataNotAvailable() {
// if not in database, fetch info
new UsernameFetcher(uid, usernameListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
}
private void fetchProfileDetails() {
if (TextUtils.isEmpty(username)) return;
new ProfileFetcher(
username.trim().substring(1),
true,
user -> this.currentUser = user
).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
final long uid = CookieUtils.getUserIdFromCookie(cookie);
new ProfileFetcher(null, uid, true, user -> this.currentUser = user).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View file

@ -279,6 +279,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
}
public void markAsSeen() {
if (currentUser == null) return;
final DirectThread thread = getThread().getValue();
if (thread == null) return;
final List<DirectItem> items = thread.getItems();

View file

@ -52,11 +52,11 @@ import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DownloadUtils;
import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
//import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Constants.DOWNLOAD_CHANNEL_ID;
import static awais.instagrabber.utils.Constants.NOTIF_GROUP_NAME;
import static awais.instagrabber.utils.Utils.logCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public class DownloadWorker extends Worker {
private static final String TAG = "DownloadWorker";
@ -260,8 +260,8 @@ public class DownloadWorker extends Worker {
try (final InputStream inputStream = contentResolver.openInputStream(uri)) {
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_1");
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_1");
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
} else if (mimeType.startsWith("video")) {
@ -277,13 +277,13 @@ public class DownloadWorker extends Worker {
try {
retriever.close();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_2");
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_2");
}
} catch (final Exception e) {
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_3");
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_3");
}
}
}

View file

@ -19,8 +19,8 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
//import java.util.zip.ZipEntry;
//import java.util.zip.ZipOutputStream;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.utils.Utils;
@ -29,7 +29,7 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
private static CrashReporter reporterInstance;
private final Application application;
private final String email;
private final File crashLogsZip;
// private final File crashLogsZip;
private boolean startAttempted = false;
public static CrashReporter get(final Application application) {
@ -40,7 +40,7 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
private CrashReporter(@NonNull final Application application) {
this.application = application;
this.email = "barinsta@austinhuang.me";
this.crashLogsZip = new File(application.getExternalCacheDir(), "crash_logs.zip");
// this.crashLogsZip = new File(application.getExternalCacheDir(), "crash_logs.zip");
}
public void start() {
@ -99,94 +99,88 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
application.startActivity(new Intent(application, ErrorReporterActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
zipLogs();
// zipLogs();
Process.killProcess(Process.myPid());
System.exit(10);
}
public synchronized CrashReporter zipLogs() {
final File logDir = Utils.logCollector != null ? Utils.logCollector.getLogDir() :
new File(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? application.getDataDir() : application.getFilesDir(), "crashlogs");
try (final FileOutputStream fos = new FileOutputStream(crashLogsZip);
final ZipOutputStream zos = new ZipOutputStream(fos)) {
final File[] files = logDir.listFiles();
if (files != null) {
zos.setLevel(5);
byte[] buffer;
for (final File file : files) {
if (file != null && file.length() > 0) {
buffer = new byte[1024];
try (final FileInputStream fis = new FileInputStream(file)) {
zos.putNextEntry(new ZipEntry(file.getName()));
int length;
while ((length = fis.read(buffer)) > 0) zos.write(buffer, 0, length);
zos.closeEntry();
}
}
}
}
} catch (final Exception e) {
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return this;
}
// public synchronized CrashReporter zipLogs() {
// final File logDir = Utils.logCollector != null ? Utils.logCollector.getLogDir() :
// new File(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? application.getDataDir() : application.getFilesDir(), "crashlogs");
//
// try (final FileOutputStream fos = new FileOutputStream(crashLogsZip);
// final ZipOutputStream zos = new ZipOutputStream(fos)) {
//
// final File[] files = logDir.listFiles();
//
// if (files != null) {
// zos.setLevel(5);
// byte[] buffer;
// for (final File file : files) {
// if (file != null && file.length() > 0) {
// buffer = new byte[1024];
// try (final FileInputStream fis = new FileInputStream(file)) {
// zos.putNextEntry(new ZipEntry(file.getName()));
// int length;
// while ((length = fis.read(buffer)) > 0) zos.write(buffer, 0, length);
// zos.closeEntry();
// }
// }
// }
// }
//
// } catch (final Exception e) {
// if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
// }
//
// return this;
// }
@SuppressWarnings("ResultOfMethodCallIgnored")
public void startCrashEmailIntent(final Context context, final boolean sendZipsOnly) {
public void startCrashEmailIntent(final Context context) {
try {
final String filePath = context.getFilesDir().getAbsolutePath();
String[] errorFileList;
if (sendZipsOnly) errorFileList = null;
else {
try {
final File dir = new File(filePath);
if (dir.exists() && !dir.isDirectory()) dir.delete();
dir.mkdir();
errorFileList = dir.list((d, name) -> name.endsWith(".stacktrace"));
} catch (final Exception e) {
errorFileList = null;
}
try {
final File dir = new File(filePath);
if (dir.exists() && !dir.isDirectory()) dir.delete();
dir.mkdir();
errorFileList = dir.list((d, name) -> name.endsWith(".stacktrace"));
} catch (final Exception e) {
errorFileList = null;
}
if ((errorFileList != null && errorFileList.length > 0) || sendZipsOnly) {
if (errorFileList != null && errorFileList.length > 0) {
final StringBuilder errorStringBuilder;
if (sendZipsOnly) errorStringBuilder = new StringBuilder("(Not a crash)\n\n");
else {
errorStringBuilder = new StringBuilder("\r\n\r\n");
final int maxSendMail = 5;
errorStringBuilder = new StringBuilder("\r\n\r\n");
final int maxSendMail = 5;
int curIndex = 0;
for (final String curString : errorFileList) {
final File file = new File(filePath + '/' + curString);
int curIndex = 0;
for (final String curString : errorFileList) {
final File file = new File(filePath + '/' + curString);
if (curIndex++ <= maxSendMail) {
errorStringBuilder.append("New Trace collected:\r\n=====================\r\n");
try (final BufferedReader input = new BufferedReader(new FileReader(file))) {
String line;
while ((line = input.readLine()) != null)
errorStringBuilder.append(line).append("\r\n");
}
if (curIndex++ <= maxSendMail) {
errorStringBuilder.append("New Trace collected:\r\n=====================\r\n");
try (final BufferedReader input = new BufferedReader(new FileReader(file))) {
String line;
while ((line = input.readLine()) != null)
errorStringBuilder.append(line).append("\r\n");
}
file.delete();
}
errorStringBuilder.append("\r\n\r\n");
file.delete();
}
errorStringBuilder.append("\r\n\r\n");
context.startActivity(Intent.createChooser(new Intent(Intent.ACTION_SEND).setType("message/rfc822")
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
.putExtra(Intent.EXTRA_EMAIL, new String[]{email})
.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(application, BuildConfig.APPLICATION_ID + ".provider", crashLogsZip))
// .putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(application, BuildConfig.APPLICATION_ID + ".provider", crashLogsZip))
.putExtra(Intent.EXTRA_SUBJECT, "Barinsta Crash Report")
.putExtra(Intent.EXTRA_TEXT, errorStringBuilder.toString()), "Select an email app to send crash logs"));
}

View file

@ -44,7 +44,7 @@ public final class ErrorReporterActivity extends Activity implements View.OnClic
@Override
public void onClick(@NonNull final View v) {
if (v == btnReport)
CrashReporter.get(getApplication()).startCrashEmailIntent(this, false);
CrashReporter.get(getApplication()).startCrashEmailIntent(this);
finish();
System.exit(10);
}

View file

@ -1,4 +1,4 @@
package awaisomereport;
/*package awaisomereport;
import android.app.Application;
import android.os.Build;
@ -140,4 +140,4 @@ public final class LogCollector {
//noinspection ResultOfMethodCallIgnored
fileOrDirectory.delete();
}
}
}*/