Merge remote-tracking branch 'upstream/master'

This commit is contained in:
sk
2023-01-26 00:56:05 +01:00
8 changed files with 511 additions and 353 deletions

View File

@@ -5,6 +5,7 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -19,6 +20,7 @@ import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.ui.DividerItemDecoration;
import org.joinmastodon.android.ui.OutlineProviders;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.utils.ElevationOnScrollListener;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.parceler.Parcels;
@@ -42,6 +44,7 @@ import me.grishka.appkit.utils.BindableViewHolder;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
import me.grishka.appkit.utils.V;
import me.grishka.appkit.views.FragmentRootLinearLayout;
import me.grishka.appkit.views.UsableRecyclerView;
import okhttp3.Call;
import okhttp3.Callback;
@@ -58,6 +61,7 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
private ArrayList<Item> items=new ArrayList<>();
private Call currentRequest;
private ItemsAdapter itemsAdapter;
private ElevationOnScrollListener onScrollListener;
@Override
public void onCreate(Bundle savedInstanceState){
@@ -72,7 +76,7 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
setNavigationBarColor(UiUtils.getThemeColor(activity, R.attr.colorWindowBackground));
instance=Parcels.unwrap(getArguments().getParcelable("instance"));
items.add(new Item("Mastodon for Android Privacy Policy", "joinmastodon.org", "https://joinmastodon.org/android/privacy", "https://joinmastodon.org/favicon-32x32.png"));
items.add(new Item("Mastodon for Android Privacy Policy", getString(R.string.privacy_policy_explanation), "joinmastodon.org", "https://joinmastodon.org/android/privacy", "https://joinmastodon.org/favicon-32x32.png"));
loadServerPrivacyPolicy();
}
@@ -93,18 +97,24 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
list.setLayoutManager(new LinearLayoutManager(getActivity()));
View headerView=inflater.inflate(R.layout.item_list_header_simple, list, false);
TextView text=headerView.findViewById(R.id.text);
text.setText(R.string.privacy_policy_subtitle);
text.setText(getString(R.string.privacy_policy_subtitle, instance.uri));
adapter=new MergeRecyclerAdapter();
adapter.addAdapter(new SingleViewRecyclerAdapter(headerView));
adapter.addAdapter(itemsAdapter=new ItemsAdapter());
list.setAdapter(adapter);
list.addItemDecoration(new DividerItemDecoration(getActivity(), R.attr.colorM3SurfaceVariant, 1, 56, 0, DividerItemDecoration.NOT_FIRST));
btn=view.findViewById(R.id.btn_next);
btn.setOnClickListener(v->onButtonClick());
buttonBar=view.findViewById(R.id.button_bar);
Button backBtn=view.findViewById(R.id.btn_back);
backBtn.setText(getString(R.string.server_policy_disagree, instance.uri));
backBtn.setOnClickListener(v->{
setResult(false, null);
Nav.finish(this);
});
return view;
}
@@ -113,13 +123,17 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
super.onViewCreated(view, savedInstanceState);
setStatusBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background));
view.setBackgroundColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background));
list.addOnScrollListener(onScrollListener=new ElevationOnScrollListener((FragmentRootLinearLayout) view, buttonBar, getToolbar()));
}
@Override
protected void onUpdateToolbar(){
super.onUpdateToolbar();
getToolbar().setBackground(null);
getToolbar().setBackgroundResource(R.drawable.bg_onboarding_panel);
getToolbar().setElevation(0);
if(onScrollListener!=null){
onScrollListener.setViews(buttonBar, getToolbar());
}
}
protected void onButtonClick(){
@@ -158,7 +172,7 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
if(!response.isSuccessful())
return;
Document doc=Jsoup.parse(Objects.requireNonNull(body).byteStream(), Objects.requireNonNull(body.contentType()).charset(StandardCharsets.UTF_8).name(), req.url().toString());
final Item item=new Item(doc.title(), instance.uri, req.url().toString(), "https://"+instance.uri+"/favicon.ico");
final Item item=new Item(doc.title(), null, instance.uri, req.url().toString(), "https://"+instance.uri+"/favicon.ico");
Activity activity=getActivity();
if(activity!=null){
activity.runOnUiThread(()->{
@@ -192,16 +206,23 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
private class ItemViewHolder extends BindableViewHolder<Item> implements UsableRecyclerView.Clickable{
private final TextView title;
private final TextView subtitle;
public ItemViewHolder(){
super(getActivity(), R.layout.item_privacy_policy_link, list);
title=findViewById(R.id.title);
title.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
subtitle=findViewById(R.id.subtitle);
}
@Override
public void onBind(Item item){
title.setText(item.title);
if(TextUtils.isEmpty(item.subtitle)){
subtitle.setVisibility(View.GONE);
}else{
subtitle.setVisibility(View.VISIBLE);
subtitle.setText(item.subtitle);
}
}
@Override
@@ -211,10 +232,11 @@ public class GoogleMadeMeAddThisFragment extends ToolbarFragment{
}
private static class Item{
public String title, domain, url, faviconUrl;
public String title, subtitle, domain, url, faviconUrl;
public Item(String title, String domain, String url, String faviconUrl){
public Item(String title, String subtitle, String domain, String url, String faviconUrl){
this.title=title;
this.subtitle=subtitle;
this.domain=domain;
this.url=url;
this.faviconUrl=faviconUrl;

View File

@@ -1,14 +1,8 @@
package org.joinmastodon.android.fragments.onboarding;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
@@ -37,6 +31,7 @@ import org.joinmastodon.android.ui.BetterItemAnimator;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.FilterChipView;
import org.joinmastodon.android.utils.ElevationOnScrollListener;
import org.parceler.Parcels;
import java.util.ArrayList;
@@ -56,7 +51,6 @@ import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.fragments.OnBackPressedListener;
import me.grishka.appkit.utils.BindableViewHolder;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
import me.grishka.appkit.utils.V;
@@ -211,47 +205,7 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
setStatusBarColor(0);
topBar=view.findViewById(R.id.top_bar);
LayerDrawable topBg=(LayerDrawable) topBar.getBackground().mutate();
topBar.setBackground(topBg);
Drawable topOverlay=topBg.findDrawableByLayerId(R.id.color_overlay);
topOverlay.setAlpha(0);
LayerDrawable btmBg=(LayerDrawable) buttonBar.getBackground().mutate();
buttonBar.setBackground(btmBg);
Drawable btmOverlay=btmBg.findDrawableByLayerId(R.id.color_overlay);
btmOverlay.setAlpha(0);
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
private boolean isAtTop=true;
private Animator currentPanelsAnim;
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
boolean newAtTop=recyclerView.getChildCount()==0 || (recyclerView.getChildAdapterPosition(recyclerView.getChildAt(0))==0 && recyclerView.getChildAt(0).getTop()==recyclerView.getPaddingTop());
if(newAtTop!=isAtTop){
isAtTop=newAtTop;
if(currentPanelsAnim!=null)
currentPanelsAnim.cancel();
AnimatorSet set=new AnimatorSet();
set.playTogether(
ObjectAnimator.ofInt(topOverlay, "alpha", isAtTop ? 0 : 20),
ObjectAnimator.ofInt(btmOverlay, "alpha", isAtTop ? 0 : 20),
ObjectAnimator.ofFloat(topBar, View.TRANSLATION_Z, isAtTop ? 0 : V.dp(3)),
ObjectAnimator.ofFloat(buttonBar, View.TRANSLATION_Z, isAtTop ? 0 : V.dp(3))
);
set.setDuration(150);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
currentPanelsAnim=null;
}
});
set.start();
currentPanelsAnim=set;
}
}
});
list.addOnScrollListener(new ElevationOnScrollListener(null, topBar, buttonBar));
searchEdit=view.findViewById(R.id.search_edit);
searchEdit.setOnEditorActionListener(this::onSearchEnterPressed);
@@ -684,4 +638,5 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
return (this==GENERAL)==isGeneral;
}
}
}

View File

@@ -17,6 +17,7 @@ import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.ui.DividerItemDecoration;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.utils.ElevationOnScrollListener;
import org.parceler.Parcels;
import androidx.annotation.NonNull;
@@ -28,6 +29,7 @@ import me.grishka.appkit.utils.BindableViewHolder;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
import me.grishka.appkit.utils.V;
import me.grishka.appkit.views.FragmentRootLinearLayout;
import me.grishka.appkit.views.UsableRecyclerView;
public class InstanceRulesFragment extends ToolbarFragment{
@@ -36,6 +38,9 @@ public class InstanceRulesFragment extends ToolbarFragment{
private Button btn;
private View buttonBar;
private Instance instance;
private ElevationOnScrollListener onScrollListener;
private static final int RULES_REQUEST=376;
@Override
public void onCreate(Bundle savedInstanceState){
@@ -81,19 +86,31 @@ public class InstanceRulesFragment extends ToolbarFragment{
super.onViewCreated(view, savedInstanceState);
// setStatusBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background));
// view.setBackgroundColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background));
list.addOnScrollListener(onScrollListener=new ElevationOnScrollListener((FragmentRootLinearLayout) view, buttonBar, getToolbar()));
}
@Override
protected void onUpdateToolbar(){
super.onUpdateToolbar();
getToolbar().setBackground(null);
getToolbar().setBackgroundResource(R.drawable.bg_onboarding_panel);
getToolbar().setElevation(0);
if(onScrollListener!=null){
onScrollListener.setViews(buttonBar, getToolbar());
}
}
protected void onButtonClick(){
Bundle args=new Bundle();
args.putParcelable("instance", Parcels.wrap(instance));
Nav.go(getActivity(), GoogleMadeMeAddThisFragment.class, args);
Nav.goForResult(getActivity(), GoogleMadeMeAddThisFragment.class, args, RULES_REQUEST, this);
}
@Override
public void onFragmentResult(int reqCode, boolean success, Bundle result){
super.onFragmentResult(reqCode, success, result);
if(reqCode==RULES_REQUEST && !success){
Nav.finish(this);
}
}
@Override

View File

@@ -132,7 +132,8 @@ public class UiUtils{
private static final DateTimeFormatter DATE_FORMATTER_SHORT_WITH_YEAR = DateTimeFormatter.ofPattern("d MMM uuuu"), DATE_FORMATTER_SHORT = DateTimeFormatter.ofPattern("d MMM");
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT);
private UiUtils(){}
private UiUtils() {
}
public static void launchWebBrowser(Context context, String url) {
try {
@@ -236,6 +237,7 @@ public class UiUtils{
/**
* Android 6.0 has a bug where start and end compound drawables don't get tinted.
* This works around it by setting the tint colors directly to the drawables.
*
* @param textView
*/
public static void fixCompoundDrawableTintOnAndroid6(TextView textView) {
@@ -262,7 +264,9 @@ public class UiUtils{
mainHandler.removeCallbacks(runnable);
}
/** Linear interpolation between {@code startValue} and {@code endValue} by {@code fraction}. */
/**
* Linear interpolation between {@code startValue} and {@code endValue} by {@code fraction}.
*/
public static int lerp(int startValue, int endValue, float fraction) {
return startValue + Math.round(fraction * (endValue - startValue));
}
@@ -274,7 +278,8 @@ public class UiUtils{
String name = cursor.getString(0);
if (name != null)
return name;
}catch(Throwable ignore){}
} catch (Throwable ignore) {
}
}
return uri.getLastPathSegment();
}
@@ -474,6 +479,7 @@ public class UiUtils{
.exec(accountID);
});
}
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback) {
confirmDeletePost(activity, accountID, status, resultCallback, false);
}
@@ -707,7 +713,8 @@ public class UiUtils{
@Override
public void onSuccess(Relationship rel) {
E.post(new FollowRequestHandledEvent(accountID, false, account, rel));
if (notificationID != null) E.post(new NotificationDeletedEvent(notificationID));
if (notificationID != null)
E.post(new NotificationDeletedEvent(notificationID));
resultCallback.accept(rel);
}
@@ -768,6 +775,7 @@ public class UiUtils{
ColorStateList iconTint = ColorStateList.valueOf(UiUtils.getThemeColor(context, android.R.attr.textColorSecondary));
insetPopupMenuIcon(item, iconTint);
}
public static void insetPopupMenuIcon(MenuItem item, ColorStateList iconTint) {
Drawable icon = item.getIcon().mutate();
if (Build.VERSION.SDK_INT >= 26) item.setIconTintList(iconTint);
@@ -795,8 +803,8 @@ public class UiUtils{
m.setAccessible(true);
m.invoke(menu, true);
enableMenuIcons(context, menu, asAction);
} catch (Exception ignored) {
}
catch(Exception ignored){}
}
}
@@ -806,7 +814,8 @@ public class UiUtils{
MenuItem item = m.getItem(i);
SubMenu subMenu = item.getSubMenu();
if (subMenu != null) enableMenuIcons(context, subMenu, exclude);
if (item.getIcon() == null || Arrays.stream(exclude).anyMatch(id -> id == item.getItemId())) continue;
if (item.getIcon() == null || Arrays.stream(exclude).anyMatch(id -> id == item.getItemId()))
continue;
insetPopupMenuIcon(item, iconTint);
}
}
@@ -820,7 +829,8 @@ public class UiUtils{
Method setOptionalIconsVisible = m.getClass().getDeclaredMethod("setOptionalIconsVisible", boolean.class);
setOptionalIconsVisible.setAccessible(true);
setOptionalIconsVisible.invoke(m, true);
}catch(Exception ignore){}
} catch (Exception ignore) {
}
}
enableMenuIcons(context, m);
}
@@ -835,6 +845,7 @@ public class UiUtils{
ColorPalette palette = ColorPalette.palettes.get(GlobalUserPreferences.color);
if (palette != null) palette.apply(context);
}
public static boolean isDarkTheme() {
if (theme == GlobalUserPreferences.ThemePreference.AUTO)
return (MastodonApp.context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
@@ -865,7 +876,8 @@ public class UiUtils{
return false;
}
if (uri.getQuery() != null || uri.getFragment() != null || uri.getPath() == null) return false;
if (uri.getQuery() != null || uri.getFragment() != null || uri.getPath() == null)
return false;
String it = uri.getPath();
return it.matches("^/@[^/]+$") ||
@@ -966,7 +978,8 @@ public class UiUtils{
@Override
public void onSuccess(SearchResults results) {
if (!results.statuses.isEmpty()) statusConsumer.accept(results.statuses.get(0));
else Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
}
@Override
@@ -1038,7 +1051,8 @@ public class UiUtils{
Nav.go((Activity) context, ProfileFragment.class, args);
} else {
if (launchBrowser) launchWebBrowser(context, url);
else Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
}
}
@@ -1071,7 +1085,8 @@ public class UiUtils{
Class<?> props = Class.forName("android.os.SystemProperties");
Method get = props.getMethod("get", String.class);
return (String) get.invoke(null, key);
}catch(Exception ignore){}
} catch (Exception ignore) {
}
return null;
}
@@ -1079,6 +1094,14 @@ public class UiUtils{
return !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.code"));
}
public static int alphaBlendColors(int color1, int color2, float alpha) {
float alpha0 = 1f - alpha;
int r = Math.round(((color1 >> 16) & 0xFF) * alpha0 + ((color2 >> 16) & 0xFF) * alpha);
int g = Math.round(((color1 >> 8) & 0xFF) * alpha0 + ((color2 >> 8) & 0xFF) * alpha);
int b = Math.round((color1 & 0xFF) * alpha0 + (color2 & 0xFF) * alpha);
return 0xFF000000 | (r << 16) | (g << 8) | b;
}
public static boolean pickAccountForCompose(Activity activity, String accountID, String prefilledText) {
Bundle args = new Bundle();
if (prefilledText != null) args.putString("prefilledText", prefilledText);

View File

@@ -0,0 +1,116 @@
package org.joinmastodon.android.utils;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.view.View;
import org.joinmastodon.android.R;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
import me.grishka.appkit.views.FragmentRootLinearLayout;
public class ElevationOnScrollListener extends RecyclerView.OnScrollListener implements View.OnScrollChangeListener{
private boolean isAtTop;
private Animator currentPanelsAnim;
private View[] views;
private FragmentRootLinearLayout fragmentRootLayout;
public ElevationOnScrollListener(FragmentRootLinearLayout fragmentRootLayout, View... views){
isAtTop=true;
this.fragmentRootLayout=fragmentRootLayout;
this.views=views;
for(View v:views){
Drawable bg=v.getBackground().mutate();
v.setBackground(bg);
if(bg instanceof LayerDrawable ld){
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
if(overlay!=null){
overlay.setAlpha(0);
}
}
}
}
public void setViews(View... views){
List<View> oldViews=Arrays.asList(this.views);
this.views=views;
for(View v:views){
if(oldViews.contains(v))
continue;
Drawable bg=v.getBackground().mutate();
v.setBackground(bg);
if(bg instanceof LayerDrawable ld){
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
if(overlay!=null){
overlay.setAlpha(isAtTop ? 0 : 20);
}
}
v.setTranslationZ(isAtTop ? 0 : V.dp(3));
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
boolean newAtTop=recyclerView.getChildCount()==0 || (recyclerView.getChildAdapterPosition(recyclerView.getChildAt(0))==0 && recyclerView.getChildAt(0).getTop()==recyclerView.getPaddingTop());
handleScroll(recyclerView.getContext(), newAtTop);
}
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
handleScroll(v.getContext(), scrollY==0);
}
private void handleScroll(Context context, boolean newAtTop){
if(newAtTop!=isAtTop){
isAtTop=newAtTop;
if(currentPanelsAnim!=null)
currentPanelsAnim.cancel();
AnimatorSet set=new AnimatorSet();
ArrayList<Animator> anims=new ArrayList<>();
for(View v:views){
if(v.getBackground() instanceof LayerDrawable ld){
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
if(overlay!=null){
anims.add(ObjectAnimator.ofInt(overlay, "alpha", isAtTop ? 0 : 20));
}
}
anims.add(ObjectAnimator.ofFloat(v, View.TRANSLATION_Z, isAtTop ? 0 : V.dp(3)));
}
if(fragmentRootLayout!=null){
int color;
if(isAtTop){
color=UiUtils.getThemeColor(context, R.attr.colorM3Background);
}else{
color=UiUtils.alphaBlendColors(UiUtils.getThemeColor(context, R.attr.colorM3Background), UiUtils.getThemeColor(context, R.attr.colorM3Primary), 0.07843137f);
}
anims.add(ObjectAnimator.ofArgb(fragmentRootLayout, "statusBarColor", color));
}
set.playTogether(anims);
set.setDuration(150);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
set.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
currentPanelsAnim=null;
}
});
set.start();
currentPanelsAnim=set;
}
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<me.grishka.appkit.views.FragmentRootLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -11,6 +11,7 @@
android:layout_weight="1"/>
<LinearLayout
android:background="@drawable/bg_onboarding_panel"
android:id="@+id/button_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -41,4 +42,4 @@
</LinearLayout>
</me.grishka.appkit.views.FragmentRootLinearLayout>
</LinearLayout>

View File

@@ -1,18 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView 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:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingEnd="24dp"
android:paddingBottom="12dp"
android:paddingStart="16dp"
android:textSize="16sp"
android:textColor="?colorM3Primary"
android:drawableStart="@drawable/ic_outline_link_24"
android:drawablePadding="16dp"
android:drawableTint="?colorM3Primary"
tools:text="Privacy Policy - example.social">
android:paddingEnd="24dp">
</TextView>
<View
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:backgroundTint="?colorM3Primary"
android:background="@drawable/ic_outline_link_24"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/icon"
android:layout_marginStart="16dp"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3Primary"
tools:text="Privacy Policy - example.social"/>
<TextView
android:id="@+id/subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/icon"
android:layout_below="@id/title"
android:layout_marginStart="16dp"
android:textAppearance="@style/m3_body_medium"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="Privacy Policy - example.social"/>
</RelativeLayout>

View File

@@ -389,7 +389,7 @@
<string name="download_update">Download (%s)</string>
<string name="install_update">Install</string>
<string name="privacy_policy_title">Your Privacy</string>
<string name="privacy_policy_subtitle">Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server\'s privacy policy.</string>
<string name="privacy_policy_subtitle">Although the Mastodon app does not collect any data, the server you sign up through may have a different policy.\n\nIf you disagree with the policy for %s, you can go back and pick a different server.</string>
<string name="i_agree">I Agree</string>
<string name="empty_list">This list is empty</string>
<string name="instance_signup_closed">This server does not accept new registrations.</string>
@@ -429,4 +429,7 @@
<string name="popular_on_mastodon">Popular on Mastodon</string>
<string name="follow_all">Follow all</string>
<string name="server_rules_disagree">Disagree</string>
<string name="privacy_policy_explanation">TL;DR: We don\'t collect or process anything.</string>
<!-- %s is server domain -->
<string name="server_policy_disagree">Disagree with %s</string>
</resources>