Merge remote-tracking branch 'megalodon_main/main'

# Conflicts:
#	mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java
#	mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposePollViewController.java
#	metadata/uk/changelogs/56.txt
This commit is contained in:
LucasGGamerM
2023-10-25 20:10:41 -03:00
21 changed files with 273 additions and 83 deletions

View File

@@ -551,10 +551,14 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
protected void updatePoll(String itemID, Status status, Poll poll){
status.poll=poll;
int firstOptionIndex=-1, footerIndex=-1;
int spoilerFirstOptionIndex=-1, spoilerFooterIndex=-1;
SpoilerStatusDisplayItem spoilerItem=null;
int i=0;
for(StatusDisplayItem item:displayItems){
if(item.parentID.equals(itemID)){
if(item instanceof PollOptionStatusDisplayItem && firstOptionIndex==-1){
if(item instanceof SpoilerStatusDisplayItem){
spoilerItem=(SpoilerStatusDisplayItem) item;
}else if(item instanceof PollOptionStatusDisplayItem && firstOptionIndex==-1){
firstOptionIndex=i;
}else if(item instanceof PollFooterStatusDisplayItem){
footerIndex=i;
@@ -567,8 +571,16 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
throw new IllegalStateException("Can't find all poll items in displayItems");
List<StatusDisplayItem> pollItems=displayItems.subList(firstOptionIndex, footerIndex+1);
int prevSize=pollItems.size();
if(spoilerItem!=null){
spoilerFirstOptionIndex=spoilerItem.contentItems.indexOf(pollItems.get(0));
spoilerFooterIndex=spoilerItem.contentItems.indexOf(pollItems.get(pollItems.size()-1));
}
pollItems.clear();
StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems, status);
if(spoilerItem!=null){
spoilerItem.contentItems.subList(spoilerFirstOptionIndex, spoilerFooterIndex+1).clear();
spoilerItem.contentItems.addAll(spoilerFirstOptionIndex, pollItems);
}
if(prevSize!=pollItems.size()){
adapter.notifyItemRangeRemoved(firstOptionIndex, prevSize);
adapter.notifyItemRangeInserted(firstOptionIndex, pollItems.size());

View File

@@ -215,7 +215,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
public Instance instance;
public Status editingStatus;
private ScheduledStatus scheduledStatus;
public ScheduledStatus scheduledStatus;
private boolean redraftStatus;
private Uri photoUri;
@@ -758,7 +758,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(16)));
}
replyText.setText(getString(quote!=null? R.string.sk_quoting_user : R.string.in_reply_to, status.account.getDisplayName()));
replyText.setText(HtmlParser.parseCustomEmoji(getString(quote!=null? R.string.sk_quoting_user : R.string.in_reply_to, status.account.getDisplayName()), status.account.emojis));
UiUtils.loadCustomEmojiInTextView(replyText);
int visibilityNameRes = switch (status.visibility) {
case PUBLIC -> R.string.visibility_public;
case UNLISTED -> R.string.sk_visibility_unlisted;

View File

@@ -8,10 +8,14 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusUpdatedEvent;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.Status;
@@ -23,9 +27,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import me.grishka.appkit.api.Callback;
@@ -51,6 +57,7 @@ public class HomeTimelineFragment extends StatusListFragment {
@Override
protected void doLoadData(int offset, int count){
String maxID=this.maxID;
AccountSessionManager.getInstance()
.getAccount(accountID).getCacheController()
.getHomeTimeline(offset>0 ? maxID : null, count, refreshing, new SimpleCallback<>(this){
@@ -58,7 +65,8 @@ public class HomeTimelineFragment extends StatusListFragment {
public void onSuccess(CacheablePaginatedResponse<List<Status>> result){
if(getActivity()==null) return;
boolean empty=result.items.isEmpty();
maxID=result.maxID;
if(result.isFromCache()) refreshCachedData(result, maxID);
HomeTimelineFragment.this.maxID=result.maxID;
AccountSessionManager.get(accountID).filterStatuses(result.items, getFilterContext());
onDataLoaded(result.items, !empty);
if(result.isFromCache() && GlobalUserPreferences.loadNewPosts)
@@ -67,6 +75,53 @@ public class HomeTimelineFragment extends StatusListFragment {
});
}
private void handleRefreshedData(List<Status> result, List<Status> cachedList){
Map<String, Status> refreshed=result.stream().collect(Collectors.toMap(Status::getID, Function.identity()));
for(Status cached : cachedList){
if(refreshed.containsKey(cached.id)){
Status updated=refreshed.get(cached.id);
if(updated.editedAt!=null && cached.editedAt!=null && updated.editedAt.isAfter(cached.editedAt))
E.post(new StatusUpdatedEvent(updated));
else
E.post(new StatusCountersUpdatedEvent(updated.getContentStatus()));
}else{
removeStatus(cached);
}
}
}
private void refreshCachedData(CacheablePaginatedResponse<List<Status>> result, String maxID){
List<Status> cachedList=new ArrayList<>(result.items);
if(cachedList.isEmpty()) return;
if(maxID==null){
// fetch top status manually so we can use its id as the max_id to fetch the rest
Status firstFromCache=cachedList.get(0);
maxID=firstFromCache.id;
cachedList.remove(0);
new GetStatusByID(maxID).setCallback(new Callback<>(){
@Override
public void onSuccess(Status result){
handleRefreshedData(
Collections.singletonList(result),
Collections.singletonList(firstFromCache)
);
}
@Override
public void onError(ErrorResponse ignored){}
}).exec(accountID);
}
new GetHomeTimeline(maxID, null, cachedList.size(), null, getSession().getLocalPreferences().timelineReplyVisibility).setCallback(new Callback<>(){
@Override
public void onSuccess(List<Status> result){
handleRefreshedData(result, cachedList);
}
@Override
public void onError(ErrorResponse ignored){}
}).exec(accountID);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);