Skip to content

Commit

Permalink
Domain badges & info sheet & my fanciest animation yet
Browse files Browse the repository at this point in the history
  • Loading branch information
grishka committed Feb 13, 2024
1 parent efb8cd5 commit 8dffbff
Show file tree
Hide file tree
Showing 12 changed files with 669 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@
import org.joinmastodon.android.ui.SimpleViewHolder;
import org.joinmastodon.android.ui.SingleImagePhotoViewerListener;
import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
import org.joinmastodon.android.ui.sheets.DecentralizationExplainerSheet;
import org.joinmastodon.android.ui.tabs.TabLayout;
import org.joinmastodon.android.ui.tabs.TabLayoutMediator;
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.text.ImageSpanThatDoesNotBreakShitForNoGoodReason;
import org.joinmastodon.android.ui.utils.SimpleTextWatcher;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.CoverImageView;
Expand Down Expand Up @@ -107,7 +109,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private ImageView avatar;
private CoverImageView cover;
private View avatarBorder;
private TextView name, username, bio, followersCount, followersLabel, followingCount, followingLabel;
private TextView name, username, usernameDomain, bio, followersCount, followersLabel, followingCount, followingLabel;
private ProgressBarButton actionButton;
private ViewPager2 pager;
private NestedRecyclerScrollView scrollView;
Expand Down Expand Up @@ -185,6 +187,7 @@ public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bu
avatarBorder=content.findViewById(R.id.avatar_border);
name=content.findViewById(R.id.name);
username=content.findViewById(R.id.username);
usernameDomain=content.findViewById(R.id.username_domain);
bio=content.findViewById(R.id.bio);
followersCount=content.findViewById(R.id.followers_count);
followersLabel=content.findViewById(R.id.followers_label);
Expand Down Expand Up @@ -320,6 +323,8 @@ public void getOutline(View view, Outline outline){
nameEdit.addTextChangedListener(new SimpleTextWatcher(e->editDirty=true));
bioEdit.addTextChangedListener(new SimpleTextWatcher(e->editDirty=true));

usernameDomain.setOnClickListener(v->new DecentralizationExplainerSheet(getActivity(), accountID, account).show());

return sizeWrapper;
}

Expand Down Expand Up @@ -499,22 +504,21 @@ private void bindHeaderView(){
boolean isSelf=AccountSessionManager.getInstance().isSelf(accountID, account);

if(account.locked){
ssb=new SpannableStringBuilder("@");
ssb.append(account.acct);
if(isSelf){
ssb.append('@');
ssb.append(AccountSessionManager.getInstance().getAccount(accountID).domain);
}
ssb=new SpannableStringBuilder(account.username);
ssb.append(" ");
Drawable lock=username.getResources().getDrawable(R.drawable.ic_lock_fill1_20px, getActivity().getTheme()).mutate();
lock.setBounds(0, 0, lock.getIntrinsicWidth(), lock.getIntrinsicHeight());
lock.setTint(username.getCurrentTextColor());
ssb.append(getString(R.string.manually_approves_followers), new ImageSpan(lock, ImageSpan.ALIGN_BOTTOM), 0);
ssb.append(getString(R.string.manually_approves_followers), new ImageSpanThatDoesNotBreakShitForNoGoodReason(lock, ImageSpan.ALIGN_BOTTOM), 0);
username.setText(ssb);
}else{
// noinspection SetTextI18n
username.setText('@'+account.acct+(isSelf ? ('@'+AccountSessionManager.getInstance().getAccount(accountID).domain) : ""));
username.setText(account.username);
}
String domain=account.getDomain();
if(TextUtils.isEmpty(domain))
domain=AccountSessionManager.get(accountID).domain;
usernameDomain.setText(domain);

CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
if(TextUtils.isEmpty(parsedBio)){
bio.setVisibility(View.GONE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void show(){
if(current!=null)
current.dismiss();
current=this;
WindowManager.LayoutParams lp=new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT);
WindowManager.LayoutParams lp=new WindowManager.LayoutParams(WindowManager.LayoutParams.LAST_APPLICATION_WINDOW, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT);
lp.width=ViewGroup.LayoutParams.MATCH_PARENT;
lp.height=ViewGroup.LayoutParams.WRAP_CONTENT;
lp.gravity=Gravity.BOTTOM;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package org.joinmastodon.android.ui.sheets;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.Snackbar;
import org.joinmastodon.android.ui.text.LinkSpan;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.RippleAnimationTextView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.NodeVisitor;

import androidx.annotation.NonNull;
import me.grishka.appkit.views.BottomSheet;

public class DecentralizationExplainerSheet extends BottomSheet{
private final String handleStr;

public DecentralizationExplainerSheet(@NonNull Context context, String accountID, Account account){
super(context);
View content=context.getSystemService(LayoutInflater.class).inflate(R.layout.sheet_decentralization_info, null);
setContentView(content);
setNavigationBarBackground(new ColorDrawable(UiUtils.alphaBlendColors(UiUtils.getThemeColor(context, R.attr.colorM3Surface),
UiUtils.getThemeColor(context, R.attr.colorM3Primary), 0.05f)), !UiUtils.isDarkTheme());

TextView handleTitle=findViewById(R.id.handle_title);
RippleAnimationTextView handle=findViewById(R.id.handle);
TextView usernameExplanation=findViewById(R.id.username_text);
TextView serverExplanation=findViewById(R.id.server_text);
TextView handleExplanation=findViewById(R.id.handle_explanation);
findViewById(R.id.btn_cancel).setOnClickListener(v->dismiss());

String domain=account.getDomain();
if(TextUtils.isEmpty(domain))
domain=AccountSessionManager.get(accountID).domain;
handleStr="@"+account.username+"@"+domain;
boolean isSelf=AccountSessionManager.getInstance().isSelf(accountID, account);

handleTitle.setText(isSelf ? R.string.handle_title_own : R.string.handle_title);
handle.setText(handleStr);
usernameExplanation.setText(isSelf ? R.string.handle_username_explanation_own : R.string.handle_username_explanation);
serverExplanation.setText(isSelf ? R.string.handle_server_explanation_own : R.string.handle_server_explanation);

String explanation=context.getString(isSelf ? R.string.handle_explanation_own : R.string.handle_explanation);
SpannableStringBuilder ssb=new SpannableStringBuilder();
Jsoup.parseBodyFragment(explanation).body().traverse(new NodeVisitor(){
private int spanStart;
@Override
public void head(Node node, int depth){
if(node instanceof TextNode tn){
ssb.append(tn.text());
}else if(node instanceof Element){
spanStart=ssb.length();
}
}

@Override
public void tail(Node node, int depth){
if(node instanceof Element){
ssb.setSpan(new LinkSpan("", DecentralizationExplainerSheet.this::showActivityPubAlert, LinkSpan.Type.CUSTOM, null, null, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
});
handleExplanation.setText(ssb);

findViewById(R.id.handle_wrap).setOnClickListener(v->{
context.getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText(null, handleStr));
if(UiUtils.needShowClipboardToast()){
new Snackbar.Builder(context)
.setText(R.string.handle_copied)
.show();
}
});
String _domain=domain;
findViewById(R.id.username_row).setOnClickListener(v->handle.animate(1, account.username.length()+1));
findViewById(R.id.server_row).setOnClickListener(v->handle.animate(handleStr.length()-_domain.length(), handleStr.length()));
}

private void showActivityPubAlert(LinkSpan s){
new M3AlertDialogBuilder(getContext())
.setTitle(R.string.what_is_activitypub_title)
.setMessage(R.string.what_is_activitypub)
.setPositiveButton(R.string.ok, null)
.show();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.joinmastodon.android.ui.text;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.style.ImageSpan;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class ImageSpanThatDoesNotBreakShitForNoGoodReason extends ImageSpan{
public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Bitmap b){
super(b);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Bitmap b, int verticalAlignment){
super(b, verticalAlignment);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Context context, @NonNull Bitmap bitmap){
super(context, bitmap);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Context context, @NonNull Bitmap bitmap, int verticalAlignment){
super(context, bitmap, verticalAlignment);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Drawable drawable){
super(drawable);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Drawable drawable, int verticalAlignment){
super(drawable, verticalAlignment);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Drawable drawable, @NonNull String source){
super(drawable, source);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Drawable drawable, @NonNull String source, int verticalAlignment){
super(drawable, source, verticalAlignment);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Context context, @NonNull Uri uri){
super(context, uri);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Context context, @NonNull Uri uri, int verticalAlignment){
super(context, uri, verticalAlignment);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Context context, int resourceId){
super(context, resourceId);
}

public ImageSpanThatDoesNotBreakShitForNoGoodReason(@NonNull Context context, int resourceId, int verticalAlignment){
super(context, resourceId, verticalAlignment);
}

@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm){
// Purposefully not touching the font metrics
return getDrawable().getBounds().right;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -929,11 +929,15 @@ public static void openSystemShareSheet(Context context, String url){
public static void maybeShowTextCopiedToast(Context context){
//show toast, android from S_V2 on has built-in popup, as documented in
//https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications
if(Build.VERSION.SDK_INT<=Build.VERSION_CODES.S_V2){
if(needShowClipboardToast()){
Toast.makeText(context, R.string.text_copied, Toast.LENGTH_SHORT).show();
}
}

public static boolean needShowClipboardToast(){
return Build.VERSION.SDK_INT<=Build.VERSION_CODES.S_V2;
}

public static void setAllPaddings(View view, int paddingDp){
int pad=V.dp(paddingDp);
view.setPadding(pad, pad, pad, pad);
Expand Down
Loading

0 comments on commit 8dffbff

Please sign in to comment.