Merge remote-tracking branch 'megalodon_main/main'

# Conflicts:
#	mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsAboutAppFragment.java
This commit is contained in:
LucasGGamerM
2023-08-29 10:41:09 -03:00
60 changed files with 522 additions and 220 deletions

View File

@@ -340,7 +340,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
req.visibility = preferences.postingDefaultVisibility;
req.inReplyToId = notification.status.id;
if (!notification.status.spoilerText.isEmpty() &&
if (notification.status.hasSpoiler() &&
(GlobalUserPreferences.prefixReplies == ALWAYS
|| (GlobalUserPreferences.prefixReplies == TO_OTHERS && !ownID.equals(notification.status.account.id)))
&& !notification.status.spoilerText.startsWith("re: ")) {

View File

@@ -27,9 +27,9 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
public void onNewEndpoint(@NotNull Context context, @NotNull String endpoint, @NotNull String instance) {
// Called when a new endpoint be used for sending push messages
Log.d(TAG, "onNewEndpoint: New Endpoint " + endpoint + " for "+ instance);
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null);
account.getPushSubscriptionManager().registerAccountForPush(null, endpoint);
}
@Override
@@ -37,7 +37,7 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
// called when the registration is not possible, eg. no network
Log.d(TAG, "onRegistrationFailed: " + instance);
//re-register for gcm
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null);
}
@@ -47,7 +47,7 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
// called when this application is unregistered from receiving push messages
Log.d(TAG, "onUnregistered: " + instance);
//re-register for gcm
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null);
}
@@ -55,7 +55,10 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
@Override
public void onMessage(@NotNull Context context, @NotNull byte[] message, @NotNull String instance) {
// Called when a new message is received. The message contains the full POST body of the push message
AccountSession account = AccountSessionManager.getInstance().getAccount(instance);
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account == null)
return;
//this is stupid
// Mastodon stores the info to decrypt the message in the HTTP headers, which are not accessible in UnifiedPush,

View File

@@ -125,11 +125,11 @@ public class PushSubscriptionManager{
// this function is used for registering push notifications using FCM
// to avoid NonFreeNet in F-Droid, this registration is disabled in it
// see https://github.com/LucasGGamerM/moshidon/issues/206 for more context
if(BuildConfig.BUILD_TYPE.equals("fdroidRelease"))
if(BuildConfig.BUILD_TYPE.equals("fdroidRelease") || TextUtils.isEmpty(deviceToken)){
Log.d(TAG, "Skipping registering for FCM push notifications");
return;
}
if(TextUtils.isEmpty(deviceToken))
throw new IllegalStateException("No device push token available");
String endpoint = "https://app.joinmastodon.org/relay-to/fcm/"+deviceToken+"/"+accountID;
registerAccountForPush(subscription, endpoint);
}

View File

@@ -465,7 +465,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
hasSpoiler=true;
spoilerWrap.setVisibility(View.VISIBLE);
spoilerBtn.setSelected(true);
}else if(editingStatus!=null && !TextUtils.isEmpty(editingStatus.spoilerText)){
}else if(editingStatus!=null && editingStatus.hasSpoiler()){
hasSpoiler=true;
spoilerWrap.setVisibility(View.VISIBLE);
spoilerEdit.setText(getArguments().getString("sourceSpoiler", editingStatus.spoilerText));
@@ -737,7 +737,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
view.findViewById(R.id.time).setVisibility(time==null ? View.GONE : View.VISIBLE);
if(time!=null) ((TextView) view.findViewById(R.id.time)).setText(time);
if (status.spoilerText != null && !status.spoilerText.isBlank()) {
if (status.hasSpoiler()) {
TextView replyToSpoiler = view.findViewById(R.id.reply_to_spoiler);
replyToSpoiler.setVisibility(View.VISIBLE);
replyToSpoiler.setText(status.spoilerText);

View File

@@ -45,8 +45,8 @@ public class FeaturedHashtagsListFragment extends BaseStatusListFragment<Hashtag
}
@Override
public void onItemClick(String id){
UiUtils.openHashtagTimeline(getActivity(), accountID, id, data.stream().filter(h -> Objects.equals(h.name, id)).findAny().map(h -> h.following).orElse(null));
public void onItemClick(String hashtag){
UiUtils.openHashtagTimeline(getActivity(), accountID, hashtag, data.stream().filter(h -> Objects.equals(h.name, hashtag)).findAny().map(h -> h.following).orElse(null));
}
@Override

View File

@@ -1169,7 +1169,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
actionButton.setText(R.string.save_changes);
pager.setVisibility(View.GONE);
tabbar.setVisibility(View.GONE);
Drawable overlay=getResources().getDrawable(R.drawable.edit_avatar_overlay).mutate();
Drawable overlay=getResources().getDrawable(R.drawable.edit_avatar_overlay, getActivity().getTheme()).mutate();
avatar.setForeground(overlay);
updateMetadataHeight();
@@ -1541,16 +1541,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
}
}
private class AboutViewHolder extends BaseViewHolder implements ImageLoaderViewHolder {
private class AboutViewHolder extends BaseViewHolder implements ImageLoaderViewHolder{
private final TextView title;
private final LinkedTextView value;
// private final ImageView verifiedIcon;
public AboutViewHolder(){
super(R.layout.item_profile_about);
title=findViewById(R.id.title);
value=findViewById(R.id.value);
// verifiedIcon=findViewById(R.id.verified_icon);
}
@Override
@@ -1558,7 +1556,18 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
super.onBind(item);
title.setText(item.parsedName);
value.setText(item.parsedValue);
// verifiedIcon.setVisibility(item.verifiedAt!=null ? View.VISIBLE : View.GONE);
if(item.verifiedAt!=null){
int textColor=UiUtils.isDarkTheme() ? 0xFF89bb9c : 0xFF5b8e63;
value.setTextColor(textColor);
value.setLinkTextColor(textColor);
Drawable check=getResources().getDrawable(R.drawable.ic_fluent_checkmark_starburst_20_regular, getActivity().getTheme()).mutate();
check.setTint(textColor);
value.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, check, null);
}else{
value.setTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
value.setLinkTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.colorAccent));
value.setCompoundDrawables(null, null, null, null);
}
}
@Override

View File

@@ -16,6 +16,7 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.List;
import java.util.Objects;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.imageloader.ImageCache;
@@ -32,7 +33,7 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void>{
setTitle(getString(R.string.about_app, getString(R.string.mo_app_name)));
AccountSession s=AccountSessionManager.get(accountID);
onDataLoaded(List.of(
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_donate_url))),
new ListItem<>(R.string.mo_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_donate_url))),
new ListItem<>(R.string.mo_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_repo_url))),
new ListItem<>(R.string.settings_tos, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/terms")),
new ListItem<>(R.string.settings_privacy_policy, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.privacy_policy_url)), 0, true),

View File

@@ -120,8 +120,8 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
for(FilterResult fr:filtered)
fr.postprocess();
if(!TextUtils.isEmpty(spoilerText)) sensitive=true;
spoilerRevealed=TextUtils.isEmpty(spoilerText);
spoilerRevealed=!hasSpoiler();
if(!spoilerRevealed) sensitive=true;
sensitiveRevealed=!sensitive;
if(visibility.equals(StatusPrivacy.LOCAL)) localOnly=true;
if(emojiReactions!=null) reactions=emojiReactions;
@@ -194,6 +194,10 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
return strippedText;
}
public boolean hasSpoiler(){
return !TextUtils.isEmpty(spoilerText);
}
@NonNull
@Override
public Status clone(){

View File

@@ -37,6 +37,16 @@ public class OutlineProviders{
}
};
private final static int BUTTON_BG_HEIGHT=V.dp(40);
public static final ViewOutlineProvider M3_BUTTON=new ViewOutlineProvider(){
@Override
public void getOutline(View view, Outline outline){
int viewHeight=view.getHeight();
int top=Math.floorDiv(viewHeight - BUTTON_BG_HEIGHT, 2);
outline.setRoundRect(0, top, view.getWidth(), top + BUTTON_BG_HEIGHT, V.dp(20));
}
};
public static ViewOutlineProvider roundedRect(int dp){
ViewOutlineProvider provider=roundedRects.get(dp);
if(provider!=null)

View File

@@ -195,7 +195,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
}
boolean isPixelfed = item.parentFragment.isInstancePixelfed();
boolean textEmpty = TextUtils.isEmpty(item.status.content) && TextUtils.isEmpty(item.status.spoilerText);
boolean textEmpty = TextUtils.isEmpty(item.status.content) && !item.status.hasSpoiler();
if(!redraft && (isPixelfed || textEmpty)){
// pixelfed doesn't support /statuses/:id/source :/
if (isPixelfed) {
@@ -327,11 +327,16 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification!=null && !item.inset ? View.VISIBLE : View.GONE);
if (item.hasVisibilityToggle){
boolean disabled = !item.status.sensitiveRevealed ||
(!TextUtils.isEmpty(item.status.spoilerText) &&
!item.status.spoilerRevealed);
visibility.setEnabled(!disabled);
V.setVisibilityAnimated(visibility, disabled ? View.INVISIBLE : View.VISIBLE);
boolean hidden = !item.status.sensitiveRevealed || (item.status.hasSpoiler() && !item.status.spoilerRevealed);
// doing this because V.setVisibilityAnimated ignores changes between INVISIBLE and GONE
int newVis=hidden ? View.INVISIBLE : View.VISIBLE;
if(newVis==View.INVISIBLE && visibility.getVisibility()==View.GONE)
visibility.setVisibility(newVis);
else
V.setVisibilityAnimated(visibility, newVis);
visibility.setEnabled(!hidden);
visibility.setContentDescription(item.parentFragment.getString(item.status.sensitiveRevealed ? R.string.spoiler_hide : R.string.spoiler_show));
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
visibility.setTooltipText(visibility.getContentDescription());

View File

@@ -80,7 +80,7 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
progressBg=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted, activity.getTheme()).mutate();
progressBgInset=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted_inset, activity.getTheme()).mutate();
itemView.setOnClickListener(this::onButtonClick);
button.setOutlineProvider(OutlineProviders.roundedRect(24));
button.setOutlineProvider(OutlineProviders.M3_BUTTON);
button.setClipToOutline(true);
}

View File

@@ -229,7 +229,7 @@ public abstract class StatusDisplayItem{
}
ArrayList<StatusDisplayItem> contentItems;
if(!TextUtils.isEmpty(statusForContent.spoilerText)){
if(statusForContent.hasSpoiler()){
if (AccountSessionManager.get(accountID).getLocalPreferences().revealCWs) statusForContent.spoilerRevealed = true;
SpoilerStatusDisplayItem spoilerItem=new SpoilerStatusDisplayItem(parentID, fragment, null, statusForContent, Type.SPOILER);
items.add(spoilerItem);
@@ -309,7 +309,7 @@ public abstract class StatusDisplayItem{
int i=1;
boolean inset=(flags & FLAG_INSET)!=0;
// add inset dummy so last content item doesn't clip out of inset bounds
if(inset || footer==null){
if((inset || footer==null) && (flags & FLAG_CHECKABLE)==0){
items.add(new DummyStatusDisplayItem(parentID, fragment));
// in case we ever need the dummy to display a margin for the media grid again:
// (i forgot why we apparently don't need this anymore)

View File

@@ -185,11 +185,10 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
readMore.setText(item.status.textExpanded ? R.string.sk_collapse : R.string.sk_expand);
StatusDisplayItem next=getNextVisibleDisplayItem().orElse(null);
int bottomPadding=next instanceof FooterStatusDisplayItem
? V.dp(6)
: (!item.inset && next instanceof DummyStatusDisplayItem) ||
next instanceof EmojiReactionsStatusDisplayItem e && !e.isHidden()
? 0
if(next!=null && !next.parentID.equals(item.parentID)) next=null;
int bottomPadding=next instanceof FooterStatusDisplayItem ? V.dp(6)
: item.inset ? V.dp(12)
: (next instanceof EmojiReactionsStatusDisplayItem || next==null) ? 0
: V.dp(12);
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), bottomPadding);

View File

@@ -40,11 +40,9 @@ public abstract class ListItemViewHolder<T extends ListItem<?>> extends Bindable
if(TextUtils.isEmpty(item.subtitle) && item.subtitleRes==0){
subtitle.setVisibility(View.GONE);
title.setMaxLines(2);
view.setMinimumHeight(V.dp(56));
}else{
subtitle.setVisibility(View.VISIBLE);
title.setMaxLines(1);
view.setMinimumHeight(V.dp(72));
if(TextUtils.isEmpty(item.subtitle))
subtitle.setText(item.subtitleRes);