Merge branch 'master' into support-android-11

This commit is contained in:
Ammar Githam 2021-04-09 20:07:22 +09:00
commit 7e3edf639d
9 changed files with 107 additions and 26 deletions

View File

@ -57,6 +57,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import awais.instagrabber.BuildConfig;
@ -149,9 +150,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
RetrofitFactory.setup(this);
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
final String cookie = settingsHelper.getString(Constants.COOKIE);
CookieUtils.setupCookies(cookie);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != 0;
setupCookie();
if (settingsHelper.getBoolean(Constants.FLAG_SECURE))
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
setContentView(binding.getRoot());
@ -177,7 +176,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
new ViewModelProvider(this).get(AppStateViewModel.class); // Just initiate the App state here
final Intent intent = getIntent();
handleIntent(intent);
if (!TextUtils.isEmpty(cookie) && settingsHelper.getBoolean(Constants.CHECK_ACTIVITY)) {
if (isLoggedIn && settingsHelper.getBoolean(Constants.CHECK_ACTIVITY)) {
bindActivityCheckerService();
}
getSupportFragmentManager().addOnBackStackChangedListener(this);
@ -192,6 +191,26 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
initDmUnreadCount();
}
private void setupCookie() {
final String cookie = settingsHelper.getString(Constants.COOKIE);
long userId = 0;
String csrfToken = null;
if (!TextUtils.isEmpty(cookie)) {
userId = CookieUtils.getUserIdFromCookie(cookie);
csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
}
if (TextUtils.isEmpty(cookie) || userId == 0 || TextUtils.isEmpty(csrfToken)) {
isLoggedIn = false;
return;
}
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID);
if (TextUtils.isEmpty(deviceUuid)) {
settingsHelper.putString(Constants.DEVICE_UUID, UUID.randomUUID().toString());
}
CookieUtils.setupCookies(cookie);
isLoggedIn = true;
}
private void initDmService() {
if (!isLoggedIn) return;
final boolean enabled = settingsHelper.getBoolean(PreferenceKeys.PREF_ENABLE_DM_AUTO_REFRESH);

View File

@ -112,6 +112,7 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
}
public void bind(final int position, final DirectItem item) {
if (item == null) return;
this.item = item;
messageDirection = isSelf(item) ? MessageDirection.OUTGOING : MessageDirection.INCOMING;
// Asynchronous binding causes some weird behaviour
@ -123,7 +124,7 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
setupLongClickListener(position, messageDirection);
}
private void bindBase(final DirectItem item, final MessageDirection messageDirection, final int position) {
private void bindBase(@NonNull final DirectItem item, final MessageDirection messageDirection, final int position) {
final FrameLayout.LayoutParams containerLayoutParams = (FrameLayout.LayoutParams) binding.container.getLayoutParams();
final DirectItemType itemType = item.getItemType();
setMessageDirectionGravity(messageDirection, containerLayoutParams);
@ -188,7 +189,7 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
containerLayoutParams.gravity = Gravity.CENTER;
}
private void setMessageInfo(final DirectItem item, final MessageDirection messageDirection) {
private void setMessageInfo(@NonNull final DirectItem item, final MessageDirection messageDirection) {
if (showMessageInfo()) {
binding.messageInfo.setVisibility(View.VISIBLE);
binding.deliveryStatus.setVisibility(messageDirection == MessageDirection.OUTGOING ? View.VISIBLE : View.GONE);

View File

@ -24,6 +24,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import awais.instagrabber.R;
@ -98,8 +99,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
final Context context = getContext();
Toast.makeText(context, R.string.empty_list, Toast.LENGTH_SHORT).show();
} catch (Exception ignored) {}
}
else {
} else {
endCursor = result.getNextCursor();
final List<HighlightModel> models = archivesViewModel.getList().getValue();
final List<HighlightModel> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
@ -198,7 +198,13 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
adapter = new FeedStoriesListAdapter(clickListener);
binding.rvStories.setLayoutManager(layoutManager);
binding.rvStories.setAdapter(adapter);
feedStoriesViewModel.getList().observe(getViewLifecycleOwner(), adapter::submitList);
feedStoriesViewModel.getList().observe(getViewLifecycleOwner(), list -> {
if (list == null) {
adapter.submitList(Collections.emptyList());
return;
}
adapter.submitList(list);
});
} else {
if (actionBar != null) actionBar.setTitle(R.string.action_archive);
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {

View File

@ -413,10 +413,14 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
case SUCCESS:
Toast.makeText(context, R.string.marked_as_seen, Toast.LENGTH_SHORT).show();
case LOADING:
item.setEnabled(false);
if (item != null) {
item.setEnabled(false);
}
break;
case ERROR:
item.setEnabled(true);
if (item != null) {
item.setEnabled(true);
}
if (resource.message != null) {
Snackbar.make(context, binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show();
return;
@ -955,7 +959,9 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
}
final DirectThread thread = threadLiveData.getValue();
if (thread == null) return;
markAsSeenMenuItem.setEnabled(!DMUtils.isRead(thread));
if (markAsSeenMenuItem != null) {
markAsSeenMenuItem.setEnabled(!DMUtils.isRead(thread));
}
});
if (itemsAdapter == null) return;
itemsAdapter.submitList(items, () -> {

View File

@ -88,13 +88,17 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
public void onSuccess(@NonNull final List<Account> accounts) {
if (!isLoggedIn) {
if (accounts.size() > 0) {
accountCategory.addPreference(getAccountSwitcherPreference(null, context));
final AccountSwitcherPreference preference = getAccountSwitcherPreference(null, context);
if (preference == null) return;
accountCategory.addPreference(preference);
}
// Need to show something to trigger login activity
accountCategory.addPreference(getPreference(R.string.add_account, R.drawable.ic_add, preference -> {
final Preference preference1 = getPreference(R.string.add_account, R.drawable.ic_add, preference -> {
startActivityForResult(new Intent(getContext(), Login.class), Constants.LOGIN_RESULT_CODE);
return true;
}));
});
if (preference1 == null) return;
accountCategory.addPreference(preference1);
}
if (accounts.size() > 0) {
accountCategory

View File

@ -82,8 +82,12 @@ public final class InboxManager {
final long userId = CookieUtils.getUserIdFromCookie(cookie);
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID);
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
if (TextUtils.isEmpty(csrfToken) || userId <= 0 || TextUtils.isEmpty(deviceUuid)) {
throw new IllegalArgumentException("User is not logged in!");
if (TextUtils.isEmpty(csrfToken)) {
throw new IllegalArgumentException("csrfToken is empty!");
} else if (userId == 0) {
throw new IllegalArgumentException("user id invalid");
} else if (TextUtils.isEmpty(deviceUuid)) {
throw new IllegalArgumentException("device uuid is empty!");
}
service = DirectMessagesService.getInstance(csrfToken, userId, deviceUuid);

View File

@ -27,6 +27,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@ -156,9 +157,9 @@ public final class ThreadManager {
viewerId = CookieUtils.getUserIdFromCookie(cookie);
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID);
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
if (TextUtils.isEmpty(csrfToken) || viewerId <= 0 || TextUtils.isEmpty(deviceUuid)) {
throw new IllegalArgumentException("User is not logged in!");
}
// if (TextUtils.isEmpty(csrfToken) || viewerId <= 0 || TextUtils.isEmpty(deviceUuid)) {
// throw new IllegalArgumentException("User is not logged in!");
// }
service = DirectMessagesService.getInstance(csrfToken, viewerId, deviceUuid);
mediaService = MediaService.getInstance(deviceUuid, csrfToken, viewerId);
friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, viewerId);
@ -564,6 +565,7 @@ public final class ThreadManager {
private List<DirectItemEmojiReaction> addEmoji(final List<DirectItemEmojiReaction> reactionList,
final String emoji,
final boolean shouldReplaceIfAlreadyReacted) {
if (currentUser == null) return reactionList;
final List<DirectItemEmojiReaction> temp = reactionList == null ? new ArrayList<>() : new ArrayList<>(reactionList);
int index = -1;
for (int i = 0; i < temp.size(); i++) {
@ -1311,6 +1313,7 @@ public final class ThreadManager {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
final Call<DirectThreadDetailsChangeResponse> addUsersRequest = service.addUsers(threadId,
users.stream()
.filter(Objects::nonNull)
.map(User::getPk)
.collect(Collectors.toList()));
handleDetailsChangeRequest(data, addUsersRequest);
@ -1319,6 +1322,10 @@ public final class ThreadManager {
public LiveData<Resource<Object>> removeMember(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) {
data.postValue(Resource.error("user is null!", null));
return data;
}
final Call<String> request = service.removeUsers(threadId, Collections.singleton(user.getPk()));
request.enqueue(new Callback<String>() {
@Override
@ -1337,6 +1344,7 @@ public final class ThreadManager {
leftUsersValue = Collections.emptyList();
}
final List<User> updatedActiveUsers = activeUsers.stream()
.filter(Objects::nonNull)
.filter(u -> u.getPk() != user.getPk())
.collect(Collectors.toList());
final ImmutableList.Builder<User> updatedLeftUsersBuilder = ImmutableList.<User>builder().addAll(leftUsersValue);
@ -1357,12 +1365,14 @@ public final class ThreadManager {
}
public boolean isAdmin(final User user) {
if (user == null) return false;
final List<Long> adminUserIdsValue = adminUserIds.getValue();
return adminUserIdsValue != null && adminUserIdsValue.contains(user.getPk());
}
public LiveData<Resource<Object>> makeAdmin(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) return data;
if (isAdmin(user)) return data;
final Call<String> request = service.addAdmins(threadId, Collections.singleton(user.getPk()));
request.enqueue(new Callback<String>() {
@ -1399,6 +1409,7 @@ public final class ThreadManager {
public LiveData<Resource<Object>> removeAdmin(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) return data;
if (!isAdmin(user)) return data;
final Call<String> request = service.removeAdmins(threadId, Collections.singleton(user.getPk()));
request.enqueue(new Callback<String>() {
@ -1411,6 +1422,7 @@ public final class ThreadManager {
final List<Long> currentAdmins = adminUserIds.getValue();
if (currentAdmins == null) return;
final List<Long> updatedAdminUserIds = currentAdmins.stream()
.filter(Objects::nonNull)
.filter(userId1 -> userId1 != user.getPk())
.collect(Collectors.toList());
final DirectThread currentThread = ThreadManager.this.thread.getValue();
@ -1583,6 +1595,7 @@ public final class ThreadManager {
public LiveData<Resource<Object>> blockUser(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) return data;
friendshipService.block(user.getPk(), new ServiceCallback<FriendshipChangeResponse>() {
@Override
public void onSuccess(final FriendshipChangeResponse result) {
@ -1600,6 +1613,7 @@ public final class ThreadManager {
public LiveData<Resource<Object>> unblockUser(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) return data;
friendshipService.unblock(user.getPk(), new ServiceCallback<FriendshipChangeResponse>() {
@Override
public void onSuccess(final FriendshipChangeResponse result) {
@ -1617,6 +1631,7 @@ public final class ThreadManager {
public LiveData<Resource<Object>> restrictUser(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) return data;
friendshipService.toggleRestrict(user.getPk(), true, new ServiceCallback<FriendshipRestrictResponse>() {
@Override
public void onSuccess(final FriendshipRestrictResponse result) {
@ -1634,6 +1649,7 @@ public final class ThreadManager {
public LiveData<Resource<Object>> unRestrictUser(final User user) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
if (user == null) return data;
friendshipService.toggleRestrict(user.getPk(), false, new ServiceCallback<FriendshipRestrictResponse>() {
@Override
public void onSuccess(final FriendshipRestrictResponse result) {
@ -1654,7 +1670,10 @@ public final class ThreadManager {
data.postValue(Resource.loading(null));
final Call<DirectThreadDetailsChangeResponse> approveUsersRequest = service
.approveParticipantRequests(threadId,
users.stream().map(User::getPk).collect(Collectors.toList()));
users.stream()
.filter(Objects::nonNull)
.map(User::getPk)
.collect(Collectors.toList()));
handleDetailsChangeRequest(data, approveUsersRequest, () -> pendingUserApproveDenySuccessAction(users));
return data;
}
@ -1811,6 +1830,7 @@ public final class ThreadManager {
@Override
public void onResponse(@NonNull final Call<DirectItemSeenResponse> call,
@NonNull final Response<DirectItemSeenResponse> response) {
if (currentUser == null) return;
if (!response.isSuccessful()) {
handleErrorBody(call, response, data);
return;

View File

@ -23,18 +23,21 @@ import awais.instagrabber.repositories.responses.directmessages.DirectThreadLast
import awais.instagrabber.repositories.responses.directmessages.RavenExpiringMediaActionSummary;
public final class DMUtils {
public static boolean isRead(final DirectItem item,
public static boolean isRead(@NonNull final DirectItem item,
@NonNull final Map<Long, DirectThreadLastSeenAt> lastSeenAt,
final List<Long> userIdsToCheck) {
@NonNull final List<Long> userIdsToCheck) {
// Further check if directStory exists
// if (read && directStory != null) {
// read = false;
// }
if (item == null) return false;
return lastSeenAt.entrySet()
.stream()
.filter(entry -> userIdsToCheck.contains(entry.getKey()))
.anyMatch(entry -> {
final String userLastSeenTsString = entry.getValue().getTimestamp();
final DirectThreadLastSeenAt threadLastSeenAt = entry.getValue();
if (threadLastSeenAt == null) return false;
final String userLastSeenTsString = threadLastSeenAt.getTimestamp();
if (userLastSeenTsString == null) return false;
final long userTs = Long.parseLong(userLastSeenTsString);
final long itemTs = item.getTimestamp();

View File

@ -13,12 +13,17 @@ import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import awais.instagrabber.R;
import awais.instagrabber.models.Resource;
import awais.instagrabber.repositories.responses.AnimatedMediaFixedHeight;
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
import awais.instagrabber.repositories.responses.giphy.GiphyGifImages;
import awais.instagrabber.repositories.responses.giphy.GiphyGifResponse;
import awais.instagrabber.repositories.responses.giphy.GiphyGifResults;
import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.webservices.GifService;
import retrofit2.Call;
import retrofit2.Callback;
@ -92,12 +97,25 @@ public class GifPickerViewModel extends ViewModel {
final GiphyGifResults results = giphyGifResponse.getResults();
images.postValue(Resource.success(
ImmutableList.<GiphyGif>builder()
.addAll(results.getGiphy() == null ? Collections.emptyList() : results.getGiphy())
.addAll(results.getGiphyGifs() == null ? Collections.emptyList() : results.getGiphyGifs())
.addAll(results.getGiphy() == null ? Collections.emptyList() : filterInvalid(results.getGiphy()))
.addAll(results.getGiphyGifs() == null ? Collections.emptyList() : filterInvalid(results.getGiphyGifs()))
.build()
));
}
private List<GiphyGif> filterInvalid(@NonNull final List<GiphyGif> giphyGifs) {
return giphyGifs.stream()
.filter(Objects::nonNull)
.filter(giphyGif -> {
final GiphyGifImages images = giphyGif.getImages();
if (images == null) return false;
final AnimatedMediaFixedHeight fixedHeight = images.getFixedHeight();
if (fixedHeight == null) return false;
return !TextUtils.isEmpty(fixedHeight.getWebp());
})
.collect(Collectors.toList());
}
// @NonNull
// private List<GiphyGifImage> getGiphyGifImages(@NonNull final List<GiphyGif> giphy) {
// return giphy.stream()