From b7251972a80ff89f61cb1643209ee8a845720bf6 Mon Sep 17 00:00:00 2001 From: Grishka Date: Thu, 28 Mar 2024 23:00:03 +0300 Subject: [PATCH] Show the profile header view if we know the username --- .../android/fragments/ProfileFragment.java | 52 ++++++++++++++++++- .../android/ui/text/HtmlParser.java | 2 + .../android/ui/text/LinkSpan.java | 19 ++++++- .../android/ui/utils/UiUtils.java | 8 +++ .../src/main/res/layout/fragment_profile.xml | 11 +++- 5 files changed, 89 insertions(+), 3 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java index 32dee77b..9602a1a9 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java @@ -135,6 +135,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList private View actionButtonWrap; private CustomDrawingOrderLinearLayout scrollableContent; private ImageButton qrCodeButton; + private ProgressBar innerProgress; + private View actions; private Account account; private String accountID; @@ -218,6 +220,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList actionButtonWrap=content.findViewById(R.id.profile_action_btn_wrap); scrollableContent=content.findViewById(R.id.scrollable_content); qrCodeButton=content.findViewById(R.id.qr_code); + innerProgress=content.findViewById(R.id.profile_progress); + actions=content.findViewById(R.id.profile_actions); avatar.setOutlineProvider(OutlineProviders.roundedRect(24)); avatar.setClipToOutline(true); @@ -305,6 +309,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList followingBtn.setOnClickListener(this::onFollowersOrFollowingClick); username.setOnLongClickListener(v->{ + if(account==null) + return true; String username=account.acct; if(!username.contains("@")){ username+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain; @@ -330,7 +336,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList nameEdit.addTextChangedListener(new SimpleTextWatcher(e->editDirty=true)); bioEdit.addTextChangedListener(new SimpleTextWatcher(e->editDirty=true)); - usernameDomain.setOnClickListener(v->new DecentralizationExplainerSheet(getActivity(), accountID, account).show()); + usernameDomain.setOnClickListener(v->{ + if(account==null) + return; + new DecentralizationExplainerSheet(getActivity(), accountID, account).show(); + }); qrCodeButton.setOnClickListener(v->{ Bundle args=new Bundle(); args.putString("account", accountID); @@ -461,6 +471,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList return true; } }); + if(!loaded) + bindHeaderViewForPreviewMaybe(); } @Override @@ -505,7 +517,41 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList } } + private void bindHeaderViewForPreviewMaybe(){ + if(loaded) + return; + String username=getArguments().getString("accountUsername"); + String domain=getArguments().getString("accountDomain"); + if(TextUtils.isEmpty(username) || TextUtils.isEmpty(domain)) + return; + content.setVisibility(View.VISIBLE); + progress.setVisibility(View.GONE); + errorView.setVisibility(View.GONE); + innerProgress.setVisibility(View.VISIBLE); + this.username.setText(username); + name.setText(username); + usernameDomain.setText(domain); + avatar.setImageResource(R.drawable.image_placeholder); + cover.setImageResource(R.drawable.image_placeholder); + actions.setVisibility(View.GONE); + bio.setVisibility(View.GONE); + countersLayout.setVisibility(View.GONE); + tabsDivider.setVisibility(View.GONE); + } + private void bindHeaderView(){ + if(innerProgress.getVisibility()==View.VISIBLE){ + TransitionManager.beginDelayedTransition(contentView, new TransitionSet() + .addTransition(new Fade(Fade.IN | Fade.OUT)) + .excludeChildren(actions, true) + .setDuration(250) + .setInterpolator(CubicBezierInterpolator.DEFAULT) + ); + innerProgress.setVisibility(View.GONE); + countersLayout.setVisibility(View.VISIBLE); + actions.setVisibility(View.VISIBLE); + tabsDivider.setVisibility(View.VISIBLE); + } setTitle(account.displayName); setSubtitle(getResources().getQuantityString(R.plurals.x_posts, (int)(account.statusesCount%1000), account.statusesCount)); ViewImageLoader.load(avatar, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(100), V.dp(100))); @@ -1082,6 +1128,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList } private void onAvatarClick(View v){ + if(account==null) + return; if(isInEditMode){ startImagePicker(AVATAR_RESULT); }else{ @@ -1095,6 +1143,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList } private void onCoverClick(View v){ + if(account==null) + return; if(isInEditMode){ startImagePicker(COVER_RESULT); }else{ diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/text/HtmlParser.java b/mastodon/src/main/java/org/joinmastodon/android/ui/text/HtmlParser.java index 34ae4289..caeedac6 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/text/HtmlParser.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/text/HtmlParser.java @@ -86,6 +86,7 @@ public class HtmlParser{ // Hashtags in remote posts have remote URLs, these have local URLs so they don't match. // Map tagsByUrl=tags.stream().collect(Collectors.toMap(t->t.url, t->t.name)); Map tagsByTag=tags.stream().distinct().collect(Collectors.toMap(t->t.name.toLowerCase(), Function.identity())); + Map mentionsByID=mentions.stream().distinct().collect(Collectors.toMap(m->m.id, Function.identity())); final SpannableStringBuilder ssb=new SpannableStringBuilder(); Jsoup.parseBodyFragment(source).body().traverse(new NodeVisitor(){ @@ -115,6 +116,7 @@ public class HtmlParser{ if(id!=null){ linkType=LinkSpan.Type.MENTION; href=id; + linkObject=mentionsByID.get(id); }else{ linkType=LinkSpan.Type.URL; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java b/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java index a4831db0..c11e707c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/text/LinkSpan.java @@ -2,9 +2,12 @@ package org.joinmastodon.android.ui.text; import android.content.Context; import android.text.TextPaint; +import android.text.TextUtils; import android.text.style.CharacterStyle; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Hashtag; +import org.joinmastodon.android.model.Mention; import org.joinmastodon.android.ui.utils.UiUtils; public class LinkSpan extends CharacterStyle { @@ -39,7 +42,21 @@ public class LinkSpan extends CharacterStyle { public void onClick(Context context){ switch(getType()){ case URL -> UiUtils.openURL(context, accountID, link, parentObject); - case MENTION -> UiUtils.openProfileByID(context, accountID, link); + case MENTION -> { + String username, domain; + if(linkObject instanceof Mention m && !TextUtils.isEmpty(m.acct)){ + String[] parts=m.acct.split("@", 2); + username=parts[0]; + if(parts.length==2){ + domain=parts[1]; + }else{ + domain=AccountSessionManager.get(accountID).domain; + } + }else{ + username=domain=null; + } + UiUtils.openProfileByID(context, accountID, link, username, domain); + } case HASHTAG -> { if(linkObject instanceof Hashtag ht) UiUtils.openHashtagTimeline(context, accountID, ht); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java index 10df920c..a9c4cb57 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java @@ -353,9 +353,17 @@ public class UiUtils{ } public static void openProfileByID(Context context, String selfID, String id){ + openProfileByID(context, selfID, id, null, null); + } + + public static void openProfileByID(Context context, String selfID, String id, String username, String domain){ Bundle args=new Bundle(); args.putString("account", selfID); args.putString("profileAccountID", id); + if(username!=null && domain!=null){ + args.putString("accountUsername", username); + args.putString("accountDomain", domain); + } Nav.go((Activity)context, ProfileFragment.class, args); } diff --git a/mastodon/src/main/res/layout/fragment_profile.xml b/mastodon/src/main/res/layout/fragment_profile.xml index e5b7bdca..6d49a756 100644 --- a/mastodon/src/main/res/layout/fragment_profile.xml +++ b/mastodon/src/main/res/layout/fragment_profile.xml @@ -32,7 +32,7 @@ android:id="@+id/cover" android:layout_width="match_parent" android:layout_height="144dp" - android:background="#808080" + android:background="@drawable/image_placeholder" android:contentDescription="@string/profile_header" android:scaleType="centerCrop" /> @@ -134,6 +134,14 @@ + +