Compose M3 redesign wip

This commit is contained in:
Grishka 2023-05-09 21:34:42 +03:00
parent 2b8451e045
commit 642e96a439
61 changed files with 2300 additions and 870 deletions

View File

@ -1,10 +1,18 @@
package org.joinmastodon.android.fragments;
import android.app.Activity;
import android.content.res.TypedArray;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.text.SpannableStringBuilder;
import android.text.style.BulletSpan;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -12,28 +20,34 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.statuses.UpdateAttachment;
import org.joinmastodon.android.api.MastodonAPIController;
import org.joinmastodon.android.model.Attachment;
import org.parceler.Parcels;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.FixedAspectRatioImageView;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.fragments.ToolbarFragment;
import java.util.Collections;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import me.grishka.appkit.fragments.OnBackPressedListener;
import me.grishka.appkit.imageloader.ViewImageLoader;
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
import me.grishka.appkit.utils.V;
public class ComposeImageDescriptionFragment extends MastodonToolbarFragment{
public class ComposeImageDescriptionFragment extends MastodonToolbarFragment implements OnBackPressedListener{
private static final String TAG="ComposeImageDescription";
private String accountID, attachmentID;
private EditText edit;
private Button saveButton;
private FixedAspectRatioImageView image;
private ContextThemeWrapper themeWrapper;
private PhotoViewer photoViewer;
@Override
public void onCreate(Bundle savedInstanceState){
@ -46,7 +60,13 @@ public class ComposeImageDescriptionFragment extends MastodonToolbarFragment{
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
setTitle(R.string.edit_image);
themeWrapper=new ContextThemeWrapper(activity, R.style.Theme_Mastodon_Dark);
setTitle(R.string.add_alt_text);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return super.onCreateView(themeWrapper.getSystemService(LayoutInflater.class), container, savedInstanceState);
}
@Override
@ -54,14 +74,48 @@ public class ComposeImageDescriptionFragment extends MastodonToolbarFragment{
View view=inflater.inflate(R.layout.fragment_image_description, container, false);
edit=view.findViewById(R.id.edit);
ImageView image=view.findViewById(R.id.photo);
image=view.findViewById(R.id.photo);
int width=getArguments().getInt("width", 0);
int height=getArguments().getInt("height", 0);
if(width>0 && height>0){
image.setAspectRatio(Math.max(1f, (float)width/height));
}
image.setOnClickListener(v->openPhotoViewer());
Uri uri=getArguments().getParcelable("uri");
ViewImageLoader.load(image, null, new UrlImageLoaderRequest(uri, 1000, 1000));
Attachment.Type type=Attachment.Type.valueOf(getArguments().getString("attachmentType"));
if(type==Attachment.Type.IMAGE)
ViewImageLoader.load(image, null, new UrlImageLoaderRequest(uri, 1000, 1000));
else
loadVideoThumbIntoView(image, uri);
edit.setText(getArguments().getString("existingDescription"));
return view;
}
private void loadVideoThumbIntoView(ImageView target, Uri uri){
MastodonAPIController.runInBackground(()->{
Context context=getActivity();
if(context==null)
return;
try{
MediaMetadataRetriever mmr=new MediaMetadataRetriever();
mmr.setDataSource(context, uri);
Bitmap frame=mmr.getFrameAtTime(3_000_000);
mmr.release();
int size=Math.max(frame.getWidth(), frame.getHeight());
int maxSize=V.dp(250);
if(size>maxSize){
float factor=maxSize/(float)size;
frame=Bitmap.createScaledBitmap(frame, Math.round(frame.getWidth()*factor), Math.round(frame.getHeight()*factor), true);
}
Bitmap finalFrame=frame;
target.post(()->target.setImageBitmap(finalFrame));
}catch(Exception x){
Log.w(TAG, "loadVideoThumbIntoView: error getting video frame", x);
}
});
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
@ -71,43 +125,114 @@ public class ComposeImageDescriptionFragment extends MastodonToolbarFragment{
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
TypedArray ta=getActivity().obtainStyledAttributes(new int[]{R.attr.secondaryButtonStyle});
int buttonStyle=ta.getResourceId(0, 0);
ta.recycle();
saveButton=new Button(getActivity(), null, 0, buttonStyle);
saveButton.setText(R.string.save);
saveButton.setOnClickListener(this::onSaveClick);
FrameLayout wrap=new FrameLayout(getActivity());
wrap.addView(saveButton, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.TOP|Gravity.LEFT));
wrap.setPadding(V.dp(16), V.dp(4), V.dp(16), V.dp(8));
wrap.setClipToPadding(false);
MenuItem item=menu.add(R.string.publish);
item.setActionView(wrap);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
inflater.inflate(R.menu.compose_image_description, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId()==R.id.help){
SpannableStringBuilder msg=new SpannableStringBuilder(getText(R.string.alt_text_help));
BulletSpan[] spans=msg.getSpans(0, msg.length(), BulletSpan.class);
for(BulletSpan span:spans){
BulletSpan betterSpan;
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.Q)
betterSpan=new BulletSpan(V.dp(10), UiUtils.getThemeColor(themeWrapper, R.attr.colorM3OnSurface));
else
betterSpan=new BulletSpan(V.dp(10), UiUtils.getThemeColor(themeWrapper, R.attr.colorM3OnSurface), V.dp(1.5f));
msg.setSpan(betterSpan, msg.getSpanStart(span), msg.getSpanEnd(span), msg.getSpanFlags(span));
msg.removeSpan(span);
}
new M3AlertDialogBuilder(themeWrapper)
.setTitle(R.string.what_is_alt_text)
.setMessage(msg)
.setPositiveButton(R.string.ok, null)
.show();
}
return true;
}
private void onSaveClick(View v){
new UpdateAttachment(attachmentID, edit.getText().toString().trim())
.setCallback(new Callback<>(){
@Override
public void onSuccess(Attachment result){
Bundle r=new Bundle();
r.putParcelable("attachment", Parcels.wrap(result));
setResult(true, r);
Nav.finish(ComposeImageDescriptionFragment.this);
}
@Override
public boolean onBackPressed(){
deliverResult();
return false;
}
@Override
public void onError(ErrorResponse error){
error.showToast(getActivity());
}
})
.wrapProgress(getActivity(), R.string.saving, false)
.exec(accountID);
@Override
protected LayoutInflater getToolbarLayoutInflater(){
return LayoutInflater.from(themeWrapper);
}
private void deliverResult(){
Bundle r=new Bundle();
r.putString("text", edit.getText().toString().trim());
r.putString("attachment", attachmentID);
setResult(true, r);
}
private void openPhotoViewer(){
Attachment fakeAttachment=new Attachment();
fakeAttachment.id="local";
fakeAttachment.type=Attachment.Type.valueOf(getArguments().getString("attachmentType"));
int width=getArguments().getInt("width", 0);
int height=getArguments().getInt("height", 0);
Uri uri=getArguments().getParcelable("uri");
fakeAttachment.url=uri.toString();
fakeAttachment.meta=new Attachment.Metadata();
fakeAttachment.meta.width=width;
fakeAttachment.meta.height=height;
photoViewer=new PhotoViewer(getActivity(), Collections.singletonList(fakeAttachment), 0, new PhotoViewer.Listener(){
@Override
public void setPhotoViewVisibility(int index, boolean visible){
image.setAlpha(visible ? 1f : 0f);
}
@Override
public boolean startPhotoViewTransition(int index, @NonNull Rect outRect, @NonNull int[] outCornerRadius){
int[] pos={0, 0};
image.getLocationOnScreen(pos);
outRect.set(pos[0], pos[1], pos[0]+image.getWidth(), pos[1]+image.getHeight());
image.setElevation(1f);
return true;
}
@Override
public void setTransitioningViewTransform(float translateX, float translateY, float scale){
image.setTranslationX(translateX);
image.setTranslationY(translateY);
image.setScaleX(scale);
image.setScaleY(scale);
}
@Override
public void endPhotoViewTransition(){
Drawable d=image.getDrawable();
image.setImageDrawable(null);
image.setImageDrawable(d);
image.setTranslationX(0f);
image.setTranslationY(0f);
image.setScaleX(1f);
image.setScaleY(1f);
image.setElevation(0f);
}
@Nullable
@Override
public Drawable getPhotoViewCurrentDrawable(int index){
return image.getDrawable();
}
@Override
public void photoViewerDismissed(){
photoViewer=null;
}
@Override
public void onRequestPermissions(String[] permissions){
}
});
photoViewer.removeMenu();
}
}

View File

@ -11,6 +11,15 @@ import androidx.annotation.CallSuper;
import me.grishka.appkit.fragments.ToolbarFragment;
public abstract class MastodonToolbarFragment extends ToolbarFragment{
public MastodonToolbarFragment(){
super();
}
protected MastodonToolbarFragment(int layout){
super(layout);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);

View File

@ -387,6 +387,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
@Override
public void onPageScrollStateChanged(int state){
if(isInEditMode)
return;
refreshLayout.setEnabled(state!=ViewPager2.SCROLL_STATE_DRAGGING);
}
});
@ -801,6 +803,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
bioEdit.setText(account.source.note);
aboutFragment.enterEditMode(account.source.fields);
refreshLayout.setEnabled(false);
}
private void exitEditMode(){
@ -840,6 +843,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
username.setVisibility(View.VISIBLE);
bio.setVisibility(View.VISIBLE);
countersLayout.setVisibility(View.VISIBLE);
refreshLayout.setEnabled(true);
bindHeaderView();
}

View File

@ -1,6 +1,8 @@
package org.joinmastodon.android.ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
@ -19,7 +21,6 @@ import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.Hashtag;
import org.joinmastodon.android.model.SearchResults;
import org.joinmastodon.android.ui.drawables.ComposeAutocompleteBackgroundDrawable;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
import org.joinmastodon.android.ui.utils.UiUtils;
@ -60,7 +61,6 @@ public class ComposeAutocompleteViewController{
private APIRequest currentRequest;
private Runnable usersDebouncer=this::doSearchUsers, hashtagsDebouncer=this::doSearchHashtags;
private String lastText;
private ComposeAutocompleteBackgroundDrawable background;
private boolean listIsHidden=true;
private UsersAdapter usersAdapter;
@ -69,19 +69,25 @@ public class ComposeAutocompleteViewController{
private Consumer<String> completionSelectedListener;
private DividerItemDecoration usersDividers, hashtagsDividers;
public ComposeAutocompleteViewController(Activity activity, String accountID){
this.activity=activity;
this.accountID=accountID;
background=new ComposeAutocompleteBackgroundDrawable(UiUtils.getThemeColor(activity, android.R.attr.colorBackground));
contentView=new FrameLayout(activity);
contentView.setBackground(background);
list=new UsableRecyclerView(activity);
list.setLayoutManager(new LinearLayoutManager(activity));
list.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false));
list.setItemAnimator(new BetterItemAnimator());
list.setVisibility(View.GONE);
list.setPadding(V.dp(16), V.dp(12), V.dp(16), V.dp(12));
list.setClipToPadding(false);
list.setSelector(null);
list.addItemDecoration(new RecyclerView.ItemDecoration(){
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
if(parent.getChildAdapterPosition(view)<parent.getAdapter().getItemCount()-1)
outRect.right=V.dp(8);
}
});
contentView.addView(list, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
progress=new ProgressBar(activity);
@ -89,9 +95,6 @@ public class ComposeAutocompleteViewController{
progressLP.topMargin=V.dp(16);
contentView.addView(progress, progressLP);
usersDividers=new DividerItemDecoration(activity, R.attr.colorPollVoted, 1, 72, 16);
hashtagsDividers=new DividerItemDecoration(activity, R.attr.colorPollVoted, 1, 16, 16);
imgLoader=new ListImageLoaderWrapper(activity, list, new RecyclerViewDelegate(list), null);
}
@ -141,11 +144,6 @@ public class ComposeAutocompleteViewController{
progress.setVisibility(View.GONE);
listIsHidden=false;
}
if((prevMode==Mode.HASHTAGS)!=(mode==Mode.HASHTAGS) || prevMode==null){
if(prevMode!=null)
list.removeItemDecoration(prevMode==Mode.HASHTAGS ? hashtagsDividers : usersDividers);
list.addItemDecoration(mode==Mode.HASHTAGS ? hashtagsDividers : usersDividers);
}
}
lastText=text;
if(mode==Mode.USERS){
@ -176,10 +174,6 @@ public class ComposeAutocompleteViewController{
this.completionSelectedListener=completionSelectedListener;
}
public void setArrowOffset(int offset){
background.setArrowOffset(offset);
}
public View getView(){
return contentView;
}
@ -258,7 +252,7 @@ public class ComposeAutocompleteViewController{
@Override
public int getImageCountForItem(int position){
return 1+users.get(position).emojiHelper.getImageCount();
return 1/*+users.get(position).emojiHelper.getImageCount()*/;
}
@Override
@ -272,20 +266,18 @@ public class ComposeAutocompleteViewController{
private class UserViewHolder extends BindableViewHolder<WrappedAccount> implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{
private final ImageView ava;
private final TextView name, username;
private final TextView username;
private UserViewHolder(){
super(activity, R.layout.item_autocomplete_user, list);
ava=findViewById(R.id.photo);
name=findViewById(R.id.name);
username=findViewById(R.id.username);
ava.setOutlineProvider(OutlineProviders.roundedRect(12));
ava.setOutlineProvider(OutlineProviders.OVAL);
ava.setClipToOutline(true);
}
@Override
public void onBind(WrappedAccount item){
name.setText(item.parsedName);
username.setText("@"+item.account.acct);
}
@ -300,7 +292,6 @@ public class ComposeAutocompleteViewController{
ava.setImageDrawable(image);
}else{
item.emojiHelper.setImageDrawable(index-1, image);
name.invalidate();
}
}
@ -333,17 +324,11 @@ public class ComposeAutocompleteViewController{
private final TextView text;
private HashtagViewHolder(){
super(new TextView(activity));
super(activity, R.layout.item_autocomplete_hashtag, list);
text=(TextView) itemView;
text.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(48)));
text.setTextAppearance(R.style.m3_title_medium);
text.setTypeface(Typeface.DEFAULT);
text.setSingleLine();
text.setEllipsize(TextUtils.TruncateAt.END);
text.setGravity(Gravity.CENTER_VERTICAL);
text.setPadding(V.dp(16), 0, V.dp(16), 0);
}
@SuppressLint("SetTextI18n")
@Override
public void onBind(Hashtag item){
text.setText("#"+item.name);
@ -395,7 +380,7 @@ public class ComposeAutocompleteViewController{
private EmojiViewHolder(){
super(activity, R.layout.item_autocomplete_user, list);
ava=findViewById(R.id.photo);
name=findViewById(R.id.name);
name=findViewById(R.id.username);
}
@Override
@ -408,6 +393,7 @@ public class ComposeAutocompleteViewController{
ava.setImageDrawable(null);
}
@SuppressLint("SetTextI18n")
@Override
public void onBind(WrappedEmoji item){
name.setText(":"+item.emoji.shortcode+":");

View File

@ -1,84 +0,0 @@
package org.joinmastodon.android.ui.drawables;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import me.grishka.appkit.utils.V;
public class ComposeAutocompleteBackgroundDrawable extends Drawable{
private Path path=new Path();
private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
private int fillColor, arrowOffset;
public ComposeAutocompleteBackgroundDrawable(int fillColor){
this.fillColor=fillColor;
}
@Override
public void draw(@NonNull Canvas canvas){
Rect bounds=getBounds();
canvas.save();
canvas.translate(bounds.left, bounds.top);
paint.setColor(0x80000000);
canvas.drawPath(path, paint);
canvas.translate(0, V.dp(1));
paint.setColor(fillColor);
canvas.drawPath(path, paint);
int arrowSize=V.dp(10);
canvas.drawRect(0, arrowSize, bounds.width(), bounds.height(), paint);
canvas.restore();
}
@Override
public void setAlpha(int alpha){
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter){
}
@Override
public int getOpacity(){
return PixelFormat.TRANSLUCENT;
}
public void setArrowOffset(int offset){
arrowOffset=offset;
updatePath();
invalidateSelf();
}
@Override
protected void onBoundsChange(Rect bounds){
super.onBoundsChange(bounds);
updatePath();
}
@Override
public boolean getPadding(@NonNull Rect padding){
padding.top=V.dp(11);
return true;
}
private void updatePath(){
path.rewind();
int arrowSize=V.dp(10);
path.moveTo(0, arrowSize*2);
path.lineTo(0, arrowSize);
path.lineTo(arrowOffset-arrowSize, arrowSize);
path.lineTo(arrowOffset, 0);
path.lineTo(arrowOffset+arrowSize, arrowSize);
path.lineTo(getBounds().width(), arrowSize);
path.lineTo(getBounds().width(), arrowSize*2);
path.close();
}
}

View File

@ -259,6 +259,10 @@ public class PhotoViewer implements ZoomPanView.Listener{
});
}
public void removeMenu(){
toolbar.getMenu().clear();
}
@Override
public void onTransitionAnimationUpdate(float translateX, float translateY, float scale){
listener.setTransitioningViewTransform(translateX, translateY, scale);

View File

@ -0,0 +1,67 @@
package org.joinmastodon.android.ui.text;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import org.joinmastodon.android.R;
import org.joinmastodon.android.ui.utils.UiUtils;
public class LengthLimitHighlighter implements TextWatcher{
private final Context context;
private final int lengthLimit;
private BackgroundColorSpan overLimitBG;
private ForegroundColorSpan overLimitFG;
private boolean isOverLimit;
private OverLimitChangeListener listener;
public LengthLimitHighlighter(Context context, int lengthLimit){
this.context=context;
overLimitBG=new BackgroundColorSpan(UiUtils.getThemeColor(context, R.attr.colorM3ErrorContainer));
overLimitFG=new ForegroundColorSpan(UiUtils.getThemeColor(context, R.attr.colorM3Error));
this.lengthLimit=lengthLimit;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
}
@Override
public void afterTextChanged(Editable s){
s.removeSpan(overLimitBG);
s.removeSpan(overLimitFG);
boolean newOverLimit=s.length()>lengthLimit;
if(newOverLimit){
int start=s.length()-(s.length()-lengthLimit);
int end=s.length();
s.setSpan(overLimitFG, start, end, 0);
s.setSpan(overLimitBG, start, end, 0);
}
if(newOverLimit!=isOverLimit){
isOverLimit=newOverLimit;
if(listener!=null)
listener.onOverLimitChanged(isOverLimit);
}
}
public LengthLimitHighlighter setListener(OverLimitChangeListener listener){
this.listener=listener;
return this;
}
public boolean isOverLimit(){
return isOverLimit;
}
public interface OverLimitChangeListener{
void onOverLimitChanged(boolean isOverLimit);
}
}

View File

@ -11,7 +11,6 @@ import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
@ -27,9 +26,15 @@ import android.provider.OpenableColumns;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.transition.ChangeBounds;
import android.transition.ChangeScroll;
import android.transition.Fade;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.PopupMenu;
@ -86,6 +91,7 @@ import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.imageloader.ViewImageLoader;
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
import okhttp3.MediaType;
@ -642,6 +648,10 @@ public class UiUtils{
return 0xFF000000 | (r << 16) | (g << 8) | b;
}
public static int alphaBlendThemeColors(Context context, @AttrRes int color1, @AttrRes int color2, float alpha){
return alphaBlendColors(getThemeColor(context, color1), getThemeColor(context, color2), alpha);
}
/**
* Check to see if Android platform photopicker is available on the device\
*
@ -713,4 +723,14 @@ public class UiUtils{
else
return String.format("%d:%02d", seconds/60, seconds%60);
}
public static void beginLayoutTransition(ViewGroup sceneRoot){
TransitionManager.beginDelayedTransition(sceneRoot, new TransitionSet()
.addTransition(new Fade(Fade.IN | Fade.OUT))
.addTransition(new ChangeBounds())
.addTransition(new ChangeScroll())
.setDuration(250)
.setInterpolator(CubicBezierInterpolator.DEFAULT)
);
}
}

View File

@ -0,0 +1,50 @@
package org.joinmastodon.android.ui.views;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Checkable;
import android.widget.LinearLayout;
public class CheckableLinearLayout extends LinearLayout implements Checkable{
private boolean checked;
private static final int[] CHECKED_STATE_SET = {
android.R.attr.state_checked
};
public CheckableLinearLayout(Context context){
this(context, null);
}
public CheckableLinearLayout(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
}
@Override
public void setChecked(boolean checked){
this.checked=checked;
refreshDrawableState();
}
@Override
public boolean isChecked(){
return checked;
}
@Override
public void toggle(){
setChecked(!checked);
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
}

View File

@ -0,0 +1,36 @@
package org.joinmastodon.android.ui.views;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
public class FixedAspectRatioImageView extends ImageView{
private float aspectRatio=1;
public FixedAspectRatioImageView(Context context){
this(context, null);
}
public FixedAspectRatioImageView(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public FixedAspectRatioImageView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int width=MeasureSpec.getSize(widthMeasureSpec);
heightMeasureSpec=Math.round(width/aspectRatio) | MeasureSpec.EXACTLY;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public float getAspectRatio(){
return aspectRatio;
}
public void setAspectRatio(float aspectRatio){
this.aspectRatio=aspectRatio;
}
}

View File

@ -127,7 +127,12 @@ public class FloatingHintEditTextLayout extends FrameLayout implements CustomVie
edit.getViewTreeObserver().removeOnPreDrawListener(this);
float scale=edit.getLineHeight()/(float)label.getLineHeight();
float transY=edit.getHeight()/2f-edit.getLineHeight()/2f+(edit.getTop()-label.getTop())-(label.getHeight()/2f-label.getLineHeight()/2f);
float transY;
if((edit.getGravity() & Gravity.TOP)==Gravity.TOP){
transY=edit.getPaddingTop()+(edit.getTop()-label.getTop())-(label.getHeight()/2f-label.getLineHeight()/2f);
}else{
transY=edit.getHeight()/2f-edit.getLineHeight()/2f+(edit.getTop()-label.getTop())-(label.getHeight()/2f-label.getLineHeight()/2f);
}
AnimatorSet anim=new AnimatorSet();
if(hintVisible){

View File

@ -0,0 +1,36 @@
package org.joinmastodon.android.ui.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
public class HorizontalScrollViewThatRespectsMatchParent extends HorizontalScrollView{
public HorizontalScrollViewThatRespectsMatchParent(Context context){
super(context);
}
public HorizontalScrollViewThatRespectsMatchParent(Context context, AttributeSet attrs){
super(context, attrs);
}
public HorizontalScrollViewThatRespectsMatchParent(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
if(getChildCount()==0)
return;
View child=getChildAt(0);
ViewGroup.LayoutParams lp=child.getLayoutParams();
if(lp.width==ViewGroup.LayoutParams.MATCH_PARENT){
int hms=getChildMeasureSpec(heightMeasureSpec, getPaddingTop()+getPaddingBottom(), lp.height);
child.measure(MeasureSpec.getSize(widthMeasureSpec) | MeasureSpec.EXACTLY, hms);
setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight());
return;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

View File

@ -6,19 +6,48 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
import org.joinmastodon.android.R;
import androidx.annotation.Nullable;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.CustomViewHelper;
import me.grishka.appkit.utils.V;
public class ReorderableLinearLayout extends LinearLayout{
public class ReorderableLinearLayout extends LinearLayout implements CustomViewHelper{
private static final String TAG="ReorderableLinearLayout";
private static final Interpolator sDragScrollInterpolator=t->t * t * t * t * t;
private static final Interpolator sDragViewScrollCapInterpolator=t->{
t -= 1.0f;
return t * t * t * t * t + 1.0f;
};
private static final long DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
private View draggedView;
private View bottomSibling, topSibling;
private float startY;
private float startX, startY, dX, dY, viewStartX, viewStartY;
private OnDragListener dragListener;
private boolean moveInBothDimensions;
private int edgeSize;
private View scrollableParent;
private long dragScrollStartTime;
private int cachedMaxScrollSpeed=-1;
final Runnable scrollRunnable= new Runnable() {
@Override
public void run() {
if (draggedView != null && scrollIfNecessary()) {
if (draggedView != null) { //it might be lost during scrolling
// moveIfNecessary(mSelected);
}
removeCallbacks(scrollRunnable);
postOnAnimation(this);
}
}
};
public ReorderableLinearLayout(Context context){
super(context);
@ -30,12 +59,13 @@ public class ReorderableLinearLayout extends LinearLayout{
public ReorderableLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
edgeSize=dp(20);
}
public void startDragging(View child){
getParent().requestDisallowInterceptTouchEvent(true);
draggedView=child;
draggedView.animate().translationZ(V.dp(1f)).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
dragListener.onDragStart(draggedView);
int index=indexOfChild(child);
if(index==-1)
@ -44,11 +74,30 @@ public class ReorderableLinearLayout extends LinearLayout{
topSibling=getChildAt(index-1);
if(index<getChildCount()-1)
bottomSibling=getChildAt(index+1);
scrollableParent=findScrollableParent(this);
viewStartX=child.getX();
viewStartY=child.getY();
}
private View findScrollableParent(View child){
if(getOrientation()==VERTICAL){
if(child.canScrollVertically(-1) || child.canScrollVertically(1))
return child;
}else{
if(child.canScrollHorizontally(-1) || child.canScrollHorizontally(1))
return child;
}
if(child.getParent() instanceof View v)
return findScrollableParent(v);
return null;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev){
if(draggedView!=null){
startX=ev.getX();
startY=ev.getY();
return true;
}
@ -60,34 +109,61 @@ public class ReorderableLinearLayout extends LinearLayout{
if(draggedView!=null){
if(ev.getAction()==MotionEvent.ACTION_UP || ev.getAction()==MotionEvent.ACTION_CANCEL){
endDrag();
removeCallbacks(scrollRunnable);
draggedView=null;
bottomSibling=null;
topSibling=null;
}else if(ev.getAction()==MotionEvent.ACTION_MOVE){
draggedView.setTranslationY(ev.getY()-startY);
if(topSibling!=null && draggedView.getY()<=topSibling.getY()){
moveDraggedView(-1);
}else if(bottomSibling!=null && draggedView.getY()>=bottomSibling.getY()){
moveDraggedView(1);
dX=ev.getX()-startX;
dY=ev.getY()-startY;
if(moveInBothDimensions){
draggedView.setTranslationX(dX);
draggedView.setTranslationY(dY);
}else if(getOrientation()==VERTICAL){
draggedView.setTranslationY(dY);
}else{
draggedView.setTranslationX(dX);
}
removeCallbacks(scrollRunnable);
scrollRunnable.run();
if(getOrientation()==VERTICAL){
if(topSibling!=null && draggedView.getY()<=topSibling.getY()){
moveDraggedView(-1);
}else if(bottomSibling!=null && draggedView.getY()>=bottomSibling.getY()){
moveDraggedView(1);
}
}else{
if(topSibling!=null && draggedView.getX()<=topSibling.getX()){
moveDraggedView(-1);
}else if(bottomSibling!=null && draggedView.getX()>=bottomSibling.getX()){
moveDraggedView(1);
}
}
dragListener.onDragMove(draggedView);
}
}
return super.onTouchEvent(ev);
}
private void endDrag(){
draggedView.animate().translationY(0f).translationZ(0f).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
dragListener.onDragEnd(draggedView);
}
private void moveDraggedView(int positionOffset){
int index=indexOfChild(draggedView);
int prevTop=draggedView.getTop();
boolean isVertical=getOrientation()==VERTICAL;
int prevOffset=isVertical ? draggedView.getTop() : draggedView.getLeft();
removeView(draggedView);
int prevIndex=index;
index+=positionOffset;
addView(draggedView, index);
final View prevSibling=positionOffset<0 ? topSibling : bottomSibling;
int prevSiblingTop=prevSibling.getTop();
int prevSiblingOffset=isVertical ? prevSibling.getTop() : prevSibling.getLeft();
if(index>0)
topSibling=getChildAt(index-1);
else
@ -101,11 +177,20 @@ public class ReorderableLinearLayout extends LinearLayout{
@Override
public boolean onPreDraw(){
draggedView.getViewTreeObserver().removeOnPreDrawListener(this);
float offset=prevTop-draggedView.getTop();
startY-=offset;
draggedView.setTranslationY(draggedView.getTranslationY()+offset);
prevSibling.setTranslationY(prevSiblingTop-prevSibling.getTop());
prevSibling.animate().translationY(0f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(200).start();
float offset=prevOffset-(isVertical ? draggedView.getTop() : draggedView.getLeft());
if(isVertical){
startY-=offset;
viewStartY-=offset;
draggedView.setTranslationY(draggedView.getTranslationY()+offset);
prevSibling.setTranslationY(prevSiblingOffset-prevSibling.getTop());
prevSibling.animate().translationY(0f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(200).start();
}else{
startX-=offset;
viewStartX-=offset;
draggedView.setTranslationX(draggedView.getTranslationX()+offset);
prevSibling.setTranslationX(prevSiblingOffset-prevSibling.getLeft());
prevSibling.animate().translationX(0f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(200).start();
}
return true;
}
});
@ -115,7 +200,105 @@ public class ReorderableLinearLayout extends LinearLayout{
this.dragListener=dragListener;
}
public boolean isMoveInBothDimensions(){
return moveInBothDimensions;
}
public void setMoveInBothDimensions(boolean moveInBothDimensions){
this.moveInBothDimensions=moveInBothDimensions;
}
boolean scrollIfNecessary(){
if(draggedView==null || scrollableParent==null){
dragScrollStartTime=Long.MIN_VALUE;
return false;
}
final long now=System.currentTimeMillis();
final long scrollDuration=dragScrollStartTime==Long.MIN_VALUE ? 0 : now-dragScrollStartTime;
int scrollX=0;
int scrollY=0;
if(getOrientation()==HORIZONTAL){
int curX=(int) (viewStartX+dX)-scrollableParent.getScrollX();
final int leftDiff=curX-getPaddingLeft();
if(dX<0 && leftDiff<0){
scrollX=leftDiff;
}else if(dX>0){
final int rightDiff=curX+draggedView.getWidth()-(scrollableParent.getWidth()-getPaddingRight());
if(rightDiff>0){
scrollX=rightDiff;
}
}
}else{
int curY=(int) (viewStartY+dY)-scrollableParent.getScrollY();
final int topDiff=curY-getPaddingTop();
if(dY<0 && topDiff<0){
scrollY=topDiff;
}else if(dY>0){
final int bottomDiff=curY+draggedView.getHeight()-(scrollableParent.getHeight()-getPaddingBottom());
if(bottomDiff>0){
scrollY=bottomDiff;
}
}
}
if(scrollX!=0){
scrollX=interpolateOutOfBoundsScroll(draggedView.getWidth(), scrollX, scrollableParent.getWidth(), scrollDuration);
}
if(scrollY!=0){
scrollY=interpolateOutOfBoundsScroll(draggedView.getHeight(), scrollY, scrollableParent.getHeight(), scrollDuration);
}
if(scrollX!=0 || scrollY!=0){
if(dragScrollStartTime==Long.MIN_VALUE){
dragScrollStartTime=now;
}
int prevX=scrollableParent.getScrollX();
int prevY=scrollableParent.getScrollY();
scrollableParent.scrollBy(scrollX, scrollY);
draggedView.setTranslationX(draggedView.getTranslationX()-(scrollableParent.getScrollX()-prevX));
draggedView.setTranslationY(draggedView.getTranslationY()-(scrollableParent.getScrollY()-prevY));
return true;
}
dragScrollStartTime=Long.MIN_VALUE;
return false;
}
public int interpolateOutOfBoundsScroll(int viewSize, int viewSizeOutOfBounds, int totalSize, long msSinceStartScroll){
final int maxScroll=getMaxDragScroll();
final int absOutOfBounds=Math.abs(viewSizeOutOfBounds);
final int direction=(int) Math.signum(viewSizeOutOfBounds);
// might be negative if other direction
float outOfBoundsRatio=Math.min(1f, 1f*absOutOfBounds/viewSize);
final int cappedScroll=(int) (direction*maxScroll*sDragViewScrollCapInterpolator.getInterpolation(outOfBoundsRatio));
final float timeRatio;
if(msSinceStartScroll>DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS){
timeRatio=1f;
}else{
timeRatio=(float) msSinceStartScroll/DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS;
}
final int value=(int) (cappedScroll*sDragScrollInterpolator.getInterpolation(timeRatio));
if(value==0){
return viewSizeOutOfBounds>0 ? 1 : -1;
}
return value;
}
private int getMaxDragScroll(){
if(cachedMaxScrollSpeed==-1){
cachedMaxScrollSpeed=getResources().getDimensionPixelSize(R.dimen.item_touch_helper_max_drag_scroll_per_frame);
}
return cachedMaxScrollSpeed;
}
public interface OnDragListener{
void onSwapItems(int oldIndex, int newIndex);
default void onDragStart(View view){
view.animate().translationZ(V.dp(3f)).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
default void onDragEnd(View view){
view.animate().translationY(0f).translationX(0f).translationZ(0f).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
default void onDragMove(View view){}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?colorM3OnSurfaceVariant" android:state_enabled="true"/>
<item android:color="?colorM3OnSurfaceVariant" android:alpha="0.38"/>
</selector>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?android:textColorPrimary" android:alpha="0.3" android:state_enabled="false"/>
<item android:color="?android:textColorPrimary"/>
<item android:color="?colorM3OnSurfaceVariant" android:alpha="0.3" android:state_enabled="false"/>
<item android:color="?colorM3OnPrimary" android:state_selected="true"/>
<item android:color="?colorM3OnSurfaceVariant"/>
</selector>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?colorM3OnPrimary" android:alpha="0.12"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android" android:inset="16dp">
<shape>
<solid android:color="?android:attr/colorBackground"/>
<corners android:radius="16dp"/>
<shape android:tint="@color/m3_primary_overlay" android:tintMode="src_atop">
<solid android:color="?colorM3Surface"/>
<corners android:radius="28dp"/>
</shape>
</inset>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:attr/colorControlHighlight">
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/m3_primary_overlay">
<item android:id="@android:id/mask">
<shape>
<solid android:color="#000"/>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android" android:inset="2dp">
<selector>
<item android:state_selected="true">
<ripple android:color="@color/m3_on_primary_overlay">
<item>
<shape>
<corners android:radius="4dp"/>
<solid android:color="?colorM3Primary"/>
</shape>
</item>
</ripple>
</item>
<item>
<ripple android:color="@color/m3_on_surface_variant_overlay">
<item android:id="@android:id/mask">
<shape>
<solid android:color="#000"/>
<corners android:radius="4dp"/>
</shape>
</item>
</ripple>
</item>
</selector>
</inset>

View File

@ -1,22 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="?colorSearchField"/>
<color android:color="?colorM3SurfaceVariant"/>
</item>
<item android:gravity="left" android:width="8dp">
<item android:height="1dp" android:gravity="bottom">
<selector>
<item android:state_focused="true">
<color android:color="?colorM3Primary"/>
</item>
<item>
<color android:color="?colorM3OnSurfaceVariant"/>
</item>
</selector>
</item>
<item android:gravity="left" android:width="5dp">
<shape>
<gradient android:type="linear" android:angle="270" android:startColor="#FEC84B" android:endColor="#F79009"/>
</shape>
</item>
<item android:id="@+id/left_drawable" android:width="8dp" android:gravity="left">
<item android:id="@+id/left_drawable" android:width="5dp" android:gravity="left">
<color android:color="#0f0"/>
</item>
<item android:gravity="right" android:width="8dp">
<item android:gravity="right" android:width="5dp">
<shape>
<gradient android:type="linear" android:angle="270" android:startColor="#FEC84B" android:endColor="#F79009"/>
</shape>
</item>
<item android:id="@+id/right_drawable" android:width="8dp" android:gravity="right">
<item android:id="@+id/right_drawable" android:width="5dp" android:gravity="right">
<color android:color="#0f0"/>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<stroke android:color="?colorM3Error" android:width="2dp"/>
<corners android:radius="4dp"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/m3_on_surface_overlay">
<item android:id="@android:id/mask">
<shape>
<solid android:color="#000"/>
<corners android:radius="4dp"/>
</shape>
</item>
</ripple>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:colorControlHighlight">
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/m3_on_surface_overlay">
<item android:id="@android:id/mask">
<shape android:shape="oval">
<solid android:color="#000"/>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?colorM3OutlineVariant"/>
<size android:width="1dp"/>
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:color="?colorM3OutlineVariant" android:width="1dp"/>
<corners android:radius="11dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M14,3V5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19H19Q19,19 19,19Q19,19 19,19V10H21V19Q21,19.825 20.413,20.413Q19.825,21 19,21H5Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3ZM19,3V5H21V7H19V9H17V7H15V5H17V3ZM6,17H18L14.25,12L11.25,16L9,13ZM5,5V8V10V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@android:color/white"
android:pathData="M10,18.333Q8.271,18.333 6.75,17.677Q5.229,17.021 4.104,15.896Q2.979,14.771 2.323,13.25Q1.667,11.729 1.667,10Q1.667,8.271 2.323,6.75Q2.979,5.229 4.104,4.104Q5.229,2.979 6.75,2.323Q8.271,1.667 10,1.667Q11.729,1.667 13.25,2.323Q14.771,2.979 15.896,4.104Q17.021,5.229 17.677,6.75Q18.333,8.271 18.333,10V11.271Q18.333,12.5 17.49,13.354Q16.646,14.208 15.417,14.208Q14.688,14.208 14.042,13.906Q13.396,13.604 12.958,13.042Q12.375,13.625 11.604,13.927Q10.833,14.229 10,14.229Q8.229,14.229 7,13Q5.771,11.771 5.771,10Q5.771,8.229 7,7Q8.229,5.771 10,5.771Q11.771,5.771 13,7Q14.229,8.229 14.229,10V11.271Q14.229,11.75 14.583,12.104Q14.938,12.458 15.417,12.458Q15.896,12.458 16.24,12.104Q16.583,11.75 16.583,11.271V10Q16.583,7.25 14.667,5.333Q12.75,3.417 10,3.417Q7.25,3.417 5.333,5.333Q3.417,7.25 3.417,10Q3.417,12.75 5.333,14.667Q7.25,16.583 10,16.583H14.125V18.333ZM10,12.479Q11.042,12.479 11.76,11.76Q12.479,11.042 12.479,10Q12.479,8.958 11.76,8.24Q11.042,7.521 10,7.521Q8.958,7.521 8.24,8.24Q7.521,8.958 7.521,10Q7.521,11.042 8.24,11.76Q8.958,12.479 10,12.479Z"/>
</vector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/ic_warning_fill1_24px"/>
<item android:drawable="@drawable/ic_warning_24px"/>
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/ic_mood_fill1_24px"/>
<item android:drawable="@drawable/ic_mood_24px"/>
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/ic_insert_chart_fill1_24px"/>
<item android:drawable="@drawable/ic_insert_chart_24px"/>
</selector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@android:color/white"
android:pathData="M7.5,16Q6.875,16 6.438,15.562Q6,15.125 6,14.5Q6,13.875 6.438,13.438Q6.875,13 7.5,13Q8.125,13 8.562,13.438Q9,13.875 9,14.5Q9,15.125 8.562,15.562Q8.125,16 7.5,16ZM12.5,16Q11.875,16 11.438,15.562Q11,15.125 11,14.5Q11,13.875 11.438,13.438Q11.875,13 12.5,13Q13.125,13 13.562,13.438Q14,13.875 14,14.5Q14,15.125 13.562,15.562Q13.125,16 12.5,16ZM7.5,11.5Q6.875,11.5 6.438,11.062Q6,10.625 6,10Q6,9.375 6.438,8.938Q6.875,8.5 7.5,8.5Q8.125,8.5 8.562,8.938Q9,9.375 9,10Q9,10.625 8.562,11.062Q8.125,11.5 7.5,11.5ZM12.5,11.5Q11.875,11.5 11.438,11.062Q11,10.625 11,10Q11,9.375 11.438,8.938Q11.875,8.5 12.5,8.5Q13.125,8.5 13.562,8.938Q14,9.375 14,10Q14,10.625 13.562,11.062Q13.125,11.5 12.5,11.5ZM7.5,7Q6.875,7 6.438,6.562Q6,6.125 6,5.5Q6,4.875 6.438,4.438Q6.875,4 7.5,4Q8.125,4 8.562,4.438Q9,4.875 9,5.5Q9,6.125 8.562,6.562Q8.125,7 7.5,7ZM12.5,7Q11.875,7 11.438,6.562Q11,6.125 11,5.5Q11,4.875 11.438,4.438Q11.875,4 12.5,4Q13.125,4 13.562,4.438Q14,4.875 14,5.5Q14,6.125 13.562,6.562Q13.125,7 12.5,7Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@android:color/white"
android:pathData="M2,16V14.083Q2,13.542 2.26,13.094Q2.521,12.646 2.979,12.375Q4.104,11.708 5.365,11.354Q6.625,11 8,11Q9.375,11 10.635,11.354Q11.896,11.708 13.021,12.375Q13.479,12.646 13.74,13.094Q14,13.542 14,14.083V16ZM15.5,16V14.083Q15.5,13.208 15.094,12.458Q14.688,11.708 14,11.229Q14.812,11.396 15.573,11.677Q16.333,11.958 17.021,12.375Q17.479,12.646 17.74,13.094Q18,13.542 18,14.083V16ZM8,10Q6.75,10 5.875,9.125Q5,8.25 5,7Q5,5.75 5.875,4.875Q6.75,4 8,4Q9.25,4 10.125,4.875Q11,5.75 11,7Q11,8.25 10.125,9.125Q9.25,10 8,10ZM12,10Q11.833,10 11.688,9.99Q11.542,9.979 11.375,9.938Q11.896,9.333 12.198,8.594Q12.5,7.854 12.5,7Q12.5,6.146 12.198,5.406Q11.896,4.667 11.375,4.062Q11.542,4.021 11.688,4.01Q11.833,4 12,4Q13.25,4 14.125,4.875Q15,5.75 15,7Q15,8.25 14.125,9.125Q13.25,10 12,10ZM3.5,14.5H12.5V14.083Q12.5,13.958 12.438,13.844Q12.375,13.729 12.271,13.667Q11.292,13.104 10.208,12.802Q9.125,12.5 8,12.5Q6.875,12.5 5.792,12.792Q4.708,13.083 3.729,13.667Q3.625,13.729 3.562,13.833Q3.5,13.938 3.5,14.083ZM8,8.5Q8.625,8.5 9.062,8.062Q9.5,7.625 9.5,7Q9.5,6.375 9.062,5.938Q8.625,5.5 8,5.5Q7.375,5.5 6.938,5.938Q6.5,6.375 6.5,7Q6.5,7.625 6.938,8.062Q7.375,8.5 8,8.5ZM8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5Q8,14.5 8,14.5ZM8,7Q8,7 8,7Q8,7 8,7Q8,7 8,7Q8,7 8,7Q8,7 8,7Q8,7 8,7Q8,7 8,7Q8,7 8,7Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M11.95,18Q12.475,18 12.838,17.637Q13.2,17.275 13.2,16.75Q13.2,16.225 12.838,15.863Q12.475,15.5 11.95,15.5Q11.425,15.5 11.062,15.863Q10.7,16.225 10.7,16.75Q10.7,17.275 11.062,17.637Q11.425,18 11.95,18ZM11.05,14.15H12.9Q12.9,13.325 13.088,12.85Q13.275,12.375 14.15,11.55Q14.8,10.9 15.175,10.312Q15.55,9.725 15.55,8.9Q15.55,7.5 14.525,6.75Q13.5,6 12.1,6Q10.675,6 9.788,6.75Q8.9,7.5 8.55,8.55L10.2,9.2Q10.325,8.75 10.763,8.225Q11.2,7.7 12.1,7.7Q12.9,7.7 13.3,8.137Q13.7,8.575 13.7,9.1Q13.7,9.6 13.4,10.037Q13.1,10.475 12.65,10.85Q11.55,11.825 11.3,12.325Q11.05,12.825 11.05,14.15ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,20Q15.35,20 17.675,17.675Q20,15.35 20,12Q20,8.65 17.675,6.325Q15.35,4 12,4Q8.65,4 6.325,6.325Q4,8.65 4,12Q4,15.35 6.325,17.675Q8.65,20 12,20ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7,17H9V10H7ZM11,17H13V7H11ZM15,17H17V13H15ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7,17H9V10H7ZM11,17H13V7H11ZM15,17H17V13H15ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15.5,11Q16.15,11 16.575,10.575Q17,10.15 17,9.5Q17,8.85 16.575,8.425Q16.15,8 15.5,8Q14.85,8 14.425,8.425Q14,8.85 14,9.5Q14,10.15 14.425,10.575Q14.85,11 15.5,11ZM8.5,11Q9.15,11 9.575,10.575Q10,10.15 10,9.5Q10,8.85 9.575,8.425Q9.15,8 8.5,8Q7.85,8 7.425,8.425Q7,8.85 7,9.5Q7,10.15 7.425,10.575Q7.85,11 8.5,11ZM12,17.5Q13.775,17.5 15.137,16.525Q16.5,15.55 17.1,14H6.9Q7.5,15.55 8.863,16.525Q10.225,17.5 12,17.5ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12ZM12,20Q15.325,20 17.663,17.663Q20,15.325 20,12Q20,8.675 17.663,6.337Q15.325,4 12,4Q8.675,4 6.338,6.337Q4,8.675 4,12Q4,15.325 6.338,17.663Q8.675,20 12,20Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15.5,11Q16.15,11 16.575,10.575Q17,10.15 17,9.5Q17,8.85 16.575,8.425Q16.15,8 15.5,8Q14.85,8 14.425,8.425Q14,8.85 14,9.5Q14,10.15 14.425,10.575Q14.85,11 15.5,11ZM8.5,11Q9.15,11 9.575,10.575Q10,10.15 10,9.5Q10,8.85 9.575,8.425Q9.15,8 8.5,8Q7.85,8 7.425,8.425Q7,8.85 7,9.5Q7,10.15 7.425,10.575Q7.85,11 8.5,11ZM12,17.5Q13.775,17.5 15.137,16.525Q16.5,15.55 17.1,14H6.9Q7.5,15.55 8.863,16.525Q10.225,17.5 12,17.5ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@android:color/white"
android:pathData="M10,18Q8.354,18 6.896,17.375Q5.438,16.75 4.344,15.656Q3.25,14.562 2.625,13.104Q2,11.646 2,10Q2,8.333 2.625,6.885Q3.25,5.438 4.344,4.344Q5.438,3.25 6.896,2.625Q8.354,2 10,2Q11.667,2 13.115,2.625Q14.562,3.25 15.656,4.344Q16.75,5.438 17.375,6.885Q18,8.333 18,10Q18,11.646 17.375,13.104Q16.75,14.562 15.656,15.656Q14.562,16.75 13.115,17.375Q11.667,18 10,18ZM9,16.417V15Q8.583,15 8.292,14.708Q8,14.417 8,14V13L3.646,8.646Q3.583,8.979 3.542,9.312Q3.5,9.646 3.5,10Q3.5,12.458 5.083,14.26Q6.667,16.062 9,16.417ZM15,14.146Q15.729,13.208 16.115,12.198Q16.5,11.188 16.5,10Q16.5,8.042 15.417,6.406Q14.333,4.771 12.5,4V4.5Q12.5,5.125 12.062,5.562Q11.625,6 11,6H9V7Q9,7.417 8.708,7.708Q8.417,8 8,8H7V10H12Q12.417,10 12.708,10.292Q13,10.583 13,11V13H13.854Q14.333,13 14.667,13.333Q15,13.667 15,14.146Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M11,20.95Q7.975,20.575 5.988,18.312Q4,16.05 4,13Q4,11.35 4.65,9.837Q5.3,8.325 6.5,7.2L7.925,8.625Q6.975,9.475 6.488,10.6Q6,11.725 6,13Q6,15.2 7.4,16.887Q8.8,18.575 11,18.95ZM13,20.95V18.95Q15.175,18.55 16.587,16.875Q18,15.2 18,13Q18,10.5 16.25,8.75Q14.5,7 12,7H11.925L13.025,8.1L11.625,9.5L8.125,6L11.625,2.5L13.025,3.9L11.925,5H12Q15.35,5 17.675,7.325Q20,9.65 20,13Q20,16.025 18.013,18.288Q16.025,20.55 13,20.95Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M3,20V4L22,12ZM5,17 L16.85,12 5,7V10.5L11,12L5,13.5ZM5,17V12V7V10.5V13.5Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,12.5ZM1,21 L12,2 23,21ZM11,15H13V10H11ZM12,18Q12.425,18 12.713,17.712Q13,17.425 13,17Q13,16.575 12.713,16.288Q12.425,16 12,16Q11.575,16 11.288,16.288Q11,16.575 11,17Q11,17.425 11.288,17.712Q11.575,18 12,18ZM4.45,19H19.55L12,6Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M1,21 L12,2 23,21ZM11,15H13V10H11ZM12,18Q12.425,18 12.713,17.712Q13,17.425 13,17Q13,16.575 12.713,16.288Q12.425,16 12,16Q11.575,16 11.288,16.288Q11,16.575 11,17Q11,17.425 11.288,17.712Q11.575,18 12,18Z"/>
</vector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:height="4dp" android:gravity="center_vertical" android:id="@android:id/background">
<shape>
<solid android:color="?colorM3SurfaceVariant"/>
</shape>
</item>
<item android:height="4dp" android:gravity="center_vertical" android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="?colorM3Primary"/>
</shape>
</clip>
</item>
</layer-list>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="200" android:exitFadeDuration="200">
<item android:state_checked="true">
<layer-list>
<item>
<shape android:shape="oval">
<solid android:color="?colorM3Primary"/>
</shape>
</item>
<item>
<vector android:width="80dp"
android:height="80dp"
android:viewportWidth="80"
android:viewportHeight="80"
android:tint="?colorM3OnPrimary">
<path
android:pathData="M60,32V28H42V32H60Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M60,52V48H42V52H60Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M23,22C21.343,22 20,23.343 20,25V35C20,36.657 21.343,38 23,38H33C34.657,38 36,36.657 36,35V25C36,23.343 34.657,22 33,22H23ZM33,27.716L26.784,34L23,30.174L24.697,28.458L26.784,30.545L31.303,26L33,27.716Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M23,42C21.343,42 20,43.343 20,45V55C20,56.657 21.343,58 23,58H33C34.657,58 36,56.657 36,55V45C36,43.343 34.657,42 33,42H23ZM33,47.716L26.784,54L23,50.174L24.697,48.458L26.784,50.545L31.303,46L33,47.716Z"
android:fillColor="#ffffff"/>
</vector>
</item>
</layer-list>
</item>
<item>
<layer-list>
<item>
<shape android:shape="oval">
<solid android:color="?colorM3PrimaryContainer"/>
</shape>
</item>
<item>
<vector android:width="80dp"
android:height="80dp"
android:viewportWidth="80"
android:viewportHeight="80"
android:tint="?colorM3Primary">
<path
android:pathData="M60,32V28H42V32H60Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M60,52V48H42V52H60Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M23,22C21.343,22 20,23.343 20,25V35C20,36.657 21.343,38 23,38H33C34.657,38 36,36.657 36,35V25C36,23.343 34.657,22 33,22H23ZM33,27.716L26.784,34L23,30.174L24.697,28.458L26.784,30.545L31.303,26L33,27.716Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M23,42C21.343,42 20,43.343 20,45V55C20,56.657 21.343,58 23,58H33C34.657,58 36,56.657 36,55V45C36,43.343 34.657,42 33,42H23ZM33,47.716L26.784,54L23,50.174L24.697,48.458L26.784,50.545L31.303,46L33,47.716Z"
android:fillColor="#ffffff"/>
</vector>
</item>
</layer-list>
</item>
</selector>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="200" android:exitFadeDuration="200">
<item android:state_checked="true">
<layer-list>
<item>
<shape android:shape="oval">
<solid android:color="?colorM3Primary"/>
</shape>
</item>
<item>
<vector android:width="80dp"
android:height="80dp"
android:viewportWidth="80"
android:viewportHeight="80"
android:tint="?colorM3OnPrimary">
<path
android:pathData="M60,32V28H42V32H60Z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M60,52V48H42V52H60Z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M28,50m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"/>
<path
android:pathData="M28,30m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"/>
<path
android:pathData="M28,30m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"
android:fillColor="#FFFFFF"/>
</vector>
</item>
</layer-list>
</item>
<item>
<layer-list>
<item>
<shape android:shape="oval">
<solid android:color="?colorM3PrimaryContainer"/>
</shape>
</item>
<item>
<vector android:width="80dp"
android:height="80dp"
android:viewportWidth="80"
android:viewportHeight="80"
android:tint="?colorM3Primary">
<path
android:pathData="M60,32V28H42V32H60Z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M60,52V48H42V52H60Z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M28,50m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"/>
<path
android:pathData="M28,30m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"/>
<path
android:pathData="M28,30m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"
android:fillColor="#FFFFFF"/>
</vector>
</item>
</layer-list>
</item>
</selector>

View File

@ -1,144 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="250dp"
android:layout_height="150dp">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="@drawable/fg_compose_attachment">
<View
android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:visibility="gone"
android:background="?colorM3OnSurface"/>
<ImageView
android:id="@+id/thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/title"
android:scaleType="centerCrop"
android:importantForAccessibility="no"
tools:src="#0f0"/>
<RelativeLayout
android:id="@+id/info_bar"
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#f2000000"
android:backgroundTint="?colorWindowBackground">
<ImageButton
android:id="@+id/remove_btn"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="2dp"
android:layout_marginStart="2dp"
android:background="?android:selectableItemBackgroundBorderless"
android:tint="#D92C2C"
android:src="@drawable/ic_fluent_delete_20_regular"/>
<TextView
android:id="@+id/file_name"
android:layout_width="match_parent"
android:layout_height="24dp"
android:textAppearance="@style/m3_body_large"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_toStartOf="@id/remove_btn"
android:gravity="center_vertical"
android:singleLine="true"
android:ellipsize="middle"
tools:text="asdf.jpg"/>
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/file_name"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:maxLines="2"
android:ellipsize="end"
android:textAppearance="@style/m3_body_medium"
android:textColor="?android:textColorSecondary"
android:text="@string/add_image_description"/>
</RelativeLayout>
<FrameLayout
android:id="@+id/overlay"
android:layout_height="24dp"
android:layout_above="@id/subtitle"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
tools:text="Title"/>
<TextView
android:id="@+id/subtitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cc000000"
android:padding="8dp"
android:clipToPadding="false"
tools:visibility="visible"
android:visibility="gone">
android:layout_height="20dp"
android:layout_above="@id/delete"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/m3_body_medium"
android:singleLine="true"
android:ellipsize="end"
android:textColor="?colorM3OnSurfaceVariant"
android:gravity="center_vertical"
tools:text="Subtitle"/>
<ImageButton
android:id="@+id/delete"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:src="@drawable/ic_delete_24px"
android:tint="?colorM3OnSurfaceVariant"
android:backgroundTint="?colorM3OnSurfaceVariant"
android:background="@drawable/bg_round_ripple"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<ImageButton
android:id="@+id/edit"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_toStartOf="@id/delete"
android:layout_alignParentBottom="true"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:src="@drawable/ic_edit_24px"
android:tint="?colorM3OnSurfaceVariant"
android:backgroundTint="?colorM3OnSurfaceVariant"
android:background="@drawable/bg_round_ripple"/>
<ImageButton
android:id="@+id/retry_or_cancel_upload"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:src="@drawable/ic_fluent_dismiss_24_filled"
android:contentDescription="@string/cancel"
android:tint="@color/gray_100"
android:background="@drawable/bg_upload_progress"/>
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="16dp"
android:layout_alignTop="@id/delete"
android:layout_toStartOf="@id/delete"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="16dp"
android:progressDrawable="@drawable/m3_progress"
style="@android:style/Widget.Material.ProgressBar.Horizontal"/>
<ProgressBar
android:id="@+id/progress"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:progressDrawable="@drawable/upload_progress"
android:max="1000"
android:padding="0dp"
android:indeterminateOnly="false"
android:indeterminate="false"/>
<TextView
android:id="@+id/state_title"
android:layout_width="match_parent"
android:layout_height="16dp"
android:layout_below="@id/retry_or_cancel_upload"
android:layout_marginTop="16dp"
android:textColor="@color/gray_200"
android:textSize="14dp"
android:gravity="center_horizontal"
android:singleLine="true"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:includeFontPadding="false"
tools:text="Upload failed"/>
<TextView
android:id="@+id/state_text"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_below="@id/state_title"
android:includeFontPadding="false"
android:textColor="@color/gray_200"
android:gravity="center_horizontal|top"
android:lines="2"
android:maxLines="2"
android:ellipsize="end"
tools:text="Your device lost connection to the internet"/>
</RelativeLayout>
<ImageButton
android:id="@+id/remove_btn2"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginBottom="4dp"
android:layout_gravity="end|bottom"
android:background="?android:selectableItemBackgroundBorderless"
android:tint="#D92C2C"
android:contentDescription="@string/delete"
android:src="@drawable/ic_fluent_delete_20_regular"/>
</FrameLayout>
</FrameLayout>
</RelativeLayout>

View File

@ -1,45 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:paddingStart="16dp"
android:background="?colorM3Surface"
android:foreground="@drawable/bg_m3_outlined_text_field_nopad"
android:addStatesFromChildren="true"
android:clipToPadding="false">
<LinearLayout
android:layout_width="0dp"
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_weight="1"
android:background="@drawable/bg_poll_option"
android:outlineProvider="background"
android:elevation="2dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="16dp"
android:tint="?colorDarkIcon"
android:src="@drawable/ic_fluent_circle_24_regular"/>
<EditText
android:id="@+id/edit"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:textAppearance="@style/m3_title_medium"
android:inputType="textCapSentences"
android:saveEnabled="false"
android:singleLine="true"/>
</LinearLayout>
android:background="@null"
android:paddingStart="16dp"
android:paddingEnd="48dp"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:textColorHint="?colorM3OnSurfaceVariant"
android:inputType="textCapSentences"
android:elevation="0dp"
android:saveEnabled="false"
android:singleLine="true"/>
<ImageView
android:id="@+id/dragger_thingy"
android:layout_width="56dp"
android:layout_width="48dp"
android:layout_height="56dp"
android:layout_gravity="end"
android:scaleType="center"
android:tint="?colorDarkIcon"
android:src="@drawable/ic_fluent_re_order_dots_vertical_24_regular"/>
android:tint="?colorM3OnSurfaceVariant"
android:contentDescription="@string/reorder"
android:paddingStart="4dp"
android:src="@drawable/ic_drag_indicator_20px"
tools:ignore="RtlSymmetry" />
</LinearLayout>
</FrameLayout>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<org.joinmastodon.android.ui.views.SizeListenerLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -12,24 +13,11 @@
android:fillViewport="true">
<LinearLayout
android:id="@+id/compose_main_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/content_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
android:hint="@string/content_warning"
android:inputType="textMultiLine|textCapSentences"
android:visibility="gone"
android:textColorHint="?android:textColorSecondary"
android:background="@drawable/bg_cw_edit"
android:padding="16dp"
android:minHeight="56dp"
android:textSize="16sp"
tools:visibility="visible"/>
<TextView
android:id="@+id/reply_text"
@ -54,35 +42,91 @@
<ImageView
android:id="@+id/avatar"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="12dp" />
android:layout_marginEnd="12dp"
android:importantForAccessibility="no"
tools:src="#0f0"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_toEndOf="@id/avatar"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:textAppearance="@style/m3_body_medium"
android:fontFamily="sans-serif-medium"
android:textColor="?colorM3OnSurface"
android:gravity="center_vertical"
tools:text="Eugen" />
<TextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@id/name"
android:layout_toEndOf="@id/avatar"
android:layout_alignTop="@id/name"
android:layout_toEndOf="@id/name"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_small"
android:textAppearance="@style/m3_body_medium"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="\@Gargron" />
<Button
android:id="@+id/btn_visibility"
android:layout_width="wrap_content"
android:layout_height="28dp"
android:layout_below="@id/name"
android:layout_toEndOf="@id/avatar"
android:layout_marginTop="8dp"
android:textAppearance="@style/m3_label_large"
android:background="@drawable/bg_filter_chip"
android:textColor="?colorM3OnSurfaceVariant"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:drawablePadding="8dp"
tools:text="@string/visibility_public"/>
</RelativeLayout>
<org.joinmastodon.android.ui.views.FloatingHintEditTextLayout
android:id="@+id/content_warning_wrap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:visibility="gone"
android:background="@drawable/bg_cw_edit"
android:addStatesFromChildren="true"
app:labelTextColor="?colorM3Primary"
app:editTextOffsetY="8dp"
tools:visibility="visible">
<EditText
android:id="@+id/content_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
android:hint="@string/content_warning"
android:inputType="textMultiLine|textCapSentences"
android:textColorHint="?colorM3OnSurfaceVariant"
android:paddingLeft="21dp"
android:paddingRight="21dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:minHeight="40dp"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:background="@null"
android:maxLines="3"/>
</org.joinmastodon.android.ui.views.FloatingHintEditTextLayout>
<FrameLayout
android:id="@+id/toot_text_wrap"
android:layout_width="match_parent"
@ -102,151 +146,263 @@
android:background="@null"
android:hint="@string/compose_hint"
android:elevation="0dp"
android:textColor="?colorM3OnSurface"
android:textColorHint="?colorM3OnSurfaceVariant"
android:inputType="textMultiLine|textCapSentences"/>
</FrameLayout>
<LinearLayout
<RelativeLayout
android:id="@+id/poll_wrap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingBottom="16dp"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:id="@+id/poll_settings"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="12dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_below="@id/poll_options"
android:gravity="center_vertical"
android:divider="@drawable/divider_vertical_variant_1dp"
android:showDividers="middle"
android:dividerPadding="8dp">
<ImageButton
android:id="@+id/add_poll_option"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="20dp"
android:src="@drawable/ic_add_24px"
android:tint="@color/button_text_m3_tonal"
android:background="@drawable/bg_button_m3_tonal"
android:contentDescription="@string/add_poll_option"/>
<ImageView
android:id="@+id/delete_poll_option"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="20dp"
android:src="@drawable/ic_delete_24px"
android:scaleType="center"
android:tint="?colorM3Error"
android:background="@drawable/bg_button_m3_tonal_error"
android:visibility="gone"
tools:visibility="visible"
android:contentDescription="@string/delete_poll_option"/>
<LinearLayout
android:id="@+id/poll_duration"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginHorizontal="8dp"
android:orientation="vertical"
android:paddingHorizontal="8dp"
android:gravity="center_vertical"
android:background="@drawable/bg_rect_4dp_ripple">
<TextView
android:layout_width="wrap_content"
android:layout_height="16dp"
android:textAppearance="@style/m3_label_small"
android:textColor="?colorM3Secondary"
android:gravity="center_vertical"
android:singleLine="true"
android:ellipsize="end"
android:text="@string/poll_length"/>
<TextView
android:id="@+id/poll_duration_value"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3Primary"
android:singleLine="true"
android:ellipsize="end"
tools:text="1 day"/>
</LinearLayout>
<LinearLayout
android:id="@+id/poll_style"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginHorizontal="8dp"
android:orientation="vertical"
android:paddingHorizontal="8dp"
android:gravity="center_vertical"
android:background="@drawable/bg_rect_4dp_ripple">
<TextView
android:layout_width="wrap_content"
android:layout_height="16dp"
android:textAppearance="@style/m3_label_small"
android:textColor="?colorM3Secondary"
android:gravity="center_vertical"
android:singleLine="true"
android:ellipsize="end"
android:text="@string/poll_style"/>
<TextView
android:id="@+id/poll_style_value"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3Primary"
android:singleLine="true"
android:ellipsize="end"
tools:text="Pick one"/>
</LinearLayout>
</LinearLayout>
<org.joinmastodon.android.ui.views.ReorderableLinearLayout
android:id="@+id/poll_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginHorizontal="16dp"
android:showDividers="middle"
android:orientation="vertical"/>
<LinearLayout
android:id="@+id/add_poll_option"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="56dp"
android:layout_marginBottom="8dp"
android:background="@drawable/bg_poll_option_clickable"
android:outlineProvider="background"
android:elevation="2dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="16dp"
android:tint="?colorDarkIcon"
android:src="@drawable/ic_fluent_add_circle_24_regular"/>
</LinearLayout>
<TextView
android:id="@+id/poll_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:textAppearance="@style/m3_label_large"
android:textColor="?android:textColorPrimary"
tools:text="Duration: 7 days"/>
</LinearLayout>
<View
android:id="@+id/poll_poof"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignTop="@id/poll_settings"
android:layout_alignStart="@id/poll_settings"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:visibility="invisible"
tools:visibility="visible"
android:background="@drawable/poof"/>
</RelativeLayout>
<org.joinmastodon.android.ui.views.ComposeMediaLayout
android:id="@+id/attachments"
android:layout_width="wrap_content"
<org.joinmastodon.android.ui.views.HorizontalScrollViewThatRespectsMatchParent
android:id="@+id/attachments_scroller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:visibility="gone"/>
android:fillViewport="true"
android:scrollbars="none"
android:clipChildren="false"
android:visibility="gone">
<org.joinmastodon.android.ui.views.ReorderableLinearLayout
android:id="@+id/attachments"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:orientation="horizontal"
android:showDividers="middle"
android:clipToPadding="false"
android:paddingHorizontal="16dp"/>
</org.joinmastodon.android.ui.views.HorizontalScrollViewThatRespectsMatchParent>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="@+id/bottom_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:background="?colorBackgroundLightest"
android:elevation="2dp"
android:elevation="3dp"
android:outlineProvider="bounds"
android:paddingHorizontal="10dp"
android:layout_marginEnd="6dp"
android:layoutDirection="locale">
android:gravity="bottom"
android:orientation="vertical">
<ImageButton
android:id="@+id/btn_media"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/actionBarItemBackground"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/add_media"
android:tooltipText="@string/add_media"
android:src="@drawable/ic_fluent_image_24_regular"/>
<View
android:id="@+id/bottom_bar_autocomplete_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="4dp"
android:visibility="invisible"
android:background="?colorM3OutlineVariant"/>
<ImageButton
android:id="@+id/btn_poll"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/actionBarItemBackground"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/add_poll"
android:tooltipText="@string/add_poll"
android:src="@drawable/ic_fluent_poll_24_selector"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layoutDirection="locale">
<ImageButton
android:id="@+id/btn_emoji"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/actionBarItemBackground"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/emoji"
android:tooltipText="@string/emoji"
android:src="@drawable/ic_fluent_emoji_24_selector"/>
<ImageButton
android:id="@+id/btn_media"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:background="@drawable/bg_compose_button"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/add_media"
android:tooltipText="@string/add_media"
android:src="@drawable/ic_add_photo_alternate_24px"/>
<ImageButton
android:id="@+id/btn_spoiler"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/actionBarItemBackground"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/content_warning"
android:tooltipText="@string/content_warning"
android:src="@drawable/ic_fluent_chat_warning_24_selector"/>
<ImageButton
android:id="@+id/btn_poll"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="@drawable/bg_compose_button"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/add_poll"
android:tooltipText="@string/add_poll"
android:src="@drawable/ic_compose_poll"/>
<ImageButton
android:id="@+id/btn_visibility"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/actionBarItemBackground"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/post_visibility"
android:tooltipText="@string/post_visibility"
android:src="@drawable/ic_fluent_earth_24_regular"/>
<ImageButton
android:id="@+id/btn_emoji"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="@drawable/bg_compose_button"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/emoji"
android:tooltipText="@string/emoji"
android:src="@drawable/ic_compose_emoji"/>
<Space
android:layout_width="0px"
android:layout_height="1px"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/btn_spoiler"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="@drawable/bg_compose_button"
android:padding="0px"
android:tint="@color/compose_button"
android:tintMode="src_in"
android:contentDescription="@string/content_warning"
android:tooltipText="@string/content_warning"
android:src="@drawable/ic_compose_cw"/>
<TextView
android:id="@+id/char_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/m3_body_large"
android:textColor="?android:textColorSecondary"
tools:text="500"/>
<Space
android:layout_width="0px"
android:layout_height="1px"
android:layout_weight="1"/>
<TextView
android:id="@+id/char_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3OnSurface"
tools:text="500"/>
</LinearLayout>
</LinearLayout>
</org.joinmastodon.android.ui.views.SizeListenerLinearLayout>

View File

@ -2,60 +2,48 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<org.joinmastodon.android.ui.views.ComposeMediaLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<ImageView
android:id="@+id/photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:importantForAccessibility="no"
tools:src="#0f0"/>
</org.joinmastodon.android.ui.views.ComposeMediaLayout>
<TextView
android:id="@+id/title"
<org.joinmastodon.android.ui.views.FixedAspectRatioImageView
android:id="@+id/photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:importantForAccessibility="no"
tools:src="#0f0"/>
<org.joinmastodon.android.ui.views.FloatingHintEditTextLayout
android:id="@+id/bio_wrap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
android:textAppearance="@style/m3_headline_medium"
android:minHeight="36dp"
android:gravity="center_vertical"
android:text="@string/add_alt_text"/>
android:layout_marginBottom="4dp"
android:paddingTop="4dp"
android:paddingBottom="12dp"
app:labelTextColor="@color/m3_outlined_text_field_label"
android:foreground="@drawable/bg_m3_outlined_text_field">
<TextView
android:id="@+id/subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/m3_title_medium"
android:textColor="?android:textColorSecondary"
android:text="@string/alt_text_subtitle"/>
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:padding="16dp"
android:background="@null"
android:inputType="textMultiLine|textCapSentences"
android:minLines="3"
android:gravity="top"
android:hint="@string/alt_text"/>
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:minHeight="212dp"
android:gravity="top"
android:inputType="textCapSentences|textMultiLine"
android:hint="@string/alt_text_hint"/>
</org.joinmastodon.android.ui.views.FloatingHintEditTextLayout>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:paddingHorizontal="12dp"
android:singleLine="true"
android:gravity="center_vertical"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3OnSurfaceVariant"
android:background="@drawable/bg_filter_chip"
tools:text="#smithereen"/>

View File

@ -1,41 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp">
android:layout_width="wrap_content"
android:layout_height="32dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="4dp"
android:paddingEnd="12dp"
android:background="@drawable/bg_filter_chip">
<ImageView
android:id="@+id/photo"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="12dp"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="8dp"
android:importantForAccessibility="no"
tools:src="#0f0"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/photo"
android:textAppearance="@style/m3_title_medium"
android:fontFamily="sans-serif"
android:singleLine="true"
android:ellipsize="end"
tools:text="User Name"/>
<TextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/photo"
android:layout_alignBottom="@id/photo"
android:textAppearance="@style/m3_body_medium"
android:textColor="?android:textColorSecondary"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3OnSurfaceVariant"
android:singleLine="true"
android:ellipsize="end"
tools:text="\@user@domain"/>
</RelativeLayout>
</LinearLayout>

View File

@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:elevation="0dp"
android:navigationIcon="@drawable/ic_fluent_arrow_left_24_regular"
android:navigationIcon="@drawable/ic_arrow_back"
android:navigationContentDescription="@string/back"
android:theme="@style/Theme.Mastodon.Toolbar.Profile"
android:background="@null"/>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="32dp"
android:paddingTop="8dp"
android:paddingHorizontal="8dp">
<org.joinmastodon.android.ui.views.CheckableLinearLayout
android:id="@+id/multiple_choice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginHorizontal="8dp"
android:orientation="vertical"
android:paddingTop="8dp"
android:background="@drawable/bg_rect_4dp_ripple"
android:gravity="center_horizontal">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/poll_multiple"
android:duplicateParentState="true"
android:importantForAccessibility="no"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/m3_title_small"
android:textColor="?colorM3OnSurface"
android:text="@string/compose_poll_multiple_choice"/>
<FrameLayout
android:layout_width="48dp"
android:layout_height="48dp"
android:duplicateParentState="true">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="false"
android:focusable="false"
android:duplicateParentState="true"/>
</FrameLayout>
</org.joinmastodon.android.ui.views.CheckableLinearLayout>
<org.joinmastodon.android.ui.views.CheckableLinearLayout
android:id="@+id/single_choice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginHorizontal="8dp"
android:orientation="vertical"
android:paddingTop="8dp"
android:background="@drawable/bg_rect_4dp_ripple"
android:gravity="center_horizontal">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/poll_single"
android:duplicateParentState="true"
android:importantForAccessibility="no"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/m3_title_small"
android:textColor="?colorM3OnSurface"
android:text="@string/compose_poll_single_choice"/>
<FrameLayout
android:layout_width="48dp"
android:layout_height="48dp"
android:duplicateParentState="true">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="false"
android:focusable="false"
android:duplicateParentState="true"/>
</FrameLayout>
</org.joinmastodon.android.ui.views.CheckableLinearLayout>
</LinearLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<me.grishka.appkit.views.FragmentRootLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/appkit_toolbar"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_gravity="bottom">
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="-10dp"
android:layout_marginBottom="-10dp"
android:indeterminate="true"
android:background="?colorM3SurfaceVariant"
android:theme="@style/Theme.Mastodon.Toolbar.ProgressBar"
style="@android:style/Widget.Material.ProgressBar.Horizontal"/>
</FrameLayout>
</FrameLayout>
<FrameLayout
android:id="@+id/appkit_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</me.grishka.appkit.views.FragmentRootLinearLayout>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/publish" android:icon="@drawable/ic_send_24px" android:showAsAction="always" android:title="@string/publish"/>
</menu>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/help" android:showAsAction="always" android:icon="@drawable/ic_help_24px" android:title="@string/help"/>
</menu>

View File

@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/vis_public"
android:icon="@drawable/ic_fluent_earth_24_regular"
android:title="@string/visibility_public"/>
<item android:id="@+id/vis_followers"
android:icon="@drawable/ic_fluent_people_checkmark_24_regular"
android:title="@string/visibility_followers_only"/>
<item android:id="@+id/vis_private"
android:icon="@drawable/ic_at_symbol"
android:title="@string/visibility_private"/>
</menu>

View File

@ -221,7 +221,7 @@
<string name="alt_text_hint">e.g. A dog looking around suspiciously with narrowed eyes at the camera.</string>
<string name="visibility_public">Public</string>
<string name="visibility_followers_only">Followers only</string>
<string name="visibility_private">Only people I mention</string>
<string name="visibility_private">Only people mentioned</string>
<string name="search_all">All</string>
<string name="search_people">People</string>
<string name="recent_searches">Recent searches</string>
@ -455,4 +455,23 @@
<string name="link_not_supported">This link is not supported in the app</string>
<string name="log_out_all_accounts">Log out of all accounts</string>
<string name="confirm_log_out_all_accounts">Log out of all accounts?</string>
<string name="retry">Retry</string>
<string name="post_failed">Failed to send post</string>
<!-- %s is formatted file size ("467 KB image") -->
<string name="attachment_description_image">%s image</string>
<string name="attachment_description_video">%s video</string>
<string name="attachment_description_audio">%s audio</string>
<string name="attachment_description_unknown">%s file</string>
<string name="attachment_x_percent_uploaded">%d%% uploaded</string>
<string name="add_poll_option">Add poll option</string>
<string name="poll_length">Poll length</string>
<string name="poll_style">Style</string>
<string name="compose_poll_single_choice">Pick one</string>
<string name="compose_poll_multiple_choice">Multiple choice</string>
<string name="delete_poll_option">Delete poll option</string>
<string name="poll_style_title">Poll style</string>
<string name="alt_text">Alt text</string>
<string name="help">Help</string>
<string name="what_is_alt_text">What is alt text?</string>
<string name="alt_text_help">Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.\n\nYou can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.\n\n<ul><li>Capture important elements</li>\n<li>Summarize text in images</li>\n<li>Use regular sentence structure</li>\n<li>Avoid redundant information</li>\n<li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li></ul></string>
</resources>

View File

@ -32,7 +32,6 @@
<item name="colorAccentLightest">@color/primary_100</item>
<item name="buttonBackground">@drawable/bg_button_primary_dark_on_light</item>
<item name="android:editTextBackground">@drawable/bg_edittext_light</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item>
@ -110,7 +109,6 @@
<item name="colorSearchHint">@color/gray_300</item>
<item name="buttonBackground">@drawable/bg_button_primary_light_on_dark</item>
<item name="android:editTextBackground">@drawable/bg_edittext_dark</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">false</item>
@ -177,7 +175,7 @@
<item name="android:toolbarStyle">@style/Widget.Mastodon.Toolbar</item>
<item name="appkitToolbarElevation">0px</item>
<item name="appkitToolbarBackground">?colorM3Background</item>
<item name="actionBarIconTint">?colorM3OnSurfaceVariant</item>
<item name="actionBarIconTint">@color/action_bar_icons</item>
</style>
<style name="Widget.Mastodon.Toolbar" parent="android:Widget.Material.Toolbar">
@ -254,8 +252,8 @@
</style>
<style name="Widget.Mastodon.EditText" parent="android:Widget.Material.Light.EditText">
<item name="android:textColorHint">?android:textColorSecondary</item>
<item name="android:elevation">2dp</item>
<item name="android:textColor">?colorM3OnSurface</item>
<item name="android:textColorHint">?colorM3OnSurfaceVariant</item>
<item name="android:textAppearance">@style/m3_body_large</item>
</style>
@ -266,11 +264,11 @@
<item name="android:buttonBarButtonStyle">@style/Widget.Mastodon.ButtonBarButton</item>
<!-- colors -->
<item name="android:colorAccent">@color/primary_700</item>
<item name="android:colorPrimary">@color/gray_800</item>
<item name="android:colorBackground">@color/gray_100</item>
<item name="android:textColorPrimary">@color/gray_800</item>
<item name="android:textColorSecondary">@color/gray_500</item>
<item name="android:colorAccent">?colorM3Primary</item>
<item name="android:colorPrimary">?colorM3OnSurface</item>
<item name="android:colorBackground">?colorM3OnSurfaceVariant</item>
<item name="android:textColorPrimary">?colorM3OnSurface</item>
<item name="android:textColorSecondary">?colorM3OnSurfaceVariant</item>
</style>
<style name="Theme.Mastodon.Dialog.Alert.Dark" parent="android:Theme.Material.Dialog.Alert">
@ -280,11 +278,11 @@
<item name="android:buttonBarButtonStyle">@style/Widget.Mastodon.ButtonBarButton</item>
<!-- colors -->
<item name="android:colorAccent">@color/primary_600</item>
<item name="android:colorPrimary">@color/gray_50</item>
<item name="android:colorBackground">@color/gray_700</item>
<item name="android:textColorPrimary">@color/gray_50</item>
<item name="android:textColorSecondary">@color/gray_400</item>
<item name="android:colorAccent">?colorM3Primary</item>
<item name="android:colorPrimary">?colorM3OnSurface</item>
<item name="android:colorBackground">?colorM3OnSurfaceVariant</item>
<item name="android:textColorPrimary">?colorM3OnSurface</item>
<item name="android:textColorSecondary">?colorM3OnSurfaceVariant</item>
</style>
<style name="Widget.Mastodon.ButtonBarButton" parent="android:Widget.Material.Button.Borderless">
@ -294,7 +292,7 @@
<item name="android:minWidth">0px</item>
<item name="android:background">@drawable/bg_alert_button</item>
<item name="android:textAppearance">@style/m3_label_large</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:textColor">?colorM3Primary</item>
</style>
<style name="Widget.Mastodon.PopupMenu" parent="android:Widget.Material.Light.PopupMenu">
@ -356,6 +354,10 @@
<item name="android:textColor">?colorM3OnSurface</item>
</style>
<style name="Theme.Mastodon.Toolbar.ProgressBar">
<item name="android:disabledAlpha">0</item>
</style>
<style name="alert_title">
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:textSize">24dp</item>
@ -394,6 +396,13 @@
<item name="android:textColor">?android:textColorSecondary</item>
</style>
<style name="m3_label_small">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">11dp</item>
<item name="android:textColor">?android:textColorSecondary</item>
<item name="android:lineSpacingExtra">3dp</item>
</style>
<style name="m3_label_medium">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">12dp</item>