diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java index 7f4f5b3788..120e9fc3dc 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -47,6 +47,7 @@ import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem; +import org.joinmastodon.android.ui.displayitems.LinkCardStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.MediaGridStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.PollOptionStatusDisplayItem; @@ -706,6 +707,47 @@ public void onRevealSpoilerClick(SpoilerStatusDisplayItem.Holder holder){ toggleSpoiler(status, isForQuote, holder.getItemID()); } + public void onAddQuoteToStatus(Status status, Status parentStatus) { + int cardIndex=-1; + int textIndex=-1; + int i=0; + for(StatusDisplayItem item:displayItems){ + if(item.parentID.equals(parentStatus.id)){ + if(item instanceof LinkCardStatusDisplayItem){ + cardIndex=i; + }else if(item instanceof TextStatusDisplayItem){ + textIndex=i; + } + } + i++; + } + + if (cardIndex!=-1) { + int flags= (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS); + if (GlobalUserPreferences.spectatorMode) + flags |= StatusDisplayItem.FLAG_NO_FOOTER; + if (!GlobalUserPreferences.showMediaPreview) + flags |= StatusDisplayItem.FLAG_NO_MEDIA_PREVIEW; + ArrayList items=StatusDisplayItem.buildItems(this, status, accountID, parentStatus, knownAccounts, null, flags); + displayItems.remove(cardIndex); + adapter.notifyItemRemoved(cardIndex); + displayItems.addAll(cardIndex, items); + adapter.notifyItemRangeInserted(cardIndex, items.size()); + return; + } + + if (textIndex!=-1) { + int flags= (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS); + if (GlobalUserPreferences.spectatorMode) + flags |= StatusDisplayItem.FLAG_NO_FOOTER; + if (!GlobalUserPreferences.showMediaPreview) + flags |= StatusDisplayItem.FLAG_NO_MEDIA_PREVIEW; + ArrayList items=StatusDisplayItem.buildItems(this, status, accountID, parentStatus, knownAccounts, null, flags); + displayItems.addAll(textIndex+1, items); + adapter.notifyItemRangeInserted(textIndex+1, items.size()); + } + } + public void onVisibilityIconClick(HeaderStatusDisplayItem.Holder holder) { Status status = holder.getItem().status; if(holder.getItem().hasVisibilityToggle) holder.animateVisibilityToggle(false); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java index 573a5cab8c..8f99ff16a4 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java @@ -17,6 +17,7 @@ import androidx.annotation.NonNull; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.search.GetSearchResults; import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.BaseStatusListFragment; @@ -35,6 +36,7 @@ import org.joinmastodon.android.model.Notification; import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.ScheduledStatus; +import org.joinmastodon.android.model.SearchResults; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.PhotoLayoutHelper; import org.joinmastodon.android.ui.text.HtmlParser; @@ -48,9 +50,13 @@ import java.util.Map; import java.util.Optional; import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import me.grishka.appkit.Nav; +import me.grishka.appkit.api.Callback; +import me.grishka.appkit.api.ErrorResponse; import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; import me.grishka.appkit.utils.BindableViewHolder; import me.grishka.appkit.views.UsableRecyclerView; @@ -372,6 +378,33 @@ public static ArrayList buildItems(BaseStatusListFragment } } + // I actually forgot where I took this, but it works + Pattern pattern = Pattern.compile("[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)"); + Matcher matcher = pattern.matcher(statusForContent.content); + + String lastUrl = null; + if (matcher.find()) { + lastUrl = matcher.group(0); + // The regex doesn't capture the scheme, so I add one here manually, so that the looksLikeFediverseUrlMethod actually works + lastUrl = "https://" + lastUrl; + } + + if (UiUtils.looksLikeFediverseUrl(lastUrl)) { + new GetSearchResults(lastUrl, GetSearchResults.Type.STATUSES, true, null, 0, 0).setCallback(new Callback<>(){ + @Override + public void onSuccess(SearchResults results){ + if (!results.statuses.isEmpty()){ + fragment.onAddQuoteToStatus(results.statuses.get(0), statusForContent); + } + } + + @Override + public void onError(ErrorResponse error){ + // Nothing + } + }).exec(accountID); + } + List nonGapItems=gap!=null ? items.subList(0, items.size()-1) : items; WarningFilteredStatusDisplayItem warning=applyingFilter==null ? null : new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, nonGapItems, applyingFilter);