commit
cc2076ec10
|
@ -47,7 +47,6 @@ import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
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.MediaGridStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.PollOptionStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.PollOptionStatusDisplayItem;
|
||||||
|
@ -707,38 +706,22 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||||
toggleSpoiler(status, isForQuote, holder.getItemID());
|
toggleSpoiler(status, isForQuote, holder.getItemID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAddQuoteToStatus(Status status, Status parentStatus) {
|
public void updateStatusWithQuote(Status status) {
|
||||||
int cardIndex=-1;
|
int startIndex=-1;
|
||||||
int textIndex=-1;
|
int endIndex=-1;
|
||||||
int i=0;
|
for(int i=0; i<displayItems.size(); i++){
|
||||||
for(StatusDisplayItem item:displayItems){
|
StatusDisplayItem item = displayItems.get(i);
|
||||||
if(item.parentID.equals(parentStatus.id)){
|
if(item.parentID.equals(status.id)) {
|
||||||
if(item instanceof LinkCardStatusDisplayItem){
|
startIndex= startIndex==-1 ? i : startIndex;
|
||||||
cardIndex=i;
|
endIndex=i;
|
||||||
}else if(item instanceof TextStatusDisplayItem){
|
|
||||||
textIndex=i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int flags= (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS | StatusDisplayItem.FLAG_IS_FOR_QUOTE);
|
if (startIndex!=-1 && endIndex!=-1) {
|
||||||
if (!GlobalUserPreferences.showMediaPreview)
|
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, status, accountID, status, knownAccounts, null, 0);
|
||||||
flags |= StatusDisplayItem.FLAG_NO_MEDIA_PREVIEW;
|
displayItems.subList(startIndex, endIndex+1).clear();
|
||||||
|
displayItems.addAll(startIndex, items);
|
||||||
if (cardIndex!=-1) {
|
adapter.notifyItemRangeChanged(startIndex, items.size());
|
||||||
ArrayList<StatusDisplayItem> 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) {
|
|
||||||
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, status, accountID, parentStatus, knownAccounts, null, flags);
|
|
||||||
displayItems.addAll(textIndex+1, items);
|
|
||||||
adapter.notifyItemRangeInserted(textIndex+1, items.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -84,6 +85,10 @@ public abstract class StatusDisplayItem{
|
||||||
public static final int FLAG_IS_FOR_QUOTE=1 << 7;
|
public static final int FLAG_IS_FOR_QUOTE=1 << 7;
|
||||||
public static final int FLAG_NO_MEDIA_PREVIEW=1 << 8;
|
public static final int FLAG_NO_MEDIA_PREVIEW=1 << 8;
|
||||||
|
|
||||||
|
|
||||||
|
private final static Pattern QUOTE_MENTION_PATTERN=Pattern.compile("(?:<p>)?\\s?(?:RE:\\s?)?<a href=\"https:\\/\\/[^\"]+\"[^>]*><span class=\"invisible\">https:\\/\\/<\\/span><span class=\"ellipsis\">[^<]+<\\/span><span class=\"invisible\">[^<]+<\\/span><\\/a>(?:<\\/p>)?$");
|
||||||
|
private final static Pattern QUOTE_PATTERN=Pattern.compile("[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)$");
|
||||||
|
|
||||||
public void setAncestryInfo(
|
public void setAncestryInfo(
|
||||||
boolean hasDescendantNeighbor,
|
boolean hasDescendantNeighbor,
|
||||||
boolean hasAncestoringNeighbor,
|
boolean hasAncestoringNeighbor,
|
||||||
|
@ -270,6 +275,14 @@ public abstract class StatusDisplayItem{
|
||||||
int quoteInlineIndex=statusForContent.content.lastIndexOf("<span class=\"quote-inline\"><br/><br/>RE:");
|
int quoteInlineIndex=statusForContent.content.lastIndexOf("<span class=\"quote-inline\"><br/><br/>RE:");
|
||||||
if(quoteInlineIndex!=-1)
|
if(quoteInlineIndex!=-1)
|
||||||
statusForContent.content=statusForContent.content.substring(0, quoteInlineIndex);
|
statusForContent.content=statusForContent.content.substring(0, quoteInlineIndex);
|
||||||
|
else {
|
||||||
|
// hide non-official quote patters
|
||||||
|
Matcher matcher=QUOTE_MENTION_PATTERN.matcher(status.content);
|
||||||
|
if(matcher.find()){
|
||||||
|
String quoteMention=matcher.group();
|
||||||
|
statusForContent.content=statusForContent.content.replace(quoteMention, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasSpoiler=!TextUtils.isEmpty(statusForContent.spoilerText);
|
boolean hasSpoiler=!TextUtils.isEmpty(statusForContent.spoilerText);
|
||||||
|
@ -325,6 +338,8 @@ public abstract class StatusDisplayItem{
|
||||||
if(!statusForContent.mediaAttachments.isEmpty() && statusForContent.poll==null) // add spacing if immediately preceded by attachment
|
if(!statusForContent.mediaAttachments.isEmpty() && statusForContent.poll==null) // add spacing if immediately preceded by attachment
|
||||||
contentItems.add(new DummyStatusDisplayItem(parentID, fragment));
|
contentItems.add(new DummyStatusDisplayItem(parentID, fragment));
|
||||||
contentItems.addAll(buildItems(fragment, statusForContent.quote, accountID, parentObject, knownAccounts, filterContext, FLAG_NO_FOOTER|FLAG_INSET|FLAG_NO_EMOJI_REACTIONS|FLAG_IS_FOR_QUOTE));
|
contentItems.addAll(buildItems(fragment, statusForContent.quote, accountID, parentObject, knownAccounts, filterContext, FLAG_NO_FOOTER|FLAG_INSET|FLAG_NO_EMOJI_REACTIONS|FLAG_IS_FOR_QUOTE));
|
||||||
|
} else {
|
||||||
|
tryAddNonOfficialQuote(statusForContent, fragment, accountID);
|
||||||
}
|
}
|
||||||
if(contentItems!=items && statusForContent.spoilerRevealed){
|
if(contentItems!=items && statusForContent.spoilerRevealed){
|
||||||
items.addAll(contentItems);
|
items.addAll(contentItems);
|
||||||
|
@ -378,33 +393,6 @@ public abstract class StatusDisplayItem{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.getStrippedText());
|
|
||||||
|
|
||||||
String lastUrl = null;
|
|
||||||
while (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) && statusForContent.quote == null) {
|
|
||||||
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<StatusDisplayItem> nonGapItems=gap!=null ? items.subList(0, items.size()-1) : items;
|
List<StatusDisplayItem> nonGapItems=gap!=null ? items.subList(0, items.size()-1) : items;
|
||||||
WarningFilteredStatusDisplayItem warning=applyingFilter==null ? null :
|
WarningFilteredStatusDisplayItem warning=applyingFilter==null ? null :
|
||||||
new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, nonGapItems, applyingFilter);
|
new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, nonGapItems, applyingFilter);
|
||||||
|
@ -427,6 +415,39 @@ public abstract class StatusDisplayItem{
|
||||||
items.add(new PollFooterStatusDisplayItem(parentID, fragment, poll, status));
|
items.add(new PollFooterStatusDisplayItem(parentID, fragment, poll, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to adds a non-official quote to a status.
|
||||||
|
* A non-official quote is a quote on an instance that does not support quotes officially.
|
||||||
|
*/
|
||||||
|
private static void tryAddNonOfficialQuote(Status status, BaseStatusListFragment fragment, String accountID) {
|
||||||
|
Matcher matcher=QUOTE_PATTERN.matcher(status.getStrippedText());
|
||||||
|
|
||||||
|
if(!matcher.find())
|
||||||
|
return;
|
||||||
|
String quoteURL="https://"+matcher.group();
|
||||||
|
|
||||||
|
if (UiUtils.looksLikeFediverseUrl(quoteURL)) {
|
||||||
|
new GetSearchResults(quoteURL, GetSearchResults.Type.STATUSES, true, null, 0, 0).setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(SearchResults results){
|
||||||
|
if (!results.statuses.isEmpty()){
|
||||||
|
Status quote=results.statuses.get(0);
|
||||||
|
// don't show self-referential quotes
|
||||||
|
if(!Objects.equals(status.id, results.statuses.get(0).id)){
|
||||||
|
status.quote=quote;
|
||||||
|
fragment.updateStatusWithQuote(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
Log.w("StatusDisplayItem", "onError: failed to find quote status with URL: " + quoteURL + " " + error);
|
||||||
|
}
|
||||||
|
}).exec(accountID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type{
|
public enum Type{
|
||||||
HEADER,
|
HEADER,
|
||||||
REBLOG_OR_REPLY_LINE,
|
REBLOG_OR_REPLY_LINE,
|
||||||
|
|
Loading…
Reference in New Issue