VQA fixes part 1
This commit is contained in:
parent
1b4afe7ba9
commit
bf44f7ef13
|
@ -73,8 +73,6 @@ abstract class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInsta
|
|||
protected boolean isSignup;
|
||||
protected CatalogInstance fakeInstance=new CatalogInstance();
|
||||
|
||||
private static final double DUNBAR=Math.log(800);
|
||||
|
||||
public InstanceCatalogFragment(int layout, int perPage){
|
||||
super(layout, perPage);
|
||||
}
|
||||
|
@ -155,7 +153,7 @@ abstract class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInsta
|
|||
}
|
||||
|
||||
protected void loadInstanceInfo(String _domain, boolean isFromRedirect, Consumer<Object> onError){
|
||||
if(TextUtils.isEmpty(_domain))
|
||||
if(TextUtils.isEmpty(_domain) || _domain.indexOf('.')==-1)
|
||||
return;
|
||||
String domain=normalizeInstanceDomain(_domain);
|
||||
Instance cachedInstance=instancesCache.get(domain);
|
||||
|
|
|
@ -5,8 +5,9 @@ import android.app.AlertDialog;
|
|||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
|
@ -26,20 +27,17 @@ import android.widget.PopupMenu;
|
|||
import android.widget.RadioButton;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.MastodonErrorResponse;
|
||||
import org.joinmastodon.android.api.requests.accounts.CheckInviteLink;
|
||||
import org.joinmastodon.android.api.requests.catalog.GetCatalogCategories;
|
||||
import org.joinmastodon.android.api.requests.catalog.GetCatalogInstances;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.catalog.CatalogCategory;
|
||||
import org.joinmastodon.android.model.catalog.CatalogInstance;
|
||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
import org.joinmastodon.android.ui.utils.SimpleTextWatcher;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.FilterChipView;
|
||||
|
@ -49,11 +47,9 @@ import org.parceler.Parcels;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -71,9 +67,6 @@ import me.grishka.appkit.utils.V;
|
|||
import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public class InstanceCatalogSignupFragment extends InstanceCatalogFragment implements OnBackPressedListener{
|
||||
private MastodonAPIRequest<?> getCategoriesRequest;
|
||||
private String currentCategory="all";
|
||||
private List<CatalogCategory> categories=new ArrayList<>();
|
||||
private View topBar;
|
||||
|
||||
private List<String> languages=Collections.emptyList();
|
||||
|
@ -149,58 +142,16 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
|
|||
}
|
||||
})
|
||||
.execNoAuth("");
|
||||
getCategoriesRequest=new GetCatalogCategories(null)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(List<CatalogCategory> result){
|
||||
getCategoriesRequest=null;
|
||||
CatalogCategory all=new CatalogCategory();
|
||||
all.category="all";
|
||||
categories.add(all);
|
||||
result.stream().sorted(Comparator.comparingInt((CatalogCategory cc)->cc.serversCount).reversed()).forEach(categories::add);
|
||||
updateCategories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
getCategoriesRequest=null;
|
||||
error.showToast(getActivity());
|
||||
CatalogCategory all=new CatalogCategory();
|
||||
all.category="all";
|
||||
categories.add(all);
|
||||
updateCategories();
|
||||
}
|
||||
})
|
||||
.execNoAuth("");
|
||||
}
|
||||
|
||||
private void updateCategories(){
|
||||
// categoriesList.removeAllTabs();
|
||||
// for(CatalogCategory cat:categories){
|
||||
// int titleRes=getTitleForCategory(cat.category);
|
||||
// TabLayout.Tab tab=categoriesList.newTab().setText(titleRes!=0 ? getString(titleRes) : cat.category).setCustomView(R.layout.item_instance_category);
|
||||
// ImageView emoji=tab.getCustomView().findViewById(R.id.emoji);
|
||||
// emoji.setImageResource(getEmojiForCategory(cat.category));
|
||||
// categoriesList.addTab(tab);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(){
|
||||
super.onDestroy();
|
||||
if(getCategoriesRequest!=null)
|
||||
getCategoriesRequest.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter getAdapter(){
|
||||
View headerView=new View(getActivity());
|
||||
headerView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
|
||||
|
||||
mergeAdapter=new MergeRecyclerAdapter();
|
||||
mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(headerView));
|
||||
mergeAdapter.addAdapter(adapter=new InstancesAdapter());
|
||||
return mergeAdapter;
|
||||
return adapter=new InstancesAdapter();
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
|
@ -222,7 +173,16 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
|
|||
setStatusBarColor(0);
|
||||
topBar=view.findViewById(R.id.top_bar);
|
||||
|
||||
list.addOnScrollListener(new ElevationOnScrollListener(null, topBar, buttonBar));
|
||||
list.addOnScrollListener(new ElevationOnScrollListener(null, topBar));
|
||||
if(buttonBar.getBackground() instanceof LayerDrawable ld){
|
||||
ld=(LayerDrawable) ld.mutate();
|
||||
buttonBar.setBackground(ld);
|
||||
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
|
||||
if(overlay!=null){
|
||||
overlay.setAlpha(20);
|
||||
}
|
||||
}
|
||||
buttonBar.setElevation(V.dp(3));
|
||||
|
||||
searchEdit=view.findViewById(R.id.search_edit);
|
||||
searchEdit.setOnEditorActionListener(this::onSearchEnterPressed);
|
||||
|
@ -572,6 +532,9 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
|
|||
filteredData.add(instance);
|
||||
}
|
||||
}
|
||||
setEmptyText(getString(R.string.no_servers_found, currentSearchQuery));
|
||||
}else{
|
||||
setEmptyText("");
|
||||
}
|
||||
}else{
|
||||
for(CatalogInstance instance:data){
|
||||
|
@ -591,27 +554,29 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
|
|||
}
|
||||
}
|
||||
}
|
||||
DiffUtil.calculateDiff(new DiffUtil.Callback(){
|
||||
@Override
|
||||
public int getOldListSize(){
|
||||
return prevData.size();
|
||||
}
|
||||
UiUtils.updateRecyclerViewKeepingAbsoluteScrollPosition(list, ()->{
|
||||
DiffUtil.calculateDiff(new DiffUtil.Callback(){
|
||||
@Override
|
||||
public int getOldListSize(){
|
||||
return prevData.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewListSize(){
|
||||
return filteredData.size();
|
||||
}
|
||||
@Override
|
||||
public int getNewListSize(){
|
||||
return filteredData.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition){
|
||||
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
||||
}
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition){
|
||||
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition){
|
||||
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
||||
}
|
||||
}).dispatchUpdatesTo(adapter);
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition){
|
||||
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
||||
}
|
||||
}).dispatchUpdatesTo(adapter);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package org.joinmastodon.android.fragments.onboarding;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -65,7 +64,7 @@ public class InstanceChooserLoginFragment extends InstanceCatalogFragment{
|
|||
protected void updateFilteredList(){
|
||||
ArrayList<CatalogInstance> prevData=new ArrayList<>(filteredData);
|
||||
filteredData.clear();
|
||||
if(currentSearchQuery.length()>0){
|
||||
if(!TextUtils.isEmpty(currentSearchQuery)){
|
||||
boolean foundExactMatch=false;
|
||||
for(CatalogInstance inst:data){
|
||||
if(inst.normalizedDomain.contains(currentSearchQuery)){
|
||||
|
@ -74,9 +73,16 @@ public class InstanceChooserLoginFragment extends InstanceCatalogFragment{
|
|||
foundExactMatch=true;
|
||||
}
|
||||
}
|
||||
if(!foundExactMatch)
|
||||
if(!foundExactMatch && currentSearchQuery.indexOf('.')!=-1)
|
||||
filteredData.add(0, fakeInstance);
|
||||
}
|
||||
if(filteredData.isEmpty()){
|
||||
for(CatalogInstance inst:data){
|
||||
if(inst.normalizedDomain.equals("mastodon.social") || inst.normalizedDomain.equals("mastodon.online")){
|
||||
filteredData.add(inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
UiUtils.updateList(prevData, filteredData, list, adapter, Objects::equals);
|
||||
for(int i=0;i<list.getChildCount();i++){
|
||||
list.getChildAt(i).invalidateOutline();
|
||||
|
@ -96,6 +102,7 @@ public class InstanceChooserLoginFragment extends InstanceCatalogFragment{
|
|||
public void onSuccess(List<CatalogInstance> result){
|
||||
data.clear();
|
||||
data.addAll(sortInstances(result));
|
||||
updateFilteredList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,6 +119,9 @@ public class InstanceChooserLoginFragment extends InstanceCatalogFragment{
|
|||
Toolbar toolbar=getToolbar();
|
||||
toolbar.setElevation(0);
|
||||
toolbar.setBackground(null);
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
|
||||
toolbar.setContentInsetStartWithNavigation(V.dp(80));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -50,6 +50,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -62,6 +63,7 @@ import me.grishka.appkit.views.FragmentRootLinearLayout;
|
|||
|
||||
public class SignupFragment extends ToolbarFragment{
|
||||
private static final String TAG="SignupFragment";
|
||||
private final Pattern emailRegex=Pattern.compile("^[^@]+@[^@]+\\.[^@]{2,}$");
|
||||
|
||||
private Instance instance;
|
||||
|
||||
|
@ -97,6 +99,7 @@ public class SignupFragment extends ToolbarFragment{
|
|||
View view=inflater.inflate(R.layout.fragment_onboarding_signup, container, false);
|
||||
|
||||
TextView domain=view.findViewById(R.id.domain);
|
||||
TextView atSign=view.findViewById(R.id.at_sign);
|
||||
displayName=view.findViewById(R.id.display_name);
|
||||
username=view.findViewById(R.id.username);
|
||||
email=view.findViewById(R.id.email);
|
||||
|
@ -118,7 +121,7 @@ public class SignupFragment extends ToolbarFragment{
|
|||
@Override
|
||||
public boolean onPreDraw(){
|
||||
username.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
username.setPadding(username.getPaddingLeft(), username.getPaddingTop(), domain.getWidth(), username.getPaddingBottom());
|
||||
username.setPadding(atSign.getWidth(), username.getPaddingTop(), domain.getWidth(), username.getPaddingBottom());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
@ -145,6 +148,10 @@ public class SignupFragment extends ToolbarFragment{
|
|||
reasonExplain.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
password.setOnFocusChangeListener(this::onPasswordFieldFocusChange);
|
||||
passwordConfirm.setOnFocusChangeListener(this::onPasswordFieldFocusChange);
|
||||
email.setOnFocusChangeListener(this::onEmailFieldFocusChange);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -281,34 +288,44 @@ public class SignupFragment extends ToolbarFragment{
|
|||
.exec(instance.uri, apiToken);
|
||||
}
|
||||
|
||||
private CharSequence makeLinkInErrorMessage(String source, LinkSpan.OnLinkClickListener onClick){
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder();
|
||||
Jsoup.parseBodyFragment(source).body().traverse(new NodeVisitor(){
|
||||
private int spanStart;
|
||||
@Override
|
||||
public void head(Node node, int depth){
|
||||
if(node instanceof TextNode tn){
|
||||
ssb.append(tn.text());
|
||||
}else if(node instanceof Element){
|
||||
spanStart=ssb.length();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tail(Node node, int depth){
|
||||
if(node instanceof Element){
|
||||
ssb.setSpan(new LinkSpan("", onClick, LinkSpan.Type.CUSTOM, null, null, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.setSpan(new TypefaceSpan("sans-serif-medium"), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
});
|
||||
return ssb;
|
||||
}
|
||||
|
||||
private CharSequence getErrorDescription(MastodonDetailedErrorResponse.FieldError error, String fieldName){
|
||||
return switch(fieldName){
|
||||
case "email" -> switch(error.error){
|
||||
case "ERR_BLOCKED" -> {
|
||||
String emailAddr=email.getText().toString();
|
||||
String s=getResources().getString(R.string.signup_email_domain_blocked, TextUtils.htmlEncode(instance.uri), TextUtils.htmlEncode(emailAddr.substring(emailAddr.lastIndexOf('@')+1)));
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder();
|
||||
Jsoup.parseBodyFragment(s).body().traverse(new NodeVisitor(){
|
||||
private int spanStart;
|
||||
@Override
|
||||
public void head(Node node, int depth){
|
||||
if(node instanceof TextNode tn){
|
||||
ssb.append(tn.text());
|
||||
}else if(node instanceof Element){
|
||||
spanStart=ssb.length();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tail(Node node, int depth){
|
||||
if(node instanceof Element){
|
||||
ssb.setSpan(new LinkSpan("", SignupFragment.this::onGoBackLinkClick, LinkSpan.Type.CUSTOM, null, null, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.setSpan(new TypefaceSpan("sans-serif-medium"), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
});
|
||||
yield ssb;
|
||||
yield makeLinkInErrorMessage(s, this::onGoBackLinkClick);
|
||||
}
|
||||
case "ERR_INVALID" -> getString(R.string.signup_email_invalid);
|
||||
case "ERR_TAKEN" -> makeLinkInErrorMessage(getString(R.string.signup_email_taken), this::onForgotPasswordLinkClick);
|
||||
default -> error.description;
|
||||
};
|
||||
case "username" -> switch(error.error){
|
||||
case "ERR_TAKEN" -> makeLinkInErrorMessage(getString(R.string.signup_username_taken), this::onGoBackLinkClick);
|
||||
default -> error.description;
|
||||
};
|
||||
default -> error.description;
|
||||
|
@ -345,7 +362,9 @@ public class SignupFragment extends ToolbarFragment{
|
|||
}
|
||||
|
||||
private void updateButtonState(){
|
||||
btn.setEnabled(username.length()>0 && email.length()>0 && email.getText().toString().contains("@") && password.length()>=8 && passwordConfirm.length()>=8 && (!instance.approvalRequired || reason.length()>0));
|
||||
btn.setEnabled(username.length()>0 && email.length()>0 && emailRegex.matcher(email.getText()).find()
|
||||
&& password.length()>=8 && passwordConfirm.length()>=8 && password.getText().toString().equals(passwordConfirm.getText().toString())
|
||||
&& (!instance.approvalRequired || reason.length()>0));
|
||||
}
|
||||
|
||||
private void createAppAndGetToken(){
|
||||
|
@ -406,6 +425,24 @@ public class SignupFragment extends ToolbarFragment{
|
|||
Nav.finish(this);
|
||||
}
|
||||
|
||||
private void onForgotPasswordLinkClick(LinkSpan span){
|
||||
UiUtils.launchWebBrowser(getActivity(), "https://"+instance.uri+"/auth/password/new");
|
||||
}
|
||||
|
||||
private void onPasswordFieldFocusChange(View v, boolean hasFocus){
|
||||
if(hasFocus || password.length()==0 || passwordConfirm.length()==0)
|
||||
return;
|
||||
if(!password.getText().toString().equals(passwordConfirm.getText().toString())){
|
||||
passwordConfirmWrap.setErrorState(getString(R.string.signup_passwords_dont_match));
|
||||
}
|
||||
}
|
||||
|
||||
private void onEmailFieldFocusChange(View v, boolean hasFocus){
|
||||
if(!hasFocus && email.length()>0 && !emailRegex.matcher(email.getText()).find()){
|
||||
emailWrap.setErrorState(getString(R.string.signup_email_invalid));
|
||||
}
|
||||
}
|
||||
|
||||
private class ErrorClearingListener implements TextWatcher{
|
||||
public final EditText editText;
|
||||
|
||||
|
|
|
@ -1040,4 +1040,20 @@ public class UiUtils{
|
|||
button.setTextColor(origColor);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateRecyclerViewKeepingAbsoluteScrollPosition(RecyclerView rv, Runnable onUpdate){
|
||||
int topItem=-1;
|
||||
int topItemOffset=0;
|
||||
if(rv.getChildCount()>0){
|
||||
View item=rv.getChildAt(0);
|
||||
topItem=rv.getChildAdapterPosition(item);
|
||||
topItemOffset=item.getTop();
|
||||
}
|
||||
onUpdate.run();
|
||||
int newCount=rv.getAdapter().getItemCount();
|
||||
if(newCount>=topItem){
|
||||
rv.scrollToPosition(topItem);
|
||||
rv.scrollBy(0, -topItemOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,6 +158,9 @@ public class FloatingHintEditTextLayout extends FrameLayout implements CustomVie
|
|||
}else{
|
||||
transY=edit.getHeight()/2f-edit.getLineHeight()/2f+(edit.getTop()-label.getTop())-(label.getHeight()/2f-label.getLineHeight()/2f);
|
||||
}
|
||||
int labelX=label.getLeft();
|
||||
int editX=edit.getLeft()+edit.getPaddingLeft();
|
||||
float xOffset=editX-labelX;
|
||||
|
||||
AnimatorSet anim=new AnimatorSet();
|
||||
if(hintVisible){
|
||||
|
@ -166,6 +169,7 @@ public class FloatingHintEditTextLayout extends FrameLayout implements CustomVie
|
|||
ObjectAnimator.ofFloat(label, SCALE_X, scale),
|
||||
ObjectAnimator.ofFloat(label, SCALE_Y, scale),
|
||||
ObjectAnimator.ofFloat(label, TRANSLATION_Y, transY),
|
||||
ObjectAnimator.ofFloat(label, TRANSLATION_X, xOffset),
|
||||
ObjectAnimator.ofFloat(FloatingHintEditTextLayout.this, "animProgress", 0f)
|
||||
);
|
||||
edit.setHintTextColor(0);
|
||||
|
@ -173,11 +177,13 @@ public class FloatingHintEditTextLayout extends FrameLayout implements CustomVie
|
|||
label.setScaleX(scale);
|
||||
label.setScaleY(scale);
|
||||
label.setTranslationY(transY);
|
||||
label.setTranslationX(xOffset);
|
||||
anim.playTogether(
|
||||
ObjectAnimator.ofFloat(edit, TRANSLATION_Y, offsetY),
|
||||
ObjectAnimator.ofFloat(label, SCALE_X, 1f),
|
||||
ObjectAnimator.ofFloat(label, SCALE_Y, 1f),
|
||||
ObjectAnimator.ofFloat(label, TRANSLATION_Y, 0f),
|
||||
ObjectAnimator.ofFloat(label, TRANSLATION_X, 0f),
|
||||
ObjectAnimator.ofFloat(FloatingHintEditTextLayout.this, "animProgress", 1f)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?colorM3OnSurfaceVariant" android:alpha="0.4"/>
|
||||
</selector>
|
|
@ -39,14 +39,15 @@
|
|||
android:layout_height="56dp"
|
||||
android:background="@drawable/bg_m3_filled_text_field"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:textColorHint="?colorM3OnSurfaceVariant"
|
||||
android:textColorHint="@color/m3_on_surface_variant_alpha40"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
android:gravity="start|bottom"
|
||||
android:paddingBottom="8dp"
|
||||
android:singleLine="true"
|
||||
android:inputType="textUri"
|
||||
android:textAppearance="@style/m3_body_large"
|
||||
android:hint="example.social/invite/AbC123"/>
|
||||
android:hint="example.social/invite/AbC123"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
|
|
|
@ -56,10 +56,12 @@
|
|||
<org.joinmastodon.android.ui.views.FloatingHintEditTextLayout
|
||||
android:id="@+id/username_wrap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="12dp"
|
||||
app:labelTextColor="@color/m3_outlined_text_field_label"
|
||||
android:foreground="@drawable/bg_m3_outlined_text_field">
|
||||
android:foreground="@drawable/bg_m3_outlined_text_field"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
|
@ -91,6 +93,20 @@
|
|||
android:textColor="?colorM3OnSurface"
|
||||
tools:text="\@mastodon.social"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/at_sign"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="56dp"
|
||||
android:layout_gravity="left|top"
|
||||
android:layout_marginLeft="56dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="2dp"
|
||||
android:textAppearance="@style/m3_body_large"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
android:text="\@"/>
|
||||
|
||||
</org.joinmastodon.android.ui.views.FloatingHintEditTextLayout>
|
||||
|
||||
<org.joinmastodon.android.ui.views.FloatingHintEditTextLayout
|
||||
|
@ -191,19 +207,6 @@
|
|||
|
||||
</org.joinmastodon.android.ui.views.FloatingHintEditTextLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="56dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginTop="-8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:textAppearance="@style/m3_body_small"
|
||||
android:textColor="?colorM3OnSurfaceVariant"
|
||||
android:text="@string/password_note"/>
|
||||
|
||||
|
||||
<org.joinmastodon.android.ui.views.FloatingHintEditTextLayout
|
||||
android:id="@+id/reason_wrap"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_body_large"
|
||||
android:paddingStart="56dp"
|
||||
android:paddingStart="80dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
android:text="@string/login_subtitle"/>
|
||||
|
@ -38,7 +38,7 @@
|
|||
android:textColorHint="?colorM3OnSurfaceVariant"
|
||||
android:inputType="textUri"
|
||||
android:importantForAutofill="no"
|
||||
android:paddingStart="48dp"
|
||||
android:paddingStart="64dp"
|
||||
android:layout_marginEnd="52dp"
|
||||
android:drawablePadding="16dp"
|
||||
android:textAppearance="@style/m3_body_large"
|
||||
|
@ -47,6 +47,7 @@
|
|||
<ImageView
|
||||
android:layout_width="44dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:scaleType="center"
|
||||
android:importantForAccessibility="no"
|
||||
|
|
|
@ -157,7 +157,6 @@
|
|||
<string name="email">Email</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="confirm_password">Confirm password</string>
|
||||
<string name="password_note">Include capital letters, special characters, and numbers to increase your password strength.</string>
|
||||
<string name="category_general">General</string>
|
||||
<string name="confirm_email_title">Check your inbox</string>
|
||||
<!-- %s is the email address -->
|
||||
|
@ -321,9 +320,9 @@
|
|||
<string name="login_subtitle">Log in with the server where you created your account.</string>
|
||||
<string name="server_url">Server URL</string>
|
||||
<string name="server_filter_any_language">Any language</string>
|
||||
<string name="server_filter_instant_signup">Instant sign-up</string>
|
||||
<string name="server_filter_instant_signup">Instant sign up</string>
|
||||
<string name="server_filter_manual_review">Manual review</string>
|
||||
<string name="server_filter_any_signup_speed">Any sign-up speed</string>
|
||||
<string name="server_filter_any_signup_speed">Any sign up speed</string>
|
||||
<string name="server_filter_region_europe">Europe</string>
|
||||
<string name="server_filter_region_north_america">North America</string>
|
||||
<string name="server_filter_region_south_america">South America</string>
|
||||
|
@ -759,4 +758,8 @@
|
|||
<string name="connection_timed_out">The request timed out. Check your connection and try again?</string>
|
||||
<string name="server_error">Something went wrong talking with your server. It’s probably not your fault. Try again?</string>
|
||||
<string name="not_found">It could’ve been deleted, or maybe it never existed at all.</string>
|
||||
<string name="no_servers_found">No servers found for “%s”</string>
|
||||
<string name="signup_username_taken">This username is taken. Try a different one or <a>pick a different server</a>.</string>
|
||||
<string name="signup_email_invalid">That doesn’t look like a valid email address.</string>
|
||||
<string name="signup_email_taken">Email address is already in use. Did you <a>forget your password</a>?</string>
|
||||
</resources>
|
Loading…
Reference in New Issue