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

Merge branch 'master' into pr/850

This commit is contained in:
Austin Huang 2021-03-26 22:27:47 -04:00
commit dc1119c604
No known key found for this signature in database
GPG key ID: 84C23AA04587A91F
41 changed files with 518 additions and 200 deletions

View file

@ -18,7 +18,6 @@ import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmProfileBinding;
import awais.instagrabber.models.enums.DirectItemType;
import awais.instagrabber.repositories.responses.ImageVersions2;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.User;
@ -97,7 +96,13 @@ public class DirectItemProfileViewHolder extends DirectItemViewHolder {
if (profile == null) return;
binding.profilePic.setImageURI(profile.getProfilePicUrl());
binding.username.setText(profile.getUsername());
binding.fullName.setText(profile.getFullName());
final String fullName = profile.getFullName();
if (!TextUtils.isEmpty(fullName)) {
binding.fullName.setVisibility(View.VISIBLE);
binding.fullName.setText(fullName);
} else {
binding.fullName.setVisibility(View.GONE);
}
binding.isVerified.setVisibility(profile.isVerified() ? View.VISIBLE : View.GONE);
itemView.setOnClickListener(v -> openProfile(profile.getUsername()));
}

View file

@ -1,6 +1,7 @@
package awais.instagrabber.customviews.masoudss_waveform;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
@ -50,8 +51,21 @@ public final class WaveformSeekBar extends View {
public WaveformSeekBar(final Context context, @Nullable final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.waveBackgroundColor = context.getResources().getColor(R.color.white);
this.waveProgressColor = context.getResources().getColor(R.color.blue_800);
final TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.WaveformSeekBar,
0,
0);
final int backgroundColor;
final int progressColor;
try {
backgroundColor = a.getResourceId(R.styleable.WaveformSeekBar_waveformBackgroundColor, R.color.white);
progressColor = a.getResourceId(R.styleable.WaveformSeekBar_waveformProgressColor, R.color.blue_800);
} finally {
a.recycle();
}
this.waveBackgroundColor = context.getResources().getColor(backgroundColor);
this.waveProgressColor = context.getResources().getColor(progressColor);
}
private float getSampleMax() {

View file

@ -292,7 +292,7 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
else if (item.getItemId() == R.id.delete) {
final Context context = getContext();
new AlertDialog.Builder(context)
.setTitle(R.string.edit_collection)
.setTitle(R.string.delete_collection)
.setMessage(R.string.delete_collection_note)
.setPositiveButton(R.string.confirm, (d, w) -> {
collectionService.deleteCollection(

View file

@ -79,7 +79,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
public void onHighlightClick(final HighlightModel model, final int position) {
if (model == null) return;
final NavDirections action = StoryListViewerFragmentDirections
.actionStoryListFragmentToStoryViewerFragment(StoryViewerOptions.forStoryArchive(position));
.actionStoryListFragmentToStoryViewerFragment(StoryViewerOptions.forStoryArchive(model.getId()));
NavHostFragment.findNavController(StoryListViewerFragment.this).navigate(action);
}

View file

@ -65,6 +65,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.R;
@ -304,11 +306,18 @@ public class StoryViewerFragment extends Fragment {
// isNotification = fragmentArgs.getIsNotification();
final Type type = options.getType();
if (currentFeedStoryIndex >= 0) {
viewModel = type == Type.HIGHLIGHT
? type == Type.STORY_ARCHIVE
? new ViewModelProvider(fragmentActivity).get(ArchivesViewModel.class)
: new ViewModelProvider(fragmentActivity).get(HighlightsViewModel.class)
: new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
switch (type) {
case HIGHLIGHT:
viewModel = new ViewModelProvider(fragmentActivity).get(HighlightsViewModel.class);
break;
case STORY_ARCHIVE:
viewModel = new ViewModelProvider(fragmentActivity).get(ArchivesViewModel.class);
break;
default:
case FEED_STORY_POSITION:
viewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
break;
}
}
setupStories();
}
@ -728,9 +737,9 @@ public class StoryViewerFragment extends Fragment {
return;
}
final HighlightModel model = models.get(currentFeedStoryIndex);
currentStoryMediaId = model.getId();
currentStoryMediaId = parseStoryMediaId(model.getId());
currentStoryUsername = model.getTitle();
fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername);
fetchOptions = StoryViewerOptions.forStoryArchive(model.getId());
break;
}
}
@ -1139,4 +1148,20 @@ public class StoryViewerFragment extends Fragment {
resetView();
}
}
/**
* Parses the Story's media ID. For user stories this is a number, but for archive stories
* this is "archiveDay:" plus a number.
*/
private static String parseStoryMediaId(String rawId) {
final String regex = "(?:archiveDay:)?(.+)";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(rawId);
if (matcher.matches() && matcher.groupCount() >= 1) {
return matcher.group(1);
}
return rawId;
}
}

View file

@ -140,6 +140,7 @@ public class DirectMessageSettingsFragment extends Fragment implements ConfirmDi
viewModel.isViewerAdmin().observe(getViewLifecycleOwner(), this::setApprovalRelatedUI);
viewModel.getApprovalRequiredToJoin().observe(getViewLifecycleOwner(), required -> binding.approvalRequired.setChecked(required));
viewModel.getPendingRequests().observe(getViewLifecycleOwner(), this::setPendingRequests);
viewModel.isGroup().observe(getViewLifecycleOwner(), this::setupSettings);
final NavController navController = NavHostFragment.findNavController(this);
final NavBackStackEntry backStackEntry = navController.getCurrentBackStackEntry();
if (backStackEntry != null) {
@ -207,13 +208,11 @@ public class DirectMessageSettingsFragment extends Fragment implements ConfirmDi
}
private void init() {
setupSettings();
// setupSettings();
setupMembers();
}
private void setupSettings() {
Boolean isGroup = viewModel.isGroup().getValue();
if (isGroup == null) isGroup = false;
private void setupSettings(final boolean isGroup) {
binding.groupSettings.setVisibility(isGroup ? View.VISIBLE : View.GONE);
binding.muteMessagesLabel.setOnClickListener(v -> binding.muteMessages.toggle());
binding.muteMessages.setOnCheckedChangeListener((buttonView, isChecked) -> {

View file

@ -1227,7 +1227,10 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
if (!isEmojiPickerShown) {
binding.emojiPicker.setAlpha(0);
}
imm.showSoftInput(binding.input, InputMethodManager.SHOW_IMPLICIT);
final boolean shown = imm.showSoftInput(binding.input, InputMethodManager.SHOW_IMPLICIT);
if (!shown) {
Log.e(TAG, "showKeyboard: System did not display the keyboard");
}
if (!isEmojiPickerShown) {
animatePan(keyboardHeight);
}

View file

@ -592,10 +592,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
binding.swipeRefreshLayout.setEnabled(false);
binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24);
binding.privatePage2.setText(R.string.no_acc);
final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) binding.privatePage.getLayoutParams();
layoutParams.topMargin = 0;
layoutParams.gravity = Gravity.CENTER;
binding.privatePage.setLayoutParams(layoutParams);
binding.privatePage.setVisibility(View.VISIBLE);
return;
}
@ -685,6 +681,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
binding.postsRecyclerView.refresh();
}
profileDetailsBinding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
profileDetailsBinding.isPrivate.setVisibility(profileModel.isPrivate() ? View.VISIBLE : View.GONE);
final long profileId = profileModel.getPk();
if (isLoggedIn) {
fetchStoryAndHighlights(profileId);
@ -919,11 +916,11 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
} else {
profileDetailsBinding.mainFollowers.setClickable(false);
profileDetailsBinding.mainFollowing.setClickable(false);
// error
binding.privatePage1.setImageResource(R.drawable.lock);
binding.privatePage2.setText(R.string.priv_acc);
binding.privatePage.setVisibility(View.VISIBLE);
binding.postsRecyclerView.setVisibility(View.GONE);
binding.swipeRefreshLayout.setRefreshing(false);
}
}
@ -1210,7 +1207,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
private void updateSwipeRefreshState() {
Log.d("austin_debug", "usrs: " + binding.postsRecyclerView.isFetching());
binding.swipeRefreshLayout.setRefreshing(binding.postsRecyclerView.isFetching());
}

View file

@ -179,6 +179,9 @@ public final class ThreadManager {
return null;
}
final DirectInbox inbox = inboxResource.data;
if (inbox == null) {
return null;
}
final List<DirectThread> threads = inbox.getThreads();
if (threads == null || threads.isEmpty()) {
return null;
@ -264,7 +267,10 @@ public final class ThreadManager {
}
private List<User> getUsersWithCurrentUser(final DirectThread t) {
final ImmutableList.Builder<User> builder = ImmutableList.<User>builder().add(currentUser);
final ImmutableList.Builder<User> builder = ImmutableList.builder();
if (currentUser != null) {
builder.add(currentUser);
}
final List<User> users = t.getUsers();
if (users != null) {
builder.addAll(users);

View file

@ -57,8 +57,8 @@ public class StoryViewerOptions implements Serializable {
return new StoryViewerOptions(position, Type.FEED_STORY_POSITION);
}
public static StoryViewerOptions forStoryArchive(final int position) {
return new StoryViewerOptions(position, Type.STORY_ARCHIVE);
public static StoryViewerOptions forStoryArchive(final String id) {
return new StoryViewerOptions(id, Type.STORY_ARCHIVE);
}
public long getId() {

View file

@ -44,7 +44,7 @@ public class DirectItemActionLog implements Serializable {
return Objects.hash(description, bold, textAttributes);
}
public static class TextRange {
public static class TextRange implements Serializable {
private final int start;
private final int end;
private final String color;

View file

@ -1,10 +1,8 @@
package awais.instagrabber.utils;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.util.Log;
import android.webkit.MimeTypeMap;
@ -13,8 +11,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.NetworkType;
@ -90,17 +86,17 @@ public final class DownloadUtils {
return dir;
}
// public static void dmDownload(@NonNull final Context context,
// @Nullable final String username,
// final String modelId,
// final String url) {
// if (url == null) return;
// if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
// dmDownloadImpl(context, username, modelId, url);
// } else if (context instanceof Activity) {
// ActivityCompat.requestPermissions((Activity) context, PERMS, 8020);
// }
// }
// public static void dmDownload(@NonNull final Context context,
// @Nullable final String username,
// final String modelId,
// final String url) {
// if (url == null) return;
// if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
// dmDownloadImpl(context, username, modelId, url);
// } else if (context instanceof Activity) {
// ActivityCompat.requestPermissions((Activity) context, PERMS, 8020);
// }
// }
private static void dmDownloadImpl(@NonNull final Context context,
@Nullable final String username,
@ -294,7 +290,8 @@ public final class DownloadUtils {
final int childPositionIfSingle) {
final Map<String, String> map = new HashMap<>();
for (final Media media : feedModels) {
final File downloadDir = getDownloadDir(context, "@" + media.getUser().getUsername());
final User mediaUser = media.getUser();
final File downloadDir = getDownloadDir(context, mediaUser == null ? "" : "@" + mediaUser.getUsername());
if (downloadDir == null) return;
switch (media.getMediaType()) {
case MEDIA_TYPE_IMAGE:
@ -307,9 +304,8 @@ public final class DownloadUtils {
case MEDIA_TYPE_VOICE: {
final String url = getUrlOfType(media);
String fileName = media.getId();
final User user = media.getUser();
if (user != null) {
fileName = user.getUsername() + "_" + fileName;
if (mediaUser != null) {
fileName = mediaUser.getUsername() + "_" + fileName;
}
final File file = getDownloadSaveFile(downloadDir, fileName, url);
map.put(url, file.getAbsolutePath());

View file

@ -943,8 +943,7 @@ public final class ResponseBodyUtils {
// }
public static StoryModel parseStoryItem(final JSONObject data,
final boolean isLoc,
final boolean isHashtag,
final boolean isLocOrHashtag,
final String username) throws JSONException {
final boolean isVideo = data.has("video_duration");
final StoryModel model = new StoryModel(data.getString("id"),
@ -952,9 +951,7 @@ public final class ResponseBodyUtils {
.getString("url"), null,
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
data.optLong("taken_at", 0),
(isLoc || isHashtag)
? data.getJSONObject("user").getString("username")
: username,
isLocOrHashtag ? data.getJSONObject("user").getString("username") : username,
data.getJSONObject("user").getLong("pk"),
data.optBoolean("can_reply"));

View file

@ -181,6 +181,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
MediaUtils.getVoiceInfo(contentResolver, uri, new MediaUtils.OnInfoLoadListener<MediaUtils.VideoInfo>() {
@Override
public void onLoad(@Nullable final MediaUtils.VideoInfo videoInfo) {
if (videoInfo == null) return;
threadManager.sendVoice(data,
uri,
result.getWaveform(),

View file

@ -95,7 +95,7 @@ public class StoriesService extends BaseService {
}
try {
final JSONObject itemJson = new JSONObject(body).getJSONArray("items").getJSONObject(0);
callback.onSuccess(ResponseBodyUtils.parseStoryItem(itemJson, false, false, null));
callback.onSuccess(ResponseBodyUtils.parseStoryItem(itemJson, false, null));
} catch (JSONException e) {
callback.onFailure(e);
}
@ -187,7 +187,7 @@ public class StoriesService extends BaseService {
final boolean isBestie = node.optBoolean("has_besties_media", false);
StoryModel firstStoryModel = null;
if (itemJson != null) {
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, false, null);
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, null);
}
feedStoryModels.add(new FeedStoryModel(id, user, fullyRead, timestamp, firstStoryModel, mediaCount, false, isBestie));
}
@ -364,9 +364,8 @@ public class StoriesService extends BaseService {
final ServiceCallback<List<StoryModel>> callback) {
final String url = buildUrl(options);
final Call<String> userStoryCall = repository.getUserStory(url);
final boolean isLoc = options.getType() == StoryViewerOptions.Type.LOCATION;
final boolean isHashtag = options.getType() == StoryViewerOptions.Type.HASHTAG;
final boolean isHighlight = options.getType() == StoryViewerOptions.Type.HIGHLIGHT;
final boolean isLocOrHashtag = options.getType() == StoryViewerOptions.Type.LOCATION || options.getType() == StoryViewerOptions.Type.HASHTAG;
final boolean isHighlight = options.getType() == StoryViewerOptions.Type.HIGHLIGHT || options.getType() == StoryViewerOptions.Type.STORY_ARCHIVE;
userStoryCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
@ -380,7 +379,7 @@ public class StoriesService extends BaseService {
data = new JSONObject(body);
if (!isHighlight) {
data = data.optJSONObject((isLoc || isHashtag) ? "story" : "reel");
data = data.optJSONObject((isLocOrHashtag) ? "story" : "reel");
} else {
data = data.getJSONObject("reels").optJSONObject(options.getName());
}
@ -388,8 +387,7 @@ public class StoriesService extends BaseService {
String username = null;
if (data != null
// && localUsername == null
&& !isLoc
&& !isHashtag) {
&& !isLocOrHashtag) {
username = data.getJSONObject("user").getString("username");
}
@ -397,12 +395,11 @@ public class StoriesService extends BaseService {
if (data != null
&& (media = data.optJSONArray("items")) != null
&& media.length() > 0 && media.optJSONObject(0) != null) {
final int mediaLen = media.length();
final List<StoryModel> models = new ArrayList<>();
for (int i = 0; i < mediaLen; ++i) {
data = media.getJSONObject(i);
models.add(ResponseBodyUtils.parseStoryItem(data, isLoc, isHashtag, username));
models.add(ResponseBodyUtils.parseStoryItem(data, isLocOrHashtag, username));
}
callback.onSuccess(models);
} else {
@ -543,6 +540,7 @@ public class StoriesService extends BaseService {
id = String.valueOf(options.getId());
break;
case HIGHLIGHT:
case STORY_ARCHIVE:
builder.append("feed/reels_media/?user_ids=");
id = options.getName();
break;
@ -550,15 +548,12 @@ public class StoriesService extends BaseService {
break;
// case FEED_STORY_POSITION:
// break;
// case STORY_ARCHIVE:
// break;
}
if (id == null) {
return null;
}
final String userId = id.replace(":", "%3A");
builder.append(userId);
if (type != StoryViewerOptions.Type.HIGHLIGHT) {
builder.append(id);
if (type != StoryViewerOptions.Type.HIGHLIGHT && type != StoryViewerOptions.Type.STORY_ARCHIVE) {
builder.append("/story/");
}
return builder.toString();